buuctf 刷題記錄 [第二章 web進階]檔案上傳
阿新 • • 發佈:2021-06-21
buuctf 刷題記錄 [第二章 web進階]檔案上傳
上傳,下面給了程式碼
程式碼審計
<?php header("Content-Type:text/html; charset=utf-8"); // 每5分鐘會清除一次目錄下上傳的檔案 require_once('pclzip.lib.php'); if(!$_FILES){ echo ' <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>檔案上傳章節練習題</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <style type="text/css"> .login-box{ margin-top: 100px; height: 500px; border: 1px solid #000; } body{ background: white; } .btn1{ width: 200px; } .d1{ display: block; height: 400px; } </style> </head> <body> <div class="container"> <div class="login-box col-md-12"> <form class="form-horizontal" method="post" enctype="multipart/form-data" > <h1>檔案上傳章節練習題</h1> <hr /> <div class="form-group"> <label class="col-sm-2 control-label">選擇檔案:</label> <div class="input-group col-sm-10"> <div > <label for=""> <input type="file" name="file" /> </label> </div> </div> </div> <div class="col-sm-8 text-right"> <input type="submit" class="btn btn-success text-right btn1" /> </div> </form> </div> </div> </body> </html> '; show_source(__FILE__); }else{ $file = $_FILES['file']; if(!$file){ exit("請勿上傳空檔案"); } $name = $file['name']; $dir = 'upload/'; $ext = strtolower(substr(strrchr($name, '.'), 1)); $path = $dir.$name; function check_dir($dir){ $handle = opendir($dir); while(($f = readdir($handle)) !== false){ if(!in_array($f, array('.', '..'))){ if(is_dir($dir.$f)){ check_dir($dir.$f.'/'); }else{ $ext = strtolower(substr(strrchr($f, '.'), 1)); if(!in_array($ext, array('jpg', 'gif', 'png'))){ unlink($dir.$f); } } } } } if(!is_dir($dir)){ mkdir($dir); } $temp_dir = $dir.md5(time(). rand(1000,9999)); if(!is_dir($temp_dir)){ mkdir($temp_dir); } if(in_array($ext, array('zip', 'jpg', 'gif', 'png'))){ if($ext == 'zip'){ $archive = new PclZip($file['tmp_name']); foreach($archive->listContent() as $value){ $filename = $value["filename"]; if(preg_match('/\.php$/', $filename)){ exit("壓縮包內不允許含有php檔案!"); } } if ($archive->extract(PCLZIP_OPT_PATH, $temp_dir, PCLZIP_OPT_REPLACE_NEWER) == 0) { check_dir($dir); exit("解壓失敗"); } check_dir($dir); exit('上傳成功!'); }else{ move_uploaded_file($file['tmp_name'], $temp_dir.'/'.$file['name']); check_dir($dir); exit('上傳成功!'); } }else{ exit('僅允許上傳zip、jpg、gif、png檔案!'); } }
程式碼分為3個功能
1.將上傳的檔案儲存在upload路徑下,同時檢查壓縮包內的檔名是否有帶有.或者..
的,並且檢查檔案是否是jpg,gif,png
$dir = 'upload/'; $ext = strtolower(substr(strrchr($name, '.'), 1)); $path = $dir.$name; function check_dir($dir){ $handle = opendir($dir); while(($f = readdir($handle)) !== false){ if(!in_array($f, array('.', '..'))){ if(is_dir($dir.$f)){ check_dir($dir.$f.'/'); }else{ $ext = strtolower(substr(strrchr($f, '.'), 1)); if(!in_array($ext, array('jpg', 'gif', 'png'))){ unlink($dir.$f);
直接上傳的'jpg', 'gif', 'png
檔案是沒有這個待遇的,會被放入一個tmp路徑
2.tmp路徑
$temp_dir = $dir.md5(time(). rand(1000,9999));
if(!is_dir($temp_dir)){
mkdir($temp_dir);
move_uploaded_file($file['tmp_name'], $temp_dir.'/'.$file['name']);
check_dir($dir);
exit('上傳成功!');
tmp路徑是隨機的md5值,從1000到9999
3.檔案解壓縮
if(in_array($ext, array('zip', 'jpg', 'gif', 'png'))){ if($ext == 'zip'){ $archive = new PclZip($file['tmp_name']); foreach($archive->listContent() as $value){ $filename = $value["filename"]; if(preg_match('/\.php$/', $filename)){ exit("壓縮包內不允許含有php檔案!");
apache漏洞
apache伺服器,有檔案解析漏洞,也就是可以上傳類似backdoor.php.notexist
這種檔案,
如果遇到無法解析的字尾名會向前解析,也就是跳過notexist
字尾,直接解析php
字尾
用010editor改檔名
首先確定目錄穿越時候用的名字
比如需要到根目錄就是../../
然後計算好起的名字的長度
例如../../1.php.xxx
這個名字就是15位的
然後給這個還沒有壓縮的馬起個佔15字元的名字,例如123456789123456
字尾無所謂,反正到時候都需要010editer改
然後zip壓縮一下
用010edirer改