2019KCTF 晋级赛Q1 | 第二题点评及解题思路

transformers,这个80年代一度风靡全球的名词,是否唤起了你热血澎湃的记忆呢?

谈到《变形金刚》,你脑海中出现的是大黄蜂Sam?还是擎天柱?

当汽车超人遇到CTF,会迸发出怎样的火花?

接下来,让我们一起来看看

KCTF 晋级赛Q1第二题——《变形金钢》


这道题目仅有44支战队破解,围观人数截止目前达到3506人。


出题团队

ech0

战队成员看雪ID:卓桐

个人主页:https://bbs.pediy.com/user-670707.htm

野生的程序员,从移植Android rom到自学Android应用开发,进而深入Android系统源码、Android黑科技,沉迷开发hook框架。

现就职某安全公司主攻移动安全。


看雪CTFcrownless评委 点评

《变形金钢》这道题主要涉及两方面的知识点:Android应用基础和最基础的加解密、编码,考验了参赛者的开发、逆向、算法知识,是一道中规中矩的基础题。


题目设计思路

主要涉及两方面的知识点。

1、Android应用基础,Activity的方法和调用顺序。因为onStart在onCreate之后执行,所以重写了父类的onStart方法,并在onStart方法中覆盖了onCreate的逻辑,进而最后生效的是onStart内的逻辑。

2、最常用、基础的加解密、编码。选择了Rc4加密算法,并在加密完一个字节后对该字节进行变形的base64编码。解题的思路就是写出变形base64的解码代码,再Rc4解密,即可得出答案。

综上,这是一道基础题,旨在巩固基础的开发、逆向、算法知识。


题目破解思路

这道题目破解思路由看雪ID:HHHso 提供

比较快速的方式是拿到中间运输的核心表,然后使用核心表拟合内部逻辑,相对来说比较省事,关键是避免全逻辑拟合的纰漏。

0x00 一切的关键在于native化的eq()函数

0x01 在核心Transformers\lib\armeabi-v7a\liboo000oo.so 中

导出函数datadiv_decode5009363700628197108 会通过简单的异或解密处 eq()函数的native化信息

0x02 解密后得到如图,于是我们可以定位到对应eq()函数的本地代码函数 A8DEE784 Hi_eq_sub_A8DEE784

(注意:后面的+1,无伤大雅,忽略就行,这是由于ARM的字对齐会忽略最低bit)

eq()函数伪码相对有点绕,不过我们只关注如何使用key,这时会发现前半部分都是由

unsigned char g_gidstr[] = "650f909c-7217-3647-9331-c82df8b98e98";

char vs16[] = "dbeafc2409715836";

经过多次变换得到ref100,然后才使用key参与运算

int __fastcall sub_A8DEE784(int a1)

