常见算法逆向
Base64
Base64加解密
1 | 1. 将要加密的字符串变成二进制 |
加密步骤
空缺时会有一个补零操作
魔改
base64加密时一般会改base64编码表
比如本来的编码表:
1 | origin = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' |
更改后的编码表:
1 | base = 'aUiBDdopSQVOFlfLnTNrv4sj+MJW3g2Cy5IZk6APYt9RGwqm/8H7eKcx1EzbX0hu' |
使用更改的编码表进行解码:
1 | import base64 |
表一般会在程序运行的时候改掉,比如下面的例子
题目 easybase.exe
#### IDA 分析找到main函数,分析程序逻辑
1 | // 打印提示信息 |
1 | // 可能跟调试相关 |
1 | //给字符串Str1加密 |
1 | // 判断输入的字符串加密后是否与已知加密字符串相同 |
直接拿去解码是乱码,所以判断应该改了表
先进到base64_encode函数中查看加密逻辑:
在这里没有发现有什么改表操作,是一个常规的base64加密方法
那问题应该在debug()
函数
在debug()
函数中,最后返回的时候有一个random_shuffle()
函数,参数传进了base64编码表,应该是使用随机数种子打乱了编码表。如果程序正常执行不调试,那么随机数种子为0,如果程序在调试模式中运行,那么随机数种子会被设置成114514
所以动态调试的时候跳过IsDebuggerPresent()
函数即可,使用随机数种子0获取到打乱后的表,在进行解密就可以了
x64dbg动态调试
感觉x64dbg动态比IDA好用
可以使用IDA快速定位到debug()
函数,(主要分析在右侧注释)
在第一个断点处,将ZF位标位1,跳过Seed = 114514
,这样就得到了非调试模式下的base64表,表就应该在0x40F020这段内存中
这一段就是修改后的base64编码表,编写一下一段py进行解码
1 | import base64 |
RC4
RC4加解密
RC4是对称加密算法,加解密使用同一套秘钥
1 |
|
题目TCR0.exe
查一下壳
IDA看一下主要逻辑
直接动调拿出解密之后的flag
调试的时候发现没法调试,应该是有反调试,找main函数里面没有IsDebuggerPresent,猜测可能是使用TlsCallback,
在最下面跳转的语句下一个断点,运行到这里先修改一下ZF标志位
分析一下主函数,v10应该是用户输入的flag,大小为40字节,所以先给input一个40位的输入,过后直接改这40位就好了
v8数组应该是秘钥,这里的密钥加载到内存中,使用小端存储,所以排列起来应该是从右到左,一个字节一个字节来(先转成Hex)
密钥:
1 | 71 0b 02 49 73 b4 e1 a3 2f 58 71 85 16 67 b3 ab |
main函数的断点下在加解密之前,第24行
查看v10里面存储了40个'a'
使用patch修改这一块的密钥,注意最后一段不要全覆盖掉,只改DWORD64
大小的数据
程序过到加密之后,再查看v10
按A键转成字符串就出来了
Flag:NSSCTF{75025d7f6c9f2fbcf746228b4f3d623a}
题目TCR.exe
这个题目没法运行exe,会报错,安装了dll还是会报错,所以直接先查壳再仿写
主要逻辑大概是这样
主要就是上面三段逻辑,密钥、init初始化和加密算法
这是一个魔改的RC4算法,程序有点问题没法动调,所以仿写一下
1 |
|
看起来没问题,但是跑不出结果
看一下上面有一个sub_A325
里面有IsDebuggerPresent()
里面有一个对密钥修改的操作:
1 | ascii('4') xor 0x55 0x34 ^ 0x55 = 0x61 => DEC 97 => 'a' |
所以,key应该是random_k5y
果然算出了答案,但是发现少了一小段,发现少了四个字符的密钥
发现这一串也是密钥的一部分
加上之后,终于算出了正确答案NSSCTF{4af695c7065c5cf6053271d3e3151a2d}
TEA
TEA(Tiny Encryption Algorithm)是一种对称密钥加密算法,由David Wheeler和Roger Needham在1994年提出。TEA的设计目标是简单、高效,并且在实现上尽量减少代码的复杂性。
TEA加解密
1 |
|
题目 SEA0.txt
题目:
1 | hint1 = {11,22,33,44} |
这是一段IDA反编译的汇编代码,Key的长度是4位的一般会想到TEA家族(TEA,XTEA,XXTEA)的加密 再看hint2,是4*10=40位,大概是flag的长度,所以hint2可能是密文,hint1是Key
分析汇编代码:
这是一段完整的TEA加密,发现了mov [rbp+var_14], 9E3779B9h
,这里的delta,sub rsp, 20h
,这里的20h应该是round = 32
汇编中还有shl eax, 4
和shr eax, 5
,左移4和右移5,判断应该是标准TEA加密。
所以这一段汇编对应的C代码应该就是:
1 |
|
完整解密:
1 |
|
解密之后的答案为:NSSCTF{5b84a51236d7043fe2480d69d24b37a3}
XTEA
XTEA加解密
1 |
|
XTEA是TEA的升级版,增加了更多的密钥表,移位和异或操作等,TEA 算法被发现存在缺陷,作为回应,设计者提出了一个 TEA 的升级版本——XTEA(有时也被称为”tean”)。XTEA 跟 TEA 使用了相同的简单运算,但它采用了截然不同的顺序,为了阻止密钥表攻击,四个子密钥(在加密过程中,原 128 位的密钥被拆分为 4 个 32 位的子密钥)采用了一种不太正规的方式进行混合,但速度更慢了。
XXTEA
特点:Corrected Block TEA,原字符串长度可以不是4的倍数了
XXTEA加解密
XXTEA与TEA类似,都是块加密算法,以下是常规的加密和解密方法
1 |
|
题目 sec_cython.so
main.py
1 | import sec_cython |
看来主要的加密是在sec_cython里面的
so文件是Linux相当于windows的dll动态链接库,所以放到kali里面
kali里面写一个python文件
1 | import sec_cython |
1 | Help on module sec_cython: |
1 | import sec_cython |
1 | [235096951, 4274635695, 1983592480, 2346500962, 4098093858, 1778866619, 2372400532, 839025380, 4012226876, 1286419149] |
看到了DELTA = 0x9e3779b9,所以应该也是TEA家族中的一个,第一个是加密字符,第二个是key
IDA分析一下sec_cython.so
在函数表里面直接搜一下之前help
中出来的encrypt:
encrypt
前面这一大部分是编译so文件时编译上去的,只看结尾这个encrypt就行
找到下面这个东西,名字看起来是SEA,所以进到这个函数里面查看一下
看到这里有些熟悉,v5 = 10,为密钥的长度;v6 = 52,v7 = Divide(v6, v5),这里应该算的就是轮数
以上两段也有非常明显的左移5右移2异或,左移3右移4异或的操作
解密代码:
1 |
|
AES
题目 wheel.exe
打开发现这个程序加了upx壳
用upx -d脱一下壳
IDA已经识别出这是一个aes加密