Printers are important in Santa’s workshops, but we haven’t really tried to secure them! The Grinch and his team of elite hackers may try and use this against us! Please investigate using the packet capture provided! The printer server IP Address is 192.168.68.128
One internal host flooded a network printer with traffic after scanning it, and found only the raw print port open. Over that port the attacker spoke PJL, the printer’s own control language, to read the device identity and browse and download files from its internal file system. That gave them confidential print material, including a list of children, a staff dismissal notice and a scheduled job, and, most importantly, an SSH private key stored on the printer. The key’s comment named a separate critical server that was supposed to accept key-only SSH, which is how the printer compromise became a lateral move. The attacker also tried to delete a file from the printer before leaving.
tshark, and Wireshark’s Follow TCP Stream for the PJL conversations7z, not unzipTimestamp note:
tsharkprints capture times in the local zone of the capture (+11:00). Q10 asks for UTC, so subtract 11 hours.
The zip is AES encrypted (method 99), so plain unzip fails. Extract it with 7-Zip and HTB’s standard archive password, then pull the IP conversation table. Only one host talks to the printer at 192.168.68.128, and it dominates the byte count.
7z x -phacktheblue evidence.zip -owork/pcap
tshark -r work/pcap/capture.pcap -q -z conv,ip
From Q1 the scanner is known. A scan leaves a burst of SYNs to many ports, but only open ports answer with SYN/ACK. Filter for SYN/ACK from the printer and one port stands out, and it is also the one carrying the long PJL streams in the protocol hierarchy.
tshark -r work/pcap/capture.pcap -Y 'ip.src==192.168.68.128 && tcp.flags.syn==1 && tcp.flags.ack==1' -T fields -e tcp.srcport | sort | uniq -c
Follow the TCP streams to port 9100. The attacker’s PJL @PJL INFO ID request is answered with the printer’s model string.
tshark -r work/pcap/capture.pcap -q -z follow,tcp,ascii,0
Hint: The format mask (
********* ** ******** ****n) is the shape of the model string, including the vendor prefix the workshop gave it.
PJL has file-system commands (FSDIRLIST, FSUPLOAD, FSDELETE). Walk the port 9100 streams for FSUPLOAD calls and look for the nice-kids path. The upload of Nice-kids/list1.txt returns the list, and the second entry is the answer.
tshark -r work/pcap/capture.pcap -q -z follow,tcp,ascii,28
The job file is a PCL document, Personal-Notice-Employee43.pcl, uploaded in one of the later streams. The reason is plain text inside the PCL body, so follow that stream and copy the sentence exactly, spacing and the odd space before the comma included.
tshark -r work/pcap/capture.pcap -q -z follow,tcp,ascii,46
Gotcha: The format asks for the full string, so partial quotes fail. Copy it exactly as printed, including its spelling and punctuation.
A second uploaded file sits under ScheduledJobs/ as Announcment-25Dec.ps. Inside it, the @PJL JOB NAME line carries the job name.
tshark -r work/pcap/capture.pcap -q -z follow,tcp,ascii,71
Gotcha: Two strings are tempting here: the file name and the
JOB NAMEvalue. The question asks for the job, so use theJOB NAMEvalue.
A key-only SSH server falls to a stolen private key. Search the PJL traffic for key material and follow the stream that holds it. The FSUPLOAD request names the full path, and the response body is an RSA private key.
tshark -r work/pcap/capture.pcap -q -z follow,tcp,ascii,46
The directory listing the attacker requested before the download reports each file’s size. The FSDIRLIST response for the ssh_systems folder lists id_rsa with its SIZE= value.
tshark -r work/pcap/capture.pcap -q -z follow,tcp,ascii,46 | grep -a 'SIZE='
The server name is in the stolen key itself. Dump the key from the stream and read its trailing comment, which labels it as a backup key for the target host. This was reasoned from that comment rather than read from an observed SSH login, since the capture only shows the key leaving the printer.
grep -a -i -E 'BEGIN|backup key' work/pcap/capture.txt
Filter for the PJL FSDELETE command and take the frame’s capture time. It is frame 3676 at 23:18:14 on the capture’s +11:00 clock, which is 12:18:14 UTC.
tshark -r work/pcap/capture.pcap -Y 'frame.number==3676' -T fields -e frame.time
Gotcha:
tsharkshows local time. Submitting the printed 23:18:14 is wrong; the answer needs the 11 hour shift back to UTC.
| Phase | Action |
|---|---|
| Discovery | Internal host 172.17.79.133 floods and port-scans the printer |
| Initial Access | Raw print service on port 9100 used to issue PJL commands |
| Discovery | @PJL INFO ID reveals the printer model |
| Collection | FSUPLOAD pulls the nice list, a dismissal notice and a scheduled job file |
| Credential Access | SSH private key downloaded from the printer’s file system |
| Lateral Movement | Key used toward the key-only server named in its comment |
| Defense Evasion | FSDELETE attempted against a file on the printer |
| Type | Value |
|---|---|
| IP (attacker) | 172.17[.]79[.]133 |
| IP (printer) | 192.168.68[.]128 |
| Port | 9100/tcp |
| File (stolen key) | /Administration/securitykeys/ssh_systems/id_rsa |
| File | Personal-Notice-Employee43.pcl |
| File | ScheduledJobs/Announcment-25Dec.ps |
| Hostname (target) | christmas[.]gifts |
| Technique | ID | Description |
|---|---|---|
| Network Service Discovery | T1046 | Port scan of the printer |
| Exploit Public-Facing Application | T1190 | Unauthenticated PJL access over port 9100 |
| Data from Local System | T1005 | FSUPLOAD of print jobs and lists from the printer file system |
| Unsecured Credentials: Private Keys | T1552.004 | SSH private key stored on the printer |
| Remote Services: SSH | T1021.004 | Stolen key aimed at a key-only server |
| Indicator Removal: File Deletion | T1070.004 | FSDELETE against a printer file |
Raw port 9100 should not be reachable from general user networks. Any host that can reach it can run PJL file-system commands with no authentication. Restrict it to the print server, and disable PJL file-system access in the printer configuration.
Never store SSH keys on a printer. A key in a device’s file share is a credential an attacker can read with one PJL command. Keep keys off appliances, and rotate any key that has been on one.
Key-only SSH is only as strong as the key’s storage. The critical server’s hardening was bypassed by the key, not by guessing a password. Bind keys to source addresses and alert on key use from unexpected hosts.
Treat printers as monitored assets. A single host with a scan followed by a long 9100 stream is visible in flow data. Alert on high byte counts to printers from a non-print-server source.
The Grinch turned an unmanaged printer into a file server, took an SSH key from it and aimed it at a server that was supposed to be safe behind key-only authentication. The printer’s unauthenticated control language was the whole breach; the hardened server never had a chance once its key was lying on the device.