Vulnerabilities in Burp 2.2.12

Author: Michael Hanselmann. Updated: December 13, 2018.

Burp (GitHub) is a network backup and restore program written by Graham Keeling. In early October 2018 I found several vulnerabilities by reading the source code and, after producing proof-of-concept exploits, reported them to Graham using responsible disclosure. He was extremely welcoming my input and spent a lot of time addressing the vulnerabilities. I contribed a couple of patches as well. An updated release was made available by Graham on December 12, 2018:

Reproduction environment

Burp 2.2.12 (commit 080c611 from September 28, 2018) built and running on CentOS 7.5.1804. Configure command:

./configure CFLAGS='-Wall -g -Og -fno-inline -fsanitize=address'

Arbitrary command execution via crafted client name

If an attacker has the ability to create files with attacker-controlled content at a predictable location on a Burp server it's possible to execute arbitrary commands, i.e. as a timer command. The proof-of-concept exploit functions as follows:

Write Burp server-side client configuration and malicious script to a newly created temporary directory. The name of the directory is assumed to be sufficiently unique and is used as the client name.

Generate new RSA key and matching certificate signing request (CSR).

Connect to Burp server on localhost and use relative path to client configuration as client name (i.e. /../../../../../../../../../../tmp/tmpxyz). The leading slash is required to avoid a check for a period in the looks_like_tmp_or_hidden_file function. The server will append the client name to the Burp server configuration directory and read the attacker-controlled client configuration.

Supply CSR to get a signed certificate from server. Store resulting certificate locally.

Reconnect to server on localhost using key and certificate. Simulate a check for the backup timer. The server will use a the timer command from the attacker-controlled client configuration and execute the malicious script.

There is also a way to execute commands on a Burp server with access to an already-authenticated Burp client. This method is not included in the proof-of-concept exploit and left as an exercise to the reader.

Unfortunately by the time of the delay the client has already received the message indicating a password mismatch. While a brute-force timing attack is still slowed down by the limit on the number of concurrent child processes it also results in a denial-of-service attack.

Heap buffer overflow in network protocol parser

The parse_readbuf_standard function in src/asfd.c is used to parse commands in communication between clients and servers connected via a TLS-encrypted TCP connection. The internal read buffer has a fixed-size length of 32032 bytes (ASYNC_BUF_LEN is 16000, thus (ASYNC_BUF_LEN * 2) + 32 = 32032). The command argument length sent by the peer is used without verification and a combination of the code in asfd_do_read_ssl and extract_buf allows for writing beyond the heap-allocated read buffer:

Depending on what is stored on the heap beyond the buffer the consequences can be more or less severe (the malicious command(s) can be sent at any time). In an AddressSanitizer-instrumented build the failure looks as follows:

Client-side buffer overflow when showing backup file list in long form

Backup clients can list the contents of backups in either a short form showing only file names or a long form with additional values such as file owner and mode. The latter uses the ls_long_output function in src/client/list.c which is prone to a buffer overflow vulnerability:

The code has multiple issues exploitable by a malicious backup server or a previously uploaded backup:

s is signed while the format string scanned for assumes an unsigned value (%08X along with a cast). On 32-bit client systems with their 32-bit ssize_t type overflowing the value beyond 231 - 1 (0x7fffffff) leads to negative values in *s which is converted again to the unsigned size_t type in the call to malloc. On 64-bit systems the size can be specified up to 232 - 1 (0xffffffff). Depending on the environment there may not be 4 GB of memory to spare and out-of-memory kills may follow.

The length parsed from the input data is not verified at all. Consequently it's possible to read beyond the input buffer and store the resulting bytes as an xattr value. We modify the stored extra metadata on the backup server simulating a malicious backup server to declare an excessively long value for the user.test1 xattr, in this case 16 kB:

A flaw in the server-side handling of paths passed from clients allows writing arbitrary files from the context of the Burp server. If the server runs as root privilege escalation is trivial. Even otherwise it's possible to gain code execution given the right circumstances.

Paths stored in a backup manifest are used without further verification. By injecting relative paths into the manifest it's possible to redirect file reads through a symlink, thus being able to read files from anywhere the Burp server has read access to by doing a restore. This vulnerability requires the attacker to be able control symlinks on the Burp backup server, e.g. by having direct (unprivileged) shell access.

Both problem stem from the fact that the server trusts paths given by the client, particularily the parameter to the CMD_FILE message. There may be other affected message codes or code paths.

The demonstration assumes that the Burp server runs as root, as does the client. Changed files are handled differently from new files, so we'll use a temporary directory to have new files:

Simulate malicious user wanting to read arbitrary files via a Burp client (test environment runs in Vagrant). We create directory into which poc2.txt will be written. By doing so a relative path is stored in the backup manifest. Before restoring later we'll replace the rootfs directory with a symlink.

As it turns out an unprivileged attacker can ensure that a certain location is a regular file during the scan phase and then change it to a symlink pointing to an otherwise unaccessible file before the file transfers are made. The backup will contain the contents of the unaccessible file and all it takes to gain access is to ask an administrator to restore an “accidentally” deleted file.

The proof-of-concept exploit demonstrates how to gain access to the SSH host keys. For simplicity GDB is used to pause the backup client before the transfer phase. A real attack could use inotify(7) to detect the scan phase with high reliability. Alternatively a large number of files and symlinks could be employed to simply race the Burp client.

SSH host and identification keys share the same format. To make everything look harmless we generate a dummy key (doing will also ensure the file contents need to be backed up as they changed):