Advertisement
zamotivator

Untitled

May 2nd, 2013
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env python2
  2.  
  3. import urllib2
  4. import sys
  5. import subprocess
  6. import os
  7. TARGET = 'http://crypto-class.appspot.com/po?er='
  8. #--------------------------------------------------------------
  9. # padding oracle
  10. #--------------------------------------------------------------
  11. class PaddingOracle(object):
  12.     def query(self, q):
  13.         target = TARGET + urllib2.quote(q)    # Create query URL
  14.         req = urllib2.Request(target)         # Send HTTP request to server
  15.         try:
  16.             f = urllib2.urlopen(req)          # Wait for response
  17.             sys.exit(0)
  18.         except urllib2.HTTPError, e:
  19.             if e.code == 404:
  20.                 sys.exit(1)
  21.             else:
  22.                 sys.exit(-1)
  23.  
  24. def from_text_pair(code):
  25.     assert(len(code)==2)
  26.     return int('0x' + code, 16)
  27.  
  28. def from_text(text):
  29.     assert(len(text) % 2 == 0)
  30.     result=[]
  31.     for i in range(0,int(len(text)/2)):
  32.         l=text[i*2]
  33.         h=text[i*2+1]
  34.         r=from_text_pair(l+h)
  35.         result.append(r)
  36.     return result
  37.  
  38. def to_hex_byte(b):
  39.     h = hex(b)
  40.     if not (len(h) == 3 or len(h) == 4):
  41.         print "to_hex_byte(%s) problem" % b
  42.         sys.exit(0)
  43.     def byte(b, i):
  44.         return int('0x' + hex(b)[i], 16)
  45.     if len(h) == 3:
  46.         return '0' + h[-1]
  47.     else:
  48.         return h[-2] + h[-1]
  49.  
  50. def to_hex(t):
  51.     return ''.join(map(to_hex_byte, t))
  52.  
  53. def to_text(data):
  54.     return ''.join(list(map(chr,data)))
  55.  
  56. def norm(data):
  57.     return to_text(from_text(data))
  58.  
  59. def guess(result, IV, C, last=False):
  60.     l=len(result)
  61.     pl=[]
  62.     for g in xrange(0,256):
  63.         iv=from_text(IV)
  64.         for i in xrange(0,l):
  65.             k=i+1
  66.             iv[-k] = iv[-k] ^ result[i] ^ (l+1)
  67.         m=l+1
  68.         iv[-m] = iv[-m] ^ g ^ (l+1)
  69.         pl.append(subprocess.Popen(["./padding_oracle.py", (to_hex(iv)+C), "oracle"], cwd=os.getcwd()))
  70.     map(lambda p: p.wait(), pl)
  71.     rl=map(lambda p: p.returncode, pl)
  72.     for_return=[]
  73.     for (g,r) in enumerate(rl):
  74.         if r == 0:
  75.             print "ACCEPTED=%s" % g
  76.         elif r == 1:
  77.             if (not last) or g != (l+1) or (len(result) and result[0] == (l+1)):
  78.                 print "PASSED=%s" % g
  79.                 for_return.append(g)
  80.     assert(len(for_return)==1)
  81.     return for_return[0]
  82.            
  83. if __name__ == "__main__":
  84.     result=""
  85.     if len(sys.argv) == 1:
  86.         print >>sys.stderr, "Specify cipher text as argument"
  87.         sys.exit(-1)
  88.     elif len(sys.argv) == 2:
  89.         ORIG=sys.argv[1]
  90.         if len(ORIG) % 32 != 0:
  91.             print >>sys.stderr, "Invalid cipher text length"
  92.             sys.exit(-1)
  93.     elif len(sys.argv) == 3 and sys.argv[-1] == "oracle":
  94.         po = PaddingOracle()
  95.         po.query(sys.argv[1])
  96.     else:
  97.         print >>sys.stderr, "Specify cipher text as argument"
  98.         sys.exit(-1)
  99.     block_count=len(ORIG)/32
  100.     if block_count < 2:
  101.         print >>sys.stderr, "You have just IV, no cypher text given"
  102.         sys.exit(-1)
  103.     block_count-=1
  104.     for i in xrange(0,block_count):
  105.         print "Decode block %s/%s" % (i+1, block_count)
  106.         a=i*32
  107.         b=a+32
  108.         c=b+32
  109.         IV=ORIG[a:b]
  110.         C=ORIG[b:c]
  111.         block=[]
  112.         while len(block) < 16:
  113.             block.append(guess(block,IV,C,last=(i+1==block_count)))
  114.         if i == 2:
  115.             pad = block[0]
  116.             block=block[pad:]
  117.         text=to_text(reversed(block))
  118.         print "Block %s/%s is '%s'" % (i,block_count,text)
  119.         result+= "".join(text)
  120.     print "Result is '%s'" % result
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement