[Crypto]ECB模式攻击

[Crypto]ECB模式攻击ECB 模式攻击原理 参考 https zachgrace com posts attacking ecb ecb 模式使用相同的 key 分块对明文分别进行加密 相同的明文获得相同的密文输出 nbsp 根据这一特性 可以构造如下数据进行攻击 nbsp 首先输入 blocksize 1 的填充 这样未知字符串的第一个字符将落到填充块的最后一个字节 nbsp nbsp XXXXXXAA nbsp AAAAAAAA nbsp AAAAAA

【ECB模式攻击原理】

(参考https://zachgrace.com/posts/attacking-ecb/)

[Crypto]ECB模式攻击

XXXXXXAA AAAAAAAA AAAAAAXX

XXXXXXBA AAAAAAAA AAAAAAAX

XXXXXXBB AAAAAAAA AAAAAAAA

这时会得到填充块的一个密文输出,爆破最后一个字节,直到产生与刚才相同的密文输出,就可以确定未知字符串的一个字节,重复这个过程就可以得到完整的未知字符串。

【攻击方法】

向包含未知字符串的明文中插入数据,其实也是枚举验算的过程:

1.获取未知字符串的第一位

比输入name为1,

服务器生成未知字符串”hello, 1, your mission’s flag is:  FLAGXXXXXX”的用ecb加密过的字符串S1给我们,

其中FLAGXXXXXX是我们希望得到的flag,通过观察题目程序可知,此处ECB使用的是16位的, 

 进而观察可知,16个字符的字符串加密后就变成32个字符的密文了。

就是说”hello, 1, your mission’s flag is:  X”的最后一个X刚好是第32位,我们首先通过这个32字符的字符串获取一下加密过的encrypto, 也就是64个字符的字符串S2,那么这个S2必然是S1的前64位。

然而我们刚开始并不知道这个X是什么,于是我们枚举这个X,令X为一个ascii字符,

比如向服务器发送”hello, 1, your mission’s flag is:  A”,获取密文,如果这个密文恰好是S1的前64位,那么A就是flag未知字符串的第一位,于是我们就激活成功教程了flag的第一位。

 2.获取未知字符串的剩余位

因为A已经是flag的第一位,根据激活成功教程的原理,我们要把未知字符放在第32位(此处和第一步一样取一个合理的16的倍数)

那么我们只要把name的名字长度缩小一个字符就可以了

即此时变为                       “hello, , your mission’s flag is:  AX”

 (可以对照第一步的字符“hello, 1, your mission’s flag is:  A”

依然枚举X即可,以此类推,获取全部的字符串(此处以”}”为结尾标志)

【代码】

主程序代码:

#!/usr/bin/env python # coding=utf-8 import conn import os number = 30 + 16 mess = "hello, 1, your mission's flag is: moeflag{" ans = "" while (number >= 0): found = False conn.remote("YourIp", 8001) conn.reads() mess = "1" * number conn.sends(mess) # print("发送 " + mess) initialdata = conn.reads() # print("原始 "+initialdata) blockdata = initialdata[0:128 + 32] # print("前端 \n"+blockdata) # print(initialdata) # print("----------") array = "mqmwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0{}_-~!@#$%^&*()-=+[]?><'|,./`\"m" #枚举的集合 for i in array: conn.reads() # print("尝试 "+i) mess = "hello, " + "1" * number + ", your mission's flag is: " + ans + i conn.sends(mess) data = conn.reads() # print(data) # print data if data[0:128 + 32] == blockdata: found = True print("发现 " + i) ans += i number = number - 1 if i == "}": number = -1 print("答案:" + ans) os.system("pause") # message=message+i break conn.close() if not found : print("没有找到~~") os.system("pause") print(ans) 

  组件conn的代码

import socket import os obj = None def remote(addr, ip): global obj obj = socket.socket() obj.connect((addr, ip)) def reads(): global obj ret_bytes = obj.recv(1024) ret_str = str(ret_bytes, encoding="utf-8") #print(ret_str) return ret_str def sends(content): global obj obj.sendall(bytes(content + "\n", encoding="utf-8")) def close(): global obj obj.close() 

    注:这两个代码需要放在同级目录下,只要运行main就可以了

【编写调试中的问题】

1.连接socket服务器后,能 收到服务器消息, 但是发送客户端发送数据后,却收不到服务器回复。

   见https://blog.csdn.net/u0/article/details/

   这可能是因为输入的字符串最后没有 换行符,导致服务器认为输入未结束。

2.程序运行到一定程度后没有输出反应:

   可能有这么几个原因:

     原因1:枚举的字符集合不够大,有些flag中例如“=”这样的数据没有包含进去。也可以采用转ascii,这样更完整,但是运算速度就降低了。

     原因2:flag位数太大, 移位以后还不够,可以 分批运行程序,也可以扩大初始name的长度

3.本来也可以用python中的pwn来做,但是Windows下面用pip来安装pwn经常出现错误,linux下,更新了国内源后,即便下载成功,安装 也会出错。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/222163.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午4:26
下一篇 2026年3月17日 下午4:26


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号