0%

2020 虎符网络安全大赛 babyupload

首先是源代码

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
 <?php
error_reporting(0);
session_save_path("/var/babyctf/");
session_start();
require_once "/flag";
highlight_file(__FILE__);
if($_SESSION['username'] ==='admin')
{
$filename='/var/babyctf/success.txt';
if(file_exists($filename)){
safe_delete($filename);
die($flag);
}
}
else{
$_SESSION['username'] ='guest';
}
$direction = filter_input(INPUT_POST, 'direction');
$attr = filter_input(INPUT_POST, 'attr');
$dir_path = "/var/babyctf/".$attr;
if($attr==="private"){
$dir_path .= "/".$_SESSION['username'];
}
if($direction === "upload"){
try{
if(!is_uploaded_file($_FILES['up_file']['tmp_name'])){
throw new RuntimeException('invalid upload');
}
$file_path = $dir_path."/".$_FILES['up_file']['name'];
$file_path .= "_".hash_file("sha256",$_FILES['up_file']['tmp_name']);
if(preg_match('/(\.\.\/|\.\.\\\\)/', $file_path)){
throw new RuntimeException('invalid file path');
}
@mkdir($dir_path, 0700, TRUE);
if(move_uploaded_file($_FILES['up_file']['tmp_name'],$file_path)){
$upload_result = "uploaded";
}else{
throw new RuntimeException('error while saving');
}
} catch (RuntimeException $e) {
$upload_result = $e->getMessage();
}
} elseif ($direction === "download") {
try{
$filename = basename(filter_input(INPUT_POST, 'filename'));
$file_path = $dir_path."/".$filename;
if(preg_match('/(\.\.\/|\.\.\\\\)/', $file_path)){
throw new RuntimeException('invalid file path');
}
if(!file_exists($file_path)) {
throw new RuntimeException('file not exist');
}
header('Content-Type: application/force-download');
header('Content-Length: '.filesize($file_path));
header('Content-Disposition: attachment; filename="'.substr($filename, 0, -65).'"');
if(readfile($file_path)){
$download_result = "downloaded";
}else{
throw new RuntimeException('error while saving');
}
} catch (RuntimeException $e) {
$download_result = $e->getMessage();
}
exit;
}
?>

这个题目只要有两个功能,上传下载文件

我们要得到flag需要满足一下条件

1
2
3
4
5
6
7
8
if($_SESSION['username'] ==='admin')
{
$filename='/var/babyctf/success.txt';
if(file_exists($filename)){
safe_delete($filename);
die($flag);
}
}

首先这道题目没有任何的session复制点,所以我们能想到的就是上传一个sess_xxxxxxxx文件来覆盖原有的sess文件

解题步骤

  • 先下载一个sess文件,看格式是什么样子的
    在这里插入图片描述这儿我们看到sess文件的格式为0x08usernames:5:"guest";
    注意前面还有一个0x08不可见字符,开始我没有加进去,就没做出来

  • 上传sess文件

    $file_path = $dir_path."/".$_FILES['up_file']['name'];
    $file_path .= "_".hash_file("sha256",$_FILES['up_file']['tmp_name']);

    这儿我们只需要将$_FILES['up_file']['name']改为sess就可以了,这样就满足sess文件的命名形式

  • 新创success.txt文件夹
    file_exists($filename),其中$filename是一个文件夹,也满足条件

  • 修改PHHSESSID,然后刷新页面就可以得到flag

​ 修改sess
在这里插入图片描述

运行hash_file函数,得到哈希值
在这里插入图片描述

1
432b8b09e30c4a75986b719d1312b63a69f1b833ab602c9ad5f0299d1d76a5a4

然后上传文件,我们需要上传两次,一次覆盖sess,一次创建success.txt文件夹

  • 上传sess文件
    在这里插入图片描述
  • 这个时候attr置空
  • 新建success.txt文件夹
    在这里插入图片描述

然后替换PHPSESSID

1
432b8b09e30c4a75986b719d1312b63a69f1b833ab602c9ad5f0299d1d76a5a4

刷新页面就可以了
在这里插入图片描述