• [buuctf.reverse] 121-125


    目录

    121_[FlareOn2]starter

    122_[b01lers2020]little_engine

    123_[GKCTF 2021]SoMuchCode

    124_[SWPU2019]EasiestRe

    125_[QCTF2018]babyre


    121_[FlareOn2]starter

    头一回见着这样的题,IDA看了半天没找着有用的东西,试着运行一下发现是个安装程序,运行后会释放出一个32位程序。程序非常简单,直接对输入异或后比较

    1. BOOL start()
    2. {
    3. int v0; // ecx
    4. HANDLE StdHandle; // [esp+4h] [ebp-Ch]
    5. HANDLE hFile; // [esp+8h] [ebp-8h]
    6. DWORD NumberOfBytesWritten; // [esp+Ch] [ebp-4h] BYREF
    7. StdHandle = GetStdHandle(0xFFFFFFF6);
    8. hFile = GetStdHandle(0xFFFFFFF5);
    9. WriteFile(hFile, aLetSStartOutEa, 0x2Au, &NumberOfBytesWritten, 0);
    10. ReadFile(StdHandle, byte_402158, 0x32u, &NumberOfBytesWritten, 0);
    11. v0 = 0;
    12. while ( ((unsigned __int8)byte_402158[v0] ^ 0x7D) == byte_402140[v0] )
    13. {
    14. if ( ++v0 >= 24 )
    15. return WriteFile(hFile, aYouAreSuccess, 0x12u, &NumberOfBytesWritten, 0);
    16. }
    17. return WriteFile(hFile, aYouAreFailure, 0x12u, &NumberOfBytesWritten, 0);
    18. }

    所以可以直接解密

    1. #先运行程序,选择输入文件目录后会生成一个32位程序然后退出,处理生成的程序
    2. c = bytes.fromhex('1F08131304220E114D0D183D1B111C0F18501213531E1210')
    3. print(bytes([i^0x7d for i in c]))
    4. #bunny_sl0pe@flare-on.com
    5. #flag{bunny_sl0pe@flare-on.com}

    122_[b01lers2020]little_engine

    IDA里main里进行加密和检查

    1. __int64 __fastcall main(__int64 a1, char **a2, char **a3)
    2. {
    3. void *vars0[5]; // [rsp+0h] [rbp+0h] BYREF
    4. vars0[3] = (void *)__readfsqword(0x28u);
    5. sub_16B0();
    6. sub_1830((__int64)vars0);
    7. sub_1510((__int64 *)vars0); // 对输入加密
    8. if ( (unsigned __int8)sub_15A0(vars0) )
    9. std::__ostream_insert<char,std::char_traits<char>>(
    10. std::cout,
    11. "Chugga chugga choo choo you're the little engine that CAN!",
    12. 58LL);
    13. else
    14. std::__ostream_insert<char,std::char_traits<char>>(
    15. std::cout,
    16. "I guess you don't know anything about trains...go do some TRAINing you non-conductor :(",
    17. 87LL);
    18. std::endl<char,std::char_traits<char>>(std::cout);
    19. if ( vars0[0] )
    20. operator delete(vars0[0]);
    21. return 0LL;
    22. }

    1510里进行加密

    1. unsigned __int64 __fastcall sub_1510(__int64 *a1)
    2. {
    3. ......
    4. v2 = *a1;
    5. if ( *a1 != a1[1] )
    6. {
    7. v3 = 0LL;
    8. v4 = -111;
    9. do
    10. {
    11. v5 = (_BYTE *)(v3 + v2);
    12. ......
    13. *v5 ^= v4;
    14. v6 = v4 + v3++;
    15. v2 = *a1;
    16. v4 = v6 + v6 / 0xFF;
    17. }
    18. while ( v3 < a1[1] - *a1 );
    19. }
    20. return __readfsqword(0x28u) ^ v8;
    21. }

    不复杂

    1. data = open('engine', 'rb').read()
    2. v4 = -111 & 0xff
    3. t = []
    4. for i in range(75):
    5. t.append( v4^data[0x2220+ 4*i] )
    6. v6 = v4+i
    7. v4 = (v6 + v6//0xff )&0xff
    8. print(bytes(t))
    9. #pctf{th3_m0d3rn_st34m_3ng1n3_w45_1nv3nt3d_1n_1698_buT_th3_b3st_0n3_in_1940}
    10. #flag{th3_m0d3rn_st34m_3ng1n3_w45_1nv3nt3d_1n_1698_buT_th3_b3st_0n3_in_1940}

    123_[GKCTF 2021]SoMuchCode

    主程序是2000行,懒得看了,看了WP说是xxtea加密,因为用了SEH,这块也找不着怎么弄的,从搜到的WP里找到一个c程序

    1. #include <stdio.h>
    2. #include <stdint.h>
    3. void XXTeaDecrypt(int n, uint32_t* v, uint32_t const key[4])
    4. {
    5. uint32_t y, z, sum;
    6. unsigned p, rounds, e;
    7. uint32_t DELTA = 0x33445566;
    8. rounds = 6 + 52 / n;
    9. sum = rounds * DELTA;
    10. y = v[0];
    11. do {
    12. e = (sum >> 2) & 3;
    13. for (p = n - 1; p > 0; p--)
    14. {
    15. z = v[p - 1];
    16. y = v[p] -= (((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum ^ y) + (key[(p & 3) ^ e] ^ z)));
    17. }
    18. z = v[n - 1];
    19. y = v[0] -= (((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum ^ y) + (key[(p & 3) ^ e] ^ z)));
    20. sum -= DELTA;
    21. } while (--rounds);
    22. }
    23. int main()
    24. {
    25. uint8_t enc_data[] = { 0x5c, 0xab, 0x3c, 0x99, 0x29, 0xe1, 0x40, 0x3f, 0xde, 0x91, 0x77, 0x77, 0xa6, 0xfe, 0x7d, 0x73, 0xe6, 0x59, 0xcf, 0xec, 0xe3, 0x4c, 0x60, 0xc9, 0xa5, 0xc0, 0x82, 0x96, 0x1e, 0x2a, 0x6f, 0x55, 0};
    26. uint32_t key[] = { 14000, 79894, 16, 123123 };
    27. XXTeaDecrypt(8, (uint32_t*)enc_data, key);
    28. puts((char*)enc_data); //9b34a61df773acf0e4dec25ea5fb0e29
    29. return 0;
    30. }

    124_[SWPU2019]EasiestRe

    这个也确实比较复杂,看了半天跟着一点点调

    这里用了int3动调,执行到int3时调用函数修改代码

    程序里涉及到ini3的地方有3次,第1处在main里,具体内容到int3就完了,根据函数里的数据修改这里的7字节指向下部的程序

    1. 的v16前7个修改sub_408A40中int3开始的7字节,得到调用加密函数和检查函数
    2. .text:00408AF5 89 45 F8 mov [ebp+var_8], eax
    3. .text:00408AF8 CC int 3 ; Trap to Debugger
    4. .text:00408AF9 90 nop
    5. .text:00408AFA 90 nop
    6. .text:00408AFB 90 nop
    7. .text:00408AFC 90 nop
    8. .text:00408AFD 90 nop
    9. .text:00408AFE 90 nop
    10. .text:00408AFF 68 80 1E 4C 00 push offset aYouAreTooShort ; "you are too short!"
    11. .text:00408AF8 90 nop
    12. .text:00408AF9 83 7D F8 18 cmp [ebp+var_8], 18h
    13. .text:00408AFD 7D 11 jge short loc_408B10 跑到下方执行加密和检查
    14. .text:00408AFD

    第2块 sub_4087e0 408824开始的30字节
    第3块检查 sub_4083c0 408432开始5字节,没有patch的内容,向下40845A开始找到对应比较数据 408635开始为数据

    408536这块是密文,然后按原来得程序进行逆向,乘的逆向用逆

    1. iv=0x1234
    2. inv=12 #gmpy2.invert(41,491)
    3. c=[0x3d1,0x2f0,0x52,0x475,0x1d2,0x2f0,0x224,0x51c,0x4e6,0x29f,0x2ee,0x39b,0x3f9,0x32b,0x2f2,0x5b5,0x24c,0x45a,0x34c,0x56d,0xa,0x4e6,0x476,0x2d9]
    4. key=[2,3,7,14,30,57,120,251] #sub_408A40
    5. flag=[]
    6. for i in range(len(c)):
    7. t=c[i]*inv%491
    8. p=""
    9. for i in range(8):
    10. if key[7-i]>t:
    11. p+="0"
    12. else:
    13. p+="1"
    14. t-=key[7-i]
    15. flag.append(int(p[::-1],2))
    16. print(chr((flag[0]^0x1234)&0xff),end="")
    17. for i in range(1,len(flag)):
    18. print(chr((flag[i]^c[i-1])&0xff),end="")
    19. #swpuctf{y0u_@re_s0_coo1}
    20. #flag{y0u_@re_s0_coo1}

    125_[QCTF2018]babyre

    这个是linux下的动调,输入一个数据然后往下跟,第一次处理是每4字符进行一个顺序交换,第二次是每4个分别加上4个数,第3次是每组中字符前几位和后几位互换。然后与密文比较

    动调时得到密文

    1. gdb-peda$ x/32c 0x7ffff781c0a0
    2. 0x7ffff781c0a0: 0xda 0xd8 0x3d 0x4c 0xe3 0x63 0x97 0x3d
    3. 0x7ffff781c0a8: 0xc1 0x91 0x97 0xe 0xe3 0x5c 0x8d 0x7e
    4. 0x7ffff781c0b0: 0x5b 0x91 0x6f 0xfe 0xdb 0xd0 0x17 0xfe
    5. 0x7ffff781c0b8: 0xd3 0x21 0x99 0x4b 0x73 0xd0 0xab 0xfe

    然后向回处理

    1. a=bytes.fromhex("DAD83D4CE363973DC191970EE35C8D7E5B916FFEDBD017FED321994B73D0ABFE")
    2. flag = ''
    3. for i in range(0, len(a), 4):
    4. d1 = a[i]
    5. d1 = (d1>>3)|(d1<<5) & 0xff
    6. d1 = (d1 - 7)& 0xff
    7. d2 = a[i+1]
    8. d2 = (d2>>6)|(d2<<2) & 0xff
    9. d2 = (d2 - 18)& 0xff
    10. d3 = a[i+2]
    11. d3 = (d3>>1)|(d3<<7) & 0xff
    12. d3 = (d3 - 88)& 0xff
    13. d4 = a[i+3]
    14. d4 = (d4>>4)|(d4<<4) & 0xff
    15. d4 = (d4-129)& 0xff
    16. flag+=chr(d2)+chr(d4)+chr(d1)+chr(d3)
    17. print(flag)
    18. #QCTF{Rus4_1s_fun4nd_1nt3r3st1ng}
    19. #flag{Rus4_1s_fun4nd_1nt3r3st1ng}

  • 相关阅读:
    这篇文章告诉你视频转音频软件哪个好用,有需自取
    Mysql创建数据库索引
    Spring常见问题解决 - 同一个类型的单例Bean找到了两个?
    Packet Tracer - 研究 DUAL FSM
    【内网渗透】vulnhub三个基础靶场wp
    1008hw/
    FineReport -问题学习图表设计图表类型-单元格扩展父子格-报表预览
    char可以存汉字吗,底层是怎么存的?
    教程 - 深度探讨在 Vue3 中引入 CesiumJS 的最佳方式
    第四届传智杯初赛_小卡与质数2
  • 原文地址:https://blog.csdn.net/weixin_52640415/article/details/125439690