原文链接:漏洞挖掘-从任意文件读取漏洞到获取账户利用
正文开篇 大家好,我是承影战队的v1ct0ry,这次我为大家分享一次比较有趣的漏洞挖掘经历。这次挖掘过程是以灰盒挖掘为主要思想进行展开,不熟悉的读者可以阅读上篇文章熟悉一下。 一、任意文件读取 开局我们通过扫描器获得一个任意文件读取漏洞,并且可列目。我们来看下代码当中的漏洞点:
这里对传入的参数filename未做任何过滤,可直接进行文件读取。 1.1思考 那么通过任意文件读取漏洞我们都可以做什么?
这里我进行了以下五种操作,来帮助我们进行下一步的漏洞挖掘。
(1)、查看用户历史命令 - /home/mbs/.bash_history
(2)、查看配置文件 -根据历史命令找到安装目录,查看conf文件
/opt/choice_install.sh
(3)、获取应用源码 -到安装目录下查看是否遗留安装包在服务器上
(4)、查看日志 -寻找登录相关信息 - /var/log/uusafe/mbs
(5)、数据库备份文件 -查看服务器是否存在数据库备份情况 - /db/
二、获取加密方式 当我们通过任意文件读取漏洞,读取到以上相关信息时,我们会发现以下几个问题:
问题1、日志当中的密码都是加密过的
问题2、存在Authorization认证字段,无法修改数据包进行爆破
问题3、数据库备份文件当中存放的密码为MD5加密,不能全部解密。
那么我们该如何解决前两个问题呢?我们有了源码后是否可以寻找到加密方式呢? 2.1打开源码,尝试寻找加密方式 我们在源码中找到ThreeDes这样一个类,在这里我们可以看到其加密算法。
其中,为3DES加密,加密模式为CBC模式,填充方式为PKCS5,在这里我们可以找到Key为 uus*********fe。
在加密过程实现代码中,我们可以找到偏移量iv=01234567。
2.2验证加密方式是否正确 首先我们找到登录接口,输入账号密码 admin/admin,获取到如下数据包:
将密码参数放入在线平台进行解密。
当我们成功解密后,能做的事情就多了起来。
(1)可以将日志当中加密后的密码进行解密,从而登录系统。
(2)可以尝试构造Authorization请求头,从而进行数据包重放。 三、请求伪造 3.1思考 首先我们根据日志了解到,这是一个移动客户端发起的请求,并且请求方式是HTTP请求,那么我们是否可以在没有移动客户端的情况下,使用BP构造请求包,从而请求一些移动客户端的接口来获取敏感信息呢?
我们尝试对整个数据包进行构造,构造中最重要的就是Authorization请求头。因为服务端中,是根据Authorization来进行身份校验的。目前我们已经知道了加密方式,那么是否直接对日志当中的Authorization进行加密就可以了呢? 3.2验证 接下来,先对日志当中的Authorization进行加密:
然后构造数据包如下: 构造成功登录。 3.3猜想 那么我们尝试利用构造好的Authorization字段访问其他接口呢?
在日志中,我们在日志当中随意找个请求,尝试用我们伪造的Authorization字段进行访问:
这时我们看到,响应报错了,哪里出了问题呢?大概率是Authorization字段当中还有其他校验。我们再一次对Authorization进行一个详细分析,解密后的Authorization如下:
0 | iOS | 59072CB6-CFEF-4240-AF40-94E780A75920 || 1667415571677 | 1.0.0 | zjrcu_zhgl | 1 | 0 | 765006618b248c408a54e1fe2bccb190
那么我们对其中每个字段和日志信息进行对比分析,大概可分析为如下:
userid | 设备类型 | securityId || 类似时间戳 | 客户端版本| org_code | 1 | 0 | 未知
最后一个字段我们无法根据日志匹配对其进行判断,那么我们可以根据一些密码学特征来猜测:长度32位,为字母和数字混合,这时我们会很容易想到 MD5加密。那么这里的MD5加密前的明文是如何选取的呢,是时间戳和盐值加密吗?
我们只能够根据现有的线索来进行猜测,这里其实可以调试代码来进行判断,但是项目无法直接运行,无法调试。 3.4构造请求 通过修改数据包、请求不同接口等不同方法的不断尝试,总结如下:
现象:我们只要更改数据包当中的任意字节,无论是添加、删除、修改,都会报错。
结论:加密内容和请求体内容有关。
这里的答案:经过验证, MD5加密前的明文为 请求体所有内容整体MD5值加密。
下图是经过再次构造后,请求成功的截图:
我们在日志当中找到个组织架构接口,开始构造数据包:
(1)首先对请求体进行MD5加密:
(2)对日志中Auth头中的MD5字段进行更改
由原来的:
0 | iOS | 59072CB6-CFEF-4240-AF40-94E780A75920 || 1667415571677 | 1.0.0 | zjrcu_zhgl | 1 | 0 | 765006618b248c408a54e1fe2bccb190
更改为:
0 | iOS | 59072CB6-CFEF-4240-AF40-94E780A75920 || 1667415571677 | 1.0.0 | zjrcu_zhgl | 1 | 0 | 3793020c3c29c73d037ebfab2a077908
(3)再次进行3DES加密:
(4)构造请求包如下,成功访问:
四、任意文件上传 在我们获取到账号密码后,我们可以登录到系统后台:
在后台的功能点中,我们注意到这样一个位置:
可以上传apk文件等。
其请求数据包如下:
4.1分块传输 这里上传大文件采用的是分块传输的方式,整体请求的数据包如下图:
首先分块传输文件,分块传输完成后,再请求uploadblockfilecomplete接口。
Tip:
我们再来巩固了解一个小技巧:https://www.freebuf.com/vuls/353646.html。
一个漏洞成因会有基本的两个要素点:外部可控参数 (Source点)+ 风险函数(Sink点),source和sink之间可以形成一个完成的流时,就会产生一个漏洞。
该应用系统采用的是微服务架构,我们根据请求的接口位置找到相应的jar包,进行代码审计,看看其业务逻辑是怎样的:
找到其代码位置后,看下其核心上传代码:
(1)、传入filecode
(2)、传入blockid
(3)、传入blockmd5
(4)、保存路径:savepath = orgcode + / +filecode + /block/ + blockid + _ +blockMd5
那么对应的,source点:filecode、blockid、blockmd5,sink点:savepath
这里就很可能会存在一个漏洞,我们再来看下uploadBlockFileComplete这里发生了什么?
从代码逻辑看来,对我们有用的信息就是:当我们上传的文件完成时,他会校验文件MD5和大小等,如果不符合,则删除该文件。
那么当数据包请求到这里时:
我们将uploadBlockFileComplete请求包丢弃即可,接下来我们开始构造数据包: 从上图的代码中我们可以看出,参数传入的地方为TransferParam,并且进行base64加密,我们找到请求包当中的该字段:
并对其内容进行解密:
这里我们发现,并没有 blockmd5 参数,那么我们是否可以在请求包中添加该参数呢?因为我们在代码中已经确定在拼接保存路径时,会使用到该参数。 4.2构造数据包 (1)这里我们尝试构造如下内容
filecode : /../../../../../../../../../../home/mbs/mbs/dist/build
blockid : 0
filesize : 不变
blockMd5 :文件后缀(1.html)
(2)最终保存如下
savepath = orgcode + / +filecode + /block/ + blockid + _ +blockMd5
savepath = orgcode + / +/../../../../../../../../../../home/mbs/mbs/dist/build + /block/ + 0 + _ +1.html
savepath = /home/mbs/mbs/dist/build/block/0_1.html
(3)漏洞证明
我们构造如下请求包:
在请求到uploadBlockFileComplete数据包时,将其丢弃,即可完成上传。
可以看到,成功上传并可访问。 五、总结 大家可以发现,有许多影响范围广、影响力大的漏洞最初都是从一个不起眼的小漏洞开始被深入挖掘的。也许挖掘0day并不像大家想象的那么困难,只需要我们留意观察漏洞挖掘过程中的不起眼的小漏洞,并深入研究,往往会有意想不到的收获。
|