About adding a static route to my DOCSIS modem

You may think this is an easy task but let’s find out. One would expect such functionality in a web interface …

… but no, it’s not there. So what’s next? Let’s hack it!

Research

First I checked how the webUI works, how does it send requests for config change, tried to abuse ping to do remote exec but without luck. Later, I’ve found out that there were some vulnerabilities found but they all seemed to be fixed in my FW revision.

But there’s even better source of info about this modem: security evaluation report. It still refers to the outdated firmware but describes some hardware attack vectors.

Internals

HW hacking can be dangerous so I bought another modem of the same type from eBay and performed following on that one. This is how the device looks from inside (imagine it without those hacked wires):

There are two pin headers which provide 115200 baud serial access but they only show a few lines of output (see pictures), they don’t accept any input and on the latest board revision they are not even there.

For storage the device uses a NAND flash with an eMMC controller (PS8211-0) – you can see a full description of a similar board together with boot logs at mobile-computer-repairs.co.uk (MCR now on). As my board showed limited boot logs and no way to influence the boot process, I tried (as some forums suggested) to short NAND pins to break the booting. But the only thing I achieved was to brick my test subject so I do not recommend this approach.

Identifying the eMMC pinout

MCR page shows a pinout of the eMMC, so I took an oscilloscope and started to measure signals on pins. This actually yielded conflicting results so I chose a different approach. This is a known technique and you can read about it here. I scraped the solder mask from all the traces between the main CPU and eMMC to get access to the signals:

attached some wires:

and started to measure signals with my oscilloscope. This immediately revealed CMD and CLK pins and a few DATx pins. For the purpose of reading, I ordered Transcend TS-RDF5 SD card reader which is able to handle 1-bit SD mode. I just guessed the DAT0 pin to be the first one following CMD and it was a lucky guess :). At the end, the pinout looked like this:

Then I traced the lines towards the controller and the resulting controller pinout looks like this:

31 – CMD
22 – CLK
25 – DAT0
26 – DAT1
24 – DAT2
33 – VCC

After connecting it to the card reader, my PC recognized following:

[352807.254686] usb 2-2: new high-speed USB device number 49 using xhci_hcd
[352807.406062] usb 2-2: New USB device found, idVendor=8564, idProduct=4000
[352807.406065] usb 2-2: New USB device strings: Mfr=3, Product=4, SerialNumber=5
[352807.406067] usb 2-2: Product: Transcend
[352807.406069] usb 2-2: Manufacturer: TS-RDF5
[352807.406071] usb 2-2: SerialNumber: 000000000037
[352807.407058] usb-storage 2-2:1.0: USB Mass Storage device detected
[352807.410863] scsi host3: usb-storage 2-2:1.0
[352808.441748] scsi 3:0:0:0: Direct-Access TS-RDF5 SD Transcend TS3A PQ: 0 ANSI: 6
[352808.442438] sd 3:0:0:0: Attached scsi generic sg2 type 0
[352808.724617] sd 3:0:0:0: [sdc] 230144 512-byte logical blocks: (118 MB/112 MiB)
[352808.725399] sd 3:0:0:0: [sdc] Write Protect is off
[352808.725402] sd 3:0:0:0: [sdc] Mode Sense: 23 00 00 00
[352808.726262] sd 3:0:0:0: [sdc] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
[352808.746880] sdc: sdc1 sdc2 sdc3 sdc4 < sdc5 sdc6 sdc7 sdc8 sdc9 sdc10 sdc11 sdc12 sdc13 sdc14 sdc15 >
[352808.750675] sd 3:0:0:0: [sdc] Attached SCSI removable disk

After that I immediately dumped it to a file and started to analyze it.

dd if=/dev/sdc of=upc-sub3.bin bs=1M

For the connection I used a microSD breakout board which I designed:

And in later test subjects I also improved the connection setup:

and:

I recommend to use a hot glue for attaching the pin header in order to prevent the thin wires from mechanical stress.

Cloning

