base64隐写(攻防世界杂项base64stego)

base64原理

先简单介绍一下base64解密:

(图片来源见水印,侵删)

base64使用 a-zA-Z0-9+/ 等64个字符来替换掉所有字符,同时使用 = 来替换掉空格,既然一共有64个字符,那么每个字符只需要6位即可表示出来,对应表如下:

base64隐写(攻防世界杂项base64stego)_第1张图片

例如,原本的3个字节的数据经过编码后需要4个字节来表示:3*8 = 4*6;可以看出,只有二进制位数恰好是8和6的倍数才可以刚好用这64位表示。

那如果位数不是8和6的公倍数怎么办呢?——方法就是在二进制数串后面加0,一直到二进制位数变成6的倍数,然后在编码后的字符串后面添加 1 个或 2 个等号”=”, 表示所添加的零值字节数。参考下图:

Tr0y

 

base64解密

解密过程是这样的:

首先把已经加密的字符串后面的等号(=)去掉,然后从左到右,每8位一组,剩余的不足8位的丢掉,再每组二进制串按照转换表转换成相应字符。

以上图为例:

VHIweQ== 变成 VHIweQ(01010100 | 01110010 | 00110000 | 01111001 | 0000变成 01010100 | 01110010 | 00110000 | 01111001 | 变成 Tr0y

base64隐写

从上面的解密过程中可以看出,多余的4位(标红的4个0)在解密的时候并没有用到,也就是说,无论后四位是0000还是0001,解密结果都没有改变,这就提供了一个可以隐藏信息的地方。如下图;

éå

那么,怎么判断有没有信息被隐藏进去了呢?

假设我们已经把后四位0000变成了0001,现在我们得到的加密后的字符串是VHIweR==,利用python中base64的解密函数直接解密后得到Tr0y,然后用base64的加密函数加密,得到的是VHIweQ==;

这时候我们就可以发现,按照正常加密流程加密得到的VHIweQ==,跟原始的字符串VHIweR==是不一样的,这就说明有信息被隐藏在了里面。

例题(攻防世界base64stego)

得到的一个加密文本是stego.txt:

base64隐写(攻防世界杂项base64stego)_第2张图片

把所有文本解密后发现得到一段话,并没有什么有用信息,参考题目,考虑base64隐写,附上脚本:(适用于python2情况)

其中

  • zfill()方法,返回指定长度的字符串,原字符串右对齐,前面填充0
  • index()方法,指定字符串中是否含有要查找的子字符串,返回包含子字符串开始处的索引值,否则抛出异常
def get_base64_diff_value(s1, s2):
    base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    res = 0
    for i in xrange(len(s1)):
        if s1[i] != s2[i]:
            return abs(base64chars.index(s1[i]) - base64chars.index(s2[i]))
    return res

def solve_stego():

    with open('D:/stego.txt', 'rb') as f:
        file_lines = f.readlines()

    bin_str = ''
    for line in file_lines:
        steg_line = line.replace('\n', '')
        norm_line = line.replace('\n', '').decode('base64').encode('base64').replace('\n', '')
        diff = get_base64_diff_value(steg_line, norm_line)

        pads_num = steg_line.count('=')
        if diff:
            #print bin(diff)
            bin_str += bin(diff)[2:].zfill(pads_num * 2)

        else:
            bin_str += '0' * pads_num * 2

    res_str = ''

    for i in xrange(0, len(bin_str), 8):

        res_str += chr(int(bin_str[i:i+8], 2))
    print res_str

solve_stego()

运行后得到:

你可能感兴趣的:(python,杂项)