2022KCTF

签到题

main函数

整个函数的分析很简单,sub_7FF677E44260函数可以根据动调得到结果

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
void *v3; // rax
int i; // [rsp+20h] [rbp-F8h]
int v6; // [rsp+24h] [rbp-F4h]
int v7; // [rsp+28h] [rbp-F0h]
struct std::_Container_base0 *v8; // [rsp+38h] [rbp-E0h]
char v9[32]; // [rsp+40h] [rbp-D8h] BYREF
__int64 SerialNumber[4]; // [rsp+60h] [rbp-B8h] BYREF
_QWORD UserName[4]; // [rsp+80h] [rbp-98h] BYREF
__int64 v12[4]; // [rsp+A0h] [rbp-78h] BYREF
_QWORD v13[4]; // [rsp+C0h] [rbp-58h] BYREF
__int64 v14[4]; // [rsp+E0h] [rbp-38h] BYREF

sub_7FF677E43320(UserName);
sub_7FF677E43320(SerialNumber);
sub_7FF677E43B40(&qword_7FF677E7A340, "User-Name:");
sub_7FF677E43F10(&qword_7FF677E7A580, UserName);
sub_7FF677E43B40(&qword_7FF677E7A340, "Serial-Number:");
sub_7FF677E43F10(&qword_7FF677E7A580, SerialNumber);
if ( len(SerialNumber) != 32 )
sub_7FF677E42D50();
sub_7FF677E43210(v14, "4fc0296a51e6d90c794c91951886dc2b");
sub_7FF677E43210(v13, "1841352");
v8 = sub_7FF677E44260(v9, v13, UserName); // v8 = v13 + UserName
MD5(v12, v8); // v12 = MD5(v8)
for ( i = 0; i < 32; ++i )
{
v6 = (i + *operate__(v14, i)) % 32; // v6 = (i + *(v14 + i)) % 32;
v7 = *operate__(SerialNumber, i); // v7 = *(SerialNumber + i)
// SerialNumber[i] == (v14[i] + i ) % 32
if ( v7 != *operate__(v12, v6) ) // v7 != *(v12 + v6)
sub_7FF677E42D50();
}
v3 = sub_7FF677E43B40(&qword_7FF677E7A340, "Success");
_CallMemberFunction0(v3, sub_7FF677E44350);
system("pause");
sub_7FF677E43180(v12);
sub_7FF677E43180(v13);
sub_7FF677E43180(v14);
sub_7FF677E43180(SerialNumber);
sub_7FF677E43180(UserName);
return 0;
}

最后的脚本

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

def encode(UserName):
table = "4fc0296a51e6d90c794c91951886dc2b"
salt = "1841352"
res = ''
test = md5((salt + UserName).encode('utf-8')).hexdigest()
for i in range(len(test)):
res += test[(ord(table[i]) + i) % 32]
return res

def test():
UserName = "6EA73E0FBD3DDC10"
print("UserName: {}".format(UserName))
print("SerialNumber: {}".format(encode(UserName)))

def Solve():
UserName = "KCTF"
print("UserName: {}".format(UserName))
print("SerialNumber: {}".format(encode(UserName)))
if __name__ == '__main__':
Solve()
#UserName: KCTF
#SerialNumber: 213d1aada77bf4a51441947c515199fb

看了98k战队的wp,才知道这些都是string类的成员函数,正确的函数名是

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
void *v3; // rax
int i; // [rsp+20h] [rbp-F8h]
int v6; // [rsp+24h] [rbp-F4h]
int v7; // [rsp+28h] [rbp-F0h]
std::string *v8; // [rsp+38h] [rbp-E0h]
std::string v9; // [rsp+40h] [rbp-D8h] BYREF
std::string serial; // [rsp+60h] [rbp-B8h] BYREF
std::string username; // [rsp+80h] [rbp-98h] BYREF
std::string digest; // [rsp+A0h] [rbp-78h] BYREF
std::string salt; // [rsp+C0h] [rbp-58h] BYREF
std::string tmp; // [rsp+E0h] [rbp-38h] BYREF

