PHP文件包含与phpinfo

0x00 漏洞概述

当遇到PHP文件包含漏洞时,如果找不到可以包含的文件,可以通过包含临时文件来GetShell。由于临时文件的文件名是随机的,如果目标网站存在phpinfo,则可以通过phpinfo来获取临时文件名,进而完成包含。

0x01 漏洞原理

在给PHP服务器POST数据包时,如果数据包含有文件区块,无论访问路径的代码是否具有处理文件上传的逻辑,PHP都会将这个区块(文件)保存为一个临时文件,通常位于/tmp/php[6个随机字符]。文件名可以在$_FILES变量中找到。该临时文件会在请求结束后被删除。

因为phpinfo会将当前请求的上下文全部打印出来,所以如果向phpinfo页面发送包含文件区块的数据包,则可以在返回包找到$_FILES变量的内容,自然也包含临时文件名。

实际情况下,文件包含漏洞和phpinfo通常来自于两个页面,理论上需要先发送给phpinfo页面,然后从返回包得到临时文件名,再将这个文件名发送给文件包含漏洞页面,进行GetShell。在第一个请求结束时,临时文件就被删除了,第二个请求自然无法完成文件包含。

此时需要用到条件竞争:

  1. 发送包含webshell的上传数据到phpinfo页面,这个数据包的header、get等位置充满了垃圾数据。
  2. 因为phpinfo页面会将所有数据打印出来,垃圾数据会将整个phpinfo页面过分填充。
  3. PHP默认的输出缓冲区大小为4096,可理解为PHP每次返回4096个字节给socket连接。直接操作原生socket,每次读取4096个字节,只要读取到的字符里包含临时文件名,就立即发送第二个数据包。
  4. 此时第一个数据包的socket连接还未结束,因为PHP还在继续每次输出4096个字节,所以临时文件此时还未被删除。
  5. 利用时间差完成包含临时文件,最终GetShell。

0x02 环境搭建

建立一个Docker项目,Apache部分直接依靠拉取,只需要编写三个文件。

执行

docker-compose up -d

等待完成即可。

PHP文件包含与phpinfo

~/docker-compose.yml

version: ‘2‘
services:
 php:
   image: php:7.2-apache
   volumes:
    - ./www:/var/www/html
   ports:
    - "8080:80"

~/www/lfi.php

即文件包含漏洞所在地。

<?php
include $_GET[‘file‘];

~/www/phpinfo.php

<?php
phpinfo();

0x03 利用流程

访问靶机

根目录为403。通过目录扫描等途径可得/phpinfo.php和/lfi.php。

访问/lfi.php,从报错信息可知服务端系统Linux、网站路径、include函数。

PHP文件包含与phpinfo

由于不知道lfi.php所接受的参数名称,需要爆破一下。

PHP文件包含与phpinfo

PHP文件包含与phpinfo

得到参数名为file

EXP

使用优质EXP,需要Python2。

因为已知网站路径/var/www/html/,所以可以在Payload处做一点自定义(同时注意文件包含路径和phpinfo路径是否正确):

PHP文件包含与phpinfo

执行:

python exp.py 192.168.31.39 8080 100

PHP文件包含与phpinfo

连接

刚才自定了Payload中的文件路径,所以访问网站根目录的cmd.php即可。

PHP文件包含与phpinfo

大功告成!

PHP文件包含与phpinfo

上一篇:第12章 微信支付


下一篇:mysql 的垂直分表和水平分表; 垂直分库和水平分库