【學習中】sql注入-字符型注入
隨筆里的內容都是個人理解,如果有不對的地方,還望各位大佬多多指正。
一、理論基礎
1、什么是字符型注入
字符型注入它發生在用戶輸入的參數被后端系統當作字符串處理,并且這些參數值在SQL查詢語句中被特殊符號(如引號或括號)包裹起來的情況下。這種注入攻擊的原理在于,如果后端系統沒有對前端用戶輸入的數據進行適當的檢驗與過濾,用戶輸入的SQL語句片段可能會被直接傳入到后端并被執行,從而導致數據庫被非法訪問和操作。
字符型注入的特點在于,輸入的參數被視為字符串,并且在SQL查詢語句中被單引號或其他特殊符號包圍。例如,當用戶在前端輸入參數值,并且這個值被后端系統的SQL查詢語句直接使用,而沒有進行適當的驗證或轉義時,就可能發生字符型注入。攻擊者可以利用這種漏洞,通過在輸入參數中插入或“注入”額外的SQL代碼,來執行未授權的數據庫操作,如查看、修改、刪除數據等。
2、SQL
union:SQL 的"UNION"操作符用于將兩個或多個 SELECT 語句的結果組合成一個結果集。使用 UNION 時,各個 SELECT 語句必須返回相同數量的列,并且這些列的數據類型也必須相同。(這句話很重要)
database()是 MySQL 中的一個系統函數,用于返回當前操作的數據庫名。
version()是 MySQL 中的一個系統函數,用于返回 MySQL 服務器的版本信息。
group_concat() 是 MySQL 中的一個聚合函數,它可以將多個行的某個字段值連接成一個字符串。這在需要將具有相同鍵值的多個記錄合并為一個記錄時非常有用。
3、SQL注入產生的原理
可控變量
帶入數據庫查詢
變量未存在過濾或過濾不嚴謹
4、靶場
Pikachu漏洞練習平臺
5、工具
burpsuite
二、注入思路
1、確認注入點
(1)使用burpsuite抓取請求數據,請求為get,id為可控變量
(2)id=1 后面多輸入一個單引號 '
(3)提交請求后,發現SQL相關的報錯,這里我們可以獲得兩個信息
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 ''1''' at line 1
①數據庫為mysql,但是版本未知
②根據報錯信息推測,后臺執行的sql可能是這樣
|
1
|
select xxx from table_name where d='$id' id傳入的value為1',則sql變成了 select xxx from table_name where id='1''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 ''1''' at line 1 |
(4)構造sql,驗證后面的sql能否正常執行
因此,傳入 1' or 1=1 #
sql變成 select xxx from table_name where id='1' or 1=1 #'

執行查詢后,頁面返回正常,因此判斷后面構造的sql可以正常執行
2、確認返回結果的列數
只有確認sql執行后,可以返回的字段數量,咱們才能將查詢的結果正確返回到前端,實際上我們要確認的是后臺sql中xxx到底是幾個字段,select xxx from table_name where id='1' or 1=1 #'
這里使用order by 來確認sql執行的結果有幾列,判斷的邏輯是order by 后面跟上數字,就是按照第幾列來排序,如 order by 4 就是按照第4列進行排序
構造參數 1' order by 4 #
如果第4列不存在,則報錯如下
Unknown column '4' in 'order clause'
就這樣不停嘗試,就可以確認sql執行后的表有幾列。
當傳入參數為 1' order by 2# 時
頁面返回正常,說明sql執行后,有2列

3、頁面找返回結果展示的地方
上面確認了后臺sql執行后的結果為2列,這時候要考慮如何才能看到這部分數據,或者說怎么才能讓這部分數據展示在頁面上
因此,我們嘗試構造一個sql,使其經過數據庫執行后,返回我們指定的內容給前端頁面。
傳入參數 1' and 1=2 union select 1,2 #
sql變成如下形式:
select c1,c2 from table_name where id='1' and 1=2 union select 1,2 #'
執行后,可以看到uid顯示為 1,email顯示為2,說明返回為兩列,一列是uid,一列是email,我們可以把要查詢的內容,通過uid和email這兩個字段,傳給前臺頁面

我們通過union將前后兩個sql的查詢結果合并了起來。結果都打印了出來,這樣我們把1和2的位置確定了,后面就是通過這兩個位置我們來展示sql執行的結果
這里有一個地方需要注意,如果頁面不支持顯示多個結果,比如這里顯示了兩個hello和兩個email,我們可以將id改成負數或者加上 and 1=2,目的是屏蔽id查詢到的結果,讓頁面只顯示我們輸入的sql語句的內容。
到這里,基本上這條路通了,應該就可以查到很多信息了。
4、找數據庫和版本
構造參數 1' union select databases(),version() #
結合上面的信息我們知道,后臺為mysql數據庫,版本為8.0.26-0ubuntu0.20.04.2,當前所使用的庫名為pikachu
5、找數據表
mysql中information_schema數據庫是MySQL自帶的,它提供了訪問數據庫元數據的方式。什么是元數據呢?元數據是關于數據的數據,如數據庫名或表名,列的數據類型,或訪問權限等。
所以我們可以通過information_schema庫來查找表和字段
TABLES表:提供了關于數據庫中的表的信息(包括視圖)。詳細表述了某個表屬于哪個schema,表類型,表引擎,創建時間等信息。是show tables from schemaname的結果取之此表。
COLUMNS表:提供了表中的列信息。詳細表述了某張表的所有列以及每個列的信息。是show columns from schemaname.tablename的結果取之此表。
select table_name from information_schema.tables where table_schema='pikachu';
使用group_concat 將結果變成一個字符串
select group_concat(table_name) from information_schema.tables where table_schema='pikachu';
所以,請求中sql構造如下
1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='pikachu' #
我們已經獲取到了數據表
6、找字段名
找字段和上面的邏輯一樣,我們去查詢information_schema.columns
這里users表,我們推測應該保存用戶密碼
所以,sql構造如下
1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' #
7、獲取目標信息
還是同樣的邏輯,我們就可以獲取用戶以及密碼了
獲取所有用戶
1' union select 1,group_concat(username) from users #
獲取admin用戶的密碼
1' union select username,password from users where username='admin' #
8、解密
e10adc3949ba59abbe56e057f20f883e 32位,有可能是md5加密,嘗試使用下方網站解密,解密后的結果為123456
https://www.cmd5.com/

浙公網安備 33010602011771號