Skip to content

Instantly share code, notes, and snippets.

@k3170makan
Created July 15, 2015 14:34
Show Gist options
  • Select an option

  • Save k3170makan/b1528efd412813408eb1 to your computer and use it in GitHub Desktop.

Select an option

Save k3170makan/b1528efd412813408eb1 to your computer and use it in GitHub Desktop.
A script I used to learn padding oracle attacks
#!/usr/bin/python
from base64 import b64encode,b64decode
import readline
import struct
from Crypto.Cipher import AES
from sys import argv,exit
from os import urandom
from random import random
BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr((BS - len(s) % BS))
def encrypt(iv,key,plain):
return AES.new(key,AES.MODE_CBC,iv).encrypt(plain)
def decrypt(iv,key,cipher):
plaintext = AES.new(key,AES.MODE_CBC,iv).decrypt(cipher)
try:
string = "%s" % (ord(plaintext[len(plaintext)-1]))
#print "padding length : '%s'" % (string) <--- uncomment this if you're havin a hard time with the attack :)
#print "intermediated value : '%s'" % (pretty_print(plaintext))
except ValueError,e:
print "decrypt:",e
raise e
padding_length = int(string)
incorrect = False
for c in plaintext[len(plaintext)-padding_length:]:
try:
c = int("%s" % (ord(c)))
except:
print "c convert:",e
raise e
if c != padding_length:
incorrect = True
if incorrect == True:
return False
return plaintext[:len(plaintext)-padding_length]
def gen_rand_plaintext(length):
return b64encode("".join([chr(int(random()*1000)%255) for c in range(length)]))
def pretty_print(text):
string = " ".join([ "%02x" % (ord(c)) for c in text])
return string
def unpretty_print(text):
return ''.join([chr(int(c,16)) for c in text.split(" ")])
def rlinput(prompt,prefill=''):
readline.set_startup_hook(lambda: readline.insert_text(prefill))
try:
return raw_input(prompt)
finally:
readline.set_startup_hook()
def block_wise_print(text):
string = " "
newlines = 0
char_count = 0
chars = text.split(" ")
for char in chars:
string += char+" "
char_count+=1
if char_count % 16 == 0:
string += "\n"
return string[1:]
if __name__ == "__main__":
while True:
plaintext = pad("P"*33)
key = "A"*32
iv = "B"*16
cipher = encrypt(iv,key,plaintext)
plaintext = decrypt(iv,key,cipher)
print "plaintext [%s]:" % (len(plaintext))
print block_wise_print(pretty_print(plaintext))
print "cipher [%s]:" % (len(cipher))
print block_wise_print(pretty_print(cipher))
print "decrypted [%s]:" % (len(plaintext))
print block_wise_print(pretty_print(plaintext))
while True:
line = rlinput('>',pretty_print(cipher))
cipher = unpretty_print(line)
line = line.split(" ")
user_cipher = ''.join([chr(int(c,16)) for c in line])
plain = decrypt(iv,key,user_cipher)
if plain != False:
print "decrypted [%s]:" % (len(plain))
print block_wise_print(pretty_print(plain))
print "[x]",plain
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment