十三:文件操作类&编辑器&上传下载删除读写

发布时间 2023-11-15 22:43:09作者: 小鱼QAQ

文件获取操作:

 1 function getfilename()
 2 {
 3     $dir = getcwd();
 4     $file = scandir($dir);
 5     foreach($file as $value)
 6     {
 7         if($value! = '.' && $value !=  '..')
 8         {
 9             $arr[]=$value;
10             echo $value.'<br>';
11         }
12     }
13 }
14 
15 //getcwd(): 这个函数用于获取当前工作目录的路径。
16 //scandir($dir): 使用 scandir 函数获取指定目录(这里是当前工作目录)下的文件和目录列表,并将其存储在名为 $file 的数组中
17 //foreach 循环:遍历 $file 数组中的每个元素,也就是当前工作目录下的所有文件和目录。
18 //在循环中,使用条件判断 if($value != '.' && $value != '..') 排除了当前目录和父目录(. 和 ..),以确保只输出实际的文件名。
19 //如果不是当前目录和父目录,将文件名添加到名为 $arr 的数组中,并使用 echo 输出文件名到页面上,每个文件名后面紧跟一个换行 <br>。
20 //在 PHP 中,`foreach` 循环用于遍历数组中的每个元素,并将每个元素的值赋给指定的变量。在这种情况下,`foreach($file as $value)` 中的 `$file` 是要遍历的数组,而 `$value` 则是用于存储每个数组元素的变量。
21 //具体来说,`foreach` 循环中的语法是这样的:`foreach($array as $value) {...}`,其中 `$array` 是要遍历的数组,`$value` 则是存储每个数组元素的变量。在每次循环迭代中,`$value` 变量都会依次存储数组中的每个元素的值。
22 //因此,在上述 PHP 代码中的 `foreach($file as $value)`,`$file` 是存储目录中文件和子目录的数组,而 `$value` 会依次存储数组中的每个文件名和子目录名。

文件取出操作:

 1 <?php
 2 //操作数据库讲数据取出进行展示
 3 $conn=mysql_connect('localhost','root','root');
 4 mysql_select_db('beescms',$conn);
 5 $i=$_GET['id'];//GET请求接受id参数名值给变量i
 6 $sql="select * from bees_article where id=$i";
 7 $result=mysql_query($sql,$conn);                //mysql_fetch_array() 函数从结果集中取得一行作为关联数组,或数字数组,或二者兼有返回根据从结果集取得的行生成的数组,如果没有更多行则返回 false。
 8 while($row=mysql_fetch_array($result)){
 9     echo '<br><br><hr>';
10     echo $row['id'];
11     echo $row['content'];
12 }
13 ?>

文件上传类:-任意文件上传

上传恶意文件或木马病毒

 

1、代码自主写 验证核心为源代码

整个文件上传逻辑由编译出来的代码进行控制

文件上传由html代码操作,html提供文件上传的表单

文件上传后的处理由php代码操作,php提供文件上传后的后续处理操作

相关变量:

全局变量$_FILES[''],用于接收表单被上传的文件

@$name=$_FILES['upfile'] ['name'] :客户端上传文件的原名称,不包含路径

@$type=$_FILES['upfile'] ['type']; //上传文件的MIME类型  

@$tmpname=$_FILES['upfile'] ['tmp_name']; //已上传文件在服务器端保存的临时文件名,包含路径

@$error=$_FILES['upfile'] ['error']; //上传文件出现的错误号,为一个整数,若>0则上传失败

@$size=$_FILES['upfile'] ['size']; //已上传文件的大小,单位为字节
//@是为了去掉undefined index的报错,但是报错也不影响代码运行。

文件移动操作:move_uploaded_file(string $from, string $to): bool

from

上传的文件的文件名。

to

移动文件到这个位置。

上传操作中,可以对上传的type进行限制,对不符合指定type的文件直接筛选掉

例如,只允许上传图片文件:

if($type=='image/png')
{
    if(!move_uploaded_file(@$_FILES["upload"]["tmp_name"], "upload/" . @$_FILES["upload"]["name"]);)
    {
        echo"文件移动失败!";
    }
    else
    {
        echo"文件上传成功";
        echo'/upload/'.$name;
    }
}
else
{
    echo"文件类型不正确";
}

2、编辑器引用 :验证核心为编辑器源代码

选取网络中已经写好的编辑器进行文件上传;

3.引用开发框架:验证核心为框架源代码

 

#文件下载类:-任意文件下载

下载敏感文件

1、直连 URL 访问

直接连接URL访问:

  • 这是最简单的文件下载方式,用户直接访问包含文件的URL,然后浏览器会根据文件类型决定是打开文件还是下载文件。

  • 如果文件URL是公开可访问的,用户可以直接在浏览器中输入或点击链接访问文件,无需进行额外的授权或身份验证。

  • 这种方式适用于共享公开的文件,例如图片、文档等,但对于需要授权或权限的文件,可能不够安全或适用。

2、传参头部修改

传参头部修改:

  • 在这种方式中,用户通过修改HTTP请求头部信息,特别是 Content-Disposition 头部,来指示浏览器下载文件,同时可以传递额外的参数,例如自定义文件名等。

  • 这种方式通常用于在动态生成文件时,通过服务器响应中的头部信息来指示浏览器下载文件,并可以在响应头部中包含额外的参数,从而实现更灵活的文件下载需求。

  • 传参头部修改可以提供更多的控制和定制,例如灵活指定文件名、文件类型等,适用于动态生成或需要个性化下载体验的文件。

