Skip to content

城通网盘代码审计

Published: at 01:54 PM

参考 https://mp.weixin.qq.com/s/atlJ1SFul6ArrHq733blJA

Table of Content

任意文件上传漏洞

原文对于文件上传漏洞已经描述的很清楚了,这里我就根据个人情况随笔记一点:

为什么要设置这三个参数?

Untitled

前两个参数都很好理解。由于对 uid 没有做校验,甚至可以直接为空。 至于第三个参数,是用来接受服务端返回的文件信息,由于文件名是使用$file_name = 'file_'.$this->getRandomName(16); 随机生成的,如果不设置该条件,即使文件上传成功我们也没办法访问.

Untitled

Untitled

由于没有对文件后缀做限制,所以直接上传php也是可以的。

Untitled

Untitled

其次跟正下原文中的一个小错误:

Untitled

Untitled

这里找他的意思是 server下的start函数是入口点,就要用start的路由去访问(从他的payload中可以猜出来)。但实际上是在 Create 方法中调用了 start , 所以该文件不能够路由去访问,直接以文件路由的形式去访问就行了.路由只能去访问对应的控制器。

Untitled

Untitled

总结 1

原文中的切入点为 move_upload_file ,在代码审计中称之为 slink 也就是所谓的危险函数,随后通过危险函数回溯找到入口点,从而找到整条利用链子,有时候我们也会称之为逆向审计。

当然,有逆向审计就有正向审计。正向审计就是从程序所有接受参数的地方( source ),依次往下分析调用,直到触发 slink .

下面我们用 source 的方法来进行分析该漏洞:

在PHP中所有参数都是通过 $_GET $_POST $_REQUEST 等方法传入的,因此我们可以先全局搜索其中的关键字,去寻找其中可能存在危险调用的地方。

Untitled

前面两个 $_GET 不知道大家是否熟悉,这就是之前PHP多语言任意PHP文件包含漏洞,如果忘记了可以前往我的博客, 里面也有详细的分析过程:https://www.noel-zero.top/2022/12/23/2022-12-23-TP多语言文件包含/。这里我们直接跳到第三个开始分析:

Untitled

这段代码可以看到程序会根据 $command 的类型执行对应分支的逻辑,我们先跟进第一个 upload 分支,可以看到里面存在一大堆传入系统的参数,跟进第一个可能存在问题的函数 getUserChunkPath

Untitled

Untitled

根据注释可以了解到该函数就是创建目录功能,与目录相关, uid 可控,很自然就会想到此处是否存在目录逃逸,造成任意文件夹覆盖。

继续回到主函数,往下分析就到$info = $this->upload_file($_GET['uid']); 了,这里就不再重复了。

source分析的大概的思路和流程就是这样

接下来我们在尝试通过source去查找其他的漏洞

再尝试:失败的文件下载

同样搜索 $_GET ,留意到case的另外一个分支,似乎是一个文件下载的功能点。

跟进了该分支下的函数,发现没有设置任何过滤,只需要通过 decodeTk() 函数拿到文件名就行。

Untitled

跟进 decodeTk() 函数,浏览一下,就是对传入的字符串进行自定义的解码从而获得文件名:

Untitled

系统所设计的功能点一定是存在相应入口点的,我们只需要去找到在哪个地方调用了下载文件这个功能,就知道怎么去构造加密字符串了。

由于该字符串是通过 $_GET['tk'] 传入的,这里我直接全局搜索 'tk' ,

Untitled

Untitled

更进第一个函数,发现是通过 urlsafe_b64encode() 这个函数来加密了的,于是我们直接复制将相应的功能函数复制出来就行了。

function urlsafe_b64encode($string) {
    $data = base64_encode($string);
    $data = str_replace(['+','/','='],['-','_',''],$data);
    return $data;
}
function encodeTk()
{
    $params = [
        'file' => "/index.php", // 下载那个文件
        'origin' => "/index.php", # 下载的文件名
        'speed' => "",
        'time' => time()
    ];
    return urlsafe_b64encode(implode(',',$params));
}

构造 tksign ,得到poc:

/public/server/index.php?md=download&tk=L2luZGV4LnBocCwvaW5kZXgucGhwLCwxNzA3MjAwOTky&sign=17c65088a435fce676d915cf2877f8b0

Untitled

成功下载 index.php .

但是如果是使用 ../../../../etc/passwd 尝试目录穿越会发现无法读取。

随后去搜了下 header('X-Accel-Redirect: '. $tk_info['file']); ,这里算是对目录穿越做了限制,所以就没办任意文件读取了.

总结2

这篇文章主要从介绍了代码审计的两种思路,一种是正向审计,一种是逆向审计。从本文提到的一些例子可以看到,针对原文提到的文件上传漏洞,使用逆向分析显然效率更快。但是在大多数情况下两种方法是没有绝对优势的说法的,两种方法我们都得熟练和掌握,只有根据情况选择相应的方法才是最高的效率。

希望这边文章能对刚入门代码升级的师傅们有所帮助