记XDCTF的misc之旅---base64隐写

Posted Pinging_Goooooo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记XDCTF的misc之旅---base64隐写相关的知识,希望对你有一定的参考价值。

bWFpbigpe2ludCBpLG5bXT17KCgoMSA8PDEpPDwgKDE8PDEpPDwoMTw8Cm==
ICAgICAgIDEpPDwoMTw8KDE+PjEpKSkrKCgxPDwxKTw8KDE8PDEpKSksKCgoMQp=
ICAgICAgIDw8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxKQq=
ICAgICAgIDw8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMQp=
ICAgICAgIDw8MSk8PCgxPDwxKTw8ICAgICAgICAgKDE8PDEpKS0oKDE8PDEpPDwoCr==
ICAgIAkxPDwxKTw8KDE8PDEpKSsgICAgICAgICgoMTw8MSk8PCgxPDwoMT4+Ch==
ICAgICAgIDEpKSkrKDE8PCgxPj4xKSkpICAgICAgICAgICAgICAgICAgICAgICAgLAq=
ICAgICAgICgoKDE8PDEpPDwoMTw8MSkgICAgICAgICAgICAgICAgICAgICAgICA8PAo=
ICAgICAgICgxPDwxKTw8KDE8PDEpKS0oKDEgPDwxKTw8KDE8PDEpIDw8KDE8PCgxCl==
ICAgICAgID4+MSkpKS0oKDE8PDEpPDwoMTw8KDE+PjEpKSkpLCgoKDE8PDEpCp==
ICAgICAgIDw8KCAgICAxPDwgICAgICAgICAgICAgICAgICAgICAgICAgIDEpCt==
ICAgICAgIDw8KCAgICAxPDwgICAgICAgICAgICAgICAgICAgICAgICAgIDEpCu==
ICAgICAgIDw8KCAxPDwxKSktKCgxIDw8MSk8PCAoMSA8PDEpPDwoMSA8PAr=
ICAgICAgICgxPj4xKSkpLSgoMTw8MSk8PCgxPDwoMT4+MSkpKSksKCgoMTw8MSk8PAo=
ICAgICAgICgxPDwxKTw8KDE8PDEpPDwoMTw8MSkpLSgoMTw8MSk8PCgxPDwxKTw8KAr=
ICAgICAgIDE8PCgxPj4xKSkpLSgxPDwoMT4+ICAgICAgICAgIDEpKSksKCgoMTw8MSk8PAq=
ICAgICAgICgxPDwxKTw8KDE8PDEpKSsgICAgKCgxPDwxKSAgICA8PCgxPDwxKTw8Ch==
ICAgICAgICgxPDwoMT4+MSkpKS0oKCAgICAgMTw8MSk8PCggICAgICAxPDwoMT4+Co==
ICAgICAgIDEpKSkpLCgoMTw8MSk8PCAgICAgICgxPDwxKSAgICAgICAgPDwoMTw8MSkpCl==
ICAgICAgICwoKCgxPDwxKTw8KDE8PCAgICAgIDEpPDwoICAgICAgIDE8PDEpPDwoMTw8MSkpLQr=
ICAgICAgICgoMTw8MSk8PCgxPDwxKSAgICAgKS0oMTw8KDE+PjEpICAgICAgKSksKCgoCj==
ICAgICAgIDE8PDEpPDwoMTw8MSk8PCggICAgMTw8MSk8PCgxPDwxKSktICAgICgoMQp=
ICAgICAgIDw8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMQq=
ICAgICAgICkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PAp=
ICAgICAgICgxPDwxKTw8KDE8PCgxPj4xKSkpLSgxPDwoMT4+MSkpKSwgKCgoMTw8MQp=
ICAgICAgICk8PCgxPDwxKTw8KDE8PDEpPDwoMTw8MSkpLSgoMTw8MSk8PCAoMSAgCk==
ICAgICAgIDw8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxCp==
ICAgICAgICkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8Cn==
ICAgICAgICggICAgIDE8PCgxPj4xKSkpKyAgICAoMTw8MSkpLCgoKDEgICAgIDw8Cj==
ICAgICAgIDEpICAgIDw8KDE8PDEpPDwgICAgICAoMTw8MSk8PCgxICAgICAgIDw8Ck==
ICAgICAgIDEgICAgICkpLSgoMTw8MSk8PCAgICAoMTw8MSk8PCgxICAgICAgIDw8Cj==
ICAgICAgICggICAgIDE+PjEpKSktKCgxICAgICAgPDwxKTw8KDE8PCAgICAgICAoCj==
ICAgICAgIDEgICAgID4+MSkpKSksKCgoMSAgICAgPDwxKTw8KDEgICAgICAgIDw8Cg==
ICAgICAgIDEgICAgICk8PCgxPDwxKTw8KCAgICAgMTw8MSkpLSgoMSAgICAgIDw8Cm==
ICAgICAgIDEgICAgICk8PCgxPDwxKTw8ICAgICAoMTw8MSkpKygoICAgICAgICAxCv==
ICAgICAgIDw8MSk8PCgxPDwoMT4+MSkpKSksKCgoMTw8MSk8PCgxPDwxKSA8PCgxCm==
ICAgICAgIDw8MSkpKygxPDwoMT4+MSkpKSwoKCgxPDwxKTw8KDE8PDEpKSArKCgxCs==
ICAgICAgIDw8MSk8PCAoMTw8KDE+PjEpKSkgKyAoMTw8ICgxPj4xKSkpfSA7Zm9yCn==
ICAgICAgIChpPSgxPj4xKTtpPCgoKDE8PDEpPDwoMSA8PDEpKSsoKDEgPDwxKTw8KAr=
ICAgICAgIDE8PCgxPj4xKSkpKygxPDwxKSk7aSsrKSAgcHJpbnRmKCIlYyIsbltpXSk7fQp=

 