存在的问题:

  • 传参下载存在一些潜在的安全隐患,主要是由于对HTTP响应头的修改和用户输入的不可信任性。以下是一些传参下载可能存在的安全隐患:

    1. 文件名注入:恶意用户可能通过修改传参中的文件名参数,注入恶意文件名或路径,导致下载非预期文件或执行恶意操作。

    2. 文件类型伪装:恶意用户可能伪装文件类型,使其看起来像常见的无害文件(如图片),实际上是恶意文件(如恶意脚本或病毒),从而欺骗用户下载并执行。

    3. 目录遍历漏洞:如果服务器端对用户提供的文件名参数进行不充分的检查和验证,可能导致目录遍历漏洞,允许恶意用户下载服务器上的敏感文件或目录。

    4. CSRF 攻击:恶意网站可能利用 CSRF(跨站请求伪造)攻击,诱使用户在受害网站上执行下载操作,从而实现对用户文件的非授权访问和下载。

    5. XSS 攻击:恶意用户可能利用跨站脚本(XSS)攻击,注入恶意脚本到下载页面,从而获取用户的下载文件权限或执行进一步的攻击。

    为了缓解这些安全隐患,开发人员可以采取以下措施:

    • 对用户输入进行严格的验证和过滤,确保文件名参数不包含恶意代码或路径。

    • 对下载文件的类型和内容进行验证,避免下载恶意文件。

    • 限制下载的文件路径和范围,避免目录遍历漏洞。

    • 实施 CSRF 防护措施,避免恶意站点发起下载请求。

    • 对下载页面进行适当的输入过滤和输出编码,以防止XSS攻击。

    通过这些措施,可以降低传参下载的安全风险,保护用户免受潜在的恶意操作和攻击。

#文件删除类-任意文件删除

删除重要文件

1、文件删除

文件删除函数:unlink($x);$x是要删除的文件

2、文件夹删除

文件夹删除函数:rmdir($x);$x是要删除的文件夹

#文件内容操作类-任意文件读取&写入

读取敏感文件,写入危险代码

1、文件读取

function fileread($name){
    $f=fopen($name,"r");
    $code=fread($f,filesize($name));
    echo $code;
    fclose($f);
}

相关函数:fopen(filename,mode,include_path,context);

常用的参数主要是filename和mode。这里的filename 必需。规定要打开的文件或 URL。mode是规定要求到该文件/流的访问类型。

mode说明
"r" 只读方式打开,将文件指针指向文件头。
"r+" 读写方式打开,将文件指针指向文件头。
"w" 写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
"w+" 读写方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
"a" 写入方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
"a+" 读写方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
"x"

创建并以写入方式打开,将文件指针指向文件头。如果文件已存在,则 fopen() 调用失败并返回 FALSE,并生成一条 E_WARNING 级别的错误信息。如果文件不存在则尝试创建之。

这和给底层的 open(2) 系统调用指定 O_EXCL|O_CREAT 标记是等价的。

此选项被 PHP 4.3.2 以及以后的版本所支持,仅能用于本地文件。

"x+"

创建并以读写方式打开,将文件指针指向文件头。如果文件已存在,则 fopen() 调用失败并返回 FALSE,并生成一条 E_WARNING 级别的错误信息。如果文件不存在则尝试创建之。

这和给底层的 open(2) 系统调用指定 O_EXCL|O_CREAT 标记是等价的。

此选项被 PHP 4.3.2 以及以后的版本所支持,仅能用于本地文件。

2、文件写入

相关函数:fwrite

fwrite(file,string,length);

参数描述
file 必需。规定要写入的打开文件。
string 必需。规定要写入文件的字符串。
length 可选。规定要写入的最大字节数。

 

function filewrite($name,$txt){
    $f=fopen($name,"a+");
    fwrite($f,$txt);
    fclose($f);
}

以上两处的$name都是接收的文件名

#文件包含-任意文件包含

1、本地文件包含

Include:包含文件

include_once:系统会自动判断文件包含过程中,是否已经包含过(一个文件最多被包含一次)

require:与include基本相同

require_once:与include_once基本相同

include和require都是用来引入外部文件的函数,但是它们有一些区别:

  1. include是包含文件,如果引入的文件不存在,会发出警告,但脚本会继续执行;而require是必须包含文件,如果引入的文件不存在,会发出致命错误,脚本会停止执行。

  2. include可以多次引入同一个文件,而require只会引入一次。

  3. include可以在条件语句中使用,而require不可以。

  4. include的执行速度比require慢,因为include会在每次调用时都进行文件搜索和读取,而require只会在第一次调用时进行文件搜索和读取,之后直接使用缓存的结果。

包含基本语法:

include‘文件名字’;

include(‘文件名字’);要求系统能够找到

如果包含的是变量,则有可能存在漏洞

2、远程文件包含

它的主要问题在于应用程序未能正确验证和过滤用户提供的外部文件路径,导致攻击者能够通过构造恶意的文件路径来包含远程服务器上的恶意文件。

#Web 漏洞核心:

1、可控变量

通过对变量的构造,形成sql注入类的攻击方式

2、特定函数-函数的多样化

找到高危函数进行攻击