BabyPHP

在这里插入图片描述
扫目录发现源码泄露,访问/www.zip

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
upload.php

$dst = '/var/www/html/不告诉你';
$fileinfo = array($_FILES["file"]["name"],$dst);
if (file_exists("$fileinfo[1]/$fileinfo[0]"))
{
echo $fileinfo[0] . " has already existed :)";
}
else
{
$cat->data=$fileinfo[0];
$cat->upload_check();
move_uploaded_file($_FILES["file"]["tmp_name"],"$fileinfo[1]/$fileinfo[0]");
$msg="file name:%s";
foreach($fileinfo as $key => $value)
{
$msg = sprintf($msg, $value);
}
echo $msg;
}

上传路径$dst放在了$fileinfo[1]中,想要foreach输出上传路径就要让$fileinfo[0]包含字符串%s,从而在第二次循环中输出路径
在这里插入图片描述
注释中有提示<!-- /var/www/html/******blablabla******/cat.php -->
合理猜测路径为/var/www/html/y0u_wi1l_n3v3r_f1nd/cat.php,由于cat.php没用给出源码,在注释中可以看到
在这里插入图片描述
可以猜测cat.php的源码是用vim来恢复得到,访问/.cat.php.swp得到临时文件,再用vim -r恢复一下就可以得到源码

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
<?php
error_reporting(0);
include('../waf.php');

session_start();
if(!$_SESSION['islogin'])
{
die('?');
}
else
{
echo "<h4 align='center'>Hello</h4>";
$a=new waf();
spl_autoload_register();
if(isset($_COOKIE["filenames"]))
{
$a->data=$_COOKIE["filenames"];
if(strlen($a->upload_check()) <= 8)
{
$filenames=unserialize($_COOKIE["filenames"]);
}
}
else
{
$filenames='test.test';
file_put_contents($filenames,' test');
}
}
?>

<!-- yep, I need to learn vim. -->

审计代码可知spl_autoload_register();可以自动加载未定义的类,而后面又有filenames参数的反序列化,可以先上传恶意文件,再用反序列化读取,触发恶意代码,spl_autoload_register();支持的文件类型有.inc和.php,由于文件上传处php被ban了,所以只能上传inc文件,再用反序列化去触发,可以先传一个phpinfo探路
在这里插入图片描述
想要反序列化就必须满足传入的参数小于8位,原本的O:1:"p":0:{}可以缩减成O:1:"p":恰好8位,成功触发后查看一下禁用函数,发现system不能用,换一换其他函数
在这里插入图片描述
在这里插入图片描述

ezphpaudit

访问/?source拿到源码

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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<?php
echo "<!--?source-->";
error_reporting(0);
function fzip_open($fzip = '',$tagdir = '')
{
if (file_exists($fzip) && is_dir($tagdir)) {
$zip = new ZipArchive;
try{
$status = $zip->open($fzip);
$status = $zip->extractTo($tagdir);
$zip->close();
return $status;
}catch(Exception $e){
return false;
}
}
return false;
}

function moveSqlFile($old_path, $target_path)
{
$handle = opendir($old_path);
while (false !== $file = (readdir($handle))) {
if ($file == '.' || $file == '..') {
continue;
}

$substr = substr($file, -4);
if ($substr === '.sql') {
rename($old_path . '/' . $file, $target_path . $file);
}
}
closedir($handle);
if (is_dir($old_path)) {
deldir($old_path);
}
}

function deldir($dir)
{
//先删除目录下的文件:
$dh = opendir($dir);
while ($file = readdir($dh)) {
if($file != "." && $file!="..") {
$fullpath = $dir."/".$file;
if(!is_dir($fullpath)) {
unlink($fullpath);
} else {
deldir($fullpath);
}
}
}
closedir($dh);

//删除当前文件夹:
if(rmdir($dir)) {
return true;
} else {
return false;
}
}

if(isset($_GET['source'])){
highlight_file(__FILE__);
}


$userdir = "./sandbox/user_".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);
$f_path= $userdir."/".$name;
$extension = substr($name, strrpos($name,".")+1);

if(preg_match("/ph/i",$extension)) die("No Hacker");
if(mb_strpos(file_get_contents($tmp_name), '<?')!==False) die("No Hacker");
@move_uploaded_file($tmp_name, $f_path);
print_r($f_path);

if($extension == 'zip')
{
$patten = "0123456789abcdef";
$random = '';
while(true) {
if (strlen($random) < 4) {
$rand = rand(0, strlen($patten));
$random .= substr($patten, $rand, 1);
} else {
break;
}
}

$tagdir = $userdir . 'tmp_' . $random.'/';
mkdir($tagdir);

$res = fzip_open($f_path, $tagdir);
if ($res) {
moveSqlFile($tagdir, $userdir);
}

}
}
?>

非预期
传入一个压缩包,其中包含以.sql结尾的文件夹,文件夹里是webshell,上传压缩包后触发moveSqlFile把文件夹移动到用户目录下,直接连接拿到flag