前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >弱鸡的代码审计之旅

弱鸡的代码审计之旅

作者头像
信安之路
发布2020-04-20 16:20:50
7800
发布2020-04-20 16:20:50
举报
文章被收录于专栏:信安之路信安之路

作为一只审计菜鸡,在前台没发现什么大漏洞,只在后台找到两个,不过代码审计过程还是很香的。接下来就掰扯一下菜鸡的审计过程。另外分享的两个漏洞已经通报给 CNVD。

0x01 失败的审计过程

根据自己的审计习惯,首先会开启 debug,然后阅读一下入口文件,跟踪一下程序运行的流程,参数的传递处理方式。

这个系统没有对参数做什么特别的处理,所以入口文件这一块没有找到太多有用的信息。之后会用自动审计程序扫一遍,查看一下有什么危险函数,习惯用的是 seay 源码审计系统

然后根据我的直 jio,前面的命令执行基本是 SQL 语句里包含了反引号,没发现啥理由价值。作为弱鸡我可能会关注这个点:

这个 eval 是放在模板解析的类当中,关于模板解析之前审计的时候发现很有可能存在代码执行漏洞,而且 zzzphp 之前的版本也存在模板解析导致的 RCE,所以先关注这个地方。

首先还是定位函数位置:

然后根据敏感函数溯源的方法和之前审计的经验,在程序 search 的位置可以插入代码破坏模板源文件:(关于要如何输入 payload 触发漏洞,不是这里的重点)输入:

{if:1=print(sha1(123))}if(1){end if}

可以看到箭头执行的位置,输入的 payload 已经改变了模板格式,接着下面的正则匹配会将我们的 payload 读取到变量当中。

通过 eval 函数解析了输入的 payload,打印出 123 的 sha1 值。

本来以为这个地方还是存在漏洞,不过输入写入 shell 的 payload 发现了问题:

输入的字符有一部分被过滤了,这个地方需要跟进一波,查看能不能 bypass。通过跟踪变量中途的变化,发现是在 parserlocation 函数进行了过滤。

跟进发现了具体的安全函数:

继续跟进 danger_key 函数:

发现这个文件当中存在较多的过滤函数,这些函数也会影响其余的漏洞利用。而这个 danger_key 函数,过滤了很多关键字,作为弱鸡没想到 bypass 的方法,哭卿卿。

在放弃这个 bypass 一段时间之后,又在审计系统发现一处可能存在变量覆盖的点:

函数具体位置:

然后发现全局唯一一次调用 geturl_path 的位置如下:

发现获取到的变量最终可以影响模板加载的路径,这个当时就灵机一动,如果存在变量覆盖漏洞,可以通过漏洞将模板的加载路径进行覆盖,重定向到一个我们自己的模板,然后通过没有安全过滤的模板解析函数进行解析模板达到代码执行的效果。至于如何上传一个自己的模板,后面会介绍一个受限的上传漏洞。

此处还印证了一个自己不知道的点:

上面的代码中 path 和 path2 表示的路径是同一个,而其实 upload 文件夹下是不存在 tests 文件夹的。

这样的话在上面的代码中,第 136 行中本来要加载一个类似 d:\html\userlogin.html 的模板,我们就可以控制变量,让模板路径变成 d:\html\user\123.html,就可以将模板地址重定向到上传的恶意模板了。

不过上面的这些都是个人猜想,在实际审计过程中发现,作为菜鸡的我没有办法进入到 parse_str 的程序逻辑:

根据这里的程序逻辑,last 变量的值应该永远为空,那就没办法进入if判断了。所以上面的猜测并没有得到实现。在写完上面两处失败的审计过程之后就要到发现漏洞的过程了。

0x02 成功的漏洞挖掘:

第一处漏洞:后台 SQL 注入

之后又在审计系统里翻找,然后发现一处调用了 exec 函数的位置,以为是命令执行,但是跟进去一看,发现是一个 SQL 执行的函数:

函数具体内容如下:

还是个执行 SQL 的地方。这个地方 exec 方法是动态的,没办法直接跟进去,可以先查找调用了 db_exec 函数的位置,主要集中在 save.php 和 zzz_db 两个文件当中:

漏洞是在红框的代码处发现的,其他的也可以跟进查看是否存在漏洞,这里就不赘述了,直接看第 959 行代码:

这个 restore 函数应该是用于数据库恢复的函数,然后查看哪个地方调用了这个函数:

还是在同一个文件内:

知道具体调用点之后,要么直接构造数据包访问,要么通过找到功能点获取数据包,此处两个办法都行,因为数据库还原的位置还是比较好找的。

来看一下数据还原触发的请求 url:

http://www.zzzphp.com/admin520/save.php?act=restore

其中这个 path 根据程序逻辑是不运行进行修改的,也尝试修改前台代码将 path 修改,但是无效,最后还是要通过抓包修改。已经知道具体的功能点了也获取到了数据包再回到代码本身来看:

上面的 restore 函数中有一个关键变量 $path,可以看到 $path 是通过表单直接获取的,只经过 safe_url 函数的过滤,便拼接形成备份文件的绝对路径,并没有检测 $path 是否属于之前的备份文件保存位置,然后直接通过 load_file 函数加载拼接的备份文件路径。Safe_url 函数不用看,因为原来的程序逻辑就是输入路径,我们只不过修改了一下路径,所以不会造成影响,具体要看一下 load_file 函数是如何加载文件内容的,是否有做处理:

