[SCTF2019]creakme 知识点
看起来很麻烦,一步步慢慢看吧
主函数 int __cdecl main (int argc, const char **argv, const char **envp) { HMODULE v3; int v4; _DWORD *v5; unsigned int v6; _DWORD *v7; unsigned int v8; char *v9; unsigned int v10; unsigned int v11; bool v12; unsigned __int8 v13; unsigned __int8 v14; unsigned __int8 v15; int v16; void *v17; void *v18; const char *v19; int v20; void *Block[5 ]; unsigned int v23; void *v24[5 ]; unsigned int v25; char Src[48 ]; int v27; v3 = GetModuleHandleW(0 ); sub_402320(v3); sub_4024A0(); v4 = sub_402870(std ::cout , "welcome to 2019 sctf" ); std ::ostream::operator <<(v4, sub_402AC0); sub_402870(std ::cout , "please input your ticket:" ); sub_402AF0(std ::cin , Src); v24[4 ] = 0 ; v25 = 15 ; LOBYTE(v24[0 ]) = 0 ; sub_401D30(v24, Src, strlen (Src)); v27 = 0 ; v5 = sub_4020D0(Block, (int )v24); v6 = strlen (aPvfqyc4ttc2uxr); v7 = v5; if ( v5[5 ] >= 0x10 u ) v7 = (_DWORD *)*v5; v8 = v5[4 ]; v9 = aPvfqyc4ttc2uxr; v10 = v8; if ( v6 < v8 ) v10 = v6; v12 = v10 < 4 ; v11 = v10 - 4 ; if ( v12 ) { LABEL_8: if ( v11 == -4 ) goto LABEL_17; } else { while ( *v7 == *(_DWORD *)v9 ) { ++v7; v9 += 4 ; v12 = v11 < 4 ; v11 -= 4 ; if ( v12 ) goto LABEL_8; } } v12 = *(_BYTE *)v7 < (unsigned __int8)*v9; if ( *(_BYTE *)v7 != *v9 || v11 != -3 && ((v13 = *((_BYTE *)v7 + 1 ), v12 = v13 < (unsigned __int8)v9[1 ], v13 != v9[1 ]) || v11 != -2 && ((v14 = *((_BYTE *)v7 + 2 ), v12 = v14 < (unsigned __int8)v9[2 ], v14 != v9[2 ]) || v11 != -1 && (v15 = *((_BYTE *)v7 + 3 ), v12 = v15 < (unsigned __int8)v9[3 ], v15 != v9[3 ]))) ) { v16 = v12 ? -1 : 1 ; goto LABEL_18; } LABEL_17: v16 = 0 ; LABEL_18: if ( !v16 ) { if ( v6 <= v8 ) v16 = v6 < v8; else v16 = -1 ; } if ( v23 >= 0x10 ) { v17 = Block[0 ]; if ( v23 + 1 >= 0x1000 ) { v17 = (void *)*((_DWORD *)Block[0 ] - 1 ); if ( (unsigned int )(Block[0 ] - v17 - 4 ) > 0x1F ) invalid_parameter_noinfo_noreturn(); } sub_402F05(v17); } v27 = -1 ; Block[4 ] = 0 ; v23 = 15 ; LOBYTE(Block[0 ]) = 0 ; if ( v25 >= 0x10 ) { v18 = v24[0 ]; if ( v25 + 1 >= 0x1000 ) { v18 = (void *)*((_DWORD *)v24[0 ] - 1 ); if ( (unsigned int )(v24[0 ] - v18 - 4 ) > 0x1F ) invalid_parameter_noinfo_noreturn(); } sub_402F05(v18); } v19 = "Have fun!" ; if ( v16 ) v19 = "A forged ticket!!" ; v20 = sub_402870(std ::cout , v19); std ::ostream::operator <<(v20, sub_402AC0); system("pause" ); return 0 ; }
sub_402320 & sub_4024A0 void __thiscall sub_402320 (_DWORD *this ) { int v1; __int16 v2; const char *v3; int i; int v5; v1 = this [15 ]; v2 = *(_WORD *)((char *)this + v1 + 6 ); v3 = (char *)this + v1 + 248 ; for ( i = 0 ; i < v2; ++i ) { v5 = strcmp (v3, ".SCTF" ); if ( v5 ) v5 = v5 < 0 ? -1 : 1 ; if ( !v5 ) { DebugBreak(); return ; } v3 += 40 ; } }
int sub_4024A0 () { void *v1; v1 = NtCurrentPeb()->UnicodeCaseTableData; if ( NtCurrentPeb()->BeingDebugged || v1 == (void *)112 ) exit (-5 ); return ((int (*)(void ))dword_404000[0 ])(); }
观察到byte_404000为数据,却在函数中return,可以猜测为smc
那么直接进入动调环节,进入sub_402320函数jmp掉DebugBreak,继续执行到call 404000一直按F7,发现\>pvfqYc,4tTc2UxRmlJ,sB{Fh4Ck2:CFOb4ErhtIcoLo
变为nKnbHsgqD3aNEB91jB3gEzAr+IklQwT1bSs3+bXpeuo=
sub_4020D0 继续分析加密函数
void *__fastcall sub_4020D0 (void *a1, int a2) { char *v2; int v3; char *v4; int v5; char v6; int v7; char v8; int v9; char *v10; unsigned int v11; char *v12; char v13; signed int v14; char *v15; char *v16; signed int v17; int v19; int v20; int v21; int v22; unsigned int v24; size_t Size; size_t Sizea; char *Block; unsigned int v28; char *v29; void **v30; char v31; int v32; size_t v33; int v34; char v35[128 ]; int v36; v2 = (char *)a2; v28 = *(_DWORD *)(a2 + 16 ); v3 = 16 * ((v28 >> 4 ) + 1 ); v24 = v3; Size = v3 + 1 ; Block = (char *)unknown_libname_1 (v3 + 1 ); memset (Block, 0 , v3 + 1 ); if ( *((_DWORD *)v2 + 5 ) >= 0x10 u ) v2 = *(char **)v2; v4 = Block; v5 = Block - v2; do { v6 = *v2++; v2[v5 - 1 ] = v6; } while ( v6 ); v7 = v28 & 0xF ; if ( 16 - v7 > 0 ) { v8 = 16 - v7; v9 = 16843009 * (unsigned __int8)(16 - v7); v10 = &Block[16 * (v28 >> 4 ) + v7]; v4 = Block; v11 = (unsigned int )(16 - v7) >> 2 ; memset32 (v10, v9, v11); memset (&v10[4 * v11], v9, v8 & 3 ); } v4[v3] = 0 ; v12 = (char *)unknown_libname_1 (Size); v29 = v12; memset (v12, 0 , Size); v30 = &AES::`vftable' ; v31 = 0 ; v32 = 0 ; v33 = 0 ; v34 = 0 ; v36 = 0 ; sub_401690 ((int )&v30, v19, v20, v21, v22); v13 = v31; if ( v31 ) { if ( v24 ) { v14 = v33; if ( !(v24 % v33) ) { v15 = Block; Sizea = 0 ; if ( v24 / v33 ) { while ( 1 ) { v16 = v35; if ( v13 ) { v17 = 0 ; if ( v14 > 0 ) { do *v16++ ^= v15[v17++]; while ( v17 < (int )v33 ); } } sub_4013E0 (v35, v12); memcpy (v35, v12, v33); v14 = v33; v15 += v33; v12 += v33; if ( ++Sizea >= v24 / v33 ) break ; v13 = v31; } } v12 = v29; } } } sub_401A70 (a1, v12, v24); j_j_free (Block); j_j_free (v12); return a1; }
sub_401690 改了一些数据类型
int __thiscall sub_401690 (int this , int a2, int a3, int a4, int a5) { int *v5; int v6; int v7; BOOL v8; int v9; int v10; int v11; int v12; int *v13; int v14; int *v15; unsigned __int8 *v16; int v17; int *v18; int result; int *v20; int v21; int v22; int v23; int v24; int v25; int v26; int v27; int v28; int v29; int v30; int v31; char *v32; int v33; int *v34; int v35; int v36; int *v37; int v38; int v39; int v40; int *v41; int v42; int *v43; __int64 v44; __int64 v45; int v46; int *v47; int *v48; int v49; int v50; int v52; int v53; int v54; int *v55; int *v56; int *v57; int *v58; char *v59; int v60; int v61; v5 = (int *)this ; *(_DWORD *)(this + 972 ) = 16 ; *(_DWORD *)(this + 968 ) = 16 ; *(_OWORD *)(this + 980 ) = xmmword_407360; memcpy ((void *)(this + 1012 ), &xmmword_407360, *(_DWORD *)(this + 972 )); v6 = v5[242 ]; if ( v6 == 16 ) { v9 = v5[243 ]; if ( v9 == 16 ) { v7 = 10 ; goto LABEL_9; } v8 = v9 != 24 ; } else { if ( v6 != 24 ) { v7 = 14 ; goto LABEL_9; } v8 = v5[243 ] == 32 ; } v7 = 2 * v8 + 12 ; LABEL_9: v5[244 ] = v7; v10 = 0 ; v11 = v5[244 ]; v12 = v5[243 ] / 4 ; v61 = v12; if ( v11 >= 0 ) { v13 = v5 + 2 ; do { if ( v12 > 0 ) { memset (v13, 0 , 4 * v12); v12 = v61; } v11 = v5[244 ]; ++v10; v13 += 8 ; } while ( v10 <= v11 ); } v14 = 0 ; if ( v11 >= 0 ) { v15 = v5 + 122 ; do { if ( v12 > 0 ) { memset (v15, 0 , 4 * v12); v12 = v61; } v11 = v5[244 ]; ++v14; v15 += 8 ; } while ( v14 <= v11 ); } v16 = "sycloversyclover" ; v60 = v12 * (v11 + 1 ); v17 = v5[242 ]; v18 = v5 + 261 ; result = v17 / 4 ; v20 = v5 + 261 ; v54 = v17 / 4 ; v56 = v5 + 261 ; if ( v17 / 4 > 0 ) { v21 = v17 / 4 ; do { v22 = *v16; v16 += 4 ; v22 <<= 24 ; *v20++ = v22; v23 = v22 | (*(v16 - 3 ) << 16 ); *(v20 - 1 ) = v23; v24 = v23 | (*(v16 - 2 ) << 8 ); *(v20 - 1 ) = v24; result = v24 | *(v16 - 1 ); *(v20 - 1 ) = result; --v21; } while ( v21 ); v5 = (int *)this ; v12 = v61; v18 = v56; } v25 = v17 / 4 ; v26 = 0 ; if ( v54 > 0 ) { v58 = v18; do { if ( v26 >= v60 ) goto LABEL_44; v27 = v26++; v29 = v27 % v12; v28 = v27 / v12; v5[8 * v28 + 2 + v29] = *v58; v25 = v17 / 4 ; v30 = v29 + 8 * (v5[244 ] - v28); result = *v58; v5[v30 + 122 ] = *v58; v12 = v61; ++v58; } while ( v26 < v54 ); } if ( v26 < v60 ) { v59 = (char *)&unk_406B40; do { v31 = v5[v25 + 260 ]; v32 = v59++; v33 = (unsigned __int8)byte_405DE0[HIBYTE (v31)] ^ (((unsigned __int8)byte_405DE0[(unsigned __int8)v31] ^ (((unsigned __int8)byte_405DE0[BYTE1 (v31)] ^ ((*v32 ^ byte_405DE0[BYTE2 (v31)]) << 8 )) << 8 )) << 8 ); result = (int )(v5 + 261 ); v5[261 ] ^= v33; if ( v25 == 8 ) { v37 = v5 + 262 ; v38 = 3 ; do { v39 = *(v37++ - 1 ); *(v37 - 1 ) ^= v39; --v38; } while ( v38 ); v40 = 3 ; v5[265 ] ^= (unsigned __int8)byte_405DE0[(unsigned __int8)v5[264 ]] ^ (((unsigned __int8)byte_405DE0[BYTE1 (v5[264 ])] ^ (((unsigned __int8)byte_405DE0[(unsigned __int8)BYTE2 (v5[264 ])] ^ (byte_405DE0[HIBYTE (v5[264 ])] << 8 )) << 8 )) << 8 ); v41 = v5 + 266 ; do { v42 = *(v41++ - 1 ); *(v41 - 1 ) ^= v42; --v40; } while ( v40 ); } else { if ( v25 <= 1 ) goto LABEL_39; v34 = v5 + 262 ; v35 = v25 - 1 ; do { v36 = *(v34++ - 1 ); *(v34 - 1 ) ^= v36; --v35; } while ( v35 ); } result = (int )(v5 + 261 ); LABEL_39: v52 = 0 ; if ( v25 > 0 ) { v43 = (int *)result; v57 = (int *)result; while ( v26 < v60 ) { v44 = v26++; v45 = v44 % v61; LODWORD (v44) = v44 / v61; v5[8 * (_DWORD)v44 + 2 + (_DWORD)v45] = *v43; v25 = v17 / 4 ; v5[8 * (v5[244 ] - (_DWORD)v44) + 122 + (_DWORD)v45] = *v57; result = v52 + 1 ; v43 = v57 + 1 ; v52 = result; ++v57; if ( result >= v54 ) goto LABEL_43; } break ; } LABEL_43: ; } while ( v26 < v60 ); } LABEL_44: v46 = 1 ; v53 = 1 ; if ( v5[244 ] <= 1 ) { *((_BYTE *)v5 + 4 ) = 1 ; } else { result = v61; v47 = v5 + 130 ; v55 = v5 + 130 ; do { if ( result > 0 ) { v48 = v47; v49 = result; do { v50 = *v48++; *(v48 - 1 ) = dword_406B60[(unsigned __int8)v50] ^ dword_4066E0[BYTE1 (v50)] ^ dword_405EE0[BYTE2 (v50)] ^ dword_406F60[HIBYTE (v50)]; --v49; } while ( v49 ); result = v61; v46 = v53; v47 = v55; } ++v46; v47 += 8 ; v53 = v46; v55 = v47; } while ( v46 < v5[244 ] ); *((_BYTE *)v5 + 4 ) = 1 ; } return result; }
get_Flag 通过里面调用的函数名就可知为AES加密,通过以下代码,可知为CBC模式,然后找密码和偏移值
do *v16++ ^= v15[v17++]; while ( v17 < (int )v33 );
密码为 v16 = “sycloversyclover”;
发现xmmword_407360
v5 = (int *)this ; *(_DWORD *)(this + 972 ) = 16 ; *(_DWORD *)(this + 968 ) = 16 ; *(_OWORD *)(this + 980 ) = xmmword_407360; memcpy ((void *)(this + 1012 ), &xmmword_407360, *(_DWORD *)(this + 972 ));进入为 xmmword 66746373667463736674637366746373 h 转为char ,记得小端转大端, sctfsctfsctfsctf
aes加密算法,CBC模式,密码为sycloversyclover,偏移量为sctfsctfsctfsctf,在线解密
flag{Ae3_C8c_I28_pKcs79ad4}