UA-102556695-1
was successfully added to your cart.

探討NAS與Linux 全扇區LUKS加密架構與資料救援方法

當你對NAS或Linux OS(怕被查水表)做了全扇區加密(FDE),其實這是用了Linux Unified Key Setup 簡稱LUKS.
但做了這加密後,萬一系統出了狀況,硬碟損壞,需要資料救援,或忘記密碼等 又會是怎樣的狀況?
這篇將會做全面分析。

對於全扇區FDE架構建議先參考 OSSLab這篇文章

首先我們要瞭解現代NAS 陣列與分區與架構如圖

(圖引用自 http://www.hivestream.de/tag/luks.html)

在一般NAS下 多顆HDD mdadm 組好的md ,再分區,前面通常會分割給NAS作業系統,會割最大塊的數據分區會使用LVM來分割
回顧一下LVM 
Physical Volume, PV, 實體捲軸
Volume Group, VG, 捲軸群組:將許多的 PV 整合成為一個捲軸群組 (VG)
Logical Volume, LV, 邏輯捲軸:最終將 VG 再切割出類似 partition 的 LV 即是可使用的裝置了
最大數據分區直接切PV ,PV 組VG 

對sda2 分區做LUKS 加密格式初始化

對VG做LUKS 加密格式初始化 ,通常NAS加密Volume就是這樣格式化的
如果對整個MD加密,那當Raid參數丟失,因為沒有其他明文文件系統.推測Raid參數需要額外處理

掛載LUKS 跟分割成ext4 檔案系統,當然要割成其他檔案系統如BTRFS也沒問題.

在全扇區加密下的檔案分區在已經格式化完畢完工.

那NAS 全扇區加密對於資料救援會有何影響? 我們都知道全扇區加密 ,一定要有地方放metadata內有被加密的密鑰,

LUKS 是將明文數據切割成若干 同樣大小Blocks .
使用同一個對稱密鑰塊和確定的算法對每個數據塊進行加解密
所以在LUKS metadata完整之下 ,資料恢復會是這樣的
1.物理硬碟壞軌:如果有做Raid 1或5 或6,從其他顆正常扇區mirror 或XOR補齊.但如果小量整體,不會影響數據太大.
2.物理硬碟整顆損壞:如果有做Raid 1或5 或6,從其他顆正常扇區mirror 或XOR補.如果沒有則需要將單顆硬碟整顆修理好.
3.檔案刪除ext4:從日誌系統撈inode,或使用檔案碎片搜索法一樣可以正常運作.
4.分區掉失: 一樣可以資料恢復

如果有先組Raid,那Raid MD需要下面參數,整個MD資料才能正確無誤
1.走向方法
2.Stripe size
3.硬碟順序

所以假設Raid參數也丟失時候,就要利用文件系統來對Raid參數的逆向推測.
如果MD內留有未加密分區,則可以文件系統順利推導回去Raid參數.
但如果做了全扇區加密,那該怎推敲Raid參數?

此時利用LUKS metadata ,來推算出Master Key .再對每個單顆硬碟做扇區解密轉換,才可求得明文文件系統
再利用文件系統特性參數來拼湊出Raid參數.(本文最後有寫推導方法與轉換指令)

但假設是LUKS有問題狀況時候,我們要怎樣來做資料救援取得資料?
我們先來看整顆硬碟上LUKS架構

  • volume (or partition) header (208 byte)

  • 8 x key slots (48 byte*8)

  • key material(加密的split master key)

以上都為LUKS metadata(Header)

  • encrypted (volume) data:被加密的密文數據

第一 一定要先備份LUKS metdata(Header)指令如下 

查看LUKS  volume (or partition)  Header與Key slot

LUKS volume (or partition) header +key slot 為 592 bytes 結構如下 建議上下核對 以下為big eddian

OffsetSize(byte)ValueDescription

0

6

“LUKS\xba\xbe”

簽名  ASCII 顯示為 “LUKS..”

6

2

1

版本

8

32

 

加密方法 (Cipher name) etc:AES
Contains an ASCII string with an end-of-string character

40

32

 

加密模式 (Cipher mode) etc:xts-plain64
Contains an ASCII string with an end-of-string character

72

32

 

哈希模式 example:sha256
用於用戶密鑰計算和抗碎片分析(AF)擴散的散列方法
Contains an ASCII string with an end-of-string character

104

4

 

加密卷開始扇區 (Payload offset)

108

4

 

Master Key大小 (注意MK bits顯示為bit 通常為128,256,512) 
Contains the size of the key in bytes

112

20

 

Master Key digiest

132

32

 

Master key salt

164

4

 

Master key 迭代次數(MK iteration)

168

40

 

卷標識符(UUID)
包含帶有字符串結尾字符的ASCII字符串,該字符串由小寫的UUID組成

208

8 x 48

 

Key slots 48 bytes總共有8個

 

Key slot

Key slot is 48 bytes 內容如下

OffsetSize(byte)ValueDescription

0

4

 

狀態 (of key slot)
0x0000dead ⇒ inactive (dead)
0x00ac71f3 ⇒ active

4

4

 

Key material 迭代次數 (Iterations)

8

32

 

Key material salt

40

4

 

Key material 開始扇區 (encrypted SMK開始位置)

44

4

 

每個 (anti-forensic) stripes有多少個Key material
(AF stripes)

主密鑰Master Key:(MK)這是最關鍵的密鑰,如果記憶體中撈的出來你也不用需要User 密碼跟LUKS Header),直接就可以解開加密的數據
                                  MK大小值取決於卷標頭中MK bits 通常是128或256或512 bit。

