Base64隐写
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
Base64隐写的更多相关文章
- 记XDCTF的misc之旅---base64隐写
bWFpbigpe2ludCBpLG5bXT17KCgoMSA8PDEpPDwgKDE8PDEpPDwoMTw8Cm==ICAgICAgIDEpPDwoMTw8KDE+PjEpKSkrKCgxPDwx ...
- base64文件隐写脚本
base64文件隐写脚本 base64 可以在文件中隐藏信息,记录一下提取脚本 ''' base64文件隐写脚本 import re import base64 b64chars = 'ABCDEFG ...
- base64stego 还不懂base64的隐写,详解15行代码带你领略
网上写了好多关于xctf MISC新手篇的base64Stego隐写的教程,但大都不太清楚,基本上都是讲了一段隐写原理,直接上代码了.但是代码是这道题的关键,代码讲了如何解码这个隐写的完整流程,这次我 ...
- python2/3中 将base64数据写成图片,并将图片数据转为16进制数据的方法、bytes/string的区别
1.python2将base64数据写成图片,并将数据转为16进制字符串的方法 import binascii img = u'R0lGODlhagAeAIcAAAAAAAAARAAAiAAAzABE ...
- CTF-练习平台-Misc之 图片又隐写
八.图片又隐写 修改后缀名为zip,打开解压出两个文件 解压发现有密码,用WinHex打开发现文件头是zip的,所以出来把后缀名改为zip,再用工具爆破 最后得到解压密码,解压后是一个图片,改后缀名为 ...
- 记一道CTF隐写题解答过程
0x00 前言 由于我是这几天才开始接触隐写这种东西,所以作为新手我想记录一下刚刚所学.这道CTF所需的知识点包括了图片的内容隐藏,mp3隐写,base64解密,当铺解密,可能用到的工具包括bin ...
- 深入理解JPEG图像格式Jphide隐写
0x00 隐写原理 Jphide是基于最低有效位LSB的JPEG格式图像隐写算法,使用JPEG图像作为载体是因为相比其他图像格式更不容易发现隐藏信息,因为JPEG图像在DCT变换域上进行隐藏比空间域隐 ...
- 隐写技巧——利用JPEG文件格式隐藏payload
0x00 前言 继续对图片隐写技巧的学习,这次是对JPEG文件格式的学习和理解.同PNG文件的格式对比,JPEG文件相对简单,读取其中隐藏payload的方式大同小异,两者区别在于文件格式不同,可供利 ...
- LSB最低有效位隐写入门
LSB也就是最低有效位 (Least Significant Bit) 被替换成传递的信息字节.对原图影响很小. 这题可以算是隐写工具[wbStego]的使用入门练习题吧. 第一步,告诉你工具是支持在 ...
随机推荐
- IOC——Spring的bean的管理(xml配置文件)
Bean实例化(三种方式) 1.使用类的无参构造进行创建(大多数情况下) <bean id="user" class="com.bjxb.ioc.User" ...
- 学习zabbix(一)
一.zabbix监控简介 server: 通过收集snmp和agent发送的数据,写入数据库(MySQL,ORACLE),再通过 php+apache 在 web 前端展示. agent:主机通过安装 ...
- 如何正确的阅读Datasheet?
不仅仅是芯片,包括工具.设备几乎任何电子产品,都需要去阅读它的datasheet,除了包括最低.最高要求,特点,建议和用途及其兼容的设备等等,更重要的是原厂商以一个成功者的身份去告诉你一些注意事项. ...
- Flex 布局新旧混合写法详解(兼容微信)
flex 是个非常好用的属性,如果说有什么可以完全代替 float 和 position ,那么肯定是非它莫属了(虽然现在还有很多不支持 flex 的浏览器).然而国内很多浏览器对 flex 的支持都 ...
- android 布局的android:padding 和android:margin的区别
android:layout_marginLeft指该控件距离边父控件的边距, android:paddingLeft指该控件内部内容,如文本距离该控件的边距. 如: 当按钮分别设置以上两个属性时,得 ...
- Element UI table参数中的selectable的使用
Element UI table参数中的selectable的使用中遇到的坑:页面: <el-table-column :selectable='selectable' type="s ...
- 【Android开发】【第三方SDK】蒲公英摇一摇
摇一摇用户信息反馈功能:用户通过摇晃手机或者触发按钮,弹出反馈信息界面,填写个人意见,上传服务器的功能. 1. 蒲公英官网注册应用,获取AppId作为唯一标识: 2. 下载sdk,获取pgyer_sd ...
- sql server总结二
一些常用查询 Insert into 表(字段一,字段二,字段三,---) values(插入一,插入二,插入三,----) Update 表 set 字段= where 字段= Delete fro ...
- Python入门-分支循环结构
编写代码的过程中,除了基本的变量,数据类型,在实际开发中,大量代码是根据判断条件,进而选择不同的的向前运行方式. 这些向前的运行方式基本分为两种:分支结构,循环结构 1.分支结构 if单分支结构 # ...
- 时间篇之centos6下修复的ntp操作(ntpd和ntpdate两个服务区别)
系统采样,本采样和命令都是在centos6.4的系统中进行 主要比较centos7和centos6之间的差异,因为大部分都开始采用centos7但是有些老系统还采用centos6,这样我们就需要熟悉c ...