利用PHP_SESSION_UPLOAD_PROGRESS上传webshell

0x01 环境配置&利用条件

image-20210922091243957

image-20210924100930479

环境分析

  • session.use_strict_mode默认值为0,此时用户是可以自己定义Session ID

    1
    我们在Cookie里设置PHPSESSID=flag,PHP将会在服务器上创建一个文件:/tmp/sess_flag
  • session.upload_progress.prefix由我们构造的session.upload_progress.name值组成,最后被写入sess_文件里。

所以:

  • 这个文件名是PHPSESSID=flag,文件名可控
  • 内容也是可以通过PHP_SESSION_UPLOAD_PROGRESS写入的
  • 如果有文件包含,就可以 getshell

一般情况还需要条件竞争

1
2
3
4
5
在默认情况下,session.upload_progress.cleanup是开启的
所以要是处理了所有POST数据,它就会清除进度信息,这个文件就没了

所以需要使用条件竞争:
要在没有处理完post数据的时候就要去触发

0x02 题目

这个题是第五空间CTF的一道WEB题

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
36
37
38
39
40
41
42
<?php

if(!isset($_GET['mode'])){
highlight_file(__file__);
}else if($_GET['mode'] == "eval"){
$shell = $_GET['shell'] ?? 'phpinfo();';
if(strlen($shell) > 15 | filter($shell) | checkNums($shell)) exit("hacker");
eval($shell);
}


if(isset($_GET['file'])){
if(strlen($_GET['file']) > 15 | filter($_GET['file'])) exit("hacker");
include $_GET['file'];
}


function filter($var): bool{
$banned = ["while", "for", "\$_", "include", "env", "require", "?", ":", "^", "+", "-", "%", "*", "`"];

foreach($banned as $ban){
if(strstr($var, $ban)) return True;
}

return False;
}

function checkNums($var): bool{
$alphanum = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$cnt = 0;
for($i = 0; $i < strlen($alphanum); $i++){
for($j = 0; $j < strlen($var); $j++){
if($var[$j] == $alphanum[$i]){
$cnt += 1;
if($cnt > 8) return True;
}
}
}
return False;
}

?>

0x03 利用

上传HTML:

1
name 要对应session.upload_progress.name中的 PHP_SESSION_UPLOAD_PROGRESS

image-20210924103445313

HTML代码:

1
2
3
4
<form action="http://xxxxxxxx.com:8088/" method="POST" enctype="multipart/form-data">
<input type="text" name="PHP_SESSION_UPLOAD_PROGRESS" value="zzzz" />
<input type="file" name="file" id="file">
<input type="submit" name="submit" value="submit">

然后抓包,在里面插入我们的一句话木马

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dwKWo8Vo-1632451391682)(…/Library/Application Support/typora-user-images/image-20210924104028736.png)]

1
2
所以文件地址就是 /tmp/sess_zz5
最终利用文件包含获取webshell

image-20210924103851551

image-20210924103915529