R1-Android-catchem
0x0 前言
分析啥的就不放了,把几个关键点放上
0x1 解密key和密文
同一个函数中,直接索引一下就找到了
0x2解密flag
enc = [0x4F, 0x1C, 0x36, 0x49, 0x09, 0x3A, 0x3F, 0x07, 0x4D, 0x3D,
0x22, 0x39, 0x00, 0x0A, 0x22, 0x25, 0x06, 0x09, 0x01, 0x20,
0x4A, 0x1B, 0x51, 0x51, 0x6C]
key = [0x24, 0x3C, 0x3D, 0x37, 0x36, 0x21, 0x35, 0x26, 0x3F, 0x37,
0x32, 0x2A, 0x72, 0x72, 0x72, 0x72, 0x53]
enc1 = ""
key1 = ""
for i in range(len(enc)):
enc1 += chr(enc[i] ^ 0x6c)
print(enc1)
for i in range(len(key)):
key1 += chr(key[i] ^ 0x53)
print(key1)
# #pZ%eVSk!QNUlfNIjemL&w==
# wonderfulday!!!!
直接把base表放上,key放上,base表直接字符串搜#
R2-FFunction
0x0 前言
第一个问题 怎么确定位数的?
最笨的方法,每次多输入一个数,然后在第30位的时候会弹出wrong key
第二个问题 怎么确定dll和加密函数的?
可以调试每一个dll开头下断,然后就会发现my_plugin这个dll断住了就可以跟到f函数
0x1 动态调试
我输入了DSCTF{12345678abcdefghijklmno} 然后变成了这样的字符串,base64解出后还发现更换了索引
还可以直接查看密文,可以通过lazyida提出来
0x2 静态分析
分析都在图中,可以发现最终加密为tea,但是注意其中的算法是tea的解密
0x3 解密
import binascii
import struct
import base64
data =binascii.unhexlify('4c75155ce781d7d173f11b5022b24dcbf5615d21e79eca3fc7b5767cb98cddc7fa230d99d31aab0b32c9128ef2ba07d323d12de52c8fb6fbe353d8bd4e1e2e89fa66dd3965ecfe87605e7c30006c0c34')
data = [struct.unpack('<I', data[t:t+4])[0] for t in range(0, len(data), 4)]
mask32 = lambda m:m&0xffffffff
result = []
for i in range(0, 20, 2):
v18 = mask32(0x79B99E37 * 32)
v17 = data[i]
v19 = data[i+1]
for _ in range(32):
v19 = mask32( v19 + ((v18 + v17) ^ (0x0DEADC0DE + (v17 >> 5)) ^ (0x0FACEB00C +16 * v17)))
v17 = mask32( v17 + ((v18 + v19) ^ (0x0DEADBEEF + (v19 >> 5)) ^ (0x0BABEC0FE +16 * v19)))
v18 = mask32(v18 - 0x79B99E37)
result.append(v17&0xffff)
result.append(v17>>16)
result.append(v19&0xffff)
result.append(v19>>16)
result = [(t>>8|t)&0xff for t in result][::-1]
result = base64.b64decode(bytearray(result))
t1 = "0123456789abcdefghijklmnopqrst"
t2 = '0t1s2r3q4p5o6n7m8l9kajbichdgef'
flag = ['' for i in range(len(result))]
for i in range(30):
flag[ t1.index(t2[i]) ] = chr(result[i])
print(''.join(flag))
#include <cstdio>
void encrypt(unsigned int* v, const unsigned int* k)
{
unsigned int v0 = v[0], v1 = v[1], sum = 0, i;
unsigned int delta = 0x3733C6E0;
unsigned int k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
for (i = 0; i < 32; i++)
{
sum += delta;
v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
}
v[0] = v0;
v[1] = v1;
}
void decrypt(unsigned int* v, unsigned int* k)
{
unsigned long v0 = v[0], v1 = v[1], sum = 0x3733C6E0, i;
unsigned long delta = 0x79B99E37;
unsigned long k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
for (i = 0; i < 32; i++)
{
v1 += ((v0 << 4) + k1) ^ (v0 + sum) ^ ((v0 >> 5) + k0);
v0 += ((v1 << 4) + k3) ^ (v1 + sum) ^ ((v1 >> 5) + k2);
sum -= delta;
}
v[0] = v0;
v[1] = v1;
}
int main()
{
unsigned int v[20] = { 0x5C15754C, 0xD1D781E7, 0x501BF173, 0xCB4DB222, 0x215D61F5, 0x3FCA9EE7, 0x7C76B5C7, 0xC7DD8CB9,
0x990D23FA, 0x0BAB1AD3, 0x8E12C932, 0xD307BAF2, 0xE52DD123, 0xFBB68F2C, 0xBDD853E3, 0x892E1E4E,
0x39DD66FA, 0x87FEEC65, 0x307C5E60, 0x340C6C00 }, k[4] = { 0xDEADC0DE,0xFACEB00C,0xDEADBEEF,0xBABEC0FE };
decrypt(v, k);
printf("%x,%x", v[0], v[1]);
return 0;
}
python为Nu1L战队wp抄的
c为我自己复现的,能解密成功
0x4 总结
又学习到了很多思路,无限的复现题目只为扩展自己对题目的敏感性。
可以拿到题目立马有思路和方法,不是像无头苍蝇一样。
本文的ida注释很简单。