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
src/protocols/ipp.py
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
IPP Protocol Support for PrinterXPL-Forge
|
|
5
|
+
======================================
|
|
6
|
+
Internet Printing Protocol (RFC 2910/2911) on port 631
|
|
7
|
+
|
|
8
|
+
Modern HTTP-based printing protocol.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
# Author : Andre Henrique (@mrhenrike)
|
|
12
|
+
# GitHub : https://github.com/mrhenrike
|
|
13
|
+
# LinkedIn : https://linkedin.com/in/mrhenrike
|
|
14
|
+
# X/Twitter : https://x.com/mrhenrike
|
|
15
|
+
|
|
16
|
+
import socket
|
|
17
|
+
import struct
|
|
18
|
+
import time
|
|
19
|
+
|
|
20
|
+
class IPPProtocol:
|
|
21
|
+
"""
|
|
22
|
+
IPP protocol implementation (Port 631)
|
|
23
|
+
Internet Printing Protocol - Modern HTTP-based protocol
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
DEFAULT_PORT = 631
|
|
27
|
+
|
|
28
|
+
# IPP versions
|
|
29
|
+
IPP_VERSION_1_0 = (1, 0)
|
|
30
|
+
IPP_VERSION_1_1 = (1, 1)
|
|
31
|
+
IPP_VERSION_2_0 = (2, 0)
|
|
32
|
+
|
|
33
|
+
# IPP operations
|
|
34
|
+
PRINT_JOB = 0x0002
|
|
35
|
+
GET_PRINTER_ATTRIBUTES = 0x000B
|
|
36
|
+
GET_JOBS = 0x000A
|
|
37
|
+
|
|
38
|
+
# IPP status codes
|
|
39
|
+
STATUS_OK = 0x0000
|
|
40
|
+
STATUS_CLIENT_ERROR = 0x0400
|
|
41
|
+
STATUS_SERVER_ERROR = 0x0500
|
|
42
|
+
|
|
43
|
+
def __init__(self, host, port=None, timeout=30):
|
|
44
|
+
self.host = host
|
|
45
|
+
self.port = port or self.DEFAULT_PORT
|
|
46
|
+
self.timeout = timeout
|
|
47
|
+
self.sock = None
|
|
48
|
+
self.request_id = 1
|
|
49
|
+
|
|
50
|
+
def connect(self):
|
|
51
|
+
"""Establish IPP connection (HTTP)"""
|
|
52
|
+
try:
|
|
53
|
+
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
54
|
+
self.sock.settimeout(self.timeout)
|
|
55
|
+
self.sock.connect((self.host, self.port))
|
|
56
|
+
return True
|
|
57
|
+
except Exception as e:
|
|
58
|
+
return False
|
|
59
|
+
|
|
60
|
+
def build_ipp_request(self, operation, attributes=None):
|
|
61
|
+
"""
|
|
62
|
+
Build IPP request packet
|
|
63
|
+
|
|
64
|
+
Format:
|
|
65
|
+
- Version (2 bytes)
|
|
66
|
+
- Operation ID (2 bytes)
|
|
67
|
+
- Request ID (4 bytes)
|
|
68
|
+
- Attributes
|
|
69
|
+
- End of attributes tag (0x03)
|
|
70
|
+
"""
|
|
71
|
+
version = struct.pack('>BB', 1, 1) # IPP 1.1
|
|
72
|
+
op_id = struct.pack('>H', operation)
|
|
73
|
+
req_id = struct.pack('>I', self.request_id)
|
|
74
|
+
self.request_id += 1
|
|
75
|
+
|
|
76
|
+
packet = version + op_id + req_id
|
|
77
|
+
|
|
78
|
+
# Add attributes if provided
|
|
79
|
+
if attributes:
|
|
80
|
+
packet += attributes
|
|
81
|
+
|
|
82
|
+
# End of attributes
|
|
83
|
+
packet += b'\\x03'
|
|
84
|
+
|
|
85
|
+
return packet
|
|
86
|
+
|
|
87
|
+
def add_attribute(self, tag, name, value):
|
|
88
|
+
"""Add IPP attribute to request"""
|
|
89
|
+
attr = struct.pack('>B', tag)
|
|
90
|
+
attr += struct.pack('>H', len(name))
|
|
91
|
+
attr += name.encode()
|
|
92
|
+
|
|
93
|
+
if value:
|
|
94
|
+
attr += struct.pack('>H', len(value))
|
|
95
|
+
attr += value.encode() if isinstance(value, str) else value
|
|
96
|
+
|
|
97
|
+
return attr
|
|
98
|
+
|
|
99
|
+
def get_printer_attributes(self):
|
|
100
|
+
"""Get printer attributes via IPP"""
|
|
101
|
+
if not self.sock:
|
|
102
|
+
if not self.connect():
|
|
103
|
+
raise ConnectionError("Failed to connect")
|
|
104
|
+
|
|
105
|
+
# Build GET-PRINTER-ATTRIBUTES request
|
|
106
|
+
attrs = b''
|
|
107
|
+
attrs += self.add_attribute(0x01, "attributes-charset", "utf-8")
|
|
108
|
+
attrs += self.add_attribute(0x48, "attributes-natural-language", "en")
|
|
109
|
+
attrs += self.add_attribute(0x45, "printer-uri", f"ipp://{self.host}/ipp/")
|
|
110
|
+
attrs += self.add_attribute(0x44, "requested-attributes", "all")
|
|
111
|
+
|
|
112
|
+
request = self.build_ipp_request(self.GET_PRINTER_ATTRIBUTES, attrs)
|
|
113
|
+
|
|
114
|
+
# Send HTTP POST
|
|
115
|
+
http_request = (
|
|
116
|
+
f"POST /ipp/ HTTP/1.1\\r\\n"
|
|
117
|
+
f"Host: {self.host}:{self.port}\\r\\n"
|
|
118
|
+
f"Content-Type: application/ipp\\r\\n"
|
|
119
|
+
f"Content-Length: {len(request)}\\r\\n"
|
|
120
|
+
f"\\r\\n"
|
|
121
|
+
).encode() + request
|
|
122
|
+
|
|
123
|
+
self.sock.send(http_request)
|
|
124
|
+
|
|
125
|
+
# Receive response
|
|
126
|
+
response = b""
|
|
127
|
+
while True:
|
|
128
|
+
try:
|
|
129
|
+
chunk = self.sock.recv(4096)
|
|
130
|
+
if not chunk:
|
|
131
|
+
break
|
|
132
|
+
response += chunk
|
|
133
|
+
if b'\\r\\n\\r\\n' in response and len(response) > 100:
|
|
134
|
+
break
|
|
135
|
+
except socket.timeout:
|
|
136
|
+
break
|
|
137
|
+
|
|
138
|
+
return response
|
|
139
|
+
|
|
140
|
+
def parse_printer_attributes(self, response):
|
|
141
|
+
"""Parse IPP response to extract printer attributes"""
|
|
142
|
+
try:
|
|
143
|
+
# Split HTTP headers and body
|
|
144
|
+
if b'\\r\\n\\r\\n' in response:
|
|
145
|
+
headers, body = response.split(b'\\r\\n\\r\\n', 1)
|
|
146
|
+
else:
|
|
147
|
+
body = response
|
|
148
|
+
|
|
149
|
+
# Parse IPP response
|
|
150
|
+
# This is simplified - full IPP parsing is complex
|
|
151
|
+
attrs = {}
|
|
152
|
+
|
|
153
|
+
# Look for common patterns
|
|
154
|
+
if b'MDL:' in body:
|
|
155
|
+
model = re.findall(b'MDL:([^;]+);', body)
|
|
156
|
+
if model:
|
|
157
|
+
attrs['model'] = model[0].decode('latin-1')
|
|
158
|
+
|
|
159
|
+
if b'CMD:' in body:
|
|
160
|
+
commands = re.findall(b'CMD:([^;]+);', body)
|
|
161
|
+
if commands:
|
|
162
|
+
attrs['commands'] = commands[0].decode('latin-1')
|
|
163
|
+
|
|
164
|
+
return attrs
|
|
165
|
+
|
|
166
|
+
except Exception as e:
|
|
167
|
+
return {}
|
|
168
|
+
|
|
169
|
+
def print_job(self, data, job_name="PrinterXPL-Forge_job"):
|
|
170
|
+
"""Print job via IPP"""
|
|
171
|
+
if not self.sock:
|
|
172
|
+
if not self.connect():
|
|
173
|
+
raise ConnectionError("Failed to connect")
|
|
174
|
+
|
|
175
|
+
# Build PRINT-JOB request
|
|
176
|
+
attrs = b''
|
|
177
|
+
attrs += self.add_attribute(0x01, "attributes-charset", "utf-8")
|
|
178
|
+
attrs += self.add_attribute(0x48, "attributes-natural-language", "en")
|
|
179
|
+
attrs += self.add_attribute(0x45, "printer-uri", f"ipp://{self.host}/ipp/")
|
|
180
|
+
attrs += self.add_attribute(0x42, "job-name", job_name)
|
|
181
|
+
|
|
182
|
+
request = self.build_ipp_request(self.PRINT_JOB, attrs)
|
|
183
|
+
|
|
184
|
+
# Add document data
|
|
185
|
+
if isinstance(data, str):
|
|
186
|
+
data = data.encode()
|
|
187
|
+
request += data
|
|
188
|
+
|
|
189
|
+
# Send HTTP POST
|
|
190
|
+
http_request = (
|
|
191
|
+
f"POST /ipp/ HTTP/1.1\\r\\n"
|
|
192
|
+
f"Host: {self.host}:{self.port}\\r\\n"
|
|
193
|
+
f"Content-Type: application/ipp\\r\\n"
|
|
194
|
+
f"Content-Length: {len(request)}\\r\\n"
|
|
195
|
+
f"\\r\\n"
|
|
196
|
+
).encode() + request
|
|
197
|
+
|
|
198
|
+
self.sock.send(http_request)
|
|
199
|
+
|
|
200
|
+
# Receive response
|
|
201
|
+
response = self.sock.recv(4096)
|
|
202
|
+
return response
|
|
203
|
+
|
|
204
|
+
def close(self):
|
|
205
|
+
"""Close IPP connection"""
|
|
206
|
+
if self.sock:
|
|
207
|
+
self.sock.close()
|
|
208
|
+
self.sock = None
|
|
209
|
+
|
|
210
|
+
def __enter__(self):
|
|
211
|
+
self.connect()
|
|
212
|
+
return self
|
|
213
|
+
|
|
214
|
+
def __exit__(self, *args):
|
|
215
|
+
self.close()
|
|
216
|
+
|