导语:我决定在黑客马拉松期间保持专注去做一个分析,并及时完成我的目标,我只会寻找开放的重定向漏洞。

布鲁诺这位伙计整理出了一个基于Flask (Python Web框架)框架开源Git存储库的CSV文件,其中有547个是可以确定有效的,有66个在下载的时候有问题(可能已经被删除),所以我只克隆了481个比较独特的开源存储库。

我决定在黑客马拉松期间保持专注去做一个分析,并及时完成我的目标,我只会寻找开放的重定向漏洞。开放式重定向漏洞是指你可以向某人发送某个链接比如:

https://chase.com?next=http://evil.com,https://chase.com?next=%68%74%74%70%73%3a%2f%2f%77%77%77%2e%65%76%69%6c%2e%63%6f%6d而这个恶意网址指向了一个钓鱼页面。我之所以选择开放重定向漏洞作为我分析的一个bug的类别是因为根据我的个人经验,这种漏洞所涉及的第二节点比较少。例如

@app.route('/login/authorized')
@facebook.authorized_handler
def facebook_authorized(resp):
    next_url = request.args.get('next') or url_for('new_paste')
    if resp is None:
        flash('You denied the login')
        return redirect(next_url)
    # ...

我所说的“第二节点”的意思是arg参数通常被检索后传入redirect()函数,不会被传递到另一个函数中,或者被用在别处的任务中。这使得它们更容易通过静态分析的方式找到,因为可以出错的事情比较少。

为了评估这个工具,我需要知道哪些Git存储库存在这种漏洞,所以我把我的垃圾黑客技巧用上了,并写了两个正则表达式。".*redirect([a-zA-Z0-9_]+).*"和".*redirect(request.*).*"。第一个正则表达式检测的是把一个变量作为唯一的参数的任何重定向调用,第二个检测的是把request.anything作为第一个参数的任何重定向调用。这些检测规则并不是很完美,但是很有可能检测到90%的可能有漏洞的函数调用。(该CSV文件有一个控制器文件与每个存储库相关联,每个正则表达式会针对每一行运行)。

同上上面的规则匹配,缩小到了20个存储库,大约占总数量的4.1%。第一个正则表达式匹配到了17个,第二个匹配到了3个。[2]

几个不错的检测结果:有4个是准确检测的结果,尽管它们中有3个是在@twitter.authorized_handler或@facebook.authorized_handler控制器中(用于OAuth)。唯一值得注意且首先要说明的一个检测结果是,这个检测结果是由Flask的创建者所编写的代码。

·  mitsuhiko/flask-pastebin 报告了5个漏洞, 第1, 2, 3个本不是漏洞但是工具分析后却误报为未知漏洞 (这是由于我们一开始并没有要检查url_for的返回值是否已经被污染这种情况 ) 第4,5个是真实存在的漏洞,工具也准确检测到了这两个漏洞。

·  ashleymcnamara/social_project_flask 2 个漏洞,工具全部检测到了。

·  fubuki/python-bookmark-service 1个漏洞,工具全部检测到了。

·  GandalfTheGandalf/twitter 2个漏洞,工具全部检测到了。

几个一般的检测结果:有7个存储库没有任何漏洞,我们的工具也没有产生任何检测报告。

·  gene1wood/flaskoktaapp

·  lepture/flask-oauthlib

·  sijinjoseph/multunus-puzzle

·  AuthentiqID/examples-flask

·  honestappalachia/honest_site

·  jpf/okta-pysaml2-example

·  ciaron/pandaflask_old

几个不太好的检测结果:4个没有真正存在漏洞,但我们的工具有一个或两个误报。

· billyfung /      flask_shortener 2个误报(使用.get源代替request.args.get等此类因懒惰导致的错误,所以redis.get被用作了检测的source。)

· ZAGJAB /      Flask_OAuth2 1个误报(开放重定向需要定制,以消除所有的误报,因为如果在字符串格式化中使用了某些被污染的东西,通常需要在字符串的最开始处就存在漏洞)。

· amehta /      Flaskly 1个误报

· mskog /      cheapskate 1个误报

不是很理想的检测结果:2个漏报。

·   oakie/oauth-flask-template 

·   cyberved/simple-web-proxy 

及其错误的检测结果:3个PyT的崩溃问题,但运气还算不错,我看了下不存在任何开放式重定向漏洞。其中第2个或第3个是上周末通过PR合并造成的。

·  commandknight/cs125-fooddy-flask 

·  bear/python-indieweb

·  ubbochum/hb2_flask 

最后,这些结果对我来说似乎没有不对,因为一旦GitHub的issue解决了这些问题,我们就没白做这次漏洞分析。这个评估当然没有找到所有的漏洞,但我们可能已经找到了大部分这种漏洞。下一次我评估这个工具时,我想我会寻找命令注入漏洞或者SSRF这类漏洞。我认为唯一要做的就是评估一个像这样的工具,你应该使用正则表达式来缩小你的时间分析的范围。我将在PyT 的存储库中发起一个PR来说明我在寻找重定向漏洞的过程中做了些什么,但是它大部分做的事情是修改了sink 列表中的redirect然后从source 列表中删除了form。

大约在2016年5月或之前

原始的文章撰写期间,PyT当时在6个或7个开源项目上进行了分析,没有发现任何漏洞。我认为可能是样本量太小了。

[1]

在CSV文件中有一些提交是删除了一些有问题的存储库,但这些提交是很久以前的了,只是要注意下统计的公正不是100%。

[2]

正则表达式是不完全正确的,如果匹配到了第二个正则表达式我会删除检测结果".*redirect(request.url).*"和".*redirect(request.referrer).*"。

源链接

Hacking more

...