以上是txt文件内容,如果你有幸把他解出来了。那么恭喜你,你将会得到一个乱起八糟的<1111111>的混淆C代码。并且执行出来是hello world。

所以并没有卵用呀有没有!!

之后查阅资料发现了神奇的隐写方法。那就是base64隐写。

在这里我要引用另一位大神的文章了:http://www.tuicool.com/articles/RRr2miE(标明出处)***

 

大家可以从上面的图片看到一个字母A对应的ascll值有八位,而base64的一个字母只占6位(原因如下:大家可以看到base64的所有加密后的内容也就这63个字符,也就是说用二进制的话6位就足够了!!)

所以一一对应过去我们发现每一个字母都多出来了两个空位,又因为3*8=4*6,所以一班base64都是用四个一组表示三个字母,如果字母不足三个,比如上上图的BC我们用base64表示就是QkM=,就是因为空出来的地方用‘=’表示了。在知道了这些之后呢我们就进入了正题。

 

在这里如果我们想隐藏一些内容需要怎么办呢?大家应该知道,base64在解码的时候是根据等号的个数进行的。也就是说我有一个等号,我就会去掉八个0-------------例如:上图的A对应的二进制位为01000001,补全之后为01000001    0000,对应的base64的编码为QQ(010000     010000),所以之后有两个‘=’。在解码的时候我就要在去掉=对应的6个零的同时在去掉4个0,也就是解码的时候会解析01000001而不是010000010000。这时候我们会发现了,我们去掉的这四个0是不是可以用来隐藏信息???反正解码的时候会被裁剪掉,那我干脆就在后面做一些手脚,用base64来混淆视听。

 

hhhh讲到这里大家是不是有所领悟呢?也就是说我前面放的txt内容其实都是被混淆过的!!所以想得到真正的base64就应该把题目中的密文解密然后在加密。对比后就得到了隐藏内容。

 

下面放上py脚本

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(\'E://encode_code.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:
            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()

这个脚本也是git上的,不是我原创的哈(声明下)。

我在这里解释下这个脚本。

一、

steg_line = line.replace(\'\\n\', \'\')

norm_line = line.replace(\'\\n\', \'\').decode(\'base64\').encode(\'base64\').replace(\'\\n\', \'\')

这个是我们应该第一个注意的地方,第二个norm_line为何先decode又encode??这就是我刚才提到的解密后去掉多余0,然后加密后真正的base64就还原了。之后才可以对比

 

 二、def get_base64_diff_value(s1, s2):

这个函数就是用来比较差异然后得出来差异的位数的。比如加密之后的最后一位是g,原密码为m,这个函数就得出来m与g相差6,也就是110.之后在主函数里在110前面补上一个0,补的原理是把=个数乘2,得到位数。例如:2*2=4,那么110前面就要补一个0编程0110

 

嗯。。。。这里就讲完了这次比赛的一道题。我是有所收获的,希望带给大家一些灵感。谢谢~~

 

 

                       Made By  Pinging!!!~~

BXS Come On~~~!!!!

 

以上是关于记XDCTF的misc之旅---base64隐写的主要内容,如果未能解决你的问题,请参考以下文章

bugku-writeup-MISC-隐写2

记某次CTF的图片隐写题✨

记某次CTF的图片隐写题✨

ctf-misc-图片隐写术套路总结

记一道CTF隐写题解答过程

base64stego 还不懂base64的隐写,详解15行代码带你领略