CrackRTF-buuctf

这一题用到了一些windows加密算法中的东西

根据字符串找到了关键的部分函数

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
void FUN_00401690(void)

{
size_t sVar1;
uint uVar2;
int iVar3;
undefined4 *puVar4;
char *pcVar5;
undefined4 local_354 [16];
BYTE local_314 [260];
int local_210;
char local_20c [260];
byte local_108 [256];
undefined4 uStack8;

iVar3 = 0xd4;
puVar4 = local_354;
while (iVar3 != 0) {
iVar3 = iVar3 + -1;
*puVar4 = 0xcccccccc;
puVar4 = puVar4 + 1;
}
_memset(local_108,0,0x104);
_memset(local_20c,0,0x104);
local_210 = 0;
FUN_00401e60((byte *)"pls input the first passwd(1): ");
FUN_00401e00(&DAT_00426104);
sVar1 = _strlen((char *)local_108);
if (sVar1 != 6) {
FUN_00401e60((byte *)"Must be 6 characters!\n");
ExitProcess(0);
__chkesp();
}
local_210 = FUN_00401c30(local_108);
if (local_210 < 100000) {
ExitProcess(0);
__chkesp();
}
FID_conflict:_strcat((char *)local_108,"@DBApp");
pcVar5 = local_20c;
sVar1 = _strlen((char *)local_108);
thunk_FUN_00401230(local_108,sVar1,pcVar5);
iVar3 = __strcmpi(local_20c,"6E32D0943418C2C33385BC35A1470250DD8923A9");
if (iVar3 == 0) {
FUN_00401e60((byte *)"continue...\n\n");
FUN_00401e60((byte *)"pls input the first passwd(2): ");
_memset(local_314,0,0x104);
FUN_00401e00(&DAT_00426104);
sVar1 = _strlen((char *)local_314);
if (sVar1 != 6) {
FUN_00401e60((byte *)"Must be 6 characters!\n");
ExitProcess(0);
__chkesp();
}
FID_conflict:_strcat((char *)local_314,(char *)local_108);
_memset(local_20c,0,0x104);
pcVar5 = local_20c;
sVar1 = _strlen((char *)local_314);
thunk_FUN_00401040(local_314,sVar1,pcVar5);
iVar3 = __strcmpi("27019e688a4e62a649fd99cadaafdb4e",local_20c);
if (iVar3 == 0) {
uVar2 = thunk_FUN_004014d0((LPCSTR)local_314);
if ((uVar2 & 0xff) == 0) {
FUN_00401e60((byte *)"Error!!\n");
ExitProcess(0);
__chkesp();
}
else {
FUN_00401e60((byte *)"bye ~~\n");
}
}
}
uStack8 = 0x4018f6;
__chkesp();
return;
}

需要pass两层密码才可以,仔细看一下加密的部分

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
void __cdecl FUN_00401230(BYTE *param_1,DWORD param_2,LPSTR param_3)

{
int iVar1;
undefined4 *puVar2;
undefined4 local_6c [16];
uint local_2c;
CHAR local_28 [4];
byte local_24 [20];
DWORD local_10;
HCRYPTHASH local_c;
HCRYPTPROV local_8;

iVar1 = 0x1a;
puVar2 = local_6c;
while (iVar1 != 0) {
iVar1 = iVar1 + -1;
*puVar2 = 0xcccccccc;
puVar2 = puVar2 + 1;
}
CryptAcquireContextA(&local_8,(LPCSTR)0x0,(LPCSTR)0x0,1,0xf0000000);
iVar1 = __chkesp();
if (iVar1 != 0) {
CryptCreateHash(local_8,0x8004,0,0,&local_c);
iVar1 = __chkesp();
if (iVar1 == 0) {
CryptReleaseContext(local_8,0);
__chkesp();
}
else {
CryptHashData(local_c,param_1,param_2,0);
iVar1 = __chkesp();
if (iVar1 == 0) {
CryptDestroyHash(local_c);
__chkesp();
CryptReleaseContext(local_8,0);
__chkesp();
}
else {
CryptGetHashParam(local_c,2,local_24,&local_10,0);
__chkesp();
*param_3 = '\0';
local_2c = 0;
while (local_2c < local_10) {
wsprintfA(local_28,"%02X",(uint)local_24[local_2c]);
__chkesp();
lstrcatA(param_3,local_28);
__chkesp();
local_2c = local_2c + 1;
}
CryptDestroyHash(local_c);
__chkesp();
CryptReleaseContext(local_8,0);
__chkesp();
}
}
}
local_8 = 0x4013b8;
__chkesp();
return;
}

