padding oracle attack 정리

padding oracle attack 정리

사전지식 소개

우선 글 이해에 필요한 사전 지식을 정리하고 설명을 시작하겠습니다.
사전 지식은 자세히 다루지 않고 간단히 정리만 하였습니다.

블록암호 (block cipher)

ex) DES, AES

긴 평문을 일정한 길이의 블록으로 나누어서 블록단위로 암호화 합니다.

운용모드 (modes of operation)

블록암호에서 블록들을 어떻게 사용하여 안전하게 암호화 할 것인지에 대한 방법입니다.
그 중 CBC모드는 key말고도 IV(Initialization Vector)라는것이 존재합니다.

CBC모드는 이전 블록의 암호화 값이 다음 블록의 평문에 xor 연산이 되어됩니다.

복호화도 비슷합니다.

패딩 (padding)

이번 글에서 핵심이 될 부분입니다. 이 글에서는 패딩에는 많은 방법, 종류가 있지만 pkcs#7 패딩을 기준으로 설명합니다.

블록암호는 plaintext가 항상 블록암호의 블록사이즈의 배수가 될 수 없기 때문에 블록사이즈의 배수로 맞춰주기 위해 패딩을 붙입니다.
그중 pkcs#7는 n bytes가 부족하다면 n bytes를 n으로 채웁니다.

예를 들어 블록의 사이즈가 8, plaintext가 admin으로 5bytes니 3bytes가 부족하다면 3 으로 3bytes를 채웁니다.

padding oracle attack 소개

CBC mode에서 복호화를 할때 암호문이 직접적으로 xor연산에 포함되어 영향을 미칠 수 있고, 복호화 후 패딩이 valid 한지를 체크하는 것을 이용합니다.

예시와 함께 설명하는게 빠르니 예시와 함께 보겠습니다.

먼저, Hello Incognito라는 문자열을 암호화 해보겠습니다.

이제 위 암호문만 가지고 평문을 알아내보도록 하겠습니다.
첫번째 블록의 마지막 글자를 brute force하여 padding이 valid하다고 뜨는 값을 찾아냅니다.

padding이 valid한 경우를 계속 brute force를 통해 찾아줍니다.
decryption 함수만 통과하고 아직 이전 블럭과 xor연산 되지 않은 값을 알아내는 과정이 계속 됩니다.

그러면 xor연산 되기 전의 값을 모두 찾아낼 수 있습니다.
Intermediate Value : 0x50, 0xfe, 0xe5, 0x70, 0x12, 0x06, 0x4e, 0x53

이제 다시, 평문을 알아내기 위해서 원본 암호화 데이터를 이용해서 xor을 합니다.

원본데이터인 0x33, 0x91, 0x82, 0x1e, 0x7b, 0x72, 0x21, 0x52
Intermediate Valud인 0x50, 0xfe, 0xe5, 0x70, 0x12, 0x06, 0x4e, 0x53 를 서로 xor 연산하면

짠! cognito 라는 문자열을 얻어낼 수 있습니다.

간단하게 예시와 함께 흐름을 먼저 보았지만 정리해보자면 이렇습니다.

  1. 이전 블럭의 마지막 byte부터 brute force를 통해 padding이 valid하다고 뜨는 값을 찾는다.
  2. 1번 과정을 반복하여 Intermediate Value 값을 전부 얻어낸다.
  3. 원본 블럭값과 Intermediate Value를 xor하여 평문을 알아낸다.

정리

실제로 이 공격이 쓰일려면 조건이 있긴 합니다.
암호문을 복호화 해주는 서버에서 status code 라든지, error message를 통해서 이게 padding validation error인지 단순히 decryption이 이상하게 돼서 발생한는 에러인지 구분할 수 있어야합니다.

추가적으로, 이 공격을 통해서 단순히 평문을 알아내는데에 그치지 않고, bit flipping attack을 이용해, 원하는 복호화 값이 나오게 암호문을 조작까지 할 수도 있습니다.

Share