由于传播、利用此文所提供的信息而造成的任何直接或间接的后果和损失,均由使用者本人承担,Cyb3rES3c及文章作者不承担任何责任。如有侵权烦请告知,我们将立即删除相关内容并致歉。请遵守《中华人民共和国个人信息保护法》、《中华人民共和国网络安全法》等相关法律法规。
Base64解码时会根据编码字符串中的填充字符等号(=)去判断是否将最后一组二进制字符串补零的部分去掉,Base64隐写主要利用填充字符(=)将秘密信息隐藏在要去掉的部分中。比如字符m的二进制字符串经过分组、补零后二进制字符串就变成了 00011011、00010000,第二个二进制字符串的后四位(0000)是补充上去的,在解码时会先将这四个字符去掉,因此这四个字符无论是什么,都不会对解码的结果造成影响,所以可以通过修改补零的部分去隐藏信息。
只有经过Base64编码后带有填充字符(=)的才能隐藏信息,因为带填充字符的才会在最后一组二进制字符串后面补零,不带填充字符的是不会补零的,也就无法隐藏秘密信息。
如果不了解Base64编码的原理,可以看上一篇文章。
将所有带有填充字符(=)的字符串上的各个字符在Base64索引表上找到对应的索引(十进制数),将索引(十进制数)转换为二进制数,将同一个Base64编码字符串上的字符的二进制字符串都拼接成一个字符串,根据填充字符(=)的个数提取补充的部分,将所有提取出来的字符串拼接成一个字符串(二进制字符串),然后按照每8个字符为一组进行分组,最后一组如果不足8个字符就丢弃。
如果以上提取步骤描述不清晰,可参考下面的程序代码帮助理解。
题目只提供了一个文本文件和一个JPEG图片
二维码对解题是没有帮助的,直接跳过。
文本文件中有很多经过Base64编码的字符串
题目已经告诉我们这是Base64隐写,直接写脚本提取隐藏的信息
def splitStringByLength(string, length):
handleList = []
tempString = ""
count = 0
for char in string:
tempString += char
count += 1
if count == length:
handleList.append(tempString)
count = 0
tempString = ""
return handleList
def base64AlphabetGenerator():
bs64Alphabet = {}
originUpperChar = 'A'
originLowerChar = 'a'
originNumberChar = '0'
for i in range(0, 62):
if i < 26:
bs64Alphabet[i] = chr(ord(originUpperChar) + i)
elif i < 52:
bs64Alphabet[i] = chr(ord(originLowerChar) + i - 26)
elif i < 62:
bs64Alphabet[i] = chr(ord(originNumberChar) + i - 52)
bs64Alphabet[62] = '+'
bs64Alphabet[63] = '/'
return bs64Alphabet
def findKeyByValue(keyValue, bs64Alphabet):
for key, value in bs64Alphabet.items():
if value == keyValue:
return key
return -1
fileName = "ComeOn!.txt"
with open(fileName, 'r') as f:
contents = f.readlines()
f.close()
stegBinaryInfoList = []
base64Alphabet = base64AlphabetGenerator()
for content in contents:
equalCount = content.count('=')
if equalCount == 0:
continue
binaryString = ""
content = content.replace('=', '').replace('n', '')
for char in content:
key = findKeyByValue(char, base64Alphabet)
tempString = format(key & 0xFF, '08b')
tempString = tempString[2:]
binaryString += tempString
stegBinaryInfo = binaryString[-(equalCount * 2):]
if stegBinaryInfo != "":
stegBinaryInfoList.append(stegBinaryInfo)
stegBinaryInfoString = ""
for element in stegBinaryInfoList:
stegBinaryInfoString += element
handleBinaryList = splitStringByLength(stegBinaryInfoString, 8)
flag = ""
for binaryString in handleBinaryList:
flag += chr(int(binaryString, 2))
print(flag)
程序执行结果
Base64隐写的原理和前面讲的LSB最低有效位隐写的原理是相同的,都是利用数据中的冗余位去隐藏信息,其实还有很多隐藏信息的方式都和这个类似,也可以利用网络协议进行信息隐藏,例如利用ICMP协议和TCP协议的冗余字段去隐藏信息,感兴趣的师傅可以去实践一下!
原文始发于微信公众号(Cyb3rES3c):隐写术之Base64隐写
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论