cbcExploit
Padding Oracle and bit flipping attacks
Requirements: pwnlib (https://github.com/Gallopsled/pwntools/tree/master/pwnlib)
You have to implement oracle, then you will be able to decrypt or fake any ciphertext (hopefully...)
Functions defititions:
def oracle(self, payload, iv, previous_resp, **kwargs):
"""
payload - hex encoded ciphertext to check
iv - hex encoded inicialization vector (most often: append it at beggining of payload)
previous_resp - value returned by previous call to oracle
Return tuple: (True/False, response)
True if padding is correct (be carefull with sending original ciphertext), Flase otherwise
"""
pass
def decrypt(self, ciphertext, iv=None, amount=0, is_correct=False, known_plaintext=None, async=0, **kwargs):
"""
ciphertext - hex encoded
iv - usually it's first block of ciphertext, but may be specified separate
amount - how much blocks decrypt (counting from last), default is all
is_correct - if True, then first decrypted byte will be treated as correct padding (speed up decryption)
known_plaintext - hex encoded, with padding, from end
async - make asynchronous calls to oracle (not implemented yet)
kwargs - push forward to oracle function
Return hex encoded plaintext
"""
pass
def fake_ciphertext(self, new_plaintext, orginal_ciphertext, iv=None, orginal_plaintext=None, is_correct=False, **kwargs):
"""
new_plaintext - hex encoded, with padding, length==len(orginal_ciphertext+iv-key_size),You want returned ciphertext deciphered to this
orginal_ciphertext - hex encoded, must be same length as new_plaintext
iv - usually it's first block of ciphertext, but may be specified separate
orginal_plaintext - hex encoded, can be only len(key_size) or None
is_correct - if True, then first decrypted byte will be treated as correct padding (speed up decryption)
kwargs - push forward to oracle function
Return hex encoded fake ciphertext that will decrypt to new_plaintext
"""
pass
def add_padding(self, data):
passExample usage(example.py):
from pwn import *
from cbcExploit import PaddingOracle
var='5745d4bbed207b6f09bcbaac0782ffeebdf92d8a.3ced346abc4e2a298ef26337cb6e697b6b1d8900051e49a323c5ddf7ee361c6fa2d0e7ae3414805d134890e8b3bed32f2edec8e3ace12d529d7f1d9d12d0eb7b'.split('.')
mac=var[0]
var=var[1]
class Padding(PaddingOracle):
def oracle(self, payload, iv, previous_resp, **kwargs):
payload=kwargs['prefix']+'.'+iv+payload
ret=subprocess.check_output(['./test_cbc.py', payload])
if 'Nope' in ret:
return True, None
return False, None
key_size=16
po=Padding(key_size)
decrypted=po.decrypt(ciphertext=var, is_correct=True, prefix=mac)
want_it='username=ahg8v94\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12&username=admin'
want_it=po.add_padding(want_it).encode('hex')
orig=po.add_padding(decrypted).encode('hex')
print po.fake_ciphertext(new_plaintext=want_it, orginal_ciphertext=var, orginal_plaintext=orig, is_correct=True, prefix=mac)