2022 美团 MT-CTF Small 借鉴:[原创]2022MT-CTF Re-茶余饭后-看雪论坛-安全社区|安全招聘|bbs.pediy.com
在做题的时候看到是ELF文件,直接尝试在Ubuntu上面运行,但是提示段错误。然后用IDA64打开,一直报错。想怎么修复ELF头,让他能直接运行,也有大佬提示试试看是不是shellcode,但是都失败了,看到了wp人都傻了。
首先用IDA64, 二进制模式打开
然后在0x68处按C反汇编,
经典的三个数两次异或运算,左移4,右移5
看cutter的反编译更清楚,可以得知这是一个TEA加密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 #include <stdint.h> int64_t entry0 (int64_t arg_10h, int64_t arg4, int64_t arg1) { rcx = arg4; rdi = arg1; rsi = arg_10h; label_0: ebx = 0 ; edx = ebx; eax = 0x3e0002 ; eax = *(rsi); rsi += 4 ; tmp_0 = eax; eax = ebp; ebp = tmp_0; eax = entry0; *(rax) += al; *(rax) += al; *(rax) += al; *(rax) += al; *(rax) += al; if (*(rsp) != 2 ) { goto label_1; } eax = *(rsi); rsi += 4 ; tmp_1 = eax; eax = edi; edi = tmp_1; do { ecx = edi; eax = edi; ebx += 0x67452301 ; ecx <<= 4 ; ecx++; eax >>= 5 ; eax += 0x23 ; ecx ^= eax; eax = edi; eax += ebx; ecx ^= eax; ebp += ecx; ecx = ebp; ecx >>= 5 ; ecx += 0x67 ; eax = ebp; eax <<= 4 ; eax += 0x45 ; ecx ^= eax; eax = ebp; eax += ebx; ecx ^= eax; edi += ecx; edx++; } while (edx < 0x23 ); *((rsi - 8 )) = ebp; *((rsi - 4 )) = edi; ecx = arg_10h; ecx += 0x20 ; if (esi < ecx) { goto label_0; } tmp_2 = rax; rax = rsi; rsi = tmp_2; esi = 0x20 ; do { cl = *(rax); if (*((esi + 0x100f7 )) != cl) { goto label_1; } esi--; rax--; } while (esi != 0 ); edi = 1 ; esi = 0x100f3 ; eax = 1 ; dx = 4 ; rax = syscall_80h (rdi, rsi, rdx, r10, r8, r9); label_1: eax = 0x3c ; edi = esi; rax = syscall_80h (rdi, rsi, rdx, r10, r8, r9); __asm ("outsd dx, dword [esi]" ); __asm ("outsd dx, dword [rsi]" ); if (esi overflow 0 ) { fp_status = fp_compare(fp_stack[0 ], fp_stack[0 ]); fp_stack++; edi -= ecx; } fp_stack[0 ] *= *((rbp + rdx*8 - 0x62 )); __asm ("insd dword [rdi], dx" ); __asm ("out 0x4e, eax" ); return void (*0x10180 )() (); }
直接定位到0x100f7,可以找到密文就是在0x100f7~0x100f7+0x20之间
解密脚本
1 2 3 4 5 6 7 8 enc=list (bytes .fromhex('437108ded21bf9c4dcdaf6da4cd59e6de74eeb7504dc1d5dd90f1b51fb88dc51' ))for i in range (0 ,len (enc),4 ): num=0 for j in range (4 ): num|=(enc[i+j]<<(8 *j)) print (hex (num),end=',' )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include <iostream> #define ut32 unsigned int #define delta 0x67452301 void Tea_Decrypt (ut32* enc) { unsigned int sum = 0x67452301 * 0x23 ; ut32 v0 = enc[0 ]; ut32 v1 = enc[1 ]; for (int i = 0 ; i < 0x23 ; i++) { v1 -= ((v0 << 4 ) + 0x45 ) ^ (v0 + sum) ^ ((v0 >> 5 ) + 0x67 ); v0 -= ((v1 << 4 ) + 1 ) ^ (v1 + sum) ^ ((v1 >> 5 ) + 0x23 ); sum -= 0x67452301 ; } enc[0 ] = v0; enc[1 ] = v1; } void Tea_Encrypt (ut32* src) { ut32 sum = 0 ; ut32 v0 = src[0 ]; ut32 v1 = src[1 ]; for (int i = 0 ; i < 0x23 ; i++) { sum += 0x67452301 ; v0 += ((v1 << 4 ) +1 ) ^ (v1 + sum) ^ ((v1 >> 5 ) + 0x23 ); v1 += ((v0 << 4 ) + 0x45 ) ^ (v0 + sum) ^ ((v0 >> 5 ) + 0x67 ); } printf ("%08x\n" , sum); src[0 ] = v0; src[1 ] = v1; }int main () { ut32 enc[8 ] = { 0xde087143 ,0xc4f91bd2 ,0xdaf6dadc ,0x6d9ed54c ,0x75eb4ee7 ,0x5d1ddc04 ,0x511b0fd9 ,0x51dc88fb }; for (int i = 0 ; i < 8 ; i += 2 ) { Tea_Decrypt(enc+i); } for (int i = 0 ; i < 32 ; i++) { printf ("%c" ,*((unsigned char *)enc+i)); } return 0 ; }