目录
一、实验环境
<?php
header('X-XSS-Protection: 0');
$xss = isset($_GET['xss'])? $_GET['xss'] : '';
$xss = str_replace(array("(",")","&","\\","<",">","'"), '', $xss);
echo "<img src=\"{$xss}\">";
?>
二、实验要求
通过注入当$xss所接收到的图片发生错误时,通过 οnerrοr=alert(1) js函数触发报错信息生成弹窗显示数字1。
三、实验步骤
3.1 环境代码分析:
1.注入的主要思路是通过 get 函数获取错误$xss信息触发报错从而通过echo函数完成弹窗显示1。
$xss = isset($_GET['xss'])? $_GET['xss'] : '';
echo "<img src=\"{$xss}\">";
2.$xss信息通过 str_replace 函数将"(",")","&","\\","<",">",“ ' ”符号替换为空,其本质就是进行了符号的过滤。(注入的主要难点)
$xss = str_replace(array("(",")","&","\\","<",">","'"), '', $xss);
3.2 注入
3.2.1 第一次注入(直接注入)
语言
http://127.0.0.1/css/demo.php?xss=aaa%22%20onerror=%22alert(1)
# %22为 " 经过url转码后的结果
# %20为空格经过url转码后的结果
注入结果:
失败
失败分析
优点:
逃出了双引号的限制:xss=aaa"与οnerrοr="alert(1)中的双引号分别与源码中的双引号组成了两对双引号。
理想接收到的语句:(imgsrc="xss=aaa"οnerrοr="alert(1)")前后两个双引号为环境语句中自带的双引号,中间两个双引号为注入语句中后写入的双引号。
缺点:
没有绕过符号“()”的过滤
原因:真实接收到的过滤后语句:(imgsrc="xss=aaa"οnerrοr="alert1")由于alert函数缺失了()导致注入失败。
3.2.2 第二次注入
语句
http://127.0.0.1/css/demo.php?xss=aaa%22%20onerror=%22alert%281%29
# %22为 " 经过url转码后的结果
# %20为空格经过url转码后的结果
# %28为 ( 经过url转码后的结果
# %29为 ) 经过url转码后的结果
注入结果:
失败
失败分析:
优点:使用了url转码将“( ” 转码为%28,将“ )”转码为%29,试图绕过函数过滤。
缺点:真实接收到语句:(imgsrc="xss=aaa"οnerrοr="alert1")括号依然被过滤。
原因:浏览器的url地址栏会自动识别一次转码后的url编码,既将%28、%29在程序运行前直接又转化回(),然后被过滤函数所过滤。
3.2.3 第三次注入
语句
http://127.0.0.1/css/demo.php?xss=aaa%22%20onerror=%22alert%25281%2529
# %22为 " 经过url转码后的结果
# %20为空格经过url转码后的结果
# %28为 ( 经过url转码后的结果
# %29为 ) 经过url转码后的结果
# %25为 % 经过url转码后的结果
注入结果
失败
失败分析
优点:希望通过url的二次转码在浏览器的url地址栏中将%2528、%2529转码为%28、%29不被过滤函数识别的进入程序,之后再在随后的进程中转码为(),保留()到alert函数中执行实现注入。
缺点:
真实接收到语句:(imgsrc="xss=aaa"οnerrοr="alert%281%29")进出程序()都是以%28、%29的形式进行保留未被进一步转码,alert函数依旧不能执行。
原因:onerror为js函数且在js函数中规定不能对符号进行编码,所以onerror函数不认可被编码后的()。
3.2.4 第四次注入
语句
http://127.0.0.1/css/demo.php?xss=aaa%22%20onerror=location=%22javascript:alert%25281%2529
# %22为 " 经过url转码后的结果
# %20为空格经过url转码后的结果
# %28为 ( 经过url转码后的结果
# %29为 ) 经过url转码后的结果
# %25为 % 经过url转码后的结果
# location函数:可以将所有的值变为变量
# location=javascript: location通过javascript的伪协议可以将值变为变量
注入结果
生成弹窗且显示1 注入成功
注意:这里的location函数在调用时会自动生成一对双引号
成功分析
1.通过url的二次转码在浏览器的url地址栏中不被识别为()的情况下,以%28、%29的形式进入到程序中。
2.由于onerror为js函数且js函数中不认可被编码后的符号,但依就认可变量,所以()以%28、%29的形式进入程序后,使用 location=javascript: location通过javascript的伪协议可以将值转变为变量,又将()编码后%28、%29转化为变量,再通过js函数对变量的编译将其转码为(),才能成功进行注入。