First part of a blog post series about our approach to reverse engineer a Philips TriMedia based IP camera.

Introduction

Bonjour à tout le monde !

This is a three parts blog post series in which I'm going to talk about a barely known CPU architecture: Philips TriMedia. This is still an ongoing project in which a first version was already presented at Ekoparty 2018 and was selected for BlackHat Europe 2018. Unfortunately, I couldn't make it for BH for personal reasons but an updated version of the talk is going to be presented at Troopers19.

This first part is an introduction to the research project, the first steps that I followed when I found the device and what happened after. The second part will focus more on the architecture itself and the third part will talk about the TriMedia assembly. I hope you like it. Any feedback is welcome, just drop me a line at ncriva [at] quarkslab.com or buzz me on TW (@crackinglandia).

Tell the story, bro!

Some years ago, a co-worker, Francisco Falcon, and I did a presentation at hack.lu and Ekoparty about hacking IP cameras. That was my first contact with the embedded world. We had a lot of fun and from that moment on, IoT became a very interesting topic for me. That way, each time I got some device, I had to open it and study it.

Some months ago, I got a D-Link IP camera, specifically, a DCS-5300. It is an end user's IP camera, mostly for home users to watch what's happening in their house or work when they are not there. This is an old IP camera but it has something very interesting from the hardware perspective.

Usually, or at least from what I saw over the years, IP cameras have an ARM or MIPS CPU inside but this is not the case here. This model, and some others from the DCS-5xxx family, have a TriMedia CPU, a very old CPU. Why is this interesting? Personally, it is a new architecture for me and that's great because I can learn new things. However, there is very little documentation about TriMedia CPUs. From what I saw during this research, nobody has docs about it, nobody is allowed to speak about it, nobody is willing to share anything about it, everything seems to be a little bit "scary" and "obscure" about the TriMedia CPU. Why? Well, I really don't know. My bet is that as it is a proprietary CPU, originally from Philips, maybe it is a matter of NDAs.

In this post, we are going to talk about the first approach I took with the firmware analysis, then we'll see some analysis of the software and hardware present in the camera, and then, we'll do an introduction to the special CPU this camera has.

Firmware analysis

The first thing I do when I start to analyze a new device is to get the firmware, generally, from the vendor's site. The latest available version of the firmware is A3 1.06 (2009) but I decided to analyze the previous version v1.05, because it is the one I have installed on my camera.

I ran binwalk over the firmware image a got the following result:

