printerxpl-forge 6.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nse/README.md +204 -0
- nse/__init__.py +6 -0
- nse/install_nse.py +412 -0
- nse/lib/printerxpl.lua +238 -0
- nse/scripts/cups-info.nse +74 -0
- nse/scripts/cups-queue-info.nse +43 -0
- nse/scripts/hp-printers-cve-2022-1026.nse +121 -0
- nse/scripts/http-device-mac.nse +107 -0
- nse/scripts/http-hp-ilo-info.nse +121 -0
- nse/scripts/http-info-xerox-enum.nse +101 -0
- nse/scripts/http-vuln-cve2022-1026.nse +158 -0
- nse/scripts/lexmark-config.nse +89 -0
- nse/scripts/pjl-ready-message.nse +106 -0
- nse/scripts/printer-banner.nse +217 -0
- nse/scripts/printer-cups-rce.nse +189 -0
- nse/scripts/printer-cve-detect.nse +279 -0
- nse/scripts/printer-discover.nse +205 -0
- nse/scripts/printer-firmware-exposed.nse +219 -0
- nse/scripts/printer-hp-pjl.nse +192 -0
- nse/scripts/printer-http-ews.nse +293 -0
- nse/scripts/printer-ipp-info.nse +235 -0
- nse/scripts/printer-lexmark-ipp.nse +203 -0
- nse/scripts/printer-passback.nse +204 -0
- nse/scripts/printer-pjl-info.nse +146 -0
- nse/scripts/printer-printnightmare.nse +211 -0
- nse/scripts/printer-snmp-info.nse +176 -0
- nse/scripts/printer-vuln-check.nse +256 -0
- nse/scripts/snmp-device-mac.nse +93 -0
- nse/scripts/snmp-info.nse +146 -0
- nse/scripts/snmp-sysdescr.nse +70 -0
- printerxpl_forge-6.2.0.dist-info/METADATA +919 -0
- printerxpl_forge-6.2.0.dist-info/RECORD +97 -0
- printerxpl_forge-6.2.0.dist-info/WHEEL +5 -0
- printerxpl_forge-6.2.0.dist-info/entry_points.txt +4 -0
- printerxpl_forge-6.2.0.dist-info/licenses/LICENSE +21 -0
- printerxpl_forge-6.2.0.dist-info/top_level.txt +4 -0
- src/assets/fonts/gunplay.pfa +1671 -0
- src/assets/fonts/kshandwrt.pfa +315 -0
- src/assets/fonts/laksoner.pfa +2402 -0
- src/assets/fonts/paintcans.pfa +9699 -0
- src/assets/fonts/stencilod.pfa +4076 -0
- src/assets/fonts/takecover.pfa +26138 -0
- src/assets/fonts/topsecret.pfa +6652 -0
- src/assets/fonts/whoa.pfa +773 -0
- src/assets/mibs/HOST-RESOURCES-MIB +1540 -0
- src/assets/mibs/Printer-MIB +4389 -0
- src/assets/mibs/README.md +9 -0
- src/assets/mibs/SNMPv2-MIB +854 -0
- src/assets/overlays/hacker.eps +596 -0
- src/assets/overlays/smiley.eps +214 -0
- src/assets/overlays/smiley2.eps +240 -0
- src/core/attack_orchestrator.py +1025 -0
- src/core/capabilities.py +323 -0
- src/core/destructive_audit.py +430 -0
- src/core/discovery.py +488 -0
- src/core/osdetect.py +74 -0
- src/core/poly_runner.py +579 -0
- src/core/printer.py +1426 -0
- src/main.py +2134 -0
- src/modules/install_printer.py +318 -0
- src/modules/login_bruteforce.py +852 -0
- src/modules/pcl.py +506 -0
- src/modules/pjl.py +3575 -0
- src/modules/print_job.py +1290 -0
- src/modules/ps.py +1102 -0
- src/payloads/__init__.py +98 -0
- src/payloads/assets/overlays/notice.eps +9 -0
- src/protocols/__init__.py +19 -0
- src/protocols/firmware.py +738 -0
- src/protocols/ipp.py +216 -0
- src/protocols/ipp_attacks.py +609 -0
- src/protocols/lpd.py +141 -0
- src/protocols/network_map.py +1004 -0
- src/protocols/raw.py +173 -0
- src/protocols/smb.py +359 -0
- src/protocols/ssrf_pivot.py +427 -0
- src/protocols/storage.py +587 -0
- src/ui/__init__.py +6 -0
- src/ui/interactive.py +742 -0
- src/ui/spinner.py +112 -0
- src/ui/tables.py +132 -0
- src/utils/banner_grabber.py +852 -0
- src/utils/codebook.py +456 -0
- src/utils/config.py +522 -0
- src/utils/cve_loader.py +158 -0
- src/utils/default_creds.py +134 -0
- src/utils/discovery_online.py +1327 -0
- src/utils/exploit_manager.py +805 -0
- src/utils/fuzzer.py +220 -0
- src/utils/helper.py +732 -0
- src/utils/local_printers.py +307 -0
- src/utils/ml_engine.py +491 -0
- src/utils/operators.py +474 -0
- src/utils/ports.py +234 -0
- src/utils/vuln_scanner.py +823 -0
- src/utils/wordlist_loader.py +412 -0
- src/version.py +36 -0
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
PrinterXPL-Forge — OS Printer Installer
|
|
5
|
+
======================================
|
|
6
|
+
Installs a network printer on the current host using the OS printer subsystem:
|
|
7
|
+
- Windows : Add-Printer / Add-PrinterPort (PowerShell)
|
|
8
|
+
- Linux : CUPS lpadmin
|
|
9
|
+
- macOS : CUPS lpadmin
|
|
10
|
+
|
|
11
|
+
This allows sending print jobs through the OS spooler (which handles format
|
|
12
|
+
conversion, driver rendering and protocol negotiation automatically) instead of
|
|
13
|
+
raw socket communication.
|
|
14
|
+
|
|
15
|
+
Supported driver modes:
|
|
16
|
+
- generic : Microsoft/HP/CUPS generic RAW/text driver (no rendering)
|
|
17
|
+
- auto : let OS auto-detect best driver via IPP/WSD discovery
|
|
18
|
+
- epson : Epson generic inkjet (WF/L/ET series compatible)
|
|
19
|
+
- hp : HP Universal Print Driver (PCL6)
|
|
20
|
+
- cups-ipp : CUPS IPP Everywhere (AirPrint-compatible, recommended for inkjets)
|
|
21
|
+
"""
|
|
22
|
+
# Author : Andre Henrique (@mrhenrike)
|
|
23
|
+
# GitHub : https://github.com/mrhenrike
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
import logging
|
|
28
|
+
import os
|
|
29
|
+
import platform
|
|
30
|
+
import shutil
|
|
31
|
+
import socket
|
|
32
|
+
import subprocess
|
|
33
|
+
import sys
|
|
34
|
+
from dataclasses import dataclass
|
|
35
|
+
from typing import List, Optional
|
|
36
|
+
|
|
37
|
+
_log = logging.getLogger('PrinterXPL-Forge.install_printer')
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dataclass
|
|
41
|
+
class InstallResult:
|
|
42
|
+
"""Result of a printer installation attempt."""
|
|
43
|
+
success: bool
|
|
44
|
+
os_type: str
|
|
45
|
+
printer_name:str
|
|
46
|
+
host: str
|
|
47
|
+
protocol: str
|
|
48
|
+
message: str = ''
|
|
49
|
+
error: str = ''
|
|
50
|
+
hint: str = ''
|
|
51
|
+
commands: List[str] = None # type: ignore[assignment]
|
|
52
|
+
|
|
53
|
+
def __post_init__(self) -> None:
|
|
54
|
+
if self.commands is None:
|
|
55
|
+
self.commands = []
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# ── Helpers ────────────────────────────────────────────────────────────────────
|
|
59
|
+
|
|
60
|
+
def _run(cmd: List[str], timeout: int = 30) -> tuple[int, str, str]:
|
|
61
|
+
"""Run a shell command, return (returncode, stdout, stderr)."""
|
|
62
|
+
try:
|
|
63
|
+
r = subprocess.run(
|
|
64
|
+
cmd, capture_output=True, text=True, timeout=timeout,
|
|
65
|
+
encoding='utf-8', errors='replace',
|
|
66
|
+
)
|
|
67
|
+
return r.returncode, r.stdout.strip(), r.stderr.strip()
|
|
68
|
+
except subprocess.TimeoutExpired:
|
|
69
|
+
return 1, '', 'Command timed out'
|
|
70
|
+
except FileNotFoundError as exc:
|
|
71
|
+
return 1, '', str(exc)
|
|
72
|
+
except OSError as exc:
|
|
73
|
+
return 1, '', str(exc)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _probe_ipp_available(host: str, port: int = 631, timeout: float = 4.0) -> bool:
|
|
77
|
+
"""Quick check: can we reach the printer on port 631?"""
|
|
78
|
+
try:
|
|
79
|
+
with socket.create_connection((host, port), timeout=timeout):
|
|
80
|
+
return True
|
|
81
|
+
except OSError:
|
|
82
|
+
return False
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _safe_name(host: str) -> str:
|
|
86
|
+
"""Generate a safe printer name from the host IP."""
|
|
87
|
+
return f"PrinterXPL-Forge-{host.replace('.', '-')}"
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
# ── Windows ────────────────────────────────────────────────────────────────────
|
|
91
|
+
|
|
92
|
+
_PS_INSTALL_TEMPLATE = r"""
|
|
93
|
+
$ErrorActionPreference = 'Stop'
|
|
94
|
+
$PrinterName = '{name}'
|
|
95
|
+
$PrinterIP = '{host}'
|
|
96
|
+
$PortName = 'IP_{host}'
|
|
97
|
+
$PortType = '{port_type}'
|
|
98
|
+
$DriverName = '{driver}'
|
|
99
|
+
|
|
100
|
+
# Remove existing printer/port with the same name (idempotent)
|
|
101
|
+
Get-Printer -Name $PrinterName -ErrorAction SilentlyContinue | Remove-Printer -ErrorAction SilentlyContinue
|
|
102
|
+
Get-PrinterPort -Name $PortName -ErrorAction SilentlyContinue | Remove-PrinterPort -ErrorAction SilentlyContinue
|
|
103
|
+
|
|
104
|
+
# Create TCP/IP port
|
|
105
|
+
Add-PrinterPort -Name $PortName -PrinterHostAddress $PrinterIP
|
|
106
|
+
|
|
107
|
+
# Add printer
|
|
108
|
+
Add-Printer -Name $PrinterName -DriverName $DriverName -PortName $PortName
|
|
109
|
+
|
|
110
|
+
Write-Host "Printer '$PrinterName' installed successfully."
|
|
111
|
+
Write-Host "To print: Get-Printer -Name '$PrinterName' | Out-Null ; Start-Process notepad /p"
|
|
112
|
+
"""
|
|
113
|
+
|
|
114
|
+
_PS_INSTALL_IPP_TEMPLATE = r"""
|
|
115
|
+
$ErrorActionPreference = 'Stop'
|
|
116
|
+
$PrinterName = '{name}'
|
|
117
|
+
$PrinterIP = '{host}'
|
|
118
|
+
$PortName = 'TCP_{host}'
|
|
119
|
+
|
|
120
|
+
# Remove existing (idempotent)
|
|
121
|
+
Get-Printer -Name $PrinterName -ErrorAction SilentlyContinue | Remove-Printer -ErrorAction SilentlyContinue
|
|
122
|
+
Get-PrinterPort -Name $PortName -ErrorAction SilentlyContinue | Remove-PrinterPort -ErrorAction SilentlyContinue
|
|
123
|
+
|
|
124
|
+
# Create Standard TCP/IP port (port 9100 by default; works for RAW and LPD passthrough)
|
|
125
|
+
Add-PrinterPort -Name $PortName -PrinterHostAddress $PrinterIP
|
|
126
|
+
|
|
127
|
+
# Pick best available driver (Generic / Text Only is always present on Windows)
|
|
128
|
+
$candidates = @('Microsoft IPP Class Driver','Epson Universal Print Driver','Generic / Text Only')
|
|
129
|
+
$driver = 'Generic / Text Only'
|
|
130
|
+
foreach ($d in $candidates) {{
|
|
131
|
+
if (Get-PrinterDriver -Name $d -ErrorAction SilentlyContinue) {{
|
|
132
|
+
$driver = $d; break
|
|
133
|
+
}}
|
|
134
|
+
}}
|
|
135
|
+
|
|
136
|
+
Add-Printer -Name $PrinterName -DriverName $driver -PortName $PortName
|
|
137
|
+
Write-Host "Printer '$PrinterName' installed — driver: $driver port: $PortName"
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
_PS_PRINT_TEST_TEMPLATE = r"""
|
|
141
|
+
$PrinterName = '{name}'
|
|
142
|
+
$TempFile = [System.IO.Path]::GetTempFileName() + '.txt'
|
|
143
|
+
Set-Content -Path $TempFile -Value @"
|
|
144
|
+
PrinterXPL-Forge - Test Page
|
|
145
|
+
=========================
|
|
146
|
+
Target : {host}
|
|
147
|
+
Protocol : {protocol}
|
|
148
|
+
Driver : {driver}
|
|
149
|
+
Date : $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
|
|
150
|
+
"@
|
|
151
|
+
$PrintDoc = New-Object System.Drawing.Printing.PrintDocument
|
|
152
|
+
$PrintDoc.PrinterSettings.PrinterName = $PrinterName
|
|
153
|
+
$PrintDoc.Print()
|
|
154
|
+
Start-Process -FilePath $TempFile -Verb Print -Wait -PassThru | Out-Null
|
|
155
|
+
Remove-Item $TempFile -ErrorAction SilentlyContinue
|
|
156
|
+
Write-Host "Test page sent to '$PrinterName'."
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def _install_windows(host: str, printer_name: str,
|
|
161
|
+
driver_mode: str = 'generic') -> InstallResult:
|
|
162
|
+
"""Install a network printer on Windows using PowerShell cmdlets."""
|
|
163
|
+
ipp_ok = _probe_ipp_available(host)
|
|
164
|
+
|
|
165
|
+
if driver_mode in ('cups-ipp', 'auto') and ipp_ok:
|
|
166
|
+
ipp_uri = f'http://{host}:631/ipp/print'
|
|
167
|
+
ps_script = _PS_INSTALL_IPP_TEMPLATE.format(
|
|
168
|
+
name=printer_name, host=host, ipp_uri=ipp_uri,
|
|
169
|
+
)
|
|
170
|
+
protocol = 'IPP'
|
|
171
|
+
else:
|
|
172
|
+
driver_map = {
|
|
173
|
+
'generic': 'Generic / Text Only',
|
|
174
|
+
'hp': 'HP Universal Printing PCL 6',
|
|
175
|
+
'epson': 'Epson Universal Print Driver',
|
|
176
|
+
'auto': 'Generic / Text Only',
|
|
177
|
+
}
|
|
178
|
+
driver = driver_map.get(driver_mode, 'Generic / Text Only')
|
|
179
|
+
ps_script = _PS_INSTALL_TEMPLATE.format(
|
|
180
|
+
name=printer_name, host=host,
|
|
181
|
+
port_type='Standard TCP/IP Port',
|
|
182
|
+
driver=driver,
|
|
183
|
+
)
|
|
184
|
+
protocol = 'RAW TCP/IP'
|
|
185
|
+
|
|
186
|
+
ps_path = os.path.join(os.environ.get('TEMP', '.'), '_pr_install.ps1')
|
|
187
|
+
try:
|
|
188
|
+
with open(ps_path, 'w', encoding='utf-8') as f:
|
|
189
|
+
f.write(ps_script)
|
|
190
|
+
|
|
191
|
+
rc, out, err = _run(
|
|
192
|
+
['powershell', '-NoProfile', '-ExecutionPolicy', 'Bypass',
|
|
193
|
+
'-File', ps_path],
|
|
194
|
+
timeout=60,
|
|
195
|
+
)
|
|
196
|
+
os.unlink(ps_path)
|
|
197
|
+
|
|
198
|
+
if rc == 0:
|
|
199
|
+
return InstallResult(
|
|
200
|
+
success=True, os_type='Windows',
|
|
201
|
+
printer_name=printer_name, host=host, protocol=protocol,
|
|
202
|
+
message=out or 'Printer installed.',
|
|
203
|
+
hint=(
|
|
204
|
+
f"Print via Start menu → print a document and select '{printer_name}', "
|
|
205
|
+
"or run: Get-PrintJob -PrinterName '{printer_name}'"
|
|
206
|
+
),
|
|
207
|
+
commands=['Get-Printer | Where-Object Name -like "*PrinterXPL-Forge*"'],
|
|
208
|
+
)
|
|
209
|
+
return InstallResult(
|
|
210
|
+
success=False, os_type='Windows',
|
|
211
|
+
printer_name=printer_name, host=host, protocol=protocol,
|
|
212
|
+
error=err or out,
|
|
213
|
+
hint=(
|
|
214
|
+
'Run PowerShell as Administrator and try again. '
|
|
215
|
+
'Also ensure the print spooler service is running: '
|
|
216
|
+
'Start-Service -Name Spooler'
|
|
217
|
+
),
|
|
218
|
+
)
|
|
219
|
+
except Exception as exc:
|
|
220
|
+
return InstallResult(
|
|
221
|
+
success=False, os_type='Windows',
|
|
222
|
+
printer_name=printer_name, host=host, protocol='',
|
|
223
|
+
error=str(exc),
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
# ── Linux / macOS ─────────────────────────────────────────────────────────────
|
|
228
|
+
|
|
229
|
+
def _install_unix(host: str, printer_name: str,
|
|
230
|
+
driver_mode: str = 'generic',
|
|
231
|
+
os_type: str = 'Linux') -> InstallResult:
|
|
232
|
+
"""Install a network printer on Linux/macOS using CUPS lpadmin."""
|
|
233
|
+
lpadmin = shutil.which('lpadmin')
|
|
234
|
+
if not lpadmin:
|
|
235
|
+
return InstallResult(
|
|
236
|
+
success=False, os_type=os_type,
|
|
237
|
+
printer_name=printer_name, host=host, protocol='',
|
|
238
|
+
error='lpadmin not found — CUPS is not installed',
|
|
239
|
+
hint='Install CUPS: apt install cups | brew install cups',
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
ipp_ok = _probe_ipp_available(host)
|
|
243
|
+
if ipp_ok:
|
|
244
|
+
device_uri = f'ipp://{host}/ipp/print'
|
|
245
|
+
ppd_opt = ['-m', 'everywhere'] # IPP Everywhere / AirPrint
|
|
246
|
+
protocol = 'IPP Everywhere'
|
|
247
|
+
else:
|
|
248
|
+
device_uri = f'socket://{host}:9100'
|
|
249
|
+
ppd_opt = ['-m', 'raw']
|
|
250
|
+
protocol = 'RAW socket'
|
|
251
|
+
|
|
252
|
+
cmd = [
|
|
253
|
+
lpadmin, '-p', printer_name,
|
|
254
|
+
'-E', # enable + accept jobs
|
|
255
|
+
'-v', device_uri,
|
|
256
|
+
'-D', f'PrinterXPL-Forge {host}',
|
|
257
|
+
'-L', host,
|
|
258
|
+
] + ppd_opt
|
|
259
|
+
|
|
260
|
+
rc, out, err = _run(cmd, timeout=30)
|
|
261
|
+
cmds_run = [' '.join(cmd)]
|
|
262
|
+
|
|
263
|
+
if rc == 0:
|
|
264
|
+
# Accept and enable
|
|
265
|
+
for sub in (['cupsenable', printer_name], ['cupsaccept', printer_name]):
|
|
266
|
+
_run([shutil.which(sub[0]) or sub[0]] + sub[1:])
|
|
267
|
+
return InstallResult(
|
|
268
|
+
success=True, os_type=os_type,
|
|
269
|
+
printer_name=printer_name, host=host, protocol=protocol,
|
|
270
|
+
message=f"Printer '{printer_name}' installed via CUPS ({protocol})",
|
|
271
|
+
hint=f"Print test: lp -d {printer_name} /etc/hostname",
|
|
272
|
+
commands=cmds_run,
|
|
273
|
+
)
|
|
274
|
+
return InstallResult(
|
|
275
|
+
success=False, os_type=os_type,
|
|
276
|
+
printer_name=printer_name, host=host, protocol=protocol,
|
|
277
|
+
error=err or out,
|
|
278
|
+
hint='Run as root / with sudo. Check CUPS service: systemctl status cups',
|
|
279
|
+
commands=cmds_run,
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
# ── Public API ─────────────────────────────────────────────────────────────────
|
|
284
|
+
|
|
285
|
+
def install_printer(
|
|
286
|
+
host: str,
|
|
287
|
+
name: Optional[str] = None,
|
|
288
|
+
driver_mode: str = 'auto',
|
|
289
|
+
) -> InstallResult:
|
|
290
|
+
"""
|
|
291
|
+
Install a network printer on the current host OS.
|
|
292
|
+
|
|
293
|
+
Args:
|
|
294
|
+
host: Printer IP or hostname.
|
|
295
|
+
name: Printer name (default: auto-generated from IP).
|
|
296
|
+
driver_mode: 'auto' | 'generic' | 'epson' | 'hp' | 'cups-ipp'.
|
|
297
|
+
|
|
298
|
+
Returns:
|
|
299
|
+
InstallResult with .success, .message, .hint.
|
|
300
|
+
"""
|
|
301
|
+
printer_name = name or _safe_name(host)
|
|
302
|
+
system = platform.system()
|
|
303
|
+
|
|
304
|
+
_log.info("Installing printer '%s' (%s) on %s", printer_name, host, system)
|
|
305
|
+
|
|
306
|
+
if system == 'Windows':
|
|
307
|
+
return _install_windows(host, printer_name, driver_mode)
|
|
308
|
+
if system == 'Darwin':
|
|
309
|
+
return _install_unix(host, printer_name, driver_mode, os_type='macOS')
|
|
310
|
+
if system == 'Linux':
|
|
311
|
+
return _install_unix(host, printer_name, driver_mode, os_type='Linux')
|
|
312
|
+
|
|
313
|
+
return InstallResult(
|
|
314
|
+
success=False, os_type=system,
|
|
315
|
+
printer_name=printer_name, host=host, protocol='',
|
|
316
|
+
error=f"Unsupported OS: {system}",
|
|
317
|
+
hint='Supported: Windows, Linux, macOS',
|
|
318
|
+
)
|