http://p6.qhimg.com/t0127b72702b9c2dab7.jpg


写在前面


本人学习渗透测试(主要是Web方向)有几个月了,现在算是刚刚入门。回想起学习漏洞挖掘的过程,除了看一些经典书籍外,最想看的就是大牛们挖漏洞的详细过程,比如如何寻找目标,从哪里入手,遇到问题怎么解决。但是,网上介绍知识的多,叙述过程的少(也可能是我的搜索姿势不对……)。除了在乌云上有几个大神有时会分享一些具体的挖洞思路外,大部分人还是“有图有真相,一图胜千言”。对于老司机来说,瞄一眼就知道是怎么回事了,但对于新手来说,往往是一头雾水。因此,本人分享一下最近的一次挖洞过程,希望能够抛砖引玉,大家踊跃分享自己的挖洞经验。

PS:作为一个有操守的白帽子,本文重在分享思路与过程,细节处还是要打码处理,毕竟不是来提交漏洞的。


寻找目标


这次是针对我常用的一个手机APP(下文简称:某APP)进行漏洞挖掘,说起来选择某APP作为目标也是挺偶然的。因为我主要是搞Web渗透测试的,并没有挖过手机APP的漏洞。有一天,在看别人分享Burp Suite的使用技巧的文章时,发现通过Burp还能够进行手机APP抓包(毕竟Too young……)。光说不练假把式,还是要自己动手操练一番。先把Burp设置一下,在Proxy中Options下的Proxy Listeners中,点击Edit,把Bind to address设置为All interfaces。

t019d5f807f3f6a25be.png

然后手机和电脑处于同一局域网中,给手机设置代理服务器,IP为电脑的IP地址,端口为Burp中的设置的端口,默认为8080。这时候,就可以用Burp抓取手机的请求包了。


山重水复


这时候我就打开某APP,执行常见的操作,Burp中就记录了大量的HTTP数据报文。然后,就是对Burp中截获的报文进行分析了。没多久,一个请求就引起了我的注意。这是一条GET请求,请求的URL是类似下面这种格式:

1
http://www.example.com/path/get_some_data.jsp?id=1234567&param1=value1&param2=value2

直觉告诉我,这里很有可能会有越权漏洞。于是,我用浏览器打开这个URL,果然直接就看到了用户数据。换个id再试一下,把id加1,结果也是一样的,都爆出用户数据了。因此,到这里已经确定某APP存在越权漏洞。

确定这个越权漏洞存在后,稍微平复一下心情,然后就发现这个漏洞造成的后果并不严重。因为这里通过帐号越权查看到的用户数据中,并没有包含一些比较敏感的数据,比如姓名、手机号、身份证等。简单地说,就是可以越权查看到他人的数据,但是“他人”是谁并不知道,这样来说看到数据只是一堆无意义的数字而已。只钓到一条小鱼有点不甘心,于是就继续挖,应该还有其他的漏洞存在。

继续查看Burp捕获的报文,这次重点查看登录过程中提交的请求和返回的响应,想从这里入手深入挖掘一番。登录的报文如下,可以看到,只有一个POST参数params,其值经过了URL编码。

t015ebd125eec2ef1eb.png

把params的值解码之后,发现是json格式的一串数据,基本内容如下:

t016be5ab3074aa9409.png

其中,让人感兴趣的就是userId字段和body字段了,目测应该分别对应登录的用户名和密码。然后我用相同的用户名和不同的密码、不同的用户名和同样的密码分别登录、抓包,然后解码对比发现,相同的用户名对应的userId值相同,相同的密码对应的body值也相同,这就证实了我的推测。进一步分析发现,userId和body的值都是十六进制的数字串,userId的长度为32位(这里指32个十六进制字符,下同),body的长度为128位。这就说明userId和body的值都经过了加密处理。对于userId,我首先想到是不是经过了MD5?不过经过计算用户名的MD5和userId并不相等,也就是说,即便是MD5也加了salt。

分析到这里,暂时没办法继续深入了。那就先放一放,分析一下登录过程中返回的数据包,下图是登录成功之后返回的数据包。

t014c6922ec02f2b8df.png

一看返回的数据包直接傻眼了,明显是经过加密的。不过,这里还是要注意一下返回的数据包长度,因为我故意输入错误的密码进行登录时(如下图所示),返回的数据包长度居然相差无及!并且也能看到,有许多相同的字符。很显然,这里有很大的可能是有问题的。

t01a88a6dd1e58a7ddd.png


柳暗花明


到目前为止,虽然已经把登录过程中的请求报文结构都分析清楚了,但是由于报文中的关键数据都进行了加密处理,所以到现在几乎仍然是一筹莫展。事实上我在这里卡了两天,也没什么好的办法,甚至还想到过分析一下别人帐号登录过程中的数据包然后破解出密码的想法。不过仔细一想就觉得这个想法太不现实,又不是密码学专家,仅仅通过几条密文就想破解加密过程,这怎么可能成功!尽管想法有点荒唐,但是还真给我带来了灵感:既然某APP发送的报文和返回的报文都是加密的,那肯定是在某APP中进行了加密和解密的操作,那么如果能够分析一下某APP的源码,应该就能够搞清楚其中的加解密过程。那么问题来了,哪里能得到某APP的源码呢?

思来想去,最方便、最有可能的办法就是将某APP进行反编译得到源码。ios版的我就不想了,毕竟也没搞过ios开发,直接去逆向肯定是不现实的。但是安卓版的还是有搞头的,因为之前看过别人进行APK逆向的文章,也写过Java代码。说干就干,网上搜一搜安卓逆向教程一大堆,毕竟咱只是想分析源代码,并不是要搞脱壳破解,入门级的教程就能够满足要求,这里就不多说了。总之,将某APP反编译之后,发现代码进行了混淆,但是并不影响分析,稍微费点劲而已。经过分析,果然有收获。

首先,发现加解密使用了AES算法,并且加解密所用的密钥是16位的。

http://p3.qhimg.com/t010205c8208b9b64d0.png

继续分析发现,开发人员居然把密钥“几乎”硬编码在代码中!密钥总共16位,前面几位是网站域名,再加上devId的前几位,凑够16位即是密钥。而devId在登录的请求包中是以明文出现的,这样一来,相当于加密算法和密钥我们都得到了。

t0174fa117ee629362f.png

到目前为止,分析的过程基本上就已经结束了,是时候写代码验证一下分析结果了。用Python写了AES加解密的代码,将userId和body进行解密之后发现,userId果然就是登录的用户名,而body的值则是如下json格式的字符串:

http://p6.qhimg.com/t017ef34676b7ddbda2.png

很明显,password的值也经过了加密,这里有可能就是计算了MD5,不过有可能加了salt。继续分析源代码,找到了对密码进行处理的过程,果然是加了salt的MD5!并且,salt也是硬编码……

http://p7.qhimg.com/t019eeb7311e7172cdf.png

拿自己的密码进行验证,证实了上述分析。


意外惊喜


到现在为止,已经可以伪造数据包进行模拟登录过程了。事实上,我最初的想法也是想伪造数据包模拟登录进行暴力破解的。不过,在进行暴破之前,还是先把返回的响应报文解密看看。按照之前的分析,返回的报文肯定是有问题的。

将响应报文解密之后,果然带来了更大的惊喜!前边已经提到,登录成功返回的数据包长度和失败时返回的数据包长度很接近,解密之后发现,何止是长度接近,内容也有九成是一样的!当然,这都不是重点,重点是不论登录是否成功,都返回了用户的真实数据,包括姓名、手机号、身份证号以及正确密码的哈希值,密码完全就是形同虚设。不枉费我一番心思,总算钓到大鱼!


总结


漏洞挖掘的过程基本上结束了,之后提交漏洞的过程我就不废话了。整个过程写起来有点像流水账,但是却把我挖掘漏洞的过程和思路写清楚了,总结起来就是:

多看多想多动手实践,有事没事多抓包分析

Web方面的挖洞思路和软件逆向相结合,带来意想不到的惊喜

不要总想着暴力破解,那是没有办法的办法

最后,希望此文能够抛砖引玉,大家都能把自己的挖洞思路分享出来。挖漏洞有时候确实需要一点灵感,多学习一下别人的挖洞思路,肯定能够对自己有所启发。



本文由 安全客 原创发布,作者:三思之旅