网网络安全基础之php开发 文件读取、写入功能的实现

前言

续之前的系列,这里php开发的文件操作的内容读取以及文本写入的部分

文件读取代码的实现

css代码

本系列的php博客都是这个css,名字都是index.css

css 复制代码
/* css样式初始化 */
* {
    font-family: 'Poppins', sans-serif;
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    outline: none;
    border: none;
    text-decoration: none;
    text-transform: capitalize;
    transition: .2s linear;
}

html {
    font-size: 62.5%;
}
/* header样式初始化*/
.header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1000;
    background: #3F3D56;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.header .logo {
    color: white;
    padding: 0 1rem;
}
/* 导航样式 */
.navbar ul{
    display: flex;
}

.navbar ul li{
    font-weight: bold;
    width: 128px;
    list-style: none;
    text-align:center;
}
.navbar ul li a {
    width: 128px;
    line-height: 45px;
    font-size: 1.7rem;
    color: white;
}
.navbar ul li a:hover{
    color: #009933;
}
/* 二级菜单样式 */
.navbar ul li ul{
    position: absolute;
    display: none;
    width: 128px;
    line-height: 45px;
}

.navbar ul li ul li{
    background-color: #3F3D56;
}
/* 悬浮展开二级菜单 */
.navbar ul li ul li a:hover{
    color: white;
}
.navbar ul li ul li:hover{
    background-color: #009933;
}

.navbar ul li:hover ul{
    display: block;
}
/* 网站内容*/
.content{
    margin-top:50px;
}

/*让文件下载的文件列表居中显示*/
.download-links {
    text-align: center; /* 使链接居中 */
    font-family: 'LiSu', 'STLiti', cursive; /* 尝试使用隶书字体,如果不可用则退回到通用草书字体 */
    font-style: italic; /* 设置字体为斜体 */
}

.download-links ul {
    list-style: none;
    padding: 0;
    margin: 0;
    display: inline-block; /* 使 <ul> 内容居中对齐 */
}

.download-links li {
    margin: 10px; /* 添加一些间距 */
}

.download-links a {
    font-size: 18px; /* 可以根据需要调整大小 */
    text-decoration: none;
    color: #000;
}

.download-links a:hover {
    text-decoration: underline;
}

文件内容的读取

新建一个文件file_read.php

plaintext 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Head</title>
    <link rel="stylesheet" href="index.css">
</head>
<body>
<div class="header">
    <a href="index.html" class="logo">
        <h1>wushiyiwuzhong</h1>
    </a>
    <nav class="navbar">
        <ul>
            <li><a href="file_index.php">文件功能导航</a></li>
            <li><a href="file_upload.php">文件上传</a></li>
            <li><a href="file_downlaod.php">文件下载</a></li>
            <li><a href="#">文件删除</a></li>
            <li><a href="#">文件读取</a></li>
            <li><a href="#">文件写入</a></li>
        </ul>
    </nav>
</div>

<div class="download-links">
    <ul>
        <?php
        $files = scandir('.');//扫描当前目录
        $files = array_filter($files, function($file) {
            return is_file($file);
        });

        foreach ($files as $file) {
            // 创建下载链接,指向 download.php,并传递 filename 参数
            echo '<li><a href="file_read.php?filename=' . urlencode($file) . '">' . htmlspecialchars($file) . '</a></li>';
        }
        ?>
    </ul>
</div>
</body>
</html>

<?php
// 读取 filename 参数
$filename = isset($_GET['filename']) ? $_GET['filename'] : '';

$filePath = './' . $filename;

// 检查文件是否存在且可读
if (file_exists($filePath) && is_readable($filePath)) {
    $content = file_get_contents($filePath); // 读取文件内容
    echo nl2br(htmlspecialchars($content)); // 将内容转换为适合在 HTML 中显示的格式
} else {
    echo "无法读取文件";
}

下面是运行效果

随意读取一个文件进行测试

成功读取当前文件的文件内容,尝试读取其他文件

php 复制代码
http://localhost:63342/wushiyiwuzhong.com/file_read.php?filename=../test.txt

成功读取

文件的写入

这里主要使用到的函数是$_SERVERfile_put_contents

知识补充
$_SERVER函数

$_SERVER 是一种超全局变量,在 PHP 中用于收集有关服务器和执行环境的信息。它包含了很多索引,每个索引都有关于服务器或者当前执行脚本的信息。这些信息是由 Web 服务器提供的,因此具体可用的信息取决于服务器软件本身。

