Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python2
- import urllib2
- import sys
- import subprocess
- import os
- TARGET = 'http://crypto-class.appspot.com/po?er='
- #--------------------------------------------------------------
- # padding oracle
- #--------------------------------------------------------------
- class PaddingOracle(object):
- def query(self, q):
- target = TARGET + urllib2.quote(q) # Create query URL
- req = urllib2.Request(target) # Send HTTP request to server
- try:
- f = urllib2.urlopen(req) # Wait for response
- sys.exit(0)
- except urllib2.HTTPError, e:
- if e.code == 404:
- sys.exit(1)
- else:
- sys.exit(-1)
- def from_text_pair(code):
- assert(len(code)==2)
- return int('0x' + code, 16)
- def from_text(text):
- assert(len(text) % 2 == 0)
- result=[]
- for i in range(0,int(len(text)/2)):
- l=text[i*2]
- h=text[i*2+1]
- r=from_text_pair(l+h)
- result.append(r)
- return result
- def to_hex_byte(b):
- h = hex(b)
- if not (len(h) == 3 or len(h) == 4):
- print "to_hex_byte(%s) problem" % b
- sys.exit(0)
- def byte(b, i):
- return int('0x' + hex(b)[i], 16)
- if len(h) == 3:
- return '0' + h[-1]
- else:
- return h[-2] + h[-1]
- def to_hex(t):
- return ''.join(map(to_hex_byte, t))
- def to_text(data):
- return ''.join(list(map(chr,data)))
- def norm(data):
- return to_text(from_text(data))
- def guess(result, IV, C, last=False):
- l=len(result)
- pl=[]
- for g in xrange(0,256):
- iv=from_text(IV)
- for i in xrange(0,l):
- k=i+1
- iv[-k] = iv[-k] ^ result[i] ^ (l+1)
- m=l+1
- iv[-m] = iv[-m] ^ g ^ (l+1)
- pl.append(subprocess.Popen(["./padding_oracle.py", (to_hex(iv)+C), "oracle"], cwd=os.getcwd()))
- map(lambda p: p.wait(), pl)
- rl=map(lambda p: p.returncode, pl)
- for_return=[]
- for (g,r) in enumerate(rl):
- if r == 0:
- print "ACCEPTED=%s" % g
- elif r == 1:
- if (not last) or g != (l+1) or (len(result) and result[0] == (l+1)):
- print "PASSED=%s" % g
- for_return.append(g)
- assert(len(for_return)==1)
- return for_return[0]
- if __name__ == "__main__":
- result=""
- if len(sys.argv) == 1:
- print >>sys.stderr, "Specify cipher text as argument"
- sys.exit(-1)
- elif len(sys.argv) == 2:
- ORIG=sys.argv[1]
- if len(ORIG) % 32 != 0:
- print >>sys.stderr, "Invalid cipher text length"
- sys.exit(-1)
- elif len(sys.argv) == 3 and sys.argv[-1] == "oracle":
- po = PaddingOracle()
- po.query(sys.argv[1])
- else:
- print >>sys.stderr, "Specify cipher text as argument"
- sys.exit(-1)
- block_count=len(ORIG)/32
- if block_count < 2:
- print >>sys.stderr, "You have just IV, no cypher text given"
- sys.exit(-1)
- block_count-=1
- for i in xrange(0,block_count):
- print "Decode block %s/%s" % (i+1, block_count)
- a=i*32
- b=a+32
- c=b+32
- IV=ORIG[a:b]
- C=ORIG[b:c]
- block=[]
- while len(block) < 16:
- block.append(guess(block,IV,C,last=(i+1==block_count)))
- if i == 2:
- pad = block[0]
- block=block[pad:]
- text=to_text(reversed(block))
- print "Block %s/%s is '%s'" % (i,block_count,text)
- result+= "".join(text)
- print "Result is '%s'" % result
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement