คลัง
crypto

ECB Mode

ECB (Electronic Codebook) เข้ารหัสแต่ละ block แยกกันด้วย key เดียว โดยไม่มีการ chain — plaintext block เดียวกันจึงให้ ciphertext block เดียวกันเสมอ นี่คือจุดอ่อนร้ายแรง: มองเห็น pattern ได้ (ECB penguin), สลับ block ได้ (block-swap/cut-and-paste), และถ้าเราควบคุม input บางส่วนได้จะถอดความลับทีละ byte (byte-at-a-time)

BeginnerIntermediateAdvanced#ecb#block-cipher#aes#block-swap#byte-at-a-time#pattern-leak#crypto#ctf

1. ทำไม ECB ถึงอันตราย

ECB แบ่ง plaintext เป็น block ขนาดคงที่ (AES = 16 byte) แล้ว C_i = Enc(P_i) แยกกันทุก block ไม่มี IV ไม่มี chaining ผลคือถ้า P_i = P_j แล้ว C_i = C_j เสมอ ข้อมูลโครงสร้าง (pattern) จึงรั่วออกมาทาง ciphertext ตรงๆ ตัวอย่างคลาสสิกคือ 'ECB penguin' — เข้ารหัสรูปด้วย ECB แล้วยังเห็นรูปเพนกวินได้

ECB — block เดียวกัน → ciphertext เดียวกัน
"AAAA..." "AAAA..." "BBBB..." Enc (key) Enc (key) Enc (key) C_x C_x C_y C_x == C_x (รั่ว pattern!)
ตรวจจับ ECB (block ซ้ำ)
def is_ecb(ct, bs=16):
    blocks = [ct[i:i+bs] for i in range(0, len(ct), bs)]
    return len(blocks) != len(set(blocks))

# ทริก: ป้อน 'A'*32+ ให้ระบบเข้ารหัส แล้วเช็คว่ามี block ซ้ำติดกันไหม
วิธีตรวจว่าเป็น ECB: ส่ง input ที่เป็น byte เดียวกันยาวๆ (เช่น 'A'×32) แล้วดู ciphertext — ถ้ามี block 16-byte ที่ซ้ำกันติดกัน = ECB แน่นอน

2. Block Swapping / Cut-and-Paste

เพราะแต่ละ block อิสระ ผู้โจมตีตัด-แปะ (cut-and-paste) ciphertext block ได้ ตัวอย่างคลาสสิก: ระบบสร้าง token จาก email + role ถ้าเราจัด input ให้คำว่า admin ตกลงใน block พอดี เราจะดึง ciphertext ของ block นั้นมาแปะทับ block role ได้ → ยกระดับเป็น admin โดยไม่รู้ key

  1. 1หา block size (มัก 16) ด้วยการเพิ่ม input ทีละ byte จน ciphertext โตขึ้น 1 block
  2. 2จัด input ให้ค่าที่ต้องการปลอม (เช่น 'admin' + padding) ตกลงใน 1 block เต็มพอดี
  3. 3ดึง ciphertext block ของค่านั้นเก็บไว้
  4. 4สร้าง token ใหม่ที่ทำให้ field เป้าหมาย (เช่น role) เริ่มต้นตรงขอบ block
  5. 5แปะ ciphertext block ที่เก็บไว้ทับตำแหน่ง role → ได้ token ปลอมที่ถอดออกมาเป็น admin

3. Byte-at-a-Time ECB Decryption

ถ้า oracle เข้ารหัส Enc(input || SECRET) โดยเราคุม input ได้ เราถอด SECRET ได้ทีละ byte: จัด input ให้ยาวจน byte แรกของ SECRET ตกที่ขอบ block สุดท้ายของ input พอดี แล้ว brute-force byte สุดท้ายทั้ง 256 ค่าเทียบ ciphertext block — ตรงเมื่อไรได้ byte นั้น แล้วเลื่อนไปทีละ byte