以下是一些常用的 $_SERVER 数组索引及其含义:

  • $_SERVER['PHP_SELF']:当前执行脚本的文件名。
  • $_SERVER['GATEWAY_INTERFACE']:服务器使用的 CGI 规范的版本。
  • $_SERVER['SERVER_ADDR']:当前运行脚本所在服务器的 IP 地址。
  • $_SERVER['SERVER_NAME']:当前运行脚本所在服务器的主机名。
  • $_SERVER['SERVER_SOFTWARE']:服务器标识字符串,在响应请求时的头信息中给出。
  • $_SERVER['SERVER_PROTOCOL']:请求页面时通信协议的名称和版本。
  • $_SERVER['REQUEST_METHOD']:访问页面使用的请求方法,例如 "GET", "HEAD", "POST", "PUT"。
  • $_SERVER['REQUEST_TIME']:请求开始时的时间戳。从 PHP 5.1.0 开始可用。
  • $_SERVER['QUERY_STRING']:查询字符串,如果有的话,通过它进行页面访问。
  • $_SERVER['DOCUMENT_ROOT']:当前运行脚本所在的文档根目录,在服务器配置文件中定义。
  • $_SERVER['HTTP_ACCEPT']:当前请求的 Accept: 头信息内容。
  • $_SERVER['HTTP_ACCEPT_CHARSET']:当前请求的 Accept-Charset: 头信息内容(如果存在)。
  • $_SERVER['HTTP_HOST']:当前请求的 Host: 头信息内容。
  • $_SERVER['HTTP_REFERER']:引导用户代理到当前页的前一页的地址(如果存在)。
  • $_SERVER['HTTPS']:如果脚本是通过 HTTPS 协议被访问,则被设为一个非空的值。
  • $_SERVER['REMOTE_ADDR']:浏览当前页面的用户的 IP 地址。
  • $_SERVER['REMOTE_HOST']:浏览当前页面的用户的主机名。
  • $_SERVER['REMOTE_PORT']:用户机器上连接到 Web 服务器所使用的端口号。
  • $_SERVER['SCRIPT_FILENAME']:当前执行脚本的绝对路径名称。
  • $_SERVER['SERVER_ADMIN']:该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。
  • $_SERVER['SERVER_PORT']:Web 服务器使用的端口。默认值为 "80"。
  • $_SERVER['SERVER_SIGNATURE']:包含了服务器版本和虚拟主机名的字符串。
  • $_SERVER['PATH_TRANSLATED']:当前脚本所在文件系统(不是文档根目录)的基本路径。
  • $_SERVER['SCRIPT_NAME']:包含当前脚本的路径。这在页面需要指向自己时非常有用。
  • $_SERVER['REQUEST_URI']:访问此页面所需的 URI。例如 "/index.html"。

注意:不是所有的服务器都会提供所有这些信息,有些服务器可能会省略一些信息或者提供额外的信息,并且某些值可能在命令行运行 PHP 时不可用。这取决于你的服务器配置和 PHP 的安装方式。

$_SERVER函数

file_put_contents() 是 PHP 中一个非常有用的函数,用于写入数据到文件。该函数是 fopen(),fwrite(),和 fclose() 函数的简单一次性替代。

这是基本语法:

php 复制代码
file_put_contents($file, $data, $flags, $context);

参数解释:

  • $file:必需。规定要写入数据的文件。如果文件不存在,此函数将尝试创建该文件。如果文件路径或权限出现问题,或者磁盘空间不足,此函数将返回 false。
  • $data:必需。规定要写入文件的数据。可以是字符串,数组或数据流。
  • $flags:可选。规定如何处理文件。可能的值:
  • FILE_USE_INCLUDE_PATH:搜索 include_path(在 php.ini 中)。
  • FILE_APPEND:在文件末尾追加数据,而不是覆盖。
  • LOCK_EX:在写入时获取一个独占锁定。
  • $context:可选。可以修改流的行为。
    这个函数返回写入到文件中的字节数,如果失败则返回 false。注意,如果在 file_put_contents() 函数中使用了 FILE_APPEND 标记,返回的字节数可能包含了由于追加导致的初始文件大小。下面是一个使用的示例
php 复制代码
<?php
$file = 'example.txt';
$data = 'Hello, World!';
file_put_contents($file, $data);  // 写入数据到文件

$file = 'example.txt';
$data = 'Hello, again!';
file_put_contents($file, $data, FILE_APPEND);  // 追加数据到文件

运行效果如下

使用file_put_contents函数时你需要确保有适当的文件权限来写入或修改文件,否则此函数会执行失败

下面我们来具体实现文件写入,这里模拟的是直接写入到一个php文件中,至于为什么不加一个用户自定义文件是因为懒想让大家更容易理解。

php 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Head</title>
    <link rel="stylesheet" href="index.css">
</head>
<body>
<div class="header">
    <a href="index.html" class="logo">
        <h1>wushiyiwuzhong</h1>
    </a>
    <nav class="navbar">
        <ul>
            <li><a href="file_index.php">文件功能导航</a></li>
            <li><a href="file_upload.php">文件上传</a></li>
            <li><a href="file_downlaod.php">文件下载</a></li>
            <li><a href="#">文件删除</a></li>
            <li><a href="file_read.php">文件读取</a></li>
            <li><a href="file_write.php">文件写入</a></li>
        </ul>
    </nav>
</div>
<div>
    <div class="content">
            <form action="file_write.php" method="post" enctype="application/x-www-form-urlencoded">
                <textarea name="fileContent" rows="4" cols="50" placeholder="请输入文件内容"></textarea><br>
                <input type="submit" value="写入文件" name="submit">
            </form>
    </div>

</div>
</div>
</body>
</html>

<?php
// 检查是否有 POST 请求,并且 'fileContent' 字段是否已经设置
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['submit'])) {
    // 定义要写入的文件名,可以是相对路径或绝对路径
    $filePath = '1.php';//模拟写入文件可控的情况

    // 从表单获取内容
    $content = $_POST['fileContent'];

    // 尝试将内容写入文件
    if (file_put_contents($filePath, $content) !== false) {
        echo "文件写入成功!"."<br><hr>";
    } else {
        echo "文件写入失败,请检查文件路径及权限。";
    }
}

运行效果如下

我们这里直接模拟攻击者写入木马从而控制服务器

访问我们写入的后门文件

成功访问我们的后门文件,如果是真实情况的话我们已经成功获取到了目标服务器的权限

总结

文件的读取、写入还是比较简单的

相关推荐
JaguarJack4 小时前
PHP 的异步编程 该怎么选择
后端·php·服务端
BingoGo4 小时前
PHP 的异步编程 该怎么选择
后端·php
JaguarJack19 小时前
为什么 PHP 闭包要加 static?
后端·php·服务端
ServBay2 天前
垃圾堆里编码?真的不要怪 PHP 不行
后端·php
用户962377954482 天前
CTF 伪协议
php
BingoGo4 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack4 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo5 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack5 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack6 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端