前言

base编码是一种常见的编码方式,常见的有base64、base32、base16,最近在做题时碰到了一道base隐写的misc题目,于是上网学习了一下base的编码方式以及隐写原理


base64编码方式

Base64就是一种基于64个可打印字符来表示二进制数据的方法,具体的64个字符分别是A-Za-z0-9+/以及占位符=
<font color=#999AAA >示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
base64编码首先将原字符串的每一个字符转换为8位的二进制ascii码,将所有的8位二进制数拼接后按照6个一组进行重组,再将每一组转换为10进制,去base64的索引表中寻找对应编码字符,以下图为例
在这里插入图片描述
原字符串为hel,将ascii码转化为二进制后一共3*8=24位,再6个一组,故编码后为aGVs四位字符。
但在实际过程中,并不是所有的字符串转化后长度都是6的倍数,这时就需要用0来补充未满的位数,并使用=来当作占位符,使最终的长度为8的倍数
在这里插入图片描述
在这里插入图片描述

base64解码方式

在对base64进行解码时,会将需要解码的字符串每四个分为一组(在有占位符=的情况下,待解码的内容长度总是4的倍数)
当末尾是=时,则将等于号去掉,并将最后一个字符的后两位二进制数去掉,剩下的二进制数长度即为8的倍数,再进行解码
当末尾是==时,则将两个等于号去掉,并将最后一个字符的后四位二进制数去掉,剩下的二进制数长度即为8的倍数,再进行解码

base64隐写原理

在存在占位符=的情况下,会将部分位的二进制数丢弃,而这些被丢弃的位中可以插入隐写的信息,即在那些用0补充的位上插入别的信息,同时又不影响base解码
可知base64编码中,末尾=的个数只可能是0个、1个、2个,而0个的时候无法隐写,故我们需要考虑末尾有1个或2个等号的情况

base64隐写例题:[GXYCTF2019]SXMgdGhpcyBiYXNlPw==

buu上有题目,附件可自行下载,
在这里插入图片描述
将附件中的base64编码正常解码后会得到一大堆英文语句,虽然有含义但是没有跟flag相关的信息,于是我们要考虑是否存在base64隐写,可用工具进行简单判断,把其中一句用base64解码后再编码

在这里插入图片描述
可以看到,解码后再编码的结果和原先不一样,则本题存在base64隐写,原本的00填充位一定隐藏了别的信息,我们可以取出所有隐写位的信息,全部拼接起来后8个一组计算10进制,再当作ascii码转化为字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import base64

table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
file = open("flag.txt")
flag=''
tmpbin=''

for line in file.readlines():
line=line.strip('\n')
if(line[-1]=='='):
if(line[-2]=='='):
i=table.index(line[-3])
b=bin(i)[2:]
b=b.zfill(6)
print(line)
print(b)
print(b[-4:]+'\n')

tmpbin+=b[-4:]
else:
i = table.index(line[-2])
b = bin(i)[2:]
b = b.zfill(6)
print(line)
print(b)
print(b[-2:]+'\n')

tmpbin+=b[-2:]

length= len(tmpbin)/8
for i in range(int(length)):
flag+=chr(int(tmpbin[i*8:i*8+8],2))

print(flag)

base32隐写

与base64隐写原理相同,通过改变填充位的0来隐藏信息,以下为base32的编码表,由于只有32个字符,故base32在编码时为5位一组来编码,末尾的=个数有可能为0个、1个、3个、4个、6个,下面直接给出脚本
在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import base64

table='ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'
file = open("xjj.txt")
flag=''
tmpbin=''

for line in file.readlines():
line=line.strip('\n')
if(line[-1]=='='):
if(line[-3]=='='):
if(line[-4]=='='):
if (line[-6] == '='):
i=table.index(line[-7])
b = bin(i)[2:]
b = b.zfill(5)
tmpbin+=b[-2:]
print(line)
print(b)
else:
i = table.index(line[-5])
b = bin(i)[2:]
b = b.zfill(5)
tmpbin += b[-4:]
print(line)
print(b)
else:
i = table.index(line[-4])
b = bin(i)[2:]
b = b.zfill(5)
tmpbin += b[-1:]
print(line)
print(b)
else:
i = table.index(line[-2])
b = bin(i)[2:]
b = b.zfill(5)
tmpbin += b[-3:]
print(line)
print(b)

length= len(tmpbin)/8
for i in range(int(length)):
flag+=chr(int(tmpbin[i*8:i*8+8],2))

print(tmpbin)
print(flag)