writeup
cryptopals解密之旅(完结篇)
2020-07-02 14:30

文章回顾:

cryptopals解密之旅 (一)

cryptopals解密之旅 (二)

cryptopals解密之旅 (三)

0x00前言

本系列文章将带来cryptocals 这套密码学挑战的write-up.不同于通过上课或者看书的方式学习密码学,这些题目来自于现在生活中一些软件系统和密码构造中的缺陷。

本系列每一个题的wp基本是采用如下结构:题目解释、相关知识点讲解、代码实现及解释,运行测试。代码均采用python3实现,代码实现部分是参考国外大佬ricpacca的,结合自己的理解及成文需要进行部分修改。

第二套一共有八关。

第二套题目

1.png

主要是和分组密码相关的

第13题

2.png

要求写一个函数profile_for,传入profile_for("foo@bar.com"),会生成

111.jpg

编码为email=foo@bar.com&uid=10&role=user

注意,不需要编码@,&等符号

接着生成随机的AES密钥,然后用这个密钥加密编码后的用户信息,再解密得到编码的结果,然后解析编码的结果。

题目要去我们仅使用user和密文,要求进行攻击,使得解密,解码后得到的role是admin,而不是user

这种攻击方法的原理利用的是ECB模式分块单独加密,之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响的特点。通过将故意构造的密文替换原密文,从而篡改解密后的信息。

具体代码如下:

定义加密函数,使用AES-128-ECB加密编码过的用户信息,以及对应的解密函数

3.png

使用key=value键值对的格式将字典对象编码为字符串,比如将

    {

        foo: 'bar',

        baz: 'qux',

        zap: 'zazzle'

}

编码为

foo=bar&baz=qux&zap=zazzle

5.png

同样写一个对应的解码函数,将key-value格式解码为字典格式

6.png

给出email地址,按指定规则进行格式化,下图中的replace是为了删除原有的&,=

6.png

下图的函数是关键,通过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。函数返回的就是这三个块组成的密文。

7.png

该密文被解密,然后解码后,得到的role就会是就会是admin而不是user

8.png

完整代码及执行结果如下所示

9.png

第14关

0.png

这一关比第12关难度大。要求我们生成随机数量的随机字符,作为明文的前缀。

11.png

还是要求我们拿到target-bytes的明文

思路就是:

1.首先找到块长度、加密模式,这些在12题里实现过了

2.找到前缀长度

3.一次一个byte解密target-byte,这在12题也实现了

加密函数加密的内容就是随机前缀+可控字符串+未知字符串

12.png

找到target-byte的一个字节。填充length_to_use个a,保证将块的最后一个字符设置为target-byte的第一个字符。然后计算我们将截取多少个字节进行比较,这个值在后面比较假的密文和实际密文时会用到。计算实际密文,然后暴力测试每个可能的字符,将每个可能字符加密后得到的密文与实际密文比较

13.png

检查给出的密文是否包含两个连续的相同块

14.png

计算前缀的长度。首先找到前缀在哪个块结尾,然后找到前缀结尾的精确位置,就可以计算出前缀的长度

首先分别加密空消息和一个字符的消息,得到两个密文。比较这两个密文,第一个不同的块就是前缀结束的块。然后需要精确定位是在前缀是在哪个位置结束的。

加密“两个块长度+一个随机增量”长度大小的相同的字节,如果字节数足够了(在密文中找到了两个连续的相同块),我们就可以精确计算前缀在其最后一个块中结束的位置。其在最后一块中结束的位置为块长度-i

15.png

找到块长度,判断是否为ECB模式,计算出target-byte的长度,这就是循环的次数。在循环中调用get_next_byte来计算。target-byte长度等于加密空字符串后的长度减去前缀长度

16.png

完整代码及执行结果如下

17.png

拿到了target-bytes的明文

第15题

18.png

要求实现一个函数,可以检测一段明文是否为pkcs#7填充,如果是话则去掉填充,不是的话则报异常

这个函数在s2p9.py中已经实现过了,这里不再重复。

第16关

19.png

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翻转攻击技术可以通过修改密文来操纵解密后的明文。其原理就是如果对初始化向量中的任意比特进行反转,则明文分组中相应的比特也会反转,其原因是第一个明文分组会和初始化向量进行异或运算。

20.png

这样我们所要做的就是对初始化向量进行攻击。

在下面的cbc_bit_flip中我们攻击的就是;和=

代码实现:

实现加密函数,添加前缀和后缀后,使用AES-128-CBC进行加密

实现解密函数,还会检查解密后的内容中是否有;admin=true;

21.png

计算块长度。要找到一个块的长度,我们需要加密越来越长的明文,直到输出密文的大小也增加为止。发生这种情况时,我们可以轻松地计算出块的长度,其值等于新的密文长度与其初始长度之间的差

22.png

计算前缀的长度。

加密两个不同的明文字节,得到两个不同的密文,计算两个密文间相同的长度,赋给common_length,确保其为块长度的整数倍。

从1开始将越来越多的相同字节添加到明文中,分别加密,比较两个密文,直到它们有一个额外的相同块为止。如果找到了,这意味着通过添加i个字节,我们可以控制相同的输入(包括前缀)为块大小的整数倍,这样我们就可以得到前缀的长度了。

23.png

cbc翻转攻击的关键函数

首先得到块长度和前缀长度,接着计算需要添加多少字节到前缀,才能使得其长度为块长度整数倍,接着计算要添加多少字节到明文才能使得其长度为块长度整数倍。然后将明文加长1个块长度(用?填充),对其加密。使用异或的方法,我们可以通过更改明文之前的块的字节来生成所需的字节。最后将伪造的密文片段放在一起,组成完整的密文

24.png

完整代码及执行结果如下

25.png

可知,在解密之后的明文里确实找到了; admin = true;,返回了true

参考:

1.https://cryptopals.com/sets/1

2.https://github.com/ricpacca/cryptopals

上一篇:“第五空间”智能安全大赛部分WP
下一篇:天翼杯2020_wp_by_LQers
版权所有 合天智汇信息技术有限公司 2013-2021 湘ICP备2024089852号-1
Copyright © 2013-2020 Heetian Corporation, All rights reserved
4006-123-731