SESSION_UPLOAD_PROGRESS 的利用

刚刚做了一道题里面用到了文件包含的SESSION_UPLOAD_PROGRESS 的利用

是这道题捏

[NPUCTF2020]ezinclude

具体解题我就不贴了,主要是做个笔记

Session Upload Progress 最初是PHP为上传进度条设计的一个功能,在上传文件较大的情况下,PHP将进行流式上传,并将进度信息放在Session中,此时即使用户没有初始化Session,PHP也会自动初始化Session。而且,默认情况下session.upload_progress.enabled是为On的,也就是说这个特性默认开启。所以,我们可以通过这个特性来在目标主机上初始化Session。

从上面官方的案例和结果中可以看到,session中一部分数据(session.upload_progress.name)是用户自己可以控制的。那么我们只要在上传文件的时候,同时POST一个恶意的字段 PHP_SESSION_UPLOAD_PROGRESS,目标服务器的PHP就会自动启用Session,Session文件将会自动创建。

PHP SESSION 的存储

Session会话储存方式

PHP将session以文件的形式存储在服务器某个文件中,可以在php.ini里面设置session的存储位置

默认路径

/var/lib/php/sess_PHPSESSID
/var/lib/php/sessions/sess_PHPSESSID
/tmp/sess_PHPSESSID
/tmp/sessions/sess_PHPSESSID

虽然说正常情况下这个SESSID是随机的,但是我们可以通过在http包里修改cookie值来让SESSID变成固定的

这样我们知道了临时文件的名字后,如果此时目标网站还存在文件包含漏洞的话,我们便可以配合文件包含漏洞来Getshell。其原理大致就是通过 PHP_SESSION_UPLOAD_PROGRESS 在目标主机上创建一个含有恶意代码的Session文件,之后利用文件包含漏洞去包含这个我们已经传入恶意代码的这个Session文件就可以达到攻击效果。

那我们怎么传入恶意文件呢

因为 PHP的 session.upload_progress.cleanup = on 这个默认选项会有限制。即文件上传结束后,PHP 将会立即清空对应Session文件中的内容,这就导致我们在包含该Session的时候相当于在包含了一个空文件,没有包含我们传入的恶意代码。所以我们需要条件竞争,赶在文件被清除前利用包含即可。

import io
import requests
import threading

sessid = 'whoami'

def POST(session):
    f = io.BytesIO(b'a' * 1024 * 50)
    session.post(
        'http://192.168.43.82/index.php',
        data={"PHP_SESSION_UPLOAD_PROGRESS":"123"},
        files={"file":('q.txt', f)},
        cookies={'PHPSESSID':sessid}
    )

with requests.session() as session:
    while True:
        POST(session)
        print("[+] 成功写入sess_whoami")

这是一个自动化利用的脚本

当这个脚本运行结束后,恶意文件就保留在了服务器中,我们只要用文件包含解析这个恶意文件就能getshell

ps:这个功能在php5.4后才加入

### 与 `upload_flag` 相关的技术内容及解决方案 在实现或处理 `upload_flag` 功能时,通常需要考虑文件上传的流程控制、安全性以及状态管理。以下是相关的技术内容和解决方案: #### 1. 文件上传的基本流程 文件上传通常包括以下几个部分: - **前端表单**:通过 HTML 表单提交文件数据,确保表单中包含 `enctype="multipart/form-data"` 属性[^4]。 - **后端接收**:使用编程语言(如 PHP、Python 等)接收文件,并将其保存到服务器指定目录。 - **状态标志管理**:引入 `upload_flag` 来标识上传的状态,例如是否成功、失败或其他特殊状态。 #### 2. 使用 `upload_flag` 的场景 `upload_flag` 可以用于以下场景: - 标识上传过程中的状态,例如 `0` 表示未开始,`1` 表示正在上传,`2` 表示上传完成。 - 在多步骤上传过程中,记录每个步骤的状态,确保流程完整性。 - 提供反馈信息给用户,告知上传结果。 #### 3. 实现 `upload_flag` 的方法 以下是一个基于 Python Django 框架的示例,展示如何实现 `upload_flag` 功能: ```python def upload_file(request): upload_flag = 0 # 初始化上传标志为未开始 if request.method == 'POST' and request.FILES.get('upload_file'): try: uploaded_file = request.FILES['upload_file'] # 验证文件类型和大小 if uploaded_file.size > 10 * 1024 * 1024: # 限制文件大小为10MB upload_flag = -1 # 标志为失败 return JsonResponse({'status': 'error', 'message': 'File size exceeds limit', 'upload_flag': upload_flag}) # 保存文件到服务器 with open(f'media/{uploaded_file.name}', 'wb+') as destination: for chunk in uploaded_file.chunks(): destination.write(chunk) upload_flag = 2 # 标志为上传完成 return JsonResponse({'status': 'success', 'message': 'File uploaded successfully', 'upload_flag': upload_flag}) except Exception as e: upload_flag = -2 # 标志为异常 return JsonResponse({'status': 'error', 'message': str(e), 'upload_flag': upload_flag}) else: upload_flag = 1 # 标志为上传中 return JsonResponse({'status': 'processing', 'message': 'Upload in progress', 'upload_flag': upload_flag}) ``` #### 4. 安全性注意事项 在实现文件上传功能时,需特别注意安全性问题: - **文件名验证**:避免用户通过文件名注入恶意路径,例如利用 `/` 或 `../` 进行目录遍历攻击[^1]。 - **文件类型检查**:确保上传的文件类型符合预期,防止上传恶意脚本文件[^2]。 - **存储路径隔离**:将上传文件存储在独立的目录中,并设置适当的权限,避免被直接访问。 #### 5. 全局变量管理 如果需要在多个视图中共享 `upload_flag` 的状态,可以将其设置为全局变量或存储在会话中。例如,在 Django 中可以通过上下文处理器实现[^4]: ```python def settings(request): context = { 'upload_flag': request.session.get('upload_flag', 0), # 默认值为0 } return context ``` --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值