您的位置:首页 > 数据库 > Oracle

CBC Padding Oracle 攻击

2017-08-14 20:03 309 查看

0x01 题目来源

https://github.com/pbiernat/BlackBox/tree/master/Padz

0x02 解题过程

1、首先还是需要了解CBC加解密模式的基本流程

CBC加密:



CBC解密:



整个做题的目标四计算出中间结果,这需要从最后一个字节开始向前逐个字节计算。整个的理论原理参考了下文中的链接,这里不再赘述。

2、查看源码



输出唯一的密文,发现当输入有效的时候只会返回“VALID PADDING”而不会返回明文,这就涉及到CBC中的Padding Oracle攻击。

依次改变最后一个字节,初始化IV为全零,然后利用填充从“0x01~0x10”进行异或,然后得到每一个中间值的字节值,共进行十六次,每次注意IV随着填充的改变。

得到了中间值的时候,可以看一下加密的过程,将中间值与前一个的密文进行异或,得到的就是这一个分组的明文,由于我们已知flag在中间的一个分组,因此,下面的代码就知识对中间的一个密文分组进行了解密,如果不知道,需要对其他的分组做同样的操作。

其实掌握了Padding Oracle的原理,编写代码也还是可以完成的,需要注意字节前面是零或者字节就是零的时候的,计算机识别的问题。

0x03 编写代码

在写代码的时候经过了很多次的调试,首先用的是笨办法,需要修改16次代码,后来完善了此版本,很多注释是调试的时候用的。

import socket

def str2num(s):
return int(s.encode('hex'),16)
def num2str(n):
d = ('%x' % n)
if len(d) % 2 == 1:
d = '0' + d
return d

def func(j,z):
x = "00"
for i in range(255):
y = "parse:"+"00"*j + x + z+"ef2c6db9d0bc134f752a119899160b72"
client.send(y)
data = client.recv(1024)
if data == "VALID PADDING":
# print i, hex(i)
return i
x = int(x, 16) + 1
x = num2str(x)

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 9004))

client.send("get:AAAAAAA")
data = client.recv(1024)
print data

client.send("parse:f9b6e7556dd0fa9038ac346e849cc5c1ef2c6db9d0bc134f752a119899160b7217a36290f3ed054ca48f1b052578b644")
data = client.recv(1024)
print data

sum = 16
j = 15
k = 1
tmp = "01" # from 1 to \x10
string_s = ""
string_mid = ""
z = ""
while(sum):
confir = num2str(func(j,z))
# print confir
string_s = str(confir)
#print "string_s:"+string_s
#print "string_mid:"+string_mid
#print tmp*k
string_mid = str(hex(int(string_s,16)^int(tmp,16)))+string_mid

print "string_mid:" + string_mid
tmp = int(tmp, 16) + 1
tmp = num2str(tmp)
string_mid = string_mid[2:].replace('L','')
if len(string_mid)%2 !=0:
string_mid = "0"+string_mid
#print string_mid
#print tmp
temp = len(z)+3

z = str(hex(int(string_mid,16)^int(tmp*k,16)))
z = z[2:].replace('L','')
if temp == len(str(hex(int(string_mid,16)^int(tmp*k,16)))):
z = "00" + z
if len(z)%2 !=0:
z = "0"+z

4000
#print "z:"+z
j = j-1
k = k+1
sum = sum-1
#func(j,z)

client.close()


0x06 得到flag

运行脚本以后得到中间值,这里显示了16轮的中间值:



将上图的最后一轮的中间值与密文的前16个字节进行以后,得到的就是我们要的flag。

0x05 参考资料

http://www.freebuf.com/articles/web/15504.html

http://blog.zhaojie.me/2010/10/padding-oracle-attack-in-detail.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: