原设计图

Flag格式
NepCTF{%s}
逻辑复原
main
UPX拆壳,main函数逻辑复原得到
- getInput
- checkInputFormat
- debuggerCheck
- cotIsDebuggerPresent++
- checkCRC
- checkBreakPoint1
- checkBreakPoint2
- thread3
- FinalCheck
checkCRC
- CRCcheck
- cotCRCcheck++
- create CRC thread
checkBreakPoint1
- BreakPoint则cotBreakPoint++
- 其它的则不管
checkBreakPoint2
thread3
- keyTEA[0] = 0x19 * cotIsDebuggerPresent;
- keyTEA[1] = 0x28 * cotBreakPoint1;
- keyTEA[2] = 0x37 * cotCRCcheck;
- keyTEA[3] = cotIsDebuggerPresent + cotCRCcheck + cotBreakPoint1
复制代码
- xxTEA加密,分析密钥结构可以知道是keyTEA
- xxTEA可以看加密结构判断,TEA族加密可以通过魔数看出
- cotSame = flag经过xxTEA后得到的字符串中,相邻且相同的字符个数
- BitInvert
- keyAES
- keyAES->m128i_i8[0] = 0x19 * cotIsDebuggerPresent;
- keyAES->m128i_i8[1] = 5 * cotBreakPoint1 * 8;
- keyAES->m128i_i8[2] = 0x37 * cotCRCcheck;
- keyAES->m128i_i8[3] = cotSame + cotIsDebuggerPresent + cotBreakPoint1 + cotCRCcheck;
- keyAES->m128i_i8[4] = 0x19 * cotIsDebuggerPresent;
- keyAES->m128i_i8[5] = 5 * cotBreakPoint1 * 8;
- keyAES->m128i_i8[6] = 0x37 * cotCRCcheck;
- keyAES->m128i_i8[7] = cotIsDebuggerPresent + cotBreakPoint1 + cotCRCcheck - cotSame;
- keyAES->m128i_i8[8] = 70 * cotIsDebuggerPresent;
- keyAES->m128i_i8[9] = 85 * cotBreakPoint1;
- keyAES->m128i_i8[10] = 100 * cotCRCcheck;
- keyAES->m128i_i8[11] = cotSame + cotIsDebuggerPresent + cotBreakPoint1 + cotCRCcheck;
- keyAES->m128i_i8[12] = 70 * cotIsDebuggerPresent;
- keyAES->m128i_i8[13] = 85 * cotBreakPoint1;
- keyAES->m128i_i8[14] = 100 * cotCRCcheck;
- keyAES->m128i_i8[15] = cotIsDebuggerPresent + cotBreakPoint1 + cotCRCcheck - cotSame;
复制代码 FinalCheck
- 检查加密后的数据和cmpVal是否相同
- 不同的话触发异常处理,要求输入不需要的password并且不可能正确
WP
只有cotSame是不确定的值,范围是0~47,后面爆破即可
cotXXX全部都是固定的,只有动态调试的时候会因为触发检测而错误,静态分析显然可以得到不同时刻的状态表- int main() {
- unsigned char flag[SIZE + 1] = "NepCTF{tEA_with_AES_by_mixing_antiDebug_hahaHah}";
- unsigned char comp[SIZE + 1] = { 0 };
- data.cot_Anti1 += 1;
- data.cot_Anti3 += 1;
- data.cot_Anti3 += 1;
- unsigned int keyTEA[4];
- keyTEA[0] = data.cot_Anti1 * 0x19;
- keyTEA[1] = data.cot_Anti2 * 0x28;
- keyTEA[2] = data.cot_Anti3 * 0x37;
- keyTEA[3] = data.cot_Anti1 + data.cot_Anti2 + data.cot_Anti3;
- xxtea_uint_encrypt((unsigned int*)flag, SIZE/4, (unsigned int*)keyTEA);
- data.cot_same = 0;
- data.cot_Anti2 += 1;
- for (int i = 0; i < SIZE; i++) {
- flag[i] = ~flag[i];
- }
- unsigned char* keyAES = new unsigned char[16];
- keyAES[0] = data.cot_Anti1 * 0x19;
- keyAES[1] = data.cot_Anti2 * 0x28;
- keyAES[2] = data.cot_Anti3 * 0x37;
- keyAES[3] = data.cot_Anti1 + data.cot_Anti2 + data.cot_Anti3 + data.cot_same;
- keyAES[4] = data.cot_Anti1 * 0x19;
- keyAES[5] = data.cot_Anti2 * 0x28;
- keyAES[6] = data.cot_Anti3 * 0x37;
- keyAES[7] = data.cot_Anti1 + data.cot_Anti2 + data.cot_Anti3 - data.cot_same;
- keyAES[8] = data.cot_Anti1 * 0x46;
- keyAES[9] = data.cot_Anti2 * 0x55;
- keyAES[10] = data.cot_Anti3 * 0x64;
- keyAES[11] = data.cot_Anti1 + data.cot_Anti2 + data.cot_Anti3 + data.cot_same;
- keyAES[12] = data.cot_Anti1 * 0x46;
- keyAES[13] = data.cot_Anti2 * 0x55;
- keyAES[14] = data.cot_Anti3 * 0x64;
- keyAES[15] = data.cot_Anti1 + data.cot_Anti2 + data.cot_Anti3 - data.cot_same;
- //for (int i = 0; i < 16; i++)
- // printf("%hx", keyAES[i]);
- aesEncrypt((const unsigned char*)keyAES, 16, (const unsigned char*)flag, (unsigned char*)comp, SIZE);
- data.cot_Anti3 += 1;
- for (int i = 0; i < SIZE; i++)
- printf("%#hx, ", comp[i]);
- return 0;
- }
复制代码- int main() {
- for (int i = 0; i < 48; i++) {
- unsigned char flag[SIZE + 1] = { 0xf4, 0x9c, 0xdd, 0x41, 0x3, 0xdd, 0x5a, 0x13, 0x2e, 0x55, 0x97, 0x9e, 0xff, 0xd5, 0x8, 0xd9, 0xf6, 0xd1, 0x9, 0x8c, 0x68, 0x9e, 0x92, 0xff, 0x75, 0xf, 0x80, 0x95, 0x4b, 0x16, 0xb9, 0xc6, 0x7f, 0x54, 0x2e, 0x20, 0x35, 0xfc, 0x1b, 0x46, 0x14, 0xaa, 0xda, 0x5e, 0x4f, 0xbd, 0x59, 0x71 , 0 };
- unsigned char comp[SIZE + 1] = { 0 };
- data.cot_Anti1 = 1;
- data.cot_Anti2 = 1;
- data.cot_Anti3 = 2;
- data.cot_same = i;
- unsigned char* keyAES = new unsigned char[16];
- keyAES[0] = data.cot_Anti1 * 0x19;
- keyAES[1] = data.cot_Anti2 * 0x28;
- keyAES[2] = data.cot_Anti3 * 0x37;
- keyAES[3] = data.cot_Anti1 + data.cot_Anti2 + data.cot_Anti3 + data.cot_same;
- keyAES[4] = data.cot_Anti1 * 0x19;
- keyAES[5] = data.cot_Anti2 * 0x28;
- keyAES[6] = data.cot_Anti3 * 0x37;
- keyAES[7] = data.cot_Anti1 + data.cot_Anti2 + data.cot_Anti3 - data.cot_same;
- keyAES[8] = data.cot_Anti1 * 0x46;
- keyAES[9] = data.cot_Anti2 * 0x55;
- keyAES[10] = data.cot_Anti3 * 0x64;
- keyAES[11] = data.cot_Anti1 + data.cot_Anti2 + data.cot_Anti3 + data.cot_same;
- keyAES[12] = data.cot_Anti1 * 0x46;
- keyAES[13] = data.cot_Anti2 * 0x55;
- keyAES[14] = data.cot_Anti3 * 0x64;
- keyAES[15] = data.cot_Anti1 + data.cot_Anti2 + data.cot_Anti3 - data.cot_same;
- aesDecrypt((const unsigned char*)keyAES, 16, (const unsigned char*)flag, (unsigned char*)comp, SIZE);
- for (int i = 0; i < SIZE; i++) {
- comp[i] = ~comp[i];
- }
- data.cot_Anti2 = 0;
- unsigned int keyTEA[4];
- keyTEA[0] = data.cot_Anti1 * 0x19;
- keyTEA[1] = data.cot_Anti2 * 0x28;
- keyTEA[2] = data.cot_Anti3 * 0x37;
- keyTEA[3] = data.cot_Anti1 + data.cot_Anti2 + data.cot_Anti3;
- xxtea_uint_decrypt((unsigned int*)comp, SIZE / 4, (unsigned int*)keyTEA);
- for (int i = 0; i < SIZE; i++)
- printf("%c", comp[i]);
- printf("\n");
- }
- return 0;
- }
复制代码 经测试,仅有cot_same==0时有合法flag- NepCTF{tEA_with_AES_by_mixing_antiDebug_hahaHah}
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |