Printer Discovery and Authorized Assessment
#Common Services
| Port | Protocol | Typical Use |
|---|---|---|
| 80/443 | HTTP/HTTPS | Administrative web console |
| 161/udp | SNMP | Device identity, counters, supplies, interfaces |
| 445 | SMB | Windows print sharing |
| 515 | LPD | Legacy print service |
| 631 | IPP/IPPS | Printer attributes and job service |
| 9100 | JetDirect/AppSocket | Raw printing and PJL-capable service |
#Paste-Ready Discovery Script
This script accepts a reviewed file of printer candidates. It does not submit jobs, change settings, upload firmware, retrieve stored documents, or attempt credential lists.
#!/usr/bin/env bash
set -Eeuo pipefail
umask 077
[[ $# -eq 1 ]] || { echo "Usage: $0 <approved-printer-targets.txt>"; exit 1; }
TARGETS="$(realpath "$1")"
[[ -s "$TARGETS" ]] || { echo "Target file is empty"; exit 1; }
[[ -n "${ENGAGEMENT_ROOT:-}" ]] || { echo "Load engagement.env first"; exit 1; }
for tool in nmap curl; do
command -v "$tool" >/dev/null 2>&1 || { echo "Missing dependency: $tool"; exit 1; }
done
OUT="$RAW_DIR/printers-$(date -u +%Y%m%dT%H%M%SZ)"
mkdir -p "$OUT"/{nmap,snmp,ipp,http,pjl}
nmap -Pn -sS -sU -p T:80,443,445,515,631,9100,U:161 \
-sV --version-light -iL "$TARGETS" -oA "$OUT/nmap/printer-services"
while IFS= read -r host; do
[[ -z "$host" ]] && continue
id="${host//[:.]/_}"
curl -ksS --max-time 8 -D "$OUT/http/$id-http.headers" \
-o "$OUT/http/$id-http.html" "http://$host/" || true
curl -ksS --max-time 8 -D "$OUT/http/$id-https.headers" \
-o "$OUT/http/$id-https.html" "https://$host/" || true
if command -v ipptool >/dev/null 2>&1; then
ipptool -tv "ipp://$host/ipp/print" get-printer-attributes.test \
> "$OUT/ipp/$id.txt" 2>&1 || true
fi
if command -v snmpwalk >/dev/null 2>&1; then
# Use only an engagement-approved community string.
COMMUNITY="${SNMP_COMMUNITY:-public}"
snmpwalk -v2c -c "$COMMUNITY" -t 2 -r 1 "$host" 1.3.6.1.2.1.1 \
> "$OUT/snmp/$id-system.txt" 2>&1 || true
snmpwalk -v2c -c "$COMMUNITY" -t 2 -r 1 "$host" 1.3.6.1.2.1.43 \
> "$OUT/snmp/$id-printer-mib.txt" 2>&1 || true
fi
# PJL INFO queries are read-only. Timeout prevents a hanging raw socket.
if command -v nc >/dev/null 2>&1; then
printf '\033%%-12345X@PJL\r\n@PJL INFO ID\r\n@PJL INFO CONFIG\r\n\033%%-12345X' \
| timeout 5 nc "$host" 9100 > "$OUT/pjl/$id.txt" 2>&1 || true
fi
done < "$TARGETS"
echo "Printer evidence: $OUT"
BASH
#Manual Validation Checklist
- Record manufacturer, model, serial number, firmware, hostname, and exposed protocols.
- Verify whether SNMPv1/v2c is enabled and whether the approved community exposes sensitive inventory.
- Check whether IPP exposes unauthenticated printer attributes.
- Review TLS certificate validity and administrative console transport security.
- Test only engagement-provided default or site-standard credentials, one device at a time, and record the attempt.
- Confirm SMB signing and whether print shares are intentionally exposed.
- Compare firmware versions with vendor advisories without uploading or downgrading firmware.
#Excluded Actions
- Printing test pages without approval.
- Accessing queued or stored jobs.
- Filesystem traversal through PJL.
- Firmware upload, configuration changes, factory reset, or denial of service.
- Broad credential spraying.
Potential findings should be validated manually and mapped into Identifying Vulnerable Services.