Hidden firmware features on the 4GEE Home Router

James White
10 min readMay 17, 2020

Did you know the 4GEE Home Router has several hidden settings pages within the firmware and its own JSON-RPC web API?

The 4GEE Home Router itself is a rebadged Alcatel HH70 used by EE. Behind the scenes it is running a modified version of OpenWrt and is running the GoAhead web server from EmbedThis that serves the EE branded web interface. This can be found in the response headers when accessing the web interface:

curl -v http://192.168.1.1/index.html
* Trying 192.168.1.1...
* TCP_NODELAY set
* Connected to 192.168.1.1 (192.168.1.1) port 80 (#0)
> GET /index.html HTTP/1.1
> Host: 192.168.1.1
> User-Agent: curl/7.58.0
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Date: Sun May 17 12:59:38 2020
< Server: GoAhead-Webs/2.5.0
< X-Frame-Options: SAMEORIGIN
< x-xss-protection: 1; mode=block
< Last-modified: Tue Oct 23 07:08:21 2018
< Content-length: 789
< Content-type: text/html
<

The web interface is using Vue.JS rather than CGI scripts, so despite the version being 2.5.0, it is not vulnerable to a well known exploit with the GoAhead web server. Although previously, the 4GEE Home router did have it’s very own root SSH backdoor. This was mitigated by EE (or possibly Alcatel themselves) disabling SSH (dropbear) entirely.

I’ve recently been trying to see if I could get some form of connection to the OpenWrt side back i.e. Telnet/SSH, as I wanted to explore the WAN configuration side in more detail when I recently obtained an 4GEE Home Router with the purpose of it being a backup WAN connection. I looked at a few areas, mainly:

  • Possibly hidden SSH setting in the web interface (unlikely)
  • Finding a method in the built in JSON-RPC API that can enable it (also unlikely)
  • Exploiting the backup and restore functionality to override the existing /etc/config/dropbear config through a modified configure.bin file (maybe, with a good chance of potentially having a brick)
  • Abusing some of the hidden features, like TR-069 (explained in more detail below)
  • Take apart the device to see if a serial/JTAG connection is an option (potentially)
  • Ask EE to provide me a special build of the firmware with SSH enabled again (ha ha, yeah right!)

Ultimately I was able to leverage some shortcomings in the backup and restore feature and enable SSH again by crafting my own exploit of sorts, I’ve wrote a more detailed explanation of how I did that. However during my exploration efforts I found some interesting hidden settings and features which are part of the firmware which I thought I’d document.

Hidden firmware features

I first realised that there were hidden settings pages, when using Google Chrome developer tools and viewed the contents of a JavaScript array (shown below) that has the purpose of storing key information about all pages/routes and navigation related options in the web interface.

Various configuration settings stored in the pageConfig variable

I noticed that some of values in the array did not seem to appear anywhere in the menu on the web interface, which made me curious. I ended up taking a look at uncompressed version of the build.js file that is used in the web interface which further confirmed this. This led me to discover there are several hidden pages that mostly seem functional but not present in the visible navigation of the web interface itself.

The way to access these pages is simply replacing the route name at the end of the URL, when viewing the web interface normally after authenticating with the admin user. Example:

http://192.168.1.1/index.html#/pageName

Replace pageName with any of the following page names to access the setting page. At the time of writing this was all found on the HH70_E1_02.00_24 firmware.

  • diagnostic — Provides further information about the cellular connection includes RSSI, EC/IO, LAC Code, Cell ID, RSRP and SINR information. This is rather useful, I’m not sure why it’s “hidden”.
  • monthlyPlan — Seems to be a way to monitor monthly usage and to automatically disconnect if a certain threshold is reached.
  • routingRules — Allows adding static routes (yes it’s had this feature the whole time!) and also an option for dynamic routing with the ability to change the version of Routing Information Protocol (RIP). The options of v1, v2 or both are present.
  • urlFilter — Allows blacklisting of one or more URLs. This feature seems to work using DNS. It makes the DNS resolver time out on blacklisted domains. Not exactly an elegant solution given the delay this has, instead it would have been better to null route domains or returning NXDOMAIN.
  • vpn — Based on the contents within build.js, this looks to be a VPN passthrough setting not a VPN server, but the setting label itself returns “undefined” when accessed so it doesn’t look entirely functional, but the toggle setting seems to have some form of action configured behind it.
  • ddns — Dynamic DNS settings. Not sure how useful or functional this would be given IPv4 is through CGNAT, but you can choose from four DDNS providers, dtdns.com, dyndns.org, no-ip.com and changeip.com.
  • backup — Looks to be a left over page and is blank, likely because the backup and restore functionality exists at restore .
  • reboot — Similar to the backup page except it does have a reboot button, however this is also present on the resetReboot page, which is in the web interface navigation.
  • tr069 — Support for TR-069 is implemented, but disabled by default. EE themselves aren’t using it as remote access method. This feature allows you to configure the router to connect to an OpenACS server endpoint with authentication credentials. This is often used by ISPs to remotely control/manage CPEs. The implementation is EasyCwmp https://openwrt.org/docs/techref/ucwmp. It is functional and I even managed to setup my own OpenACS server (using GenieACS) and get it to connect with the ability to control some areas/settings.
  • activePicopoint — I’m not really too sure what this is, the settings page presents a file upload with a button stating “Activate Picopoint” which seems to expect a JSON file. I haven’t tried it. Best guess it’s https://www.picopoint.com/, EE is listed as being one of their customers.
  • incomingCall , outgoingCall , missedCall — Call related menus which don’t really have any functionality, given calls aren’t supported with the 4GEE Home Router, but the functionality exists on the Alcatel HH70.
  • ussd — Unstructured Supplementary Service Data. Allows you run one or more USSD codes programmed into the SIM. I tried a few UK USSD codes and they all returned “Not support!Please try again.” suggesting the USSD settings page isn’t implemented. The English translation string for this message would suggest it’s likely something original part of the Alcatel firmware that’s been left in the EE firmware. Equally because the 4GEE Home Router doesn’t support any call functionality, that’s probably why!
  • voiceMail — Similar to the VPN settings page, doesn’t look implemented. Presents a single text field with a max length of 20 and the label for the settings as “undefined”. Again, call related functionality isn’t supported on the 4GEE Home Router so no surprise there.

Here’s some screenshots of the pages described above:

Diagnostics, USSD and Activate Picopoint settings pages.
DDNS, VPN and URL filter settings pages.
Static/Dynamic routing, Monthly Plan and TR-069 settings pages.

It is highly likely that most if not all of these settings are originally from the Alcatel firmware. EE will have likely rebranded the web interface templates and the navigation items config, leaving some of these features in the firmware build but just not directly accessible. Looking at the original manual provided by Alcatel themselves for this model, it would hint this is likely the case:

http://www.alcatel-move.com/um/HH70/00_Generic/USER_Manual_en.pdf?project=HH70

A lot of these settings pages appear functional. I can verify this because if you use the backup and restore feature and dump the contents of the configure.bin, you’ll find config files present related to them (with the date modified being recent). In some cases you can use the undocumented JSON-RPC API to modify them as well, which I’ll cover next.

JSON-RPC API

The 4GEE Home Router has a JSON-RPC web API which has various methods to return data and in some cases commit data or change settings as well. It seems to be primarily used for the web interface to communicate between the front end and backend. It’s not exactly hidden but it is undocumented, it can provide further data for some areas which the web interface doesn’t show. In a similar way to discovering the hidden pages, the build.js file has various SDK calls with either get/set naming conventions. There are a lot, so I won’t list all of them but here’s a few of examples of interacting with the JSON-RPC web API.

API URL: http://192.168.1.1/jrd/webapi (Change the IP address if it is different)

GetSystemStatus:

curl --location --request POST 'http://192.168.1.1/jrd/webapi' \
--header '_TclRequestVerificationKey: <YOUR_KEY>' \
--header 'Referer: http://192.168.1.1/index.html' \
--header 'Content-Type: application/json' \
--data-raw '{
"id": "12",
"jsonrpc": "2.0",
"method": "GetSystemStatus",
"params": {}
}'

