Feature for PUT method, data sent in JSON format, and has verbose
alasalamont opened this issue · 15 comments
As the title does, I did try run
python3 sstimap.py -u "http://api.example.com" -m PUT -d "{\"username\":\"david",\"content\":\"*\"}"
or
python3 sstimap.py -u "http://api.example.com" -m PUT -d "username=david&content=*"
But none of them work. The issue might arise from the current version not supporting the PUT method, or not accepting data in JSON format, or am I using the tool incorrectly?
Beside that, another case successfully injected SSTI payload. In the result says File write: ok
. So this means the tool can upload file on Target's server or the tools can run payload that can write file?
I also hope in the future the result can show which payloads are used during the scan, which payloads work.
Regards!
Currently, SSTImap is not supporting JSON. I am working on it, so hopefully I would be able to release an update soon enough.
It seems current version does not support with PUT request too. So far only support GET & POST method. Hope in the next update will have them all. Thanks bro
SSTImap fully supports PUT requests, as well as any other method (even nonexisting ones). For now, only application/x-www-form-urlencoded
body is supported, so json data would get processed in the wrong way
SSTImap fully supports PUT requests, as well as any other method (even nonexisting ones). For now, only
application/x-www-form-urlencoded
body is supported, so json data would get processed in the wrong way
Then I suggest changing the output according to the -m REQUEST_TYPE
, because when I test PUT
request, the tool still says [*] Testing if POST parameter 'email' is injectable
which can cause confused
Then I suggest changing the output according to the
-m REQUEST_TYPE
, because when I testPUT
request, the tool still says[*] Testing if POST parameter 'email' is injectable
which can cause confused
I would change it soon, as it is indeed confusing. It should clarify that it is a param in a body form
Should be fixed in 1.2.0
Can you verify?
Payloads should appear in ~/.sstimap/sstimap.log
Verbose output might be added later
Should be fixed in 1.2.0 Can you verify?
Payloads should appear in
~/.sstimap/sstimap.log
Verbose output might be added later
Hi brother,
I did use version 1.2.0
And the POST request looks like
POST /api/pug HTTP/1.1
Host: template-sandbox
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json;charset=utf-8
Content-Length: 59
Origin: http://template-sandbox
Connection: close
Referer: http://template-sandbox/pug
{"data":"123","vars":{"showSecret":true,"name":"Osku"}}
Attempt 1
Here is the command that I run
python3 sstimap.py -u http://template-sandbox/api/pug -m POST -d "{\"data\":\"*\",\"vars\":{\"showSecret\":true,\"name\":\"Osku\"}}" --date-type json -e pug
And here is the tool response
sstimap.py: error: unrecognized arguments: --date-type json
Attempt 2
I ignore the flag --data-type
, and run the tool runs but does not give the correct output
[*] Version: 1.2.0
[*] Author: @vladko312
[*] Based on Tplmap
[!] LEGAL DISCLAIMER: Usage of SSTImap for attacking targets without prior mutual consent is illegal.
It is the end user's responsibility to obey all applicable local, state and federal laws.
Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] Loaded plugins by categories: languages: 5; legacy_engines: 2; engines: 17
[*] Loaded request body types: 4
[*] Scanning url: http://template-sandbox/api/pug
[*] Testing if Body parameter '{"data":"*","vars":{"showSecret":true,"name":"Osku"}}' is injectable
[*] Pug plugin is testing rendering with tag '\n= *\n'
[*] Pug plugin is testing )*// code context escape with 6 variations
[*] Pug plugin is testing blind injection
[*] Pug plugin is testing )*// code context escape with 6 variations
[-] Tested parameters appear to be not injectable.
So did I use the tool wrongly?
I also expect you can provide the value for each flags. Assume user does not know what value of the flag can be input, user can run
python3 sstimap.py --data-type -h
And the tool will shows all the value that flag --data-type
accepts. Then it will be easier to use. To be honest, there are some flags that I dont know how to use/ or when to use such as --load-forms
, what is the different between -l
and -L
In your attempt 1 you used --date-type
instead of --data-type
, which caused the error.
In attempt 2 SSTIMAP tried processing JSON as a web form, which prevented it from finding vulnerabilities.
I agree that SSTImap needs better documentation. I will work on that later.
As for params you mentioned:
--load-forms
is a way to load forms saved using--save-forms
-l
tries all context escapes up to the selectedLEVEL
-L
tries template context escapes only for the selectedLEVEL
and base language context escapes only for the selectedCLEVEL
.
I rarely use the last flag myself. It was probably added toTplmap
to skip tests after the initial detection to allow faster exploitation. InSSTImap
I made fast exploitation easier adding interactive mode (-i
), so restarting detection is no longer needed.
In your attempt 1 you used
--date-type
instead of--data-type
, which caused the error. In attempt 2 SSTIMAP tried processing JSON as a web form, which prevented it from finding vulnerabilities.I agree that SSTImap needs better documentation. I will work on that later. As for params you mentioned:
--load-forms
is a way to load forms saved using--save-forms
-l
tries all context escapes up to the selectedLEVEL
-L
tries template context escapes only for the selectedLEVEL
and base language context escapes only for the selectedCLEVEL
.
I rarely use the last flag myself. It was probably added toTplmap
to skip tests after the initial detection to allow faster exploitation. InSSTImap
I made fast exploitation easier adding interactive mode (-i
), so restarting detection is no longer needed.
Hi thank you for pointing out my typo. I did test again,
python3 sstimap.py -u "http://template-sandbox/api/pug" -m POST -d "{\"data\":\"123*\",\"vars\":{\"showSecret\":true,\"name\":\"Osku\"}}" --data-type json --proxy http://127.0.0.1:8080 -e pug
and here is the result
[*] Version: 1.2.0
[*] Author: @vladko312
[*] Based on Tplmap
[!] LEGAL DISCLAIMER: Usage of SSTImap for attacking targets without prior mutual consent is illegal.
It is the end user's responsibility to obey all applicable local, state and federal laws.
Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] Loaded plugins by categories: languages: 5; legacy_engines: 2; engines: 17
[*] Loaded request body types: 4
[*] Scanning url: http://template-sandbox/api/pug
[*] Testing if Body parameter 'data' is injectable
[*] Pug plugin is testing rendering with tag '\n= *\n'
[*] Pug plugin is testing )*// code context escape with 6 variations
[*] Pug plugin is testing blind injection
[*] Pug plugin is testing )*// code context escape with 6 variations
[-] Tested parameters appear to be not injectable.
I also check the POST request via Burp. It seems the tool try to add \n
that cause the payload does not work as expect
POST /api/pug HTTP/1.1
Host: template-sandbox
User-Agent: SSTImap/1.2.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Content-Length: 116
{"data": "123\n= 7401602210\n\n= typeof(88)+69\n\n= 9646249855\n", "vars": {"showSecret": true, "name": "Osku"}}
And here is the response
HTTP/1.1 500 Internal Server Error
Content-Length: 1152
Content-Security-Policy: default-src 'none'
Content-Type: text/html; charset=utf-8
Date: Sun, 07 Jan 2024 16:13:43 GMT
X-Content-Type-Options: nosniff
X-Powered-By: Express
Connection: close
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>TypeError: Cannot set property 'SECRET_STRING' of undefined<br> at /usr/src/app/index.js:14:26<br> at Layer.handle [as handle_request] (/usr/src/app/node_modules/express/lib/router/layer.js:95:5)<br> at next (/usr/src/app/node_modules/express/lib/router/route.js:137:13)<br> at Route.dispatch (/usr/src/app/node_modules/express/lib/router/route.js:112:3)<br> at Layer.handle [as handle_request] (/usr/src/app/node_modules/express/lib/router/layer.js:95:5)<br> at /usr/src/app/node_modules/express/lib/router/index.js:281:22<br> at Function.process_params (/usr/src/app/node_modules/express/lib/router/index.js:335:12)<br> at next (/usr/src/app/node_modules/express/lib/router/index.js:275:10)<br> at urlencodedParser (/usr/src/app/node_modules/body-parser/lib/types/urlencoded.js:100:7)<br> at Layer.handle [as handle_request] (/usr/src/app/node_modules/express/lib/router/layer.js:95:5)</pre>
</body>
</html>
Regards!
I also check the POST request via Burp. It seems the tool try to add \n that cause the payload does not work as expect
Have you tried resending the request through burp repeater without extra \n
?
I did find out the reason. If I add -H "Content-Type: application/json;charset=utf-8"
it works perfectly. So I think the tool should remind user or add for user this header when use option --data-type json
By the way, what is the char key that combine multiple Headers? or stack multiple Cookies?
I did use semi-colon
to stack multiple headers but it does not work. Example: -H "Content-Type: application/json;charset=utf-8; Host: template-sandbox
it turn out in POST request: Content-Type: application/json;charset=utf-8, Host:template-sandbox
. They are not separate in new line
So I think the tool should remind user or add for user this header when use option
--data-type json
Yes, this is a good idea.
By the way, what is the char key that combine multiple Headers? or stack multiple Cookies?
The intended way of specifying multiple headers/cookies is by using multiple -H
/-C
flags or corresponding interactive commands using -i
.
If really needed, headers can be separated within one flag by \r\n
and cookies by ;
, just like in HTTP.
But I am not sure this is work for all cases or not. To me, it is still kind of weird as follow
If I send your payload \n= 7530515504\n\n= typeof(91)+96\n\n= 5816490115\n
in via Burp, it works
But if I inject directly on GUI website, the site response There was an error rendering your content
Error: Pug:1:1
> 1| \n= 7530515504\n\n= typeof(91)+96\n\n= 5816490115\n
-------^
unexpected text "\n= 2"
at makeError (/usr/src/app/node_modules/pug-error/index.js:34:13)
at Lexer.error (/usr/src/app/node_modules/pug-lexer/index.js:62:15)
at Lexer.fail (/usr/src/app/node_modules/pug-lexer/index.js:1629:10)
at Lexer.advance (/usr/src/app/node_modules/pug-lexer/index.js:1694:12)
at Lexer.callLexerFunction (/usr/src/app/node_modules/pug-lexer/index.js:1647:23)
at Lexer.getTokens (/usr/src/app/node_modules/pug-lexer/index.js:1706:12)
at lex (/usr/src/app/node_modules/pug-lexer/index.js:12:42)
at Object.lex (/usr/src/app/node_modules/pug/lib/index.js:104:9)
at Function.loadString [as string] (/usr/src/app/node_modules/pug-load/index.js:53:24)
at compileBody (/usr/src/app/node_modules/pug/lib/index.js:82:18)
Somehow your payload only works in Burp, not in GUI site
Why dont you use simple payload such as #{111*"111"}
to detect?
Somehow your payload only works in Burp, not in GUI site
Payload is transfered in JSON, so newlines are encoded as \n
. In Burp, you send this encoded payload, so it works fine.
While sending it through GUI, you are sending \n
as two literal charecters, as it is encoded again in JSON becoming \\n
and breaking the syntax.
To send payload through GUI, try just replacing \n
with actual newlines.
Why dont you use simple payload such as
#{111*"111"}
to detect?
First of all, we need to escape to template context for our payload to work. In the simplest cases, we are already there, but we need to check other cases up to the selected --level
(for example, #{"Hello, NICKNAME!"}
would require something like "}PAYLOAD#{"
). Then, to check the result, we need to add some ways of finding our result on the page. This is what the big numbers in the payload are for. Also, there are many engines with a very similar basic syntax but different exploitation payloads, so #{111*"111"}
will not be enough to check if we have found the right engine. As a result, detection payloads are a bit more complex, using unique features of the languages, such as multiline syntax of Pug and typeof(91)+96
evaluating to number96
in javascript.
Exploitation payloads are way more complex, as they are designed to work with any higher-level payload passed through them.
I have plans to add a faster detection method based on syntax detection, but it would add some time.
Somehow your payload only works in Burp, not in GUI site
Payload is transfered in JSON, so newlines are encoded as
\n
. In Burp, you send this encoded payload, so it works fine. While sending it through GUI, you are sending\n
as two literal charecters, as it is encoded again in JSON becoming\\n
and breaking the syntax. To send payload through GUI, try just replacing\n
with actual newlines.Why dont you use simple payload such as
#{111*"111"}
to detect?First of all, we need to escape to template context for our payload to work. In the simplest cases, we are already there, but we need to check other cases up to the selected
--level
(for example,#{"Hello, NICKNAME!"}
would require something like"}PAYLOAD#{"
). Then, to check the result, we need to add some ways of finding our result on the page. This is what the big numbers in the payload are for. Also, there are many engines with a very similar basic syntax but different exploitation payloads, so#{111*"111"}
will not be enough to check if we have found the right engine. As a result, detection payloads are a bit more complex, using unique features of the languages, such as multiline syntax of Pug andtypeof(91)+96
evaluating tonumber96
in javascript. Exploitation payloads are way more complex, as they are designed to work with any higher-level payload passed through them.I have plans to add a faster detection method based on syntax detection, but it would add some time.
Thank you for enlighting me up <3 now I understand