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

可能会花费你很长时间,大约一天半天,但是我们要有信心,恒心!

base64 隐写原理 + 破解隐写的代码

仔细看!!!!!!!

Tr0y's Blog baseStego

存在隐写的编码末尾都存在 = ,一个 = 隐写 2bit

隐写的编码,解码后,再编码,最后挨着 = 的字符会发生变化。

史上最完全的源码解析

真小白级此题的隐写解码的python解析,

代码分析

# -*- coding: utf-8 -*-
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)
print(''.join([chr(int(bin_str[i:i + 8], 2)) for i in range(0, len(bin_str), 8)]))

1 python 3.8.无法保存

# -*- coding: utf-8 -*-

在 python 3.8 IDE编写的程序文件无法保存,也就无法运行,加上这一行就可以了保存了。

2 这一行为后面求隐写数据提供了标尺,后面再解释

b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

3 python 文件读写

with open('1.txt', 'rb') as f:

python提供的打开文件的方法,不需要关闭文件,即不需要写 f.close() ,但要注意文件操作的代码都写到 f:下面,有格式要求,有缩进。

注意stego.txt要和脚本放到同一目录下。

"r" - 读取 - 默认值。打开文件进行读取,如果文件不存在则报错。

"b" - 二进制 - 二进制模式(例如图像)。

以二进制读入文件数据,也可以直接读入文本数据。

w3school 文件读写

博主 有梦就要去实现它 with open() as f:

4 隐写数据二进制字符串

bin_str = ''

用来存储,隐藏的字符flag, 在后面所有求的的隐写二进制数据都将追加到 bin_str 的尾部

5 readlines()

for line in f.readlines():

可以使用 readline() 方法返回一行:

循环读入文件,每次读取一行,下面就是对每一次读入的二进制数据的一些操作。

6 strip("\n")

stegb64 = str(line, "utf-8").strip("\n")  //将读入的二进制串编成文本串,此时和stego.txt中的base64串一样,去除了\n换行符 假!
rowb64 = str(base64.b64encode(base64.b64decode(stegb64)), "utf-8").strip("\n") //解码后的又编码的base64串,即原来的base64 真!

可以理解为 utf-8的英文字符 和 ASCII的英文字符 编码是一致的。 在任何一种编码格式中 0-127所代表的字符都是一样的

在base64隐写中,如果存在隐写的数据,隐写数据后的base64 和 没有隐写数据的base64 在最后一个字符会发生变化,即=后面

一个 = 隐藏 2bit数据。集齐8bit,就可以拼出一个字符串

  • eg.隐写

    stegb64 = IHdyaXRpbmcgaGlkZGVuIG1lc3NhZ2VzIGluIHN1Y2ggYSB3YXkgdGhhdCBubyBvbmV=

    rowb64 = IHdyaXRpbmcgaGlkZGVuIG1lc3NhZ2VzIGluIHN1Y2ggYSB3YXkgdGhhdCBubyBvbmU=

    这里隐写了数据 '01'

    特别!如果没有变化,也算是一种隐写 ==->'0000' =->'00' 这个可能根据不同的隐藏方法有关。我也可以定义只有不同的
  • eg.strip()

    a=" gho stwwl\n"

    a.strip("\n") = ' gho stwwl'

    去掉一行首部和尾部的换行符,若要去一边的话还有 rstrip() lstrip()

7 offset 偏离(数字类型)

offset = abs(b64chars.index(stegb64.replace('=','')[-1])-b64chars.index(rowb64.replace('=','')[-1]))
  • abs() 返回绝对值 V的位置 - U的位置
  • stegb64.replace('=','')[-1] 去掉末尾的'=' 并且返回它的最后一个字符 V
  • rowb64.replace('=','')[-1] 去掉末尾的'=' 并且返回它的最后一个字符 U
  • index() 返回这个字符在 b64chars 中的位置

8 计算 '=' 的数量

equalnum = stegb64.count('=') #no equalnum no offset
if equalnum:
bin_str += bin(offset)[2:].zfill(equalnum * 2)

如果存在等号表示隐藏了数据,我们把隐藏的数据转换成二进制存到 bin_str 中 以追加的方式

  • bin(x) 返回一个整数 int 或者长整数 long int 的二进制表示。

    bin(1)='0b1' 上面的例子就是这个(U V)

    bin(2)='0b10'

    bin(4)='0b100'

    因为返回的字符串都有 '0b' 但我们只要二进制数据

    [2:] 从 '0b' 之后截取 我们取到'1'

    但是这个隐写了 2bit 所以用到了 zfill()

  • .zfill(equalnum * 2) 方法返回指定长度的字符串,原字符串右对齐,前面填充0。

  • str = '1'

    str.zfill(2) = '01'

    str.zfill(4) = '0001'

经过这次的转换 我们求解了 '01' 的隐藏数据

经过几个循环

IHdyaXRpbmcgaGlkZGVuIG1lc3NhZ2VzIGluIHN1Y2ggYSB3YXkgdGhhdCBubyBvbmV= '01'

LCBhcGFydCBmcm9tIHRoZSBzZW5kZXIgYW5kIGludGVuZGVkIHJlY2lwaWVudCwgc3VzcGU= '00'

Y3RzIHRoZSBleGlzdGVuY2Ugb2YgdGhlIG1lc3M= '00'

YWdlLCBhIGZvcm0gb2Ygc2VjdXJpdHkgdGhyb3VnaCBvYnNjdXJpdHkuIFS= '11'

我们得到了 B 0100 0011 这是 码ascii

输出

print(''.join([chr(int(bin_str[i:i + 8], 2)) for i in range(0, len(bin_str), 8)]))
  • int() 函数用于将一个字符串或数字转换为整型。

    int(x, base=10)

    x -- 字符串或数字。

    base -- 进制数,默认十进制。
  • join()

Python join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串。

str.join(sequence)

sequence -- 要连接的元素序列。

str = "-";

seq = ("a", "b", "c"); # 字符串序列

print str.join( seq );

结果 : a-b-c

为了匹配 sequence 生成一个字符列表 以便用于 join();

最后,这些解码的字符就连接到一起了。

动手写一遍吧

base64stego 还不懂base64的隐写,详解15行代码带你领略的更多相关文章

  1. base64文件隐写脚本

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

  2. SQL Server 表的管理_关于事务的处理的详解(案例代码)

    SQL Server 表的管理_关于事务的处理的详解(案例代码) 一.SQL 事务 1.1SQL 事务 ●事务是在数据库上按照一定的逻辑顺序执行的任务序列,既可以由用户手动执行,也可以由某种数据库程序 ...

  3. 代码详解:TensorFlow Core带你探索深度神经网络“黑匣子”

    来源商业新知网,原标题:代码详解:TensorFlow Core带你探索深度神经网络“黑匣子” 想学TensorFlow?先从低阶API开始吧~某种程度而言,它能够帮助我们更好地理解Tensorflo ...

  4. SQL Server 表的管理_关于数据增删查改的操作的详解(案例代码)

    SQL Server 表的管理_关于数据增删查改的操作的详解(案例代码)-DML 1.SQL INSERT INTO 语句(在表中插入) INSERT INTO 语句用于向表中插入新记录. SQL I ...

  5. SQL Server 表的管理_关于事务操作的详解(案例代码)

    SQL Server 表的管理_关于事务操作的详解(案例代码) 1.概念 事务(transaction): 是将多个修改语句组合在一起的方法,这个方法中的所有语句只有全部执行才能正确完成功能.即要么全 ...

  6. SQL Server 表的管理_关于表的操作增删查改的操作的详解(案例代码)

    SQL Server 表的管理_关于表的操作增删查改的操作的详解(案例代码) 概述: 表由行和列组成,每个表都必须有个表名. SQL CREATE TABLE 语法 CREATE TABLE tabl ...

  7. http500:服务器内部错误案例详解(服务器代码语法错误或者逻辑错误)

    http500:服务器内部错误案例详解(服务器代码语法错误或者逻辑错误) 一.总结 服务器内部错误可能是服务器中代码运行的时候的语法错误或者逻辑错误 二.http500:服务器内部错误案例详解 只是一 ...

  8. Notepad2(C语言+Windows消息写的,24592行代码)

    C语言+Windows消息写的,24592行代码 http://www.flos-freeware.ch/

  9. scala 隐式详解(implicit关键字)

    掌握implicit的用法是阅读spark源码的基础,也是学习scala其它的开源框架的关键,implicit 可分为: 隐式参数 隐式转换类型 隐式调用函数 1.隐式参数 当我们在定义方法时,可以把 ...

随机推荐

  1. C语言函数调用完整过程

    C语言函数调用详细过程 函数调用是步骤如下: 按照调用约定传参 调用约定是调用方(Caller)和被调方(Callee)之间按相关标准 对函数的某些行为做出是商议,其中包括下面内容: 传参顺序:是从左 ...

  2. N皇后求解。万万没想到,只用一个一维数组就搞定了。还体现了回溯。

    一.啥是N皇后?先从四皇后入手 给定一个4x4的棋盘,要在棋盘上放置4个皇后.他们的位置有这样的要求,每一列,每一行,每一对角线都能有一个皇后. 你可能会对这个对角线有疑惑,其实就是每一个小正方形的对 ...

  3. ethtool - 命令

    ethtool 导览:     1. 如何查看 Linux 中可用的网卡接口     2. 如何查看 Linux 中网卡信息     3. 如何查看网卡驱动版本以及硬件版本     4. 如何查看网络 ...

  4. DNS 缓存中毒--Kaminsky 攻击复现

    0x00 搭建实验环境 使用3台Ubuntu 16.04虚拟机,可到下面的参考链接下载 攻击的服务是BIND9,由于条件限制,这里使用本地的一台虚拟机当作远程DNS解析器,关闭了DNSSEC服务,其中 ...

  5. HTML5和CSS3提高

    一.HTML5的新特性 HTML5 的新增特性主要是针对于以前的不足,增加了一些新的标签.新的表单和新的表单属性等. 这些新特性都有兼容性问题,基本是 IE9+ 以上版本的浏览器才支持,如果不考虑兼容 ...

  6. Centos下搭建DNS域名解析服务器

    Centos下搭建DNS域名解析服务器 DNS  即Domain Name System(域名系统)的缩写,它是一种将ip地址转换成对应的主机名或将主机名转换成与之相对应ip地址的一种机制.其中通过域 ...

  7. k8s 运行单实例 mysql

    配置文件mysql.yaml --- apiVersion: v1 kind: Service metadata: name: mysql-01 spec: ports: - port: 3306 s ...

  8. mooc人大单元测试2

    1 单选(2分) 下列选项中不是关系数据库基本特征的是(  ). A. 不同的列应有不同的数据类型 B. 不同的列应有不同的列名 C. 与行的次序无关 D. 与列的次序无关 2 单选(2分) 关系代数 ...

  9. ASP程序写的项目与微信服务号(公众号)完美结合。仅需一个DLL组建WeixinDLL

    因ASP程序开发有很多优点,早年间ASP风靡全球,因此如今还在继续运营的ASP开发的项目仍在运行着,但是随着社交网络不断发达,特别是微信支付.微信通讯.小程序等的出现,导致很多ASP项目对接起来就比较 ...

  10. 01- APP移动端测试怎么测试?APP测试方法大全。

    由于智能手机时代来临,很多产品都有了APP,作为一个测试人员掌握APP测试是必要的. 在展开APP测试之前,首先了解一下几个点: 1.基于软件测试框架之上.复习下软件测试框架. 2.框架的内容贯穿于A ...