Vulnerability Research
June 17, 2020
By Leo Dorrendorf

The Case of BusyBox Wget: A Long Overdue Fix

We were investigating a routine CVE found in a customer's firmware - CVE-2018-1000500 - when we stumbled upon a problem. Normally, when detecting a CVE that can be used to severely compromise a device, we advise the customer to upgrade the vulnerable component or at least to apply a patch. In this case, no upgrade was available! The CVE, issued in 2018, was not fixed despite having a high severity score (a CVSS of 8.1) which is s fairly unusual.

Digging deeper, we found that the researcher who originally disclosed the CVE also submitted a code patch to the maintainers, but that was rejected because the patch could break existing functionality. To explain what could happen and why, let's briefly review BusyBox and the affected component, BusyBox Wget.

What's the vulnerability?

The BusyBox toolkit implements a large number of Linux tools in a single executable and can even replace the Linux init system. Its small size and flexibility make it popular in embedded devices. The original Wget is a popular GNU utility for retrieving files from Internet servers using the command line and is often used in system scripts, including for sensitive purposes such as software updates.

BusyBox replaces Wget with a compact implementation of its own, which does not support all the security features and options. In particular, the BusyBox version of Wget will not abort a connection to a server with an invalid TLS certificate, only printing an error message and continuing download. Here's an illustration of the different behavior in regular Wget versus BusyBox wget:

The Case of BusyBox Wget- A Long Overdue Fix-1

In fact, the BusyBox TLS library does not support certificate validation! The original Wget does support it, and has to be launched with an explicit command line switch (--no-check-certificate) in case the certificate validation should be skipped.

This is where the vulnerability lies. The attacker can intercept a Wget HTTPS request by impersonating the server, either using DNS/ARP poisoning to redirect the request to an attacker-controlled server or by direct network traffic interception. Because the attacker does not need a valid TLS certificate, they can substitute any file for the requested download.

If the substituted download contains a software module or update, this can directly lead to the execution of malicious code. If the download contains configurations or data, the attacker can still affect the device's functionality in malicious ways. Even if clients initiating the download check the downloaded file for integrity and authenticity before installing or executing it (which they certainly should), the attacker still can cause denial of service by having the client download invalid multi-gigabyte files or never reaching the legitimate server.

How did the BusyBox team handle it?

The BusyBox maintainers argued that fixing their Wget to stop on an invalid TLS certificate could break existing functionality, including vital functions. This is a common conflict between security and engineering: a security practitioner would prefer to break existing functionality if it can be exploited, while an engineer would prefer to keep it, especially if the alternative meant breaking (and maybe even bricking) devices already deployed in the field.

The only change made was adding an error message in version 1.29.0 of the software, when detecting an invalid TLS certificate. The error message is printed to standard output and does not leave a permanent trace in the system's logs, meaning that the error can freely occur, and an attacker can exploit the device, without being noticed by an administrator.

How do we recommend handling it?

By now, BusyBox Wget supports launching an OpenSSL client in a sub-process to perform TLS operations. This client fully supports certificate validation logic, which is controlled through its command line options. Therefore we propose applying the following patch, which we contribute for public use, in order to explicitly add certificate checking to BusyBox Wget.

First of all, make sure the following configuration flag is set. This will make BusyBox use OpenSSL's TLS/SSL client instead of its internal implementation:

CONFIG_FEATURE_WGET_OPENSSL=y

Then apply the following patch:

index f2fc9e215..6bcc24421 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -662,7 +662,7 @@ static int spawn_https_helper_openssl(const char *host, unsigned port)
 	pid = xvfork();
 	if (pid == 0) {
 		/* Child */
-		char *argv[8];
+		char *argv[11];
 
 		close(sp[0]);
 		xmove_fd(sp[1], 0);
@@ -690,6 +690,11 @@ static int spawn_https_helper_openssl(const char *host, unsigned port)
 			argv[6] = (char*)servername;
 		}
 
+		/* Abort on bad server certificate */
+		argv[7] = (char*)"-verify";
+		argv[8] = (char*)"100";
+		argv[9] = (char*)"-verify_return_error";
+
 		BB_EXECVP(argv[0], argv);
 		xmove_fd(3, 2);
 # if ENABLE_FEATURE_WGET_HTTPS

After applying the patch, BusyBox Wget now behaves correctly, stopping on an invalid certificate (albeit with a generic error message): The Case of BusyBox Wget- A Long Overdue Fix-2

Conclusion

In our day and age, it should be self-evident to anyone working with embedded devices that it is not acceptable to sacrifice security in favor of functionality and release insecure code to the field. This approach is largely to blame for the poor security state of the connected (IoT) device market. Of course, high-grade, multi-layered, hardware-supported security is not suitable for every product due to the cost and time-to-market implications. However, vendors should expect their upstream components, including open-source code maintainers such as those of BusyBox, to implement reasonable security measures required to establish a first line of defense. In simple terms, you don't need 6-foot-high walls and state-of-the-art alarm systems in every home, but it's natural to expect at least a front door with a working lock.

Automated security scanning products such as VDOO Vision can help vendors establish a device's security profile, including any vulnerabilities introduced by third-party components. This can help vendors select their component providers more carefully, without needing fully-staffed verification testing or penetration-testing teams.

Share this post

You may also like