1. 程式人生 > >記XDCTF的misc之旅---base64隱寫

記XDCTF的misc之旅---base64隱寫

ping 個數 new for return lin logs pri ide

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隱寫