第一层加密,重点看看一个函数CryptCreateHash(local_8,0x8004,0,0,&local_c)

上微软查查定义

1
2
3
4
5
6
7
BOOL CryptCreateHash(
HCRYPTPROV hProv,
ALG_ID Algid,
HCRYPTKEY hKey,
DWORD dwFlags,
HCRYPTHASH *phHash
);

hProv
A handle to a CSP created by a call to CryptAcquireContext.

Algid
An ALG_ID value that identifies the hash algorithm to use.

Valid values for this parameter vary, depending on the CSP that is used. For a list of default algorithms, see Remarks.

hKey
If the type of hash algorithm is a keyed hash, such as the Hash-Based Message Authentication Code (HMAC) or Message Authentication Code (MAC) algorithm, the key for the hash is passed in this parameter. For nonkeyed algorithms, this parameter must be set to zero.

For keyed algorithms, the key must be to a block cipher key, such as RC2, that has a cipher mode of Cipher Block Chaining (CBC).

dwFlags
The following flag value is defined.

Value Meaning
CRYPT_SECRETDIGEST0x00000001 This flag is not used.

phHash
The address to which the function copies a handle to the new hash object. When you have finished using the hash object, release the handle by calling the CryptDestroyHash function.

需要关注Algid,定义了加密的方式,在 ALG_ID 查一下0x8004

Identifier Value Description
CALG_SHA 0x00008004 SHA hashing algorithm. This algorithm is supported by the Microsoft Base Cryptographic Provider.
CALG_SHA1 0x00008004 Same as CALG_SHA. This algorithm is supported by the Microsoft Base Cryptographic Provider.

sha1加密,对我们输入的6位纯数字和后面接上的字符串进行sha1加密然后直接进行字符串对比,知道是数字所以爆破非常简单

1
2
3
4
5
6
7
8
9
10
import hashlib

flag2 = '@DBApp'

for i in range(100000, 999999):
h2 = hashlib.sha1((str(i) + flag2).encode('utf-8'))
flags = h2.hexdigest()
if "6e32d0943418c2c33385bc35a1470250dd8923a9" == flags:
print(str(i) + flag2)
print(flags)

输出得到第一部分的密码

1
2
123321@DBApp
6e32d0943418c2c33385bc35a1470250dd8923a9

然后看一下下一部分加密

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
void __cdecl FUN_00401040(BYTE *param_1,DWORD param_2,LPSTR param_3)

{
int iVar1;
undefined4 *puVar2;
undefined4 local_68 [16];
uint local_28;
CHAR local_24 [4];
byte local_20 [16];
DWORD local_10;
HCRYPTHASH local_c;
HCRYPTPROV local_8;

iVar1 = 0x19;
puVar2 = local_68;
while (iVar1 != 0) {
iVar1 = iVar1 + -1;
*puVar2 = 0xcccccccc;
puVar2 = puVar2 + 1;
}
CryptAcquireContextA(&local_8,(LPCSTR)0x0,(LPCSTR)0x0,1,0xf0000000);
iVar1 = __chkesp();
if (iVar1 != 0) {
CryptCreateHash(local_8,0x8003,0,0,&local_c);
iVar1 = __chkesp();
if (iVar1 == 0) {
CryptReleaseContext(local_8,0);
__chkesp();
}
else {
CryptHashData(local_c,param_1,param_2,0);
iVar1 = __chkesp();
if (iVar1 == 0) {
CryptDestroyHash(local_c);
__chkesp();
CryptReleaseContext(local_8,0);
__chkesp();
}
else {
CryptGetHashParam(local_c,2,local_20,&local_10,0);
__chkesp();
*param_3 = '\0';
local_28 = 0;
while (local_28 < local_10) {
wsprintfA(local_24,"%02X",(uint)local_20[local_28]);
__chkesp();
lstrcatA(param_3,local_24);
__chkesp();
local_28 = local_28 + 1;
}
CryptDestroyHash(local_c);
__chkesp();
CryptReleaseContext(local_8,0);
__chkesp();
}
}
}
local_8 = 0x4011c8;
__chkesp();
return;
}

