The manufacturer describes the product as follows:
The AES 256-bit Hardware Encryption seamlessly encrypts all data on the drive in real-time. The drive is compliant with GDPR requirements as 100% of the drive is securely encrypted. The built-in fingerprint recognition system allows access for up to eight authorised users and one administrator who can access the device via a password. The SSD does not store passwords in the computer or system’s volatile memory making it far more secure than software encryption.
The used test methodology regarding this research project, the considered attack surface and attack scenarios, and the desired security properties expected in a secure USB flash drive were already described in the first part of this article series.
When analyzing a hardware device like a secure USB flash drive, the first thing to do is taking a closer look at the hardware design. By opening the case of the Verbatim Executive Fingerprint Secure SSD, its printed circuit board (PCB) can be removed. The following figure shows the front side of the PCB and the used SSD with an M.2 form factor.
Here, we can already see the first three main components of this device:
NAND flash memory chips
a memory controller (Maxio MAS0902A-B2C)
a SPI flash memory chip (XT25F01D)
On the back side of the PCB, the following further three main components can be found:
a USB-to-SATA bridge controller (INIC-3637EN)
a fingerprint sensor controller (INIC-3782N)
a fingerprint sensor
The Maxio memory controller and the NAND flash memory chips are part of an SSD in M.2 form factor. This SSD can be read and written using another SSD enclosure supporting this form factor which was very useful for different security tests.
By having a closer look at the encrypted data, obvious patters could be seen, as the following hexdump illustrates:
# hexdump -C /dev/sda
00000000 7c a1 eb 7d 4e 39 1e b1 9b c8 c6 86 7d f3 dd 70 ||..}N9......}..p|
000001b0 99 e8 74 12 35 1f 1b 3b 77 12 37 6b 82 36 87 cf |..t.5..;w.7k.6..|
000001c0 fa bf 99 9e 98 f7 ba 96 ba c6 46 3a e5 bc 15 55 |..........F:...U|
000001d0 7c a1 eb 7d 4e 39 1e b1 9b c8 c6 86 7d f3 dd 70 ||..}N9......}..p|
000001f0 92 78 15 87 cd 83 76 30 56 dd 00 1e f2 b3 32 84 |.x....v0V.....2.|
00000200 7c a1 eb 7d 4e 39 1e b1 9b c8 c6 86 7d f3 dd 70 ||..}N9......}..p|
00100000 1e c0 fa 24 17 d9 4b 72 89 44 20 3b e4 56 99 32 |...$..Kr.D ;.V.2|
00100010 d8 65 93 7c 37 aa 8f 59 5e ec f1 e7 e6 9b de 9e |.e.|7..Y^.......|
in this hexdump output means that the previous line (here 16 bytes of data) is repeated one or more times. The first column showing the address indicates how many consecutive lines are the same. For example, the first 16 bytes
7c a1 eb 7d 4e 39 1e b1 9b c8 c6 86 7d f3 dd 70
are repeated 432 (0x1b0) times starting at the address
, and the same pattern of 16 bytes is repeated 32 times starting at the address
Seeing such repeating byte sequences in encrypted data is not a good sign, as we already know from part one of this series.
By writing known byte patterns to an unlocked device, it could be confirmed that the same 16 bytes of plaintext always result in the same 16 bytes of ciphertext. This looks like a block cipher encryption with 16 byte long blocks using Electronic Codebook (ECB)mode was used, for example AES-256-ECB.
For some data, the lack of the cryptographic property called diffusion, which this operation mode has, can leak sensitive information even in encrypted data. A famous example for illustrating this issue is a bitmap image of Tux, the Linux penguin, and its ECB encrypted data shown in the following Figure.
This found security issue was reported in the course of our responsible disclosure program via the security advisory SYSS-2022-010 and was assigned the CVE ID CVE-2022-28382.
The SPI flash memory chip (XT25F01D) of the Verbatim Executive Fingerprint Secure SSD contains the firmware for the USB-to-SATA bridge controller Initio INIC-3637EN. The content of this SPI flash memory chip could be extracted using the universal programmer XGecu T56.
When analyzing the firmware, it could be found out that the firmware validation only consists of a simple CRC-16 check using XMODEM CRC-16. Thus, an attacker is able to store malicious firmware code for the INIC-3637EN with a correct checksum on the used SPI flash memory chip.
For updating modified firmware images, a simple Python tool was developed that fixes the required CRC-16, as the following output exemplarily shows.
Thus, an attacker is able to store malicious firmware code for the INIC-3637EN with a correct checksum on the used SPI flash memory chip (XT25F01D), which then gets successfully executed by the USB-to-SATA bridge controller. For instance, this security vulnerability could be exploited in a so-called supply chain attack when the device is still on its way to its legitimate user.
An attacker with temporary physical access during the supply could program a modified firmware on the Verbatim Executive Fingerprint Secure SSD, which always uses an attacker-controlled AES key for the data encryption, for example. If the attacker later on gains access to the used USB drive, he can simply decrypt all contained user data.
This found security issue concerning the insufficient firmware validation, which allows an attacker to store malicious firmware code for the USB-to-SATA bridge controller on the USB drive, was reported in the course of our responsible disclosure program via the security advisory SYSS-2022-011 and was assigned the CVE ID CVE-2022-28383.
The hardware design of the Verbatim Executive Fingerprint Secure SSD allowed for sniffing the serial communication between the fingerprint sensor controller (INIC-3782N) and the USB-to-SATA bridge controller (INIC-3637EN).
The following Figure exemplarily shows exchanged data when unlocking the device with a correct fingerprint. The actual communication is bidirectional and different data packets are exchanged during an unlocking process.
In the course of this research project, no further time was spent to analyze the used proprietary protocol between the fingerprint sensor controller and the USB-to-SATA bridge controller, as a simpler way could be found to attack this device, which is described in the next section.
For the biometric authentication, a fingerprint sensor and a specific microcontroller (INIC-3782N) are used. Unfortunately, no public information about the INIC-3782N could be found, like data sheets or programming manuals.
For the registration of fingerprints, a client software (available for Windows or macOS) is used. The client software also supports a password-based authentication for accessing the administrative features and unlocking the secure disk partition containing the user data. The following Figure shows the login dialog of the provided client software for Windows.
During this research project, only the Windows software in form of the executable
was analyzed. This Windows client software communicates with the USB storage device via
) commands using the Windows API function
. However, simply analyzing the USB communication by setting a breakpoint on this API function in a software debugger like [x64dbg][x64db] was not possible, because the USB communication is AES-encrypted as the following Figure exemplarily illustrates.
Fortunately, the Windows client software is very analysis-friendly, as meaningful symbol names are present in the executable, for example concerning the used AES encryption for protecting the USB communication.
The following Figure shows the AES (Rijndael) functions found in the Windows executable
Here, especially the two functions named
were of greater interest.
Furthermore, runtime analyses of the Windows client software using a software debugger like x64dbg could be performed without any issues. And in doing so, it was possible to analyze the AES-encrypted USB communication in cleartext, as the following Figure with a decrypted response from the USB flash drive illustrates.
For securing the USB communication, AES with a hard-coded cryptographic key is used.
When analyzing the USB communication between the client software and the USB storage device, a very interesting and concerning observation was made. That is, before the login dialog with the password-based authentication is shown, there was already some USB device communication with sensitive data. And this sensitive data was nothing less than the currently set password for the administrative access.
The following Figure shows the corresponding decrypted USB device response with the current administrator password
in this example.
Thus, by accessing the decrypted USB communication of this specific IOCTL command, for instance using a software debugger as illustrated in the previous Figure, an attacker can instantly retrieve the correct plaintext password and thus unlock the device in order to gain unauthorized access to its stored user data.
In order to simplify the password retrieval process, a software tool named
As described previously, the client software for administrative purposes is provided on an emulated CD-ROM drive. As my analysis showed, the content of this emulated CD-ROM drive is stored as an ISO-9660 image in the hidden sectors of the USB drive, that can only be accessed using special IOCTL commands, or when installing the drive in an external enclosure.
output shows disk information using the Verbatim enclosure with a total of 1000179711 sectors.
# fdisk -l /dev/sda
Disk /dev/sda: 476.92 GiB, 512092012032 bytes, 1000179711 sectors
Disk model: Portable Drive
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xbfc4b04e
Device Boot Start End Sectors Size Id Type
/dev/sda1 2048 1000171517 1000169470 476.9G c W95 FAT32 (LBA)
output shows the information for the same disk when using an external enclosure where a total of 1000215216 sectors is available.
And in those 35505 hidden sectors concerning the tested 512 GB version of the Verbatim Executive Fingerprint Secure SSD, the ISO-9660 image with the content of the emulated CD-ROM drive is stored, as the following output illustrates.
# dd if=/dev/sda bs=512 skip=1000179711 of=cdrom.iso
35505+0 records in
35505+0 records out
18178560 bytes (18 MB, 17 MiB) copied, 0.269529 s, 67.4 MB/s
# file cdrom.iso
cdrom.iso: ISO 9660 CD-ROM filesystem data 'VERBATIMSECURE'
By manipulating this ISO-9660 image or replacing it with another one, an attacker is able to store malicious software on the emulated CD-ROM drive. This malicious software may get executed by an unsuspecting victim when using the device at a later point in time.
The following Figure exemplarily shows what an emulated CD-ROM drive manipulated by an attacker containing malware my look like.
The following output exemplarily shows how a hacked ISO-9660 was generated for testing this attack vector.
# mkisofs -o hacked.iso -J -R -V "VerbatimSecure" ./content
# dd if=hacked.iso of=/dev/sda bs=512 seek=1000179711
25980+0 records in
25980+0 records out
13301760 bytes (13 MB, 13 MiB) copied, 1.3561 s, 9.8 MB/s
As a thought experiment, this security issue concerning the data authenticity of the ISO-9660 image for the emulated CD-ROM partition could be exploited in an attack scenario one could call The Poor Hacker’s Not Targeted Supply Chain Attack which consists of the following steps:
Buy vulnerable devices in online shops
Modify bought devices by adding malware
Return modified devices to vendors
Hope that returned devices are resold and not destroyed
Wait for potential victims to buy and use the modified devices
This found security issue was reported in the course of our responsible disclosure program via the security advisory SYSS-2022-013 with the assigned CVE ID CVE-2022-28385.
I’ve really enjoyed reversing cheap/weird IoT devices in my free time. In early May of 2022, I went on an Amazon/AliExpress shopping spree and purchased ~15 cheap IoT devices. Among them was this mini portable router by GL.iNET.
GL.iNET is a leading developer of OpenWrt Wi-Fi and IoT network solutions and to my knowledge is a Chinese company based out in Hong Kong & USA. They offer a wide variety of products, and the company’s official website is www.gl-inet.com. The GL-MT300N-V2 firmware version I dove into was
released on April 29th, 2022 for the Mango model. The goodcloud remote cloud management gateway was
This blog will be separated into two sections. The first half contains software vulnerabilities, this includes the local web application and the remote cloud peripherals. The second mainly consists of an attempted hardware teardown.
I like to give credit where credit is due. The GL.iNET team was really awesome to work & communicate with. They genuinely care about the security posture of their products. So I'd like to give some quick praise for being an awesome vendor that kept me in the loop throughout the patching/disclosure process.
In terms of overall timeline/transparency, I started testing on-and-off between
May 2nd 2022
June 15th 2022
. After reporting the initial command injection vulnerability GL.iNET asked if I were interested in monetary compensation to find additional bugs. We ultimately agreed to public disclosure & the release of this blog in exchange for continued testing. As a result, I was given safe passage and continued to act in good faith. Lastly, the GL.iNet also shipped me their (GL-AX1800 / Flint) for additional testing. GL.iNet does nothave a BBP or VDP program, I asked, and was given permission to perform the tests I did. In other words, think twice before poking at their infrastructure and being a nuisance.
Having vulnerabilities reported should never be seen as a defeat or failure. Development and security are intertwined in a never ending cycle. There will always be vulnerabilities in all products that take risks on creativity, innovation, and change - the essence of pioneering.
A total of 6 vulnerabilities were identified in GL.iNet routers and IoT cloud gateway peripheral web applications:
1. OS command injection on router & cloud gateway (CVE-2022-31898)
2. Arbitrary file read on router via cloud gateway (CVE-2022-42055)
3. PII data leakage via user enumeration leading to account takeover
4. Account takeover via stored cross-site scripting (CVE-2022-42054)
5. Account takeover via weak password requirements & lack of rate limiting
6. Password policy bypass leading to single character passwords
OS Command Injection
The MT300N-V2 portable router is affected by an OS Command Injection vulnerability that allows authenticated attackers to run arbitrary commands on the affected system as the application’s user. This vulnerability exists within the local web interface and remote cloud interface. This vulnerability stems from improper validation of input passed through the ping (
) and traceroute (
) parameters. The vulnerability affects ALL GL.iNET product’s firmware
CVE ID: CVE-2022-31898
Access Vector: Remote/Adjacent
Security Risk: High
CVSS Base Score: 8.4
CVSS Vector: CVSS:3.1/AV:A/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H
I’ll run through the entire discovery process. There exists a file on disk
which essentially manages the application panels. Think of it as the endpoint reference in charge of calling different features and functionality. As seen below, the path parameter points to the endpoint containing the router feature’s location on disk. When the endpoint such as
is fetched its respective
files are loaded onto the page.
Through this endpoint, I quickly discovered that a lot of these panels were not actually accessible through the web UI’s sidebar seen below.
However, the functionality of these endpoints existed and were properly configured & referenced. Visually speaking, within the application they don’t have a sidebar «button» or action that can redirect us to it.
Here is a full list of endpoints that can not be accessed through web UI actions.
I should mention that some of these endpoints do become available after connecting modems, and other peripheral devices to the router. See the documentation for more details https://docs.gl-inet.com/.
As seen above, there exists a
endpoint. From experience, these are always interesting. This endpoint has the ability to perform typical
commands. Let’s quickly confirm that these files exist,
actions get called as defined within the
root@GL-MT300N-V2:/www/src/temple/ping# pwd && ls /www/src/temple/ping index.CSS index.html index.js
The expected usage and output can be seen below.
What’s OS Command Injection? OS command injection is a fairly common vulnerability seen in such endpoints. Its typically exploited by using command operators (
, etc,) that would allow you to execute multiple commands in succession, regardless of whether each previous command succeeds.
Looking back at the ping portal, the UI (frontend) sanitizes the user-provided input against the following regex which is a very common implementation for validating IPv4 addresses.
isn’t an expected IPv4 schema character so when the
check is performed, and any invalid characters will fail the request.
And we’re presented with the following error message.
We need to feed malicious content into the parameter
. If we do this successfully and don’t fail the check, our request will be sent to the web server where the server application act upon the input.
To circumvent the input sanitization on the front-end we will send our post request to the webserver directly using Burp Suite. This way we can simply modify the POST request without the front-end sanitization being forced. As mentioned above, using the
command separator we should be able to achieve command injection through the
parameters. If I’ve explained this poorly, perhaps the following visual can help.
Let’s give it a try. If you look closely at the POST request below the
which returned the present working directory of the application user. Confirming that OS Command Injection had been successfully performed.
Cool, but this attack scenario kinda sucks… we need to be authenticated, on the same network, etc, etc. One of the main reasons I think this is a cool find, and why it’s not simply a local attack vector is that we can configure our device with the vendor’s IoT cloud gateway! This cloud gateway allows us to deploy and manage our connected IoT gateways remotely.
I’ve discovered that there are roughly
devices configured this way. One of the features of this cloud management portal is the ability to access your device’s admin panel remotely through a public-facing endpoint. Such can be seen below.
As you may have guessed, command injection could be performed from this endpoint as well.
In theory, any attacker with the ability to hijack goodcloud.xyz user sessions or compromise a user account (both achieved in this blog) could potentially leverage this attack vector to gain a foothold on a network compromise.
Additional things you can do:
Scan internal network:
Obtain WiFi password of joined SSID's
Obtain WiFi password of routers SSID's
May 2, 2022: Initial discovery May 2, 2020: Vendor contacted May 3, 2022: Vulnerability reported to the vendor May 10, 2022: Vulnerability confirmed by the vendor July 6, 2022: CVE reserved July 7, 2022: Follow up with the vendor October 13, 2022: Fixed in firmware 3.215
Arbitrary File Read
The MT300N-V2 portable router, configured along sides the vendor’s cloud management gateway (goodcloud.xyz) is vulnerable to Arbitrary File Read. The remote cloud gateway is intended to facilitate remote device access and management. This vulnerability exists within the cloud manager web interface and is only a feature available to enterprise users. The device editing interface tools harbors the
functionality which is vulnerable to a broken type of command injection whose behavior is limited to performing arbitrary file reads. Successful exploitation of this vulnerability will allow an attacker to access sensitive files and data on the router. It is possible to read any arbitrary files on the file system, including application source code, configuration, and other critical system files.
CVE ID: CVE-2022-42055
Access Vector: Remote
Security Risk: Medium
Vulnerability: CWE-23 & CWE-25
CVSS Base Score: 6.5
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Enterprise users will have the
menu when editing their devices as seen below.
both allow you to read any file on disk when prepending
to the file you want to read.
I’m not sure why this happens. I have not been able to get regular command injection due to the way its calling
within busybox from what I assume is data passing through something similar to a ngrok tunnel. I can’t use funky delimiters or common escapes to simply comment out the rest of the operation. Anyhow, valid payloads would look like the following:
on my router and I’m going to read it from the cloud gateway. I could just as easily read the
files. Successfully cracking them offline would allow me access to both the cloud ssh terminal, and the login UI.
Funny enough, this action can then be seen getting processed by the logs on the cloud gateway. So definitely not «OPSEC» friendly.
May 25, 2022: Initial discovery May 25, 2022: Vendor contacted & vulnerability reported May 26, 2022: Vendor confirms vulnerability July 7, 2022: Follow up with the vendor October 13, 2022: Fixed in firmware 3.215
PII Data Leakage & User Enumeration
The MT300N-V2 portable router has the ability to be configured along sides the vendor’s cloud management gateway (goodcloud.xyz) which allows for remote access and management. This vulnerability exists within the cloud manager web interface through the device-sharing endpoint
GET request. Successful enumeration of a user will result in that user’s PII information being disclosed. At its core, this is a funky IDOR. The vulnerability affected the goodcloud.xyz prior to May, 12th 2022.
CVE ID: N/A
Access Vector: Network
Security Risk: Medium
Vulnerability: CWE-200 & CWE-203
CVSS Base Score: 6.5
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
I identified roughly
users which were enumerated via their username or email address. Successful enumeration compromises the confidentiality of the user. This vulnerability returns sensitive information that could be leveraged by a sophisticated, and motivated attacker to compromise the user’s account credentials.
This attack is performed after creating a regular
cloud gateway account and linking your GL.iNet device. In the image below we see that our device can be shared with another registered user.
The request and response for sharing a device with another user are seen below.
request against an existing user will disclosure the following account information:
- company name
- account creation time
- credential's salt (string+MD5)
- account email
- account user ID
- last login time
- password hash (MD5)
- phone number
- password salt (MD5)
- secret key
- security value (boolean)
- status value (boolean)
- account last updated time
- application user id
The password appears to be MD5 HMAC but the actual formatting/order is unknown, and not something I deem necessary to figure out. That being said, given all the information retrieved from the disclosure I believe the chances of finding the right combination to be fairly high. Below is an example of how it could be retrieved.
Additionally, I discovered no rate-limiting mechanisms in place for sharing devices. Therefore, it’s relatively easy to enumerate a good majority of valid application users using Burp Suite intruder.
Another observation I made, which was not confirmed with the vendor (so is purely speculation) I noticed that not every user had a
value associated with their account. I suspect that perhaps this secret code is actually leveraged for the 2FA QR code creation mechanism. The syntax would resemble something like this:
The GL.iNET team was extremely quick to remediate this issue. Less than 12h after reporting it a fix was applied as seen below.
May 11, 2022: Initial discovery May 11, 2022: Vendor contacted & vulnerability reported May 11, 2022: Vendor confirms vulnerability May 12, 2022: Vendor patched the vulnerability
Stored Cross-Site Scripting
The MT300N-V2 portable router has the ability to join itself to the remote cloud management configuration gateway (goodcloud.xyz) which allows for remote management of linked IoT devices. There exist multiple user input fields that do not properly sanitize user-supplied input. As a result, the application is vulnerable to stored cross-site scripting attacks. If this attack is leveraged against an enterprise account through the
invitation it can lead to the account takeover of the joined accounts.
CVE ID: CVE-2022-42054
Access Vector: Network
Security Risk: Medium
CVSS Base Score: 8.7
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:N/A:H
We’ll find the vulnerable inputs field in the «Group Lists» panel, in which a user can modify and create as many groups as they want.
The vulnerable fields are
. The payloads I used as a proof of concept are the following:
<img src=x onerror=confirm(document.cookie)>
<img src=x onerror=alert(document.cookie)>
Once the group is saved anytime the user either logs in or switches regions (Asia Pacific, America, Europe), logs in, or switched organication the XSS will trigger as seen below.
Can this be used maliciously? Unfortunately not with regular user accounts. With enterprise accounts yes, as we’ll see later. Here’s why. Realistically the only way to leverage this would be to share a device with a malicious named
fields with another user.
Even with the patch for the PII and User Enumeration vulnerability above, it is still possible to enumerate
‘s which is exactly what we need to send a shared device invitation to users. Below is an example request.
An attacker with a regular user account would create a group with a
. Then invite a victim to that group. When the victim would login the attacker would able to steal their sessions. Unfortunately with a regular user account, this isn’t possible.
If we share the device from
(victim). Here’s how the chain would go. After
creates the malicious group and sends an invitation to
he’s done. The victim
would login and receive the invite from
as seen below.
However, when we sign-out and back into
no XSS triggered, why? It’s because there is a difference between being a member of a shared group (a group shared by another user with you) and being the owner (you made the group shared and created) as can be seen below.
As seen above, a user of a shared group won’t have the malicious fields of the group translated to their «frontend».
HOWEVER! If you have a business/enterprise account or are logged in as a business/enterprise user you can leverage this stored XSS to hijack user sessions! All thanks to features only available to business users :).
Business features provide the ability to add «Sub Accounts». You can think of this as having the ability to enroll staff/employees into your management console/organization. If a user accepts our
invitation they become a staff/employee inside of our «organization». In doing so, we’ll have the ability to steal their fresh session cookies after they login because they’d become owners of the malicious group by association.
Let’s take this one step at a time. The Subscription Account panel looks like this.
I’m sure you can make out its general functionality. After inviting a user via their email address they will receive the following email.
I’ll try and break this down as clearly as I can.
User A (attacker) is
in red highlights.
User B (victim) is
in green highlights.
Step 1: Create a malicious company as
with XSS company name and description
Step 2: Invite
to the malicious company as
Step 3: Get boschko1 cookies and use them to log in as him
Below is the user info of
who owns the company/organization
. He also owns the «Group List»
the group which is part of the
has been sent an invitation email from
has accepted and has been enrolled into
has been given the
level access over the organization.
the user would see the following two «workspaces», his personal
and the one he has been invited to
is signed into his own team/organization
, if devices are shared with him nothing bad happens.
signes into the
are properly referenced/called upon when
The stored XSS in the malicious
fields (members of the
Group List) gets trigger when
is signed into
From our malicious
user, we will create a group with the following malicious
We can leverage the following website since we’re too lazy to spin up a digital ocean droplet. With this webhook in hand, we’re ready to steal the cookies of
fields simply log
organization owned by
and receive the cookies via the webhook.
As seen below, we get a bunch of requests made containing the session cookies of
Using the stolen
session cookies the account can be hijacked.
The GL.iNET team remediated the issue by July 15 with some pretty solid/standard filtering.
I attempted a handful of bypasses with U+FF1C and U+FF1E, some more funky keyword filtering, substrings, array methods, etc, and had no success bypassing the patch.
May 12, 2022: Initial discovery May 12, 2022: Vendor contacted & vulnerability reported May 13, 2022: Vendor confirms vulnerability May 19, 2022: Contact vendor about enterprise user impact July 7, 2022: Follow up with the vendor July 15, 2022: Vendor patched the vulnerability
Weak Password Requirements & No Rate Limiting
The MT300N-V2 portable router has the ability to join itself to the remote cloud management configuration gateway with its accounts created through goodcloud.xyz which allows for remote management of linked IoT devices. The login for goodcloud.xyz was observed to have no rate limiting. Additionally, user passwords only require a minimum of 6 characters and no special characters/password policy. This makes it extremely simple for an attacker to brute force user accounts leading to account takeover.
CVE ID: N/A
Access Vector: Network
Security Risk: Medium
CVSS Base Score: 9.3
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:N
As seen below when users create their cloud gateway
accounts they’re only required to have a password ≥6 with no capitalization, or special characters being required or enforced.
Additionally, due to having no rate limiting on login attempts by using Burp Suite intruder it’s trivial to spray users or brute force user accounts.
Below is an example of successfully obtaining the password for a sprayed user.
In total, I was able to recover the passwords of
application users. I never tested these credentials to log into the UI for obvious ethical reasons. All the data was reported back to the GL.iNET team.
May 18, 2022: Initial discovery May 24, 2022: Vendor contacted & vulnerability reported May 24, 2022: Vendor confirms vulnerability June 7, 2022: Vendor implements rate-limiting, patching the vulnerability
Password Policy Bypass
The MT300N-V2 portable router has the ability to join itself to the remote cloud management configuration gateway (goodcloud.xyz) which allows for remote management of linked IoT devices. For these cloud gateway accounts, while password complexity requirements were implemented in the original signup page, these were not added to the password reset page. The current lack of rate limiting this severely impacts the security posture of the affected users.
CVE ID: N/A
Access Vector: Network
Security Risk: Medium
CVSS Base Score: 6.7
CVSS Vector: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N
The reset password policy isn’t consistent with the registration and change password policy. As a result, it’s possible to bypass the 6-character password requirements to a single character. In general, the application should validate that the password contains alphanumeric characters and special characters with a minimum length of around eight. Additionally, I feel like it’s best practice not to allow users to set the previously used password as the new password.
As seen below, through the UI the password change has checks on the client side to ensure the password policy is respected.
In Burp Suite we can intercept the request and manually set it to a single character.
The request above is submitting successfully, and the new password for the
user has been set to
. The request below is the login request, as you can see it was successful.
May 26, 2022: Initial discovery May 26, 2022: Vendor contacted & vulnerability reported May 26, 2022: Vendor confirms vulnerability July 7, 2022: Follow up with the vendor July 15, 2022: Vulnerability has been patched
Additional Interesting Finds
I made a few interesting discoveries that I don’t consider vulnerabilities.
Before we jump into this one we have to quickly talk about ACL configuration. Basically, for
having appropriate access control over the invocations the application can make is very important. These methods should be strictly controlled. For more information on this refer to the Ubus-Wiki.
Once we’ve installed OpenWrt as seen above, the application will generate the list of
invocation methods for OpenWrt which is defined within the ACL configuration file
Not being a subject matter expert, I would however say that the above methods are well-defined. Methods in the file namespace aren’t simply «allow all» —
( "file": [ "*" ] )
if it were the case, then this would be an actual vulnerability.
has also a defined user in
that we can use for the management interface. This user is used to execute code through a large number of
With this information in hand, we should be able to login with these credentials. As a result, we will obtain a large number of methods that can be called, and get the
As seen in the following image this
value is used to call other methods defined in ACL config files.
Now we might look at the image above and think we have RCE of sorts. However, for some weird reason
is actually defined with valid read primitives within the
ACL config file.
As seen below attempting to read any other files will result in a failed operation.
I simply found this interesting hence why I am writing about it.
Let’s actually start the intended project! The GL-MT300N router looks like this:
It’s nothing fancy, the device has a USB port, 2 ethernet ports (LAN & WAN), a reset button, and a mode switch. Let’s break it open and see what hardware we have on hand.
Immediately there are some interesting components. There looks to be a system on a chip (SoC), SPI flash, and some SD RAM. There is also a serial port and what looks like could potentially be JTAG, and almost definitely UART.
In terms of chipsets, there is a MediaTek MT7628NN chip which is described as being a «router on a chip» the datasheet shows it is basically the CPU and it supports the requirements for the entry-level AP/router.
Looking at the diagram of the chip there is communication for UART, SPI, and I2C which are required to transfer data. This also confirms that this chip has a serial console that can be used for debugging. If this is still enabled this could allow us to access the box while it’s running and potentially obtain a shell on the system.
The second chip is the Macronix MX25L12835F SPI (serial flash chip) this is what attacked for most of the reversing process to obtain the application’s firmware. This is because the serial flash usually contains the configuration settings, file systems, and is generally the storage for devices lacking peripherals would be stored. And looking around on the board there is no other «storage device».
The third, and last chip is the Etron Technology EM68C16CWQG-25H which is the ram used by the device when it is running.
Connecting to UART
Let’s quickly go over what’s UART. UART is used to send and receive data from devices over a serial connection. This is done for purposes such as updating firmware manually, debugging, or interfacing with the underlying system (kind of like opening a new terminal in Ubuntu). UART works by communicating through two wires, a transmitter wire (TX) and a receiver wire (RX) to talk to the micro-controller or system on a chip (basically the brains of the device) directly.
The receiver and transmitter marked RX and TX respectively, need to connect to a second respective UART device’s TX and RX in order to establish a communication. I’m lucky enough to have received my Flipper Zero so I’ll be using it for this!
If you would like more in-depth information on UART see my blog on hacking a fertility sperm tester. We’ll connect our Flipper Zero to the router UART connection as seen below.
The result will be a little something like this.
Since I’m a Mac user connecting to my Flipper Zero via USB will «mount» or make the device accessible at
so if I want to connect to it all I need to do is run the command below.
Once I’ve ran the screen command, and the router is powered on, ill start seeing serial output confirming that I’ve properly connected to UART.
As you can see, I’ve obtained a root shell. Unprotected root access via the UART is technically a vulnerability CWE-306. Connecting to the UART port drops you directly to a root shell, and exposes an unauthenticated Das U-Boot BIOS shell. This isn’t something you see too often, UART is commonly tied down. However, «exploitation» requires physical access, the device needs to be opened, and wires connecting to pads RX, TX, and GND on the main logic board. GL.iNET knows about this, and to my knowledge doesn’t plan on patching it. This is understandable as there’s no «real» impact.
I’ll go on a «quick» rant about why unprotected UART CVEs are silly. The attack requires physical access to the device. So, an attacker has to be on-site, most likely inside a locked room where networking equipment is located, and is probably monitored by CCTV… The attacker must also attach an additional USB-to-UART component to the device’s PCB in order to gain console access. Since physically dismantling the device is required to fulfill the attack, I genuinely don’t consider this oversight from the manufacturer a serious vulnerability. Obviously, it’s not great, but realistically these types of things are at the vendor’s discretion. Moreover, even when protections are in place to disable the UART console and/or have the wide debug pads removed from the PCB there are many tricks one can use to navigate around those mechanisms.
Although personally, I believe it’s simply best practice for a hardware manufacturer to disable hardware debugging interfaces in the final product of any commercial device. Not doing so isn’t worthy of a CVE.
Getting back on track. Hypothetically if we were in a situation where we couldn’t get access to a shell from UART we’d likely be able to get one from U-Boot. There are actually a lot of different ways to get an application shell from here. Two of those techniques were covered in my blog Thanks Fo’ Nut’in — Hacking YO’s Male Fertility Sperm Test so I won’t be covering them here.
Leveraging the SPI Flash
Even though the serial console is enabled, if it weren’t, and we had no success getting a shell from U-Boot, our next avenue of attack might be to extract the firmware from the SPI flash chip.
The goal is simple, read the firmware from the chip. There are a few options like using clips universal bus interface device, unsoldering the chip from the board and connecting it to a specialized EPROM read/write device or attaching it to a Protoboard. I like the first option and using SOIC8 clips over hook clips.
At a minimum, we’ll need a hardware tool that can interact with at least an SPI interface. I’m a big fan of the Attify Badge as it’s very efficient and supports many interfaces like SPI, UART, JTAG, I2C, GPIO, and others. But you could other devices like a professional EPROM programmer, a Bus Pirate, beaglebone, Raspberry Pi, etc,.
Below is the pinout found on the datasheet for our Macronix MX25L12835F flash.
All you need to do is make the proper connections from the chip to the Attify badge. I’ve made mine according to the diagram below.
OK. I spent a solid two nights trying to dump the firmware without success. I’ve tried the Bus Pirate, Shikra, Attify, and a beaglebone black but nothing seems to work. Flashrom appears to be unable to read the data or even identify the chip, which is really weird. I’ve confirmed the pinouts are correct from the datasheet, and as seen below, flashrom supports this chip.
Attempting to dump the firmware results in the following.
So what’s going on? I’m not an EE so I had to do a lot of reading & talking to extremely patient people. Ultimately, I suspect this is happening because there is already a contention for the SPI bus (the MediaTek MT7628NN chip), and due to the nature of what we’re attempting to do, the router is receiving two masters connections and ours is not taking precedence. Currently, the MCU on the board is the master of the SPI chip, that’s the one where all the communication is going to and from. I wasn’t able to find a way to intercept, short, or stop that communication to make our Attify badge the master. In theory, a trick to get around this would be by holding down a reset button while reading the flash and just hoping to get lucky (I did this for ~2h and had no luck). Since our Attify badge would already be powered on, it could «IN THEORY» take precedence. This could, again «in theory» stop the chip from mastering to the MCU. But I haven’t been able to do so properly. I’ve spent ~8 hours on this, tying out multiple different hardware (PI, beaglebone, Attify, BusPirate) without success. I also suspect that being on a MacBook Pro with funky USB adapters could be making my situation worse.
Okay, we’re left with no other option than to go «off-chip». As previously mentioned, there are multiple ways to dump the contents of flash memory. Let’s try desoldering the component from the board, and use a chip reprogrammer to read off the contents.
My setup is extremely cheap setup is very sub-optimal. I don’t own a fixed «hot air station» or PDC mount. I’m just using a loose heat gun.
Our goal is to apply enough heat so that the solder joints melt. We need to extracted the chip with tweezers without damaging components. Easier said then done with my shitty station. differential heating on the board can be an issue. When a jet of hot air is applied to a PCB at room temperature, most of the heat is diffused to the colder spots, making the heating of the region of interest poor. To work around this you might think that increasing the heat will solve all of our issues. However, simply increasing the temperature is dangerous and not advisable.
When a component is put under increased thermal stress the temperature gradient increases along the board. The temperature difference on the board will produce thermal expansion in different areas, producing mechanical stress that may damage the board, break, and shift components. Not good. My setup is prone to this type of error because I don’t have a mounting jig for the heat gun that can control distance. I don’t have any high-temperature tape I can apply to the surrounding components so that they don’t get affected by my shaky hand controlling the heat source.
Regardless, for most small components, a preheating temperature of 250º C should be enough.
After a few minutes, I was able to get the chip off. However, there is a tiny shielded inductor or resistor that was affected by the heat which shifted when I removed the SPI with the tweezers. I wasn’t able to get this component back on the board. Fuck. I’m not an EE so I don’t fully understand the impact and consequences this has.
Let’s mount the SPI onto a SOP8 socket which we’ll then connect to our reprogrammer. Below is the orientation of the memory in the adapter.
This is, once again, quite a shitty reprogrammer. I actually had to disable driver signing to get the USB connection recognized after manually installing the shady driver. We’ll go ahead and configure our chip options knowing our SPI is Macronix MX25L12835F.
However, this also failed/couldn’t do any reads. I spend another ~5 hours debugging this. I thought it was the SOP socket clip so I soldered it onto a board and relayed the links to the reprogrammer but the results were the same.
After a while, I went ahead and re-soldered it to the main router PCB, and the device was fully bricked. To be quite honest, I’m not sure what I did wrong/at which step I made the mistake.
They say that failure is another stepping stone to greatness, but given that the entire reason for this purchase was to try out some new hardware hacking methodologies…. this was very bittersweet.
I remembered the squashfs information displayed in the UART log information. So, if we really wanted to reverse the firmware it’s still impossible. You can grab the unsigned firmware from the vendor’s site vendors here. Below are the steps you’d follow if you had successfully extracted the firmware to get to the filesystem.
So let’s check if they have any hardcoded credentials.
Luckily, they don’t.
The last thing I observed was that in the UBI reader there is an extra data block at the end of the image and somewhere in between that in theory could allow us to read code.
This purchase was supposed to be hardware hacking focused & I failed my personal objectives. To compensate I’ll share some closing thoughts with you.
In case you were wondering «how can the vendor prevent basic IoT hardware vulnerabilities? And is it worth it?». The answer is yes, and yes. This blog is long enough so I’ll keep it short.
Think of it this way. Having an extra layer of protection or some baseline obfuscation in the event that developers make mistakes is a good idea and something that should be planned for. The way I see it, if the JTAG, UART, or ICSP connector weren’t immediately apparent, this would’ve slowed me down and perhaps eventually demotivate me to push on.
The beautiful part is that hardware obfuscation is easy to introduce at the earliest stages of product development. Unlike software controls, which are implemented at later stages of the project and left out due to lack of time. There exist many different hardware controls which are all relatively easy to implement.
Since the hardware hacking portion of this blog wasn’t a great success I might as well share some thoughts & ideas on remediation & how to make IoT hardware more secure.
1. Removing the PCB silkscreen. Marks, logos, symbols, etc, have to go. There’s no real reason to draw up the entire board, especially if it’s in production.
2. Hide the traces! It’s too simple to follow the solder mask (the light green parts on this PCB) What’s the point of making them so obvious?
3. Hardware-level tamper protection. It’s possible to set hardware and even software fuses to prevent readout (bear in mind that both can be bypassed in many cases).
4. Remove test pins and probe pads and other debugging connections. Realistically speaking if the product malfunctions and a firmware update won’t fix it, the manufacturer likely won’t send someone onsite to debug /fix it. 99% of the time they’re simply going to send you a new one. So why have debug interfaces enabled/on production devices?
5. If you’re using vias as test points (because they make using a multimeter or a scope probe much easier, and are typically used by embedded passive components) it would be wise to use buried or blind vias. The cost of adding additional PCB layers is cheap if you don’t already have enough to do this.
6. Remove all chipset markings! It’s seriously so much harder & time-consuming to identify a chip with no markings.
7. Why not use tamper-proof cases, sensors (photodiode detectors), or one-way screws. Again some of these are not difficult to drill bypass. However, you’re testing the motivation of the attacker. Only really motivated reverse engineers would bother opening devices in the dark.
If you’re interested, here are some solid publications regarding hardware obfuscation I’d recommend the following papers:
I hope you liked the blog post. Follow me on twitter I sometimes post interesting stuff there too. This was a lot of fun! Personally, I’d strongly recommend going on Amazon, Alibaba, or Aliexpress and buying a bunch of odd or common IoT devices and tearing them down. You never know what you will find 🙂