Many enterprise organizations that deal with large amounts of data that needs to be shared between employees or stakeholders often use enterprise file transfer software.
In our experience, we have seen many industries adopt this type of software to quickly deliver large files. File transfer software can store extremely sensitive data and can act as a single point of failure, as if these services are breached, all of the data stored can also be obtained by the attacker.
One of the most popular solutions for transfering files quickly and “securely” is called IBM Aspera Faspex. As explained by IBM, “IBM Aspera Faspex is a file-exchange application built on IBM Aspera High-Speed Transfer Server as a centralized transfer solution. With a Web-based GUI, Faspex offers advanced management options for FASP high-speed transfer to match your organization’s workflow.”
IBM Aspera Faspex promises security to end users by offering encryption options for the files being uploaded through its application. This security model is broken through the pre-authentication RCE vulnerability we discovered, that allowed us to execute arbitrary commands on the Aspera Faspex server.
As always, customers of our Attack Surface Management platform were the first to know when this vulnerability affected them. We continue to perform original security research in an effort to inform our customers about zero-day vulnerabilities.
This vulnerability has been assigned CVE-2022-47986.
Approaching a Rails Application
When auditing a Ruby on Rails application it is important to understand the project layout. The project layout can be split up into models, views and controllers, but due to the dynamic nature of Ruby on Rails, it can sometimes not be as predictable as other frameworks such as Flask. In this case, Aspera Faspex was using a layout such as the one seen below:
One of the things to check for when auditing a Ruby on Rails application, is whether or not they are shipping the software with a static <span class="code_single-line">SECRET_KEY_BASE</span> value inside any of their configuration files. If this value is found in the code base that you are auditing, and it is not derived through an environment variable but rather is static, this could lead to command execution through Ruby deserialization payloads.
You can see how this was exploited in the past in GitHub Enterprise here.
Another characteristic of auditing Ruby on Rails applications is the presence of a routes file containing a list of routes and the relevant controllers that handle those routes. If you come from a world of auditing Tomcat, this is essentially the equivalent of a <span class="code_single-line">web.xml</span> file.
Our methodology was to deep dive into the <span class="code_single-line">app/</span> folder and focus heavily on all of the controllers which were routable without authentication. We spent some time mapping the routes to the corresponding controllers.
When auditing any Ruby web application, there are a lot of vulnerabilities that may not be obvious unless you have previously read writeups on the sinks or have spent a lot of time programming with the language. The vulnerability we discovered in Aspera Faspex was something that either would have required researching dangerous behaviours for sinks in Ruby or previous knowledge about dangerous sinks in Ruby.
What you might find in Rails apps
While Ruby on Rails is a complex web framework, a lot of the sinks that you will find inside Ruby on Rails projects may simply be dangerous regardless of the framework, but more to do with the Ruby programming language and libraries being used. That being said there are some specific code patterns that tend to be seen inside Ruby on Rails applications.
Below are some of the sinks you may want to look for when auditing Ruby on Rails applications:
- Session cookie if the <span class="code_single-line">SECRET_KEY_BASE</span> is controlled, leaked or guessed
- render inline: “Hello “ + params[:name]
- ERB.new(“Hello “ + params[:name]).result(context)
- ActiveRecord based SQL Injection (https://rails-sqli.org/)
render text, html etc, in:
- <span class="code_single-line"><%= @var %></span>
A Unsafe YAML.load on route /package_relay/relay_package
We identified a call to <span class="code_single-line">YAML.load</span> inside a controller that seemed to be accessible without any authentication. As mentioned earlier in this blog post, one of the deserialization sinks for Ruby is this function.
Our initial steps were to backtracing the calls (tainting) to determine whether or not we controlled the user input that flowed down to this sink.
An unsafe <span class="code_single-line">YAML.load</span> inside default configurations of Ruby is quite dangerous. Through deserialization gadgets, it is possible to achieve command execution if this sink is processing user controlled data.
With this <span class="code_single-line">YAML.load</span>, we are able to construct arbitrary classes. This doesn’t necessarily mean that we will always lead to RCE, but due to the dynamic nature of class instantiation through the <span class="code_single-line">YAML.load</span>, it is a likely candidate towards achieving command execution.
The route was defined as such:
The affected controller inside Aspera Faspex was found in the file <span class="code_single-line">app/controllers/package_relay_controller.rb</span>:
We were able to trace the call for <span class="code_single-line">MultiServer::RelayDescriptor.new</span> to the file <span class="code_single-line">lib/multi_server/relay_descriptor.rb</span>:
As you can see above, the params are passed from the package relay controller, reaching our <span class="code_single-line">YAML.load</span> sink with our user controlled parameter <span class="code_single-line">external_emails</span>.
In order to achieve the RCE, we were able to use the following base gadget:
However, in realistic attack scenarios we found that the version of Ruby that was bundled with Aspera Faspex became a problem. This was because certain classes we would try to instantiate were not available or differed depending on the Ruby version.
Specifically, the class <span class="code_single-line">Gem::RequestSet</span> was missing on a lot of Aspera Faspex installations, but we were able to overcome this through the use of <span class="code_single-line">PrettyPrint</span> located in <span class="code_single-line">vendor/ruby/lib/ruby/1.9.1/prettyprint.rb</span>:
The final <span class="code_single-line">yaml</span> gadget we created that was reliable across Aspera Faspex installations can be found below:
The timeline for this disclosure process can be found below:
- Oct 6th, 2022: Disclosure of the RCE vulnerability in Aspera Faspex to IBM
- Oct 6th, 2022: IBM responded telling us that when we submit a vulnerability report to IBM we grant IBM a no charge license to all intellectual property rights unless we notify them that the rights are covered by someone else.
- Oct 14th, 2022: We clarify with IBM that the research was done during employment at Assetnote and as per the employment contract all intellectual property rights belong to Assetnote.
- Nov 5th, 2022: IBM acknowledges and accepts that intellectual property rights are owned by Assetnote.
- Jan 15th, 2023: We request an update regarding the remediation of this vulnerability
- Jan 18th, 2023: IBM notifies us that the vulnerability has been patched in Faspex 4.4.2 Patch Level 2.
This vulnerability can be remediated by either upgrading to Faspex 4.4.2 Patch Level 2 or Faspex 5.x which does not contain this vulnerability. See IBM’s security advisory for this issue here.