文件遍歷上傳下載刪除編輯包含等
$_FILES:PHP中一個預定義的超全局變量,用于在上傳文件時從客戶端接收文件,并將其保存到服務器上。它是一個包含上傳文件信息的數組,包括文件名、類型、大小、臨時文件名等信息。
$_FILES"表單值" 獲取上傳文件原始名稱
$_FILES"表單值" 獲取上傳文件MIME類型
$_FILES"表單值" 獲取上傳文件字節單位大小
$_FILES"表單值" 獲取上傳的臨時副本文件名
$_FILES"表單值" 獲取上傳時發生的錯誤代碼
move_uploaded_file() 將上傳的文件移動到指定位置的函數
#文件顯示:
1.打開目錄讀取文件列表
2.遞歸循環讀取文件列表
3.判斷是文件還是文件夾
4.PHP.INI目錄訪問控制
is_dir() 函數用于檢查指定的路徑是否是一個目錄
opendir() 函數用于打開指定的目錄,返回句柄,用來讀取目錄的文件和子目錄
readdir() 函數用于從打開的目錄句柄中讀取目錄中的文件和子目錄
open_basedir:PHP.INI中的設置用來控制腳本程序訪問目錄
scandir() 函數返回指定目錄中的文件和目錄列表,以數組形式返回
ini_set('open_basedir',DIR); 設置配置文件中,只能訪問本目錄
?scandir 函數遍歷目錄
用opendir 加 readdir 函數遍歷文件目錄 用兩個“\\” 防止一個\時識別為轉義字符
?
#文件刪除:
unlink() 文件刪除函數
調用命令刪除:system shell_exec exec等
?unlink() 函數 1.txt和file.php 在同一級 訪問地址后1.txt被刪除,輸出文件名
用系統命令刪除文件
#文件下載:
修改HTTP相應頭實現文件讀取解析下載:
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename="" . $file . """);
header("Content-Length: " . filesize($file));
readfile($file);
這里正常訪問1.php 是可以正常顯示內容的
當訪問file.php 時就變成下載1.php文件了,這里可以打開f12 查看數據包響應頭內容 ,就會出現代碼中的那幾句修改頭參數的值 的內容
#文件讀取:
1、file_get_contents() 讀取文件內容
2、fopen() fread() 文件打開讀入
?右鍵 點擊查看頁面源代碼
#文件包含:
include、require、include_once、require_once等
直接訪問寫有php代碼的txt文件時,只會講php代碼輸出出來,而不會執行
當訪問file.php 時,1.txt中的php代碼就會被執行
require
include_once
require_once
實踐:
讓ai寫一個文件編輯,下載,讀取,刪除的功能
<?php
// 設置默認路徑
$directory = isset($_GET['dir']) ? $_GET['dir'] : './';
?
// 文件操作
if (isset($_POST['action'])) {
??? if ($_POST['action'] == 'create_folder' && !empty($_POST['folder_name'])) {
??????? // 創建文件夾
??????? mkdir($directory . '/' . $_POST['folder_name']);
??? } elseif ($_POST['action'] == 'delete' && isset($_POST['file'])) {
??????? // 刪除文件或文件夾
??????? $path = $directory . '/' . $_POST['file'];
??????? if (is_dir($path)) {
??????????? rmdir($path); // 刪除文件夾
??????? } else {
??????????? unlink($path); // 刪除文件
??????? }
??? } elseif ($_POST['action'] == 'rename' && isset($_POST['file']) && isset($_POST['new_name'])) {
??????? // 重命名文件或文件夾
??????? rename($directory . '/' . $_POST['file'], $directory . '/' . $_POST['new_name']);
??? } elseif ($_POST['action'] == 'save_edit' && isset($_POST['file']) && isset($_POST['file_content'])) {
??????? // 保存文件內容
??????? file_put_contents($directory . '/' . $_POST['file'], $_POST['file_content']);
??? }
}
?
// 下載文件
if (isset($_GET['download']) && !empty($_GET['download'])) {
??? $file = $directory . '/' . $_GET['download'];
??? if (file_exists($file)) {
??????? // 設置下載頭
??????? header('Content-Type: application/octet-stream');
??????? header('Content-Disposition: attachment; filename="' . basename($file) . '"');
??????? header('Content-Length: ' . filesize($file));
??????? readfile($file);
??????? exit;
??? } else {
??????? echo '文件不存在!';
??? }
}
?
// 讀取文件內容
$content = '';
if (isset($_GET['read']) && !empty($_GET['read'])) {
??? $file = $directory . '/' . $_GET['read'];
??? if (file_exists($file)) {
??????? $content = file_get_contents($file);
??? } else {
??????? $content = '文件不存在!';
??? }
}
?
// 列出目錄中的文件和文件夾
$files = scandir($directory);
$files = array_diff($files, array('.', '..')); // 排除 . 和 ..
?
?>
?
<!DOCTYPE html>
<html lang="en">
<head>
??? <meta charset="UTF-8">
??? <meta name="viewport" content="width=device-width, initial-scale=1.0">
??? <title>PHP 文件管理器</title>
??? <style>
??????? body {
??????????? font-family: Arial, sans-serif;
??????? }
??????? .file-manager {
??????????? max-width: 800px;
??????????? margin: 0 auto;
??????????? padding: 20px;
??????? }
??????? table {
??????????? width: 100%;
??????????? border-collapse: collapse;
??????? }
??????? th, td {
??????????? padding: 10px;
??????????? border: 1px solid #ddd;
??????? }
??????? th {
??????????? text-align: left;
??????? }
??????? .action-buttons {
??????????? margin-top: 20px;
??????? }
??????? .action-buttons form {
??????????? display: inline-block;
??????????? margin-right: 10px;
??????? }
??????? .content-area {
??????????? margin-top: 20px;
??????? }
??????? textarea {
??????????? width: 100%;
??????????? height: 300px;
??????? }
??? </style>
</head>
<body>
<div class="file-manager">
??? <h2>文件管理器</h2>
??? <h3>當前目錄:<?php echo $directory; ?></h3>
?
??? <!-- 文件和文件夾列表 -->
??? <table>
??????? <thead>
??????? <tr>
??????????? <th>名稱</th>
??????????? <th>類型</th>
??????????? <th>操作</th>
??????? </tr>
??????? </thead>
??????? <tbody>
??????? <?php foreach ($files as $file): ?>
??????????? <tr>
??????????????? <td>
??????????????????? <?php if (is_dir($directory . '/' . $file)): ?>
??????????????????????? <a href="?dir=<?php echo urlencode($directory . '/' . $file); ?>"><?php echo $file; ?>/</a>
??????????????????? <?php else: ?>
??????????????????????? <?php echo $file; ?>
??????????????????? <?php endif; ?>
??????????????? </td>
??????????????? <td><?php echo is_dir($directory . '/' . $file) ? '文件夾' : '文件'; ?></td>
??????????????? <td>
??????????????????? <!-- 刪除操作 -->
??????????????????? <form action="" method="POST" style="display:inline;">
??????????????????????? <input type="hidden" name="action" value="delete">
??????????????????????? <input type="hidden" name="file" value="<?php echo $file; ?>">
??????????????????????? <button type="submit" onclick="return confirm('確定要刪除此文件嗎?');">刪除</button>
??????????????????? </form>
??????????????????? <!-- 下載操作 -->
??????????????????? <?php if (!is_dir($directory . '/' . $file)): ?>
??????????????????????? <a href="?download=<?php echo urlencode($file); ?>">下載</a>
??????????????????? <?php endif; ?>
??????????????????? <!-- 重命名操作 -->
??????????????????? <form action="" method="POST" style="display:inline;">
??????????????????????? <input type="hidden" name="action" value="rename">
??????????????????????? <input type="hidden" name="file" value="<?php echo $file; ?>">
??????????????????????? <input type="text" name="new_name" placeholder="新名稱" required>
??????????????????????? <button type="submit">重命名</button>
??????????????????? </form>
??????????????????? <!-- 編輯操作 -->
??????????????????? <?php if (!is_dir($directory . '/' . $file)): ?>
??????????????????????? <a href="?read=<?php echo urlencode($file); ?>">編輯</a>
??????????????????? <?php endif; ?>
??????????????? </td>
??????????? </tr>
??????? <?php endforeach; ?>
??????? </tbody>
??? </table>
?
??? <!-- 創建新文件夾 -->
??? <div class="action-buttons">
??????? <h3>創建新文件夾</h3>
??????? <form action="" method="POST">
??????????? <input type="hidden" name="action" value="create_folder">
??????????? <input type="text" name="folder_name" placeholder="文件夾名稱" required>
??????????? <button type="submit">創建</button>
??????? </form>
??? </div>
?
??? <!-- 文件內容區 -->
??? <?php if (!empty($content)): ?>
??????? <div class="content-area">
??????????? <h3>編輯文件</h3>
??????????? <form action="" method="POST">
??????????????? <input type="hidden" name="action" value="save_edit">
??????????????? <input type="hidden" name="file" value="<?php echo $_GET['read']; ?>">
??????????????? <textarea name="file_content"><?php echo htmlspecialchars($content); ?></textarea><br>
??????????????? <button type="submit">保存更改</button>
??????????? </form>
??????? </div>
??? <?php endif; ?>
?
</div>
</body>
</html>
效果
點擊目錄時會進到該目錄下,上面會有一個參數,通過修改參數實現跳級 %2F 就是 /
在后面加一個../ 就跳一級,就到了上級目錄 這里跳不了盤,可能有限制 這里是文件顯示
當點擊編輯某個文件時,上面的參數名變了 那這里是不是可以實現對上級文件的編輯呢,從而拿到代碼
在這個目錄上級中有一個upload.html 文件,這里嘗試讀取它,發現可以成功讀取, 當目標有這個編輯功能時,可以測試一下,黑盒中用fuzz工具去跑文件名,拿到文件名再來測試
刪除文件,這里先測試一下,先刪除了1.txt 在f12 下的負載中看到delete 字樣 ,下面還有一個1.txt,猜想,如果我把1.txt 改成上級目錄下的某個文件,是否可以對其進行刪除呢?
打開butp 攔截 刪除操作數據包 ,將1.txt 修改成../upload.html 然后把數據包放出去,在回到瀏覽器中點擊確認刪除,再去上級目錄查看一下,upload.html 文件是否被刪除了,這里測試是可以刪除的
上述測試,可以對任意文件進行修改,刪除,讀取
#代碼審計案例
1、Rrzcms遍歷讀取
https://xz.aliyun.com/t/10932
先安裝一下
這里其實是一個偽靜態的頁面
登錄一下后臺頁面
進來后找到有關文件的地方,這里演示時雖然是在后臺管理員里面操作,但是實戰時只要普通用戶也有文件操作的功能也可以作為測試點,這里分黑盒和白盒,黑盒就嘗試是否可以跳級等等,白盒就直接從代碼里面看
黑盒測試
打開burp 攔截數據包,然后修改參數值在放出去
這里看到一個參數 path ,嘗試修改它,看是否能跳級
將path值改成 ../ 再放出去,發現不行
白盒中,先按照url找到對應的文件
然后進到文件里面找調用的方法,直接搜索,發現這里是要帶 template 如果參數值沒有這個就會報錯
這里保留template 然后輸入,,/index.php 成功讀取到上級目錄的index.php 文件
2、Metinfo文件下載
任意文件下載+讀取+刪除
3、Xhcms文件包含
https://xz.aliyun.com/t/11310