0x00 题目分析 比较可惜这题没在规定时间内做出来,被劫持摆了一道
0x01 解 无壳,直接上IDA
main函数相对比较简单,不难看懂,重点应该就是图中的sub_7A121C
跟进去可以发现是XXTEA算法,key就是byte_7AB048=[0x44, 0x41, 0x53, 0x21]
而sub_7AB000里面就是32字节长的东西
取一下enc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import structdef read_int_array (file_name ): with open (file_name, 'rb' ) as f: data = f.read() return struct.unpack('<' +'i' * (len (data) // 4 ), data) a = read_int_array('./enc.txt' ) enc = [] for i in range (8 ): enc.append(a[i]) for i in enc: if i < 0 : i += 2 **32 print (hex (i), 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 import structdef shift (z, y, x, k, p, e ): return ((((z >> 5 ) ^ (y << 2 )) + ((y >> 3 ) ^ (z << 4 ))) ^ ((x ^ y) + (k[(p & 3 ) ^ e] ^ z))) def decrypt (v, k ): delta = 0x9E3779B9 n = len (v) rounds = int (6 + 52 / n) x = (rounds * delta) & 0xFFFFFFFF y = v[0 ] for i in range (rounds): e = (x >> 2 ) & 3 for p in range (n - 1 , 0 , -1 ): z = v[p - 1 ] v[p] = (v[p] - shift(z, y, x, k, p, e)) & 0xFFFFFFFF y = v[p] p -= 1 z = v[n - 1 ] v[0 ] = (v[0 ] - shift(z, y, x, k, p, e)) & 0xFFFFFFFF y = v[0 ] x = (x - delta) & 0xFFFFFFFF return v if __name__ == '__main__' : k = [0x44 , 0x41 , 0x53 , 0x21 ] enctxt = [0x9432244e , 0x5f60b399 , 0xee847593 , 0xdccbe9cc , 0x86e178b1 , 0x2f304163 , 0x543b0818 , 0xb2205663 ,] print ("===========================================================================" ) decrypted = decrypt(enctxt, k) print (decrypted) for i in range (len (decrypted)): print ("{:08X}" .format (decrypted[i])) tmp = b'' for i in range (len (decrypted)): tmp += struct.pack('<L' , decrypted[i]) print ("解密内容:" ) print (tmp)
临近比赛结束出了个fakeflag,至此错过提交时间(
之后想了想应该没这么简单的,直接上动调,从比较的地方入手
结果连断点都没到就给我截下来了
还是降低难度了,这个地方不放个int3完全可以
看来在比较之前被劫持了,执行了其他东西
一个个看
这个byte_17B024里面也是32字节的数据,可能这个才是真的flag
不过用XXTEA直接解是没有什么结果的
而之后的这个函数sub_171348跟下去会发现是比较
试了试向上跟也没发现什么很有意思的东西,只是发现劫持用的函数
不过在比较的函数里发现加密结果不同了
我输入的是全1,在XXTEA的加密结果应该是这样的
1 2 3 4 5 6 7 8 9 10 """ 57505803 608BF893 3E4021AD BAD19A87 1A37D5C3 14B0A95B 6081C020 DB4BE498 """
可以发现应该后面又加了一次什么东西
在main函数中的比较下断点,然后再下内存断点,看看什么时候这个结果被更改了
断下来之后就能发现这个
XTEA算法
看来XXTEA之后又进行了XTEA加密
不过继续运行起来会发现不止使用了一次XTEA加密,而是两次(一共断下来四次,加密一次会断两次)
之后再进行跟踪会发现两次XTEA之后就比较了,看来加密方式就是一次XXTEA加上两次XTEA
需要注意的是XTEA一次只对数组中的8字节进行操作,所以要将输入两两一组分为4组进去进行操作,轮数是0x24H = 36D
上脚本!
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 import structdef XTEAdecrypt (rounds, v, k ): v0 = v[0 ] v1 = v[1 ] delta = 0x9E3779B9 x = delta * rounds for i in range (rounds): v1 -= (((v0 << 4 ) ^ (v0 >> 5 )) + v0) ^ (x + k[(x >> 11 ) & 3 ]) v1 = v1 & 0xFFFFFFFF x -= delta x = x & 0xFFFFFFFF v0 -= (((v1 << 4 ) ^ (v1 >> 5 )) + v1) ^ (x + k[x & 3 ]) v0 = v0 & 0xFFFFFFFF v[0 ] = v0 v[1 ] = v1 return v def shift (z, y, x, k, p, e ): return ((((z >> 5 ) ^ (y << 2 )) + ((y >> 3 ) ^ (z << 4 ))) ^ ((x ^ y) + (k[(p & 3 ) ^ e] ^ z))) def XXTEAdecrypt (v, k ): delta = 0x9E3779B9 n = len (v) rounds = int (6 + 52 / n) x = (rounds * delta) & 0xFFFFFFFF y = v[0 ] for i in range (rounds): e = (x >> 2 ) & 3 for p in range (n - 1 , 0 , -1 ): z = v[p - 1 ] v[p] = (v[p] - shift(z, y, x, k, p, e)) & 0xFFFFFFFF y = v[p] p -= 1 z = v[n - 1 ] v[0 ] = (v[0 ] - shift(z, y, x, k, p, e)) & 0xFFFFFFFF y = v[0 ] x = (x - delta) & 0xFFFFFFFF return v encrypted = [0x87aaa7c1 , 0x857321b6 , 0xe71d28c , 0xcadf39f2 , 0x58efca14 , 0xd7e7d9d8 , 0xf29f5c5d , 0x5f5ed45e ] k = [0x44 , 0x41 , 0x53 , 0x21 ] rounds = 36 i = 0 for j in range (int (len (encrypted)/2 )): tmp = [0 ]*2 tmp[0 ] = encrypted[i] tmp[1 ] = encrypted[i+1 ] tmp = XTEAdecrypt(rounds, tmp, k) encrypted[i] = tmp[0 ] encrypted[i+1 ] = tmp[1 ] i += 2 i = 0 for j in range (int (len (encrypted)/2 )): tmp = [0 ]*2 tmp[0 ] = encrypted[i] tmp[1 ] = encrypted[i+1 ] tmp = XTEAdecrypt(rounds, tmp, k) encrypted[i] = tmp[0 ] encrypted[i+1 ] = tmp[1 ] i += 2 decrypted = XXTEAdecrypt(encrypted, k) tmp = b'' for i in range (len (decrypted)): tmp += struct.pack('<L' , decrypted[i]) print (tmp)
真是给摆了一道呢(