首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

SQL 注入漏洞實戰:繞過登錄認證的經典 Payload 構造與原理剖析

     編輯:MySQL 資料庫相關知識

漏洞代碼還原


$sql = "SELECT * FROM users WHERE username='$name' AND password='$pwd'";
$query = mysql_query($sql);
if (mysql_fetch_array($query)) {
    header('Location: manager.php'); // 登錄成功跳轉
}

無任何過濾,直接拼接參數。

萬能密碼構造

輸入:


username: ' OR 1=1#
password: 任意

拼接後 SQL:


SELECT * FROM users WHERE username='' OR 1=1#' AND password='xxx'
  • # 為 MySQL 註釋符,後內容被忽略;
  • 1=1 恆真,WHERE 子句永遠成立;
  • 等價於 SELECT * FROM users,返回第一行(通常是管理員),直接登入後台。

單引號的作用

原始 SQL 中參數被單引號包裹:username='$name'。攻擊者輸入的 ' 閉合前引號,OR 1=1 注入新邏輯,# 註釋掉尾部殘留引號與密碼條件。

防禦失效場景:開啟 magic_quotes_gpc

若 magic_quotes_gpc=On,單引號被轉義為 \',上述 Payload 失效。但數字型參數無引號包裹仍可繞過:


$sql = "SELECT * FROM users WHERE uid=$uid"; // 無引號
-- 攻擊:uid=1 OR 1=1

三層防禦體系

  1. 參數化查詢(根治):PDO/mysqli 預處理,數據與代碼徹底分離;
  2. 輸入規範化:數字型 intval(),字符串 mysqli_real_escape_string();
  3. 最小權限原則:Web 賬號僅擁有 SELECT/INSERT/UPDATE,無 DROP/FILE/GRANT。

代碼級修復示例(PDO)


$stmt = $pdo->prepare("SELECT * FROM users WHERE username=? AND password=?");
$stmt->execute([$_POST['username'], $_POST['password']]);
if ($stmt->fetch()) { /* 登錄成功 */ }
本文旨在幫助開發者理解注入原理以編寫安全代碼,嚴禁用於非授權滲透測試。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved