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编码。

  1. 根据ASCII编码进行转换:tolele <==> 01110100 01101111 01101100 01100101 01101100 01100101
  2. 重新按6bit进行划分:011101 000110 111101 101100 011001 010110 110001 100101
  3. 根据Base64编码表进行转码:dG9sZWxl

检验一下是没问题的:

通过这种方式编码,当字符数为3的倍数时才会刚好可以转换成若干个Base64编码字符。那当字符数不为3的倍数时,该怎么办呢?解决方法就是往后面以8bit为单位填充0。

这时,有两种情况:

  1. 字符数为3n+1:此情况最后会多出2个比特位,我们可以填充2个单位的0(即16个比特位的0),这时会有多余的18个比特位。前6个比特位按表格进行转码,其余的每6个bit位转换成'='。
  2. 字符数为3n+2:此情况会多出4个比特位,填充1个单位的0,这样就多余12个比特位,为6的整数倍。后续和1中类似。

图像总是比话语更能说明内容:

检验一下:

0x02: Base64的解码过程:

很显然,解码过程就是编码的逆过程。

拿上面"tole"的Base64编码"dG9sZQ=="进行举例:

  1. 先把填充的'='去掉:dG9sZQ
  2. 根据Base64编码表进行转码:dG9sZQ <==> 011101 000110 111101 101100 011001 010000
  3. 从前往后,以每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隐写的更多相关文章

  1. 记XDCTF的misc之旅---base64隐写

    bWFpbigpe2ludCBpLG5bXT17KCgoMSA8PDEpPDwgKDE8PDEpPDwoMTw8Cm==ICAgICAgIDEpPDwoMTw8KDE+PjEpKSkrKCgxPDwx ...

  2. base64文件隐写脚本

    base64文件隐写脚本 base64 可以在文件中隐藏信息,记录一下提取脚本 ''' base64文件隐写脚本 import re import base64 b64chars = 'ABCDEFG ...

  3. base64stego 还不懂base64的隐写,详解15行代码带你领略

    网上写了好多关于xctf MISC新手篇的base64Stego隐写的教程,但大都不太清楚,基本上都是讲了一段隐写原理,直接上代码了.但是代码是这道题的关键,代码讲了如何解码这个隐写的完整流程,这次我 ...

  4. python2/3中 将base64数据写成图片,并将图片数据转为16进制数据的方法、bytes/string的区别

    1.python2将base64数据写成图片,并将数据转为16进制字符串的方法 import binascii img = u'R0lGODlhagAeAIcAAAAAAAAARAAAiAAAzABE ...

  5. CTF-练习平台-Misc之 图片又隐写

    八.图片又隐写 修改后缀名为zip,打开解压出两个文件 解压发现有密码,用WinHex打开发现文件头是zip的,所以出来把后缀名改为zip,再用工具爆破 最后得到解压密码,解压后是一个图片,改后缀名为 ...

  6. 记一道CTF隐写题解答过程

      0x00 前言 由于我是这几天才开始接触隐写这种东西,所以作为新手我想记录一下刚刚所学.这道CTF所需的知识点包括了图片的内容隐藏,mp3隐写,base64解密,当铺解密,可能用到的工具包括bin ...

  7. 深入理解JPEG图像格式Jphide隐写

    0x00 隐写原理 Jphide是基于最低有效位LSB的JPEG格式图像隐写算法,使用JPEG图像作为载体是因为相比其他图像格式更不容易发现隐藏信息,因为JPEG图像在DCT变换域上进行隐藏比空间域隐 ...

  8. 隐写技巧——利用JPEG文件格式隐藏payload

    0x00 前言 继续对图片隐写技巧的学习,这次是对JPEG文件格式的学习和理解.同PNG文件的格式对比,JPEG文件相对简单,读取其中隐藏payload的方式大同小异,两者区别在于文件格式不同,可供利 ...

  9. LSB最低有效位隐写入门

    LSB也就是最低有效位 (Least Significant Bit) 被替换成传递的信息字节.对原图影响很小. 这题可以算是隐写工具[wbStego]的使用入门练习题吧. 第一步,告诉你工具是支持在 ...

  10. [CTF隐写]png中CRC检验错误的分析

    [CTF隐写]png中CRC检验错误的分析 最近接连碰到了3道关于png中CRC检验错误的隐写题,查阅了相关资料后学到了不少姿势,在这里做一个总结 题目来源: bugku-MISC-隐写2 bugku ...

随机推荐

  1. 【干货分享】流程DEMO-请休假

    流程名: 请假申请  流程相关文件: 流程包.xml WebService业务服务.xml WebService.asmx WebService.cs  流程说明: 流程中集成了webservice服 ...

  2. javaScirpt事件详解-原生事件基础(一)

    事件 JavaScript与HTML之间的交互是通过事件实现的.事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间,通过监听特定事件的发生,你能响应相关的操作.图片引用:UI Events 事件流 ...

  3. block的常见用法

    一.声明和定义 1.声明 声明方式:返回值(^block)(参数).声明时,参数变量名可以省略:使用时,参数变量名不能省略,不然会无法调用传入的参数 void(^block)(); void(^blo ...

  4. 详细讲解Quartz.NET

    Quartz.NET是一个开源的作业调度框架,是OpenSymphony 的 Quartz API的.NET移植,它用C#写成,可用于winform和asp.net应用中.它提供了巨大的灵活性而不牺牲 ...

  5. Windows宿主机访问Ubuntu中mysql数据库笔记

    1.网络 既然要远程ubuntu的系统.那么首先是两个网络是不是在一个网段.能不能ping的通? a)  Windows电脑上--cmd 打开命令窗口.键入:ipconfig 命令.查看主机IP. b ...

  6. springmvc参数类型转换三种方式

    SpringMVC绑定参数之类型转换有三种方式:     1. 实体类中加日期格式化注解      @DateTimeFormat(pattern="yyyy-MM-dd hh:MM&quo ...

  7. JavaScript面向对象,闭包内存图,闭包和作用域

    var i = 10; function test(){ var j; i=20; //未定义 function test(){ j='hello'; } console.log(test()); / ...

  8. 从SVN到Git最强指南

    对于软件开发人员来说,版本控制系统他们再熟悉不过了,所谓版本控制系统就是软件项目开发过程中用于储存开发人员所写代码所有修订版本的软件.它的主要目的是实现开发团队并行开发.提高开发效率,对软件开发进程中 ...

  9. 201521123076《java程序设计》第三周学习总结

    1. 本周学习总结 2.书面作业 Q1.代码阅读 public class Test1 { private int i = 1;//这行不能修改 private static int j = 2; p ...

  10. MIP 技术进展月报:储存功能全新上线,MIP-Cache域名升级,校验更严谨

    集 ** 瞬时触达用户.高转化率.炫酷闪电标.优质展现形式 ** 等诸多特性为一体的 MIP 页面吸引了众多站点进行改造.为了更好地服务于广大站长,更快地倾听站长们的声音,MIP 技术团队特推出< ...