首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

Linux 下 MySQL 命令行密碼隱藏技術原理與 C 語言實現

     編輯:MySQL 綜合教學

Linux 下 MySQL 命令行密碼隱藏技術原理與實現

在命令行直接傳遞密碼(如 mysql -p123456)會導致密碼在進程列表(ps -ef)中明文可見,構成嚴重安全風險。本文深度解析 MySQL 官方採用的 argv 重寫技術,並提供完整 C 語言演示代碼。

核心原理:argv 內存覆蓋

C 程式啟動時,命令行參數存儲在 argv 字符串數組中,佔用進程用戶空間內存。利用 memset() 將密碼參數對應的內存區塊覆蓋為 x(或任意字符),即可使 ps 讀取到的命令行參數變為掩碼形式,而不影響程式邏輯對原密碼的使用(因密碼通常在覆蓋前已拷貝至私有緩衝區)。

完整演示代碼(pwhide.c)

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>

int main(int argc, char *argv[]) {
    int i = 0;
    pid_t mypid = getpid();

    if (argc == 1) return 1;  // 缺少參數異常退出

    printf("argc = %d and arguments are:\n", argc);
    for (i = 0; i < argc; i++)
        printf("%d = %s\n", i, argv[i]);

    printf("Replacing first argument with x... Now run: ps p %d\n", (int)mypid);
    fflush(stdout);

    // 關鍵:用 'x' 覆蓋 argv[1](密碼參數)
    memset(argv[1], 'x', strlen(argv[1]));

    getc(stdin);  // 阻塞進程,便於另開終端觀察 ps 輸出
    return 0;
}

編譯與測試步驟

# 切換普通用戶模擬真實場景
su dabu
cd ~

# 編譯
gcc -o hide pwhide.c

# 運行,傳入模擬密碼
./hide "my_secret_pwd"

# 輸出示例:
# argc = 2 and arguments are:
# 0 = ./hide
# 1 = my_secret_pwd
# Replacing first argument with x... Now run: ps p 15585

此時程式阻塞於 getc(stdin),另開終端以 root 執行:

ps p 15585
# 輸出:
# PID TTY STAT TIME COMMAND
# 15585 pts/0 S+ 0:00 ./hide xxxxxxxxxxxxx  # 13 個 x 對應密碼長度

生產環境最佳實踐

  • MySQL 官方方案:mysql_config_editor 將憑證加密存儲於 .mylogin.cnf,登錄時自動讀取,命令行無密碼
  • 環境變量:export MYSQL_PWD='pwd'(注意:ps e 仍可見,較 argv 略優)
  • 選項文件:--defaults-file=/path/.cnf 指定包含 [client] password=... 的配置文件,權限設為 600
  • 交互式輸入:僅 mysql -u root -p,回車後提示輸入,進程列表無密碼

跨平台補充

  • FreeBSD/macOS:使用 setproctitle() 系統調用直接修改進程標題
  • Linux 現代內核:prctl(PR_SET_MM, PR_SET_MM_ARG_START, ...) 可更精確控制參數顯示

掌握 argv 重寫原理,不僅能理解 MySQL 密碼隱藏機制,更能在開發敏感信息處理程式時,從源頭消除命令行洩露風險。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved