Brute-Force MySQL Password From a Hash

栏目: IT技术 · 发布时间: 4年前

内容简介:There is no magic: as long as only hashes are stored and not the original passwords, the only way to recover the lost password is to brute force it from the known hash.Interestingly, if a hacker has access to password hash, he doesn’t need to recover a pla

Brute-Force MySQL Password From a Hash In most cases, MySQL password instructions provide information on changing MySQL user passwords on the production system (e.g., reset root password without restart ). It is even recommended to change passwords regularly for security reasons. But still, sometimes DBA duties on legacy systems offer surprises and you need to recover the original password for some old users.

There is no magic: as long as only hashes are stored and not the original passwords, the only way to recover the lost password is to brute force it from the known hash.

Note on Security and mysql-unsha1 Attack

Interestingly, if a hacker has access to password hash, he doesn’t need to recover a plain text password from it. It doesn’t matter how strong the password and how strong the hashing algorithm inside the auth plugin, because due to MySQL protocol design, hash is enough to connect to a database with a patched version of MySQL client. It means, if a hacker has access to a database backup, he automatically receives all needed information (SHAs) for connecting to a running database. See for the attack details .

Since MySQL 8.0, caching_sha2_password auth plugin is used by default, and this plugin brings a stronger sha256 function instead of sha1 used in mysql_native_password plugin. For authentication with caching_sha2_password plugin, it is also enough to have only a hash, see for the implementation details .

So, caching_sha2_password plugin doesn’t add any additional security compared to  mysql_native_password plugin: if you have a hash, you don’t need plain text password to be able to connect to the instance with a patched MySQL client.

Still, if you want to have a password that works with an unmodified client, however, you need to do some hacking, see instructions below.

Dump Hash

Let’s return to the password recovery. First of all, we need to dump hashes.

MySQL 5.7 uses the mysql_native_password auth plugin by default and we can dump sha1 hashes with the following command.

% mysql -Ns -uroot -e "SELECT SUBSTR(authentication_string,2) AS hash FROM mysql.user WHERE plugin = 'mysql_native_password' AND authentication_string NOT LIKE '%THISISNOTAVALIDPASSWORD%' AND authentication_string !='';" > sha1_hashes

MySQL 8.0 uses the caching_sha2_password auth plugin by default and we can dump sha256 hashes as follows.

% mysql -Ns -uroot -e "SELECT CONCAT('\$mysql',LEFT(authentication_string,6),'*',INSERT(HEX(SUBSTR(authentication_string,8)),41,0,'*')) AS hash FROM mysql.user WHERE plugin = 'caching_sha2_password' AND authentication_string NOT LIKE '%INVALIDSALTANDPASSWORD%' AND authentication_string !='';" > sha256_hashes

If you need to get the root password hash and don’t have a user who has read access to mysql.user table, you should start mysqld with the --skip-grant-tables option, see the official doc for details .

Run Linode GPU Instance

For password recovery, it is needed to run calculations on some powerful GPUs, and there are not so many cloud providers with GPU instances on the market. Linode is one of the remarkable cloud providers if you need a simple, reliable provider with a really helpful support department. Linode has a powerful CLI tool that simplifies “bash” automation a lot. Also, for more serious automation, the official Terraform provider exists.

128GB GPU Linode instance password recovery speed is 30000 MH/s (million hashes per second), which is very good. It needs only 2 hours to brute-force an 8-characters MySQL 5.7 passwords (upper case, lower case, numbers). Instance price is only 6 USD/Hour.

For example, the other biggest cloud provider (4 x NVIDIA Tesla V100 instance) with the same recovery speed cost two times more expensive – 12.24 USD/Hour.

Prepare Dictionary

The password brute-forcing is done based on dictionaries. We will use a small rockyou dictionary as an example, to show how it goes.

% wget 'https://gitlab.com/kalilinux/packages/wordlists/-/raw/kali/master/rockyou.txt.gz'
 
% gunzip rockyou.txt.gz

You can find really good dictionaries on the weakpass dot com website.

But it is possible that even the largest dictionary will not be enough for the recovery. In such a case you should check if the validate_password plugin is enabled and prepare a dictionary based on it. Check it as follows:

% mysql -uroot -e "SHOW VARIABLES LIKE 'validate_password%';"
 
+--------------------------------------+-------------------------------+
| Variable_name                        | Value                         |
+--------------------------------------+-------------------------------+
| validate_password_check_user_name    | ON                            |
| validate_password_dictionary_file    | /var/lib/mysql/prohibited.txt |
| validate_password_length             | 8                             |
| validate_password_mixed_case_count   | 1                             |
| validate_password_number_count       | 1                             |
| validate_password_policy             | STRONG                        |
| validate_password_special_char_count | 1                             |
+--------------------------------------+-------------------------------+

