GKCTF re wp

考试时的一个比赛,没怎么做题,现在来补一下,然后写的过程比较简单。

总结一下学到的新知识把

  • 解密网站https://www.chinabaiker.com/cyberchef.htm
  • 然后Enigma Virtual Box封包后的exe
  • tracerpid 反调试
  • 动调so文件,终于解决了,虽然目前只能调x86的,但也不错了,后面去问问其他师傅怎么弄的其他环境。

Crash

一个go语言写的程序,用ida7.6直接打开就可以还原符号表了。

程序逻辑也比较清晰,先判断格式,然后长度为43,分4段加密,3DES加密然后base64处理,hash-sha256,hash-sha512,hash-md5。

3DES找到密文和key,iv后直接用脚本解就行,在线网站也行https://www.chinabaiker.com/cyberchef.htm,hash就爆破吧。

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

from Crypto.Cipher import DES3
import base64

str1 ="o/aWPjNNxMPZDnJlNp0zK5+NLPC4Tv6kqdJqjkL0XkA="
s=base64.b64decode(str1)
c = s
key = b'WelcomeToTheGKCTF2021XXX'
iv = b'1Ssecret'

des = DES3.new(key, DES3.MODE_CBC, iv1)

m = des.decrypt(c)

print(m)

import hashlib

for a in range(0,128):
for b in range(0,128):
for c in range(0,128):
for d in range(0,128):
str = chr(a)+chr(b)+chr(c)+chr(d)
flag = hashlib.md5(str.encode('utf-8')).hexdigest()
if flag == 'ff6e2fd78aca4736037258f0ede4ecf0':
print(str, end='')


import hashlib

for a in range(0,128):
for b in range(0,128):
for c in range(0,128):
for d in range(0,128):
str = chr(a)+chr(b)+chr(c)+chr(d)
flag = hashlib.sha256(str.encode('utf-8')).hexdigest()
if flag == '6e2b55c78937d63490b4b26ab3ac3cb54df4c5ca7d60012c13d2d1234a732b74':
print(str, end='')
# GKCTF{87f645e9-b628-412f-9d7a-e402f20af940}

QQQQT

Enigma Virtual Box封包后的exe,还是第一次遇到,下载EnigmaVBUnpacker解包,然后分析解包后的exe,发现就是一个base58,表都没有改,写个python解一下就行了。

1
2
3
4
5
6

import base58

s='56fkoP8KhwCf3v7CEz'
print(base58.b58decode(s))
#12t4tww3r5e77

SoMuchCode

程序难点在垃圾代码太多,处理方法的话就是动调输入值,然后去找到调用输入的地方,会发现就是一个xxtea加密,通过不断的调试发现只是改了dealt,只是xxtea中间的for循环直接没了,变成了一步步的。然后后面就需要得到密文了,密文是在后面调试过程中生成的。

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

#include<stdio.h>

void decrypt(unsigned int *code ,unsigned int *key ,unsigned int n)
{
unsigned int next,end,sum;
unsigned int rounds,e,delta=0x33445566;
int i;

rounds=6+52/n;
sum=rounds*delta;
next=code[0];//设置next为code的第一个
do
{
e=(sum>>2)&3;
for(i=n-1;i>0;i--)//解密最后一个到第二个
{
end=code[i-1];
code[i]-=(( (end>>5^next<<2) + (next>>3^end<<4) ) ^ ( (sum^next) + (key[(i&3)^e]^end) ))&0xffffffff;
next=code[i];
}
end=code[n-1];
code[0]-=(( (end>>5^next<<2) + (next>>3^end<<4) ) ^ ( (sum^next) +(key[i&3^e]^end) ))&0xffffffff;
next=code[0];
sum-=delta;
}while(--rounds);
}
int main()
{
unsigned int key[4]={0x000036B0, 0x00013816, 0x00000010, 0x0001E0F3};
unsigned int n=8;
int i;
unsigned int code[8]={0x993CAB5C, 0x3F40E129, 0x777791DE, 0x737DFEA6, 0x0ECCF59E6, 0x0C9604CE3, 0x9682C0A5, 0x556F2A1E};
decrypt(code,key,n);
for(i=0;i<8;i++)
{
printf("%c%c%c%c",*((char*)&code[i]+0),*((char*)&code[i]+1),*((char*)&code[i]+2),*((char*)&code[i]+3));
}

}
//9b34a61df773acf0e4dec25ea5fb0e29

app-debug

先拖到jeb中看看,发现check函数在so文件里面,然后分析so文件发现了一个tracerpid 反调试,一篇比较好的文章https://www.jianshu.com/p/cae682a27f0c,对付这种反调试是把TracerPid的值改为0就行了。这个反调试实际上就是将check函数里面的key给改了。

然后本来想ida结合adb调试看看的,发现so文件只给了arm的,雷电模拟器是x86架构的,就算了,反正这个加密也不难。安卓动调挺烦的,环境太苛刻了。

分析check函数,发现就是一个改了dealt的tea加密,key用反调试改了。

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

#include<stdio.h>

void decrypt(unsigned int *code , unsigned int *key)
{
unsigned int delta=0x458BCD42;
unsigned int v0,v1,sum=delta*32,i;// sum=0xC6EF3720

v0=code[0];
v1=code[1];
for(i=0;i<32;i++)
{
v1-=( (v0<<4)+key[2] ) ^ (v0+sum) ^ ( (v0>>5)+key[3] );
v0-=( (v1<<4)+key[0] ) ^ (v1+sum) ^ ( (v1>>5)+key[1] );
sum-=delta;
}
code[0]=v0;
code[1]=v1;
}


int main()
{
unsigned int key[4]={9,7,8,6};
unsigned int code[2]={0xF5A98FF3,0xA21873A3};
int i;
decrypt(code,key);
for(i=0;i<2;i++)
{
printf("%c%c%c%c",*((char*)(&code[i])),*((char*)&code[i]+1),*((char*)&code[i]+2),*((char*)&code[i]+3));
}
}
//GKcTFg0

KillerAid

这道题非常的恶心,把dll拖到ida里面用findcrypto插件发现了aes的表,加密函数在checkcode,整个逻辑用了aes里面的一些处理,但是不是aes,ida里面看起太恶心了,有时间在看看吧。