std::string::ctr_1(&username);
std::string::ctr_1(&serial);
std::ostream::write(&std::cout, "User-Name:");
std::istream::read(&std::cin, &username);
std::ostream::write(&std::cout, "Serial-Number:");
std::istream::read(&std::cin, &serial);
if ( std::string::size(&serial) != 32 )
fail();
std::string::ctr_0(&tmp, "4fc0296a51e6d90c794c91951886dc2b");
std::string::ctr_0(&salt, "1841352");
v8 = std::string::operator_add(&v9, &salt, &username);
MD5(&digest, v8);
for ( i = 0; i < 32; ++i )
{
v6 = (i + *std::string::at(&tmp, i)) % 32;
v7 = *std::string::at(&serial, i);
if ( v7 != *std::string::at(&digest, v6) )
fail();
}
v3 = std::ostream::write(&std::cout, "Success");
std::ostream::write_0(v3, std::endl);
system("pause");
std::string::dtor(&digest);
std::string::dtor(&salt);
std::string::dtor(&tmp);
std::string::dtor(&serial);
std::string::dtor(&username);
return 0;
}

第六题

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
unsigned int v4; // ebx
int v5; // eax
unsigned int v6; // edi
_DWORD *v7; // esi
_DWORD *v8; // esi
_DWORD Str[32]; // [esp+4h] [ebp-A0h] BYREF
char v11[8]; // [esp+84h] [ebp-20h] BYREF
char String[8]; // [esp+8Ch] [ebp-18h] BYREF
int v13; // [esp+94h] [ebp-10h]
int v14; // [esp+98h] [ebp-Ch]
int v15; // [esp+9Ch] [ebp-8h]

memset(Str, 0, sizeof(Str));
printf("please input :\n");
scanf_s("%s", Str);
if ( strlen(Str) != 14 )
goto LABEL_19;
String[5] = 0;
*(_DWORD *)String = Str[0];
String[4] = Str[1];
v3 = atoi(String);
v15 = *(_DWORD *)((char *)&Str[1] + 1);
v11[5] = 0;
*(_DWORD *)v11 = *(_DWORD *)((char *)&Str[2] + 1);
v4 = v3;
v11[4] = BYTE1(Str[3]);
v5 = atoi(v11);
v13 = 0;
v6 = v5;
v14 = 1;
srand(v4);
v7 = &unk_40F000;
while ( rand() == *v7 )
{
if ( (int)++v7 >= (int)&unk_40F050 )
goto LABEL_7;
}
v14 = 0;
LABEL_7:
srand(v6);
v8 = &unk_40F050;
while ( rand() == *v8 )
{
if ( (int)++v8 >= (int)&dword_40F0A0 )
goto LABEL_12;
}
v14 = 0;
LABEL_12:
if ( (_BYTE)v15 == 'K' && *(_WORD *)((char *)&v15 + 1) == 'TC' && HIBYTE(v15) == 'F' )
v13 = 1;
if ( v14 && v13 )
{
printf("success : %s\n", (const char *)Str);
system("pause");
}
else
{
LABEL_19:
printf("error\n");
system("pause");
}
return 0;
}

非常简单的随机数爆破

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
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

int bruteforce(int* values, int n) {
for (int i = 0; i < 100000; i++) {
int flag = 1;
srand(i);
for (int j = 0; j < n; j++) {
if (values[j] != rand()) {
flag = 0;
break;
}
}
if (flag)
return i;
}

assert(0);
}

int main() {
int _a[] = { 15356, 8563, 9659, 14347, 11283, 30142, 29542, 18083, 5057, 5531, 23391, 21327, 20023, 14852, 4865, 23820, 16725, 18665, 25042, 24920 };
int _b[] = { 11190, 27482, 980, 5419, 28164, 9548, 16558, 22218, 6113, 21959, 13889, 11580, 2625, 19397, 25139, 8167, 28165, 3950, 25496, 27351 };
int a = bruteforce(_a, 20);
int b = bruteforce(_b, 20);

printf("%dKCTF%d\n", a, b);
return 0;
}
//14725KCTF83690

2022KCTF
http://example.com/2023/08/13/2022KCTF/
Author
Eutop1a
Posted on
August 13, 2023
Licensed under