In [1]:
#foo=bar&baz=qux&zap=zazzle
def parse2dict(s):
d={}
s=s.split("&")
for item in s:
t=item.split("=")
d[t[0]]=t[1]
return d
uid=1
def profile_for(key,email):
global uid
email=email.strip("&=")
s="email="+str(email)+"&uid="+str(uid)+"&role=user"
news=pad(s,16)
out=encryptECBAES(key,news)
#uid+=1
return out
def create_profile(key,ct):
out=decryptECBAES(key,ct)
out=unpad(out)
d=parse2dict(out)
return d
from blockcrypto import *
globalkey=randomkey(16)
In [2]:
ct=profile_for(globalkey,"foo@bar.com")
Assume blocksize is 16-byes (128-bit) - discovering this is possible but a pain in the ass.
In [3]:
print newECBorCBCoracle(globalkey,16,profile_for)
In [64]:
### Need to modify padding oracle
## First of all find where we are - how much input to we have to give to keep +1 blocks (16 chars) the same (from no input)?
## Then insert this number + (16-n) bytes to do the padding attack - can only decrypt part after our input
import numpy as np
def wherearewe(blackbox, key):
#return offset to block
pastblocks=np.zeros(16)
blocksnoinput = splitblocks(blackbox(key,""), 16)
blocksonebyte=splitblocks(blackbox(key,"A"), 16)
#numsameorig=np.sum(np.array(blocksnoinput)==np.array(blocksonebyte))
numsameorig=len(set(blocksnoinput).intersection(set(blocksonebyte)))
for b in xrange(1,18):
blocks = splitblocks(blackbox(key,"A"*b), 16)
#numsame=np.sum(np.array(blocksnoinput)==np.array(blocks))
numsame=len(set(blocks).intersection(set(pastblocks)))
if numsame>numsameorig:
return ((b-1)%16, np.max(np.where(np.array(blocks[:len(pastblocks)])==np.array(pastblocks)) ))
pastblocks=blocks
return None
(offset,ourblock) =wherearewe(profile_for,globalkey) #expect 10
print offset
###So we want to start with 35As, then reduce
### TODO - We need to set the starting block correctly - want to extract from second block not first to begin with
def newcreatedict(blackbox, key,blocksize,curblock=0,byte=1,knownletters=[], offset=0):
d={}
z=(curblock*blocksize)
for a in xrange(0,128):
#print ("A"*((blocksize-byte)))+"".join(knownletters)+chr(a)
d[blackbox(key,("A"*((blocksize-byte)+offset))+"".join(knownletters)+chr(a))[z:z+blocksize]]=chr(a)
#print ("A"*((blocksize-byte)))+"".join(knownletters)+chr(a)
return d
# TODO CANNOT GET FIRST BYTE ?!?
def newpadoracle(blackbox,blocksize,totalbytes,key, offset=0, ourblock=0):
outs=[]
knownletters=[]
for b in xrange((ourblock+1),totalbytes/blocksize):
o=""
for byte in xrange(1,blocksize+1):
onebyteshort=blackbox(key, "A"*((blocksize-byte)+offset))
d=newcreatedict(blackbox,key,blocksize,curblock=b,byte=byte,knownletters=knownletters, offset=offset)
#print d
#print d
try: #TODO: Hack for last byte
knownletters.append(d[onebyteshort[b*blocksize:(b+1)*blocksize]])
o+=d[onebyteshort[b*blocksize:(b+1)*blocksize]]
except Exception as e:
#print e
pass
# print o, b
outs.append(o)
#print outs,b
return "".join(outs)
print len(profile_for(globalkey,""))
print newpadoracle(profile_for,16,len(profile_for(globalkey,"")), globalkey,offset, ourblock)
In [44]:
In [5]:
hiddenlength= len(profile_for(globalkey,""))
print hiddenlength
In [15]:
out=padoracle(profile_for,16,hiddenlength,globalkey)
print unpad(out)
In [ ]: