大约一年前,某校同学学习T大和P大树洞,也开发了一个匿名论坛系统,取名“无可奉告”。其愿景值得肯定,也符合所谓的黑客精神。然而在匿名化以后,人性的丑恶面被无限制放大,论坛一度沦为厕所,让人吃了口大瓜(diao yu)。虽然作为一项社会学实验效果拔群,然而在技术层面,尤其是其核心特征“匿名”来说,这个toy-like的系统是不及格的。

由于《不可抗力因素》,其app和网站均已下线,时间也过去了这么久了,就让笔者好好梳理下小伙伴们是如何从无到有,打穿“匿名”体系,让整个论坛在攻击者面前完全透明的。

本文仅供技术交流使用,本人不提供包括EXP、漏洞详情、数据库数据在内的任何资料!

匿名性是如何实现的

根据开发者原始公告,主要流程大概是验证邮箱、发送验证码、哈希邮箱生成唯一ID,从而达到邮箱(个人身份)和论坛账号的解耦,而且作者特地说明了其采用了加盐哈希来保证安全性并给出了具体例子(划重点)。从理论上来说,这么做的确能保证即使是运营方也无法追踪单个用户的身份(姑且这么认为),而且论坛发帖时会生成一个临时假名,从而避免追踪用户名推断身份等社工行为(也产生了很多有意思的情况,后续说明)。

看上去很美好,不是么?

理想与现实的差距

发布当天晚上小伙伴们就把协议、接口摸清楚了。数学是严谨的,然而工程实现总是充满了妥协。如何验证邮箱地址?一个简单的方法是验证末尾 @xxx 是否为指定域名(他们确实也是这么做的),然而CTF中的奇技淫巧多了去了,大家猜猜 a@xxx@yyy 这个地址最终发到哪里去?由于某个邮件组件的bug,这个地址最终会被发往 a@xxx,然而后端验证却是截取最后一个 @ 来比较的,这样我们在邮箱后面再加一个后缀就可以完美绕过检测了,结合跳板机和一次性邮箱这才是真正的匿名(笑)

至此是当天晚上23点,大家已经分析完接口,攻破了第一道【邮箱验证】防线。

千里之堤,溃于蚁穴

23:30,日常一把梭扫描收获了意外惊喜,某个like查询接口存在sql注入,虽然是time based blind但是也可以打出信息了。大家瞬间高潮了,要知道搞CTF的都是夜猫,正好是亢奋的时候,手绕了绕就能select了,于是乎直接脱裤。

2:00,服务器带宽比较小,脱裤刚刚结束,翻了翻数据库发现作者还是讲武德的,库里确实只存了哈希,具体来说,用户表就是一个哈希(管理员全0)和一个数字(1是管理员),其他表都有一个id指向用户表。

至此,我们已经拿到论坛所有数据,距离透明化很近了。

我即是你

这边由于有两个攻击路径,我们兵分两路,先看这一边。如果我们需要以别的用户登录,由于只支持邮箱验证码,我们必须知道这个值才能登录。

进一步测试发现登录的验证码在输入错误时没有失效(可能是跑飞了),4位数字有效期10分钟,只需要1秒爆10个即可有60%的爆破成功率,用golang写了个并发脚本可以达到200个/s,进一步,由于其服务器架设于腾讯云,我们在腾讯云相同区域开了台服务器内网跑可以达到1000+/s,10秒内即可获取正确的验证码。

此时是凌晨4点,距离透明化只差最后一步。

神来之笔-暴力美学

时间回到凌晨3点,虽然我们已经脱裤获取了邮箱和对应的哈希值,但因为有盐和不同哈希方式的存在如何定位个人成了一个难点。然而黑客总是能在缝隙中挖掘出信息,回过头看开发者的公告,其在解释匿名原理时给了一个例子,通过两次哈希获得唯一ID。而这正是破局所在!我们可以合理的推断出服务器后端也是用相同的方法进行哈希的,唯一的问题就是盐了,考虑到先前对该程序安全性的分析,我们断定开发者采用的盐并不长,利用GPU+hashcat秒秒钟就爆破出相应的盐,果然只有4位数。

接下来依然是暴力美学的时间,由于学校邮箱以个人账户开头,而个人账户仅包含小写字母和数字,枚举空间较低,加上大家手上多多少少都有些数据源,先跑数据源再爆破即可。

第二天20:30,我们匹配出了全站97%的用户,可以近似认为整个站点对于我们已经透明化。

Any more?

攻击时发现了挺多有意思的东西:

  • 奇怪的协议:app所有流量都是通过一个自己写的raw tcp客户端转发的,操作很奇怪。
  • 流量放大攻击:可能是由于爆验证码爆的太狠了(打掉几十块流量),第二天晚上网站就挂了,根据返回估计是流量没了。因此随便找个接口(比如长贴)即可实现经济的流量放大攻击……
  • 乌烟瘴气的环境:根据对用户发帖交叉匹配,我们发现各种搅屎棍、钓鱼人层出不穷,例如某位老哥前个贴还在喷别的女性,后脚就开始重《拳》出击,还有自问自答到处钓鱼就不说了,因此笔者认为这作为一项社会学实验是效果极佳的。

总结

开发者的想法很好,也很有魄力,然而经验欠缺,任何一个微小的错误都可能导致严重的后果。例如我们在48小时(包括爆破时间)内即可注册任意用户、获取所有站点数据、10秒内伪造任意用户登录、建立真实用户与匿名用户的关系、DoS攻击等等行为,可以说是千疮百孔,因此我说这作为一个技术型应用来说是不及格的。

另外大家需要思考,就算这样实现的站点本身没有漏洞,这样也确实是匿名么?

例如raw tcp方式传送数据,网管中心几分钟就可以锁定api特征,进而追踪个人账号,甚至中间人攻击也可以轻而易举地实现,通过简单的抓包即可获取用户JWT密钥进而伪造用户。

例如邮箱服务器log、IP log清楚地建立了用户与哈希的联系(就不说爆破匹配了),整个信任链因此土崩瓦解。

私以为,在目前的技术条件下,或许只有区块链和Tor网络这类去中心化系统才有真正匿名的可能性吧(至于针对这些的攻击就是另一个话题了)!