Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

Brandon Myers Security Researcher @pwnbus Jonathan Claudius Lead Security Researcher @claudijd

Slide 3

Slide 3 text

Who’s used Ruby before?

Slide 4

Slide 4 text

Stuff you might know… that uses Ruby

Slide 5

Slide 5 text

Today’s Plan •  Ruby Gems 101 •  Transport Security Risks •  Trojan/Injection Tactics •  Mitigation Techniques/Bypasses •  Your Action Items •  DEMOs – sprinkled in along the way

Slide 6

Slide 6 text

Why research this stuff?

Slide 7

Slide 7 text

Research Motivation

Slide 8

Slide 8 text

What is a Ruby gem?

Slide 9

Slide 9 text

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”)

Slide 10

Slide 10 text

Dissecting a Ruby Gem

Slide 11

Slide 11 text

Dissecting a Ruby Gem: metadata.gz

Slide 12

Slide 12 text

Dissecting a Ruby Gem: data.tar.gz

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

How are Ruby gems built/installed?

Slide 15

Slide 15 text

How are Ruby Gems Built?

Slide 16

Slide 16 text

How are Ruby Gems Distributed? •  Most popular gem hosting server is rubygems.org –  Communication to gem server is via HTTP Author User Gem Server

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

How are Ruby Gems Installed?

Slide 19

Slide 19 text

Gem Transport

Slide 20

Slide 20 text

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)

Slide 21

Slide 21 text

Where is the Gem Server?

Slide 22

Slide 22 text

What are the dependencies?

Slide 23

Slide 23 text

Download the gems

Slide 24

Slide 24 text

Gem Transport Risks

Slide 25

Slide 25 text

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)

Slide 26

Slide 26 text

Hijack via DNS Replies Where is the Gem Server? Client Attacker DNS Rep Future coms. Gem Server

Slide 27

Slide 27 text

Insert Malicious Gem Dependency What are the dependencies? Client Attacker Dep Req Dep Req Deps Deps++

Slide 28

Slide 28 text

Trojan Gem Directly Give me the gems! Client Attacker Gem Req Gem Req Gem Gem++

Slide 29

Slide 29 text

Demo #1

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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’

Slide 32

Slide 32 text

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…

Slide 33

Slide 33 text

Gem Trojaning

Slide 34

Slide 34 text

Steps to use 3rd party gem in project Load Install Download

Slide 35

Slide 35 text

Download Time Attacker Client TBD (Work in progress) $ gem fetch c7decrypt

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

Pickaxe

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

Demo #2

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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.

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

Gem Signing

Slide 46

Slide 46 text

Why sign gems?

Slide 47

Slide 47 text

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/

Slide 48

Slide 48 text

Installing a signed gem “gem cert –add jclaudius-public_cert.pem” - Trusting signing key based on author, not project “gem install c7decrypt –P HighSecurity”

Slide 49

Slide 49 text

Trust Policies High Security Medium Security Not Signed

Slide 50

Slide 50 text

Demo #3

Slide 51

Slide 51 text

Thotcon6 Gem Dependency Tree Remove Signature and Inject as Extension in Rakefile

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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.

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

What should you do?

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

Thank You!

Slide 59

Slide 59 text

Questions? Brandon Myers Security Researcher @pwnbus Jonathan Claudius Lead Security Researcher @claudijd