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

Jonathan Claudius

May 15, 2015
Tweet

More Decks by Jonathan Claudius

Other Decks in Technology

Transcript

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

    •  Trojan/Injection Tactics •  Mitigation Techniques/Bypasses •  Your Action Items •  DEMOs – sprinkled in along the way
  2. 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”)
  3. How are Ruby Gems Distributed? •  Most popular gem hosting

    server is rubygems.org –  Communication to gem server is via HTTP Author User Gem Server
  4. 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>”
  5. 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)
  6. 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)
  7. Hijack via DNS Replies Where is the Gem Server? Client

    Attacker DNS Rep Future coms. Gem Server
  8. 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
  9. 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’
  10. 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…
  11. 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
  12. 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
  13. 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
  14. 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
  15. 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
  16. 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.
  17. 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
  18. Signing your gems -  Generate your signing key -  “gem

    cert –build [email protected]” -  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/
  19. Installing a signed gem “gem cert –add jclaudius-public_cert.pem” - Trusting

    signing key based on author, not project “gem install c7decrypt –P HighSecurity”
  20. 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
  21. 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.
  22. 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
  23. 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
  24. 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