freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

cryptopals解密之旅(完结篇)
2020-07-02 11:49:34
所属地 湖南省
 
 
0x00前言
本系列文章将带来cryptocals 这套密码学挑战的write-up.不同于通过上课或者看书的方式学习密码学,这些题目来自于现在生活中一些软件系统和密码构造中的缺陷。
本系列每一个题的wp基本是采用如下结构:题目解释、相关知识点讲解、代码实现及解释,运行测试。代码均采用python3实现,代码实现部分是参考国外大佬ricpacca的,结合自己的理解及成文需要进行部分修改。
第二套一共有八关。
第二套题目
v2-8991b7ac2ed05dec14edd76bc57a7b1d.jpg
主要是和分组密码相关的
0x05
第13题
v2-d404e2f0879f9fb5c628be0d31848d38.jpg
要求写一个函数profile_for,传入profile_for("foo@bar.com"),会生成
{
email: 'foo@bar.com',
uid: 10,
role: 'user'
}



注意,不需要编码@,&等符号
接着生成随机的AES密钥,然后用这个密钥加密编码后的用户信息,再解密得到编码的结果,然后解析编码的结果。
题目要去我们仅使用user和密文,要求进行攻击,使得解密,解码后得到的role是admin,而不是user
这种攻击方法的原理利用的是ECB模式分块单独加密,之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响的特点。通过将故意构造的密文替换原密文,从而篡改解密后的信息。
具体代码如下:
定义加密函数,使用AES-128-ECB加密编码过的用户信息,以及对应的解密函数
v2-f9aefa69509794683b83412797669db4.jpg
使用key=value键值对的格式将字典对象编码为字符串,比如将
{
foo: 'bar',
baz: 'qux',
zap: 'zazzle'
}
编码为
foo=bar&baz=qux&zap=zazzle
v2-02aeb412a6810ae47bb2112dede685a6.jpg
同样写一个对应的解码函数,将key-value格式解码为字典格式
v2-0bc9d9fd117558f570f25d68cc78ba41.jpg
给出email地址,按指定规则进行格式化,下图中的replace是为了删除原有的&,=
v2-938469b05e54157becbae733c7bb5f26.jpg
下图的函数是关键,通过cut-and-paste攻击,将部分user的原密文替换成admin的。然后返回重新组合后的密文。
第一次加密的明文分为三个块,第一个块为email=xx..xx将这个填充成一个块,第二个块为admin,然后根据pkcs#7填充规则,还需填充11个\x0b,第三个块为&uid=10&role=user
第二次加密的明文分为三个块。第一个块为email=master@me.,第二个块为com&uid=10&role=,第三个块为user\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c
接下来我们组合三个块成新的密文,
第一个块为email=master@me.,
第二个块为com&uid=10&role=,
第三个块为admin\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b。
函数返回的就是这三个块组成的密文。
v2-fdffff9796e5bc5b883dc78891b5e223.jpg
该密文被解密,然后解码后,得到的role就会是就会是admin而不是user
v2-f52b6eae56b322d6c21fdab3d09e3208.jpg
完整代码及执行结果如下所示
v2-26a49a2ddc557ac84f78a1632827e339.jpg
0x06
第14关
v2-009729bf974b90a0b98d0aae7bc0bcd2.jpg
这一关比第12关难度大。要求我们生成随机数量的随机字符,作为明文的前缀。
v2-ad4d3c5284c65846c35d74bb38423831.jpg
还是要求我们拿到target-bytes的明文
思路就是:
  1. 首先找到块长度、加密模式,这些在12题里实现过了
  2. 找到前缀长度
  3. 一次一个byte解密target-byte,这在12题也实现了
加密函数加密的内容就是随机前缀+可控字符串+未知字符串
v2-80a4203911309d2c463854de4550fc06.jpg
找到target-byte的一个字节。填充length_to_use个a,保证将块的最后一个字符设置为target-byte的第一个字符。然后计算我们将截取多少个字节进行比较,这个值在后面比较假的密文和实际密文时会用到。计算实际密文,然后暴力测试每个可能的字符,将每个可能字符加密后得到的密文与实际密文比较
v2-c182d947aa1f5fe1bd76c3b808e9281b.jpg
检查给出的密文是否包含两个连续的相同块
v2-17b873064752d0b45a80e183594b340a.jpg
计算前缀的长度。首先找到前缀在哪个块结尾,然后找到前缀结尾的精确位置,就可以计算出前缀的长度
首先分别加密空消息和一个字符的消息,得到两个密文。比较这两个密文,第一个不同的块就是前缀结束的块。然后需要精确定位是在前缀是在哪个位置结束的。
加密“两个块长度+一个随机增量”长度大小的相同的字节,如果字节数足够了(在密文中找到了两个连续的相同块),我们就可以精确计算前缀在其最后一个块中结束的位置。其在最后一块中结束的位置为块长度-i
v2-6b0ddc247d99fde2d48a87cf37d45679.jpg
找到块长度,判断是否为ECB模式,计算出target-byte的长度,这就是循环的次数。在循环中调用get_next_byte来计算。target-byte长度等于加密空字符串后的长度减去前缀长度
v2-75be4fa257bf9d094c2c287b9ad6bb1d.jpg
完整代码及执行结果如下
v2-91ac53860adff1ae330b135ab10b5ab4.jpg
拿到了target-bytes的明文
0x07
第15题
v2-caae6ec86d7d60cf9c61a05036f5f739.jpg
 
要求实现一个函数,可以检测一段明文是否为pkcs#7填充,如果是话则去掉填充,不是的话则报异常
这个函数在s2p9.py中已经实现过了,这里不再重复。
0x08
第16关
v2-71b4f9bd1dc8f2437defb1c5ebb6e40a.jpg
cbc翻转攻击,这个知识点在CTF中也有出现过,那么我们看看脱去CTF的外衣,其本质是怎样的
题目要求首先生成随机的AES密钥
写一个函数接收任意输入字符串,加上前缀"comment1=cooking%20MCs;userdata=",加上后缀";comment2=%20like%20a%20pound%20of%20bacon",去掉;和=
然后,该函数应将输入填充到16字节AES块长度,并在随机AES密钥下对其进行加密。
写一个函数解密该字符串并查找“; admin = true; “。根据字符串是否存在,返回true或false。如果上一个函数正确实现,则第二个函数会返回false。实际上,可以进行cbc翻转攻击,使其返回true。我们通过修改密文来实现这一点(无需密钥)。
CBC翻转攻击技术可以通过修改密文来操纵解密后的明文。其原理就是如果对初始化向量中的任意比特进行反转,则明文分组中相应的比特也会反转,其原因是第一个明文分组会和初始化向量进行异或运算。
v2-044b165047885f862cd08a4994beb840.jpg
 
这样我们所要做的就是对初始化向量进行攻击。
在下面的cbc_bit_flip中我们攻击的就是;和=
代码实现:
实现加密函数,添加前缀和后缀后,使用AES-128-CBC进行加密
实现解密函数,还会检查解密后的内容中是否有;admin=true;
v2-f98c7c146dfa2f637b5bf719a1a1d797.jpg
计算块长度。要找到一个块的长度,我们需要加密越来越长的明文,直到输出密文的大小也增加为止。发生这种情况时,我们可以轻松地计算出块的长度,其值等于新的密文长度与其初始长度之间的差
v2-b6173e5b0e88aa9fae88e36d839c8927.jpg
计算前缀的长度。
加密两个不同的明文字节,得到两个不同的密文,计算两个密文间相同的长度,赋给common_length,确保其为块长度的整数倍。
从1开始将越来越多的相同字节添加到明文中,分别加密,比较两个密文,直到它们有一个额外的相同块为止。如果找到了,这意味着通过添加i个字节,我们可以控制相同的输入(包括前缀)为块大小的整数倍,这样我们就可以得到前缀的长度了。
v2-e13ccda2b6c0f63c277bc5cb0fa3ebc8.jpg
cbc翻转攻击的关键函数
首先得到块长度和前缀长度,接着计算需要添加多少字节到前缀,才能使得其长度为块长度整数倍,接着计算要添加多少字节到明文才能使得其长度为块长度整数倍。然后将明文加长1个块长度(用?填充),对其加密。使用异或的方法,我们可以通过更改明文之前的块的字节来生成所需的字节。最后将伪造的密文片段放在一起,组成完整的密文
v2-d83bf9f17f06499daedb1017574d4551.jpg
完整代码及执行结果如下
v2-1a60fdbe1075938f28b820e752e7c381.jpg
可知,在解密之后的明文里确实找到了; admin = true;,返回了true
参考:
声明:笔者初衷用于分享与普及网络知识,若读者因此作出任何危害网络安全行为后果自负,与合天智汇及原作者无关!
 
# 网络安全
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者