mirror of
https://github.com/byt3bl33d3r/MITMf.git
synced 2025-08-19 04:59:33 -07:00
commit
b74fc33252
13 changed files with 98 additions and 712 deletions
58
.gitignore
vendored
58
.gitignore
vendored
|
@ -1,3 +1,59 @@
|
||||||
*.pyc
|
|
||||||
/plugins/old_plugins/
|
/plugins/old_plugins/
|
||||||
backdoored/
|
backdoored/
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
env/
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*,cover
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
target/
|
||||||
|
|
14
README.md
14
README.md
|
@ -12,6 +12,8 @@ Contact me at:
|
||||||
- IRC on Freenode: #MITMf
|
- IRC on Freenode: #MITMf
|
||||||
- Email: byt3bl33d3r@gmail.com
|
- 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 the appropriate [section](#submitting-issues).**
|
||||||
|
|
||||||
Available plugins
|
Available plugins
|
||||||
|
@ -81,12 +83,14 @@ How to install on Kali
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
============
|
============
|
||||||
If MITMf is not in your distro's repo or you just want the latest version:
|
If you're rocking Kali and want the latest version:
|
||||||
- Run the command ```git clone https://github.com/byt3bl33d3r/MITMf.git``` to clone this directory
|
- Clone this repository
|
||||||
- Run the ```setup.sh``` script
|
- Run the ```kali_setup.sh``` script
|
||||||
- Run the command ```pip install --upgrade -r requirements.txt``` to install all Python dependencies
|
|
||||||
|
|
||||||
On Kali Linux, if you get an error while installing the ```pypcap``` package or when starting MITMf you see: ```ImportError: no module named pcap```, run ```apt-get install python-pypcap``` to fix it
|
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
|
Submitting Issues
|
||||||
=================
|
=================
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#! /usr/bin/env python2.7
|
#! /usr/bin/env python2.7
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from watchdog.observers import Observer
|
from mitmflib.watchdog.observers import Observer
|
||||||
from watchdog.events import FileSystemEventHandler
|
from mitmflib.watchdog.events import FileSystemEventHandler
|
||||||
from configobj import ConfigObj
|
from configobj import ConfigObj
|
||||||
|
|
||||||
logging.getLogger("watchdog").setLevel(logging.ERROR) #Disables watchdog's debug messages
|
logging.getLogger("watchdog").setLevel(logging.ERROR) #Disables watchdog's debug messages
|
||||||
|
|
|
@ -1,673 +0,0 @@
|
||||||
#
|
|
||||||
#httpagentparser library, stolen from https://github.com/shon/httpagentparser
|
|
||||||
#
|
|
||||||
|
|
||||||
"""
|
|
||||||
Extract client information from http user agent
|
|
||||||
The module does not try to detect all capabilities of browser in current form (it can easily be extended though).
|
|
||||||
Tries to
|
|
||||||
* be fast
|
|
||||||
* very easy to extend
|
|
||||||
* reliable enough for practical purposes
|
|
||||||
* assist python web apps to detect clients.
|
|
||||||
"""
|
|
||||||
|
|
||||||
__version__ = '1.7.7'
|
|
||||||
|
|
||||||
|
|
||||||
class DetectorsHub(dict):
|
|
||||||
_known_types = ['os', 'dist', 'flavor', 'browser']
|
|
||||||
|
|
||||||
def __init__(self, *args, **kw):
|
|
||||||
dict.__init__(self, *args, **kw)
|
|
||||||
for typ in self._known_types:
|
|
||||||
self.setdefault(typ, [])
|
|
||||||
self.registerDetectors()
|
|
||||||
|
|
||||||
def register(self, detector):
|
|
||||||
if detector.info_type not in self._known_types:
|
|
||||||
self[detector.info_type] = [detector]
|
|
||||||
self._known_types.insert(detector.order, detector.info_type)
|
|
||||||
else:
|
|
||||||
self[detector.info_type].append(detector)
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
return iter(self._known_types)
|
|
||||||
|
|
||||||
def registerDetectors(self):
|
|
||||||
detectors = [v() for v in globals().values() if DetectorBase in getattr(v, '__mro__', [])]
|
|
||||||
for d in detectors:
|
|
||||||
if d.can_register:
|
|
||||||
self.register(d)
|
|
||||||
|
|
||||||
|
|
||||||
class DetectorBase(object):
|
|
||||||
name = "" # "to perform match in DetectorsHub object"
|
|
||||||
info_type = "override me"
|
|
||||||
result_key = "override me"
|
|
||||||
order = 10 # 0 is highest
|
|
||||||
look_for = "string to look for"
|
|
||||||
skip_if_found = [] # strings if present stop processin
|
|
||||||
can_register = False
|
|
||||||
version_markers = [("/", " ")]
|
|
||||||
allow_space_in_version = False
|
|
||||||
_suggested_detectors = None
|
|
||||||
platform = None
|
|
||||||
bot = False
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
if not self.name:
|
|
||||||
self.name = self.__class__.__name__
|
|
||||||
self.can_register = (self.__class__.__dict__.get('can_register', True))
|
|
||||||
|
|
||||||
def detect(self, agent, result):
|
|
||||||
# -> True/None
|
|
||||||
word = self.checkWords(agent)
|
|
||||||
if word:
|
|
||||||
result[self.info_type] = dict(name=self.name)
|
|
||||||
result['bot'] = self.bot
|
|
||||||
version = self.getVersion(agent, word)
|
|
||||||
if version:
|
|
||||||
result[self.info_type]['version'] = version
|
|
||||||
if self.platform:
|
|
||||||
result['platform'] = {'name': self.platform, 'version': version}
|
|
||||||
return True
|
|
||||||
|
|
||||||
def checkWords(self, agent):
|
|
||||||
# -> True/None
|
|
||||||
for w in self.skip_if_found:
|
|
||||||
if w in agent:
|
|
||||||
return False
|
|
||||||
if isinstance(self.look_for, (tuple, list)):
|
|
||||||
for word in self.look_for:
|
|
||||||
if word in agent:
|
|
||||||
return word
|
|
||||||
elif self.look_for in agent:
|
|
||||||
return self.look_for
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
"""
|
|
||||||
=> version string /None
|
|
||||||
"""
|
|
||||||
version_markers = self.version_markers if \
|
|
||||||
isinstance(self.version_markers[0], (list, tuple)) else [self.version_markers]
|
|
||||||
version_part = agent.split(word, 1)[-1]
|
|
||||||
for start, end in version_markers:
|
|
||||||
if version_part.startswith(start) and end in version_part:
|
|
||||||
version = version_part[1:]
|
|
||||||
if end: # end could be empty string
|
|
||||||
version = version.split(end)[0]
|
|
||||||
if not self.allow_space_in_version:
|
|
||||||
version = version.split()[0]
|
|
||||||
return version
|
|
||||||
|
|
||||||
|
|
||||||
class OS(DetectorBase):
|
|
||||||
info_type = "os"
|
|
||||||
can_register = False
|
|
||||||
version_markers = [";", " "]
|
|
||||||
allow_space_in_version = True
|
|
||||||
platform = None
|
|
||||||
|
|
||||||
|
|
||||||
class Dist(DetectorBase):
|
|
||||||
info_type = "dist"
|
|
||||||
can_register = False
|
|
||||||
platform = None
|
|
||||||
|
|
||||||
|
|
||||||
class Flavor(DetectorBase):
|
|
||||||
info_type = "flavor"
|
|
||||||
can_register = False
|
|
||||||
platform = None
|
|
||||||
|
|
||||||
|
|
||||||
class Browser(DetectorBase):
|
|
||||||
info_type = "browser"
|
|
||||||
can_register = False
|
|
||||||
|
|
||||||
|
|
||||||
class Firefox(Browser):
|
|
||||||
look_for = "Firefox"
|
|
||||||
version_markers = [('/', '')]
|
|
||||||
skip_if_found = ["SeaMonkey", "web/snippet"]
|
|
||||||
|
|
||||||
|
|
||||||
class SeaMonkey(Browser):
|
|
||||||
look_for = "SeaMonkey"
|
|
||||||
version_markers = [('/', '')]
|
|
||||||
|
|
||||||
|
|
||||||
class Konqueror(Browser):
|
|
||||||
look_for = "Konqueror"
|
|
||||||
version_markers = ["/", ";"]
|
|
||||||
|
|
||||||
|
|
||||||
class OperaMobile(Browser):
|
|
||||||
look_for = "Opera Mobi"
|
|
||||||
name = "Opera Mobile"
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
try:
|
|
||||||
look_for = "Version"
|
|
||||||
return agent.split(look_for)[1][1:].split(' ')[0]
|
|
||||||
except IndexError:
|
|
||||||
look_for = "Opera"
|
|
||||||
return agent.split(look_for)[1][1:].split(' ')[0]
|
|
||||||
|
|
||||||
|
|
||||||
class Opera(Browser):
|
|
||||||
look_for = "Opera"
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
try:
|
|
||||||
look_for = "Version"
|
|
||||||
return agent.split(look_for)[1][1:].split(' ')[0]
|
|
||||||
except IndexError:
|
|
||||||
look_for = "Opera"
|
|
||||||
version = agent.split(look_for)[1][1:].split(' ')[0]
|
|
||||||
return version.split('(')[0]
|
|
||||||
|
|
||||||
|
|
||||||
class OperaNew(Browser):
|
|
||||||
"""
|
|
||||||
Opera after version 15
|
|
||||||
"""
|
|
||||||
name = "Opera"
|
|
||||||
look_for = "OPR"
|
|
||||||
version_markers = [('/', '')]
|
|
||||||
|
|
||||||
|
|
||||||
class Netscape(Browser):
|
|
||||||
look_for = "Netscape"
|
|
||||||
version_markers = [("/", '')]
|
|
||||||
|
|
||||||
|
|
||||||
class Trident(Browser):
|
|
||||||
look_for = "Trident"
|
|
||||||
skip_if_found = ["MSIE", "Opera"]
|
|
||||||
name = "IE"
|
|
||||||
version_markers = ["/", ";"]
|
|
||||||
trident_to_ie_versions = {
|
|
||||||
'4.0': '8.0',
|
|
||||||
'5.0': '9.0',
|
|
||||||
'6.0': '10.0',
|
|
||||||
'7.0': '11.0',
|
|
||||||
}
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
return self.trident_to_ie_versions.get(super(Trident, self).getVersion(agent, word))
|
|
||||||
|
|
||||||
|
|
||||||
class MSIE(Browser):
|
|
||||||
look_for = "MSIE"
|
|
||||||
skip_if_found = ["Opera"]
|
|
||||||
name = "IE"
|
|
||||||
version_markers = [" ", ";"]
|
|
||||||
|
|
||||||
|
|
||||||
class Galeon(Browser):
|
|
||||||
look_for = "Galeon"
|
|
||||||
|
|
||||||
|
|
||||||
class WOSBrowser(Browser):
|
|
||||||
look_for = "wOSBrowser"
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Safari(Browser):
|
|
||||||
look_for = "Safari"
|
|
||||||
|
|
||||||
def checkWords(self, agent):
|
|
||||||
unless_list = ["Chrome", "OmniWeb", "wOSBrowser", "Android"]
|
|
||||||
if self.look_for in agent:
|
|
||||||
for word in unless_list:
|
|
||||||
if word in agent:
|
|
||||||
return False
|
|
||||||
return self.look_for
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
if "Version/" in agent:
|
|
||||||
return agent.split('Version/')[-1].split(' ')[0].strip()
|
|
||||||
if "Safari/" in agent:
|
|
||||||
return agent.split('Safari/')[-1].split(' ')[0].strip()
|
|
||||||
else:
|
|
||||||
return agent.split('Safari ')[-1].split(' ')[0].strip() # Mobile Safari
|
|
||||||
|
|
||||||
class GoogleBot(Browser):
|
|
||||||
# https://support.google.com/webmasters/answer/1061943
|
|
||||||
look_for = ["Googlebot", "Googlebot-News", "Googlebot-Image",
|
|
||||||
"Googlebot-Video", "Googlebot-Mobile", "Mediapartners-Google",
|
|
||||||
"Mediapartners", "AdsBot-Google", "web/snippet"]
|
|
||||||
bot = True
|
|
||||||
version_markers = [('/', ';'), ('/', ' ')]
|
|
||||||
|
|
||||||
class GoogleFeedFetcher(Browser):
|
|
||||||
look_for = "Feedfetcher-Google"
|
|
||||||
bot = True
|
|
||||||
|
|
||||||
def get_version(self, agent):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class RunscopeRadar(Browser):
|
|
||||||
look_for = "runscope-radar"
|
|
||||||
bot = True
|
|
||||||
|
|
||||||
class GoogleAppEngine(Browser):
|
|
||||||
look_for = "AppEngine-Google"
|
|
||||||
bot = True
|
|
||||||
|
|
||||||
def get_version(self, agent):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class GoogleApps(Browser):
|
|
||||||
look_for = "GoogleApps script"
|
|
||||||
bot = True
|
|
||||||
|
|
||||||
def get_version(self, agent):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class TwitterBot(Browser):
|
|
||||||
look_for = "Twitterbot"
|
|
||||||
bot = True
|
|
||||||
|
|
||||||
class MJ12Bot(Browser):
|
|
||||||
look_for = "MJ12bot"
|
|
||||||
bot = True
|
|
||||||
|
|
||||||
class YandexBot(Browser):
|
|
||||||
# http://help.yandex.com/search/robots/agent.xml
|
|
||||||
look_for = "Yandex"
|
|
||||||
bot = True
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
return agent[agent.index('Yandex'):].split('/')[-1].split(')')[0].strip()
|
|
||||||
|
|
||||||
class BingBot(Browser):
|
|
||||||
look_for = "bingbot"
|
|
||||||
version_markers = ["/", ";"]
|
|
||||||
bot = True
|
|
||||||
|
|
||||||
|
|
||||||
class BaiduBot(Browser):
|
|
||||||
# http://help.baidu.com/question?prod_en=master&class=1&id=1000973
|
|
||||||
look_for = ["Baiduspider", "Baiduspider-image", "Baiduspider-video",
|
|
||||||
"Baiduspider-news", "Baiduspider-favo", "Baiduspider-cpro",
|
|
||||||
"Baiduspider-ads"]
|
|
||||||
bot = True
|
|
||||||
version_markers = ('/', ';')
|
|
||||||
|
|
||||||
|
|
||||||
class LinkedInBot(Browser):
|
|
||||||
look_for = "LinkedInBot"
|
|
||||||
bot = True
|
|
||||||
|
|
||||||
class ArchiveDotOrgBot(Browser):
|
|
||||||
look_for = "archive.org_bot"
|
|
||||||
bot = True
|
|
||||||
|
|
||||||
class YoudaoBot(Browser):
|
|
||||||
look_for = "YoudaoBot"
|
|
||||||
bot = True
|
|
||||||
|
|
||||||
class YoudaoBotImage(Browser):
|
|
||||||
look_for = "YodaoBot-Image"
|
|
||||||
bot = True
|
|
||||||
|
|
||||||
class RogerBot(Browser):
|
|
||||||
look_for = "rogerbot"
|
|
||||||
bot = True
|
|
||||||
|
|
||||||
class TweetmemeBot(Browser):
|
|
||||||
look_for = "TweetmemeBot"
|
|
||||||
bot = True
|
|
||||||
|
|
||||||
class WebshotBot(Browser):
|
|
||||||
look_for = "WebshotBot"
|
|
||||||
bot = True
|
|
||||||
|
|
||||||
class SensikaBot(Browser):
|
|
||||||
look_for = "SensikaBot"
|
|
||||||
bot = True
|
|
||||||
|
|
||||||
class YesupBot(Browser):
|
|
||||||
look_for = "YesupBot"
|
|
||||||
bot = True
|
|
||||||
|
|
||||||
class DotBot(Browser):
|
|
||||||
look_for = "DotBot"
|
|
||||||
bot = True
|
|
||||||
|
|
||||||
class PhantomJS(Browser):
|
|
||||||
look_for = "Browser/Phantom"
|
|
||||||
bot = True
|
|
||||||
|
|
||||||
class FacebookExternalHit(Browser):
|
|
||||||
look_for = 'facebookexternalhit'
|
|
||||||
bot = True
|
|
||||||
|
|
||||||
|
|
||||||
class NokiaOvi(Browser):
|
|
||||||
look_for = "S40OviBrowser"
|
|
||||||
|
|
||||||
class UCBrowser(Browser):
|
|
||||||
look_for = "UCBrowser"
|
|
||||||
|
|
||||||
class BrowserNG(Browser):
|
|
||||||
look_for = "BrowserNG"
|
|
||||||
|
|
||||||
class Dolfin(Browser):
|
|
||||||
look_for = 'Dolfin'
|
|
||||||
|
|
||||||
class NetFront(Browser):
|
|
||||||
look_for = 'NetFront'
|
|
||||||
|
|
||||||
class Jasmine(Browser):
|
|
||||||
look_for = 'Jasmine'
|
|
||||||
|
|
||||||
class Openwave(Browser):
|
|
||||||
look_for = 'Openwave'
|
|
||||||
|
|
||||||
class UPBrowser(Browser):
|
|
||||||
look_for = 'UP.Browser'
|
|
||||||
|
|
||||||
class OneBrowser(Browser):
|
|
||||||
look_for = 'OneBrowser'
|
|
||||||
|
|
||||||
class ObigoInternetBrowser(Browser):
|
|
||||||
look_for = 'ObigoInternetBrowser'
|
|
||||||
|
|
||||||
class TelecaBrowser(Browser):
|
|
||||||
look_for = 'TelecaBrowser'
|
|
||||||
|
|
||||||
class MAUI(Browser):
|
|
||||||
look_for = 'Browser/MAUI'
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
version = agent.split("Release/")[-1][:10]
|
|
||||||
return version
|
|
||||||
|
|
||||||
|
|
||||||
class NintendoBrowser(Browser):
|
|
||||||
look_for = 'NintendoBrowser'
|
|
||||||
|
|
||||||
|
|
||||||
class AndroidBrowser(Browser):
|
|
||||||
look_for = "Android"
|
|
||||||
skip_if_found = ['Chrome', 'Windows Phone']
|
|
||||||
|
|
||||||
# http://decadecity.net/blog/2013/11/21/android-browser-versions
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Linux(OS):
|
|
||||||
look_for = 'Linux'
|
|
||||||
platform = 'Linux'
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Blackberry(OS):
|
|
||||||
look_for = 'BlackBerry'
|
|
||||||
platform = 'BlackBerry'
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class BlackberryPlaybook(Dist):
|
|
||||||
look_for = 'PlayBook'
|
|
||||||
platform = 'BlackBerry'
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class WindowsPhone(OS):
|
|
||||||
name = "Windows Phone"
|
|
||||||
platform = 'Windows'
|
|
||||||
look_for = ["Windows Phone OS", "Windows Phone"]
|
|
||||||
version_markers = [(" ", ";"), (" ", ")")]
|
|
||||||
|
|
||||||
|
|
||||||
class iOS(OS):
|
|
||||||
look_for = ('iPhone', 'iPad')
|
|
||||||
skip_if_found = ['like iPhone']
|
|
||||||
|
|
||||||
|
|
||||||
class iPhone(Dist):
|
|
||||||
look_for = 'iPhone'
|
|
||||||
platform = 'iOS'
|
|
||||||
skip_if_found = ['like iPhone']
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
version_end_chars = [' ']
|
|
||||||
if not "iPhone OS" in agent:
|
|
||||||
return None
|
|
||||||
part = agent.split('iPhone OS')[-1].strip()
|
|
||||||
for c in version_end_chars:
|
|
||||||
if c in part:
|
|
||||||
version = part.split(c)[0]
|
|
||||||
return version.replace('_', '.')
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
class IPad(Dist):
|
|
||||||
look_for = 'iPad;'
|
|
||||||
platform = 'iOS'
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
version_end_chars = [' ']
|
|
||||||
if not "CPU OS " in agent:
|
|
||||||
return None
|
|
||||||
part = agent.split('CPU OS ')[-1].strip()
|
|
||||||
for c in version_end_chars:
|
|
||||||
if c in part:
|
|
||||||
version = part.split(c)[0]
|
|
||||||
return version.replace('_', '.')
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
class Macintosh(OS):
|
|
||||||
look_for = 'Macintosh'
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class MacOS(Flavor):
|
|
||||||
look_for = 'Mac OS'
|
|
||||||
platform = 'Mac OS'
|
|
||||||
skip_if_found = ['iPhone', 'iPad']
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
version_end_chars = [';', ')']
|
|
||||||
part = agent.split('Mac OS')[-1].strip()
|
|
||||||
for c in version_end_chars:
|
|
||||||
if c in part:
|
|
||||||
version = part.split(c)[0]
|
|
||||||
return version.replace('_', '.')
|
|
||||||
return ''
|
|
||||||
|
|
||||||
|
|
||||||
class Windows(Dist):
|
|
||||||
look_for = 'Windows'
|
|
||||||
platform = 'Windows'
|
|
||||||
|
|
||||||
|
|
||||||
class Windows(OS):
|
|
||||||
look_for = 'Windows'
|
|
||||||
platform = 'Windows'
|
|
||||||
skip_if_found = ["Windows Phone"]
|
|
||||||
win_versions = {
|
|
||||||
"NT 6.3": "8.1",
|
|
||||||
"NT 6.2": "8",
|
|
||||||
"NT 6.1": "7",
|
|
||||||
"NT 6.0": "Vista",
|
|
||||||
"NT 5.2": "Server 2003 / XP x64",
|
|
||||||
"NT 5.1": "XP",
|
|
||||||
"NT 5.01": "2000 SP1",
|
|
||||||
"NT 5.0": "2000",
|
|
||||||
"98; Win 9x 4.90": "Me"
|
|
||||||
}
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
v = agent.split('Windows')[-1].split(';')[0].strip()
|
|
||||||
if ')' in v:
|
|
||||||
v = v.split(')')[0]
|
|
||||||
v = self.win_versions.get(v, v)
|
|
||||||
return v
|
|
||||||
|
|
||||||
|
|
||||||
class Ubuntu(Dist):
|
|
||||||
look_for = 'Ubuntu'
|
|
||||||
version_markers = ["/", " "]
|
|
||||||
|
|
||||||
|
|
||||||
class Debian(Dist):
|
|
||||||
look_for = 'Debian'
|
|
||||||
version_markers = ["/", " "]
|
|
||||||
|
|
||||||
|
|
||||||
class Chrome(Browser):
|
|
||||||
look_for = "Chrome"
|
|
||||||
version_markers = ["/", " "]
|
|
||||||
skip_if_found = ["OPR"]
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
part = agent.split(word + self.version_markers[0])[-1]
|
|
||||||
version = part.split(self.version_markers[1])[0]
|
|
||||||
if '+' in version:
|
|
||||||
version = part.split('+')[0]
|
|
||||||
return version.strip()
|
|
||||||
|
|
||||||
|
|
||||||
class ChromeiOS(Browser):
|
|
||||||
look_for = "CriOS"
|
|
||||||
version_markers = ["/", " "]
|
|
||||||
|
|
||||||
|
|
||||||
class ChromeOS(OS):
|
|
||||||
look_for = "CrOS"
|
|
||||||
platform = ' ChromeOS'
|
|
||||||
version_markers = [" ", " "]
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
version_markers = self.version_markers
|
|
||||||
if word + '+' in agent:
|
|
||||||
version_markers = ['+', '+']
|
|
||||||
return agent.split(word + version_markers[0])[-1].split(version_markers[1])[1].strip()[:-1]
|
|
||||||
|
|
||||||
|
|
||||||
class Android(Dist):
|
|
||||||
look_for = 'Android'
|
|
||||||
platform = 'Android'
|
|
||||||
skip_if_found = ['Windows Phone']
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
return agent.split(word)[-1].split(';')[0].strip()
|
|
||||||
|
|
||||||
|
|
||||||
class WebOS(Dist):
|
|
||||||
look_for = 'hpwOS'
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
return agent.split('hpwOS/')[-1].split(';')[0].strip()
|
|
||||||
|
|
||||||
|
|
||||||
class NokiaS40(OS):
|
|
||||||
look_for = 'Series40'
|
|
||||||
platform = 'Nokia S40'
|
|
||||||
|
|
||||||
def getVersion(self, agent, word):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Symbian(OS):
|
|
||||||
look_for = ['Symbian', 'SymbianOS']
|
|
||||||
platform = 'Symbian'
|
|
||||||
|
|
||||||
|
|
||||||
class PlayStation(OS):
|
|
||||||
look_for = ['PlayStation', 'PLAYSTATION']
|
|
||||||
platform = 'PlayStation'
|
|
||||||
version_markers = [" ", ")"]
|
|
||||||
|
|
||||||
|
|
||||||
class prefs: # experimental
|
|
||||||
os = dict(
|
|
||||||
Linux=dict(dict(browser=[Firefox, Chrome], dist=[Ubuntu, Android])),
|
|
||||||
BlackBerry=dict(dist=[BlackberryPlaybook]),
|
|
||||||
Macintosh=dict(flavor=[MacOS]),
|
|
||||||
Windows=dict(browser=[MSIE, Firefox]),
|
|
||||||
ChromeOS=dict(browser=[Chrome]),
|
|
||||||
Debian=dict(browser=[Firefox])
|
|
||||||
)
|
|
||||||
dist = dict(
|
|
||||||
Ubuntu=dict(browser=[Firefox]),
|
|
||||||
Android=dict(browser=[Safari]),
|
|
||||||
IPhone=dict(browser=[Safari]),
|
|
||||||
IPad=dict(browser=[Safari]),
|
|
||||||
)
|
|
||||||
flavor = dict(
|
|
||||||
MacOS=dict(browser=[Opera, Chrome, Firefox, MSIE])
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
detectorshub = DetectorsHub()
|
|
||||||
|
|
||||||
|
|
||||||
def detect(agent, fill_none=False):
|
|
||||||
"""
|
|
||||||
fill_none: if name/version is not detected respective key is still added to the result with value None
|
|
||||||
"""
|
|
||||||
result = dict(platform=dict(name=None, version=None))
|
|
||||||
_suggested_detectors = []
|
|
||||||
|
|
||||||
for info_type in detectorshub:
|
|
||||||
detectors = _suggested_detectors or detectorshub[info_type]
|
|
||||||
for detector in detectors:
|
|
||||||
try:
|
|
||||||
detector.detect(agent, result)
|
|
||||||
except Exception as _err:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if fill_none:
|
|
||||||
attrs_d = {'name': None, 'version': None}
|
|
||||||
for key in ('os', 'browser'):
|
|
||||||
if key not in result:
|
|
||||||
result[key] = attrs_d
|
|
||||||
else:
|
|
||||||
for k, v in attrs_d.items():
|
|
||||||
result[k] = v
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def simple_detect(agent):
|
|
||||||
"""
|
|
||||||
-> (os, browser) # tuple of strings
|
|
||||||
"""
|
|
||||||
result = detect(agent)
|
|
||||||
os_list = []
|
|
||||||
if 'flavor' in result:
|
|
||||||
os_list.append(result['flavor']['name'])
|
|
||||||
if 'dist' in result:
|
|
||||||
os_list.append(result['dist']['name'])
|
|
||||||
if 'os' in result:
|
|
||||||
os_list.append(result['os']['name'])
|
|
||||||
|
|
||||||
os = os_list and " ".join(os_list) or "Unknown OS"
|
|
||||||
os_version = os_list and (result.get('flavor') and result['flavor'].get('version')) or \
|
|
||||||
(result.get('dist') and result['dist'].get('version')) or (result.get('os') and result['os'].get('version')) or ""
|
|
||||||
browser = 'browser' in result and result['browser'].get('name') or 'Unknown Browser'
|
|
||||||
browser_version = 'browser' in result and result['browser'].get('version') or ""
|
|
||||||
if browser_version:
|
|
||||||
browser = " ".join((browser, browser_version))
|
|
||||||
if os_version:
|
|
||||||
os = " ".join((os, os_version))
|
|
||||||
return os, browser
|
|
|
@ -43,7 +43,7 @@ from configobj import ConfigObj
|
||||||
from core.configwatcher import ConfigWatcher
|
from core.configwatcher import ConfigWatcher
|
||||||
from core.utils import shutdown
|
from core.utils import shutdown
|
||||||
|
|
||||||
from dnslib import *
|
from mitmflib.dnslib import *
|
||||||
from IPy import IP
|
from IPy import IP
|
||||||
|
|
||||||
formatter = logging.Formatter("%(asctime)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
|
formatter = logging.Formatter("%(asctime)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
|
||||||
|
|
|
@ -56,13 +56,13 @@ import logging
|
||||||
import ntpath
|
import ntpath
|
||||||
import ConfigParser
|
import ConfigParser
|
||||||
|
|
||||||
from impacket import LOG as logger
|
from mitmflib.impacket import LOG as logger
|
||||||
from impacket import smbserver, smb, version
|
from mitmflib.impacket import smbserver, smb, version
|
||||||
import impacket.smb3structs as smb2
|
import mitmflib.impacket.smb3structs as smb2
|
||||||
from impacket.smb import FILE_OVERWRITE, FILE_OVERWRITE_IF, FILE_WRITE_DATA, FILE_APPEND_DATA, GENERIC_WRITE
|
from mitmflib.impacket.smb import FILE_OVERWRITE, FILE_OVERWRITE_IF, FILE_WRITE_DATA, FILE_APPEND_DATA, GENERIC_WRITE
|
||||||
from impacket.nt_errors import STATUS_USER_SESSION_DELETED, STATUS_SUCCESS, STATUS_ACCESS_DENIED, STATUS_NO_MORE_FILES, \
|
from mitmflib.impacket.nt_errors import STATUS_USER_SESSION_DELETED, STATUS_SUCCESS, STATUS_ACCESS_DENIED, STATUS_NO_MORE_FILES, \
|
||||||
STATUS_OBJECT_PATH_NOT_FOUND
|
STATUS_OBJECT_PATH_NOT_FOUND
|
||||||
from impacket.smbserver import SRVSServer, decodeSMBString, findFirst2, STATUS_SMB_BAD_TID, encodeSMBString, \
|
from mitmflib.impacket.smbserver import SRVSServer, decodeSMBString, findFirst2, STATUS_SMB_BAD_TID, encodeSMBString, \
|
||||||
getFileTime, queryPathInformation
|
getFileTime, queryPathInformation
|
||||||
|
|
||||||
class KarmaSMBServer():
|
class KarmaSMBServer():
|
||||||
|
|
|
@ -4,7 +4,7 @@ import threading
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from socket import error as socketerror
|
from socket import error as socketerror
|
||||||
from impacket import version, smbserver, LOG
|
from mitmflib.impacket import version, smbserver, LOG
|
||||||
from core.servers.smb.KarmaSMB import KarmaSMBServer
|
from core.servers.smb.KarmaSMB import KarmaSMBServer
|
||||||
from core.configwatcher import ConfigWatcher
|
from core.configwatcher import ConfigWatcher
|
||||||
from core.utils import shutdown
|
from core.utils import shutdown
|
||||||
|
@ -62,7 +62,7 @@ class SMBserver(ConfigWatcher):
|
||||||
|
|
||||||
except socketerror as e:
|
except socketerror as e:
|
||||||
if "Address already in use" in e:
|
if "Address already in use" in e:
|
||||||
shutdown("\n[-] Unable to start SMB server on port {}: port already in use".format(listenPort))
|
shutdown("\n[-] Unable to start SMB server on port {}: port already in use".format(self.smb_port))
|
||||||
|
|
||||||
def configureLogging(self, formatter):
|
def configureLogging(self, formatter):
|
||||||
#yes I know this looks awful, yuck
|
#yes I know this looks awful, yuck
|
||||||
|
|
|
@ -24,8 +24,8 @@ import zlib
|
||||||
import gzip
|
import gzip
|
||||||
import StringIO
|
import StringIO
|
||||||
import sys
|
import sys
|
||||||
import core.httpagentparser as hap
|
|
||||||
|
|
||||||
|
from mitmflib.user_agents import parse
|
||||||
from twisted.web.http import HTTPClient
|
from twisted.web.http import HTTPClient
|
||||||
from URLMonitor import URLMonitor
|
from URLMonitor import URLMonitor
|
||||||
from core.sergioproxy.ProxyPlugins import ProxyPlugins
|
from core.sergioproxy.ProxyPlugins import ProxyPlugins
|
||||||
|
@ -72,15 +72,12 @@ class ServerConnection(HTTPClient):
|
||||||
def sendRequest(self):
|
def sendRequest(self):
|
||||||
if self.command == 'GET':
|
if self.command == 'GET':
|
||||||
try:
|
try:
|
||||||
|
user_agent = parse(self.headers['user-agent'])
|
||||||
if ('Unknown' in self.clientInfo[0]) or ('Unknown' in self.clientInfo[1]):
|
self.clientInfo = (user_agent.browser.family, user_agent.browser.version[0], user_agent.os.family)
|
||||||
mitmf_logger.info("{} Sending Request: {}".format(self.client.getClientIP(), self.headers['host']))
|
mitmf_logger.info("{} [type:{}-{} os:{}] {}".format(self.client.getClientIP(), user_agent.browser.family, user_agent.browser.version[0], user_agent.os.family, self.headers['host']))
|
||||||
else:
|
|
||||||
mitmf_logger.info("{} [type:{} os:{}] Sending Request: {}".format(self.client.getClientIP(), self.clientInfo[1], self.clientInfo[0], self.headers['host']))
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
mitmf_logger.debug("[ServerConnection] Unable to parse UA: {}".format(e))
|
mitmf_logger.debug("[ServerConnection] Unable to parse UA: {}".format(e))
|
||||||
mitmf_logger.info("{} Sending Request: {}".format(self.client.getClientIP(), self.headers['host']))
|
mitmf_logger.info("{} Sending request: {}".format(self.client.getClientIP(), self.headers['host']))
|
||||||
pass
|
pass
|
||||||
|
|
||||||
mitmf_logger.debug("[ServerConnection] Full request: {}{}".format(self.headers['host'], self.uri))
|
mitmf_logger.debug("[ServerConnection] Full request: {}{}".format(self.headers['host'], self.uri))
|
||||||
|
@ -110,12 +107,6 @@ class ServerConnection(HTTPClient):
|
||||||
|
|
||||||
def connectionMade(self):
|
def connectionMade(self):
|
||||||
mitmf_logger.debug("[ServerConnection] HTTP connection made.")
|
mitmf_logger.debug("[ServerConnection] HTTP connection made.")
|
||||||
try:
|
|
||||||
self.clientInfo = hap.simple_detect(self.headers['user-agent'])
|
|
||||||
except KeyError as e:
|
|
||||||
mitmf_logger.debug("[ServerConnection] Client didn't send UA with request")
|
|
||||||
self.clientInfo = None
|
|
||||||
pass
|
|
||||||
|
|
||||||
self.plugins.hook()
|
self.plugins.hook()
|
||||||
self.sendRequest()
|
self.sendRequest()
|
||||||
|
@ -152,7 +143,7 @@ class ServerConnection(HTTPClient):
|
||||||
self.isCompressed = True
|
self.isCompressed = True
|
||||||
|
|
||||||
elif (key.lower()== 'strict-transport-security'):
|
elif (key.lower()== 'strict-transport-security'):
|
||||||
mitmf_logger.info("{} [type:{} os:{}] Zapped a strict-trasport-security header".format(self.client.getClientIP(), self.clientInfo[1], self.clientInfo[0]))
|
mitmf_logger.info("{} [type:{}-{} os:{}] Zapped a strict-trasport-security header".format(self.client.getClientIP(), self.clientInfo[0], self.clientInfo[1], self.clientInfo[2]))
|
||||||
|
|
||||||
elif (key.lower() == 'content-length'):
|
elif (key.lower() == 'content-length'):
|
||||||
self.contentLength = value
|
self.contentLength = value
|
||||||
|
|
6
kali_setup.sh
Executable file
6
kali_setup.sh
Executable file
|
@ -0,0 +1,6 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
git submodule init && git submodule update --recursive
|
||||||
|
apt-get install -y python-capstone python-twisted python-requests python-scapy python-dnspython python-cryptography python-crypto
|
||||||
|
apt-get install -y python-msgpack python-configobj python-pefile python-ipy python-openssl python-pypcap
|
||||||
|
pip install Pillow mitmflib
|
3
other_setup.sh
Normal file
3
other_setup.sh
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
git submodule init && git submodule update --recursive
|
|
@ -170,6 +170,7 @@ class Inject(CacheKill, Plugin):
|
||||||
options.add_argument("--js-url", type=str, help="Location of your (presumably) malicious Javascript.")
|
options.add_argument("--js-url", type=str, help="Location of your (presumably) malicious Javascript.")
|
||||||
options.add_argument("--html-url", type=str, help="Location of your (presumably) malicious HTML. Injected via hidden iframe.")
|
options.add_argument("--html-url", type=str, help="Location of your (presumably) malicious HTML. Injected via hidden iframe.")
|
||||||
options.add_argument("--html-payload", type=str, default='', help="String you would like to inject.")
|
options.add_argument("--html-payload", type=str, default='', help="String you would like to inject.")
|
||||||
|
#options.add_argument("--html-file", type=argparse.FileType('r'), help='File containg HTML you would like to inject')
|
||||||
options.add_argument("--match-str", type=str, default=None, help="String you would like to match and place your payload before. (</body> by default)")
|
options.add_argument("--match-str", type=str, default=None, help="String you would like to match and place your payload before. (</body> by default)")
|
||||||
options.add_argument("--preserve-cache", action="store_true", help="Don't kill the server/client caching.")
|
options.add_argument("--preserve-cache", action="store_true", help="Don't kill the server/client caching.")
|
||||||
group = options.add_mutually_exclusive_group(required=False)
|
group = options.add_mutually_exclusive_group(required=False)
|
||||||
|
|
|
@ -2,15 +2,16 @@ Twisted
|
||||||
requests
|
requests
|
||||||
netaddr
|
netaddr
|
||||||
scapy
|
scapy
|
||||||
|
dnspython
|
||||||
|
cryptography
|
||||||
|
pycrypto
|
||||||
msgpack-python
|
msgpack-python
|
||||||
dnslib
|
|
||||||
configobj
|
configobj
|
||||||
|
mitmflib
|
||||||
Pillow
|
Pillow
|
||||||
pefile
|
pefile
|
||||||
ipy
|
ipy
|
||||||
pyopenssl
|
pyopenssl
|
||||||
service_identity
|
service_identity
|
||||||
watchdog
|
|
||||||
impacket
|
|
||||||
capstone
|
capstone
|
||||||
pypcap
|
pypcap
|
3
setup.sh
3
setup.sh
|
@ -1,3 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
git submodule init && git submodule update --recursive
|
|
Loading…
Add table
Add a link
Reference in a new issue