密码学知识积累
概述
在ctf比赛中,逆向这块很大一部分都是在考查密码学的知识,其中需要逆向的代码基本都会是一些加解密的操作,因此有必要学习和积累一些常见的密码学知识。当然这里我们并不太需要知道如何使用密码学上的方法去破解加密密文,如果一定要破解的话,也是有工具和对应程序实现的。因此我们要做的就是去熟悉这些密码学的加密方式,并在逆向代码中认出来。
凯撒密码
凯撒密码(Caesar),相传为凯撒所创,属于古典密码学中的移位密码。这种加密方式比较简单,就是将字母的对应关系向前或者向后偏移几位,因此一般也就是限制在26个大小写字母中。比如:abc,使用向后偏移一位进行加密,那么密文就是bcd,当然解密的话把密文字母对应关系向前推一位就行。
如下图所示,是2020年ACTF的一道逆向题rome,下图中的while循环部分就使用了凯撒密码的加密方式。第一个if判断字符是否处于大写字母A(ord(“A”) == 65)和Z(ord(“Z”) == 90)之间,同理第二个if判断字符是否处于小写字母a和z之间,然后不属于大写字母和小写字母的字符将不会被处理。在if判断成功后,我们可以看到,大写字母使用的是65-51=14作为偏移,小写字母使用的是97-79=18作为偏移,因此将加密后的密文大小写字母分别减去对应偏移即可得到原来的结果。

如下代码所示,是我个人写的一个模板,可以复用,其中的测试数据正是这道题给出的加密后的密文。
import string
class Caesar:
def __init__(self, text, l_off, u_off):
"""
text: 待加密或者解密文本
l_off: 小写字母偏移
u_off: 大写字母偏移
"""
self.text = text
self.l_off = l_off
self.u_off = u_off
self.l_case = string.ascii_lowercase
self.u_case = string.ascii_uppercase
def encrypt(self):
"""
大小写字母有各自的偏移单独加密,非字母不加密
"""
res = ""
for ch in self.text:
if ch in self.l_case:
loc = (ord(ch)-97+self.l_off) % 26
res += self.l_case[loc]
elif ch in self.u_case:
loc = (ord(ch)-65+self.u_off) % 26
res += self.u_case[loc]
else:
res += ch
return res
def decrypt(self):
"""
大小写字母有各自的偏移单独解密,非字母不解密
"""
res = ""
for ch in self.text:
if ch in self.l_case:
loc = (ord(ch)-97-self.l_off) % 26
res += self.l_case[loc]
elif ch in self.u_case:
loc = (ord(ch)-65-self.u_off) % 26
res += self.u_case[loc]
else:
res += ch
return res
if __name__ == "__main__":
# test
text = "Qsw3sj_lz4_Ujw@l"
res = Caesar(text, 18, 14).decrypt()
print(res)
res = Caesar(res, 18, 14).encrypt()
print(res)

rot移位密码
rot移位密码其实和凯撒密码是类似的,都是在当前字符集中取一定的偏移作为密码字符对应进行加密的,可以看成凯撒密码的拓展,其可以分为四种类型,每一种都有固定的偏移和用途。
- rot5,仅对数字进行加密,取5作为偏移,1加密后对应6;
- rot13,仅对大写或者小写字母进行加密,其实就是凯撒密码不论大小写都取偏移13,a加密后对应n;
- rot18,即上述两种密码的结合,分别对数字和字母进行操作;
- rot47,可对ascii字符进行移位加密,取偏移位47,此时0加密后对应下划线_
如下图所示,是FlareOn4比赛上一道的re题目login,是一道逆向js代码的题目,打开附件发现是一个网页文件,查看源代码可以发现下面的js代码。

对上面js代码仔细分析后,可以发现就是rot13加密,然后解密的话可以直接复用前面凯撒密码的脚本,结果如下。

base编码系列
base64加密
base64加密,与其说是一种加密,不如说是一种编码方式,常用于网络传输中,其主要特点是将字符编码为64种可见字符。其大致编码过程如下:3个字符一组,按照ascii的规则每个字符由8bit构成,这样就是3*8=24bit一组,然后按照6bit构成一个索引,匹配64种可见字符构成的表,刚好对应4个base64字符。此外对于不是3的倍数的字符串,末尾会用\x00补齐一个或者两个字节,相应的base64编码就会以一个或者两个等号结束来表明补齐的字节数。
那么在逆向中,base64会有什么特点吗?如下图所示,对于逆向中使用base64编码的程序,一般在程序中都会有如下由大写字母、小写字母以及数字和+/构成的base64表。

此外我们再看程序本身,如下图所示,在程序开头我们会看到有判断是否被3整除的操作。在while循环中,aAbcdefghijklmn就是我们的base64表,然后可以看到每次循环都有4个字符从base64表中被匹配出来。在程序最后,我们可以看到仍然有判断是否被3整除的操作,然后根据余数末尾补齐61(chr(61) == “=”)),所以这是典型的base64编码的操作。当然不同程序实现base64编码的方式不尽相同,但大致流程和原理是一样的,所以在逆向过程中需要把握其灵魂所在。

这里对上面代码中的关键部分做个解释,如下代码所示:
// 取出第一个字符的前6位并找出对应的结果字符
*(v6 + v2) = aAbcdefghijklmn[*(v3 + a1) >> 2];
// 将第一个字符的后2位与第二个字符的前4位进行组合并找到对应的结果字符
*(v6 + v2 + 1) = aAbcdefghijklmn[(16 * (*(v3+a1) & 3)) | (*(v3 + 1+ a1) >> 4)];
// 将第二个字符的后4位与第三个字符的前2位组合并找出对应的结果字符
*(v6 + v2 + 2) = aAbcdefghijklmn[4 * (*(</

本文详细介绍了CTF比赛中的密码学逆向分析知识,包括凯撒密码、rot移位密码、base编码系列、MD5、RSA、DES、AES等常见加密算法的原理与应用。在逆向工程中,理解和识别这些加密方式是关键,文章通过实例代码解析了如何在实际解题中应用这些知识。
最低0.47元/天 解锁文章
2万+

被折叠的 条评论
为什么被折叠?