GetNetworkInfo:

curl --location --request POST 'http://192.168.1.1/jrd/webapi' \
--header '_TclRequestVerificationKey: <YOUR_KEY>' \
--header 'Referer: http://192.168.1.1/index.html' \
--header 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36' \
--header '_TclRequestVerificationToken: <YOUR_TOKEN>' \
--header 'Content-Type: application/json' \
--data-raw '{
"id": "12",
"jsonrpc": "2.0",
"method": "GetNetworkInfo",
"params": {}
}'

setFirewallSwitch:

This example changes a toggle switch setting, in this case WAN ping. You can pass valid setting names in the params array for various set methods. Generally for toggle settings they take a 0 or 1 integer value, which represents a boolean true/false state, meaning on or off. You can find the right parameters by looking at the equivalent “Get” method in the SDK which hints at the parameters accepted.

curl --location --request POST 'http://192.168.1.1/jrd/webapi' \
--header '_TclRequestVerificationKey: <YOUR_KEY>' \
--header 'Referer: http://192.168.1.1/index.html' \
--header '_TclRequestVerificationToken: <YOUR_TOKEN' \
--header 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36' \
--header 'Content-Type: application/json' \
--data-raw '{
"id": "12",
"jsonrpc": "2.0",
"method": "setFirewallSwitch",
"params": {
"wan_ping_status": 1
}
}'

