逆向分析 — 仿射加密

通过一个简单的仿射加密程序逆向,学习仿射加密在逆向程序中的表示以及如何进行关键点的处理。熟悉了基本的逆向分析方法和流程。

初识程序

运行初见截图如下:

在 IDA 中观察主程序流程大致如下图:

这是一个 32 位 exe 程序,通过试运行,大致观察到程序接受了一个字符串,若满足相应条件,会输出 ok,you really know,否则,会输出 sorry。我们的目标,就是要让程序输出前者。

结构分析

用 32 位 IDA 打开这个程序。

test ecx,ecx后,通过不大于转移 (jle) 命令,判断是否跳转到short loc_40105A地址上,否则,进入loc_401047地址,进行循环,循环结束后仍然进入loc_40105A地址,继续进行比较。循环时有inc eax操作,说明这里的循环可能是for循环。

继续顺序执行。在test ecx,ecx后发生了又一次不大于转移命令,判断是否需要直接跳转到loc_401062地址上,在loc_401062内部又发生了循环。当不满足小于转移条件时,出循环,继续向下执行。

看来是要从内存中取字符串了,记下来,可能是分析的重点。

一堆条件判断和跳转,根据前三条红色路线和绿色路线走,还有循环,略有些复杂。

终于到结尾了!这一部分就是简单的条件分支结构了。由于整个程序有效代码部分只有一个main函数,所以整个程序的结构分析到此就结束了。

逻辑分析

首先从main函数开始,从sub开始数起。

我们输入的字符串被存放在esp+68h+var_64中。然后经过test检验,当寄存器的值小于等于0时,跳转到40105A地址上。否则进入401047地址中进行循环。

esp+eax+68h+var64中,即用户输入的值中取值与61h7Ah进行比较,大体意思即为判断用户输入满足在"a"~"z"之间。若不满足条件,跳至short loc_4010B3中,而它直接终止了整个函数的运行。

关键的一步。esp+esi+70h+var_64中的内容被移入值eax中,该段内容经eax+eax*2-0x11C=3*eax-0x11C的结果被放入了eax中,之后mod26运算,得到的结果再加上61ha的 ascii 码表示)构成密文并写入内存的esp+esi+70h+var64中。

根据上述过程,有 3*eax-0x11C=a*eax-a*0x61+b,得到。即仿射加密函数为

最后,加密后的内容(在esp+70h+var_64)与程序中的字符串qxbxpluxvwhuzjct比较,若成功就会得到You really knows了。

再用 F5 看下伪代码确认下分析是否正确。

该知道的都知道了,可以开始写 payload 了!

Payload 编写

整理一下思路:
输入的内容经过仿射密钥加密,函数为 ,密文e(x)qxbxpluxvwhuzjct
根据密码学的知识,解密密钥应为

编写 python 解密程序如下

rev_payload.py
1
2
3
4
5
6
def rev_3():
str = '''qxbxpluxvwhuzjct'''
ori_str = list(str)
# 解密x=9(y-7) ord('a')=97
new_str = [chr((ord(i) - 97 - 7 + 26) * 9 % 26 + 97) for i in ori_str]
print(''.join(new_str))

其输出结果为doyouknownfangshe

将其作为命令行参数运行程序,结果为下图所示

成功达成目标