Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Trojaned Gems: You can't tell you're using one

Trojaned Gems: You can't tell you're using one

This talk was presented at THOTCON 0x6, Beacon and OWASP Chicago. Brandon Myers and I talk about our research on Ruby Gem security. We talk about RubyGem 101 basics, transport layer security risks, how to trojan a gem, and discuss how to bypass gem signing. We also discuss a research tool we created to demonstrate the exploitation and trojaning process. We also provide guidance on how developers and users can better protect themselves from such weaknesses.

Demonstration Video #1: Gem Install Request Hijacking
https://vimeo.com/130781378

Demonstration Video #2: Trojaning a Gem in Transit
https://vimeo.com/130781377

Demonstration Video #3: Bypassing Signed Gems (on MediumSecurity)
https://vimeo.com/130781379

Blog Post:
https://www.trustwave.com/Resources/SpiderLabs-Blog/Attacking-Ruby-Gem-Security-with-CVE-2015-3900/?page=1&year=0&month=0

Edb7903a55645abee02925213e0d25b2?s=128

Jonathan Claudius

May 15, 2015
Tweet

Transcript

  1. TROJANED GEMS YOU CAN’T TELL YOU’RE USING ONE!

  2. Brandon Myers Security Researcher @pwnbus Jonathan Claudius Lead Security Researcher

    @claudijd
  3. Who’s used Ruby before?

  4. Stuff you might know… that uses Ruby

  5. Today’s Plan •  Ruby Gems 101 •  Transport Security Risks

    •  Trojan/Injection Tactics •  Mitigation Techniques/Bypasses •  Your Action Items •  DEMOs – sprinkled in along the way
  6. Why research this stuff?

  7. Research Motivation

  8. What is a Ruby gem?

  9. What is a Ruby gem? •  A simplistic packaging file

    format for Ruby code (.gem) –  Compressed folder of ruby source code –  Allows for easy distribution and consumption –  Metadata about library specified in ‘gemspec’ file within gem •  Name •  Author •  Version •  Dependencies •  Public key (assuming gem is “signed”)
  10. Dissecting a Ruby Gem

  11. Dissecting a Ruby Gem: metadata.gz

  12. Dissecting a Ruby Gem: data.tar.gz

  13. Dissecting a Ruby Gem: checksums.yaml.gz … …

  14. How are Ruby gems built/installed?

  15. How are Ruby Gems Built?

  16. How are Ruby Gems Distributed? •  Most popular gem hosting

    server is rubygems.org –  Communication to gem server is via HTTP Author User Gem Server
  17. How are Ruby Gems Installed? •  Once ruby gem server

    is specified as a gem source: –  Download gem source to current working directory •  “gem fetch <gemname>” •  “gem install <gemname>.gem” –  Download and ‘install’ gem •  “gem install <gemname>”
  18. How are Ruby Gems Installed?

  19. Gem Transport

  20. What happens on the wire? DNS SRV Request DNS SRV

    Reply HTTP GET Reply HTTP GET Request Where is the Gem Server? What are the dependencies? HTTP GET Reply HTTP GET Request Download the gem(s)
  21. Where is the Gem Server?

  22. What are the dependencies?

  23. Download the gems

  24. Gem Transport Risks

  25. Gem Transport Attacks •  Altering DNS SVR replies •  Altering

    HTTP Gem Dependency replies •  Altering HTTP Gem Download content •  These attacks assume at least one of these perquisites –  Race Attack (DNS) –  MiTM (DNS or HTTP) –  Coffee shop scenario (DNS or HTTP)
  26. Hijack via DNS Replies Where is the Gem Server? Client

    Attacker DNS Rep Future coms. Gem Server
  27. Insert Malicious Gem Dependency What are the dependencies? Client Attacker

    Dep Req Dep Req Deps Deps++
  28. Trojan Gem Directly Give me the gems! Client Attacker Gem

    Req Gem Req Gem Gem++
  29. Demo #1

  30. Gem Install Request Hijacking •  Scenario –  User has https://rubygems.org

    as a gem source –  We expect all gem transport to be encrypted w/ SSL/TLS •  Attack –  User runs “gem install” –  MiTM attacker forges DNS reply to point to attacker gem server –  User installs attacker controlled gem J
  31. Violating HTTPS Gem Transport Trust w/ DNS Client What’s the

    SRV record for _rubygems._tcp.rubygems.org? SRV answer is gems.trustwave.com and resolves to 10.1.1.110 GET request for c7decrypt gem c8decrypt gem DNS Traffic HTTPS Traffic Attacker ‘gem install c7decrypt’
  32. CVE-2015-3900 •  Request Hijacking Vulnerability in RubyGems –  Affects: Ruby

    1.9.0 – 2.2.0 –  Affects: RubyGems 2.0 – 2.0.15, 2.2 – 2.2.3, 2.4 – 2.4.6 •  How to fix: –  ‘gem update –system’ Oh, and BTW…
  33. Gem Trojaning

  34. Steps to use 3rd party gem in project Load Install

    Download
  35. Download Time Attacker Client TBD (Work in progress) $ gem

    fetch c7decrypt
  36. Install Time Attacker Client $ cat c7decrypt.gemspec …. s.extensions =

    ["Rakefile"] …. $ cat Rakefile …. `echo ’PWND' > /tmp/pwnd.txt` $ gem fetch c7decrypt $ gem install c7decrypt-0.3.2.gem …. Building native extensions. … $ cat /tmp/pwnd.txt PWND https://speakerdeck.com/benjaminleesmith/hacking-with-gems
  37. Load Time Attacker Client $ cat lib/c7decrypt.rb …. `echo ’PWND'

    > /tmp/pwnd.txt` $ gem fetch c7decrypt $ gem install c7decrypt-0.3.2.gem $ irb 2.1.2 :001 > require ‘c7decrypt’ $ cat /tmp/pwnd.txt PWND
  38. Pickaxe

  39. Tool Components •  Serves client gem install requests •  Caches

    each downloaded gem once retrieved from rubygems.org Gem Caching Server •  Unpacks gem •  Injects malicious code into various locations in gem source •  Packs gem Gem Trojaner
  40. With our powers combined… Caching server downloads gem from rubygems

    Downloaded gem is unpacked, trojaned, and then repackaged Trojaned gem is then sent to client
  41. Demo #2

  42. Attacker Trojans Gem in Transit •  Scenario –  User has

    https://rubygems.org as a gem source –  We expect all gem transport to be encrypted w/ SSL/TLS •  Attack –  User runs “gem install” –  MiTM attacker forges DNS reply to point to attacker gem server –  Attacker adds malicious code to gem on the fly –  Malicious code runs on user’s system
  43. How to trojan a gem in transit? •  Author produces

    a gem for public consumption •  User consumes the gem using defacto gem install standards •  Attacker MiTM’s the gem installation process, trojan’s the gem on the fly, user gets owned without even knowing it.
  44. How to trojan a gem in transit? GET c7decrypt gem

    Trojaned c7decrypt gem HTTPS Traffic Attacker ‘gem install c7decrypt’ Client c7decrypt gem rubygems.org GET c7decrypt gem DNS Traffic
  45. Gem Signing

  46. Why sign gems?

  47. Signing your gems -  Generate your signing key -  “gem

    cert –build jclaudius@trustwave.com” -  Add signing key to gemspec -  s.cert_chain = [‘certs/gem-public_cert.pem’] -  s.signing_key = File.expand_path(‘~/secret/gem- private_key.pem’) if $0 =~ /gem\z/ -  “Gem build c7decrypt.gemspec” -  http://guides.rubygems.org/security/ -  https://www.trustwave.com/Resources/SpiderLabs-Blog/Signed- Ruby-Gems--A-c7decrypt-walk-through/
  48. Installing a signed gem “gem cert –add jclaudius-public_cert.pem” - Trusting

    signing key based on author, not project “gem install c7decrypt –P HighSecurity”
  49. Trust Policies High Security Medium Security Not Signed

  50. Demo #3

  51. Thotcon6 Gem Dependency Tree Remove Signature and Inject as Extension

    in Rakefile
  52. Bypassing Signed Ruby Gems •  Scenario –  User has https://rubygems.org

    as a gem source –  Ruby gem and all but of it’s dependencies are signed •  Attack –  User runs “gem install gem_name –P MediumSecurity” –  MiTM attacker forges DNS reply to point to attacker gem server –  Performs “downgrade attack” on a signed dependency –  Attacker adds malicious code to gem on the fly –  Malicious code runs on user’s system
  53. How to bypass a Medium Trust Policy? •  Author has

    decided to sign the parent gem •  User has decided to use a Medium trust policy, to verify and protect the signed gems in their dependency tree •  All gems within the dependency tree are signed •  We will show how an attacker can still land trojaned gems installed on the target by doing a gem signing downgrade attack •  It’s simple, in a medium trust policy, only the primary gem must be signed, if we remove all signing attributes from the dependent gems, we can trick the installer into installing them.
  54. GET thotcon6 + dependencies HTTPS Traffic Attacker ‘gem install thotcon6

    –P MediumSecurity’ Client thotcon6 + dependencies GET thotcon6 + dependencies DNS Traffic rubygems.org thotcon6 + dependencies* How to bypass a Medium Trust Policy
  55. What should you do?

  56. User Action Items •  Disable all HTTP Gem Sources in

    favor of HTTPS –  ‘gem sources’ •  Update gem command to latest version –  ‘gem update –system’ •  Use the highest trust policy possible when downloading gems –  Signed gems will not always be verified by default
  57. Developer Action Items •  Disable all HTTP gem sources in

    favor of HTTPS •  Update gem command to latest version –  Pushing gems uses similar HTTP/S communication •  Start signing your gems –  The Update Framework (TUF) –  GPG
  58. Thank You!

  59. Questions? Brandon Myers Security Researcher @pwnbus Jonathan Claudius Lead Security

    Researcher @claudijd