Hi there! This will be just a quick write up about something I did last weekend. A week ago, I got a new router at home. Just by curiosity, or because we always want to know what’s inside of every device, I tried to google for the router’s firmware and the default configurations. I also wanted to harden the device and remove all those settings that come by default and are always a security problem. Guess what, I couldn’t find any interesting information about the device, or at least something that would make me feel that this version is being widely used. So I decided to root it by myself.
TL;DR
Since I didn’t find information about this device and I didn’t know what was inside of it, I decided to try a few things and root it by myself. In a nutshell, I tried to exploit a buffer overflow on the Samba running locally but I failed on doing this because of what I think was a configuration problem. Then I abused symlinks on the same Samba in order to overwrite a samba configuration file exposing the whole file system and running commands as root.
Overview
I found a user manual, but this wasn’t enough. I wanted to know more about the router. One thing thant caught my attention was that the interface wasn’t green as the rest of the ZTE devices, and the whole web was written in lua. It seems like a custom version, maybe just for this ISP?
Device’s information:
- Device Type: F670E
- Hardware Version V1.0
- Software Version V1.0.10P1T7
- Boot Version V1.0.10P1T8
Samba
I discovered that I was able to set up a samba server. After scanning the samba router, I could grab the version: 1.9.16p10 (Pretty old to be honest, it was released in 1997). I was sure that this was the entry point to get access to this device. I took one of my USB sticks and plugged in directly to the router. Nothing happened. I discovered later that the USB memory must be formatted to NTFS.
Now I was able to see the content of the USB drive by accessing \\192.160.1.1\samba. Now what? Since I had already tried a lot of things against the samba server and nothing had worked (check Failed attempt, at the end of the post). I decided to go for a logical bug. I mounted the pen drive on a Linux machine with the intention of creating a symlink and see how the server responded to that.
ln -s /var/samba/lib/smb.conf .
By doing a little bit of research about ZTE routers and some trial and tries, I discovered the path to the Samba config file. I decided to give it a chance. I mounted back the USB stick to the router and when I tried to open the file using the shared folder I could see the content of the file inside the server. Great!
Let’s try to change it and see if we are able to overwrite it. I added a new share:
I saved it and it worked:
Now we can see the content of the whole file system and maybe edit it. But wait, if you have configured a Samba server before you must be thinking about “preexec” or “root preexec” option.
Yep, it is what it seems. We can run code by just editing the samba. One thing that worth mention is that the option root preexec
doesn’t exist on this samba version, but I managed to run code as root by adding the following option at the beginning of the configuration file:
guest account = root
If you check the original content of the file, you will notice that it was running as nobody. Well, now we are running samba as root, and even executing code.
We are almost done. Now we need to extract the content of the router, so we can analyze it peacefully without the need to be using this old and broken samba.
I copied busybox for arm systems with the name busybox. And then added the following option to the smb.conf:
preexec = /mnt/usb1_1/busybox telnetd -b 192.168.1.1:27 -l /mnt/usb1_1/sh
When I checked the port with nmap, it showed that the port was open but it didn’t detect the telnet service. I tried to connect to it using Putty but I wasn’t lucky. After a few hours of playing with the different binaries and options from busybox and the router, I gave up and decided to use what I had at the moment.
I created a script /mnt/usb1_1/backup.sh
and added the following content:
I gave it execution permissions by doing preexec = chmod +x /mnt/usb1_1/backup.sh
. If you notice the second line, it will remove the execution flag from the file. This is because we just want to run the command once and avoid crashing the router. I also excluded some folders, most of them are virtual directories that are mounted by the router and something could go wrong if we try to copy them.
Recovering my admin password
The best part was at the end when my ISP changed my admin password because I asked them to reconfigure my router after a few failed attempts of recovering their configurations. And I used this whole process again to extract the web admin password from the router that they didn’t want to give me. How?
I mounted the pen drive, modified the smb.conf and exposed the whole file system. Then I extracted the file located at `/userconfig/cfg/db_backup_cfg.xml`. This file is stored using Zlib compression. I found this script on StackOverflow that prints the plain text content of the XML file:
Conclusion
Of course, I crashed the router multiple times, reset it to default once and even ask my ISP to configure the router again because I was having connection issues. But it was fun, now I have the whole firmware of the rooter, which I may be uploading to github soon, and I also exploited an old fashion bug on samba.
Failed attempt:
I downloaded the source code and run a quick static scanner called FlawFinder. The output showed 1517 hits as possible vulnerabilities. Too many to validate, so I focused on any possible unauthenticated buffer overflow. I saw they where using getpass
in multiple parts of the source to grab and manipulate the password. FlawFinder also gave me the following info:
This function is obsolete and not portable. It was in SUSv2 but removed by POSIX.2. What it does exactly, varies considerably between systems, particularly in where its prompt is displayed and where it gets its data (e.g., /dev/tty, stdin, stderr, etc.). In addition, some implementations overflow buffers. (CWE-676, CWE-120, CWE-20). Make the specific calls to do exactly what you want. If you continue to use it, or write your own, be sure to zero the password as soon as possible to avoid leaving the cleartext password visible in the process’ address space.
By doing a little more research I found out that the version 1.9.17 was actually vulnerable to a buffer overflow on the password. I found a public exploit and the CVE-1999-0182. As expected this exploit didn’t work at the first try, therefore I had to modify it a little bit to make it runnable.
After a few modifications and checking the SMB packets sent to the user I ended up with the conclusion it wasn’t vulnerable. I think that for this exploit to work, plain text password needs to be enabled, in order to trigger the overflow. Not sure about this, but I wanted to mention it, maybe someone knows why it didn’t work, or it could be just a custom version of samba with some patches.