逆向分析之密码学
RC4
RC4是对称加密算法,通过密钥key和S盒生成密钥流,明文逐字节异或S盒,同时S盒也会发生改变。所以加密与解密使用了相同的函数和密钥K。RC4加密的强度主要来源于密钥的安全性,如果密钥泄露,则能直接解密出明文。
算法分析
S盒初始化
第一个256循环:初始化为0-255
第二个256循环:根据密钥K,交换密钥盒S
1 | for i=0 to 255 do |
异或生成密文
虽然是一个循环,但是可以分成两步
- 根据明文的长度生成相同长度的密钥流
- 密钥流和明文异或生成密文
1 | i,j=0; |
逆向分析识别RC4算法
使用ida pro中的Findcrypt识别一下,因为没有magicnum和一些特征字符,所以Findcrypt没有识别到rc4
rc4_setup
可以容易的发现两个256循环,第一个循环给s盒赋值,第二个循环根据密钥key对S盒进行swap。根据源码的了解,a2中保存的是密钥key
rc4_crypt
循环中最关键的就是S盒的swap,明文和S盒的异或。其中v6为S盒,a2指向明文和密文。
RC4特征判断
可以看到有很多的 %256 操作
汇编语言识别RC4算法
1 | #RC4加密C代码 |
汇编语言特征判断
debug x64:与debug x86差不多
MD5
java中MD5加密结果默认为32位小写
buu 消失的MD5:MD5加密的正确代码
1 | import hashlib |
MD5加密方式的判别
1 | stringBuilder.Append(b.ToString("X2"));//输出大写的十六进制 |
凯撒
凯撒加密代码(凯撒的加密对象:大小写字母)
1 |
|
注意关注“%26”,可以作为逆向中判别flag经过凯撒加密的特征之一(不代表只有%26出现才是凯撒加密)
大小写不同位移
这里分别对字符串中的大小字母进行了不同位移的凯撒加密
常规加密
%128的那一行代码也是对字符串进行了凯撒加密,因此%26不能作为判别凯撒加密的唯一特征。抓住凯撒对大小写字母加密的特征来判别是否为凯撒加密,又是否是相同位移的大小写字母加密
rot13加密
这是特殊的凯撒加密,即偏移量为13的凯撒加密
遍历字符串,判断每一位的值
1.和”Z”(90)比较大小,根据结果返回90或者122
2.执行c=c+13,并且和左边表达式返回的90或122比较大小
3.如果是满足大于等于关系,返回c(此时的c就是c=c+13)
否则返回c-26(此时c>”z”或者c>”Z”,c-26相当于循环了一次)
这个算法是rot13算法,将字符移动了13位,加密解密都使用同一个函数
RSA
根据”65537“和函数mpz_powm可以判别RSA加密
常见算法识别
特征值识别
很多常见的算法,如AES、DES等,在运算过程中会使用一些常量,而为了提高运算效率,这些常量往往被硬编码在程序中
通过识别这些特征值,可以对算法进行一个大致判断
算法 | 特征值(无特殊说明为十六进制)(备注) |
---|---|
TEA系列 | 9e377b9(Delta值) |
AES | 63 7c 77 7b f2 6b 6f c5 …(S盒) |
AES | 52 09 6a d5 30 36 a5 38…(逆S盒) |
DES | 3a 32 2a 22 1a 12 0a 02…(置换表) |
DES | 39 31 29 21 19 11 09 01…(密钥变换数组PC-1) |
DES | 0e 11 0b 18 01 05 03 1c…(密钥变换数组PC-2) |
DES | 0e 04 0d 01 02 0f 0b 08…(S函数表格1) |
BlowFish | 243f6a88 85a308d3 13198a2e 0370734(P数组) |
MD5 | 67452301 efcdab89 98bbadcfe 10325476(寄存器初始值) |
MD5 | d76aa478 e8c7bb756 24070db c1bdceee…(Ti数组常量) |
SHA1 | 67452301 efcdab89 98badcfe 10325476 c3d2e1f0(寄存器初始值) |
CRC32 | 00000000 77073096 ee0e612c 990951ba(CRC表) |
Basa64 | 字串”ABCDEFGHIJKLMNNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/“(字符串表) |
通过这种简单的识别法,许多开发者为各种分析工具开发了常量查找插件,如IDA的FindCypt、PEiD的KANAL等
在IDA中,FindCrypt、PEiD和KANAL都是用于分析PE文件的插件。
FindCrypt插件
可以识别PE文件中的加密算法。它可以识别多种常见的加密算法,包括RSA、AES、DES、RC4等。FindCrypt还可以识别一些自定义的加密算法。
PEiD插件
可以显示PE文件的各种信息,包括文件头、节表、导入表、导出表等。PEiD还可以识别一些常见的PE文件保护技术,如壳、混淆等。
KANAL插件
是PEiD的一个插件,用于分析PE文件中的加密算法。KANAL可以识别多种常见的加密算法,包括RSA、AES、DES、RC4等。KANAL还可以识别一些自定义的加密算法。
特征运算识别(伪代码)
算法 | 特征运算(伪代码)(说明) |
---|---|
RC4 | i=(i+1)%256; j=(j+s[i])%256; swap(s[i],s[j]) ; t=(s[i]+s[j]%256; (密钥流生成) |
RC4 | j=(j+s[i]+k[i])%256; swap(s[i],s[j]); 循环256次(S盒变换) |
Base64 | b1=c1>>2; b2=((c1&0x3)<<4)|(c2>>4); b3=((c2&0xf)<<2)|(c3>>6); b4=c3&0x3f;(8位变6位) |
TEA系列 | ((x<<4)+kx)^ (y+sum) ^ ((y>>5)+ky)(轮函数) |
MD5 | (X&Y)|((~X)&Z)(F函数) (X&Z)|(Y&( ~ Z))(G函数) X ^Y ^Z (H函数) Y ^(X|( ~ Z))(I函数) |
AES | x[j]=si%4] 循环4次 s[i][j]=x[j] 循环4次 整体循环4次(行位移) |
DES | L=R R=F(R,K)^ L(Feistel结构) |
第三方库识别
1、字符串识别
很多第三方库会将版权信息和该库使用的其它字符串(如报错信息)以字符串的形式写入库中。在静态编译时,这些字符串会被一并放入二进制文件。通过寻找这些字符串,可以快速判断使用了哪些第三方库。
2、函数签名识别
加载函数签名:Local File—FLIRT Sgnature file
IDA的签名识别功能能够识别C语言运行库函数,同时对同样由二进制机器代码构成的第三方库函数可以通过对应签名库匹配函数名、参数等信息。
3、二进制比对识别
由于编译环境等各种情况的差异,签名有时无法完全匹配库函数,但是使用同一个库编译的二进制文件中的库函数也会存在许多相同之处。如果能够确定程序编写者使用了某个已知库,并且我们能够获得一份含有符号且同样使用了该库的静态编译二进制文件,可以利用二进制比对的方法来确定每个库函数。
二进制比对工具—BinDiff:准备好待逆向文件和自己编译的带符号文件后,就可以在IDA中加载BinDiff,再分别加载这两个文件的IDB,稍等片刻即可看到比对结果。
比对的结果中会显示两个函数的相似度、变动和各自的函数名,双击即可具体跳转到某个函数。如果能够人工确定某两个函数是相同的,则可利用快捷菜单对函数重命名。
一般情况下,如果比较结果显示两个函数几乎没有改动(Similarity极高,Change没有或只有I)且他们不是空函数,那么他们极有可能是同一个函数,有小部分改动的(Similarity在0.9左右,Change有2~3项),则需要查看之后再确定。