fastix@fastix-virtual-machine:~/dcs-5300$ binwalk dcs5300_firmware_105.bin

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
978627        0xEEEC3         HTML document header
979192        0xEF0F8         HTML document footer
979238        0xEF126         HTML document header
995907        0xF3243         HTML document header
996327        0xF33E7         HTML document footer
997041        0xF36B1         HTML document header
997325        0xF37CD         HTML document footer
998169        0xF3B19         HTML document header
1000439       0xF43F7         HTML document footer
1000448       0xF4400         HTML document header
1000689       0xF44F1         HTML document footer
1000698       0xF44FA         HTML document header
1000743       0xF4527         HTML document footer
1007314       0xF5ED2         HTML document footer
1007323       0xF5EDB         HTML document header
1008041       0xF61A9         HTML document footer
1010780       0xF6C5C         HTML document footer
1010789       0xF6C65         HTML document header
1011723       0xF700B         HTML document footer
1011737       0xF7019         HTML document header
1012801       0xF7441         HTML document header
1013342       0xF765E         HTML document footer
1013438       0xF76BE         HTML document header
1017960       0xF8868         HTML document footer
1017969       0xF8871         HTML document header
1018032       0xF88B0         HTML document footer
1021031       0xF9467         HTML document footer
1025042       0xFA412         HTML document footer
1030588       0xFB9BC         HTML document footer
1034276       0xFC824         HTML document footer
1036344       0xFD038         HTML document footer
1038311       0xFD7E7         HTML document footer
1044539       0xFF03B         HTML document footer
1046711       0xFF8B7         HTML document footer
1047499       0xFFBCB         HTML document footer
1049110       0x100216        HTML document footer
1049897       0x100529        HTML document footer
1049906       0x100532        HTML document header
1050018       0x1005A2        HTML document footer
1050026       0x1005AA        HTML document header
1056592       0x101F50        HTML document footer
1060214       0x102D76        HTML document header
1060247       0x102D97        HTML document footer
1060755       0x102F93        XML document, version: "1.0"
1096400       0x10BAD0        Unix path: /usr/local/etc/zoneinfo
1103113       0x10D509        Base64 standard index table
1103407       0x10D62F        HTML document header
1103549       0x10D6BD        HTML document footer
1103557       0x10D6C5        HTML document header
1103691       0x10D74B        HTML document footer
1103699       0x10D753        HTML document header
1103857       0x10D7F1        HTML document footer
1106328       0x10E198        Microsoft Cabinet archive data, 278748 bytes, 1 file
1385220       0x152304        Certificate in DER format (x509 v3), header length: 4, sequence length: 964
1386188       0x1526CC        Certificate in DER format (x509 v3), header length: 4, sequence length: 1023
1387215       0x152ACF        Certificate in DER format (x509 v3), header length: 4, sequence length: 1215
1388434       0x152F92        Certificate in DER format (x509 v3), header length: 4, sequence length: 1269
1388593       0x153031        Digi International firmware, load address: 0x204D6963, entry point: 0x66742053,
1390788       0x1538C4        JPEG image data, JFIF standard 1.02
1392148       0x153E14        GIF image data, version "89a", 1 x 1
1392191       0x153E3F        GIF image data, version "89a", 1022 x 124
1424806       0x15BDA6        GIF image data, version "89a", 584 x 8
1426129       0x15C2D1        GIF image data, version "89a", 96 x 96
1431469       0x15D7AD        GIF image data, version "89a", 107 x 48
1432998       0x15DDA6        GIF image data, version "89a", 8 x 476
1434185       0x15E249        GIF image data, version "89a", 4 x 402
1434868       0x15E4F4        GIF image data, version "89a", 552 x 6
1436408       0x15EAF8        GIF image data, version "89a", 592 x 33
1440118       0x15F976        GIF image data, version "89a", 592 x 33
1445416       0x160E28        GIF image data, version "89a", 592 x 33
1450651       0x16229B        GIF image data, version "89a", 592 x 33
1455879       0x163707        GIF image data, version "89a", 107 x 48
1457575       0x163DA7        GIF image data, version "89a", 107 x 48
1459238       0x164426        GIF image data, version "89a", 107 x 48
1461378       0x164C82        GIF image data, version "89a", 107 x 48
1463544       0x1654F8        GIF image data, version "89a", 107 x 48
1465357       0x165C0D        GIF image data, version "89a", 107 x 48
1467138       0x166302        GIF image data, version "89a", 107 x 48
1468934       0x166A06        GIF image data, version "89a", 107 x 48
1470780       0x16713C        GIF image data, version "89a", 107 x 48
1472975       0x1679CF        GIF image data, version "89a", 107 x 48
1475212       0x16828C        GIF image data, version "89a", 107 x 48
1476772       0x1688A4        GIF image data, version "89a", 107 x 48
1478325       0x168EB5        GIF image data, version "89a", 107 x 48
1480001       0x169541        GIF image data, version "89a", 107 x 48
1481655       0x169BB7        GIF image data, version "89a", 107 x 48
1483360       0x16A260        GIF image data, version "89a", 107 x 48
1485155       0x16A963        GIF image data, version "89a", 107 x 48
1486785       0x16AFC1        GIF image data, version "89a", 107 x 48
1488409       0x16B619        GIF image data, version "89a", 107 x 48
1489931       0x16BC0B        GIF image data, version "89a", 107 x 48
1491372       0x16C1AC        GIF image data, version "89a", 107 x 48
1493089       0x16C861        GIF image data, version "89a", 107 x 48
1494774       0x16CEF6        GIF image data, version "89a", 45 x 62
1496151       0x16D457        GIF image data, version "89a", 45 x 62
1497544       0x16D9C8        GIF image data, version "89a", 592 x 33
1502797       0x16EE4D        GIF image data, version "89a", 592 x 33
1506569       0x16FD09        GIF image data, version "89a", 107 x 48
1508333       0x1703ED        GIF image data, version "89a", 107 x 48
1511052       0x170E8C        GIF image data, version "89a", 107 x 48
1512824       0x171578        GIF image data, version "89a", 58 x 34
1513950       0x1719DE        GIF image data, version "89a", 58 x 34
1515053       0x171E2D        GIF image data, version "89a", 107 x 48
1517167       0x17266F        GIF image data, version "89a", 107 x 48
1519329       0x172EE1        GIF image data, version "89a", 68 x 37
1521849       0x1738B9        GIF image data, version "89a", 68 x 37
1524424       0x1742C8        GIF image data, version "89a", 37 x 37
1525605       0x174765        GIF image data, version "89a", 37 x 37
1526826       0x174C2A        GIF image data, version "89a", 37 x 68
1529382       0x175626        GIF image data, version "89a", 37 x 68
1532007       0x176067        GIF image data, version "89a", 68 x 68
1536479       0x1771DF        GIF image data, version "89a", 68 x 68
1540151       0x178037        GIF image data, version "89a", 37 x 68
1542697       0x178A29        GIF image data, version "89a", 37 x 68
1545300       0x179454        GIF image data, version "89a", 37 x 37
1546541       0x17992D        GIF image data, version "89a", 68 x 37
1549014       0x17A2D6        GIF image data, version "89a", 68 x 37
1551567       0x17ACCF        GIF image data, version "89a", 37 x 37
1553024       0x17B280        HTML document header
1555494       0x17BC26        HTML document footer
1556564       0x17C054        HTML document header
1556598       0x17C076        HTML document footer
1556607       0x17C07F        HTML document header
1556720       0x17C0F0        HTML document footer
1556729       0x17C0F9        HTML document header
1557234       0x17C2F2        HTML document footer
1557742       0x17C4EE        GIF image data, version "89a", 82 x 40
1559960       0x17CD98        GIF image data, version "89a", 81 x 40
1562052       0x17D5C4        GIF image data, version "89a", 54 x 40
1564516       0x17DF64        Base64 standard index table
1565332       0x17E294        Base64 standard index table

