Talos Vulnerability Report

TALOS-2018-0695

Novatek NT9665X XML_UploadFile path overflow code execution vulnerability

May 13, 2019
CVE Number

CVE-2018-4023

Summary

An exploitable code execution vulnerability exists in the XML_UploadFile Wi-Fi command of the NT9665X Chipset firmware, running on the Anker Roav A1 Dashcam, version "RoavA1SWV1.9". A specially crafted packet can cause a stack-based buffer overflow, resulting in code execution.

Tested Versions

Anker Roav A1 Dashcam RoavA1SWV1.9

Product URLs

https://goroav.com/products/roav-dash-cam-a1

CVSSv3 Score

10.0 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H

CWE

CWE-121: Stack-based Buffer Overflow

Details

The Novatek NT9665X SOC is a chipset used in an large number of consumer camera devices, particularly in dashboard cameras. The chip provides default firmware that is a fork of the Embedded Configurable Operating System (eCOS) project, which is found within the Roav A1 Dashcam,the product we are focusing on in this advisory.

The Roav A1 Dashcam by Anker is a dashboard camera that allows users to connect using the Roav app for Android and iOS and control the camera remotely. In order to do this, users must first enable the “Wi-Fi AP” setting manually on the dashcam, and then connect to the “RoavA1” SSID, with the default password of “goroavcam.”

From here, the app interacts with the dashcam via an eCOS webserver running on port 80 that requires no authentication. The standard HTTP POST, GET, and DELETE requests can be used to upload, download, or delete videos and pictures from the dashcam, but there’s also a separate interface used for configuration. The camera accesses a set of commands when requesting any URL after providing the following HTTP query string: ?custom=1&cmd=<0000-9999>. It should be noted that only a firmware-specific subset of commands are implemented on any given device, the list of which is found here: http://192.168.1.254/?custom=1&cmd=3012.

The XML_UploadFile command (5001) is covered in this vulnerability. This particular command is not just found in the Roav line of dashcams, but seems to be a default command in the Novatek NT9665X firmware. Note, however, that while this command shows up in all the NT9665X devices, the device in question might not be vulnerable, as certain devices (e.g. The SJ6 Camera) contain extra checks to avoid the issue.

When using any of the Wi-Fi command functions on the Roav A1, the first parameter $a0 is always the path provided by the user, with the current guess at the full prototype being: wifiCmd(URLPath,QueryStr,POSTData,POSTDataLen,???,???). When utilizing the XML_UploadFile command, the URLPath of the HTTP request is passed into the function dubbed fixup_path(src,dst) as the src parameter. This function essentially just copies the data at src to the buffer at dst, as one would expect, but with the changes of prepending “A:,” and changing all forward slashes to backslashes. The relevant loop of the short function is:

ROM:80221BA0                 addu    $v0, $s1, $v0
ROM:80221BA4                 li      $a0, "/"
ROM:80221BA8                 li      $a1, "\"
ROM:80221BAC
ROM:80221BAC loc_80221BAC:   # CODE XREF: fixup_path+58↓j
ROM:80221BAC                 beql    $v1, $a0, loc_80221BB8
ROM:80221BB0                 sb      $a1, 0($v0)    //[1]
ROM:80221BB4                 sb      $v1, 0($v0)    //[2]
ROM:80221BB8
ROM:80221BB8 loc_80221BB8:   # CODE XREF: fixup_path:loc_80221BAC↑j
ROM:80221BB8                 addiu   $s0, 1
ROM:80221BBC                 lbu     $v1, 0($s0)
ROM:80221BC0                 bnez    $v1, loc_80221BAC //[3]
ROM:80221BC4                 addiu   $v0, 1 

At [1] we see the char substitution, and at [2] where the non-slash characters are copied. Most importantly, at [3] we see a complete lack of bounds checking, and the function only returns upon finding a null byte.

The issue then lies in the exact type of buffer being filled. If we trace backward into the XML_UploadFile function, we can see the following:

