网上写了好多关于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. Java并发编程之并发关键字

    volatile 保证可见性 一个线程修改volatile变量的值时,该变量的新值会立即刷新到主内存中,这个新值对其他线程来说是立即可见的 一个线程读取volatile变量的值时,该变量在本地内存中缓 ...

  2. P1012 拼数(JAVA语言)

    //早起刷题傻一天 题目描述 设有nn个正整数(n≤20)(n≤20),将它们联接成一排,组成一个最大的多位整数. 例如:n=3n=3时,33个整数1313,312312,343343联接成的最大整数 ...

  3. Prometheus 配置文件中 metric_relabel_configs 配置--转载

    Prometheus 配置文件中 metric_relabel_configs 配置 参考1:https://www.baidu.com/link?url=YfpBgnD1RoEthqXOL3Lgny ...

  4. [hash-bfs]USACO 3.2 Magic Squares 魔板

    魔 板 魔板 魔板 题目描述 在成功地发明了魔方之后,拉比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 我们知道魔板的每一个方格都有一种颜色 ...

  5. openGL官方Glut库配置教程

    在配置前要先安装好Visual Stdio环境 官方下载网站 注:一台Windows操作系统中可以存在多版本的Visual Stdio,多个版本之间互不干扰但不共享插件库,且高版本向下兼容,因此笔者更 ...

  6. MySQL提升笔记(1):MySQL逻辑架构

    深入学习MySQL,从概览MySQL逻辑架构开始. 首先来看一下MySQL的逻辑架构图: MySQL逻辑架构大概可以分为三层: 客户端:最上层的服务并不是MySQL所独有的,大多数基于网络的客户端/服 ...

  7. Windows命令行学习(系统信息收集)

    echo off :关闭回显 echo on :开启回显 net user :显示主机的电脑用户 ipconfig /displaydns:后面的 /displaydns是显示当前电脑所缓存的dns信 ...

  8. 6. Mybatis resultMap

    resultMap 元素是MyBatis中最重要最强大的元素.它就是让你远离90%的需要从结果集中取出数据的JDBC代码的那东西,而且在一些情形下允许你做一些JDBC不支持的事情.事实上,编写相似于对 ...

  9. Message Decoding UVA - 213

     Some message encoding schemes require that an encoded message be sent in two parts. The fifirst par ...

  10. Django 视图(View)

    1. 视图简介 2. URLconf 1)关联各应用下的 URLconf 2)URLconf 的编写 3)namespace 反向解析 3. 视图函数&错误视图 4. HttpRequest ...