最新消息:

【转载】继续怼i春秋安全防护——微信端测试

WEB安全 Eternal 1322浏览 0评论

声明,所有演示均为真实环境可实际操作,仅供学习参考和讨论,请勿自行实施攻击,本人不承担任何法律责任。

今年上半年,我花了几个月时间深入测试了各类微信第三方服务(公众号、企业号、小程序),发现的数据漏洞很多,甚至触目惊心。虽然网络安全法出台了,但是企业的安全防护不见得就提高了。就拿微信小程序来说事,据某厂商自己描述:


这款微信小程序叫做群应用,号称几十天就斩获千万用户,在微信小程序里属于明星产品,这款小程序主要干吗用的呢?就是把个人信息、联系方式、公司等存储进去,然后发给别人,方便别人快速保存。经过测试,所有用户信息接口直接对外暴露、加密规则对外暴露,直接导致所有用户数据裸奔。


如上图所示,我们只要知道card_id和aid就能够获取一个用户的详细信息。aid看起来是个加密的数据,正常情况是不能遍历的,保证了安全性。但是他们提供了下面这个接口,传递任意uid即用户id,就可以获取card_id和aid。

至此,千万级别用户数据就这么暴露出来了。话说,商家所谓的千万级用户,我只能呵呵。。。

趁着新兴市场的刚刚开始,只要肯花时间,真的可以手握一堆高危漏洞,因为厂商在新型领域投入的服务,确实安全防护要弱一些。

为什么这么说呢?接下来我们以sql注入为例子,对于sql注入这类漏洞的挖掘,一般情况下,我们首先要找到待测试url地址。

常见的sql注入接口大概长这个样子:

http://test.com/article?id=123
http://test.com/newsList?num=3&limit=20
http://test.com/shop?sort=price

这些url地址,都可以直接丢到sqlmap里面跑,通过修改get/post参数进行注入尝试,攻击手法简单,只要在一边等就可以了。

不过目前大部分网站都提高了安全性,让攻击者无法进行sql注入,方法有很多,比如:

1. 阿里云云翼计划网址,参数不能够随意更改。
https://promotion.aliyun.com/ntms/campus2017.html

2. i春秋的某篇文章,这里用到了伪静态页。
https://bbs.ichunqiu.com/thread-24693-1-1.html

3. csdn新闻页,参数进行了数字类型强制转换。
http://geek.csdn.net/news/detail/211237

对于网站而言,这一层保护很重要,提高了安全门槛。那么对于攻击者而言,有没有什么更好的思路呢?

本篇文章,将会给大家介绍一种方法————从微信端进行sql注入攻击

这种方法,是建立在移动互联网趋势下的。随着移动互联网的发展,大部分互联网产品都不再提供单一的网站服务,产品往往涵盖了移动端APP、移动端web站、微信公众号、小程序、微信/支付宝企业号等,对于企业级产品可能还会作为应用投放到某个平台,比如钉钉平台。程序员在开发以上这些互联网服务时,就没办法像网站那样做同样的安全防护。传统网站的页面可以直接由服务器渲染,将数据接口隐藏起来;但是像APP和微信小程序这类应用服务,数据是通过调用api接口进行获取,这些接口本身必须暴露给客户端。

好了,我们拿i春秋作为演示。(为什么拿i春秋做演示?因为是真爱。)

这是i春秋在微信客户端的展示页面

https://wx.ichunqiu.com/m/course … mp;isappinstalled=0


手机连接到burpsuit进行抓包,整个网页的请求包如下:


通过burpsuit抓包分析,我很快找到了api的请求接口:

https://api.ichunqiu.com/rest?ap … amp;_=1500362196997

将这个url地址进行copy,然后在浏览器进行输入,得到了这么一个页面:

上图说明,i春秋获取数据的接口做了时间限制,超过一段时间,就会返回请求时间无效。也就是说,每次调用这个api接口,都要使用当前最新的时间。没办法,再次抓包,并快速拷贝url地址到浏览器访问,确保时间不失效,最终浏览器显示数据是这样的:


我们再深入分析一下这个接口,还可能有哪些其他限制?在这里,我随意修改了某个get参数,请求如下,提示签名错误:

分析到这里,基本可以得到一个结论:

i春秋的api接口,做了时间限制和签名限制,修改任意参数,都会导致此api接口无法正常运行。

像这种情况,如果我们直接把url地址丢给sqlmap来跑,肯定会失败的,所有请求直接被拦截在时间和签名判断处了,根本没有走到执行数据库这一步。对于小白黑客而言,时间失效这个问题容易搞定,但是签名怎么破,最终只能白白浪费时间去跑sqlmap没有结果,或者直接放弃此处sql注入。

这时,请大家回想一下我最上面提供的案例,其实有一个结论:

当加密规则本身暴露给攻击者时,加密机制再强,也形同裸奔。

没错,我会试图寻找i春秋api接口的加密规则。根据url地址,https://api.ichunqiu.com/rest?ap … amp;_=1500362196997,GET参数有这么多。

  • app_key——app的标识。
  • datetime——时间,用于判断时间有效性。
  • from——来源。
  • id——获取数据的id值,不同id获取不同数据。
  • method——api方法名,此为获取课程列表,还有其它方法比如open.course.info.get,open.course.comment.get等,通过字面意思就能知道接口是干嘛的,i春秋接口还是蛮人性的。
  • timestamp——时间戳,和datetime保持一致。
  • type、ver——这两个参数,目测用处不大。
  • callback——这个关键词,第一反应就是JSONP,看了返回body,确认就是JSONP。
  • sig——重点!只剩下sig了,看名字八九不离十,这个参数就是签名参数。

除了sig,其它所有参数都比较容易构造,只要知道sig的计算方式,那么就能够模拟api发起请求了。

这里吐槽一下i春秋,时间参数不够严谨,如果我选择一个非常大的时间,就可以一直不失效了。还有,我直接加字母,依旧可以,说明程序进行强制类型转换了,如果是我,只要不符合规范,直接出错,而不是进行强制类型转换,避免因为强制类型转换导致一些攻击绕过。

祭出一个nb的,不会被防住的值(哈哈哈):

timestamp=’1501223421312310a’

sig计算规则怎么找?

还记得burpsuit抓包么,除了api接口,其实我们还抓到了几个js文件,我们从js文件里面找。

既然我们知道sig就是签名,那么就需要通过sig进行查找。

前往每个js文件进行关键字搜索。


js文件地址:

http://wx.ichunqiu.com/m/courseS … 0.11729205804666631

果然,搜索到了sig,但是这代码看起来太恶心,明显被压缩了。在这里强烈推荐一款神器————Pretty Beautiful Javascript

Chrome插件——Pretty Beautiful Javascript,可以让js展示的更美观清晰,利于攻击者分析被压缩的js源码。

js进行美化之后,我们可以发现sig的加密规则,可以看到,不同的method(api方法),sig加密是有区分的,找到我们需要的加密方法:


这是加密的代码:

function fn_courseListDataAjax() {
    var e = "";
    Date.parse(new Date), (new Date).pattern("yyyy-MM-dd hh:mm:ss");
    e += app_key, e += "method=open.course.list.get&", e += app_from, e += ver, e += timestamp, e += dateTime, e += "id=" + GetQueryString("id") + "&", e += "type=" + GetQueryString("type");
    var t = e.split("&").sort().join("&"),
        i = $.md5(t + "&612e9a2ebe762486d04eb29411344769");
    $.ajax({
        url: host + t + "&sig=" + i,
        type: "GET",
        dataType: "jsonp"
    }).done(function(e) {
        $("#videoPlay").attr("src", e.data.chapter_list[0].course_list[0].course_play_url), fn_foundElementByChapter(e)
    }).fail(function() {
        console.log("网络异常,请稍后重试")
    })
}

