LUKS2 Başlık Değiştirilebilirliği ve Null-Cipher Abuse in Confidential VMs’de

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

TL;DR

  • Birçok Linux-based Confidential VMs (CVMs) — AMD SEV-SNP veya Intel TDX üzerinde çalışan — kalıcı depolama için LUKS2 kullanır. Disk üzerindeki LUKS2 başlığı değiştirilebilir olup depolama bitişiğindeki saldırganlara karşı bütünlük korumasına sahip değildir.
  • Başlık içindeki veri segmenti şifrelemesi null cipher olarak ayarlanırsa (ör. “cipher_null-ecb”), cryptsetup bunu kabul eder ve guest disk şifreli olduğunu zannederken şeffaf şekilde plaintext olarak okur/yazar.
  • cryptsetup 2.8.0 ve öncesinde null ciphers keyslots için kullanılabiliyordu; 2.8.1’den itibaren boş olmayan parolaya sahip keyslots için reddediliyor, ancak null ciphers volume segmentleri için izinli kalmaya devam ediyor.
  • Remote attestation genellikle VM kodunu/yapılandırmasını ölçer, değiştirilebilir dış LUKS başlıklarını değil; açık bir doğrulama/ölçüm yapılmadıkça, disk yazma erişimine sahip bir saldırgan plaintext I/O zorlayabilir.

Background: LUKS2 on-disk format (what matters for attackers)

  • Bir LUKS2 cihazı, başlık ile başlar ve ardından şifrelenmiş veri gelir.
  • Başlık, iki özdeş binary bölüm kopyası ve bir JSON metadata bölümü ile bir veya daha fazla keyslots içerir.
  • JSON metadata şunları tanımlar:
    • etkin keyslots ve bunların sarmalayan KDF/cipher’ları
    • veri alanını tanımlayan segments (cipher/mode)
    • digests (ör., passphrase’leri doğrulamak için volume anahtarının hash’i)
  • Tipik güvenli değerler: keyslot KDF argon2id; keyslot ve data segment şifrelemesi aes-xts-plain64.

Hızlıca segment cipher’ını doğrudan JSON’dan inceleyin:

# Read JSON metadata and print the configured data segment cipher
cryptsetup luksDump --type luks2 --dump-json-metadata /dev/VDISK \
| jq -r '.segments["0"].encryption'

Kök neden

  • LUKS2 başlıkları depolama manipülasyonuna karşı doğrulanmaz. Bir host/depolama saldırganı, cryptsetup tarafından kabul edilen JSON metadata’sını yeniden yazabilir.
  • cryptsetup 2.8.0 itibarıyla, bir segmentin şifrelemesini cipher_null-ecb olarak ayarlayan başlıklar kabul edilir. null cipher anahtarları yok sayar ve düz metin döndürür.
  • 2.8.0 öncesine kadar, null cipher’lar keyslot’lar için de kullanılabiliyordu (keyslot herhangi bir passphrase ile açılır). 2.8.1’den itibaren, null cipher’lar boş olmayan parolaya sahip keyslot’lar için reddediliyor, ancak segmentler için izin verilmeye devam ediyor. Sadece segment cipher’ını değiştirmek, 2.8.1 sonrası hâlâ düz metin I/O ile sonuç verir.

Tehdit modeli: neden attestation varsayılan olarak sizi korumadı

  • CVM’ler, güvensiz bir hostta gizlilik, bütünlük ve özgünlük sağlamayı amaçlar.
  • Remote attestation genellikle VM imajını ve başlatma yapılandırmasını ölçer; güvensiz depolamada bulunan değişken LUKS başlığını değil.
  • Eğer CVM’iniz diskteki başlığa sağlam bir doğrulama/ölçüm olmadan güveniyorsa, bir depolama saldırganı onu null cipher olacak şekilde değiştirebilir ve guest herhangi bir hata olmadan düz metin bir volume’u mount eder.

İstismar (depolama yazma erişimi gerekli)

Önkoşullar:

  • CVM’nin LUKS2 ile şifrelenmiş blok aygıtına yazma erişimi.
  • Guest, diskteki LUKS2 başlığını sağlam doğrulama/attestation olmadan kullanıyor.

Adımlar (yüksek seviye):

  1. Başlık JSON’unu oku ve veri segmenti tanımını belirle. Örnek hedef alan: segments[“0”].encryption.
  2. Veri segmenti şifrelemesini bir null cipher olarak ayarla, örn. cipher_null-ecb. Guest’in olağan passphrase’inin hâlâ “çalışması” için keyslot parametrelerini ve digest yapısını bozmadan bırak.
  3. Her iki başlık kopyasını ve ilişkili başlık digest’lerini güncelleyin, böylece başlık kendi içinde tutarlı olsun.
  4. Bir sonraki boot’ta guest cryptsetup çalıştırır, mevcut keyslot’u passphrase ile başarıyla açar ve volume’u mount eder. Segment cipher bir null cipher olduğundan tüm okuma/yazmalar düz metindir.

