Hacking the Nokia Fastmile: Part 2

Having had some time to off to mull over what to do next and attend to some other priorities I decided it was time to get back to looking at this.  

But first, I had to address the issue of having to take my internet down every time I wanted to do any prodding. So then there were two...

Fun Party Tricks

Of course we can't just dive straight into the hard stuff so I thought I'd take a look at what ridiculous things I could do with the Android side first.

As it's just a standard Android phone, we can use scrcpy to virtually interact with it over ADB. This doesn't really tell you anything else that you can't find via CLI.

What it does allow us to do however is install our own apps and interact with them. So naturally, I installed FlappyBird to have a go.


I am claiming the world record for FlappyBird on a Nokia Fastmile Router.

Come at me.

Identical Super Admin Passwords

Alright back to the serious stuff.

After receiving my second device, I noticed that the second device was on a newer firmware version with the authenticated privilege escalation vulnerability patched out.

This locks us out of the configuration backup/restore utility.

Luckily, there's a higher privileged account with the same default password that seems to be baked into every Optus shipped device.

<WebAccount. n="WebAccount" t="staticObject">
    <Enable rw="RW" t="boolean" v="True"></Enable>
    <Alias t="string" ml="64" rw="RW" dv="cpe-NokiaAlias2" v="cpe-NokiaAlias2"></Alias>
    <Priority max="10" min="1" rw="RW" t="unsignedInt" v="1"></Priority>
    <UserName ml="64" rw="RW" t="string" v="admin"></UserName>
    <Password ml="64" rw="RW" t="string" v="7hrGZUG0NX48jHEq3+Twog==" ealgo="ab"></Password>
    <PresetPassword ml="64" rw="RW" t="string" v="7hrGZUG0NX48jHEq3+Twog==" ealgo="ab"></PresetPassword>

Using the same tricks from last time the password 'decrypts' to Nq+L5st7o with the username being admin.

At least in my case, the password I obtained from my first device also worked on my second device.

Maybe somebody should tell Optus, or maybe not because having full access to these devices is nice.

UDPATE: Informed Nokia and as of U-Boot Aug-09-2022--20:45:33 patch version 3TG00118ABGA31 this is no longer available.

UPDATE 2: This has been assigned CVE-2022-36222.

Diving into the Firmware

Shout out to @neggles for helping me through some of this.

I never did end up going through the process of dumping the Router side firmware so I might come back to do this as an exercise. In this case, I didn't end up needing to.

Obtaining Firmware

When the device goes to update itself, it very nicely logs the download URL for the firmware.

Sifting through my own device's logs I managed to download some firmware only to find that it's encrypted.

Luckily for us some nice person on the internet has posted a download URL for an older firmware version that isn't encrypted.


You'll probably need to be on the Optus network somewhere to reach this:

Cracking open this older firmware file we see a couple of files. The highlighted one being relevant for the Router side with the zip file being relevant for the Android side.

Trying to unpack this file we immediately run into a hurdle, it looks like a UBI image but fails to unpack with ubidump.

Some Googling brings us to this issue which seems to be what we ran into. Several Squashfs volumes inside a UBI image.

Unpacking the squashfs volume shows us the root filesystem.

Needle in a Haystack

Cracking open the firmware revealed a massive attack surface to evaluate. I put together a non exhaustive list of things to look at that might help us to get root and just started working my way down the list.

  • Finding an issue with one of the CGI Scripts in the web directory
  • Reversing the jail shell /usr/sbin/vtysh
  • Reversing the configuration management utility usr/sbin/cfgmgr
  • Figure out how to repack the firmware with an entry point for us
  • Attacking the router from the Android side (that 5GCPE app on the Android side must be doing something)
    • Storage of Android /sdcard/ is shared to the router via USB-OTG and files seem to be written there to transfer some information!
    • There's also network connectivity as we established last time but I'm unsure if this only used for routing traffic

CGI Scripts

Looking at just the first point in that list, there's a sea of CGI scripts that could potentially lead us to shell access.

I had a look at a few of these and found some other vulnerabilities (that will be documented at the bottom for those interested) but quickly decided to move on from this.

Jail Shell

Quick recap, in the last blog post we were able to SSH into the device by enabling the SSH user in the configuration file.

While the credentials we set in the configuration worked for SSH, they did not work for the password prompt presented when trying to use the 'shell' command at the jail shell.

Next I decided to look at the jail shell which seemed to be located at /usr/sbin/vtysh. Notably, I was interested in what was actually being checked when we were getting prompted for a password.

Opening the binary in Ghidra it become quickly apparent that the password we were getting prompted for had little to do with the one we set in the configuration. It seemed to be consisted of a group of integers that I couldn't figure out where they were set.

Ghidra Output

Reversing isn't my strong suit so I decided to move on from this as well.

Configuration Manager

Next I started to look into the configuration manager.

While I was looking at the CGI scripts I noticed a number of them simply took user input and passed them onto bash scripts to then perform actions.

I'm all about being as lazy as possible, so trying the easiest stuff first made sense to see if the same pattern had been used in this binary. After running strings on the binary and sifting through the results, a single line caught my eye.

Adding management users sounds like something I want to do.

In the middle of this script there's also a very interesting if statement (full script for those interested).

if [ -e /usr/sbin/vtysh -a "$user_name" != "ONTUSER" -a "$OPID" != "0000" -a "OPID" != "9999" ]; then
   adduser -D -h ${home_dir}/${user_name} -G wheel ${user_name} -s /usr/sbin/vtysh
   adduser -D -h ${home_dir}/${user_name} -G wheel ${user_name}

At this point, we know:

  • We have access to change the config of the router including managing users
  • This script is called by the Configuration Manager at some point
  • If the username == ONTUSER OR if the OperatorID == (9999 OR 1111) then users are created with the default shell instead of the jail shell
  • In the previous write-up, we found mentions of setting LimitAccount_ONTUSER in config to false doing something

It can't possibly be that easy.


The config ships with the "TelnetSshAccount" username of "admin". I changed this to "ONTUSER" and upon SSH we are greeted with full root access instead of a jail shell.

Config Sample

Mission accomplished.

There's tons more to look at obviously so maybe there'll be a part 3 as I'm almost certain there's another way in with such a large attack surface. For now though, I'll leave you with some of the other interesting things I noticed while looking through this device.

Other Interesting Things

WTF Backdoor??????

There's a telnet script in the web directory which seems to spin up a telnet server that gives shell access without authentication.

Couldn't find anywhere this gets called though. ./telnet.sh on will turn the backdoor on and ./telnet.sh st checks the status of the backdoor

Pipe Path Traversal

UPDATE: This has been assigned CVE-2022-36221.

The CGI script used to read the output of diagnostic pings is affected by a path traversal vulnerability.

Opening the command_web_app.cgi script up we see that it passes user input straight to the cat.sh script.

Ghidra Output of command_web_app.cgi

This script performs a check to see if the file is a pipe but otherwise just returns the contents.

The result? We have path traversal!

The usefulness of this is dependent on the existence of pipes on the router that contain sensitive information. Also the endpoint is only available as an authenticated user (albeit full admin is not required).

There's also a similar issue allowing you to check for the existence of any arbitrary directory.