If the output of this command is empty, it means that the plugin is disabled. You can find some more details about the plugin in one of our previous blog posts about it, Improving MySQL Password Security with Validation Plugin .

The validate_password_policy field is the most important one here. It can have the following values:

Policy Tests Performed
0 or LOW Length
1 or MEDIUM Length; numeric, lowercase/uppercase, and special characters
2 or STRONG Length; numeric, lowercase/uppercase, and special characters; dictionary file

If validate_password_policy=STRONG and validate_password_dictionary_file is set, we need to exclude passwords from validate_password_dictionary_file :

cat huge-dictonary.txt \
    | pw-inspector -m 8 -M 32 -l -u -n -p \
    | sort -u \
    | grep -F -v -x -f prohibited.txt \
    > reduced-dictonary.txt

In the example above:

-m 8 is the minimal length of the password, value from validate_password_length variable;

-M 32 is the maximal length of the password, for replication passwords the maximal length is 32 characters, see MySQL release nodes ;

-n password should contain numbers, see validate_password_number_count variable;

-l -u password should contain lowercase/uppercase characters, see validate_password_mixed_case_count variable;

-p password should contain special characters, see validate_password_special_char_count variable;

prohibited.txt is a file from validate_password_dictionary_file variable;

huge-dictonary.txt is the initial dictionary;

reduced-dictonary.txt is the new dictionary without words from prohibited.txt .

If the dictionary attack failed, you have to create your own dictionary for the brute force. In this case, we recommend using one of the following tools: crunch, maskprocessor or via Hashcat options.

Compile Hashcat

In the case of MySQL 8.0, the latest version of hashcat from the master branch should be compiled due to the fact that code from https://github.com/hashcat/hashcat/issues/2305 wasn’t released in any version right now.

% sudo apt -y install make gcc
 
% git clone https://github.com/hashcat/hashcat.git
 
% cd hashcat
 
% make
 
% sudo make install

Enable OpenCL for NVIDIA

Update to the latest software, disable the nouveau driver and reboot:

% sudo apt update && sudo apt full-upgrade -y
 
% echo -e "blacklist nouveau\noptions nouveau modeset=0\nalias nouveau off" | sudo tee /etc/modprobe.d/blacklist-nouveau.conf
 
% sudo update-initramfs -u
 
% reboot

Install the proprietary driver and reboot

% sudo apt install -y nvidia-cuda-toolkit ocl-icd-libopencl1 
 
% sudo apt install -y nvidia-driver-440 nvidia-utils-440
 
% sudo apt remove mesa-opencl-icd
 
% reboot

Check the driver

% sudo nvidia-smi
 
% hashcat -I

Run Password Recovery

For mysql_native_password (MySQL 5.7) use the 300 code:

% hashcat -m 300 -a 0 -D 2 -O -w 3 ./sha1_hashes ./rockyou.txt

For caching_sha2_password (MySQL 8.0) use the 7401 code:

% hashcat -m 7401 -a 0 -D 2 -O -w 3 ./sha256_hashes ./rockyou.txt

If your password was recovered correctly, you can run the same command with the --show option to display the password.

% hashcat -m 300 -a 0 -D 2 ./sha1_hashes ./rockyou.txt --show
 
0913bf2e2ce20ce21bfb1961af124d4920458e5f:new_password

Here new_password is the correct answer.

Conclusion

8-chars password with lower and upper case letters and digits for MySQL 5.7 can be recovered only in 2 hours on the Linode GPU instance. The same password for MySQL 8.0 can be recovered in 2.8 years. But in general, hackers don’t need to recover plain text passwords at all (see “mysql-unsha1 attack” section above). To reduce risks, it is needed to protect the content of mysql.user table, there are a few things that can be done:

  1. don’t store hashes in MySQL itself, for example, use LDAP plugin for Percona Server
  2. or use encryption at rest with HashiCorp Vault plugin
  3. or at least use encryption at rest for backups .

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

WWW信息体系结构(影印版第2版)

WWW信息体系结构(影印版第2版)

Louis Rosenfeld / 清华大学出版社 / 2003-6 / 49.8

如今的网站和内联网已经变得比以前越来越大,越来越有价值,而且越来越复杂,同时其用户也变得更忙,也更加不能容忍错误的发生。数目庞大的信息、快速的变化、新兴的技术和公司策略是设计师、信息体系结构构建师和网站管理员必须面对的事情,而这些已经让某些网让看起来像是个快速增长却规划很差的城市——到处都是路,却无法导航。规划精良的信息体系结构当前正是最关键性的。 本书介绍的是如何使用美学和机械学的理念创建......一起来看看 《WWW信息体系结构(影印版第2版)》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具