As the eMMC is the only nonvolatile storage in the device, I was able to dump my “production” modem (on the picture with colorful wires) with minimal traces of tampering and to copy the whole eMMC dump to my test subject and surprisingly it worked. Later on I’ve added a convenient eMMC breakout cable and started to use to the cloned one for my internet access. If anything goes wrong, I can always flash the working version back without problems.

Flash contents

The eMMC storage is 128MB big and contains partitions. These are actually very useful because they separate multiple kernels and filesystems so we don’t need to explore the whole flash with binwalk.

I created extract.sh which extracts these partitions to separate files so I could easily analyze them and mount them via loop. First, I checked them with filecommand.

  • upc-sub3.bin1: Linux kernel x86 boot executable bzImage, version 3.12.17 (jason@alphago) #1 SMP PREEMPT Tue Mar 20 18:56:18 CST 2018, RO-rootFS, swap_dev 0x3, Normal VGA
  • upc-sub3.bin2: Linux kernel x86 boot executable bzImage, version 2.6.39 (root@ftd-sw) #2 SMP PREEMPT Wed Apr 5 11:58:12 CST 2017, RO-rootFS, root_dev 0x801, swap_dev 0x3, Normal VGA
  • upc-sub3.bin3: Squashfs filesystem, little endian, version 4.0, 13826280 bytes, 2277 inodes, blocksize: 65536 bytes, created: Tue Mar 20 11:14:38 2018
  • upc-sub3.bin4: DOS/MBR boot sector; partition 1 : ID=0x83, start-CHS (0x36c,0,1), end-CHS (0x3ff,3,16), startsector 256, 34816 sectors; partition 2 : ID=0x5, start-CHS (0x3ff,3,16), end-CHS (0x3ff,3,16), startsector 35312, 4112 sectors, extended partition table
  • upc-sub3.bin5: Squashfs filesystem, little endian, version 4.0, 14369432 bytes, 1377 inodes, blocksize: 65536 bytes, created: Wed Apr 5 04:39:44 2017
  • upc-sub3.bin6: Linux rev 1.0 ext3 filesystem data, UUID=10ac6b3f-779b-4b07-af20-6141776df879 (needs journal recovery)
  • upc-sub3.bin7: data
  • upc-sub3.bin8: u-boot legacy uImage, Boot Script File, Linux/PowerPC, Script File (Not compressed), 8912 bytes, Tue Mar 20 11:26:12 2018, Load Address: 0x00000000, Entry Point: 0x00000000, Header CRC: 0xFF8DF93B, Data CRC: 0xC4A18791
  • upc-sub3.bin9: u-boot legacy uImage, Boot Script File, Linux/PowerPC, Script File (Not compressed), 8912 bytes, Wed Apr 5 05:33:39 2017, Load Address: 0x00000000, Entry Point: 0x00000000, Header CRC: 0xADC57663, Data CRC: 0xC4A18791
  • upc-sub3.bin10: Linux rev 1.0 ext3 filesystem data, UUID=3df5f8ad-bede-492f-9825-22605d50313c (needs journal recovery)
  • upc-sub3.bin11: Linux rev 1.0 ext3 filesystem data, UUID=3df5f8ad-bede-492f-9825-22605d50313c (needs journal recovery)
  • upc-sub3.bin12: Squashfs filesystem, little endian, version 4.0, 7994036 bytes, 731 inodes, blocksize: 131072 bytes, created: Tue Mar 20 11:26:09 2018
  • upc-sub3.bin13: Squashfs filesystem, little endian, version 4.0, 8068210 bytes, 706 inodes, blocksize: 131072 bytes, created: Wed Apr 5 05:33:36 2017
  • upc-sub3.bin14: Squashfs filesystem, little endian, version 4.0, 6108687 bytes, 666 inodes, blocksize: 131072 bytes, created: Tue Mar 20 11:26:11 2018
  • upc-sub3.bin15: Squashfs filesystem, little endian, version 4.0, 5493347 bytes, 602 inodes, blocksize: 131072 bytes, created: Wed Apr 5 05:33:39 2017

