首先是源代码
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
|
刷新页面就可以了