要特別注意的,這跟WD全扇區硬體加密硬碟一樣,
當變更用戶密碼時候.MK主密鑰不會改變.變動的是Key material(encrypted SMK)

以下為LUKS 加密架構


下面為 LUKS 初始加密時寫入Header  Pseudo code

下面為LUKS metadata(Header+Key material)+用戶密碼的 ,完成mk驗證的Pseudo code

忘了用戶密碼怎辦?
一.由於LUKS沒有限制輸入密碼次數因此可以寫script嘗試爆破
下面參考自 https://nmattia.com/posts/2017-03-05-crack-luks-stutter-gnu-parallel.html

我們將過程存儲在一些shell變量中,以便我們可以將它傳遞給xargs,例如:

stutter將潛在的密碼短語提供給xargs,crack_maybe在PASS用潛在密碼短語替換所有出現的密碼後調用。如果cryptsetup返回任何其他內容2,我們退出exit 255,這基本上是告訴xargs停止的唯一方法(否則程式會繼續跑)  

二. bruteforce-luks (GitHub)是用調用cryptsetup API爆破, 速度有好一點

不過上面二個方法當然不夠有效率 
來看看hastcat爆破LUKS的思路…..

來從看一下LUKS 解密架構

第一次PBKDF2 跟AF轉換後就有有主密鑰,就可以開始嘗試做解密攻擊.
而不需要如正統流程再跑一次PBKDF2.這非常耗時間..
hashcat發現LUKS加密的過的數據會像是隨機數據
因此對數據區做熵檢查,如果熵低於某個閾值,可以假設密碼是正確的
要鏡像超過2MB超過LUKS metadata,就是因為需要包含數據區.

這思路很酷,以資料救援設備MRT來講.爆破FDE密鑰是利用驗證第0扇區 末端magic number為55AA
Hastcat開發者ATOM非常自豪他的LUKS破解思路,他認為比起市面上商業軟體如Passware都快了20倍以上.

Hashcat破解LUKS指令

首先要取得LUKS Header 2.1MB (是的 要比LUKS metadata再大一點)