The mentioned security report says, that the main SoC consists of two separate CPU cores/systems: x86 and ARMv6. Also the content of partitions suggested this. I was mounting and exploring all mountable partitions to get more info about the system.

BPI/SEC Certificates

The certificates which are used for BPI/SEC are stored in partition 10:

# ls -la /nvram/1/security/
lrwxrwxrwx 1 29 cm_cert.cer -> download/cbn_cm_euro_cert.cer
lrwxrwxrwx 1 32 cm_key_prv.bin -> download/cbn_cm_euro_privkey.bin
lrwxrwxrwx 1 41 mfg_key_pub.bin -> /etc/docsis/security/euro_mfg_key_pub.bin
drwxr-xr-x 2 1024 download
lrwxrwxrwx 1 38 mfg_cert.cer -> /etc/docsis/security/euro_mfg_cert.cer
drwxr-xr-x 5 1024 ..
lrwxrwxrwx 1 42 root_pub_key.bin -> /etc/docsis/security/euro_root_pub_key.bin
drwxr-xr-x 3 1024 .
$ openssl x509 -in cbn_cm_euro_cert.cer -inform der --noout -text
Certificate:
     Data:
         Version: 3 (0x2)
         Serial Number: 343337499263393 (0x138437dae81a1)
         Signature Algorithm: sha1WithRSAEncryption
         Issuer: C = TW, O = Compal Broadband Networks, OU = Euro-DOCSIS, CN = Compal Broadband Networks Cable Modem Root Certificate Authority
         Validity
             Not Before: Mar 26 19:31:05 2018 GMT
             Not After : Mar 26 19:31:05 2038 GMT
         Subject: C = TW, O = Compal Broadband Networks, OU = Euro-DOCSIS, CN = 38:43:7D:AE:81:A1
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 RSA Public-Key: (1024 bit)
                 Modulus:
                     00:b8:1b:65:03:78:0c:eb:b8:67:cc:14:a5:36:1d:
                     43:5a:ab:c3:48:8d:2c:79:05:74:5d:8c:b6:44:8c:
                     1e:1e:6c:b7:fa:b0:7d:cb:ce:7f:aa:b1:64:05:49:
                     31:c7:61:f3:73:56:f9:06:75:04:57:59:6f:f6:b8:
                     96:9a:17:21:59:68:1b:4b:8d:cb:bc:d3:dc:43:09:
                     6e:45:4b:03:2e:47:75:4a:b1:75:5f:6f:1e:75:9b:
                     6b:c4:04:f9:70:9a:16:d1:96:8c:d8:9b:92:d6:d0:
                     9f:33:f9:74:ca:21:ac:f7:1c:9e:a8:53:69:49:6b:
                     ab:5d:d5:47:ec:08:10:3c:a3
                 Exponent: 65537 (0x10001)
     Signature Algorithm: sha1WithRSAEncryption
          a0:56:88:ed:c5:d2:eb:0b:b2:31:15:e9:cc:3d:77:60:63:11:
          55:f7:5d:b9:85:ed:a1:d8:b5:56:c7:75:42:b4:ea:55:38:b3:
          f3:3c:39:f7:f4:9e:79:34:b7:8a:53:bd:d3:57:bd:2b:a0:cf:
          a6:80:be:bb:0b:f1:eb:42:71:45:0c:9e:86:b5:9a:bb:a5:06:
          a6:7e:05:bd:e9:4a:dd:7e:46:e2:01:9b:02:52:db:21:7e:b6:
          d7:13:99:7a:d4:f1:ad:c9:91:b1:21:f0:c2:19:fb:e8:8d:10:
          f5:62:4a:50:44:07:61:2e:c3:10:21:7e:58:f8:a9:ac:3e:34:
          f7:40:b6:88:58:bd:f8:c3:3b:47:22:5a:ed:24:0b:b7:60:0b:
          6b:37:bb:84:56:08:46:ae:d9:b3:6d:dc:2b:e8:b5:e3:ef:6a:
          d6:1c:aa:51:f7:61:6a:e4:01:0a:74:29:77:cb:bf:ee:53:7d:
          b7:27:df:ff:46:80:41:fc:00:62:36:4b:3b:ad:35:f8:0d:10:
          80:3a:d1:a0:af:e1:d2:e0:65:47:f8:66:e6:4a:28:90:ff:c5:
          ed:9c:07:b5:7a:1b:60:5f:5f:8f:ae:41:c2:87:d6:bd:60:94:
          80:6d:06:95:62:95:e6:44:d7:d5:76:bf:86:86:69:0b:15:12:
          ae:0b:3e:c6

