攻防世界_Misc_新手区_base64stego
题目描述:菜狗经过几天的学习,终于发现了如来十三掌最后一步的精髓
知识点
BASE64 是一种编码方式, 是一种可逆的编码方式.
编码后的数据是一个字符串, 包含的字符为: A-Za-z0-9+/
共 64 个字符:26 + 26 + 10 + 1 + 1 = 64
其实是 65 个字符, “=”是填充字符.
64 个字符需要 6 位二进制来表示, 表示成数值为 0~63.
索引 | 字符 | 索引 | 字符 | 索引 | 字符 | 索引 | 字符 |
---|---|---|---|---|---|---|---|
0 | A | 16 | Q | 32 | g | 48 | w |
1 | B | 17 | R | 33 | h | 49 | x |
2 | C | 18 | S | 34 | i | 50 | y |
3 | D | 19 | T | 35 | j | 51 | z |
4 | E | 20 | U | 36 | k | 52 | 0 |
5 | F | 21 | V | 37 | l | 53 | 1 |
6 | G | 22 | W | 38 | m | 54 | 2 |
7 | H | 23 | X | 39 | n | 55 | 3 |
8 | I | 24 | Y | 40 | o | 56 | 4 |
9 | G | 25 | Z | 41 | p | 57 | 5 |
10 | K | 26 | a | 42 | q | 58 | 6 |
11 | L | 27 | b | 43 | r | 59 | 7 |
12 | M | 28 | c | 44 | s | 60 | 8 |
13 | N | 29 | d | 45 | t | 61 | 9 |
14 | O | 30 | e | 46 | u | 62 | + |
15 | P | 31 | f | 47 | v | 63 | / |
长度为 3 个字节的数据经过 Base64 编码后会变为 4 个字节
例如:
Z | T | Q | |||||||||||||||||||||
90 | 84 | 81 | |||||||||||||||||||||
0 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 |
22 | 37 | 17 | 17 | ||||||||||||||||||||
W | I | R | R |
三个字符的数据位数是38=24 正好24=64所以能刚好分为4组,如果数据位数不是6的倍数就会有空位,此时需要往后补0凑够6的倍数,如果8个数据位全为0则对应“=”
L | w | ||||||||||||||||||||||
76 | 119 | ||||||||||||||||||||||
0 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
19 | 7 | 28 | 0 | ||||||||||||||||||||
T | H | c | = |
注意到119的ASCLL码对应的二进制是0 1 1 1 0 1 1 1,而加密出的字符c只有其后四位有关,所以0 1 1 1 0 0中后面两个0可以任意修改而不会影响解密后的结果,所以就可以在这两位中隐藏数据,(至于为什么不能再最后面的0 0 0 0 0 0中隐藏数据 :000000对应的是 ’ = ’ 如果改动后解密出来的结果就变了,容易被人发现。)
tips:有一个 ‘ = ’ 可以隐藏两位数据 两个 ‘ = ’可以隐藏四位,‘ = ’最多只能有两位。
至此给出这道题的python脚本。
其实对应的这种题python有专门的base64库来写脚本,这里给出的是最基本的语法编写了。
base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
path = input("path") #读取文件的位置
def change(string_test) :
strings_ans = ""
for every in string_test :
bin_num = ""
if every == "=" :
return strings_ans
else :
num = base64.find(every)
while num != 0 :
bin_num += str(num%2)
num = int(num/2)
while len(bin_num) <6 :
bin_num += "0"
bin_num = bin_num[::-1]
strings_ans += bin_num
return strings_ans
def answer(strings_last) :
ans = ""
strings_temp = change(strings_last)
if strings_last.count('=') == 1 :
ans += strings_temp[-2:]
else :
ans += strings_temp[-4:]
return ans
with open(path + "\\" + "stego.txt","r") as in_file : #输入文件的名称
strings_first = in_file.readlines()
strings = []
for every_strings in strings_first :
if every_strings[-2] =="=" :
strings.append(every_strings)
with open(path + "\\" + "out.txt","w") as out_file : #输出文件的名称
ans = ""
for line in strings :
ans += answer(line)
num = 0
list_num = []
for i in range(0,len(ans)) :
num = num*2+int(ans[i])
if (i+1)%8 == 0 :
list_num.append(num)
num = 0
ans = ""
for i in list_num :
ans += chr(i)
out_file.write(ans)