-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ea9a338
commit 95f34f7
Showing
11 changed files
with
993 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
|
||
class LoggingBrief < Logging | ||
def escape(s) | ||
# Encode all special characters # More info: http://www.asciitable.com/ | ||
# r=/[^\x20-\x5A\x5E-\x7E]/ | ||
|
||
# Encode low ascii non printable characters | ||
r = /[\x00-\x1F]/ | ||
|
||
# based on code for CGI.escape | ||
s.gsub(r) { |x| "%#{x.unpack('H2' * x.size).join('%').upcase}" } | ||
end | ||
|
||
# don't use colours if not to STDOUT | ||
def out(target, status, results) | ||
brief_results = [] | ||
|
||
# sort results so plugins that are less important at a glance are last | ||
# last_plugins=%w| CSS MD5 Header-Hash Footer-Hash Tag-Hash| | ||
# results=results.sort_by {|x,y| last_plugins.include?(x) ? 1 : 0 } | ||
|
||
results = results.sort # sort results by plugin name alphabetically | ||
|
||
results.each do |plugin_name, plugin_results| | ||
next if plugin_results.empty? | ||
suj = suj(plugin_results) | ||
|
||
certainty = suj[:certainty].to_i | ||
version = escape(suj[:version]) | ||
os = escape(suj[:os]) | ||
string = escape(suj[:string]) | ||
accounts = escape(suj[:account]) | ||
model = escape(suj[:model]) | ||
firmware = escape(suj[:firmware]) | ||
modules = escape(suj[:module]) | ||
filepath = escape(suj[:filepath]) | ||
|
||
# colour the output | ||
# be more DRY | ||
# if plugins have categories or tags this would be better, eg. all hash plugins are grey | ||
if (@f == STDOUT && $use_colour == 'auto') || ($use_colour == 'always') | ||
coloured_string = grey(string) | ||
coloured_string = cyan(string) if plugin_name == 'HTTPServer' | ||
coloured_string = yellow(string) if plugin_name == 'Title' | ||
|
||
coloured_string = grey(string) if plugin_name == 'MD5' | ||
coloured_string = grey(string) if plugin_name == 'Header-Hash' | ||
coloured_string = grey(string) if plugin_name == 'Footer-Hash' | ||
coloured_string = grey(string) if plugin_name == 'CSS' | ||
coloured_string = grey(string) if plugin_name == 'Tag-Hash' | ||
|
||
coloured_plugin = white(plugin_name) | ||
coloured_plugin = grey(plugin_name) if plugin_name == 'MD5' | ||
coloured_plugin = grey(plugin_name) if plugin_name == 'Header-Hash' | ||
coloured_plugin = grey(plugin_name) if plugin_name == 'Footer-Hash' | ||
coloured_plugin = grey(plugin_name) if plugin_name == 'CSS' | ||
coloured_plugin = grey(plugin_name) if plugin_name == 'Tag-Hash' | ||
|
||
p = ((certainty && certainty < 100) ? "#{grey(Helper::certainty_to_words(certainty))} " : '') + | ||
coloured_plugin + (!version.empty? ? "[#{green(version)}]" : '') + | ||
(!os.empty? ? "[#{red(os)}]" : '') + | ||
(!string.empty? ? "[#{coloured_string}]" : '') + | ||
(!accounts.empty? ? "[#{cyan(accounts)}]" : '') + | ||
(!model.empty? ? "[#{dark_green(model)}]" : '') + | ||
(!firmware.empty? ? "[#{dark_green(firmware)}]" : '') + | ||
(!filepath.empty? ? "[#{dark_green(filepath)}]" : '') + | ||
(!modules.empty? ? "[#{red(modules)}]" : '') | ||
|
||
brief_results << p | ||
else | ||
|
||
brief_results << ((certainty && certainty < 100) ? "#{Helper::certainty_to_words(certainty)} " : '') + | ||
plugin_name + (!version.empty? ? "[#{version}]" : '') + | ||
(!os.empty? ? "[#{os}]" : '') + | ||
(!string.empty? ? "[#{string}]" : '') + | ||
(!accounts.empty? ? " [#{accounts}]" : '') + | ||
(!model.empty? ? "[#{model}]" : '') + | ||
(!firmware.empty? ? "[#{firmware}]" : '') + | ||
(!filepath.empty? ? "[#{filepath}]" : '') + | ||
(!modules.empty? ? "[#{modules}]" : '') | ||
end | ||
end | ||
|
||
status_code = HTTP_Status.code(status) | ||
|
||
if (@f == STDOUT && $use_colour == 'auto') || ($use_colour == 'always') | ||
brief_results_final = "#{blue(target)} [#{status} #{status_code}] #{brief_results.join(', ')}" | ||
else | ||
brief_results_final = "#{target} [#{status} #{status_code}] #{brief_results.join(', ')}" | ||
end | ||
$semaphore.synchronize do | ||
@f.puts brief_results_final | ||
end | ||
end | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
# Elasticseach Output, copy of JSON ouput then a HTTP request to send result to elastic | ||
# Does not use elasticsearch gem. Instead only sends HTTP | ||
class LoggingElastic < Logging | ||
def initialize(s) | ||
@host = s[:host] || '127.0.0.1:9200' | ||
@index = s[:index] || 'whoknows' | ||
end | ||
|
||
def close | ||
# nothin' | ||
end | ||
|
||
def flatten_elements!(obj) | ||
if obj.class == Hash | ||
obj.each_value do |x| | ||
flatten_elements!(x) | ||
end | ||
end | ||
|
||
obj.flatten! if obj.class == Array | ||
end | ||
|
||
|
||
def out(target, status, results) | ||
# nice | date be like 2009-11-15T14:12:12 to be autodetected by elastic | ||
foo = { target: target.to_s, http_status: status, date: Time.now.strftime('%FT%T'), plugins: {} } | ||
|
||
results.each do |plugin_name, plugin_results| | ||
# thisplugin = {:name=>plugin_name} | ||
thisplugin = {} | ||
|
||
next if plugin_results.empty? | ||
# important info in brief mode is version, type and ? | ||
# what's the highest probability for the match? | ||
|
||
certainty = plugin_results.map { |x| x[:certainty] unless x[:certainty].class == Regexp }.flatten.compact.sort.uniq.last | ||
|
||
version = plugin_results.map { |x| x[:version] unless x[:version].class == Regexp }.flatten.compact.sort.uniq | ||
os = plugin_results.map { |x| x[:os] unless x[:os].class == Regexp }.flatten.compact.sort.uniq | ||
string = plugin_results.map { |x| x[:string] unless x[:string].class == Regexp }.flatten.compact.sort.uniq | ||
accounts = plugin_results.map { |x| x[:account] unless x[:account].class == Regexp }.flatten.compact.sort.uniq | ||
model = plugin_results.map { |x| x[:model] unless x[:model].class == Regexp }.flatten.compact.sort.uniq | ||
firmware = plugin_results.map { |x| x[:firmware] unless x[:firmware].class == Regexp }.flatten.compact.sort.uniq | ||
modules = plugin_results.map { |x| x[:module] unless x[:module].class == Regexp }.flatten.compact.sort.uniq | ||
filepath = plugin_results.map { |x| x[:filepath] unless x[:filepath].class == Regexp }.flatten.compact.sort.uniq | ||
|
||
thisplugin[:certainty] = certainty if !certainty.nil? && certainty != 100 | ||
|
||
thisplugin[:version] = version unless version.empty? | ||
thisplugin[:os] = os unless os.empty? | ||
thisplugin[:string] = string unless string.empty? | ||
thisplugin[:account] = accounts unless accounts.empty? | ||
thisplugin[:model] = model unless model.empty? | ||
thisplugin[:firmware] = firmware unless firmware.empty? | ||
thisplugin[:module] = modules unless modules.empty? | ||
thisplugin[:filepath] = filepath unless filepath.empty? | ||
# foo[:plugins] << thisplugin | ||
foo[:plugins][plugin_name.to_sym] = thisplugin | ||
end | ||
|
||
@charset = results.map { |n, r| r[0][:string] if n == 'Charset' }.compact.first | ||
|
||
if @charset.nil? || @charset == 'Failed' | ||
# could not find encoding force UTF-8 anyway | ||
Helper::utf8_elements!(foo) | ||
else | ||
Helper::utf8_elements!(foo) # convert foo to utf-8 | ||
flatten_elements!(foo) | ||
end | ||
|
||
url = URI('http://' + @host + '/' + @index + '/whoknowsresult') | ||
req = Net::HTTP::Post.new(url) | ||
req.add_field('Content-Type', 'application/json') | ||
req.body = JSON.generate(foo) | ||
res = Net::HTTP.start(url.hostname, url.port) do |http| | ||
http.request(req) | ||
end | ||
|
||
case res | ||
when Net::HTTPSuccess | ||
# ok | ||
else | ||
error(res.code + ' ' + res.message + "\n" + res.body) | ||
end | ||
end | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
class LoggingErrors < Logging | ||
# don't need semaphore.synchronize, as it's locked by the error handling routine | ||
def out(error) | ||
@f.puts error | ||
end | ||
end | ||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
|
||
# JSON Output # | ||
class LoggingJSON < Logging | ||
def initialize(f = STDOUT) | ||
super | ||
@is_first_log_entry = true | ||
# opening bracket | ||
@f.puts '[' | ||
end | ||
|
||
def close | ||
# closing bracket | ||
@f.puts ']' | ||
@f.close | ||
end | ||
|
||
def flatten_elements!(obj) | ||
if obj.class == Hash | ||
obj.each_value do |x| | ||
flatten_elements!(x) | ||
end | ||
end | ||
|
||
obj.flatten! if obj.class == Array | ||
end | ||
|
||
def out(target, status, results) | ||
# nice | ||
|
||
foo = { target: target.to_s, http_status: status, request_config: {}, plugins: {} } | ||
|
||
# request-config | ||
req_config = {} | ||
if $USE_PROXY | ||
req_config[:proxy] = { proxy_host: $PROXY_HOST, proxy_port: $PROXY_PORT } | ||
req_config[:proxy][:proxy_user] = $PROXY_USER if $PROXY_USER | ||
end | ||
|
||
req_config[:headers] = {} unless $CUSTOM_HEADERS.empty? | ||
$CUSTOM_HEADERS.each do |header_name, header_value| | ||
req_config[:headers][header_name] = header_value.dup | ||
end | ||
foo[:request_config] = req_config | ||
|
||
# plugins | ||
|
||
results.each do |plugin_name, plugin_results| | ||
# thisplugin = {name: plugin_name} | ||
thisplugin = {} | ||
|
||
next if plugin_results.empty? | ||
# important info in brief mode is version, type and ? | ||
# what's the highest probability for the match? | ||
|
||
certainty = plugin_results.map { |x| x[:certainty] unless x[:certainty].class == Regexp }.flatten.compact.sort.uniq.last | ||
|
||
version = plugin_results.map { |x| x[:version] unless x[:version].class == Regexp }.flatten.compact.sort.uniq | ||
os = plugin_results.map { |x| x[:os] unless x[:os].class == Regexp }.flatten.compact.sort.uniq | ||
string = plugin_results.map { |x| x[:string] unless x[:string].class == Regexp }.flatten.compact.sort.uniq | ||
accounts = plugin_results.map { |x| x[:account] unless x[:account].class == Regexp }.flatten.compact.sort.uniq | ||
model = plugin_results.map { |x| x[:model] unless x[:model].class == Regexp }.flatten.compact.sort.uniq | ||
firmware = plugin_results.map { |x| x[:firmware] unless x[:firmware].class == Regexp }.flatten.compact.sort.uniq | ||
modules = plugin_results.map { |x| x[:module] unless x[:module].class == Regexp }.flatten.compact.sort.uniq | ||
filepath = plugin_results.map { |x| x[:filepath] unless x[:filepath].class == Regexp }.flatten.compact.sort.uniq | ||
|
||
thisplugin[:certainty] = certainty if !certainty.nil? && certainty != 100 | ||
|
||
thisplugin[:version] = version unless version.empty? | ||
thisplugin[:os] = os unless os.empty? | ||
thisplugin[:string] = string unless string.empty? | ||
thisplugin[:account] = accounts unless accounts.empty? | ||
thisplugin[:model] = model unless model.empty? | ||
thisplugin[:firmware] = firmware unless firmware.empty? | ||
thisplugin[:module] = modules unless modules.empty? | ||
thisplugin[:filepath] = filepath unless filepath.empty? | ||
# foo[:plugins] << thisplugin | ||
foo[:plugins][plugin_name.to_sym] = thisplugin | ||
end | ||
|
||
@charset = results.map { |n, r| r[0][:string] if n == 'Charset' }.compact.first | ||
|
||
if @charset.nil? || @charset == 'Failed' | ||
# could not find encoding force UTF-8 anyway | ||
Helper::utf8_elements!(foo) | ||
else | ||
Helper::utf8_elements!(foo) # convert foo to utf-8 | ||
flatten_elements!(foo) | ||
end | ||
|
||
$semaphore.synchronize do | ||
unless @is_first_log_entry | ||
@f.puts "," | ||
else | ||
@is_first_log_entry = false | ||
end | ||
|
||
@f.puts JSON.generate(foo) | ||
end | ||
end | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
|
||
# This is not JSON compliant as a list | ||
class LoggingJSONVerbose < Logging | ||
def out(target, status, results) | ||
# brutal and simple | ||
$semaphore.synchronize do | ||
@f.puts JSON.fast_generate([target, status, results]) | ||
end | ||
end | ||
end |
Oops, something went wrong.