任务四:Crypto学习

任务四:Crypto学习

内容:

学习掌握长度扩展攻击,明白攻击原理,知道攻击的条件,实践长度扩展攻击,题目:Plaid CTF 2014 Crypto 250 Parlor,完成WP。



长度扩展攻击

定义

长度扩展攻击(Length Extension Attack),是指针对某些允许包含额外信息的加密散列函数的攻击手段。只要是满足下列两个条件的散列函数,都可以作为攻击对象:

  • 加密前将加密的明文按照一定规则填充到固定长度(例如512或1024bit)的倍数;
  • 按照该固定长度,将明文分块加密,闭关用前一个块的加密结果,作为下一块就的初始向量。
    对于H(salt+data)的加密模式,在满足下面三种情况下,攻击者可以通过方法获取H(salt+一定规则构造的data):
    ①知道密文的加密算法且该算法满足上面两条散列函数的特征。
    ②不知道salt,但知道salt的长度,并可控制data的值;
    ③可以得到一个H(salt+data)的值。

攻击原理

以MD5为例,简述长度扩展攻击如何进行攻击:
①按位补充数据:拿到明文后,MD5将明文转为二进制文件,然后将二进制文件的长度除以512bit(即64字节),那么直接在后面加上八个字节的长度标识符,使之成为512bit的倍数 。否则在明文后填一个1,再填0,知道长度除以512等于448,然后再照此法动作。长度是使用大端序(big Endian)来存储的,即低字节放在高地址位上。
大端序:大端序(big-endian)和小端序(little-endian)是字节存储顺序的两种主要顺序,主要区别是:

  • 大端序:高位字节存入低地址,低位字节存入高地址。
  • 小端序:低位字节存入低地址,高位字节存入高地址。
    一般来说,X86系列CPU都采用小端序,PowerPC系列都采用大端序。
    因为网络协议也都是采用大端序,所以有时也把大端序方式称为网络字节序。
    ②扩展长度:补位完毕后,又将一个表示数据原始长度的64的数补在最后。当完成补位及补充数据的描述后,得到的结果数据长度正好是512的整数倍。
    ③初始化MD缓存器:MD5运算要用到一个128位的MD5缓存器,用来保存中间变量和最终的结果。该缓存器又可以看成是4个32位的寄存器A、B、C、D的初始化:
    A:01 23 45 67
    B:89 ab cd ef
    C:fe dc ba 98
    D:76 54 32 10
    ④数据分块:函数就将填充后的明文以512bit的长度分块,以便进行运算。在运算过程中,会用到四个初始向量。经过复杂的数学运算,函数会得到第一块的MD5的值分成四块。
    ⑤处理数据:定义四个非线性函数F、G、H、I,对输入的报文运算以512位数据段位单位进行处理,对每个数据段都要进行四轮的逻辑处理,在四轮处理中,分别使用四个不同的函数FG、H、J、I。每一轮以A、B、C、D和当前的512位的块为输入,处理后送入ABCD。
    ⑥输出:信息最终处理成A、B、C、D的形式输出,也就是开始于A的低位在前,结束于D的高位在后的顺序字节。

攻击条件

对于满足以下两条条件的散列函数,都可以作为攻击对象:

  • 加密前将代价密的明文按一定规则填充到固定长度(例如512或1024位)的倍数。
  • 按照固定长度,将明文分块加密,并用前一块的加密结果,作为下一块加密的初始向量。
    满足这两个条件的函数称为Merkle-Damgard散列函数,举几个Merkle-Damgard散列函数的例子:MD4、MD5(常用)、RIPEMD-160、SHA-1、SHA-256、SHA-512。

题目复现:Plaid CTF 2014 Crypto 250 Parlor

原题网址:https://fail0verflow.com/blog/2014/plaidctf2014-crypto250-parlor/gaiti
该题的规则如下:
①:set your odds||设定odds的值
②:set your bet||设下你的注
③:play a round||打一个回合
④:get balance||达到平衡(即满足表达式:md5(our number + your number) % odds == 0)
⑤:receal nonce||显示nonce(获得一千或失去一千)
⑥:quit||关闭
然后再开始新的一轮,直到获得十亿。
在长度扩展攻击中:
A:01 23 45 67
B:89 ab cd ef
C:fe dc ba 98
D:76 54 32 10
在加密的过程中,明文会被分为512bit一块的长度分块。然后与四个初始向量做复杂的数学运算,每一轮使用不同的函数,得到的结果与当前的512bit的块一同输出,作为结果。
在加密时的明文会分为block[i]的模块,假设经历复杂的数学运算后,有aa bb cc dd,那么就有:aa,bb,cc,dd=f(a,b,c,d,block[i])
然后将a,b,c,d分别与aa,bb,cc,dd相加,这个过程视为一轮。
a+=aa
b+=bb
c+=cc
d+=dd
如果前面还有block[i]就继续运算,直到没有了block[i]为止。
a,b,c,d的最终值合并后就为MD5的值。现在我们已知MD5(nonce+num)的结果,将其结果还原为a b c d,并当作f中的a b c d的初值,做一次f(a,b,c,d,block[i])运算,结果等同MD5(nonce+num+padding+msg),所以即使不知道nonce+num的值,也能预测出结果。

先reveal nonce判断是否可行:
nonce = “760c4a0f8ec61bec304ed4d8d8abeb98”.decode(‘hex’)
num = ‘a\n’
md5(nonce + num) = ‘5b356daa0313063af25f8da01922128d’
a,b,c,d = md5tonum(md5(nonce + num))
#nonce = 16, a\n = 2, 所以填充\x80+\x00*37 + len 8, total = 64
padding = “\x80”+"\x00"*37 + “\x90”+"\x00"*7
print md5(‘a\n’+padding+‘b\n’)
block = [256511094 3961243278 3637792304 2565581784 8391265 0 0 0 0 0 0 0 0 0 144 0 8391266 0 0 0 0 0 0 0 0 0 0 0 0 0 528 0]
md5: 12b74d8200ff1c84500b1e55ada2ce7e
print guess(‘b\n’,a,b,c,d,66) # 新的长度是 66 byte
block = [8391266 0 0 0 0 0 0 0 0 0 0 0 0 0 16 0]
md5: 12b74d8200ff1c84500b1e55ada2ce7e

接下来要得到MD5的结果。先把赔率设为最大,即将odds设为100。第一次送‘a\n’得到r1,且r1=MD5%2**100。第二次送’a\n+padding+‘b\n’’,得到r2。用r1推断出a,b,c,d,并带入r2测试,如果其结果相同,那么就得到了完整的MD5的值了。通过MD5解密,就能得到flag了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值