Load_file 函数只是简单检测文件是否存在,还是没有校验合法性,之后直接返回文件内的数据内容。根据上面 restore 函数,将文件内容进行解析(读取里面的 sql 语句),然后通过 db_exec 函数执行语句,其中 db_exec 函数如下:

在这里可以看到 db_exec 函数并没有对传入的 sql 语句进行处理,直接判断数据库类型,然后调用了 exec 函数执行,至于 exec 里面是否存在过滤,我们开启 debug 跟踪一下流程就可以知道:首先是触发 restore 函数,可以看到 $path 已经变成自定义的路径了。

通过 load_file 函数加载文件内容:

将加载的内容通过 expload 函数拆分,实际就是分离里面的 sql 语句。

然后通过 db_exec 函数运行 sql 语句,函数中实际调用了 pdo 中的 exec 函数

通过 exec 函数执行 sql 语句

执行结果,成功插入了一个普通管理员用户:

至于自定义的文件怎么传上去,接着看下去:

这个程序在后台可以设置文件上传的白名单,本以为可以直接添加扩展名,达到任意文件上传的目的,但通过代码审计发现代码中还是对 .php 等扩展名进行黑名单限制:

而且通过代码可以发现,不能上传 .sql 文件。不过这并不影响我们对上一个漏洞的利用,之前的备份功能点是通过 load_file 加载文件内容的,png 等等扩展名也是可以当作文本文件加载的,那么此处便可以利用文件上传功能上传一个带有恶意 sql 的 png 图片文件,具体内容如下:

其中的插入语句是为了添加一个创始人用户,可以达到低权限用户提权到高权限,之后语句是通过 mysql 日志文件进行 getshell。

将文件保存为 png 文件,然后在后台找一处上传点,通过上传功能上传文件:

文件上传成功之后可以看到返回了图片的路径。这样的就可以结合之前的任意 sql 执行,运行我们自定义的 sql 代码了。首先还是看一下上传文件数据包:

其中 uptype 为上传文件类型,upfloader 为文件存储路径,这两个变量会用于控制上传文件扩展名和存储路径。之后我们可以在 upload 文件夹看到上传的文件:

接下来便是完整的利用上面的任意 sql 执行获取创始人权限和 getshell:

结果:多出创始人 admins:

通过 mysql 日志 getshell:

上面的过程忽略了关于文件上传功能点的审计,但是审计过程并没有发现可以任意文件上传,因为通过黑名单的方式,还是过滤了 php 等扩展名,不过 php5,php4 这样的就不在黑名单之类了,其实也可以利用一波。之后还是介绍任意文件上传功能点的发现吧。

漏洞二:任意文件上传漏洞

在审计系统去找关于文件操作的功能点时,突然发现一个有趣的点:ueditor 远程文件下载功能

触发函数在 down_url 函数位置,先来看一下需要传递的参数:

其中 $upfolder 变量存储远程文件下载位置,但是通过 safe_word 过滤,因此无法进行目录穿越

$action 参数用于触发 down_url 函数,可以忽略,另外便是 $source 变量,用于存放远程文件 url,因此应该构造如下的数据包,用于触发漏洞:

当参数传递成功,便进入 down_url 函数,接下来看一下这个函数:

第 890 行规定了文件存储位置只能在 upload 文件夹下,因为之前存在过滤,无法目录穿越。第 891 行到 893 行规定存储的文件名,与远程文件相同。在第 899 行读取了可以获取远程文件的扩展名,然后通过对比当前扩展名白名单判断是否允许写入文件,因此需要通过低权限管理员修改可上传的扩展名白名单。通过上面的扩展名检测,拼接获取文件绝对路径,然后检查文件是否存在,如果存在第 910 行删除文件,之后便是通过 readfile 文件获取远程文件最后写入。还是通过 debug 来跟踪一下参数传递:

获取参数,变量存储的值与分析相同。

之后先传递到 safe_url 进行远程 url 合法性的校验。

之后进入 down_url 函数,参数的传递与上面的解释相同。

下面就是利用这个漏洞了:因为 readfile 函数读取的是文件内容,如果是 php 文件,那么会写入 php 文件运行后的内容,因此首先在远程服务器写入如下 payload:

其中 base64 编码内容解码后如下:

将文件保存为 1.php。此远程文件的完整 url 为:http://127.0.0.1/1.php(需要放在vps)

然后通过之前的构造数据包的方式在本地读取这个远程文件

成功写入文件 1.php

之后前台访问文件便可达到代码执行的效果:

另外在 down_url 函数的位置,根据 $type 变量的值来进行下载文件方法的选取,如果 $type 变量为 1 的话这个地方就还有可能存在 SSRF 漏洞了,不过唯一调用 down_url 函数的地方,没有传递 $type 变量,因此默认为 0。另外就是这个漏洞可以上传自定义模板啦,与上面的猜想组合利用。

0x03 最后的骚话

作为一个代码审计的弱鸡,没能有更多的发现,没有想到更骚的利用思路,审计的技巧方面还有待提高,不过信息安全的男人从不放弃。代码审计一时爽,一直审计一直爽。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 信安之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x01 失败的审计过程
  • 0x02 成功的漏洞挖掘:
  • 0x03 最后的骚话
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档