思路
RC4 是对称加密算法, 对于相同的密钥,把一个明文加密两遍就可以变成原文(有点类似异或)。所以有两种思路
-
动态调试
-
直接解密
标准 RC4 的加密过程分为
- 获取密钥流
- 待加密的明文进行简单的交换位置
- 交换完后的明文与密钥流进行异或
如果使用 python 表示大概是这样的
def KSA(key):
key_length = len(key)
# 初始化S盒
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % key_length]) % 256
S[i], S[j] = S[j], S[i]
return S
def PRGA(S):
i = 0
j = 0
while True:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
K = S[(S[i] + S[j]) % 256]
yield K
def RC4(key, data):
S = KSA(key)
keystream = PRGA(S)
res = []
for c in data:
res.append(c ^ next(keystream))
return bytes(res)
key = b'密钥'
encrypted_data = b'数据' # 注意是 bytes 类型的
decrypted_data = RC4(key, encrypted_data)
print(decrypted_data)
打开ida直接可以得到 key 和 密文, 直接解密过于简单这里就不赘述了。
我将详细解释如何使用 IDA 通过动态调试的方法修改程序执行流 ,把密文解密出来
步骤

如果我在 rc4_crypt 这里打下断点然后修改 v2 为 v1 , 修改 len 为 v1 的长度, 那么就可以得到解密后的明文了.

随便输几个值, 然后断点断在 31行

单步步过到 4019E8 停下. 然后修改寄存器的值,
首先是传入的 Len 变量, 要把它修改成密文一样的长度 也就是 44

右键 R8 寄存器然后选择 Modify Value, 输入 2C
返回源码窗口双击 v1 变量找到它的地址
然后选中 RDX 修改为 v1 的地址

可见, 修改了之后 rdx 后面直接显示这是 v1 的地址.
然后返回源码窗口单步步过. 再次进入 v1

它的值已经被修改了.
复制出来就可以了
res = [0x4E, 0x53, 0x53, 0x43, 0x54, 0x46, 0x7B, 0x30, 0x64, 0x36,
0x66, 0x39, 0x30, 0x61, 0x63, 0x2D, 0x34, 0x62, 0x35, 0x65,
0x2D, 0x34, 0x65, 0x66, 0x62, 0x2D, 0x38, 0x35, 0x30, 0x32,
0x2D, 0x36, 0x33, 0x34, 0x39, 0x63, 0x66, 0x37, 0x39, 0x38,
0x66, 0x32, 0x65, 0x7D]
for i in res:
print(chr(i), end='')