ROM:80221EA4  move    $a0, $s5         //[4]
ROM:80221EA8  jal     fixup_path       # 
ROM:80221EAC  move    $a1, $s7

Where $s5 is the original HTTP URLPath provided, and $s7 is assigned to point to a size 0x80 buffer on the stack at:

ROM:80221EA0  addiu  buff_0x80, $fp, 0xE8+Size_0x80_StackBuff

This allows an attacker to arbitrarily control code execution with a size 0x9E buffer, the last four bytes being the return address.

Crash Output

WifiCmd_DispatchCmd(): cmd:5001 evt:0 par:0 CB:80221be8 wait:0
WifiCmd_DispatchCmd(): ret 0
USB 1.5A
CONNECT to CHARGER
uiUsage=1
CHK: 2306, XML_UploadFile
ERR:fs_interfopen() pathDeep:69(Limit:1~7), pathLeng:168(Limit:3~131)
ERR:FileSys_SeekFile() pFile is NULL
CHK: 2314, XML_UploadFile
ERR:FileSys_SeekFile() pFile is NULL
ERR:FST_CMDWriteFile() Invalid file handle 0x0
CHK: 2330, XML_UploadFile
*** CPU Exception!!! cause 0x04: Address error exception (load or instruction fetch)
epc  - 0x39383736
$ra  - 0x39383736
$sp  - 0x80d424d0
$fp  - 0x33333232
general registers:
     $zero : 0x00000000       $at : 0x00000008       $v0 : 0x00000000       $v1 : 0x0000000c
       $a0 : 0x806774c8       $a1 : 0xf0a3bde8       $a2 : 0xf0a3bde8       $a3 : 0x00000008
       $t0 : 0x00000008       $t1 : 0x01010101       $t2 : 0x80d3ceb4       $t3 : 0x00000012
       $t4 : 0x00000008       $t5 : 0x807d2bb4       $t6 : 0x00000017       $t7 : 0x00000002
       $s0 : 0x61616161       $s1 : 0x61616161       $s2 : 0x62626261       $s3 : 0x62626262
       $s4 : 0x63626262       $s5 : 0x64636363       $s6 : 0x65646464       $s7 : 0x32326565
       $t8 : 0x80033e90       $t9 : 0x00003000      null : 0x5c5c5c5c      null : 0x5c5c5c5c
        gp : 0x8060f540        sp : 0x80d424d0        fp : 0x33333232        ra : 0x39383736
co-processor registers:
   entrylo : 0x00000002    status : 0x00000010    vector : 0x0100c403       epc : 0x39383736
     cause : 0x00000000  badvaddr : 0x10800010    hwrena : 0x39383736      prid : 0x00019655
   entrylo : 0x01645792
Thread(id) :

  Hfs Session(260)
stack      :
    range(0x80d3ce94 - 0x80d42e94)
call stack :
    :
  abort ($pc 39383736 is invalid address!)
*** CPU Exception in Task[]! cause=0x00000004, addr=0x39383736

Timeline

2018-10-29 - Talos contacts vendor
2018-11-02 - Report disclosed to vendor
2018-12-04 - 30 day follow up
2019-01-18 - 60 day follow up - Talos reaches out to TWNCERT for assistance reaching vendor (Novatek)>br> 2019-01-22 - TWNCERT contacted Novatek and advised Novatek will check emails for reports
2019-03-06 - 90+ day follow up - Talos asks TWNCERT for direct point of contact for Novatek
2019-03-27 - Talos sends follow up to TWNCERT
2019-04-02 - Talos sends copies of email correspondence and reports to TWNCERT
2019-04-18 - Suggested pubic disclosure date of 2019-05-13 (171 days after initial disclosure)
2019-04-19 - Vendor fixed issue and provided patch to their IDH
2019-05-13 - Public disclosure

Credit

Discovered by Lilith [<_<] of Cisco Talos.