Nepctf2023 Review 出题思路及WP

打印 上一主题 下一主题

主题 863|帖子 863|积分 2589

原设计图


Flag格式

NepCTF{%s}
逻辑复原

main

UPX拆壳,main函数逻辑复原得到

  • getInput
  • checkInputFormat
  • debuggerCheck

    • 如果存在,则加密一些数据

  • cotIsDebuggerPresent++
  • checkCRC
  • checkBreakPoint1
  • checkBreakPoint2
  • thread3
  • FinalCheck
checkCRC


  • CRCcheck
  • cotCRCcheck++
  • create CRC thread

    • function: checkCRC

checkBreakPoint1


  • BreakPoint则cotBreakPoint++
  • 其它的则不管
checkBreakPoint2


  • 检测cotBreakPoint个数,判断是否失败
thread3


  • checkCRC
  • keyTEA
  1. keyTEA[0] = 0x19 * cotIsDebuggerPresent;
  2. keyTEA[1] = 0x28 * cotBreakPoint1;
  3. keyTEA[2] = 0x37 * cotCRCcheck;
  4. keyTEA[3] = cotIsDebuggerPresent + cotCRCcheck + cotBreakPoint1
复制代码

  • xxTEA加密,分析密钥结构可以知道是keyTEA

    • xxTEA可以看加密结构判断,TEA族加密可以通过魔数看出

  • cotSame = flag经过xxTEA后得到的字符串中,相邻且相同的字符个数
  • BitInvert
  • keyAES
  1. keyAES->m128i_i8[0] = 0x19 * cotIsDebuggerPresent;
  2. keyAES->m128i_i8[1] = 5 * cotBreakPoint1 * 8;
  3. keyAES->m128i_i8[2] = 0x37 * cotCRCcheck;
  4. keyAES->m128i_i8[3] = cotSame + cotIsDebuggerPresent + cotBreakPoint1 + cotCRCcheck;
  5. keyAES->m128i_i8[4] = 0x19 * cotIsDebuggerPresent;
  6. keyAES->m128i_i8[5] = 5 * cotBreakPoint1 * 8;
  7. keyAES->m128i_i8[6] = 0x37 * cotCRCcheck;
  8. keyAES->m128i_i8[7] = cotIsDebuggerPresent + cotBreakPoint1 + cotCRCcheck - cotSame;
  9. keyAES->m128i_i8[8] = 70 * cotIsDebuggerPresent;
  10. keyAES->m128i_i8[9] = 85 * cotBreakPoint1;
  11. keyAES->m128i_i8[10] = 100 * cotCRCcheck;
  12. keyAES->m128i_i8[11] = cotSame + cotIsDebuggerPresent + cotBreakPoint1 + cotCRCcheck;
  13. keyAES->m128i_i8[12] = 70 * cotIsDebuggerPresent;
  14. keyAES->m128i_i8[13] = 85 * cotBreakPoint1;
  15. keyAES->m128i_i8[14] = 100 * cotCRCcheck;
  16. keyAES->m128i_i8[15] = cotIsDebuggerPresent + cotBreakPoint1 + cotCRCcheck - cotSame;
复制代码

  • AES
  • checkCRC
FinalCheck


  • 检查加密后的数据和cmpVal是否相同
  • 不同的话触发异常处理,要求输入不需要的password并且不可能正确
WP

只有cotSame是不确定的值,范围是0~47,后面爆破即可
cotXXX全部都是固定的,只有动态调试的时候会因为触发检测而错误,静态分析显然可以得到不同时刻的状态表
  1. int main() {
  2.     unsigned char flag[SIZE + 1] = "NepCTF{tEA_with_AES_by_mixing_antiDebug_hahaHah}";
  3.     unsigned char comp[SIZE + 1] = { 0 };
  4.     data.cot_Anti1 += 1;
  5.     data.cot_Anti3 += 1;
  6.     data.cot_Anti3 += 1;
  7.     unsigned int keyTEA[4];
  8.     keyTEA[0] = data.cot_Anti1 * 0x19;
  9.     keyTEA[1] = data.cot_Anti2 * 0x28;
  10.     keyTEA[2] = data.cot_Anti3 * 0x37;
  11.     keyTEA[3] = data.cot_Anti1 + data.cot_Anti2 + data.cot_Anti3;
  12.     xxtea_uint_encrypt((unsigned int*)flag, SIZE/4, (unsigned int*)keyTEA);
  13.     data.cot_same = 0;
  14.     data.cot_Anti2 += 1;
  15.     for (int i = 0; i < SIZE; i++) {
  16.         flag[i] = ~flag[i];
  17.     }
  18.     unsigned char* keyAES = new unsigned char[16];
  19.     keyAES[0] = data.cot_Anti1 * 0x19;
  20.     keyAES[1] = data.cot_Anti2 * 0x28;
  21.     keyAES[2] = data.cot_Anti3 * 0x37;
  22.     keyAES[3] = data.cot_Anti1 + data.cot_Anti2 + data.cot_Anti3 + data.cot_same;
  23.     keyAES[4] = data.cot_Anti1 * 0x19;
  24.     keyAES[5] = data.cot_Anti2 * 0x28;
  25.     keyAES[6] = data.cot_Anti3 * 0x37;
  26.     keyAES[7] = data.cot_Anti1 + data.cot_Anti2 + data.cot_Anti3 - data.cot_same;
  27.     keyAES[8] = data.cot_Anti1 * 0x46;
  28.     keyAES[9] = data.cot_Anti2 * 0x55;
  29.     keyAES[10] = data.cot_Anti3 * 0x64;
  30.     keyAES[11] = data.cot_Anti1 + data.cot_Anti2 + data.cot_Anti3 + data.cot_same;
  31.     keyAES[12] = data.cot_Anti1 * 0x46;
  32.     keyAES[13] = data.cot_Anti2 * 0x55;
  33.     keyAES[14] = data.cot_Anti3 * 0x64;
  34.     keyAES[15] = data.cot_Anti1 + data.cot_Anti2 + data.cot_Anti3 - data.cot_same;
  35.     //for (int i = 0; i < 16; i++)
  36.     //   printf("%hx", keyAES[i]);
  37.     aesEncrypt((const unsigned char*)keyAES, 16, (const unsigned char*)flag, (unsigned char*)comp, SIZE);
  38.     data.cot_Anti3 += 1;
  39.     for (int i = 0; i < SIZE; i++)
  40.         printf("%#hx, ", comp[i]);
  41.     return 0;
  42. }
复制代码
  1. int main() {
  2.         for (int i = 0; i < 48; i++) {
  3.                 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 };
  4.                 unsigned char comp[SIZE + 1] = { 0 };
  5.                 data.cot_Anti1 = 1;
  6.                 data.cot_Anti2 = 1;
  7.                 data.cot_Anti3 = 2;
  8.                 data.cot_same = i;
  9.                 unsigned char* keyAES = new unsigned char[16];
  10.                 keyAES[0] = data.cot_Anti1 * 0x19;
  11.                 keyAES[1] = data.cot_Anti2 * 0x28;
  12.                 keyAES[2] = data.cot_Anti3 * 0x37;
  13.                 keyAES[3] = data.cot_Anti1 + data.cot_Anti2 + data.cot_Anti3 + data.cot_same;
  14.                 keyAES[4] = data.cot_Anti1 * 0x19;
  15.                 keyAES[5] = data.cot_Anti2 * 0x28;
  16.                 keyAES[6] = data.cot_Anti3 * 0x37;
  17.                 keyAES[7] = data.cot_Anti1 + data.cot_Anti2 + data.cot_Anti3 - data.cot_same;
  18.                 keyAES[8] = data.cot_Anti1 * 0x46;
  19.                 keyAES[9] = data.cot_Anti2 * 0x55;
  20.                 keyAES[10] = data.cot_Anti3 * 0x64;
  21.                 keyAES[11] = data.cot_Anti1 + data.cot_Anti2 + data.cot_Anti3 + data.cot_same;
  22.                 keyAES[12] = data.cot_Anti1 * 0x46;
  23.                 keyAES[13] = data.cot_Anti2 * 0x55;
  24.                 keyAES[14] = data.cot_Anti3 * 0x64;
  25.                 keyAES[15] = data.cot_Anti1 + data.cot_Anti2 + data.cot_Anti3 - data.cot_same;
  26.                 aesDecrypt((const unsigned char*)keyAES, 16, (const unsigned char*)flag, (unsigned char*)comp, SIZE);
  27.                 for (int i = 0; i < SIZE; i++) {
  28.                         comp[i] = ~comp[i];
  29.                 }
  30.                 data.cot_Anti2 = 0;
  31.                 unsigned int keyTEA[4];
  32.                 keyTEA[0] = data.cot_Anti1 * 0x19;
  33.                 keyTEA[1] = data.cot_Anti2 * 0x28;
  34.                 keyTEA[2] = data.cot_Anti3 * 0x37;
  35.                 keyTEA[3] = data.cot_Anti1 + data.cot_Anti2 + data.cot_Anti3;
  36.                 xxtea_uint_decrypt((unsigned int*)comp, SIZE / 4, (unsigned int*)keyTEA);
  37.                 for (int i = 0; i < SIZE; i++)
  38.                         printf("%c", comp[i]);
  39.                 printf("\n");
  40.         }
  41.         return 0;
  42. }
复制代码
经测试,仅有cot_same==0时有合法flag
  1. NepCTF{tEA_with_AES_by_mixing_antiDebug_hahaHah}
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

我爱普洱茶

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表