#數據庫知識:
1、數據庫名,表名,列名,數據
2、自帶數據庫,數據庫用戶及權限
3、數據庫敏感函數,默認端口及應用
4、數據庫查詢方法(增加刪除修改更新)
#SQL注入產生原理:
代碼中執行的SQL語句存在可控變量導致
#影響SQL注入的主要因素:
1、數據庫類型(權限操作)
2、數據操作方法(增刪改查)
3、參數數據類型(符號干擾)
4、參數數據格式(加密編碼等)
5、提交數據方式(數據包部分)
6、有無數據處理(無回顯邏輯等)
#常見SQL注入的利用過程:
1、判斷數據庫類型
2、判斷參數類型及格式
3、判斷數據格式及提交
4、判斷數據回顯及防護
5、獲取數據庫名,表名,列名
5、獲取對應數據及嘗試其他利用
#黑盒/白盒如何發現SQL注入
1、盲對所有參數進行測試
2、整合功能點腦補進行測試
白盒參考后期代碼審計課程
利用過程:
獲取數據庫名->表名->列名->數據(一般是關鍵數據,如管理員)
案例說明:
在應用中,存在增刪改查數據的操作,其中SQL語句結構不一導致注入語句也要針對應用達到兼容執行,另外也需要明白黑盒中功能對應的操作方法;除此之外部分業務應用功能也要做到了解(如接受IP,UA,COOKIE,Referer等頭部),并且通過功能分析出對應SQL操作方法。
UA(User-Agent):
場景1:對UA設備指定顯示方案
漏洞成因:應用將 UA 頭直接拼接到 SQL 語句中(如用戶行為日志記錄、用戶身份驗證等場景),且未使用參數化查詢
接收UA頭信息,然后聯合sql語句去數據庫中直接查詢,沒有做任何防護,就會造成漏洞
// 錯誤示例:直接拼接UA頭到SQL
$ua = $_SERVER['HTTP_USER_AGENT'];
$sql = "INSERT INTO user_agent_log (user_id, ua) VALUES ('$user_id', '$ua')";
mysqli_query($conn, $sql);
黑盒時就看有沒有顯示內容,沒有顯示就直接盲測,對有可能接收的數據進行測試
白盒就直接查看源代碼即可,查sql語句等,
測試場景:
這個是接收ua頭到數據庫中查詢,所以是用的select語句
開去burp抓包,因為burp抓包時會忽略本地(127.0.0.1) 這個地址的,所以改成本機IP即可,或者換成burp中打開的瀏覽器也行
抓到數據包后
修改ua頭的值,看顯示部分是否變化
這里前面還有兩步一步是判斷是否有注入點,一步是判斷列數的; 這里是判斷數據回顯位置的
先使用’ 閉合前面的查詢語句,然后寫自己的查詢語句,最后加個# 將后面的查詢語句注釋掉
s
場景2:對UA設備進行信息記錄
網站對訪問者的IP等信息進行存儲,寫到數據庫中 ;對ua信息進行接收和存儲
這里就要用到insert語句中的注入語句了,再用select的注入語句是行不通的,會報錯,導致即使有漏洞也沒有用
XFF(X-Forwarded-For):
場景1:限制IP訪問功能
網站中某個網頁限制IP訪問,只允許特定的IP訪問;如果它是接收xff頭來確定IP的話,那么就有可能產生安全問題;可以防止非指定IP訪問,是要用xff頭接收IP時,會造成這個注入
這是一個登錄頁面,它會交給xff.php 去處理數據
提交數據后頁面提示 沒有權限訪問頁面
打開burp 抓包
這個是接收xff頭來判斷是否是允許訪問的IP,如果沒有xff頭就會用到下面的獲取方式,而下面的獲取方式是直接獲取當前的IP地址,就不能在burp中修改了,就無法造成注入;所以要看是否是xff頭驗證;黑盒中的話就直接加一個xff頭進行測試,有就有,沒有就換下一個測試地方
// 獲取 X-Forwarded-For 頭信息
$xff = $_SERVER['HTTP_X_FORWARDED_FOR']?? null;
?
// 如果 X-Forwarded-For 頭存在,取第一個 IP 地址
if ($xff) {
??? $client_ip = $xff;
} else {
??? // 如果 X-Forwarded-For 頭不存在,使用客戶端的 IP 地址
??? $client_ip = $_SERVER['REMOTE_ADDR'];
}
加一個xff頭測試,這里還是不給訪問,因為是測試,所以知道哪些IP 可以訪問;
修改IP為指定IP 后可以正常進行訪問頁面了,測試sql注入時,不需要知道指定的IP是什么,只要它查詢的是數據庫的里面的內容,那么隨便寫一個IP即可,后面接上測試語句即可;測試指定IP是什么是為了其他漏洞測試,這里如果想知道指定IP是什么就可以先重可能的IP段進行測試,比如服務器的IP,不行之后就用工具進行爆破,C段爆破
隨便寫一個IP測試,判斷回顯位置
?
查看數據庫名;后面就是查表名,數據了
場景2:記錄IP訪問日志
這個和ua頭記錄一樣是用的insert語句;后面會有實驗
?Cookie:
場景:開發人員在編寫一個根據用戶 ID(存儲在Cookie中)來查詢信息的功能
?接收cookie中的某個數據來確定訪問的用戶是登錄狀態,是否是VIP等,如果接收的數據在查詢時是在數據庫進行查詢,那么就可能會造成sql注入
訪問頁面時 提示 未發現用戶 要么是沒登陸;或者是權限不夠
判斷用戶語句
// 從 Cookie 中獲取用戶 ID
if (isset($_COOKIE['user_id'])) {
??? $user_id = $_COOKIE['user_id'];
} else {
??? die("未發現存在用戶訪問。");
}
?
// 構建存在 SQL 注入風險的查詢語句
$sql = "SELECT * FROM users WHERE id = $user_id";
?
// 執行查詢
$result = $conn->query($sql);
?
if ($result && $result->num_rows > 0) {
??? $row = $result->fetch_assoc();
??? echo "用戶名: ". $row['username']. "<br>";
??? echo "郵箱: ". $row['email'];
} else {
??? echo "未找到用戶信息。";
}
開burp抓包
黑盒中就測試時可以先注冊一個賬號,然后開啟抓包,查看接收的變量是什么,這里是user_id ;或者直接對變量名進行爆破
判斷列數
查看回顯位置
查看當前數據庫名
測試思路:
黑盒:
注冊一個賬號,查看數據包;fuzz字典爆破;findsomething 獲取參數
Referer: 和這個 csrf 漏洞相似
網站期望登錄請求來自于本站頁面,如果Referer是其他來源,則拒絕登錄。
數據庫中寫了一個表,里面的值是網址;后端代碼來判斷數據來源是否是來自數據庫里面的網址,是就放行,不是就拒絕;如果應用不是通過查詢數據庫中的網址是否符合,而是寫一個表或者一個文件存儲的話,就沒有sql注入了
// 獲取 Referer 頭信息
$referer = $_SERVER['HTTP_REFERER']?? '';
?
// 構建存在 SQL 注入風險的查詢語句,檢查 Referer 是否允許
$referer_sql = "SELECT * FROM allowed_referers WHERE referer_url = '$referer'";
$referer_result = $conn->query($referer_sql);
?
if ($referer_result->num_rows === 0) {
??? die("登錄請求來源不合法,拒絕登錄。");
}else{
??? $row = $referer_result->fetch_assoc();
??? echo "來源 ". $row['referer_url']. "<br>";
}
來到登錄頁面,隨便輸入賬號密碼測試
頁面顯示 來源不合法
開burp抓包,看到有referer 記錄來源
修改為正確網址,查看情況
網址隨便輸入什么都行,然后在后面輸入測試語句即可;這個是測試有幾列的
輸入3就報錯,說明是兩列
查詢數據庫名
實戰中就看有么有referer ,如果有就修改來源,測試網頁是否正常,不正常,則說明可能有sql注入;因為如果它只是接收后去文件里面比對或者和某個列表進行對比的話,就不會有sql注入
增刪改查大致功能應用:
MySQL三種報錯注入方式下的insert,update,delete命令注入示例 - impulse- - 博客園
select查詢:用戶查詢,新聞查詢
delete刪除:用戶刪除,新聞刪除
update修改:用戶修改,新聞修改
insert增加:用戶注冊,新聞添加
下面是用php代碼寫了一個數據庫增刪改查的功能的網頁
select語句 在查詢功能中注入
先輸入 ‘and 1=1# 測試可以查詢到數據
輸入 ’and 1=2 # 時 查詢不到,說明有注入點
輸入 zhangsan' order by 3 # 時能正常顯示數據,說明原查詢的sql語句的字段大于等于3;加大字段數測試
輸入字段數為4 時錯誤,所以字段數為3
輸入 ‘union select 1,2,3# 查看數據回顯位置
查看當前數據庫,后面操作和第53天的一樣,下面就是查表名,然后根據表名查數據,查用戶的數據(admin) ,查到后就用admin登錄網頁
insert語句 插入數據
用select一樣的語句 執行時,會報錯,所以要判斷當前輸入框中可能是用的什么方法,是增,刪,改,查 中的哪一種
?insert 語句的寫法就和select完全不一樣了,要用 ' or updatexml(1,concat(0x7e,(database())),0) or ' 這種
update語句 更新數據
delete 語句
顯示和其他三個不同,主要是因為顯示的內容不一樣,寫的語句也不一樣;因為查詢的數據內容要顯示出來,而其他三個只需要顯示成功或者失敗即可,不需要將刪除了什么或者修改了什么的內容顯示出來,它們沒有回顯;但是增刪改 的語句也是不一樣的 ;
為什么不能用查詢語句來進行其他語句的注入?主要是其他方法不支持,其他方法的數據不回顯等;比如說,就是查詢語句里面的union select 這個是聯合查詢,那其他方法沒有這個,所以用了這個就會報錯
#實例應用:
HTTP頭-XFF注入
https://mp.w eixin.qq.com/s/CiCxpHbW4IArB2nYSH-12w
https://mp.weixin.qq.com/s/_jj0o7BKm8CGEcn77gvdOg
加密還原+JSON注入
https://mp.weixin.qq.com/s/c3wji_LL_nuiskAKpg89pA
HTTP頭-403繞過
https://mp.weixin.qq.com/s/t0VH_9qmb1EuwPGiz3Bbcw