蚌埠住了,32位调用64位代码遇到N次了。后面又来个movfuscator混淆的题因为多开打比赛(我好菜啊……),比赛结束了几十分钟才出。
题目算不上质量高,好在又学到新东西了?
Random
伪随机数异或
ida动调拿xorkey
# 0x07C1181 reg = "al" data.append(idc.get_reg_value(reg))
一把梭
xorkey = [0x58, 0xa1, 0xcb, 0xe9, 0xed, 0x2c, 0xec, 0xfb, 0xe9, 0xc4, 0x16, 0x97, 0x99, 0xb1, 0xa4, 0xe9, 0xc3, 0xc6, 0x80, 0xbf, 0x3e, 0x44, 0x18, 0x2e, 0x73, 0x56, 0x52, 0xb8, 0x5b, 0x66, 0xed, 0xbc, 0x8a, 0xd8, 0x36, 0x8f, 0xe6, 0xd3, 0xb1, 0x51, 0xb9, 0x59, 0xd3, 0x5a] flag = bytearray([0x3E, 0xCD, 0xAA, 0x8E, 0x96, 0x1F, 0x89, 0xCD, 0xDB, 0xF1, 0x70, 0xF2, 0xA9, 0x9C, 0xC2, 0x8B, 0xF2, 0xFE, 0xAD, 0x8B, 0x58, 0x7C, 0x2F, 0x03, 0x4A, 0x65, 0x31, 0x89, 0x76, 0x57, 0x88, 0xDF, 0xB8, 0xE9, 0x01, 0xE9, 0xDE, 0xE5, 0x86, 0x68, 0x8F, 0x24, 0xD3, 0x5A]) for i in range(len(flag)): flag[i] ^= xorkey[i] print(flag)
wow
遇到N次这类题目了,32位运行64位代码
windbg跑起来动调
这里有个坑,需要改成固定基址
修改PE头强制IDA反编译
Rebase
定位402176
,创建函数
void __fastcall sub_402176(unsigned int *a1) { unsigned int v1; // er9 int v2; // ebp unsigned int v3; // esi unsigned int *v4; // rdi unsigned int *v5; // r10 unsigned int v6; // ebx unsigned int i; // er11 unsigned int v8; // er8 int v9; // edx unsigned int v10; // eax unsigned int v11; // er9 unsigned int v12; // er8 int v13; // ebx int v14; // ebx int v15; // ebx int v16; // edx unsigned int v17; // eax unsigned int v18; // er9 v1 = a1[8]; v2 = 12; v3 = 0; while ( 1 ) { v3 += 0x67452301; v4 = a1 + 1; v5 = a1; v6 = v3 >> 2; for ( i = 0; i < 8; ++i ) { v8 = *v4; if ( (((unsigned __int8)i ^ (unsigned __int8)v6) & 3) != 0 ) { switch ( ((unsigned __int8)i ^ (unsigned __int8)v6) & 3 ) { case 1: v9 = (v1 >> 5) ^ (4 * v8); v10 = v1; v11 = v1 ^ 0x10325476; break; case 2: v9 = (v1 >> 5) ^ (4 * v8); v10 = v1; v11 = v1 ^ 0x98BADCFE; break; case 3: v9 = (v1 >> 5) ^ (4 * v8); v10 = v1; v11 = v1 ^ 0xC3D2E1F0; break; default: goto LABEL_12; } } else { v9 = (v1 >> 5) ^ (4 * v8); v10 = v1; v11 = v1 ^ 0xEFCDAB89; } *v5 += (v11 + (v3 ^ v8)) ^ (((16 * v10) ^ (v8 >> 3)) + v9); v1 = *v5; LABEL_12: ++v4; ++v5; } v12 = *a1; v13 = ((unsigned __int8)i ^ (unsigned __int8)v6) & 3; if ( !v13 ) { v16 = (v1 >> 5) ^ (4 * v12); v17 = v1; v18 = v1 ^ 0xEFCDAB89; goto LABEL_21; } v14 = v13 - 1; if ( !v14 ) { v16 = (v1 >> 5) ^ (4 * v12); v17 = v1; v18 = v1 ^ 0x10325476; goto LABEL_21; } v15 = v14 - 1; if ( !v15 ) { v16 = (v1 >> 5) ^ (4 * v12); v17 = v1; v18 = v1 ^ 0x98BADCFE; LABEL_21: a1[8] += (v18 + (v3 ^ v12)) ^ (((16 * v17) ^ (v12 >> 3)) + v16); v1 = a1[8]; goto LABEL_22; } if ( v15 == 1 ) { v16 = (v1 >> 5) ^ (4 * v12); v17 = v1; v18 = v1 ^ 0xC3D2E1F0; goto LABEL_21; } LABEL_22: if ( !--v2 ) __asm { retfq } } }
魔改的XXTEA,手动化简一下
void __fastcall sub_402176(unsigned int *v) { DWORD z; // rax unsigned int sum; // er11 unsigned int e; // edx int i; // r9 unsigned int y; // er8 uint32_t k[4] = {0xEFCDAB89, 0x10325476, 0x98BADCFE, 0xC3D2E1F0}; z = v[8]; sum = 0; do { sum += 0x67452301; for ( i = 0; i < 8; ++i ) { e = (sum >> 2) & 3; y = v[i + 1]; z = v[i] + (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (k[(i&3)^e] ^ z))); v[i] = z; } y = v[0]; z = v[8] + (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (k[(i&3)^e] ^ z))); v[8] = z; } while (sum != 0xD73DA40C ); }
解密脚本
void __fastcall sub_402176ss(unsigned int *v) { DWORD z; // rax unsigned int sum; // er11 unsigned int e; // edx int i; // r9 unsigned int y; // er8 uint32_t k[4] = {0xEFCDAB89, 0x10325476, 0x98BADCFE, 0xC3D2E1F0}; y = v[0]; sum = 0xD73DA40C; do { for ( i = 8; i > 0; --i ) { e = (sum >> 2) & 3; z = v[i - 1]; y = v[i] -= (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (k[(i&3)^e] ^ z))); } z = v[8]; y = v[0] -= (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (k[(i&3)^e] ^ z))); sum -= 0x67452301; } while (sum != 0 ); } int main() { uint32_t v[9] = { 0xD8F758F5, 0x526849DB, 0xE2D72563, 0x485EEFAC, 0x608F4BC6, 0x5859F76A, 0xB03565A3, 0x3E4091C1, 0xD3DB5B9A }; sub_402176ss(v); for (int i = 0; i < 9; ++i) { printf("0x%x, ", v[i]); } return 0; }
小端序完事
Un(ix)zip
linux下解压,python脚本梭
""" @Author: Mas0n @File: mtctf1.py @Time: 2021-12-11 9:58 @Desc: It's all about getting better. """ import os path = "ppp" def getListFiles(path): assert os.path.isdir(path), '%s not exist.' % path ret = [] for root, dirs, files in os.walk(path): for filespath in files: ret.append([os.path.split(root)[1], int(filespath, 10)]) return ret lis = getListFiles(path) flags = bytearray([0] * (len(lis)+1)) for al in lis: flags[al[1]] = ord(al[0]) print(flags.decode(), flags[::-1]) # base64decode
Superflat
mov混淆介绍
domas_2015_the_movfuscator.pdf
找到个反混淆工具
偷懒直接拿docker跑了
sudo docker pull iyzyi/demovfuscator ··· cp superflat /home/ sudo docker run --name demov -it -v /home/mason/Desktop/:/home/ iyzyi/demovfuscator /bin/bash cd demovfuscator ./demov /home/superflat -g /home/superflat.dot -o /home/fix_superflat dot -tPng superflat.dot > superflat.png
拿到一个流程图和初步修复好的文件,虽然说不是完全修复,凑活看
通过流程图,可以猜测范围区间内的功能
翻找下特征
这里能看到AES的特征Sbox,其实是障眼法…
看到两组42位的数组
动调起来,关键处打断点,单步观察寄存器及指令,反复调试几遍结合合理推测:
- 输入长度为0x2A
- Sbox作为映射表
- unknown2作为xorkey
伪代码如下
for i in range(42): sbox[flag[i]] ^ unknown2[i] == unknown1[i]
逆过程即可
# -*- coding:utf-8 -*- """ @Author: Mas0n @File: mtctf2.py @Time: 2021-12-11 21:22 @Desc: It's all about getting better. """ sbox = [0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16] xorkey = [0x44, 0xCA, 0x41, 0xBB, 0x8D, 0x29, 0x1F, 0xB0, 0x22, 0x9A, 0x0D, 0x50, 0xC8, 0xAC, 0x27, 0x36, 0x87, 0xC3, 0x25, 0xAE, 0xD7, 0x94, 0x06, 0xB9, 0xE6, 0xBF, 0xC7, 0x32, 0x55, 0x7A, 0x72, 0x92, 0xF8, 0xE0, 0x42, 0xF8, 0x40, 0x8E, 0x51, 0x99, 0x39, 0x8D] enc = [0x77, 0x9A, 0xAE, 0x3E, 0xAC, 0x6A, 0x1B, 0xB5, 0x11, 0x9E, 0xA7, 0xAB, 0x33, 0x74, 0x35, 0xF5, 0xCA, 0xC7, 0xFD, 0xBC, 0x2C, 0x02, 0xAC, 0x61, 0x21, 0xBA, 0x00, 0x7F, 0x8D, 0x37, 0xB5, 0x8A, 0xFD, 0xF8, 0x85, 0x62, 0x45, 0xCD, 0x92, 0x8B, 0xAF, 0x72] flag = bytearray([0] * 42) for i in range(42): flag[i] = sbox.index(xorkey[i] ^ enc[i]) print(flag)
发表回复