ESLOCK Recovery
下載 : 這裡 (將 eslock 的檔案放進去 無須密碼 即可解鎖到上一層的目錄)
一個專用的命令列工具,用於在密碼遺失時復原 ES 檔案瀏覽器(ES File Explorer)加密的 .eslock 檔案——利用嵌入在檔案尾部(Footer)中的加密金鑰直接解密。
ES 檔案瀏覽器加密演算法
ES 檔案瀏覽器使用 AES-128-CFB(密碼回饋模式,128 位元區段)搭配一個固定的初始向量(IV)來加密檔案。加密後的輸出會以 .eslock 副檔名儲存為新檔案。
金鑰推導
密碼(UTF-8 字串)
│
▼
MD5 雜湊(16 位元組)
│
▼
AES-128 金鑰(MD5 摘要的前 16 位元組)
- 使用者的密碼以 MD5 進行雜湊。
- 完整的 16 位元組摘要直接作為 AES 金鑰。
- 沒有鹽值(Salt)、沒有迭代次數、沒有金鑰延展(未使用 PBKDF2 / scrypt / Argon2)。
檔案加密流程
根據檔案大小使用兩種模式:
完整加密(小檔案)
┌─────────────────────────────────┐
│ 原始檔案 │
│ (所有位元組) │
└────────────────┬────────────────┘
│
▼
AES-128-CFB 串流加密
IV = [0x00, 0x01, 0x02 … 0x0F]
Key = MD5(密碼)
│
▼
┌─────────────────────────────────┐
│ 加密後內容 │
├─────────────────────────────────┤
│ Footer │
│ (中繼資料 + 金鑰 + CRC) │
└─────────────────────────────────┘
輸出:file.eslock
所有位元組透過單一 AES-CFB 加密器實例處理(區塊之間不會重設加密器)。
部分加密(大檔案)
┌──────────────┬───────────────────────┬──────────────┐
│ 前段區塊 │ 中段 │ 後段區塊 │
│(1024 位元組)│ (明文) │(1024 位元組)│
└──────┬───────┴───────────────────────┴──────┬───────┘
│ │
▼ ▼
AES-CFB 加密 AES-CFB 加密
(全新加密器) (全新加密器)
│ │
▼ ▼
┌──────────────┬───────────────────────┬──────────────┐
│ 加密後的 │ 明文(直接透傳, │ 加密後的 │
│ 前段區塊 │ 未經處理) │ 後段區塊 │
├──────────────┴───────────────────────┴──────────────┤
│ Footer │
└──────────────────────────────────────────────────────┘
- 預設區塊大小 = 1024 位元組。
- 僅加密前端和後端各 1024 位元組的區塊。
- 檔案中段保持為明文。
- 每個區塊使用全新的加密器(相同金鑰 + 相同 IV)。
Footer 結構
Footer 附加在加密內容之後。檔案的最後 4 個位元組始終存放 footer 長度,作為解析的入口點。
| 欄位 | 大小 | 說明 |
|---|---|---|
| 加密旗標 | 1 B | 0xFF = 完整加密; 其他 = 部分加密 |
| 區塊大小 | 4 B(大端序) | 僅在部分加密時存在 |
| 檔名長度 | 1 B | 0xFF = 未儲存檔名 |
| 加密的檔名 | 可變長度 | AES-CFB 加密,使用相同金鑰 |
| 金鑰前綴魔術位元組 | 1 B | 固定為 0x10 |
| ★ AES 金鑰 ★ | 16 B | 解密金鑰,以明文儲存 |
| 金鑰後綴魔術位元組 | 1 B | 0x00 或 0x02 |
| CRC 填充 | 4 B | 全為零 |
| 儲存的 CRC32 | 4 B(大端序) | CRC 區段之前的 footer 位元組之 CRC |
| Footer 長度 | 4 B(大端序) | 包含此欄位在內的 footer 總長度 |
漏洞——為什麼能夠復原
AES 解密金鑰以明文形式儲存在加密檔案本身之中。
.eslock 格式更接近混淆而非加密。被「鎖定」的檔案攜帶著自己的鑰匙——就像一個上了鎖的箱子,卻把鑰匙貼在箱子外面。
| 弱點 | 說明 |
|---|---|
| 嚴重 金鑰儲存在檔案中 | 16 位元組的 AES 金鑰位於魔術位元組 0x10 和 0x00/0x02 之間。任何能讀取檔案的人都可以提取它。 |
| 嚴重 不需要密碼 | 因為金鑰在 footer 中,使用者的密碼完全不需要即可解密。 |
| 高 弱金鑰推導 | MD5(密碼) — 沒有鹽值、沒有迭代。即使金鑰沒有嵌入,密碼也能被輕易暴力破解。 |
| 高 固定 IV | IV = [0, 1, 2, …, 15] — 每個檔案、每個區塊都使用完全相同的 IV。破壞了 CFB 的語義安全性。 |
| 高 部分加密洩漏資料 | 在部分加密模式下,檔案中段全部為明文。媒體檔案的內容大部分可直接檢視。 |
| 中 僅有 CRC,無 MAC | CRC32 驗證的是結構完整性,而非檔案真實性。沒有 HMAC 或 AEAD。 |
復原流程
┌──────────────┐
│ 啟動 CLI │
└──────┬───────┘
│
┌──────▼───────┐
│ 掃描輸入路徑 │
│ 尋找 *.eslock│
└──────┬───────┘
│
┌────────────▼────────────┐
│ 對每個 .eslock 檔案 │
└────────────┬────────────┘
│
┌──────────▼──────────┐
│ 讀取最後 4 位元組 │
│ → footer_length │
└──────────┬──────────┘
│
┌───────▼────────┐ 否
│ 長度有效? ├──────┐
└───────┬────────┘ │
是 │ ┌────▼────────────┐
│ │ --heuristic? │
│ │ 掃描最後 128KB │
│ │ 尋找特徵碼 │
│ └────┬────────────┘
│ │
┌──────────▼───────────────▼┐
│ 解析 footer 結構 │
│ 提取:金鑰、CRC、 │
│ 加密模式、區塊大小、 │
│ 加密檔名 │
└──────────┬────────────────┘
│
┌───────▼────────┐
│ CRC 有效? │
└──┬──────────┬──┘
是 │ │ 否
│ ┌─────▼──────────┐
│ │ --ignore-crc? │
│ └──┬──────────┬──┘
│ 是 │ 否 → 跳過
│ │
┌─────▼───────▼──┐
│ 從 footer 提取 │
│ 16 位元組 │
│ AES 金鑰 │
└───────┬────────┘
│
┌─────────▼─────────┐
│ 解密原始檔名 │
│(如果有的話) │
└─────────┬─────────┘
│
┌─────────▼─────────┐
│ 解密檔案內容: │
│ 完整 → AES-CFB │
│ 整個串流 │
│ 部分 → 前段 + │
│ 後段區塊 │
└─────────┬─────────┘
│
┌─────────▼─────────┐
│ 寫入復原後的 │
│ 檔案至輸出目錄 │
└─────────┬─────────┘
│
┌─────▼──┐
│ 完成 │
└────────┘
環境需求
| 套件 | 版本 | 用途 |
|---|---|---|
| Python | ≥ 3.8 | 執行環境 |
| pycryptodome | ≥ 3.9 | AES-128-CFB 解密 |
使用的標準函式庫模組:argparse、hashlib、os、struct、sys、zlib、datetime、pathlib、typing。
pip install pycryptodome
使用方法
# 復原目前目錄下所有 .eslock 檔案
python ESLOCK_Recovery.py
# 復原單一檔案
python ESLOCK_Recovery.py photo.eslock
# 將目錄復原至指定輸出資料夾
python ESLOCK_Recovery.py ./encrypted ./recovered
# 使用啟發式搜尋處理損壞的檔案
python ESLOCK_Recovery.py --heuristic ./damaged
# 忽略 CRC 不符強制復原
python ESLOCK_Recovery.py --ignore-crc ./files
# 覆寫已存在的輸出檔案
python ESLOCK_Recovery.py --overwrite ./files ./output
| 參數 | 說明 |
|---|---|
input | 要復原的檔案或目錄(預設:目前目錄) |
output | 目的地目錄(預設:自動建立 recovered-YYYYMMDD-HHMMSS) |
--overwrite | 覆寫已存在的輸出檔案 |
--ignore-crc | 即使 footer CRC 檢查失敗仍繼續處理 |
--heuristic | 使用啟發式 footer 搜尋(適用於損壞/截斷的檔案) |
函式參考
密碼學
| 函式 | 說明 |
|---|---|
_make_aes(key) | 使用固定 IV [0..15] 建立 AES-128-CFB 加密器 |
decrypt_stream(…) | 解密檔案本體——處理完整及部分加密模式 |
decrypt_file_name(…) | 解密儲存在 footer 中的原始檔名(補齊至 16 位元組邊界) |
Footer 解析
| 函式 | 說明 |
|---|---|
read_footer_standard(path) | 快速讀取器——讀取最後 1024 位元組,從宣告的長度欄位解析 |
read_footer_heuristic(path) | 容錯讀取器——掃描最後 128 KB 尋找特徵碼與結構模式 |
_seq_parse(buf, total, offset) | 在指定的緩衝區偏移量嘗試解析 footer 結構(由啟發式掃描器使用) |
_read_tail(path, length) | 讀取檔案的最後 N 個位元組 |
_crc32(data) | 計算無號 32 位元 CRC32 |
復原
| 函式 | 說明 |
|---|---|
_recover_one(…) | 核心函式:讀取 footer → 提取金鑰 → 驗證 CRC → 解密 → 寫入輸出 |
main() | CLI 進入點:解析參數、收集檔案、執行復原、列印摘要 |
資料模型
| 類別 | 說明 |
|---|---|
EslockFooter | 儲存所有已解析的 footer 欄位:key、is_partial_encryption、encrypted_block_size、encrypted_original_name、stored_crc、calculated_crc、footer_offset、footer_length。屬性 is_crc_valid 檢查 CRC 是否吻合。 |
沒有留言:
張貼留言