Varyant (2.8.1 öncesi keyslot suistimali): eğer bir keyslot’un area.encryption’ı null cipher ise, herhangi bir passphrase ile açılır. Bunu null segment cipher ile birleştirerek guest secret’ını bilmeden sorunsuz düz metin erişimi sağlanabilir.

Sağlam hafifletmeler (detached headers ile TOCTOU’dan kaçının)

Disk üzerindeki LUKS başlıklarını her zaman güvensiz girdi olarak ele alın. detached-header mode kullanın, böylece doğrulama ve açma aynı korumalı RAM’den gelen güvenilir baytları kullanır:

# Copy header into protected memory (e.g., tmpfs) and open from there
cryptsetup luksHeaderBackup --header-backup-file /tmp/luks_header /dev/VDISK
cryptsetup open --type luks2 --header /tmp/luks_header /dev/VDISK --key-file=key.txt

Sonra şu (veya daha fazlasını) zorunlu kılın:

  1. MAC the full header
  • Kullanımdan önce tüm header üzerinde bir MAC hesaplayın/doğrulayın.
  • MAC doğrulandığında yalnızca volume’u açın.
  • Gerçekteki örnekler: Flashbots tdx-init ve Fortanix Salmiac, MAC tabanlı doğrulamayı benimsedi.
  1. Strict JSON validation (backward compatible)
  • JSON metadata’sını döküp parametrelerin sıkı bir allowlist’ini doğrulayın (KDF, ciphers, segment count/type, flags).
#!/bin/bash
set -e
# Store header in confidential RAM fs
cryptsetup luksHeaderBackup --header-backup-file /tmp/luks_header $BLOCK_DEVICE
# Dump JSON metadata header to a file
cryptsetup luksDump --type luks2 --dump-json-metadata /tmp/luks_header > header.json
# Validate the header
python validate.py header.json
# Open the cryptfs using key.txt
cryptsetup open --type luks2 --header /tmp/luks_header $BLOCK_DEVICE --key-file=key.txt
Örnek doğrulayıcı (güvenli alanları zorunlu kılar) ```python from json import load import sys with open(sys.argv[1], "r") as f: header = load(f) if len(header["keyslots"]) != 1: raise ValueError("Expected 1 keyslot") if header["keyslots"]["0"]["type"] != "luks2": raise ValueError("Expected luks2 keyslot") if header["keyslots"]["0"]["area"]["encryption"] != "aes-xts-plain64": raise ValueError("Expected aes-xts-plain64 encryption") if header["keyslots"]["0"]["kdf"]["type"] != "argon2id": raise ValueError("Expected argon2id kdf") if len(header["tokens"]) != 0: raise ValueError("Expected 0 tokens") if len(header["segments"]) != 1: raise ValueError("Expected 1 segment") if header["segments"]["0"]["type"] != "crypt": raise ValueError("Expected crypt segment") if header["segments"]["0"]["encryption"] != "aes-xts-plain64": raise ValueError("Expected aes-xts-plain64 encryption") if "flags" in header["segments"]["0"] and header["segments"]["0"]["flags"]: raise ValueError("Segment contains unexpected flags") ```
  1. Başlığı ölçün/doğrulayın
  • Rastgele salt/digest’leri kaldırın ve temizlenmiş başlığı TPM/TDX/SEV PCRs veya KMS policy state içine ölçün.
  • Şifre çözme anahtarlarını yalnızca ölçülen başlık onaylanmış, güvenli bir profile uyduğunda serbest bırakın.

Operasyonel rehberlik:

  • detached header + MAC veya sıkı doğrulamayı zorunlu kılın; disk üzerindeki başlıklara doğrudan asla güvenmeyin.
  • Attestation tüketicileri, allow-list’lerinde pre-patch framework sürümlerini reddetmelidir.

Sürümler ve bakımcı pozisyonu hakkında notlar

  • cryptsetup bakımcıları, bu durumda LUKS2’nin depolama oynanmasına karşı bütünlük sağlamak için tasarlanmadığını açıkladı; null ciphers geriye dönük uyumluluk için korunuyor.
  • cryptsetup 2.8.1 (Oct 19, 2025) boş olmayan parolalara sahip keyslots için null ciphers’i reddeder, ancak hala segments için null ciphers’e izin verir.

Hızlı kontroller ve triyaj

  • Herhangi bir segment encryption’ının null cipher olarak ayarlanıp ayarlanmadığını inceleyin:
cryptsetup luksDump --type luks2 --dump-json-metadata /dev/VDISK \
| jq -r '.segments | to_entries[] | "segment=" + .key + ", enc=" + .value.encryption'
  • Keyslot ve segment algoritmalarını volümü açmadan önce doğrulayın. Eğer MAC yapamıyorsanız, sıkı JSON doğrulaması zorunlu kılın ve korumalı bellekten detached header kullanarak açın.

Referanslar

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin