0%

2020-hufu

真的是放假在老家与世隔绝久了,题目都写不出来了…还坑了队友,emmmm先记录一下再说。

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;
}
?>

这题的意图很明显,告诉了我们session上传的路径,看完代码发现当满足

1
2
3
4
$_SESSION['username'] ==='admin'			#1
&
$filename='/var/babyctf/success.txt'; #2
if(file_exists($filename) #3

我们就可以拿到flag。顺着下来看代码,告诉了我们session的位置,有下载功能,尝试过后发现能读取。

1
direction=download&filename=sess_xxxxxxx

可以读到session的格式

1
<0x08>usernames:5:"guest";

我们可以直接构造一个admin的session去上传。

上传文件命名规则

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

可以不传递attr参数,将文件名为sess,就会有/var/babyctf/sess_hashfile(“sha256”)类似session文件命名规则的文件出现。

hash是随机函数,但是hashfile则是根据文件生成的hash值,我们可以控制上传内容也就能控制hash值。

就有了先POST attr=&direction=upload&filename=sess(文件内容为<0x08>usernames:5:”admin”;)上传

读取sess_hash_file()可以读取成功。

绕过#2、#3,我们发现一行

1
$dir_path = "/var/babyctf/".$attr;

我们可以利用这点,上传attr=success.txt&direction=upload&….,构造一个success.txt的目录来绕过判断,再带着我们之前上传的session(修改PHPSESSID=hash_file()),访问抓包即可获得flag。


-------------    本文结束  感谢您的阅读    -------------