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