hacktricks/network-services-pentesting/pentesting-printers/accounting-bypass.md

8.4 KiB
Raw Blame History

零基础学习AWS黑客攻击到高级技巧 htARTE (HackTricks AWS Red Team Expert)

支持HackTricks的其他方式

介绍

未经许可的打印本身可能是一个安全风险或违反公司政策。在打印作业需要收费的环境中,内部攻击者有动机绕过计费系统。此外,能够‘打印’是针对网络打印机的大多数攻击的先决条件。

在打印作业计费方面有两种主要方法:要么直接让打印机处理,要么使用打印服务器作为中介。第一种方法是特定于供应商的,通常涉及某种特殊的‘打印机驱动程序’,在此不再讨论。另一种方法涉及使用单独的打印服务器 - 通常是像CUPSLPRng这样的软件实现 - 来处理计费这在公司和机构中非常常见。打印服务器可能使用LPD、IPP或其他打印协议并将作业转发给实际的打印机。重要的是要注意,必须限制对打印机的直接网络访问,否则攻击者可以轻松绕过打印服务器及其计费机制。这意味着要过滤对典型和非典型端口LPD、IPP、raw、HTTP、SMB、FTP、SNMP的访问。

基本上有两种方法来规避打印作业计费系统:要么冒充另一个用户,要么操纵打印页数的计数器。以下针对LPRngv3.8.B和CUPSv2.1.4)安装进行了讨论,这些是在学术和企业环境中使用的流行开源打印系统。下面给出了两种系统的安全功能比较。

打印系统 协议 加密 认证 页数计数器
LPRng LPD SSL/TLS Kerberos, PGP 硬件
CUPS IPP SSL/TLS Kerberos, HTTP 软件

认证绕过

LPRng和CUPS都提供基于SSL的通道加密和像KerberosPGP签名打印作业或HTTP 基本/摘要认证的安全认证方案。如果配置得当,并且攻击者无法直接访问打印机,她将无法冒充其他用户。然而,这些安全功能是可选的,而且在现实世界的打印服务器中很少应用。相反作为LPDLPRng或IPPCUPS参数给出的用户名被记录和计费 - 这可以由客户端设置为任意值。这样做的原因是大多数机构的简单成本效益考虑:Kerberos需要在每个客户端上进行特殊设置,而HTTP认证要求用户在想要打印某些东西时输入密码,而少量未计费的打印输出的成本是可以承受的。

您可以尝试使用自定义用户名打印来验证适当的认证,如下所示:

lp -U nobody test.ps

页面计数器操纵

硬件页面计数器

为了正确的计费,必须由打印系统确定打印的页面数量,这不是一项简单的任务。LPRng 的作者们_假设打印机具有某种非易失性页面计数器机制该机制可靠且不受开/关电源周期的影响_。这种硬件页面计数器得到了大多数打印机的支持,并且在每次打印作业后通过LPRng 使用PJL读取HP甚至记录了一项通过将打印机置于服务模式来写入页面计数器变量的功能。通过这种方式,HP LaserJet 1200、HP LaserJet 4200NHP LaserJet 4250N页面计数器可以在打印作业中被操纵。在要打印的文档的末尾,并通过UEL分隔,只需将计数器重置为其原始值(例如,2342

\x1b%-12345X@PJL JOB
This page was printed for free
\x1b%-12345X@PJL EOJ
\x1b%-12345X@PJL JOB
@PJL SET SERVICEMODE=HPBOISEID
@PJL SET PAGES=2342
\x1b%-12345X@PJL EOJ

攻击者可能会设置打印页数为负数。请注意,将设备重置为出厂默认设置也会在某些测试设备上将页面计数器重置为零
降低页面计数器也可以用来以高于其价值的价格出售打印机,这可以与购买二手车时的里程表相比较。然而,值得强调的是,重置页面计数器并不一定是出于恶意目的:出售价格过高的墨水给低成本的喷墨打印设备,并通过拒绝在打印一定数量的页面后使用第三方补充套件来封锁,是一个众所周知的商业模式——为了处理这种不道德的做法,重置页面计数器是完全合理的。

在较旧的HP激光打印机上可以使用PRETpagecount命令来轻松设置硬件页面计数器:

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

Welcome to the pret shell. Type help or ? to list commands.
printer:/> pagecount 10
Old pagecounter: 53214
New pagecounter: 10

软件页面计数器

CUPS 使用了为所有主要页面描述语言实现的软件页面计数器。对于PostScript绕过计数的一种简单方法是在实际打印文档之前检查PageCount系统参数是否存在——在CUPS/Ghostscript中解释时会返回false如下所示。

currentsystemparams (PageCount) known {
<@\textit{[...] code which is only executed on a printer device [...]}@>
} if

这种方式下CUPS 使用的计费软件渲染的文档与打印机的不同。CUPS 只计算一页 —— 这似乎是一个硬编码的最小值 —— 而实际的打印作业可能包含数百 。请注意,使用 IPP 的raw队列/选项是必须的,否则 CUPS 会在作业到达页面计数器之前,使用 PostScript 到 PostScript 过滤器Ghostscript 的 ps2write解析代码。

如何测试这种攻击?

任意多页 PostScript 文档包裹在上述代码中并打印。然后访问 http://printserver:631/jobs?which_jobs=all 并检查 CUPS 的页面计数器对于这个打印作业的记录。请注意,你必须建立一个 raw 队列。也就是说,一个不涉及过滤系统的队列,打印作业直接发送到打印机。对于 CUPS这是通过将内容类型设置为 application/vnd.cups-raw 来完成的。如果你的系统已经配置为使用要测试的打印服务器,只需使用:

lp -o raw test.ps
从零到英雄学习AWS黑客技术通过 htARTE (HackTricks AWS Red Team Expert)

支持HackTricks的其他方式