From bea0fc8a1ad7f54e4124239be0f5277bdbda3aba Mon Sep 17 00:00:00 2001 From: Swissky Date: Tue, 16 Oct 2018 12:18:00 +0200 Subject: [PATCH] INFRA - Handling JSON in request + example SSRF2 (json data) --- README.md | 1 + core/requester.py | 40 ++++++++++++++++++++++++++++++---------- data/example.py | 12 ++++++++++-- data/request2.txt | 13 +++++++++++++ 4 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 data/request2.txt diff --git a/README.md b/README.md index 5bc0b62..94613f5 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ Feel free to add any feature listed below or a new service. - networkscan - same a portscan, we want to discover machines in the same network - aws and other cloud providers - extract sensitive data from http://169.254.169.254/latest/meta-data/iam/security-credentials/dummy and more - sockserver - SSRF SOCK proxy server - https://github.com/iamultra/ssrfsocks +- handle request with file in requester The following code is a template if you wish to add a module interacting with a service. diff --git a/core/requester.py b/core/requester.py index 7598707..90a6368 100644 --- a/core/requester.py +++ b/core/requester.py @@ -1,4 +1,5 @@ import re +import json import requests import logging @@ -37,10 +38,17 @@ class Requester(object): def data_to_dict(self, data): if self.method == "POST": - for arg in data.split("&"): - regex = re.compile('(.*)=(.*)') - for name,value in regex.findall(arg): - self.data[name] = value + + # Handle JSON data + if self.headers['Content-Type'] and self.headers['Content-Type'] == "application/json": + self.data = json.loads(data) + + # Handle FORM data + else: + for arg in data.split("&"): + regex = re.compile('(.*)=(.*)') + for name,value in regex.findall(arg): + self.data[name] = value def do_request(self, param, value): @@ -51,12 +59,24 @@ class Requester(object): if param in data_injected: data_injected[param] = value - r = requests.post( - "http://" + self.host + self.action, - headers=self.headers, - data=data_injected, - timeout=3 - ) + + # Handle JSON data + if self.headers['Content-Type'] and self.headers['Content-Type'] == "application/json": + r = requests.post( + "http://" + self.host + self.action, + headers=self.headers, + json=data_injected, + timeout=3 + ) + + # Handle FORM data + else: + r = requests.post( + "http://" + self.host + self.action, + headers=self.headers, + data=data_injected, + timeout=3 + ) else: # String is immutable, we don't have to do a "forced" copy regex = re.compile(param+"=(\w+)") diff --git a/data/example.py b/data/example.py index 5706a9d..65aa84e 100644 --- a/data/example.py +++ b/data/example.py @@ -9,14 +9,23 @@ def hello(): return "SSRF Example!" # do not try this at home - highly vulnerable ! (SSRF and RCE) +# curl -i -X POST -d 'url=http://example.com' http://localhost:5000/ssrf @app.route("/ssrf", methods=['POST']) def ssrf(): data = request.values + content = command("curl {}".format(data.get('url'))) + return content + +# curl -i -H "Content-Type: application/json" -X POST -d '{"url": "http://example.com"}' http://localhost:5000/ssrf +@app.route("/ssrf2", methods=['POST']) +def ssrf2(): + data = request.json print(data) print(data.get('url')) content = command("curl {}".format(data.get('url'))) return content + def command(cmd): proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) (out, err) = proc.communicate() @@ -25,5 +34,4 @@ def command(cmd): if __name__ == '__main__': app.run(host='127.0.0.1', port=5000, debug=True) # FLASK_APP=example.py flask run -# NOTE: this file should become a simple ssrf example in order to test SSRFmap -# curl -i -X POST -d 'url=http://example.com' http://localhost:5000/ssrf \ No newline at end of file +# NOTE: this file should become a simple ssrf example in order to test SSRFmap \ No newline at end of file diff --git a/data/request2.txt b/data/request2.txt new file mode 100644 index 0000000..4491447 --- /dev/null +++ b/data/request2.txt @@ -0,0 +1,13 @@ +POST /ssrf2 HTTP/1.1 +Host: 127.0.0.1:5000 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0 +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 +Accept-Language: en-US,en;q=0.5 +Accept-Encoding: gzip, deflate +Referer: http://127.0.0.1:5000/ +Content-Type: application/json +Content-Length: 43 +Connection: close +Upgrade-Insecure-Requests: 1 + +{"userId":"1", "url": "http://example.com"} \ No newline at end of file