Byte-at-a-time decryption (โครงร่าง Python)
BS = 16
known = b''
for i in range(TARGET_LEN):
    pad = b'A' * (BS - 1 - (len(known) % BS))
    block_idx = len(known) // BS
    # ciphertext เป้าหมายเมื่อ byte ถัดไปของ secret ตกที่ขอบ
    target = oracle(pad)[block_idx*BS:(block_idx+1)*BS]
    for b in range(256):
        guess = pad + known + bytes([b])
        if oracle(guess)[block_idx*BS:(block_idx+1)*BS] == target:
            known += bytes([b]); break
print(known)
oracle(x) = ส่ง x ให้ระบบเข้ารหัส Enc(x || SECRET) แล้วรับ ciphertext กลับ
เจอโจทย์ ECB — ไล่ตามนี้
ส่ง 'A'×32 → มี block ซ้ำติดกันไหม?
ยืนยันว่าเป็น ECB
เราคุม input ก่อน SECRET ได้ไหม?
ได้→ byte-at-a-time decryption
แค่จัดตำแหน่ง field ได้→ block-swap / cut-and-paste
หา block size + หา offset ของ SECRET
ถอด SECRET / ปลอม token → auth bypass

4. สรุป & Quick Reference

จุดอ่อน ECBโจมตีเงื่อนไข
block ซ้ำ → ciphertext ซ้ำตรวจจับ ECB / อ่าน patternส่ง input ซ้ำๆ ได้
block อิสระblock-swap / cut-and-pasteจัดตำแหน่ง field ใน input ได้
Enc(input || secret)byte-at-a-time decryptionคุม input prefix ได้
  • ยืนยัน ECB ด้วย input ซ้ำ → หา ciphertext block ที่ซ้ำติดกัน
  • AES block = 16 byte; ความยาว ciphertext เป็นทวีคูณของ 16 เสมอ
  • ECB ไม่มี IV — ต่างจาก CBC ตรงนี้ (ใช้แยกสองโหมดออกจากกัน)
เนื้อหาต่อเนื่อง: โหมด block cipher อื่น + diagram อยู่ในหัวข้อ AES & Block Cipher Modes (aes); ส่วน chaining/bit-flipping/padding oracle อยู่ใน CBC Mode (cbc) และ Padding Oracle Attack (padding-oracle)

🧭 จับมือทำทีละขั้น (มีแค่ Kali) + ถ้าติดไปไหนต่อ

สมมติสงสัยว่าโจทย์เข้ารหัสด้วย ECB (มาจากขั้นตรวจสอบในหัวข้อ AES) มีแค่เครื่อง Kali เปล่าๆ ทำตามนี้ทีละขั้นเพื่อยืนยันแล้วโจมตีจริง

  1. 1ยืนยันก่อนว่าเป็น ECB จริง: ถ้าคุมส่ง input ได้ ส่ง `'A'*48` (หรือมากกว่า) แล้วดู ciphertext ด้วย `xxd` หรือ python — มี 16-byte block ซ้ำติดกันไหม
  2. 2ยืนยันแล้ว → ตัดสินใจว่าจะโจมตีแบบไหน: คุม input ก่อนความลับได้ไหม (byte-at-a-time) หรือแค่จัดตำแหน่ง field ในข้อมูลได้ (block-swap)
  3. 3Byte-at-a-time: หา block size ก่อนโดยเพิ่ม input ทีละ 1 byte จนความยาว ciphertext กระโดดขึ้น 16 byte พอดี (ยืนยัน block size = 16)
  4. 4เขียน python oracle function ที่เรียก endpoint/binary ส่ง input แล้วคืน ciphertext กลับมา แล้วรัน byte-at-a-time script (โค้ดเต็มอยู่ในหัวข้อด้านบน) ไล่ถอดทีละ byte
  5. 5ติด edge case ระหว่างทาง (padding เปลี่ยน length กะทันหัน / error) → ปรับ script ให้ตัด/pad input ให้ตรง block boundary ก่อน compare
  6. 6Block-swap: หา offset ที่ field เป้าหมาย (เช่น username, role) เริ่มต้น แล้ว craft input ให้คำที่ต้องการปลอม (เช่น 'admin' + padding) ตกลงเต็ม 1 block พอดี
  7. 7ส่ง request สร้าง token 2 แบบ: อันหนึ่งเก็บ ciphertext ของ block ที่ต้องการ (เช่น block ของคำว่า admin) อีกอันคือ token จริงที่จะแก้ แล้วเอา ciphertext block มาสลับ (cut-and-paste) ด้วย python
  8. 8ส่ง token ที่ปลอมแล้วกลับไปที่ server ทดสอบว่า auth bypass สำเร็จไหม (เช่นเข้าเป็น admin ได้)
  9. 9server เช็ค integrity/MAC (แก้ ciphertext แล้วถูกปฏิเสธทันที) → ECB attack ตรงๆ ใช้ไม่ได้ ต้องดูว่า MAC อ่อนพอจะ crack/ปลอมได้ไหม
  10. 10ถอด SECRET หรือปลอม token สำเร็จแล้ว → ตรวจ flag/privilege ที่ได้ และเช็ค format ตามที่โจทย์ต้องการ
