云计算百科
云计算领域专业知识百科平台

第三十二天(文件操作安全)

文件遍历上传下载删除编辑包含等

$_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 {             fontfamily: Arial, sansserif;         }         .filemanager {             maxwidth: 800px;             margin: 0 auto;             padding: 20px;         }         table {             width: 100%;             bordercollapse: collapse;         }         th, td {             padding: 10px;             border: 1px solid #ddd;         }         th {             textalign: left;         }         .actionbuttons {             margintop: 20px;         }         .actionbuttons form {             display: inlineblock;             marginright: 10px;         }         .contentarea {             margintop: 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

赞(0)
未经允许不得转载:网硕互联帮助中心 » 第三十二天(文件操作安全)
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!