base64隐写
本文最后更新于346 天前,其中的信息可能已经过时,如有错误请发送邮件到2292955451@qq.com

最近在打攻防时发现了一个隐写叫base64隐写,因为里面的东西涉及脚本和其他的我不知道的奇奇怪怪的知识,然后刁哥告诉我要做笔记,于是就直接搬了个大佬的笔记过来。

base64

BASE64 是一种编码方式,是一种可逆的编码方式.
编码后的数据是一个字符串,包含的字符为: A-Za-z0-9+/
共 64 个字符:26 + 26 + 10 + 1 + 1 = 64
其实是 65 个字符,= 是填充字符.

64 个字符需要 6 位二进制来表示,表示成数值为 0 ~ 63

这样,长度为 3 个字节的数据经过 Base64 编码后就变为 4 个字节


编码

比如,字符串 Tr0 经过 Base64 编码后变为 VHIw

Tr0
Tr0

上面说的字符串长度为 3 个字节的数据位数是 8x3=24,可以精确地分成 6x4.
如果字节数不是 3 的倍数,则位数就不是 6 的倍数,那么就不能精确地划分成 6 位的块.
此时,需在原数据二进制值后面添加零,使其字节数是 6 的倍数.
然后,在编码后的字符串后面添加 1 个或 2 个等号,表示所添加的零值字节数.
比如,字符串 Tr0y 经过 Base64 编码后变为 VHIweQ==

Tr0y
Tr0y

橙色底纹就是添加的 0

这是 Base64 编码的方式

解码

解码就是编码的逆过程。

  1. 把 Base64 字符串去掉等号,转为二进制数(VHIweQ== -> VHIweQ -> 010101000111001000110000011110010000)
  2. 从左到右,8 个位一组,多余位的扔掉,转为对应的 ASCII 码(01010100 01110010 00110000 01111001 0000 -> 扔掉最后 4 位 -> 01010100 01110010 00110000 01111001 -> Tr0y)

隐写原理

注意红色的 0,我们在解码的时候将其丢弃了,所以这里的值不会影响解码. 所以我们可以在这进行隐写。为什么等号的那部分 0 不能用于隐写?因为修改那里的二进制值会导致等号数量变化,解码的第 1 步会受影响。自然也就破坏了源字符串。而红色部分的 0 是作为最后一个字符二进制的组成部分,还原时只用到了最后一个字符二进制的前部分,后面的部分就不会影响还原。

唯一的影响就是最后一个字符会变化。如下图

隐写


如果你直接解密VHIweQ==VHIweR==‘,得到的结果都是’Tr0y‘。

当然,一行 base64 顶多能有 2 个等号,也就是有 2*2 位的可隐写位。所以我们得弄很多行,才能隐藏一个字符串,这也是为什么题目给了一大段 base64 的原因。接下来,把要隐藏的 flag 转为 8 位二进制,塞进去就行了。

加密

import base64

flag = 'Tr0y{Base64isF4n}' #flag
bin_str = ''.join([bin(ord(c)).replace('0b', '').zfill(8) for c in flag])

base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

with open('0.txt', 'rb') as f0, open('1.txt', 'wb') as f1: #'0.txt'是明文, '1.txt'用于存放隐写后的 base64
for line in f0.readlines():
rowstr = base64.b64encode(line.replace('\n', ''))
equalnum = rowstr.count('=')

if equalnum and len(bin_str):
offset = int('0b'+bin_str[:equalnum * 2], 2)
char = rowstr[len(rowstr) - equalnum - 1]
rowstr = rowstr.replace(char, base64chars[base64chars.index(char) + offset])
bin_str = bin_str[equalnum*2:]

f1.write(rowstr + '\n')
PYTHON

解密

import base64
b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
with open('stego.txt', 'rb') as f:
    bin_str = ''
    for line in f.readlines():
        stegb64 = str(line, "utf-8").strip("\n")
        rowb64 = str(base64.b64encode(base64.b64decode(stegb64)), "utf-8").strip("\n")
        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)
    b = ''.join([chr(int(bin_str[i:i + 8], 2)) for i in range(0, len(bin_str), 8)])  # 8 位一组
    data = ""
    m = "flag{" + b + "}"
    m = m.replace("\x00", "")
    print(m)
使用这个脚本的时候要注意把对应的文件放在python文件下
文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