Mastodon

SSH Access for Netgear’s Nighthawk M5 Mobile LTE/Router

In my previous post, I demonstrated how to gain root access by enabling a Telnet daemon via the routers AT-over-TCP interface. In this post I will close this gasping security hole by replacing the Telnet with a Secure Shell (SSH) daemon. Netgear’s firmware does not ship with a SSH daemon itself. So we first build a statically linked Dropbear instead of the rather heavy OpenSSH daemon.

Building Dropbear SSH

I’ve build a statically linked version of Dropbear using a Debian-based Docker image as it allows us to use the packaged cross-compiler toolchains by Debian:

Dockerfile
FROM debian:bullseye

RUN apt-get update && \
    apt-get -y install \
    	wget tar bzip2 build-essential \
	gcc-arm-linux-gnueabihf \
	binutils-arm-linux-gnueabihf

RUN wget https://matt.ucc.asn.au/dropbear/releases/dropbear-2022.82.tar.bz2
RUN tar xvf dropbear-2022.82.tar.bz2

WORKDIR /dropbear-2022.82

ENV CC=arm-linux-gnueabihf-gcc
ENV CFLAGS="-DDROPBEAR_SVR_PASSWORD_AUTH=0"

RUN ./configure --host=arm-linux-gnueabhf \
	--disable-zlib \
	--disable-shadow \
	--disable-syslog \
	--disable-lastlog \
	--enable-static
RUN make PROGRAMS="dropbear scp" MULTI=1

RUN arm-linux-gnueabihf-strip dropbearmulti

With this Dockerfile we can build the image, create a temporary container and copy the resulting binary from the image to your local folder:

docker build -t dropbear .

id=$(docker create dropbear)
docker cp ${id}:/dropbear-2022.82/dropbearmulti ./
docker rm ${id}

Installing Dropbear

Now that we have a statically linked version of the SSH daemon, we will need to copy it to our target. I accomplished this by using netcat (nc):

On the target

mkdir -p /data/mod/bin
pushd /data/mod/bin

nc -l -p 1234 > dropbearmulti
chmod +x dropbearmulti

ln -s dropbearmulti dropbear
ln -s dropbearmulti scp

On the machine which build Dropbear

nc <ip-of-target> 1234 < dropbearmulti

This is followed by installing a SystemD service which start the SSH daemon on system boot:

cat > /etc/systemd/system/dropbear.service <<EOF
[Unit]
Description=Dropbear SSH server
After=network.target

[Service]
Type=forking
ExecStart=/data/mod/bin/dropbear -R
PIDFile=/var/run/dropbear.pid

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now dropbear.service

Before you will be able to connect to the target, you will need to install an authorized_keys file. Password login is not supported.

mkdir -p /home/root/.ssh
cat > /home/root/.ssh/authorized_keys <<EOF
ssh-rsa AAAAB3NzaC1...GaoxPrQ== # replace by your SSH key
EOF

All that remains is a quick test:

ssh root@<ip-of-target>

Disable SSH daemon

In order to restore the security of the device we must also disable the Telnet daemon. There are in principle two options to achieve this:

  • Reverse the steps from my first blog post via the AT-over-TCP interface.
  • Use the iptables firewall to block access to the Telnet port

I’ve decided to go for the second option:

cat > /etc/systemd/system/block-telnet.service <<EOF
[Unit]
Description=Block Telnet access
After=network.target

[Service]
Type=simple
ExecStart=/usr/sbin/iptables -I INPUT -p tcp --dport telnet -j DROP
ExecStop=/usr/sbin/iptables -D INPUT -p tcp --dport telnet -j DROP

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now block-telnet.service