0x00: 前言
Base64編碼的作用:
- 將一些特殊的字符轉換成常見的字符,特殊的字符可能是不可見字符或者是大于ascii碼127的,將其變成常見的字符(在base64中為a~z A~Z 0~9 + /),
- Base64特別適合在某些網路協議下快速傳輸,
在學習Base64隱寫之前,得先熟悉Base64編碼與解碼的程序,
0x01: Base64的編碼程序
Base64編碼后的字符為”a~z A~Z 0~9 + /“共計64個,每個需要6個位元位進行存盤,原本,ASCII編碼字符每個字符占8個位元位,Base64編碼則是把原來每單位8個位元位的字符序列劃分成每單位6個位元位,然后按單位轉換成上述中的64個字符,

Base64編碼表
舉個栗子~:將字串"tolele"進行Base64編碼,
- 根據ASCII編碼進行轉換:tolele <==> 01110100 01101111 01101100 01100101 01101100 01100101
- 重新按6bit進行劃分:011101 000110 111101 101100 011001 010110 110001 100101
- 根據Base64編碼表進行轉碼:dG9sZWxl
檢驗一下是沒問題的:

通過這種方式編碼,當字符數為3的倍數時才會剛好可以轉換成若干個Base64編碼字符,那當字符數不為3的倍數時,該怎么辦呢?解決方法就是往后面以8bit為單位填充0,
這時,有兩種情況:
- 字符數為3n+1:此情況最后會多出2個位元位,我們可以填充2個單位的0(即16個位元位的0),這時會有多余的18個位元位,前6個位元位按表格進行轉碼,其余的每6個bit位轉換成'=',
- 字符數為3n+2:此情況會多出4個位元位,填充1個單位的0,這樣就多余12個位元位,為6的整數倍,后續和1中類似,
影像總是比話語更能說明內容:

檢驗一下:

0x02: Base64的解碼程序:
很顯然,解碼程序就是編碼的逆程序,
拿上面"tole"的Base64編碼"dG9sZQ=="進行舉例:
- 先把填充的'='去掉:dG9sZQ
- 根據Base64編碼表進行轉碼:dG9sZQ <==> 011101 000110 111101 101100 011001 010000
- 從前往后,以每8個位元位為單位進行ASCII轉換成字符,最后面會有4個'0'多余,直接去掉就行,
0x03: Base64隱寫原理:
可以留意一下解碼程序中的第三步,會將多余的位元位去掉(因為湊不到8位),那么,這說明了:這多余的位元位即使我們隨意的改變值也不會影響解碼后的結果,因為它會被丟棄掉,
測驗一下:還是上面的例子,最后是Q,為010000,后面的4個0在解碼時會被丟棄掉的,那我們使其變成010101,變成了V,解碼后的結果會改變嗎?

可見,這個改變并不會對解碼結果造成影響,
這樣,為了隱寫某些資料,我們就可以將資料寫入這里,但每個Base64編碼最多多余4個位元位,為了隱藏較大的資料,我們常常需要多個位元位,提取時,我們可以將每個多余的位元位截取出來,按一定的順序組合,從而得到我們的隱藏資料,
0x04: 例題實踐
Buuctf的base64隱寫:
https://buuoj.cn/challenges#[ACTF%E6%96%B0%E7%94%9F%E8%B5%9B2020]base64%E9%9A%90%E5%86%99
打開關鍵的txt檔案一看,大量的base64編碼,base64隱寫跑不了了:

這里直接用大佬的腳本了,python2執行是沒問題的,至于python3的話……
# -*- coding: cp936 -*-
b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
with open('1.txt', 'rb') as f:
bin_str = ''
for line in f.readlines():
stegb64 = ''.join(line.split())
rowb64 = ''.join(stegb64.decode('base64').encode('base64').split())
offset = abs(b64chars.index(stegb64.replace('=','')[-1])-b64chars.index(rowb64.replace('=','')[-1]))
equalnum = stegb64.count('=') #no equalnum no offset
if equalnum:
bin_str += bin(offset)[2:].zfill(equalnum * 2)
print ''.join([chr(int(bin_str[i:i + 8], 2)) for i in xrange(0, len(bin_str), 8)]) #8 位一組
0x05: 感慨
“您這flag挺能藏的呀~”
tolele
2022-05-14
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/498781.html
標籤:訊息安全
