概述:MySQL 8 弱密码预研说明,根据目前的调研结果,暂时只能通过注入并调用的方式来检测,且这种方式会触发 MySQL 防爆破策略。

mysql 认证相关接口均以插件形式,全局导出了插件的列表

Cached_authentication_plugins * g_cached_authentication_plugins	0000000147BB31D0	13573

mysql 8.0.34 版本及之后共有三个插件:

  • sha256_password
  • mysql_native_password
  • caching_sha2_password

可以获取到这三个插件,但是 mysql 的安全机制上,没有办法调用插件对应的函数接口。在每个插件函数接口的内部都是通过 THD 的变量传递登录信息和登录结果的。

  THD *thd = current_thd;
  if (!thd->m_disable_password_validation) {
    if (my_validate_password_policy(inbuf, inbuflen)) return 1;
  }

插件导出接口的详细说明可查看这篇文章 [【弱密码】[【弱密码】MySQL8-密码Function|MySQL8-密码Function

安装及启动

  1. 设置环境变量,path添加 mysql\bin 目录
  2. mysqld install <服务名>
  3. mysqld -–initilalize –-console 这一步会生成 root 账户的密码,启动 MySQL 服务后使用这个密码登录
  4. net start <服务名>
  5. mysql -u root -p 生成的密码
  6. 登录后修改密码 alter user root@localhost identified by 'Admin@123';
  7. 创建不同插件的用户 create USER mnpweak2 IDENTIFIED WITH mysql_native_password BY 'admin123';

![](【弱密码】MySQL8-安装及插件机制/Pasted image 20250320180229.png)

相关导出接口

声明

typedef MYSQL * (__stdcall *pfn_mysql_init)(MYSQL *mysql);
typedef int(__stdcall *pfn_mysql_options)(MYSQL *mysql, enum mysql_option option, const void *arg);
typedef MYSQL * (__stdcall *pfn_mysql_real_connect)(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long clientflag);
typedef int(__stdcall *pfn_mysql_query)(MYSQL *mysql, const char *q);
typedef int(__stdcall *pfn_mysql_real_query)(MYSQL *mysql, const char *q, unsigned long length);
typedef MYSQL_RES * (__stdcall *pfn_mysql_store_result)(MYSQL *mysql);
typedef unsigned int(__stdcall *pfn_mysql_num_fields)(MYSQL_RES *mysql);
typedef MYSQL_FIELD * (__stdcall *pfn_mysql_fetch_field)(MYSQL_RES *mysql);
typedef MYSQL_ROW(__stdcall *pfn_mysql_fetch_row)(MYSQL_RES *mysql);
typedef const char * (__stdcall *pfn_mysql_error)(MYSQL *mysql);
typedef void(__stdcall *pfn_mysql_close)(MYSQL *sock);
typedef std::pair<bool, bool>(__stdcall *fastAuthenticate)(const std::string &authorization_id,
	const unsigned char *random,
	unsigned int random_length,
	const unsigned char *scramble,
	bool check_second);
 
	// 此外还导出了两个插件
	st_mysql_plugin				*m_builtin_caching_sha2_password_plugin = NULL;
	st_mysql_plugin				*m_builtin_mysql_password_plugin = NULL;

获取

		m_ptr_mysql_init = (pfn_mysql_init)GetProcAddress(hExe, "mysql_init");
		m_ptr_mysql_options = (pfn_mysql_options)GetProcAddress(hExe, "mysql_options");
		m_ptr_mysql_real_connect = (pfn_mysql_real_connect)GetProcAddress(hExe, "mysql_real_connect");
		m_ptr_mysql_query = (pfn_mysql_query)GetProcAddress(hExe, "mysql_query");
		m_ptr_mysql_real_query = (pfn_mysql_real_query)GetProcAddress(hExe, "mysql_real_query");
		m_ptr_mysql_store_result = (pfn_mysql_store_result)GetProcAddress(hExe, "mysql_store_result");
		m_ptr_mysql_num_fields = (pfn_mysql_num_fields)GetProcAddress(hExe, "mysql_num_fields");
		m_ptr_mysql_fetch_field = (pfn_mysql_fetch_field)GetProcAddress(hExe, "mysql_fetch_field");
		m_ptr_mysql_fetch_row = (pfn_mysql_fetch_row)GetProcAddress(hExe, "mysql_fetch_row");
		m_ptr_mysql_error = (pfn_mysql_error)GetProcAddress(hExe, "mysql_error");
		m_ptr_mysql_close = (pfn_mysql_close)GetProcAddress(hExe, "mysql_close");
 
		m_builtin_caching_sha2_password_plugin = (st_mysql_plugin*)GetProcAddress(hExe, "builtin_caching_sha2_password_plugin");
		m_builtin_mysql_password_plugin = (st_mysql_plugin*)GetProcAddress(hExe, "builtin_mysql_password_plugin");