As you can see in the output, binwalk was able to recognize some HTML, XML and GIF files only. There are also some certificates of what seems to be some Base64 index tables, but there aren't any signs of a bootloader, kernel or filesystems. Generally, bootloader and kernel image tend to be at the beginning of the firmware's image file, but that's not the case.

Binwalk also identified something called "Digi International firmware" but we'll see later that is just a false positive.

For those who have not noticed, binwalk was capable of recognizing some files starting at offset 0xEEEC3, what about the rest? I assumed that the binary blob at the beginning of the file was encrypted/compressed or both, so I decided to do an entropy analysis using binwalk ("-E" and "-B -E" options):

  • Entropy analysis only

Entropy
  • Entropy plus signature analysis

Entropy and signature

By looking at the graphs, we can see that almost the first megabyte of data has a very high entropy and looking at the variation, we can't totally be sure that it is only compressed or encrypted. Even though I tried to do a more exhaustive analysis of the entropy, I couldn't identify any known algorithm or cipher. At this point, I was sure I wasn't dealing with a common firmware image.

The last thing I tried at this point was to look at the strings (strings dcs5300_firmware_105.bin > output.txt) but I didn't find anything that could give me a clue about what I was dealing with.

So, I left this approach for a moment (we will see later what this binary blob has inside) and tried something different.

Exploring the attack surface

The next thing I tried was to start looking at different aspects of the camera in order to see if there was any vulnerability I could take advantage off in order to get access to it. At the end, we always want to get a shell. :)

I started by doing an nmap scan:

nmap -sV 192.168.1.0/24