到目前为止,所有参数我们都基本清楚了,现在就是如何把这个规则应用到sqlmap了,我们需要使用–eval参数。
参数:–eval

在有些时候,需要根据某个参数的变化,而修改另个一参数,才能形成正常的请求,这时可以用–eval参数在每次请求时根据所写python代码做完修改后请求。

例子:

python sqlmap.py -u “http://www.target.com/vuln.php?id=1&hash=c4ca4238a0b923820dcc509a6f75849b” –eval=”import hashlib;hash=hashlib.md5(id).hexdigest()”

上面的请求就是每次请求时根据id参数值,做一次md5后作为hash参数的值。

出于安全起见,i春秋api接口的sqlmap命令,就不在这里给大家展示了。

不过给大家说一个注意事项,关于–eval参数的使用,sqlmap最新版本还有一个bug。

一般情况下,sqlmap这个bug极难触发,但是i春秋API接口本身的特殊性,导致这个bug真的就触发了!!!因为在测试的时候,出现了诡异的失败,才发现了这个bug。

对i春秋API实施攻击的sqlmap eval内容大致如下:

–eval=”import hashlib;str=’app_key=’ + app_key + ‘&datetime=’ + datetime + ‘&from=’ + from + ‘&method=’ + method + ‘×tamp=’ + timestamp + ‘&url=’ + url + ‘&ver=’ + ver + ‘&612e9a2ebe762486d04eb29411344769’;sig=hashlib.md5(str).hexdigest()”

因为i春秋的get参数是from,所以eval执行的时候有这么一句:
‘&from=’ + from

而python语言里,from是关键词,不能直接这么用的,会导致程序异常,所以作者增加了一个非常赞的解决办法。这个解决办法,专门用来解决参数中使用import、from等参数时,避免抛出异常,并保证程序正确执行。
代码在lib/request/connect.py文件的,大概980多行到1000行之间:

sqlmap源码大概思路是:

  1. 首先将所有参数存入字典,以k=》v形式存储,并将k值是关键字的如from,改成from_KEYWORD。
  2. while True语句,会将eval语句通过分号进行切分。
  3. 不断执行每一句切分的语句。
  4. 当某一语句执行失败时,如果是因为关键字问题导致的,将语句中所有关键字增加后缀_KEYWORD。
  5. 重新执行此语句。

而i春秋API这个例子,可以产生程序异常的语句是:

‘&from=’ + from

sqlmap会将这句话直接转换,变成’&from_KEYWORD=’ + from_KEYWORD,最终执行sqlmap -v4 输出详细信息,你会发现,所有get参数from都被莫名其妙地替换成了from_KEYWORD,当然无法对i春秋实施攻击了。

临时解决方案,将语句拆分成两个:

temp = ‘&from=’
temp += from

目前,我通过github给sqlmap作者提交bug修复代码,作者还没同意合并,所以大家在使用时候注意一下。

最后,针对i春秋的测试,附上一点个人建议:

  1. sig加密规则避免在js中出现,否则防护达不到预期效果。
  2. 如果一定要在客户端加密,加密关键字不使用sig等明显单词,可以使用a、e等词,这种词在代码搜索时非常困难,直接提高了攻击者搜索的难度。
  3. i春秋api接口的时间判断存在问题,如果选择一个非常大的时间,那么就永不失效。
  4. 参数有做强制类型转换,如果传递的时间戳。
  5. i春秋API接口支持JSONP,而JSONP在使用中,并没有对refer等做白名单限制。那么,作为攻击者,可以通过JSONP进行意想不到的攻击。

关于JSONP的威力,可以参考我之前写的一篇文章:利用jsonp原理精准定位约炮需求用户

原文地址:https://bbs.ichunqiu.com/thread-24918-1-1.html

转载请注明:即刻安全 » 【转载】继续怼i春秋安全防护——微信端测试

您必须 登录 才能发表评论!

合作伙伴