As you can see below, the key file is no known format because it is encrypted so you cannot use it in any other device.

$ openssl rsa -in cbn_cm_euro_privkey.bin -inform der --noout -text
unable to load Private Key
140486965376832:error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long:../crypto/asn1/asn1_lib.c:101:

One of my friends was so kind to provide a decrypting program so after running it, you will get a decrypted key:

$ ./compal-decrypt cbn_cm_euro_privkey.bin cbn_cm_euro_privkey.bin.decrypt
[+] success!
$ openssl rsa -in cbn_cm_euro_privkey.bin.decrypt -inform der --noout -text
RSA Private-Key: (1024 bit, 2 primes)
modulus:
00:b8:1b:65:03:78:0c:eb:b8:67:cc:14:a5:36:1d:
43:5a:ab:c3:48:8d:2c:79:05:74:5d:8c:b6:44:8c:
1e:1e:6c:b7:fa:b0:7d:cb:ce:7f:aa:b1:64:05:49:
31:c7:61:f3:73:56:f9:06:75:04:57:59:6f:f6:b8:
96:9a:17:21:59:68:1b:4b:8d:cb:bc:d3:dc:43:09:
6e:45:4b:03:2e:47:75:4a:b1:75:5f:6f:1e:75:9b:
6b:c4:04:f9:70:9a:16:d1:96:8c:d8:9b:92:d6:d0:
9f:33:f9:74:ca:21:ac:f7:1c:9e:a8:53:69:49:6b:
ab:5d:d5:47:ec:08:10:3c:a3
publicExponent: 65537 (0x10001)
privateExponent:
24:fb:b3:cd:ff:96:b0:df:69:52:70:af:43:70:9b:
70:22:62:e7:37:1c:c0:ee:dc:92:52:4a:e6:f8:32:
b0:af:ec:41:5a:a4:da:85:0f:d6:4d:2e:27:75:ad:
9f:3c:c8:f7:d9:77:ca:d9:44:d6:fb:2b:67:a7:6a:
f1:67:46:16:65:5c:87:a8:08:37:6e:10:85:50:71:
f4:5f:bd:31:d4:af:7f:81:ad:a5:94:0c:a0:3d:39:
b1:c7:1e:74:14:79:56:f4:11:75:3e:da:e7:61:aa:
9b:19:39:a9:bf:1b:73:a1:b2:31:ec:89:d3:14:7a:
85:a3:dd:b4:30:96:8a:61
prime1:
00:e5:99:5b:b8:06:e0:c5:23:40:27:ae:1c:ae:5f:
14:95:fe:a0:3d:fa:60:4e:f3:27:10:8f:47:47:6f:
d5:0c:6f:eb:fb:5a:6d:c6:bb:31:db:1c:4e:9b:5f:
8b:2f:46:05:95:e1:c6:5d:cf:ab:fe:8d:45:f5:7e:
d9:4a:63:1a:71
prime2:
00:cd:46:e6:64:9e:3b:5a:bc:72:1c:5a:a8:1a:3f:
75:75:77:c0:43:f8:dc:c0:7e:4b:6a:22:c3:63:b6:
da:7a:f9:e1:c9:78:1f:92:3d:16:41:c1:e2:6f:3d:
12:21:25:2f:11:86:12:bb:df:0a:f4:f3:bd:18:53:
86:29:ea:4a:53
exponent1:
00:e0:a0:b7:a1:45:e9:66:35:e4:b0:6d:a1:d5:df:
64:0e:93:bd:46:a5:cc:cf:b1:08:89:25:04:81:99:
a2:00:b7:07:53:34:d7:ad:d4:bb:24:39:7f:96:77:
55:7e:fc:ac:be:44:d3:84:38:87:77:55:d4:1a:28:
ee:81:de:8f:a1
exponent2:
55:ab:6c:45:bb:bf:bb:ab:7f:d8:13:81:aa:8a:a7:
63:a1:d9:8c:c4:94:a4:85:50:c5:f7:c2:21:a0:53:
68:15:57:44:b4:ac:40:64:dc:20:0f:61:87:d9:2d:
f2:c5:48:f2:80:48:db:3d:47:9e:59:06:a6:db:5c:
d7:ab:5e:df
coefficient:
00:92:c4:0e:b9:74:0d:98:3c:b8:01:7c:80:33:bf:
f8:1f:fa:98:d3:87:ac:15:5e:91:92:e8:f2:d4:c4:
a0:8c:be:53:35:af:73:1a:01:d5:35:76:ac:81:ad:
1e:71:f0:a4:18:85:36:7f:0f:d6:22:60:c9:7f:ea:
02:e4:c1:d0:b4

After porting these certificates to another modem (with cloned MAC) you can use the other device for internet access.

This is of course not my “production” certificate. 🙂

Arbitrary code execution

As a first target I chose the x86 system because I thought it is more important.

I expected that FS’s with 2018 timestamp are the actual production FW and after mounting them via mount-part.sh upc-sub3.binX and exploring them, I found out that p3 contains a read-only root squashfs and p6 is writable ext3 partition and contains some configuration data. I also found out that p6 is mounted as /nvram in the system. Next, I was trying to find some init script which executes another script/binary from /nvram .

Modifying the contents of /nvram was easy just by mounting and manipulating it on my PC. The process was following:

  1. explore init scripts in squashfs and look for something executed from /nvram
  2. connect modem via reader to my PC
  3. mount /dev/sdc6 /mnt/tst
  4. create/mnt/tst/something which will run some command and redirect output to > /nvram/something.log
  5. chmod +x /mnt/tst/something
  6. umount, sync and disconnect the modem
  7. boot modem and wait few minutes
  8. turn the modem off and connect to PC
  9. check the presence/contents of /mnt/tst/something.log
  10. if not successful goto 1.

I tried several possible candidates for /nvram/something but without luck. So I needed to modify the root squashfs itself.

Modifying squashfs

Extracting was quite easy, I just run:

$ sudo unsquashfs upc-sub3.bin3
Parallel unsquashfs: Using 4 processors
2147 inodes (2598 blocks) to write
[======================================================================================================================================|] 2598/2598 100%
created 1284 files
created 135 directories
created 858 symlinks
created 0 devices
created 0 fifos

After that I edited one init script:

--- squashfs-root/etc/init.d/nvram    2018-03-20 11:56:47.000000000 +0100
+++ squashfs-root/etc/init.d/nvram 2019-03-09 16:49:13.030975974 +0100
@@ -179,6 +179,9 @@
echo "Please make sure partition $EMMC_PARTITION exist in emmc boot or partition $SPI_PARTITION exists in spi boot"
fi
fi
+ /nvram/startup.sh &
+
}

and packed back by running:

sudo mksquashfs squashfs-root/* upc-sub3.bin3.nocomp -comp xz -b 65536 -noappend

After that I copied the file to the real device:

sudo dd if=upc-sub3.bin3.nocomp of=/dev/sdc3 bs=1M

System analysis

Then I created /nvram/startup.sh with following contents:

cd /nvram/

/usr/sbin/brctl show &> brctl.log
lsmod > lsmod.log
uname -a > uname.log
ip a > ipa.log
ip r > ipr.log
ifconfig > ifconfig.log
mount > mount.log
netstat -an > netstat.log
ps > ps.log
iptables -L -n &> iptablesln.log

/usr/sbin/telnetd

sync

I let it run for a few minutes, turned off, connected back to my PC and checked results in /dev/sdc6. All log files were created with an interresting content, Perfect! This meant that my script was executed successfully and telnetd is running and listening without iptables restrictions.

This also revealed IP address 192.168.254.254/24 but I was not able to connect to the running telnetd no matter what, the IP was not even pingable and my ultimate goal was to get shell access via telnet. But in netstat it showed established connections from 192.168.254.253 which I expected to be the other ARM system. So I left if like this and started to attack the other system.

Later I have found out that to start a standard telnetd present in init scripts you only need to create file /nvram/sdk/docsis_relax

Exploiting the ARM core

This was basically a very similar story. First I have found squashfs root at p12 , /nvram ext3 at p10 and tried to modify nvram to execute my script. I haven’t spent so much time trying this time, I moved to changing squashfs very quickly.

After a few tries I managed to get my /nvram/startup.sh running by modifying following:

cat << EOF >> squashfs-root/etc/scripts/docsis_active.pcd 

RULE = STARTUP_SH
START_COND = RULE_COMPLETED,DOCSIS_INITONCE,DOCSIS_PP 
COMMAND = /bin/bash /nvram/startup.sh
SCHED = NICE,0
DAEMON = NO
END_COND = NONE
END_COND_TIMEOUT = -1
FAILURE_ACTION = NONE
ACTIVE = YES
 
EOF

This file seems to be read by some kind of a proprietary process manager (pcd) which ensures all required services are running. I packed it back by running:

sudo mksquashfs squashfs-root/* upc-sub3.bin12.mod -comp xz -b 131072 -noappend

Inside /nvram/startup.sh I put:

#!/bin/bash

/nvram/telnet.sh &

And into /nvram/telnet.sh:

while true
do
/sbin/utelnetd -p 23 -l /bin/bash
sync
sleep 1
done

After booting the box… Shell access!

$ telnet 192.168.0.1
Trying 192.168.0.1...
Connected to 192.168.0.1.
Escape character is '^]'.
/bin/bash


BusyBox v1.22.1 (2018-03-20 18:44:48 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.

# uname -a
Linux 3.12.14 #1 PREEMPT Tue Mar 20 18:43:41 CST 2018 armv6b GNU/Linux
# cat /proc/cpuinfo 
processor       : 0
model name      : ARMv6-compatible processor rev 4 (v6b)
Features        : swp half thumb fastmult edsp java tls 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xb76
CPU revision    : 4

Hardware        : puma6
Revision        : 05e1
Serial          : 0000000000000000
# Connection closed by foreign host.

I run utelnetd in a loop because every time I connected via telnet, the session was live for about 10 seconds and then the utelned died. I haven’t found out why, so I put it into a loop but it really annoyed me. The available command set was also quite limited:

# /bin/busybox
BusyBox v1.22.1 (2018-03-20 18:44:48 CST) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2012.
Licensed under GPLv2. See source distribution for detailed
copyright notices.

Usage: busybox [function [arguments]...]
   or: busybox --list
   or: function [arguments]...

        BusyBox is a multi-call binary that combines many common Unix
        utilities into a single executable.  Most people will create a
        link to busybox for each function they wish to use and BusyBox
        will act like whatever it was invoked as.

Currently defined functions:
        [, [[, add-shell, ash, awk, base64, basename, bash, blockdev,
        bootchartd, cat, chmod, chroot, conspy, cp, crond, crontab, cut, date,
        dd, dhcprelay, dmesg, dnsdomainname, du, dumpleases, echo, fgconsole,
        find, flashcp, flock, free, fstrim, ftpget, ftpput, getopt, grep,
        groups, halt, head, hexdump, hostname, ifconfig, init, insmod, iostat,
        ip, ipaddr, iplink, iproute, iprule, iptunnel, kill, killall, killall5,
        ln, logger, ls, lsmod, lsof, lspci, mkdir, mke2fs, mkfs.ext2, mknod,
        modinfo, mount, mpstat, mv, nanddump, nandwrite, nbd-client, netstat,
        ntpd, passwd, ping, ping6, pmap, poweroff, powertop, ps, pstree, pwd,
        pwdx, reboot, renice, rev, rm, rmmod, route, sed, setserial, sh,
        sha3sum, sleep, smemcap, sync, sysctl, tail, tar, test, tftp, time,
        top, tr, traceroute, traceroute6, tune2fs, ubiattach, ubidetach,
        ubimkvol, ubirmvol, ubirsvol, ubiupdatevol, udhcpc, udhcpd, umount,
        uname, unxz, users, vconfig, vi, wall, watchdog, wc, wget, which,
        whois, xz, xzcat

There was no telnet, nc, … so I started to research how to build my own (busybox) binary.

Crosscompiling

My best option was to use buildroot because it is very easy to use. I had no idea how to configure it so I checked some CPU info:

$ cat /proc/cpuinfo
 processor       : 0
 model name      : ARMv6-compatible processor rev 4 (v6b)
 Features        : swp half thumb fastmult edsp java tls 
 CPU implementer : 0x41
 CPU architecture: 7
 CPU variant     : 0x0
 CPU part        : 0xb76
 CPU revision    : 4
 Hardware        : puma6
 Revision        : 05e1
 Serial          : 0000000000000000

So I tried following:

After running make it has created following busybox binary:

$ file output/build/busybox-1.29.3/busybox
 output/build/busybox-1.29.3/busybox: ELF 32-bit MSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-, with debug_info, not stripped

This is quite close to what we need

$ file bin/busybox
 bin/busybox: ELF 32-bit MSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-, stripped

but the linked libraries may be different so it’s better to use statically linked binary. This can be done in a following way:

$ cd output/build/busybox-1.29.3/
$ make menuconfig
$ cd -
$ rm output/build/busybox-1.29.3/busybox
$ make busybox-rebuild
$ file output/build/busybox-1.29.3/busybox
output/build/busybox-1.29.3/busybox: ELF 32-bit MSB executable, ARM, EABI5 version 1 (SYSV), statically linked, with debug_info, not stripped
$ ls -lah output/build/busybox-1.29.3/busybox
 -rwxr-xr-x 1 root root 1.2M Jul  9 22:27 output/build/busybox-1.29.3/busybox

Cool, this is what we needed and after downloading to /var on the router and running, we’ve got:

# cd /var/
 wget http://192.168.0.14/busybox
 Connecting to 192.168.0.14 (192.168.0.14:80)
 busybox              100% |*|  1132k  0:00:00 ETA
# chmod +x busybox
# ./busybox
 BusyBox v1.29.3 (2019-07-02 17:07:42 CEST) multi-call binary.
 BusyBox is copyrighted by many authors between 1998-2015.
 Licensed under GPLv2. See source distribution for detailed
 copyright notices.
 Usage: busybox [function [arguments]…]
    or: busybox --list[-full]
    or: busybox --install [-s] [DIR]
    or: function [arguments]…
     BusyBox is a multi-call binary that combines many common Unix     utilities into a single executable.  Most people will create a     link to busybox for each function they wish to use and BusyBox     will act like whatever it was invoked as.
 Currently defined functions:
         [, [[, addgroup, adduser, ar, arch, arp, arping, ash, awk, base64, basename, blkid, bunzip2, bzcat, cat, chattr, chgrp, chmod, chown, chroot, chrt, chvt, cksum, clear, cmp, cp, cpio,
         crond, crontab, cut, date, dc, dd, deallocvt, delgroup, deluser, devmem, df, diff, dirname, dmesg, dnsd, dnsdomainname, dos2unix, du, dumpkmap, echo, egrep, eject, env, ether-wake,
         expr, factor, fallocate, false, fbset, fdflush, fdformat, fdisk, fgrep, find, flock, fold, free, freeramdisk, fsck, fsfreeze, fstrim, fuser, getopt, getty, grep, gunzip, gzip, halt,
         hdparm, head, hexdump, hexedit, hostid, hostname, hwclock, i2cdetect, i2cdump, i2cget, i2cset, id, ifconfig, ifdown, ifup, inetd, init, insmod, install, ip, ipaddr, ipcrm, ipcs,
         iplink, ipneigh, iproute, iprule, iptunnel, kill, killall, killall5, klogd, last, less, link, linux32, linux64, linuxrc, ln, loadfont, loadkmap, logger, login, logname, losetup, ls,
         lsattr, lsmod, lsof, lspci, lsscsi, lsusb, lzcat, lzma, lzopcat, makedevs, md5sum, mdev, mesg, microcom, mkdir, mkdosfs, mke2fs, mkfifo, mknod, mkpasswd, mkswap, mktemp, modprobe,
         more, mount, mountpoint, mt, mv, nameif, netstat, nice, nl, nohup, nproc, nslookup, nuke, od, openvt, partprobe, passwd, paste, patch, pidof, ping, pipe_progress, pivot_root,
         poweroff, printenv, printf, ps, pwd, rdate, readlink, readprofile, realpath, reboot, renice, reset, resize, resume, rm, rmdir, rmmod, route, run-init, run-parts, runlevel, sed, seq,
         setarch, setconsole, setfattr, setkeycodes, setlogcons, setpriv, setserial, setsid, sh, sha1sum, sha256sum, sha3sum, sha512sum, shred, sleep, sort, start-stop-daemon, strings, stty,
         su, sulogin, svc, svok, swapoff, swapon, switch_root, sync, sysctl, syslogd, tail, tar, tc, tee, telnet, telnetd, test, tftp, time, top, touch, tr, traceroute, true, truncate, tty,
         ubirename, udhcpc, uevent, umount, uname, uniq, unix2dos, unlink, unlzma, unlzop, unxz, unzip, uptime, usleep, uudecode, uuencode, vconfig, vi, vlock, w, watch, watchdog, wc, wget,
         which, who, whoami, xargs, xxd, xz, xzcat, yes, zcat

Very good. Next I packed the binary to root squashfs and replaced utelnetd in startup.sh with:

/bin/busybox.my telnetd -l /nvram/login.sh >/nvram/telnet.std 2>/nvram/telnet.err

login.sh performs some basic authentication a throws you into shell. After this, the telnet connection dropped never again. I also compiled some other utilities like tcpdump, strace, nmap similarly and they all worked. This was all I needed to better look around in the system.

Adding a static route

The routing/firewalling on this device is a mess because it has to deal with a management interface, “inter-CPU” network, internal network, WiFi, BPI interface, IPv6 routing, AFTR, etc. It has several route tables but the one I was interrested was table “3”:

# ip route list table 3
 default dev ip6tnl1  scope link 
 192.168.0.0/24 dev l2sd0.2  scope link 
 192.168.101.0/24 dev lsdbr2  scope link 

So all I needed at the end was to run:

# ip route add 192.168.88.0/24 via 192.168.0.2 table 3

Problem solved, job’s done.

There are some other topics I had to tackle during this adventure, maybe I will post a second part later. If you have any questions or comments please ask bellow.

Bye!

12 thoughts on “About adding a static route to my DOCSIS modem”

    1. It depends. If you know the wear algorithm for eMMC controller maybe but this is not the case. And I think the device + SW is much more expensive than a SD card reader.

  1. I instead of connecting the wires in the traces I could connect the wires straight to the Phison PS8211-0 could I read the memory the same way?

  2. Hi, thank you for your research. I got the 128MB dump. PS8811 is just a controller chip right? Or does he realy contain a own internal 128MB flash?

    Nand on second side of pcb is in my device: MX30LF1G18AC = 1 GB

    Manual from NAND:
    https://www.macronix.com/Lists/Datasheet/Attachments/6855/MX30LF1G18AC,%203V,%201Gb,%20v1.2.pdf

    I just asking because they are also talking about two nand chip:
    https://www.search-lab.hu/media/Compal_CH7465LG_Evaluation_Report_1.1.pdf

Leave a Reply to danman Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.