Nmap scan report for 192.168.1.106
Host is up (0.0018s latency).
Not shown: 994 closed ports
PORT     STATE SERVICE        VERSION
21/tcp   open  ftp
23/tcp   open  telnet
80/tcp   open  http           D-Link Internet Camera
5001/tcp open  commplex-link?
5002/tcp open  rfe?
5003/tcp open  filemaker?
3 services unrecognized despite returning data. If you know the service/version, please submit the following fingerprints at https://nmap.org/cgi-bin/submit.cgi?new-service :
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port21-TCP:V=7.60%I=7%D=11/7%Time=5A01C181%P=i686-pc-windows-windows%r(
SF:NULL,20,"220\x20DCS-5300\x20FTP\x20server\x20ready\.\r\n")%r(GenericLin
SF:es,34,"220\x20DCS-5300\x20FTP\x20server\x20ready\.\r\n530\x20access\x20
SF:denied\.\r\n")%r(Help,34,"220\x20DCS-5300\x20FTP\x20server\x20ready\.\r
SF:\n530\x20access\x20denied\.\r\n")%r(SMBProgNeg,34,"220\x20DCS-5300\x20F
SF:TP\x20server\x20ready\.\r\n530\x20access\x20denied\.\r\n");
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port23-TCP:V=7.60%I=7%D=11/7%Time=5A01C181%P=i686-pc-windows-windows%r(
SF:NULL,26,"\xff\xfd\x18DCS-5300\x20Telnet\x20Daemon\r\nPassword\x20:\x20"
SF:)%r(GenericLines,26,"\xff\xfd\x18DCS-5300\x20Telnet\x20Daemon\r\nPasswo
SF:rd\x20:\x20")%r(tn3270,26,"\xff\xfd\x18DCS-5300\x20Telnet\x20Daemon\r\n
SF:Password\x20:\x20")%r(GetRequest,31,"\xff\xfd\x18DCS-5300\x20Telnet\x20
SF:Daemon\r\nPassword\x20:\x20Password\x20:\x20")%r(RPCCheck,26,"\xff\xfd\
SF:x18DCS-5300\x20Telnet\x20Daemon\r\nPassword\x20:\x20")%r(Help,31,"\xff\
SF:xfd\x18DCS-5300\x20Telnet\x20Daemon\r\nPassword\x20:\x20Password\x20:\x
SF:20")%r(SIPOptions,94,"\xff\xfd\x18DCS-5300\x20Telnet\x20Daemon\r\nPassw
SF:ord\x20:\x20Password\x20:\x20Password\x20:\x20Password\x20:\x20Password
SF:\x20:\x20Password\x20:\x20Password\x20:\x20Password\x20:\x20Password\x2
SF:0:\x20Password\x20:\x20Password\x20:\x20")%r(NCP,26,"\xff\xfd\x18DCS-53
SF:00\x20Telnet\x20Daemon\r\nPassword\x20:\x20");
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port80-TCP:V=7.60%I=7%D=11/7%Time=5A01C181%P=i686-pc-windows-windows%r(
SF:GetRequest,10D,"HTTP/1\.1\x20401\x20Unauthorized\r\nWWW-Authenticate:\x
SF:20Basic\x20realm=\"DCS-5300\"\r\nContent-Type:\x20text/html\r\nServer:\
SF:x20D-Link\x20Internet\x20Camera\r\n\r\n<HTML>\n<HEAD>\n<TITLE>Protected
SF:\x20Object</TITLE></HEAD><BODY>\n<H1>Protected\x20Object</H1>This\x20ob
SF:ject\x20on\x20the\x20server\x20is\x20protected\.<P>\n</BODY></HTML>")%r
SF:(HTTPOptions,6E,"HTTP/1\.1\x20405\x20Method\x20Not\x20Allowed\r\nAllow:
SF:\x20GET,\x20HEAD,\x20POST\r\nContent-Length:\x200\r\nServer:\x20D-Link\
SF:x20Internet\x20Camera\r\n\r\n")%r(RTSPRequest,6E,"HTTP/1\.1\x20405\x20M
SF:ethod\x20Not\x20Allowed\r\nAllow:\x20GET,\x20HEAD,\x20POST\r\nContent-L
SF:ength:\x200\r\nServer:\x20D-Link\x20Internet\x20Camera\r\n\r\n")%r(Four
SF:OhFourRequest,E8,"HTTP/1\.1\x20404\x20Not\x20Found\r\nContent-Type:\x20
SF:text/html\r\nServer:\x20D-Link\x20Internet\x20Camera\r\n\r\n<HTML>\n<HE
SF:AD>\n<TITLE>Object\x20Not\x20Found</TITLE></HEAD><BODY>\n<H1>Object\x20
SF:Not\x20Found</H1>The\x20requested\x20URL\x20\x20was\x20not\x20found\x20
SF:on\x20the\x20server\.<P>\n</BODY></HTML>")%r(SIPOptions,6E,"HTTP/1\.1\x
SF:20405\x20Method\x20Not\x20Allowed\r\nAllow:\x20GET,\x20HEAD,\x20POST\r\
SF:nContent-Length:\x200\r\nServer:\x20D-Link\x20Internet\x20Camera\r\n\r\
SF:n");
MAC Address: 00:0D:88:7E:35:B9 (D-Link)

We have the following services:

  • HTTP server: This is used for the management of the IP camera. An HTTPS server can be enabled from the web interface but is not turned on by default.

  • FTP server: This is used to access the screenshots and audio the camera can generate. It is the most comfortable way to access the multimedia files.

  • Telnet server: This is used for a more "advanced" management of the camera.

There are three other services I wasn't sure at the very beginning what their function was, but after doing some Googling, I could find out something interesting about them:

Radio Free Ethernet (RFE) is a network audio broadcasting system. It consists of programs and tools that allow packets of audio data to be transmitted around a network. The system is best understood by using the analogy of traditional radio broadcasting.

The camera has an incorporated microphone so this service is probably used to broadcast the captured audio.

  • The filemaker (TCP 5003) service is used to stream live video, a kind of RTP/RTSP service. With the D-ViewCam application, we can access the audio and video transmitted by the camera. The transmission is done via HTTP by requesting the video.vam file.

  • The commplex-link (TCP 5001) service is used to sync up the audio and video transmitted by the camera [2].

All these services seem to be custom-made, I didn't find any banner of a well-known http, ftp, etc... server.

Telnet service

When connecting to the Telnet server, you have to specify a password. The password is 'admin' (I just tried the default ones, and guess what? I had luck) and cannot be changed by the user in the web interface nor by using the Telnet service.

If you type 'help', you get the following menu:

DCS-5300 Telnet Daemon
Password : Authorized and start service
Supported commands :
        debug   : Dump debug information
        dinote  : Dump changed input status
        stop    : Stop dumping debug info and input status
        diquery : Dump current input status
        do1=h   : Set output 1 to high
        do1=l   : Set output 1 to low
        erase graph : Erase all graphics
        erase homepage : Erase custom homepage
        lock    : Lock network settings
        unlock  : Reset network settings
        clear   : Restore factory settings
        reset   : Restart system
        save    : Save parameters

We have an option to reset to factory settings and one to reset network settings, another option to restart the camera, and then some debug options. For example, the 'debug' option shows the following information:

TLN: Start debugging
SYS: MAC address = 00-0D-88-7E-35-B9
ETH: Activate Ethernet
ETH: Ethernet link speed is 100Mbps.
SYS: Ethernet is chosen
SYS: -----NET INFO-----
SYS: Host IP=192.168.1.106
SYS: Subnet Mask=255.255.255.0
SYS: Default gateway=192.168.1.1
SYS: Primary DNS server=186.56.20.66
SYS: Secondary DNS server=186.56.20.67
SYS: Video modulation is NTSC
SYS: No logo
TLN: Server starts up
FTP: Server starts up
SYS: No background
SYS: No custom homepage
H263 Encode Task start!
Audio Encode Task start!
comm res0:0
h263_control.dwBitRate=356000
WWW: Server starts up
Reboot Timer started
Reboot after 86400 sec = 1day 00hr:00min:00sec
SYS: System starts at 2017/11/07 12:01:54 in local time
[UPNPMiniServer] Bind at port 19815
UPnP started:0
[RpSendingServerPushResponse]
TLN: Xf00b
 -STOP-

We have information about the network settings in the camera (MAC, IP, DNS servers), the status of the different services running, and that's it, not too much more.

Usually, there is always an option to get a shell but this is not the case. It seems to be a very limited (fake) Telnet server with just a few options. If you grep strings in the image firmware file, you'll find some interesting things:

SYS: -----NET INFO-----
SYS: Host IP=%s
SYS: Subnet Mask=%s
SYS: Default gateway=%s
SYS: Fail to set gateway
SYS: Primary DNS server=%s
SYS: Secondary DNS server=%s
192.168.0.99
Network Interface OK
DHCP proceeding
DHCP proceed failed
DHCP proceed OK
End of get IP loop
!!!!
SYS: Ethernet is chosen
SYS: Jump out NetTask
system.log
network.log
video@%04d%02d%02d%02d%02d%02d.jpg
video.jpg
EML: socket error
0000000%04d%02d%02d
TLN: Telnet is logged in as admin
TLN: Telnet rejects user
reset
help
pass
stop
debug
newweb
Restart Web %X
conn?
conn%02d %d %02d %08X    conn%02d %d %02d %08X
mess?
mess=%d
lock
Fail
unlock
save
clear
erase graph
erase homepage
dinote
diquery
DI1=H
DI1=L
setmac
setlanguage
iicw
iicr
(%02X, %01X)->%02X
hang
suicide
fanon
on ok
fanoff
off ok
ethernet
report
Unknown command:
 -WRAPPED-
 -STOP-
TLN: Connected
 by %s
Telnet timeout for no action

Scrambled with some of the Telnet commands we saw, there are some strings that seem to be part of other 'undocumented' commands, for example the 'fanon' and 'fanoff', which I suppose are used to turn on and turn off, respectively, a kind of 'fan' inside the camera (this is not entirely true, if you disassemble the camera, you won't find any fan there. This fan is probably present in another device from the same family). There is another interesting command called 'suicide' that is used to reboot the camera. There is also a 'newweb' command that is used to create a new root for the web server.

There's not much else we can talk about this service.

FTP server

When connecting to the FTP server (anonymous is the default connection type; we can set a user and password from the web interface), we get the following:

FTP

We get the root of the FTP server and we can't go anywhere from here. This is the only accessible folder for us. Also, as you can see, there aren't many files we can get. Most of the files are 0 sized.

We can see a file named 'flash.bin'. This file contains the file system of the camera but we can't download it, its permission is just 'w' (write), we don't have 'r' (read) access. However, we do have access to the 'config.ini' file. This file contains all the configuration from the camera, including the web interface credentials. So, assuming that we get a remote code execution vulnerability in the future, this file is the one we should get. Here's a little extract of the content of the 'config.ini' file:

DCS-5300 Initial Configuration File

[SYSTEM]
<reset system>
Yes
<host name>
DCS-5300
<serial number>
000D887E35B9
<software version>
PT31x2-DLNK-0105b
<current date>
2017/11/07
<current time>
12:19:12
<time zone>
-3
<user name>
(0)admin
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)
(10)
(11)
(12)
(13)
(14)
(15)
(16)
(17)
(18)
(19)
(20)
<user password>
(0)admin

At the moment, there isn't too much else we can do with the FTP server. It is mostly used to store all the media (screenshots, audio, video) collected by the camera.

HTTP server

The HTTP server gives us access to a web interface via a browser:

Web interface

The default administrator's user is 'admin' with blank password. As you can see, you can change it in the web interface. Also, you can add different users and restrict them to use I/O and PT functionality. One interesting thing is that there is a 'guest' account available with user 'demo' and blank password. This guest account gives us access to the video stream via snapshots. Unfortunately (from an attacker's point of view), this account is disabled by default. However, some of the cameras I found in shodan.io had the demo account enabled.

Nowadays, if you search for a DCS-5300 camera in a service like Shodan, you won't get too many results.

If you pay attention to the 'realm' used in the 'WWW-Authenticate' header from the response, you'll see that if you grep in the firmware image file, there will be a different 'User-Agent' reported by the web server:

User-Agent

The 'User-Agent' reported by the web server is the one used by Vivotek IP cameras, VVTK. Is it the same web server used by Vivotek? Well, I'm not sure but it could be an option ;p given that it shares almost the same CGI API that some Vivotek IP cameras. For example, this is the WEB API provided by a Vivotek PT31x4 IP camera (check the ' URL Commands of the Network Camera' section) and this is the one provided for the DCS-5300. do you see the similarities?

As in many other cases, CGI programs are a very good starting point to look for vulnerabilities. Our goal is to have unauthenticated access to the camera through the web administration interface, which tends to be the exposed part to the Internet.

The only known vulnerability until now, or at least the only one I could find, is CVE-2012-5319, a CSRF in the /setup/security.cgi app in which an authenticated can be fooled to follow a link and this way the administrator account be hijacked. Just for the records, here's the PoC for this vulnerability:

&lt;html&gt;
&lt;body onload="javascript:document.forms[0].submit()"&gt;
&lt;form method="POST" name="form0" action="http://www.example.com/setup/security.cgi"&gt;
&lt;input type="hidden" name="rootpass" value="your_pass"/&gt;
&lt;input type="hidden" name="confirm" value="your_pass"/&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;

However, this vulnerability requires the user to be logged to the web administration interface. That's not what we are looking for. We need unauthenticated access. So, I decided to make a list of all the possible CGI programs listed in the documentation of the D-Link and Vivotek IP cameras:

CGIs available in the Vivotek IP camera documentation
--

/cgi-bin/video.jpg requires admin access (Protected Object)
/cgi-bin/getdi.cgi requires admin access (Protected Object)
/cgi-bin/setdo.cgi requires admin access (Protected Object)
/setup/restore.cgi requires admin access (Protected Object)
/setup/reset.cgi requires admin access (Protected Object)
/setup/system.cgi object not found
/setup/security.cgi object not found
/setup/network.cgi object not found
/setup/ddns.cgi requires admin access (Protected Object)
/setup/mailftp.cgi object not found
/setup/video.cgi object not found
/setup/ptcamera.cgi requires admin access (Protected Object)
/setup/image.cgi object not found
/setup/app.cgi object not found

CGIs available in the D-Link IP camera documentation
--

/cgi-bin/sysinfo.cgi requires admin access (Protected Object)
/cgi-bin/admin/configfile.cgi requires admin access (Protected Object)
/setup/setmd.cgi requires the privilege of I/O access control (Protected Object)
/cgi-bin/camctrl.cgi requires camera control access privilege (Protected Object)
/cgi-bin/recall.cgi requires camera control access privilege (Protected Object)
/cgi-bin/senddata.cgi requires camera control access privilege (Protected Object) (Only for models with RS-485 port)

Also, the doc lists all the referenced URLs used by the CGI programs:

Homepage name Referenced URL
Client settings page /client.html
configuration page /setup/config.html
system option /setup/system.html
security option /setup/security.html
network option /setup/network.html
DDNS & UPnP option /setup/ddns.html
audio/video option /setup/video.html
camera control option /setup/ptframe.html
motion detection /setup/motion.html
image quality option /setup/image.html
application option /setup/app.html
system log /setup/logfile.html
system parameters /setup/parafile.html
set factory default /setup/factory.html

Most of the CGI programs listed in the Vivotek's doc aren't available in the D-Link camera and the ones available require authentication. The same happens with the ones listed in the D-Link's doc, all CGI programs require authentication. Some of these CGIs were affected by different vulnerabilities in the past in some other Vivotek IP camera models, as the ones tagged as CVE-2013-1594, getparam.cgi and the parafile.html page [3].

Just to be sure I didn't miss any CGI program, I did a grep over the firmware image file but it seems that I checked all:

CGI

Ok, it seems that we couldn't find any unauthenticated CGI.

Then, I spent some time playing with Burp Suite and some of the CGI programs in order to see if I could find a post-auth vulnerability, mostly a remote command execution, to have access to the internal file system and that way have access to CGI binaries. I tried the most common issues as path traversal, semicolon injection in places like the DDNS, NTP, config, but due to the lack of output I wasn't sure about the success of the commands. I needed to go deeper, it was time to open the device.

Exploring the hardware

I decided to open the camera. I was hoping to find an interface like UART or similar in order to have access to the file system through a shell. This is what I found.

The camera has two PCBs. The biggest has almost all the interesting components we can find in a device like this (CPU, RAM, Flash, etc) and the small one has some chips for the PTZ functionality.

This is a picture of the front side of the biggest PCB:

PCB front side

In the above picture, we can identify the following components:

We have 128 MB of RAM, WiFi/Ethernet capabilities, 16 MB of Flash, a small video decoder and an EEPROM chip.

Then, this is a picture of the back side of the PCB:

PCB back side

On this side, we can see that we only have a big chip identified as Philips TriMedia PNX1300EH (32-bit processor). This is the reason for this post and we'll have a specific section dedicated to it.

Finally, this is a picture of the second PCB:

Second PCB

On this side, we can see a Winbond W78E54BP-40 and two Allegro A3967SLBT chips. All this stuff is used to move the engine of the camera and blink some LEDs.

As you can see, most of the hardware in this camera is what anyone expects to find in a device of this kind. There isn't anything special about it except the fact that the CPU is not what you commonly see in the IP cameras sold today, most of them use ARM or MIPS CPUs.

Before going into some details about the TriMedia CPU, let's talk a little bit about the pinout found on this device.

If you pay attention to the first picture, the one about the front side of the biggest PCB, we can see two interesting pinouts:

Pinout

We have 10 pins marked with a red rectangle and 12 pins marked with a yellow rectangle. At first sight, both look promising but the 10 pins are a little bit far from the main CPU and there aren't visible traces to it. Instead, the 12 pins are really close to the main CPU and there are traces that seem to go in that direction. If we read the datasheet, specifically, the Chapter 18 "JTAG Functional Specification", we can see that the TriMedia CPU has a JTAG interface. These are good news!, but we have to identify the right pinout. This is not always an easy task, however, my first approach was trying to reverse engineer the pinout using a voltmeter as described here. After some time, I came up with the following results:

Possible pinout
  • P1: Voltage fluctuation: 0,94 - 1, 14 - 2,x - 3,46 (TX?)

  • P2: Voltage fluctuation: 2,x - 3,46 (after a few seconds, remains steady at 3,46) (RX?)

  • P3/P4: Fixed voltage: 3,29

  • P5/P7/P11: Voltage fluctuation: 3,27 - 3,29 - 3,30

  • P9: Fixed voltage: 1,79

  • P6/P8/P10/P12: GND

Even though we got some information about the nature of the signals, we cannot get too much detailed information with a voltmeter in this case. The right tool we need in this case is an oscilloscope. With a scope you can check the basic nature of a signal (VCC, GND, Pulled-up line, numeric signal) and guess its parameters (max voltage, frequency, etc). At that moment, I didn't have that tool in my hands, I was armed with only a voltmeter and a Bus Pirate. Even though it's possible to build a cheap oscilloscope using a Bus Pirate, the bandwidth and sampling rate aren't good (5720 samples per second; in practice, gives a maximum measurable frequency of about 1kHz). At the end, in order to continue with this work, I bought a PicoScope 2204A but that will be a subject for another post.

Just as a side note, there exists a JTAG PCI debugger for TriMedia microprocessors offered by Monument Data Systems that can be used to debug the code running on this CPUs. I'm not sure if it is useful in this particular case, but it is good to know that we have more options.

The Philips TriMedia CPU

TriMedia microprocessors were originally manufactured by Philips, currently known as NXP (Nexperia) semiconductors (Qualcomm announced the acquisition of NXP in 2016 [4]). It is a family of VLIW [5] (Very Long Instruction Word) processors, which means they can execute a given number of instructions in parallel at the same time, with a Harvard architecture [6] and its main use is for DSP (Digital Signal Processing) [7].

At the very beginning, TriMedia processors were designated with the acronym 'PNX' and then it was changed to 'TM'.

TriMedia microprocessors run a real time operating system known as pSOS. Also, there has been some efforts to port the 2.6 Linux kernel branch to run on TriMedia CPUs [8] [9].

In order to program code for TriMedia microprocessors, there is an official SDK that includes everything you need (libraries, compiler, debugger, simulator, etc) but is not available except for the big companies that sell products using TriMedia processors, D-Link and 2Wire, for example. However, there are some TriMedia compliant SDK as the one offered by Streaming Networks, known as IADK (Integrated Application Development Kit), specifically designed for the PNX1300 family series.

Also, there are some development boards equipped with TriMedia CPUs that can be acquired if you want to play with this processor, for example, the TriREF development board offered by Streaming Networks. However, this kind of board, which includes the IADK, is not cheap. In fact, I contacted Streaming Network and asked for the TriREF board and it costs around US $5,000, a lot of money that I can't afford.

At the time of this study (January 2019), I looked for other options on the market, but they did not include the SDK.

If you want to read more about TriMedia microprocessors, you can refer to its corresponding Wikipedia entry.

In this post, I'm going to refer, specifically, to the TriMedia PNX1300EH microprocessor. Hopefully, all the information provided here can help you to research other processors of the same family.

Sources of information to Reverse Engineer a TriMedia CPU

To reverse engineer a TriMedia processor is not an easy task, especially due to the lack of documentation and tools. There is a very little documentation on the Internet about the TriMedia architecture, the instruction set documentation is poor and the existing tools are private and expensive. Anyway, there are some old sources of information we can use in order to start our journey.

The first source of information to start the research is the datasheet. This document includes information about all the architecture of the processor. We can get the main idea of the different components in the chip, how they interact, the specific instruction set used by the controller, etc. If you want to start with the right foot, you MUST read the datasheet.

Another good source of information, although specifically about JTAG research, is http://hackingbtbusinesshub.wordpress.com. Even though the blog is not available anymore, there are still some copies stored in web.archive.org [10] [11] [12]. This guy did an excellent work reversing 2Wire routers, which are based on TriMedia CPUs, and creating some excellent tools as 2wiglet (based on urjtag, a JTAG wiggler tool for 2Wire routers and tm32dis), a TriMedia disassembler for the TM32 family.

Now we are talking about JTAG, in a previous section, I mentioned that there is a JTAG PCI debugger for TriMedia CPUs offered by Monument Data System. There also exist an official JTAG debugger offered by Philips but it has some peculiarities. Quoting asbokid:

The TriMedia JTAG tools are designed to work only with a proprietary JTAG cable. The ‘cable’ is actually a sophisticated piece of programming equipment. It is a USB device that connects to the PC via a NetChip NET-2282 peripheral controller. The programmer boots from its own EEPROM and is driven by a Philips PNX1502 CPU with NOR flash and DRAM memory.

Obviously, IDA can't be excluded from the list of tools. IDA has support for TriMedia CPUs since its 4.x version, specifically, its 4.21 version [13]:

New features in version 4.21 (19/04/2002)
Processors
Trimedia (upon special request only)
[..]

As you can read in the release notes, the processor module is only available upon special request. I requested the processor module from HexRays but they no longer offer it.

Finally, during this research I collected different kinds of information about TriMedia (doc, tools) and stored it on a github repo.

Conclusion

In this first part of the series, I introduced the Philips TriMedia architecture. I used the IP camera as an excuse to talk about how it is to research a TriMedia based device, what and how much public information resources are available regarding software and hardware and how to deal with its magic ASM.

In the second part I'll dig into the TriMedia architecture itself. See you later! :)

Acknowledgements

Thanks to all my Quarkslab colleagues who proofread this article and provided valuable feedback.


If you would like to learn more about our security audits and explore how we can help you, get in touch with us!