和上面的加密几乎一样,但是这次是0x8003,再查一查

Identifier Value Description
CALG_MD5 0x00008003 MD5 hashing algorithm. This algorithm is supported by the Microsoft Base Cryptographic Provider.

md5加密,并且没有限定字符的范围,下辈子都跑不出来

再往下面看,两层加密都通过之后

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
void __cdecl FUN_004014d0(LPCSTR param_1)

{
int iVar1;
undefined4 *puVar2;
undefined4 local_64 [16];
undefined4 local_24;
LPCVOID local_20;
undefined4 local_1c;
DWORD local_18;
uint local_14;
HGLOBAL local_10;
HRSRC local_c;
HANDLE local_8;

iVar1 = 0x18;
puVar2 = local_64;
while (iVar1 != 0) {
iVar1 = iVar1 + -1;
*puVar2 = 0xcccccccc;
puVar2 = puVar2 + 1;
}
local_8 = (HANDLE)0x0;
local_c = (HRSRC)0x0;
local_10 = (HGLOBAL)0x0;
local_14 = 0;
local_18 = 0;
local_1c = 0;
local_20 = (LPCVOID)0x0;
local_24 = 0;
FindResourceA((HMODULE)0x0,(LPCSTR)0x65,"AAA");
local_c = (HRSRC)__chkesp();
if (local_c != (HRSRC)0x0) {
SizeofResource((HMODULE)0x0,local_c);
local_14 = __chkesp();
LoadResource((HMODULE)0x0,local_c);
local_10 = (HGLOBAL)__chkesp();
if (local_10 != (HGLOBAL)0x0) {
LockResource(local_10);
local_20 = (LPCVOID)__chkesp();
thunk_FUN_00401420(param_1,(int)local_20,local_14);
CreateFileA("dbapp.rtf",0x10000000,0,(LPSECURITY_ATTRIBUTES)0x0,2,0x80,(HANDLE)0x0);
local_8 = (HANDLE)__chkesp();
if (local_8 != (HANDLE)0xffffffff) {
WriteFile(local_8,local_20,local_14,&local_18,(LPOVERLAPPED)0x0);
iVar1 = __chkesp();
if (iVar1 != 0) {
CloseHandle(local_8);
__chkesp();
}
}
}
}
local_8 = (HANDLE)0x40162d;
__chkesp();
return;
}

写了一个dbapp.rtf,写入的内容在上面一个函数

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
void __cdecl FUN_00401420(LPCSTR param_1,int param_2,uint param_3)

{
uint uVar1;
int iVar2;
undefined4 *puVar3;
undefined4 local_50 [16];
uint local_10;
LPCSTR local_c;
undefined4 local_8;

iVar2 = 0x13;
puVar3 = local_50;
while (iVar2 != 0) {
iVar2 = iVar2 + -1;
*puVar3 = 0xcccccccc;
puVar3 = puVar3 + 1;
}
lstrlenA(param_1);
uVar1 = __chkesp();
local_c = param_1;
local_10 = 0;
while (local_10 < param_3) {
*(byte *)(param_2 + local_10) = *(byte *)(param_2 + local_10) ^ param_1[local_10 % uVar1];
local_10 = local_10 + 1;
}
local_8 = 0x4014a3;
__chkesp();
return;
}

发现前面不知从哪里获取了一些内容,然后和我们输入的密码进行了一个循环异或,写入一个rtf文件

这里有一个点就是rtf文件的文件头是固定的6个字符,可以通过这里来算出来输入的第二次密码是什么

可以用ResourceHacker看一下AAA到底是什么

AAA

然后异或一下出来密码

1
2
3
4
5
6
7
8
9
s = "{\\rtf1"

a = [0x05,0x7D,0x41,0x15,0x26,0x01]

flag = ""
for i in range(0,len(s)):
x = ord(s[i]) ^ a[i]
flag += chr(x)
print(flag)

得到第二个密码~!3a@0

两个都通过后会生成一个rtf文件,内容是flag

1
Flag{N0_M0re_Free_Bugs}

但是提交的时候要交小写的flag

Fibonacci-JavisOJ-wp Javis-OJ-wp

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×