-m = hash method – 14600 for LUK encryption
-a = Crack method – 0 for standard dictionary (3 for bruteforce)
-w = resource allocation – 3 for high
header.luks = 加密分區檔頭
Dictionary.txt = dictionary
-o = output luks_password.txt 
破解成功後.就可從luks_password.txt 的到用戶密碼.
爆破LUKS其實很困難,配上1070顯卡也才3000 Hash/s 上下
因此一般狀況下不必擔心LUKS 用戶密碼被破解

如果電腦沒有關機下 LUKS 還有其他破解方式:
1.假設是加密方法是AES,那可做記憶體鑑識 ,將記憶體DUMP ,使用findaes 找出在記憶體中的MK ,由於取得是MK就直接可以用了.
你要知道Ciper mode ,並且還有加密區大小..

比較有趣的是,這個方法在Mount時候就可以忽略到LUKS header..

那當LUKS metadata(Header+ encrypted SMK)如果遭遇硬碟扇區損壞跟惡意擦除
(通常是上門查水表,駭客立刻消滅密鑰,讓警方無法做數位鑑識) 這會是怎樣狀況?

先來看看破壞方法,比如sdX1為LUKS分區 下DD擦除 前面2MB就可.

這樣還有機會做資料救援嗎?

看一下主密鑰MK 是怎樣產生的

這會跟Hashcat不一樣 ,這時反而有User Key  (pwd) 
只求破解用masterKeyCandidate就可以做MK (沒做第二次PBKDF2驗證)

所以只需要下面
以下這二個 是最必備的
1.encryptedKey:Key material ,encrypted SMK 以最上面為例,大小4000 x 256bit=125KBytes
2.ks.salt:Key slot 中的Key material salt大小32 byte

以下為好推測的 同一款NAS 版本下應該是一樣
1.masterKeyLength 這好推測128 ,256,512bit
2.cipherSpec:cbc,ecb,xts
3.ks.iteration−count :Key material 迭代次數
4.ks.key−material−offset:Key slot中的Key material 開始扇區 (encrypted SMK開始位置)
5.ks.stripes:key slot Stripe 數.
6.encrypted :Material Key 大小=masterKeyLength *ks.stripes

算出 MK 一樣檢查對數據區檢查熵,一定低於某個閾值.就應該為正確MK
求得MK後,一樣直接用crypt 來解密

前述中若NAS Raid參數丟失,而Raid MD中只有單一加密分區,LUKS metadata也完整時,也是用上面方法生成MK先,
用上面指令做單顆硬碟解密,再根據解密文件系統分析推導出Raid參數.

看到這,確實當Key material (encrypted SMK),ks.salt(Key slot 中的Key material salt) 被擦除掉或是這部位硬碟扇區損壞.
也沒有從記憶體取中取得MK時.是無法解密資料的.

結論:
會寫這篇文其實是因為客戶遇到這樣狀況詢問我們,
一台6 Bay NAS做了加密,無法掛載資料,當初拿給原廠Support Team,但原廠也沒辦法作處理.
之後也不確定Raid組態跟LUKS Header是否還在.
(這方面來講,原廠其實不該負責客戶資料,或是客戶應該要做全硬碟備份先,再給原廠處理.)

OSSLab之前會使用LUKS攻擊工具但不知道其原理,
這次研究整合必須一次做到
1.一般NAS架構上套件安裝流程才會知道架構.
2.加密程式原始碼與演算法架構
3.多種破解手法與破解程式經驗與思路

最終編寫自己程式,才有機會做如此高難度的資安與資料恢復處理.

上面圖引用自與參考
https://github.com/libyal/libluksde
https://hashcat.net/forum/thread-6225.html
http://www.hivestream.de/tag/luks.html
http://netinfo-security.org/CN/abstract/abstract5917.shtml#
https://www.freebuf.com/articles/database/181010.html
https://blog.pnb.io/2018/02/bruteforcing-linux-full-disk-encryption.html
https://blog.appsecco.com/breaking-full-disk-encryption-from-a-memory-dump-5a868c4fc81e