KCTF-CCG CrackMe crypto 1.0
继续分享一个KCTF里面的题,也是比较古老的题。
首先查壳
提示是tElock壳,下面提示工具RL!detElock,
提示成功了,但运行不了,拖入IDA,发现逻辑正常,估计是加了保护,也懒得看,直接分析源码
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{dword_4171EC = (int)hInstance;dword_413118(hInstance, 101, 0, sub_401230, 101);return 0;
}
WinMain显示,事件回调为sub_401230
int __stdcall sub_401230(int a1, int a2, int a3, int a4)
{int v4; // ebxint v5; // esiint v6; // ebpint v8; // eaxint v9; // eaxint v10; // eaxint v11; // ebxchar v12[64]; // [esp+60h] [ebp-7Ch] BYREFint v13[4]; // [esp+A0h] [ebp-3Ch] BYREFchar v14[4]; // [esp+B0h] [ebp-2Ch] BYREFint v15; // [esp+B4h] [ebp-28h]int v16; // [esp+B8h] [ebp-24h]switch ( a2 ){case 272:sub_401490(a1);v8 = dword_41314C(a1, 1008);dword_413114(v8);v9 = dword_41311C(dword_4171EC, 103);dword_4171E8 = v9;if ( v9 ){dword_413140(a1, 128, 1, v9);dword_413140(a1, 128, 0, dword_4171E8);}v10 = dword_413158(a1, 0);v11 = v10;if ( v10 ){dword_413154(v10, 2048, 0, 0);dword_413154(v11, 0, 1148, aAbout);}break;case 273:if ( (unsigned __int16)a3 == 1002 )goto LABEL_8;if ( (unsigned __int16)a3 != 1003 ){
LABEL_9:dword_413144(a1, a2, a3, a4);return 0;}if ( dword_413150(a1, 1008, &unk_417180, 101) && dword_413150(a1, 1007, &unk_417100, 128) ){if ( (unsigned __int8)sub_401610(&unk_417180, &unk_417100) )dword_413124(a1, aSuccessfullyRe, aGreat, 64);elsedword_413124(a1, aIncorrectSeria, aFailed, 16);}break;case 15:v4 = dword_413130(a1, v12);dword_413128(a1, v13);v5 = dword_413120(dword_4171EC, 105);dword_413014(v5, 24, v14);v6 = dword_413004(v4);dword_413010(v6, v5);dword_413000(v4, 0, 0, v13[2] - v13[0], v16, v6, 0, 0, v15, v16, 13369376);dword_413008(v6);dword_41312C(a1, v12);dword_41300C(v5);return 0;case 274:if ( a3 == 1148 )dword_413124(a1, aCcgCryptoCrack, aAboutThisKeyge, 0);return 0;case 16:
LABEL_8:dword_413148(a1, 0);return 0;default:goto LABEL_9;}return 0;
}
消息273为register按钮点击事件,首先判断Name和Serial都不为空,然后获取输入值,再调用sub_401610检查
int __cdecl sub_401610(int a1, int a2)
{int v2; // esichar *v3; // ebxunsigned __int16 v4; // axint v5; // esichar v6; // dlint v7; // eaxchar v9[4]; // [esp+0h] [ebp-1CCh] BYREFchar v10[88]; // [esp+4h] [ebp-1C8h] BYREFchar v11[8]; // [esp+5Ch] [ebp-170h] BYREFchar v12[8]; // [esp+64h] [ebp-168h] BYREFchar v13[5]; // [esp+6Ch] [ebp-160h] BYREFchar v14[3]; // [esp+71h] [ebp-15Bh] BYREFchar v15[260]; // [esp+74h] [ebp-158h] BYREFint v16; // [esp+178h] [ebp-54h] BYREFint v17; // [esp+17Ch] [ebp-50h] BYREFint v18; // [esp+180h] [ebp-4Ch] BYREFint v19; // [esp+184h] [ebp-48h] BYREFchar v20[32]; // [esp+188h] [ebp-44h] BYREFint v21[6]; // [esp+1A8h] [ebp-24h] BYREFint v22; // [esp+1C8h] [ebp-4h]v21[5] = (int)v9;sub_401000(v9);v22 = 0;v2 = dword_413094(a2);v3 = (char *)operator new(v2);v4 = sub_401020(a2, v3, v2);if ( v4 < 8u )goto LABEL_12;v3[v4] = 0;v5 = 8;if ( v4 > 8u ){do{v6 = v3[v5];if ( v6 < 48 || v6 > 57 )goto LABEL_12;}while ( ++v5 < v4 );}sub_408310(v10);v7 = dword_413094(&unk_417180);sub_408340(v10, &unk_417180, v7);sub_4085F0(v10);qmemcpy(v13, ")G\a", 3);v13[3] = -123;v13[4] = -121;qmemcpy(v14, "3%D", sizeof(v14));sub_408FF0(v13, 8, v15);sub_4090F0(v3, 8, v15);if ( memcmp(v11, v3, 8u) ){
LABEL_12:sub_4092DC(v3);v22 = -1;nullsub_1(v9);return 0;}v16 = 0;v17 = 0;v18 = 0;v19 = 0;sub_4071D0(v3 + 8, (int)&v16);sub_4092DC(v3);sub_4071D0(a65537, (int)&v17);sub_406ED0(aB80a90bf53c6c9, (int)&v18);sub_405E40(v16, v17, v18, &v19);sub_4014F0(v12, 8, v20);v21[0] = 0;sub_406ED0(v20, (int)v21);if ( sub_402290(v21[0], v19) ){v22 = -1;nullsub_1(v9);return 0;}else{v22 = -1;nullsub_1(v9);return 1;}
}
dword_413094=strlen, sub_401020查看代码
int __stdcall sub_401020(int a1, int a2, unsigned __int16 a3)
{int v3; // esiint v4; // ecx__int16 v5; // axint v6; // ebxchar v9; // [esp+10h] [ebp-24h]char v10; // [esp+11h] [ebp-23h]char v11; // [esp+12h] [ebp-22h]int v12; // [esp+14h] [ebp-20h]char v13; // [esp+18h] [ebp-1Ch]v3 = a3;if ( (a3 & 3) != 0 )return 0;v4 = a1;v5 = a3 / 4;v6 = 0;if ( a3 ){v12 = 0;do{v9 = sub_4011A0(*(_BYTE *)(a1 + v12));v10 = sub_4011A0(*(_BYTE *)(a1 + v12 + 1));v11 = sub_4011A0(*(_BYTE *)(a1 + v12 + 2));v13 = sub_4011A0(*(_BYTE *)(a1 + v12 + 3));*(_BYTE *)((unsigned __int16)v6 + a2) = (v10 >> 4) | (4 * v9);*(_BYTE *)((unsigned __int16)(v6 + 1) + a2) = (v11 >> 2) | (16 * v10);*(_BYTE *)((unsigned __int16)(v6 + 2) + a2) = v13 | (v11 << 6);v12 = (unsigned __int16)(v12 + 4);v6 += 3;}while ( v12 < a3 );v5 = a3 / 4;v4 = a1;v3 = a3;}if ( *(_BYTE *)(v3 + v4 - 1) != 61 )return (unsigned __int16)(3 * v5);if ( *(_BYTE *)(v3 + v4 - 2) == 61 )return (unsigned __int16)(3 * v5 - 2);elsereturn (unsigned __int16)(3 * v5 - 1);
}
明显的base64解码特征,即为base64解码Serial并返回解码后字符串长度。由此可知,Serial是一个base64编码的字符串。
解码后,检查解码后长度是否小于8,小于8则报错。
长度大于等于8时,检查第9位后面是否全是数字,有不是数字的报错。
char __cdecl sub_408340(int a1, char *a2, unsigned int a3)
{char result; // alint v5; // edxunsigned int v6; // ecxunsigned int v7; // esiint v8[19]; // [esp+10h] [ebp-4Ch] BYREFresult = a3;v5 = (*(_DWORD *)a1 >> 3) & 0x3F;v6 = *(_DWORD *)a1 + 8 * a3;if ( v6 < *(_DWORD *)a1 )++*(_DWORD *)(a1 + 4);*(_DWORD *)a1 = v6;*(_DWORD *)(a1 + 4) += a3 >> 29;v7 = a3 - 1;if ( a3 ){do{result = *a2;*(_BYTE *)(v5 + a1 + 24) = *a2++;++v5;--v7;if ( v5 == 64 ){v8[0] = *(unsigned __int8 *)(a1 + 24) | (*(unsigned __int8 *)(a1 + 25) << 8) | (*(unsigned __int8 *)(a1 + 26) << 16) | (*(unsigned __int8 *)(a1 + 27) << 24);v8[1] = *(unsigned __int8 *)(a1 + 28) | (*(unsigned __int8 *)(a1 + 29) << 8) | (*(unsigned __int8 *)(a1 + 30) << 16) | (*(unsigned __int8 *)(a1 + 31) << 24);v8[2] = *(unsigned __int8 *)(a1 + 32) | (*(unsigned __int8 *)(a1 + 33) << 8) | (*(unsigned __int8 *)(a1 + 34) << 16) | (*(unsigned __int8 *)(a1 + 35) << 24);v8[3] = *(unsigned __int8 *)(a1 + 36) | (*(unsigned __int8 *)(a1 + 37) << 8) | (*(unsigned __int8 *)(a1 + 38) << 16) | (*(unsigned __int8 *)(a1 + 39) << 24);v8[4] = *(unsigned __int8 *)(a1 + 40) | (*(unsigned __int8 *)(a1 + 41) << 8) | (*(unsigned __int8 *)(a1 + 42) << 16) | (*(unsigned __int8 *)(a1 + 43) << 24);v8[5] = *(unsigned __int8 *)(a1 + 44) | (*(unsigned __int8 *)(a1 + 45) << 8) | (*(unsigned __int8 *)(a1 + 46) << 16) | (*(unsigned __int8 *)(a1 + 47) << 24);v8[6] = *(unsigned __int8 *)(a1 + 48) | (*(unsigned __int8 *)(a1 + 49) << 8) | (*(unsigned __int8 *)(a1 + 50) << 16) | (*(unsigned __int8 *)(a1 + 51) << 24);v8[7] = *(unsigned __int8 *)(a1 + 52) | (*(unsigned __int8 *)(a1 + 53) << 8) | (*(unsigned __int8 *)(a1 + 54) << 16) | (*(unsigned __int8 *)(a1 + 55) << 24);v8[8] = *(unsigned __int8 *)(a1 + 56) | (*(unsigned __int8 *)(a1 + 57) << 8) | (*(unsigned __int8 *)(a1 + 58) << 16) | (*(unsigned __int8 *)(a1 + 59) << 24);v8[9] = *(unsigned __int8 *)(a1 + 60) | (*(unsigned __int8 *)(a1 + 61) << 8) | (*(unsigned __int8 *)(a1 + 62) << 16) | (*(unsigned __int8 *)(a1 + 63) << 24);v8[10] = *(unsigned __int8 *)(a1 + 64) | (*(unsigned __int8 *)(a1 + 65) << 8) | (*(unsigned __int8 *)(a1 + 66) << 16) | (*(unsigned __int8 *)(a1 + 67) << 24);v8[11] = *(unsigned __int8 *)(a1 + 68) | (*(unsigned __int8 *)(a1 + 69) << 8) | (*(unsigned __int8 *)(a1 + 70) << 16) | (*(unsigned __int8 *)(a1 + 71) << 24);v8[12] = *(unsigned __int8 *)(a1 + 72) | (*(unsigned __int8 *)(a1 + 73) << 8) | (*(unsigned __int8 *)(a1 + 74) << 16) | (*(unsigned __int8 *)(a1 + 75) << 24);v8[13] = *(unsigned __int8 *)(a1 + 76) | (*(unsigned __int8 *)(a1 + 77) << 8) | (*(unsigned __int8 *)(a1 + 78) << 16) | (*(unsigned __int8 *)(a1 + 79) << 24);v8[14] = *(unsigned __int8 *)(a1 + 80) | (*(unsigned __int8 *)(a1 + 81) << 8) | (*(unsigned __int8 *)(a1 + 82) << 16) | (*(unsigned __int8 *)(a1 + 83) << 24);v8[15] = *(unsigned __int8 *)(a1 + 84) | (*(unsigned __int8 *)(a1 + 85) << 8) | (*(unsigned __int8 *)(a1 + 86) << 16) | (*(unsigned __int8 *)(a1 + 87) << 24);result = sub_4088A0(a1 + 8, v8);v5 = 0;}}while ( v7 != -1 );}return result;
}
int __cdecl sub_4088A0(_DWORD *a1, _DWORD *a2)
{int v2; // edxint v3; // ediint v4; // esiint v5; // ebxint v6; // ebpint v7; // ecxint v8; // edxint v9; // ebxint v10; // ebpint v11; // esiint v12; // ecxint v13; // ebxint v14; // edxint v15; // ediint v16; // eaxint v17; // ecxint v18; // ebpint v19; // edxint v20; // ebxint v21; // ecxint v22; // eaxint v23; // edxint v24; // esiint v25; // ediint v26; // eaxint v27; // ebxint v28; // ecxint v29; // edxint v30; // eaxint v31; // ebxint v32; // ecxint v33; // esiint v34; // eaxint v35; // edxint v36; // ebxint v37; // esiint v38; // eaxint v39; // edxint v40; // ebpint v41; // esiint v42; // eaxint v43; // edxint v44; // ebpint v45; // ediint v46; // esiint v47; // eaxint v48; // ebpint v49; // edxint v50; // esiint v51; // eaxint v52; // ebxint v53; // ecxint v54; // edxint v55; // eaxint v56; // ediint v57; // esiint v58; // ebpint v59; // ebxint v60; // ecxint v61; // eaxint v62; // edxint v63; // ebpint v64; // ecxint result; // eaxint v66; // [esp+8h] [ebp-68h]int v67; // [esp+Ch] [ebp-64h]int v68; // [esp+10h] [ebp-60h]int v69; // [esp+14h] [ebp-5Ch]int v70; // [esp+18h] [ebp-58h]int v71; // [esp+20h] [ebp-50h]int v72; // [esp+24h] [ebp-4Ch]int v73; // [esp+28h] [ebp-48h]int v74; // [esp+2Ch] [ebp-44h]int v75; // [esp+30h] [ebp-40h]int v76; // [esp+34h] [ebp-3Ch]int v77; // [esp+38h] [ebp-38h]int v78; // [esp+3Ch] [ebp-34h]int v79; // [esp+40h] [ebp-30h]int v80; // [esp+44h] [ebp-2Ch]int v81; // [esp+48h] [ebp-28h]int v82; // [esp+4Ch] [ebp-24h]int v83; // [esp+50h] [ebp-20h]int v84; // [esp+58h] [ebp-18h]v82 = a1[1];v70 = a1[2];v66 = a1[3];v2 = v82 + __ROL4__(*a1 + *a2 + (v66 & ~v82 | v70 & v82) - 680876936, 7);v72 = a2[1];v3 = v2 + __ROL4__(v72 + (v70 & ~v2 | v2 & v82) + v66 - 389564586, 12);v67 = a2[2];v4 = v3 + __ROL4__(v70 + v67 + (v82 & ~v3 | v3 & v2) + 606105819, 17);v75 = a2[3];v5 = v4 + __ROL4__(v82 + v75 + (v2 & ~v4 | v3 & v4) - 1044525330, 22);v68 = a2[4];v6 = v5 + __ROL4__(v68 + v2 + (v3 & ~v5 | v4 & v5) - 176418897, 7);v76 = a2[5];v7 = v6 + __ROL4__(v76 + (v4 & ~v6 | v6 & v5) + v3 + 1200080426, 12);v69 = a2[6];v8 = v7 + __ROL4__(v69 + v4 + (v5 & ~v7 | v7 & v6) - 1473231341, 17);v79 = a2[7];v9 = v8 + __ROL4__(v79 + v5 + (v6 & ~v8 | v7 & v8) - 45705983, 22);v71 = a2[8];v10 = v9 + __ROL4__(v71 + v6 + (v7 & ~v9 | v8 & v9) + 1770035416, 7);v73 = a2[9];v11 = v10 + __ROL4__(v73 + (v8 & ~v10 | v10 & v9) + v7 - 1958414417, 12);v74 = a2[10];v12 = v11 + __ROL4__(v74 + v8 + (v9 & ~v11 | v11 & v10) - 42063, 17);v78 = a2[11];v13 = __ROL4__(v78 + v9 + (v10 & ~v12 | v11 & v12) - 1990404162, 22);v77 = a2[12];v84 = v12 + v13 + __ROL4__(v77 + v10 + (v11 & ~(v12 + v13) | v12 & (v12 + v13)) + 1804603682, 7);v80 = a2[13];v14 = v84 + __ROL4__(v80 + (v12 & ~v84 | v84 & (v12 + v13)) + v11 - 40341101, 12);v81 = a2[14];v15 = v14 + __ROL4__(v81 + v12 + (~v14 & (v12 + v13) | v14 & v84) - 1502002290, 17);v83 = a2[15];v16 = v15 + __ROL4__(v83 + v12 + v13 + (~v15 & v84 | v14 & v15) + 1236535329, 22);v17 = v16 + __ROL4__(v72 + v84 + (v15 & ~v14 | v14 & v16) - 165796510, 5);v18 = v17 + __ROL4__(v69 + (v16 & ~v15 | v17 & v15) + v14 - 1069501632, 9);v19 = v18 + __ROL4__(v78 + v15 + (v17 & ~v16 | v18 & v16) + 643717713, 14);v20 = v19 + __ROL4__(*a2 + v16 + (v18 & ~v17 | v17 & v19) - 373897302, 20);v21 = v20 + __ROL4__(v76 + v17 + (v19 & ~v18 | v18 & v20) - 701558691, 5);v22 = v21 + __ROL4__(v74 + (v20 & ~v19 | v21 & v19) + v18 + 38016083, 9);v23 = v22 + __ROL4__(v83 + v19 + (v21 & ~v20 | v22 & v20) - 660478335, 14);v24 = v23 + __ROL4__(v68 + v20 + (v22 & ~v21 | v21 & v23) - 405537848, 20);v25 = v24 + __ROL4__(v73 + v21 + (v23 & ~v22 | v22 & v24) + 568446438, 5);v26 = v25 + __ROL4__(v81 + (v24 & ~v23 | v25 & v23) + v22 - 1019803690, 9);v27 = v26 + __ROL4__(v75 + v23 + (v25 & ~v24 | v26 & v24) - 187363961, 14);v28 = v27 + __ROL4__(v71 + v24 + (v26 & ~v25 | v25 & v27) + 1163531501, 20);v29 = v28 + __ROL4__(v80 + v25 + (v27 & ~v26 | v26 & v28) - 1444681467, 5);v30 = v29 + __ROL4__(v67 + (v28 & ~v27 | v29 & v27) + v26 - 51403784, 9);v31 = v30 + __ROL4__(v79 + v27 + (v29 & ~v28 | v30 & v28) + 1735328473, 14);v32 = v31 + __ROL4__(v77 + v28 + (v30 & ~v29 | v29 & v31) - 1926607734, 20);v33 = v32 + __ROL4__(v76 + v29 + (v30 ^ v31 ^ v32) - 378558, 4);v34 = v33 + __ROL4__(v71 + (v31 ^ v32 ^ v33) + v30 - 2022574463, 11);v35 = v34 + __ROL4__(v78 + v31 + (v32 ^ v33 ^ v34) + 1839030562, 16);v36 = v35 + __ROL4__(v81 + v32 + (v33 ^ v34 ^ v35) - 35309556, 23);v37 = v36 + __ROL4__(v72 + v33 + (v34 ^ v35 ^ v36) - 1530992060, 4);v38 = v37 + __ROL4__(v68 + (v35 ^ v36 ^ v37) + v34 + 1272893353, 11);v39 = v38 + __ROL4__(v79 + v35 + (v36 ^ v37 ^ v38) - 155497632, 16);v40 = v39 + __ROL4__(v74 + v36 + (v37 ^ v38 ^ v39) - 1094730640, 23);v41 = v40 + __ROL4__(v80 + v37 + (v38 ^ v39 ^ v40) + 681279174, 4);v42 = v41 + __ROL4__(*a2 + (v39 ^ v40 ^ v41) + v38 - 358537222, 11);v43 = v42 + __ROL4__(v75 + v39 + (v40 ^ v41 ^ v42) - 722521979, 16);v44 = v43 + __ROL4__(v69 + v40 + (v41 ^ v42 ^ v43) + 76029189, 23);v45 = v44 + __ROL4__(v73 + v41 + (v42 ^ v43 ^ v44) - 640364487, 4);v46 = v45 + __ROL4__(v77 + (v43 ^ v44 ^ v45) + v42 - 421815835, 11);v47 = v46 + __ROL4__(v83 + v43 + (v44 ^ v45 ^ v46) + 530742520, 16);v48 = v47 + __ROL4__(v67 + v44 + (v45 ^ v46 ^ v47) - 995338651, 23);v49 = v48 + __ROL4__(*a2 + v45 + (v47 ^ (v48 | ~v46)) - 198630844, 6);v50 = v49 + __ROL4__((v48 ^ (v49 | ~v47)) + v79 + v46 + 1126891415, 10);v51 = v50 + __ROL4__(v81 + v47 + (v49 ^ (v50 | ~v48)) - 1416354905, 15);v52 = v51 + __ROL4__(v76 + v48 + (v50 ^ (v51 | ~v49)) - 57434055, 21);v53 = v52 + __ROL4__(v77 + v49 + (v51 ^ (v52 | ~v50)) + 1700485571, 6);v54 = v53 + __ROL4__((v52 ^ (v53 | ~v51)) + v75 + v50 - 1894986606, 10);v55 = v54 + __ROL4__(v74 + v51 + (v53 ^ (v54 | ~v52)) - 1051523, 15);v56 = v55 + __ROL4__(v72 + v52 + (v54 ^ (v55 | ~v53)) - 2054922799, 21);v57 = v56 + __ROL4__(v71 + v53 + (v55 ^ (v56 | ~v54)) + 1873313359, 6);v58 = v57 + __ROL4__((v56 ^ (v57 | ~v55)) + v83 + v54 - 30611744, 10);v59 = v58 + __ROL4__(v69 + v55 + (v57 ^ (v58 | ~v56)) - 1560198380, 15);v60 = v59 + __ROL4__(v80 + v56 + (v58 ^ (v59 | ~v57)) + 1309151649, 21);v61 = v60 + __ROL4__(v68 + v57 + (v59 ^ (v60 | ~v58)) - 145523070, 6);v62 = v61 + __ROL4__((v60 ^ (v61 | ~v59)) + v78 + v58 - 1120210379, 10);v63 = v62 + __ROL4__(v67 + v59 + (v61 ^ (v62 | ~v60)) + 718787259, 15);v64 = __ROL4__(v73 + v60 + (v62 ^ (v63 | ~v61)) - 343485551, 21);result = *a1 + v61;*a1 = result;a1[1] = v82 + v63 + v64;a1[2] = v70 + v63;a1[3] = v66 + v62;return result;
}
sub_4088A0就是未修改的MD5Transform,可以看出,sub_408340和 sub_4085F0计算了Name的MD5.
int __cdecl sub_408FF0(int a1, int a2, int a3)
{int v3; // edxint v4; // eaxint v5; // ebxint v6; // ediint v7; // ebp__int64 v8; // raxint result; // eaxint v10; // [esp+18h] [ebp-1Ch]int v11; // [esp+1Ch] [ebp-18h]int v12; // [esp+1Ch] [ebp-18h]int v13; // [esp+20h] [ebp-14h]v13 = 0;v3 = 1;v4 = 3;v11 = 0;v10 = 2;do{*(_BYTE *)(v11 + a3) = v13;*(_BYTE *)((__int16)v3 + a3) = v3;*(_BYTE *)((__int16)v10 + a3) = v10;*(_BYTE *)((__int16)v4 + a3) = v4;v3 += 4;v10 += 4;v4 += 4;v13 += 4;v11 = (__int16)v13;}while ( (__int16)v13 < 256 );*(_BYTE *)(a3 + 256) = 0;*(_BYTE *)(a3 + 257) = 0;v5 = 0;v6 = 0;v12 = 0;v7 = a3;do{v8 = v12 + *(unsigned __int8 *)(v5 + a1) + *(unsigned __int8 *)(v6 + a3);v12 = (unsigned __int8)((BYTE4(v8) ^ ((BYTE4(v8) ^ v8) - BYTE4(v8))) - BYTE4(v8));sub_4091C0(v7, a3 + v12);result = (unsigned int)(v5 + 1) / (__int64)a2;v5 = (unsigned __int8)((unsigned int)(v5 + 1) % (__int64)a2);++v7;++v6;}while ( v6 < 256 );return result;
}
int __cdecl sub_4090F0(int a1, int a2, int a3)
{int v3; // ebxint result; // eax__int64 v5; // rax__int64 v6; // raxint v7; // [esp+10h] [ebp-1Ch]int v8; // [esp+14h] [ebp-18h]int v9; // [esp+18h] [ebp-14h]LOBYTE(v3) = *(_BYTE *)(a3 + 256);result = *(unsigned __int8 *)(a3 + 257);if ( a2 > 0 ){v7 = 0;v8 = 0;v9 = *(unsigned __int8 *)(a3 + 257);do{v3 = (unsigned __int8)(v3 + 1);v5 = v9 + *(unsigned __int8 *)(a3 + v3);v9 = (unsigned __int8)((BYTE4(v5) ^ ((BYTE4(v5) ^ v5) - BYTE4(v5))) - BYTE4(v5));sub_4091C0(v3 + a3, a3 + v9);v6 = *(unsigned __int8 *)(v9 + a3) + *(unsigned __int8 *)(a3 + v3);*(_BYTE *)(v7 + a1) ^= *(_BYTE *)((unsigned __int8)((BYTE4(v6) ^ ((BYTE4(v6) ^ v6) - BYTE4(v6))) - BYTE4(v6)) + a3);v7 = (__int16)++v8;}while ( a2 > (__int16)v8 );result = v9;}*(_BYTE *)(a3 + 256) = v3;*(_BYTE *)(a3 + 257) = result;return result;
}
sub_408FF0、sub_4090F0符合明显的RC4加密特点,秘钥为V13。
之后判断MD5的前8个字节,与Serial解码后的前8个字节RC4加密后相同。
sub_4071D0为10进制字符串转大整数,sub_406ED0为16进制字符串转大整数。sub_405E40为大整数模运算。最后,sub_405E40运算结果与MD5的后8字节相等。标准的已知e,n,c求m模型。
到这里,逻辑分析完了,破解思路就是先计算Name的MD5,然后将前8个字节进行RC4解密,得到未编码的serial的前8字节,再根据已知e,n,c求出第9字节开始的数字,最后进行base64编码。
写exp如下
from Crypto.Util.number import *
from gmpy2 import *
from Crypto.Cipher import ARC4 as rc4cipher
import base64
import hashlibdef fermat_attack(n):a = isqrt(n)b2 = a*a - nb = isqrt(n)count = 0while b*b != b2:a = a + 1b2 = a*a - nb = math.isqrt(b2)count += 1p = a+bq = a-bassert n == p * qreturn p, qmd5 = hashlib.md5(b'KCTF').hexdigest()
#print(md5)key = b')G\x07\x85\x873%D'
enc = rc4cipher.new(key)
res = enc.decrypt(bytes.fromhex(md5[:16]))
#print(res.hex())n = 0xB80A90BF53C6C979
e = 65537
c = int(md5[16:32], 16)p, q = fermat_attack(n)
phi = (p-1)*(q-1)
d = invert(e, phi)m = pow(c, d, n)
#print(m)
fullvalue = res + str(m).encode()
flag = base64.b64encode(fullvalue).decode()
print(flag)