{

size_t guidlen;// r10

unsigned __int8*gidbuf1_reverse_gid;// r6

_BYTE*gidbuf2_nosplit;// r8

_BYTE*gidbuf3;// r11

signed int gidbuf2_nosplit_len;// r0

size_t v6;// r2

char*v7;// r1

int v8;// r3

int v9;// r1

unsigned int v10;// r2

int v11;// r3

int v12;// r0

int v13;// r4

unsigned __int8 v14;// r0

_BYTE*v15;// r3

char*v16;// r5

char*pbuf2;// r4

int i;// r5

int v19;// r1

int ix;// r0

signed int v21;// r1

int v22;// r2

size_t pwdlen;// r0

unsigned int loc_pwdlen;// r8

unsigned int b64_salt_size;// r5

_BYTE*pwdsaltstr;// r0

int v27;// r3

int txi;// r10

unsigned int pwd_idx;// r2

int txj;// r12

bool b31;// zf

_BYTE*v32;// r1

bool b32;// zf

int v34;// r3

int tx;// r1

unsigned __int8 txijvx;// r11

unsigned int v37;// lr

char v38;// r1

char*v39;// r2

int v40;// t1

unsigned int pwd_salt_b64_bytelen;// [sp+4h] [bp-234h]

unsigned int pwd_b64_bitlen;// [sp+8h] [bp-230h]

unsigned int v44;// [sp+10h] [bp-228h]

char*pwd;// [sp+14h] [bp-224h]

char loc_buf100[256];// [sp+18h] [bp-220h]

char buf100_2[256];// [sp+118h] [bp-120h]

int v48;// [sp+218h] [bp-20h]

pwd=(char*)(*(int(**)(void))(*(_DWORD*)a1+676))();

guidlen=strlen(gidstr);

gidbuf1_reverse_gid=(unsigned __int8*)malloc(guidlen);

gidbuf2_nosplit=malloc(guidlen);

gidbuf3=malloc(guidlen);

_aeabi_memclr(gidbuf1_reverse_gid,guidlen);

_aeabi_memclr(gidbuf2_nosplit,guidlen);

_aeabi_memclr(gidbuf3,guidlen);

if(guidlen)

{

gidbuf2_nosplit_len=0;

v6=guidlen;

v7=gidstr;

do

{

v8=(unsigned __int8)*v7++;

if(v8!='-' )

gidbuf2_nosplit[gidbuf2_nosplit_len++]=v8;

--v6;

}

while(v6);

if(gidbuf2_nosplit_len>=1)

{

v9=gidbuf2_nosplit_len-1;

v10=-8;

v11=0;

v12=0;

do

{

if((v11|(v10>>2))>3)

{

v13=v12;

}

else

{

v13=v12+1;

gidbuf1_reverse_gid[v12]='-';

}

v14=gidbuf2_nosplit[v9--];

v11+=0x40000000;

gidbuf1_reverse_gid[v13]=v14;

++v10;

v12=v13+1;

}

while(v9!=-1);

if(v13>=0)

{

v15=gidbuf3;

while(1)

{

v16=(char*)*gidbuf1_reverse_gid;

if((unsigned __int8)((_BYTE)v16-'a') <= 5u )

break;

if((unsigned __int8)((_BYTE)v16-'0') <= 9u )

{

v16=&aDbeafc24097158[(_DWORD)v16-42];

goto LABEL_18;

}

LABEL_19:

*v15++=(_BYTE)v16;

--v12;

++gidbuf1_reverse_gid;

if(!v12)

goto LABEL_20;

}

v16=&aDbeafc24097158[(_DWORD)v16-'a'];

LABEL_18:

LOBYTE(v16)=*v16;

goto LABEL_19;

}

}

}

LABEL_20:

_aeabi_memcpy8(loc_buf100,Hi_gbuf100,256);

pbuf2=buf100_2;

i=0;

do

{

Hi_idx_mod_len(i,guidlen);

buf100_2[i++]=gidbuf3[v19];

}

while(i!=256);

ix=(unsigned __int8)(buf100_2[0]-41);

loc_buf100[0]=loc_buf100[ix];

loc_buf100[ix]=-41;

v21=1;

do

{

v22=(unsigned __int8)loc_buf100[v21];

ix=(ix+(unsigned __int8)buf100_2[v21]+v22)%256;

loc_buf100[v21++]=loc_buf100[ix];

loc_buf100[ix]=v22;

}

while(v21!=256);

pwdlen=strlen(pwd);

loc_pwdlen=pwdlen;

b64_salt_size=(unsigned __int8)gidbuf3[3];

pwd_b64_bitlen=8*(3--3*(pwdlen/3));

pwd_salt_b64_bytelen=b64_salt_size+pwd_b64_bitlen/6;

pwdsaltstr=malloc(pwd_salt_b64_bytelen+1);

if(loc_pwdlen)

{

txi=0;

pwd_idx=0;

txj=0;

v44=b64_salt_size;

do

{

txi=(txi+1)%256;

tx=(unsigned __int8)loc_buf100[txi];

txj=(txj+tx)%256;

loc_buf100[txi]=loc_buf100[txj];

loc_buf100[txj]=tx;

pbuf2=(char*)(unsigned __int8)loc_buf100[txi];

txijvx=loc_buf100[(unsigned __int8)(tx+(_BYTE)pbuf2)]^pwd[pwd_idx];

if(pwd_idx&&(v27=0xAAAAAAAB*(unsigned __int64)pwd_idx>>32,v37=3*(pwd_idx/3),v37!=pwd_idx))

{

b31=pwd_idx==1;

if(pwd_idx!=1)

b31=v37+1==pwd_idx;

if(b31)

{

v32=aAbcdefghijklmn;

pwdsaltstr[v44+pwd_idx]=aAbcdefghijklmn[(unsigned __int8)pwdsaltstr[v44+pwd_idx]|((unsigned int)txijvx>>4)];

pbuf2=&pwdsaltstr[v44+pwd_idx];

v27=4*txijvx&0x3C;

pbuf2[1]=v27;

if(pwd_idx+1>=loc_pwdlen)

goto LABEL_53;

}

else

{

b32=pwd_idx==2;

if(pwd_idx!=2)

b32=v37+2==pwd_idx;

if(b32)

{

pbuf2=(char*)(txijvx&0xC0);

v34=v44+++pwd_idx;

pwdsaltstr[v34]=aAbcdefghijklmn[(unsigned __int8)pwdsaltstr[v34]|((unsigned int)pbuf2>>6)]^0xF;

v27=(int)&pwdsaltstr[v34];

*(_BYTE*)(v27+1)=aAbcdefghijklmn[txijvx&0x3F];

}

}

}

else

{

pwdsaltstr[v44+pwd_idx]=aAbcdefghijklmn[(unsigned int)txijvx>>2]^7;

pbuf2=&pwdsaltstr[v44+pwd_idx];

v27=16*txijvx&0x30;

pbuf2[1]=v27;

if(pwd_idx+1>=loc_pwdlen)

{

v38=aAbcdefghijklmn[v27];

*((_WORD*)pbuf2+1)=';;';

goto LABEL_43;

}

}

++pwd_idx;

}

while(pwd_idx

}

while(1)

{

if(pwd_b64_bitlen)

{

v32=(_BYTE*)1;

pbuf2=(char*)pwd_salt_b64_bytelen;

v39=&Hi_cmp_byte_A8DF04E8;

do

{

v27=(unsigned __int8)pwdsaltstr[b64_salt_size++];

v40=(unsigned __int8)*v39++;

if(v40!=v27)

v32=0u;

}

while(b64_salt_size

}

else

{

v32=(_BYTE*)1;

}

pwdsaltstr=(_BYTE*)(_stack_chk_guard-v48);

if(_stack_chk_guard==v48)

break;

LABEL_53:

v38=v32[v27];

pbuf2[2]='4';

LABEL_43:

pbuf2[1]=v38;

}

return(unsigned __int8)v32;

}

0x03 代码相对比较清晰,由下述横线分为前后两个部分:

(1)上半部分(主要得到loc_buf100表,这个我们可以通过下述断点断下后,通过IDAPython脚本提取buf存储的表;

(2)下半部分就是依次通过(1)表提取因子A与key的字符B异或,得到结果R,而将结果转为类似64进制编码结果。

这里其对64编码结果加了盐,即对特地位异或了不同因子。

最后与Hi_cmp_byte_A8DF04E8 即 xb64_pwd = " {9*8ga*l!Tn?@#fj'j$\\g;;"比较。

0x04 因为关键的都是异或,所以可逆,通过断点处的提取,我们得到初使表,此表没选用一个异或因子后,都会发生变动。

memcpy(&loc_buf100[0],&g_buf100[0],0x100);

unsigned char ref100[] = {

0xF0, 0x37, 0xE1, 0x9B, 0x2A, 0x15, 0x17, 0x9F, 0xD7, 0x58, 0x4D, 0x6E, 0x33, 0xA0, 0x39, 0xAE, 

0x04, 0xD0, 0xBE, 0xED, 0xF8, 0x66, 0x5E, 0x00, 0xD6, 0x91, 0x2F, 0xC3, 0x10, 0x4C, 0xF7, 0xA6, 

0xC1, 0xEC, 0x6D, 0x0B, 0x50, 0x65, 0xBB, 0x34, 0xFA, 0xA4, 0x2D, 0x3B, 0x23, 0xA1, 0x96, 0xD5, 

0x1D, 0x38, 0x56, 0x0A, 0x5D, 0x4F, 0xE4, 0xCC, 0x24, 0x0D, 0x12, 0x87, 0x35, 0x85, 0x8E, 0x6F, 

0xC6, 0x13, 0x9A, 0xD3, 0xFC, 0xE7, 0x08, 0xAC, 0xB7, 0xE9, 0xB0, 0xE8, 0x41, 0xAA, 0x55, 0x53, 

0xC2, 0x42, 0xBC, 0xE6, 0x0F, 0x8A, 0x86, 0xA8, 0xCF, 0x84, 0xC5, 0x48, 0x74, 0x36, 0x07, 0xEB, 

0x88, 0x51, 0xF6, 0x7F, 0x57, 0x05, 0x63, 0x3E, 0xFE, 0xB8, 0xC9, 0xF5, 0xAF, 0xDF, 0xEA, 0x82, 

0x44, 0xF9, 0xCD, 0x06, 0xBA, 0x30, 0x47, 0x40, 0xDE, 0xFD, 0x1C, 0x7C, 0x11, 0x5C, 0x02, 0x31, 

0x2C, 0x9C, 0x5F, 0x46, 0x27, 0xC4, 0x83, 0x73, 0x16, 0x90, 0x20, 0x76, 0x7B, 0xF2, 0xE3, 0xF3, 

0x77, 0x52, 0x80, 0x25, 0x09, 0x26, 0x3F, 0xC7, 0x18, 0x1B, 0xA3, 0xFF, 0xFB, 0xCB, 0xA9, 0x8C, 

0x54, 0x7A, 0x68, 0xB4, 0x70, 0x4B, 0xE2, 0x49, 0x22, 0x7E, 0xA5, 0xB6, 0x81, 0x9D, 0x4E, 0x67, 

0xF1, 0xA7, 0x3C, 0xD9, 0x94, 0xEF, 0x32, 0x6B, 0x1F, 0xB1, 0x60, 0xB9, 0x64, 0x59, 0x01, 0xB3, 

0x7D, 0xE0, 0x6C, 0xAD, 0x97, 0x19, 0xB5, 0x3A, 0xF4, 0xD8, 0x8D, 0x98, 0x03, 0x93, 0x1A, 0xDC, 

0x1E, 0x4A, 0xC0, 0x5A, 0xE5, 0xD1, 0x3D, 0x14, 0xC8, 0x79, 0xBD, 0x43, 0xDB, 0x69, 0xD2, 0x61, 

0x95, 0x9E, 0x21, 0x45, 0x89, 0x2B, 0xAB, 0x29, 0xA2, 0x8B, 0x2E, 0xD4, 0x0E, 0x62, 0xCA, 0x28, 

0xDA, 0x5B, 0x72, 0x8F, 0x99, 0x75, 0xEE, 0x78, 0x0C, 0x71, 0xBF, 0xDD, 0xCE, 0x92, 0x6A, 0xB2

};

有了表,通过简单运算,我们就可以得到key

基本逻辑是我们先值得得到由表的异或因子与key异或的b64编码加密前的结果b64bin

通过b64bin的字节依次与表产生的异或因子异或,即可得到key

txi=0;

i=0;

txj=0;

//v44=b64_salt_size;

do

{

txi=(txi+1)%256;

tx=(unsigned char)loc_buf100[txi];

txj=(txj+tx)%256;

loc_buf100[txi]=loc_buf100[txj];

loc_buf100[txj]=tx;

pwdch=loc_buf100[(unsigned char)(tx+loc_buf100[txi])]^b64bin[i];

gpwd[i] = pwdch;

++i;

}

while(i<16);

printf("-----------------------------------------\n");

txi=0;

i=0;

txj=0;

//v44=b64_salt_size;

do

{

txi=(txi+1)%256;

tx=(unsigned char)ref100[txi];

txj=(txj+tx)%256;

ref100[txi]=ref100[txj];

ref100[txj]=tx;

printf("0x%02X, ",ref100[(unsigned char)(tx+ref100[txi])]);

pwdch=ref100[(unsigned char)(tx+ref100[txi])]^b64bin[i];

gpwd[i] = pwdch;

++i;

}

while(i<20);

printf("gidbuf3 len: %d\tbytes:[%s]\n",16,gpwd);

0x05 如何得到b64bin

这里先直接给出

unsigned char b64bin[16] = {0xFD, 0x1E, 0x8A, 0x4E, 0x09, 0xCA, 0x90, 0x03, 0xE7, 0xF1, 0x85, 0x9F, 0x9B, 0xF7, 0x83, 0x3E};

unsigned char gpwd[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

因为b64bin经过64编码后再局部加密得到 xb64_pwd = " {9*8ga*l!Tn?@#fj'j$\\g;;"

xb64_pwd = " {9*8ga*l!Tn?@#fj'j$"#\\g;;"

b64str = ''

for i in range(0,xb64_pwd.__len__()):

if i%4 == 0:

b64_ch = chr(ord(xb64_pwd[i])^0x07)

elif i%4 == 2:

b64_ch = chr(ord(xb64_pwd[i])^0x0F)

else:

b64_ch = xb64_pwd[i]

b64str+=b64_ch

print b64str.__repr__()

"'{6*?gn*k![n8@,fm'e$^"

我们得到b64局部加密后的结果,再b64解密得到

b64 = r"!:#$%&()+-*/`~_[]{}?<>,.@^abcdefghijklmnopqrstuvwxyz0123456789\'"

b64str = "'{6*?gn*k![n8@,fm'e$"

b64bin = ''

for i in range(0,b64str.__len__(),4):

b3 = b64str[i:i+4]

b0 = ((b64.index(b3[0])<<2)|(b64.index(b3[1])>>4))&0xFF

b1 = ((b64.index(b3[1])<<4)|(b64.index(b3[2])>>2))&0xFF

b2 = (((b64.index(b3[2])&0x3)<<6)|b64.index(b3[3]))&0xFF

b64bin += ''.join([chr(c) for c in [b0,b1,b2]])

print b64bin.__repr__()

'\xfd\x1e\x8aN\t\xca\x90\x03\xe7\xf1\x85\x9f\x9b\xf7\x83'

由于其编码的特殊情形,其最后的"\\g;;"直接解码得到

0x3E = b64.index('\\'))|b64.index('g')

于是有了b64bin,完整代码如下,通过 cl.exe 直接编译,执行得到key,其中前半部分许多位测试过程中国使用的中间拟合逻辑。

由于前半部分拟合出了纰漏,最终直接选中提取其中间运算过程中现成的表来使用,大大简化分析。

//test_main.cpp

//to compile: cl.exe test_main.cpp

//to run: test_main.exe

#include 

#include 

unsigned char g_gidstr[] = "650f909c-7217-3647-9331-c82df8b98e98";

char vs16[] = "dbeafc2409715836";

unsigned char g_buf100[] = {

0xD7, 0xDF, 0x02, 0xD4, 0xFE, 0x6F, 0x53, 0x3C, 0x25, 0x6C, 0x99, 0x97, 0x06, 0x56, 0x8F, 0xDE, 

0x40, 0x11, 0x64, 0x07, 0x36, 0x15, 0x70, 0xCA, 0x18, 0x17, 0x7D, 0x6A, 0xDB, 0x13, 0x30, 0x37, 

0x29, 0x60, 0xE1, 0x23, 0x28, 0x8A, 0x50, 0x8C, 0xAC, 0x2F, 0x88, 0x20, 0x27, 0x0F, 0x7C, 0x52, 

0xA2, 0xAB, 0xFC, 0xA1, 0xCC, 0x21, 0x14, 0x1F, 0xC2, 0xB2, 0x8B, 0x2C, 0xB0, 0x3A, 0x66, 0x46, 

0x3D, 0xBB, 0x42, 0xA5, 0x0C, 0x75, 0x22, 0xD8, 0xC3, 0x76, 0x1E, 0x83, 0x74, 0xF0, 0xF6, 0x1C, 

0x26, 0xD1, 0x4F, 0x0B, 0xFF, 0x4C, 0x4D, 0xC1, 0x87, 0x03, 0x5A, 0xEE, 0xA4, 0x5D, 0x9E, 0xF4, 

0xC8, 0x0D, 0x62, 0x63, 0x3E, 0x44, 0x7B, 0xA3, 0x68, 0x32, 0x1B, 0xAA, 0x2D, 0x05, 0xF3, 0xF7, 

0x16, 0x61, 0x94, 0xE0, 0xD0, 0xD3, 0x98, 0x69, 0x78, 0xE9, 0x0A, 0x65, 0x91, 0x8E, 0x35, 0x85, 

0x7A, 0x51, 0x86, 0x10, 0x3F, 0x7F, 0x82, 0xDD, 0xB5, 0x1A, 0x95, 0xE7, 0x43, 0xFD, 0x9B, 0x24, 

0x45, 0xEF, 0x92, 0x5C, 0xE4, 0x96, 0xA9, 0x9C, 0x55, 0x89, 0x9A, 0xEA, 0xF9, 0x90, 0x5F, 0xB8, 

0x04, 0x84, 0xCF, 0x67, 0x93, 0x00, 0xA6, 0x39, 0xA8, 0x4E, 0x59, 0x31, 0x6B, 0xAD, 0x5E, 0x5B, 

0x77, 0xB1, 0x54, 0xDC, 0x38, 0x41, 0xB6, 0x47, 0x9F, 0x73, 0xBA, 0xF8, 0xAE, 0xC4, 0xBE, 0x34, 

0x01, 0x4B, 0x2A, 0x8D, 0xBD, 0xC5, 0xC6, 0xE8, 0xAF, 0xC9, 0xF5, 0xCB, 0xFB, 0xCD, 0x79, 0xCE, 

0x12, 0x71, 0xD2, 0xFA, 0x09, 0xD5, 0xBC, 0x58, 0x19, 0x80, 0xDA, 0x49, 0x1D, 0xE6, 0x2E, 0xE3, 

0x7E, 0xB7, 0x3B, 0xB3, 0xA0, 0xB9, 0xE5, 0x57, 0x6E, 0xD9, 0x08, 0xEB, 0xC7, 0xED, 0x81, 0xF1, 

0xF2, 0xBF, 0xC0, 0xA7, 0x4A, 0xD6, 0x2B, 0xB4, 0x72, 0x9D, 0x0E, 0x6D, 0xEC, 0x48, 0xE2, 0x33

};

unsigned char ref100[] = {

0xF0, 0x37, 0xE1, 0x9B, 0x2A, 0x15, 0x17, 0x9F, 0xD7, 0x58, 0x4D, 0x6E, 0x33, 0xA0, 0x39, 0xAE, 

0x04, 0xD0, 0xBE, 0xED, 0xF8, 0x66, 0x5E, 0x00, 0xD6, 0x91, 0x2F, 0xC3, 0x10, 0x4C, 0xF7, 0xA6, 

0xC1, 0xEC, 0x6D, 0x0B, 0x50, 0x65, 0xBB, 0x34, 0xFA, 0xA4, 0x2D, 0x3B, 0x23, 0xA1, 0x96, 0xD5, 

0x1D, 0x38, 0x56, 0x0A, 0x5D, 0x4F, 0xE4, 0xCC, 0x24, 0x0D, 0x12, 0x87, 0x35, 0x85, 0x8E, 0x6F, 

0xC6, 0x13, 0x9A, 0xD3, 0xFC, 0xE7, 0x08, 0xAC, 0xB7, 0xE9, 0xB0, 0xE8, 0x41, 0xAA, 0x55, 0x53, 

0xC2, 0x42, 0xBC, 0xE6, 0x0F, 0x8A, 0x86, 0xA8, 0xCF, 0x84, 0xC5, 0x48, 0x74, 0x36, 0x07, 0xEB, 

0x88, 0x51, 0xF6, 0x7F, 0x57, 0x05, 0x63, 0x3E, 0xFE, 0xB8, 0xC9, 0xF5, 0xAF, 0xDF, 0xEA, 0x82, 

0x44, 0xF9, 0xCD, 0x06, 0xBA, 0x30, 0x47, 0x40, 0xDE, 0xFD, 0x1C, 0x7C, 0x11, 0x5C, 0x02, 0x31, 

0x2C, 0x9C, 0x5F, 0x46, 0x27, 0xC4, 0x83, 0x73, 0x16, 0x90, 0x20, 0x76, 0x7B, 0xF2, 0xE3, 0xF3, 

0x77, 0x52, 0x80, 0x25, 0x09, 0x26, 0x3F, 0xC7, 0x18, 0x1B, 0xA3, 0xFF, 0xFB, 0xCB, 0xA9, 0x8C, 

0x54, 0x7A, 0x68, 0xB4, 0x70, 0x4B, 0xE2, 0x49, 0x22, 0x7E, 0xA5, 0xB6, 0x81, 0x9D, 0x4E, 0x67, 

0xF1, 0xA7, 0x3C, 0xD9, 0x94, 0xEF, 0x32, 0x6B, 0x1F, 0xB1, 0x60, 0xB9, 0x64, 0x59, 0x01, 0xB3, 

0x7D, 0xE0, 0x6C, 0xAD, 0x97, 0x19, 0xB5, 0x3A, 0xF4, 0xD8, 0x8D, 0x98, 0x03, 0x93, 0x1A, 0xDC, 

0x1E, 0x4A, 0xC0, 0x5A, 0xE5, 0xD1, 0x3D, 0x14, 0xC8, 0x79, 0xBD, 0x43, 0xDB, 0x69, 0xD2, 0x61, 

0x95, 0x9E, 0x21, 0x45, 0x89, 0x2B, 0xAB, 0x29, 0xA2, 0x8B, 0x2E, 0xD4, 0x0E, 0x62, 0xCA, 0x28, 

0xDA, 0x5B, 0x72, 0x8F, 0x99, 0x75, 0xEE, 0x78, 0x0C, 0x71, 0xBF, 0xDD, 0xCE, 0x92, 0x6A, 0xB2

};

//unsigned char b64bin[18] = {0xF9, 0x1E, 0x8A, 0x4E, 0x09, 0xCA, 0x90, 0x03, 0xE7, 0xF1, 0x85, 0x9F, 0x9B, 0xE7, 0x83, 0x3E, 0x0E, 0x3F};

//unsigned char b64bin[16] = {0xF9, 0x1E, 0x8A, 0x4E, 0x09, 0xCA, 0x90, 0x03, 0xE7, 0xF1, 0x85, 0x9F, 0x9B, 0xE7, 0x83, 0x5E};

unsigned char b64bin[16] = {0xFD, 0x1E, 0x8A, 0x4E, 0x09, 0xCA, 0x90, 0x03, 0xE7, 0xF1, 0x85, 0x9F, 0x9B, 0xF7, 0x83, 0x3E};

unsigned char gpwd[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

void test1(){

unsigned char *gidstr = &g_gidstr[0];

unsigned char *gidbuf1 = NULL;

unsigned char *gidbuf2_nosplit = NULL;

unsigned char *gidbuf3 = NULL;

unsigned char *v7,v14,*v15,pwdch,tx;

char * v16,*pbuf2;

int guidlen,gidbuf2_nosplit_len,v6,v8,v9,v11,v12,v13,ix,v21,v22,txi,txj;

unsigned int v1,i;

char loc_buf100[0x100];

char buf100_2[0x100];

guidlen = strlen((const char*)gidstr);

gidbuf1 = (unsigned char *)malloc(guidlen);

gidbuf2_nosplit = (unsigned char *)malloc(guidlen);

gidbuf3 = (unsigned char *)malloc(guidlen);

memset(gidbuf1,0,guidlen);

memset(gidbuf2_nosplit,0,guidlen);

memset(gidbuf3,0,guidlen);

if(guidlen){

gidbuf2_nosplit_len=0;

v6=guidlen;

v7=gidstr;

do

{

v8=(unsigned char)*v7++;

if(v8!='-' )

gidbuf2_nosplit[gidbuf2_nosplit_len++]=v8;

--v6;

}

while(v6);

}

printf("gidbuf2 len: %d\tbytes:[%s]\n",gidbuf2_nosplit_len,gidbuf2_nosplit);

//gidbuf2 len: 32 bytes:[650f909c721736479331c82df8b98e98]

if(gidbuf2_nosplit_len > 1){

v9=gidbuf2_nosplit_len-1;

v1=-8;

v11=0;

v12=0;

do{

if((v11|(v1>>2))>3){

v13=v12;

}

else{

v13=v12+1;

gidbuf1[v12]='-';

}

v14=gidbuf2_nosplit[v9--];

v11+=0x40000000;

gidbuf1[v13]=v14;

++v1;

v12=v13+1;

}while(v9!=-1);

}

printf("gidbuf1 len: %d %d\tbytes:[%s]\n",v13,v12,gidbuf1);

//gidbuf1 len: 35 bytes:[89e89b8f-d28c-1339-7463-7127c909f056]

if(v13>=0){

v15=gidbuf3;

do{

v16=(char*)gidbuf1;

if((unsigned char)(*v16-'a') <= 5u ){

v16 = &vs16[*v16-'a'];

}else if((unsigned char)(*v16-'0') <= 9u ){

v16=&vs16[*v16-'0'];

}

*v15=*v16;

v15++;

--v12;

++gidbuf1;

}while(v12!=0);

}

printf("gidbuf3 len: %d\tbytes:[%s]\n",v15-gidbuf3,gidbuf3);

//gidbuf3 len: 36 bytes:[09f09b0c-ae0e-baa9-4f2a-4be4e9d9cdc2]

memcpy(&loc_buf100[0],&g_buf100[0],0x100);

pbuf2=&buf100_2[0];

i=0;

do{

buf100_2[i++]=gidbuf3[i%guidlen];

}

while(i!=256);

//

ix=(unsigned char)(buf100_2[0]-41);

loc_buf100[0]=loc_buf100[ix];

loc_buf100[ix]=0xd7;//-41;

v21=1;

do

{

v22=(unsigned char)loc_buf100[v21];

ix=(ix+(unsigned char)buf100_2[v21]+v22)%256;

loc_buf100[v21++]=loc_buf100[ix];

loc_buf100[ix]=v22;

}

while(v21!=256);

printf("-----------------------------------------\n");

for(i=0;i<0x100;i++){

printf("%02X ",(unsigned char)loc_buf100[i]);

if((i+1)%16==0){

printf("\n");

}

}

printf("-----------------------------------------\n");

/*

0xF0, 0x37, 0xE1, 0x9B, 0x2A, 0x15, 0x17, 0x9F, 0xD7, 0x58, 0x4D, 0x6E, 0x33, 0xA0, 0x39, 0xAE, 

0x04, 0xD0, 0xBE, 0xED, 0xF8, 0x66, 0x5E, 0x00, 0xD6, 0x91, 0x2F, 0xC3, 0x10, 0x4C, 0xF7, 0xA6, 

0xC1, 0xEC, 0x6D, 0x0B, 0x50, 0x65, 0xBB, 0x34, 0xFA, 0xA4, 0x2D, 0x3B, 0x23, 0xA1, 0x96, 0xD5, 

0x1D, 0x38, 0x56, 0x0A, 0x5D, 0x4F, 0xE4, 0xCC, 0x24, 0x0D, 0x12, 0x87, 0x35, 0x85, 0x8E, 0x6F, 

0xC6, 0x13, 0x9A, 0xD3, 0xFC, 0xE7, 0x08, 0xAC, 0xB7, 0xE9, 0xB0, 0xE8, 0x41, 0xAA, 0x55, 0x53, 

0xC2, 0x42, 0xBC, 0xE6, 0x0F, 0x8A, 0x86, 0xA8, 0xCF, 0x84, 0xC5, 0x48, 0x74, 0x36, 0x07, 0xEB, 

0x88, 0x51, 0xF6, 0x7F, 0x57, 0x05, 0x63, 0x3E, 0xFE, 0xB8, 0xC9, 0xF5, 0xAF, 0xDF, 0xEA, 0x82, 

0x44, 0xF9, 0xCD, 0x06, 0xBA, 0x30, 0x47, 0x40, 0xDE, 0xFD, 0x1C, 0x7C, 0x11, 0x5C, 0x02, 0x31, 

0x2C, 0x9C, 0x5F, 0x46, 0x27, 0xC4, 0x83, 0x73, 0x16, 0x90, 0x20, 0x76, 0x7B, 0xF2, 0xE3, 0xF3, 

0x77, 0x52, 0x80, 0x25, 0x09, 0x26, 0x3F, 0xC7, 0x18, 0x1B, 0xA3, 0xFF, 0xFB, 0xCB, 0xA9, 0x8C, 

0x54, 0x7A, 0x68, 0xB4, 0x70, 0x4B, 0xE2, 0x49, 0x22, 0x7E, 0xA5, 0xB6, 0x81, 0x9D, 0x4E, 0x67, 

0xF1, 0xA7, 0x3C, 0xD9, 0x94, 0xEF, 0x32, 0x6B, 0x1F, 0xB1, 0x60, 0xB9, 0x64, 0x59, 0x01, 0xB3, 

0x7D, 0xE0, 0x6C, 0xAD, 0x97, 0x19, 0xB5, 0x3A, 0xF4, 0xD8, 0x8D, 0x98, 0x03, 0x93, 0x1A, 0xDC, 

0x1E, 0x4A, 0xC0, 0x5A, 0xE5, 0xD1, 0x3D, 0x14, 0xC8, 0x79, 0xBD, 0x43, 0xDB, 0x69, 0xD2, 0x61, 

0x95, 0x9E, 0x21, 0x45, 0x89, 0x2B, 0xAB, 0x29, 0xA2, 0x8B, 0x2E, 0xD4, 0x0E, 0x62, 0xCA, 0x28, 

0xDA, 0x5B, 0x72, 0x8F, 0x99, 0x75, 0xEE, 0x78, 0x0C, 0x71, 0xBF, 0xDD, 0xCE, 0x92, 0x6A, 0xB2, 

*/

txi=0;

i=0;

txj=0;

//v44=b64_salt_size;

do

{

txi=(txi+1)%256;

tx=(unsigned char)loc_buf100[txi];

txj=(txj+tx)%256;

loc_buf100[txi]=loc_buf100[txj];

loc_buf100[txj]=tx;

pwdch=loc_buf100[(unsigned char)(tx+loc_buf100[txi])]^b64bin[i];

gpwd[i] = pwdch;

++i;

}

while(i<16);

printf("-----------------------------------------\n");

txi=0;

i=0;

txj=0;

//v44=b64_salt_size;

do

{

txi=(txi+1)%256;

tx=(unsigned char)ref100[txi];

txj=(txj+tx)%256;

ref100[txi]=ref100[txj];

ref100[txj]=tx;

printf("0x%02X, ",ref100[(unsigned char)(tx+ref100[txi])]);

pwdch=ref100[(unsigned char)(tx+ref100[txi])]^b64bin[i];

gpwd[i] = pwdch;

++i;

}

while(i<16);

printf("\ngidbuf3 len: %d\tbytes:[%s]\n",16,gpwd);

for(i=0;i<20;i++){

printf("%02X ",(unsigned char)gpwd[i]);

}

printf("\n");

}

int main(int argc,char* argv[]){

test1();

return 0;

}

*本文由看雪论坛原创,转载请注明来源

你可能感兴趣的:(2019KCTF 晋级赛Q1 | 第二题点评及解题思路)