สงสัย ECB มีแค่ Kali — ไล่ตามนี้
ส่ง 'A'×48 (หรือมากกว่า) แล้วเช็ค block ซ้ำ
✅ มี block ซ้ำติดกัน→ ยืนยัน ECB แน่นอน
❌ ไม่ซ้ำเลย→ ไม่ใช่ ECB กลับไปเช็ค mode อื่น
คุม input ก่อนความลับได้ไหม (Enc(input || SECRET))?
✅ ได้→ byte-at-a-time decryption
❌ แค่จัดตำแหน่ง field ได้→ block-swap / cut-and-paste
หา block size (เพิ่ม input ทีละ byte จน ciphertext ยาวขึ้น 16 byte)
เขียน oracle function + รัน byte-at-a-time script ทีละ byte
✅ ถอด SECRET ได้ครบ→ จบ
❌ ติด edge case (padding/error)→ ปรับ script จัดการ edge case ต่อ
หา offset ที่ field เป้าหมายเริ่ม + craft input ให้คำปลอมตกใน 1 block พอดี
ดึง ciphertext block ที่ต้องการ แล้วแปะสลับ (cut-and-paste) เข้า token จริง
✅ ส่ง token ปลอมแล้ว auth bypass สำเร็จ→ จบ
❌ server เช็ค integrity/MAC→ ECB attack ใช้ไม่ได้ตรงๆ
ขั้นตอน/งานเครื่องมือใน Kaliติดตั้งเพิ่ม (ถ้าไม่มี)เครื่องมือออนไลน์
ดู ciphertext เป็น hex หา block ซ้ำxxd, python3-CyberChef (To Hex)
ยิง request ทดสอบ input ซ้ำๆcurl, python3 (requests)pip install requestsBurp Suite Repeater (ถ้ามี)
เขียน oracle + byte-at-a-time scriptpython3--
ตัด-แปะ (cut-and-paste) ciphertext blockpython3-CyberChef (การต่อ hex ด้วยมือ)
ทดสอบส่ง token ปลอมกลับ servercurl, python3 (requests)--
เช็คว่า MAC/hash ที่ป้องกันอ่อนไหมhashid, hashcat-hashes.com
🚑 ถ้าตันสนิท ลองท่าถัดไป: AES — ถ้าเช็คแล้วไม่ใช่ ECB (ไม่มี block ซ้ำเลย) ให้กลับไปดู mode อื่น · CBC — ถ้าเปลี่ยนมาเจอ IV/chaining แทน · Hash Cracking — ถ้า server ป้องกันด้วย MAC/signature ที่อาจ crack ได้แทนที่จะโจมตี ECB ตรงๆ · Padding Oracle — ถ้าจริงๆ แล้วเป็น CBC ที่มี padding error รั่วออกมา

หัวข้อที่เชื่อมโยง

โน้ตของฉัน

ยังไม่มีโน้ตสำหรับหัวข้อนี้