๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿด‍โ˜ ๏ธ CTF ๐Ÿด‍โ˜ ๏ธ/๐Ÿงฎ ์•”ํ˜ธํ•™ ๐Ÿงฎ

[Dream Hack - Crypto] Padding Oracle

๋ฐ˜์‘ํ˜•

PKCS#7 ํŒจ๋”ฉ

  1. ํŒจ๋”ฉ ๊ธธ์ด ๊ณ„์‚ฐ: ํŒจ๋”ฉ์€ ๋งˆ์ง€๋ง‰ ๋ธ”๋ก์˜ ๊ธธ์ด๊ฐ€ ๋ธ”๋ก ํฌ๊ธฐ์™€ ๋‹ค๋ฅผ ๋•Œ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ํŒจ๋”ฉ์˜ ๊ฐ’์€ ์ถ”๊ฐ€๋˜์–ด์•ผ ํ•˜๋Š” ๋ฐ”์ดํŠธ ์ˆ˜๋กœ ํ‘œํ˜„๋ฉ๋‹ˆ๋‹ค.
  2. ํŒจ๋”ฉ ๊ฐ’์˜ ์ผ๊ด€์„ฑ: ํŒจ๋”ฉ ๊ฐ’์€ ์ถ”๊ฐ€๋˜์–ด์•ผ ํ•˜๋Š” ๋ฐ”์ดํŠธ ์ˆ˜๋กœ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๋ฉฐ, ์˜ˆ๋ฅผ ๋“ค์–ด 1๋ฐ”์ดํŠธ๊ฐ€ ์ถ”๊ฐ€๋˜์–ด์•ผ ํ•œ๋‹ค๋ฉด 0x01, 2๋ฐ”์ดํŠธ๊ฐ€ ์ถ”๊ฐ€๋˜์–ด์•ผ ํ•œ๋‹ค๋ฉด 0x02๋กœ ์ฑ„์›Œ์ง‘๋‹ˆ๋‹ค. ์ด๋Š” ํŒจ๋”ฉ์„ ๋‚˜์ค‘์— ์ œ๊ฑฐํ•  ๋•Œ ์–ด๋””๊นŒ์ง€๊ฐ€ ํŒจ๋”ฉ์ธ์ง€ ์‰ฝ๊ฒŒ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  3. ๋ชจ๋“  ๋ฐ”์ดํŠธ๊ฐ€ ํŒจ๋”ฉ์ธ ๊ฒฝ์šฐ: ๋งŒ์•ฝ ๋ฐ์ดํ„ฐ์˜ ๊ธธ์ด๊ฐ€ ๋ธ”๋ก ํฌ๊ธฐ์˜ ์ •ํ™•ํ•œ ๋ฐฐ์ˆ˜์ผ ๋•Œ, ๋ธ”๋ก ํฌ๊ธฐ๋งŒํผ์˜ ํŒจ๋”ฉ์ด ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ์ถ”๊ฐ€๋˜๋Š” ๋ชจ๋“  ๋ฐ”์ดํŠธ ๊ฐ’์€ ํŒจ๋”ฉ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  4. ํŒจ๋”ฉ ์ œ๊ฑฐ ์‹œ ์œ ํšจ์„ฑ ํ™•์ธ: ํŒจ๋”ฉ ์ œ๊ฑฐ ์‹œ์—๋Š” ์ถ”๊ฐ€๋œ ํŒจ๋”ฉ ๊ฐ’์ด ์˜ฌ๋ฐ”๋ฅธ์ง€ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ์˜ ๋ฌด๊ฒฐ์„ฑ์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

 

Oracle Padding Attack

AES Oracle Padding Attack์€ ํŒจ๋”ฉ์ด ์ ์šฉ๋œ ์•”ํ˜ธ๋ฌธ์— ๋Œ€ํ•œ ์˜ค๋ผํด ์„œ๋น„์Šค๋ฅผ ์ด์šฉํ•˜์—ฌ ํ‰๋ฌธ์„ ์ถ”์ถœํ•˜๋Š” ๊ณต๊ฒฉ ๊ธฐ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ด ๊ณต๊ฒฉ์€ ์ฃผ๋กœ ๋ธ”๋ก ์•”ํ˜ธํ™” ๋ชจ๋“œ ์ค‘ ํ•˜๋‚˜์ธ CBC (Cipher Block Chaining) ๋ชจ๋“œ์—์„œ ๋ฐœ์ƒํ•˜๋ฉฐ, ํŒจ๋”ฉ ์˜ค๋ผํด์ด ์•”ํ˜ธ๋ฌธ์˜ ํŒจ๋”ฉ์ด ์œ ํšจํ•œ์ง€ ํ™•์ธํ•˜๋Š” ์„œ๋น„์Šค์ผ ๋•Œ ํ™œ์šฉ๋ฉ๋‹ˆ๋‹ค.

 

๊ณต๊ฒฉ ๊ณผ์ •:

  1. ์•”ํ˜ธ๋ฌธ ์ˆ˜์ง‘: ๊ณต๊ฒฉ์ž๋Š” ํŒจ๋”ฉ์ด ์ ์šฉ๋œ AES ์•”ํ˜ธ๋ฌธ์„ ์–ป์Šต๋‹ˆ๋‹ค.
  2. ํŒจ๋”ฉ ์˜ค๋ผํด ์„œ๋น„์Šค ์ด์šฉ: ๊ณต๊ฒฉ์ž๋Š” ํŒจ๋”ฉ ์˜ค๋ผํด ์„œ๋น„์Šค๋ฅผ ์ด์šฉํ•˜์—ฌ ์•”ํ˜ธ๋ฌธ์„ ๋ณตํ˜ธํ™”ํ•ฉ๋‹ˆ๋‹ค. ํŒจ๋”ฉ ์˜ค๋ผํด์€ ํŒจ๋”ฉ์ด ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์€ ๊ฒฝ์šฐ ์—๋Ÿฌ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ ํŠน๋ณ„ํ•œ ์‹ ํ˜ธ๋ฅผ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  3. ํŒจ๋”ฉ์ด ์œ ํšจํ•œ์ง€ ํ™•์ธ: ๊ณต๊ฒฉ์ž๋Š” ํŒจ๋”ฉ ์˜ค๋ผํด์ด ๋ฐ˜ํ™˜ํ•œ ์ •๋ณด๋ฅผ ๋ถ„์„ํ•˜์—ฌ ํŒจ๋”ฉ์ด ์ •ํ™•ํ•œ์ง€ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•ฉ๋‹ˆ๋‹ค. ํŒจ๋”ฉ์ด ์˜ฌ๋ฐ”๋ฅด๋ฉด ์˜ค๋ผํด์€ ์ •์ƒ์ ์ธ ๋ณตํ˜ธํ™” ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , ํŒจ๋”ฉ์ด ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์œผ๋ฉด ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  4. ๋ธ”๋ก ๋ณ„ ๋ณตํ˜ธํ™”: ๊ณต๊ฒฉ์ž๋Š” ์•”ํ˜ธ๋ฌธ์˜ ๋๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ๋ธ”๋ก์„ ํ•˜๋‚˜์”ฉ ๋ณตํ˜ธํ™”ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ๋ธ”๋ก์„ ๋ณตํ˜ธํ™”ํ•  ๋•Œ ํŒจ๋”ฉ์„ ์กฐ์ •ํ•˜์—ฌ ์˜ค๋ผํด์— ์˜ฌ๋ฐ”๋ฅธ ํŒจ๋”ฉ์„ ์ ์šฉํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  5. ์ „์ฒด ๋ฉ”์‹œ์ง€ ๋ณตํ˜ธํ™”: ๊ฐ ๋ธ”๋ก์„ ๋ณตํ˜ธํ™”ํ•˜์—ฌ ์ „์ฒด ๋ฉ”์‹œ์ง€๋ฅผ ๋ณต๊ตฌํ•ฉ๋‹ˆ๋‹ค.

 

ํ’€์ด ์ฝ”๋“œ

์„œ๋ฒ„์˜ ์‘๋‹ต ๊ฐ’์œผ๋กœ Padding์— ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์€ ๊ฒฝ์šฐ(ValueError), Padding์€ ์ •์ƒ์ ์ด์ง€๋งŒ ๋ณตํ˜ธํ™”๊ฐ€ ์ž˜๋ชป๋˜์—ˆ์„ ๊ฒฝ์šฐ(JSONDecodeError)๋กœ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

import base64
from urllib import parse
import requests

API_URL = "<http://host3.dreamhack.games:23349/>"
BLOCK_SIZE = 16

def cbc_byte_decryption(ciphertext, index, block_size) :
    burtf_i = index - block_size
    burtf_c = ciphertext[burtf_i]

    for i in range(0x00, 0xff+1) :
        ciphertext[index - block_size] = i ^ burtf_c
        enc_encoding = parse.quote(base64.b64encode(ciphertext))

        params = f'secure/decrypt?token=abc&e_data={enc_encoding}&sig=abc'
        response = requests.get(API_URL + params).json()
        if(response['result']['message'] != 'ValueError') :
            return i ^ (2*block_size - index)
    return None

def cbc_block_decryption(ciphertext) :
    decipher_text = [0] * BLOCK_SIZE
    modified_block = ciphertext[:]

    for index in range(BLOCK_SIZE - 1, -1, -1) : ## ๋ณตํ˜ธํ™”ํ•  ์ธ๋ฑ์Šค ์ˆœ์„œ

        for i in range(index + 1, BLOCK_SIZE) : ## i๋ณด๋‹ค ํฐ ์ธ๋ฑ์Šค ํŒจ๋”ฉ ์ ์šฉ
            modified_block[i] = decipher_text[i] ^ ciphertext[i] ^ (BLOCK_SIZE - index)
        decipher_text[index] = cbc_byte_decryption(modified_block, index + BLOCK_SIZE, BLOCK_SIZE)
        print((chr)(decipher_text[index]))
    return ''.join(chr(i) for i in decipher_text)

response = requests.get(API_URL + "gb/1")  
enc_data = base64.b64decode(response.json()['result']['article']['enc_data'])

enc_01 = bytearray(enc_data[0 : 2*BLOCK_SIZE])
enc_02 = bytearray(enc_data[BLOCK_SIZE : 3*BLOCK_SIZE])

dec_01 = cbc_block_decryption(enc_01) 
dec_02 = cbc_block_decryption(enc_02)
print(dec_01) 
print(dec_02)

## p45$W0Rd
๋ฐ˜์‘ํ˜•