You can find the _TclRequestVerificationKey and _TclRequestVerificationToken values when you log into the web interface with a browser in the normal way, you’ll then want to inspect the request headers for webapi requests to find them. Some API calls only need the _TclRequestVerificationKey and Referer, others need both the key and token, along with the Referer and User-Agent. The token will expire when the session with the web interface times out, so you’ll need to log back in to get another valid token.

Dumping the configure.bin with binwalk

Another way to take a peek at some of the configuration/functionality is to extract the contents of the configure.bin generated by the backup and restore feature, this can be done by using a tool call binwalk.

Analysing the bin file we can see it made up of two gzip archives. No encryption appears to be used, just compression.

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
45 0x2D gzip compressed data, maximum compression,
from Unix, last modified: 2020-05-17 14:38:34
19224 0x4B18 gzip compressed data, maximum compression,
from Unix, last modified: 2020-05-17 14:38:30

Extracting the contents of both archives reveals that the offset 0x2D contains config files and an additional sysconfig.tar.gz. The 0x4B18, is another archive that contains further config files. Recursively extracting the contents gives you a look at the config files within:

Contents of the backup_dir within the 0x2D offset.
Contents of the backup_dir/sysconfig.tar.gz in the configure.bin
Config files which are restored on /etc/config
Contents of backup_dir at the 0x4B18 offset.

At this point you might have the idea to crack the shadow password for root, but that would be pointless, given it’s the worst kept secret that this router has hardcoded SSH root credentials:

  • Username: root
  • Password: oelinux123

It’s the main reason why SSH access was disabled entirely, but interestingly you can still authenticate with those details when using the FTP or Samba functions as well.

SQLite database

From analysing the contents of the configure.bin I discovered there is an user_info.db3 SQLite database present in both archives, which looks to be the same database except the one present within the 0x4B18 offset is slightly larger and has one extra database table, but otherwise the schema looks identical.

user_info.db3 database present in 0x2D
user_info.db3 database present in 0x4B18

I don’t know the exact purpose of this database, it does seem to have some form of relation to settings as there are specific setting values I have personally made to my own device, while others seem like defaults from Alcatel/EE.

That concludes my round up of the most interesting things I found hiding in the firmware!

--

--

James White

I'm a web developer, but also like writing about technical networking and security related topics, because I'm a massive nerd!