추측 실행(Speculation Execution)

성능을 위해서 다음 실행될 명령어 예측하여 먼저 실행하는 기법.

분기 예측은 추측 실행의 한 종류라고 할 수 있습니다.

if (a > 16)    
    b = 32

위의 조건문에서 a > 16을 판단하기 위해서 a 값을 읽어오는데, 시간이 걸립니다. 이때 미리 b = 32를 실행해 둡니다.

예측이 맞으면 미리 실행한 만큼 성능이 좋아집니다.

 

추측 실행과 비순차적 실행으로 인해서 멜트다운 취약점이 발생합니다.

인텔 CPU와 ARM Cortex-A 시리즈 기종에서만 발생합니다

커널 메모리를 읽을 수 있는 치명적인 취약점입니다.

 

공격

raise_exception();
// the line below is never reached
access(probe_array[data * 4096]);

1. raise_exception() 함수가 실행됩니다.

2. 순차적 실행에서는 3번 줄이 실행되지 않지만, 비순차적 실행으로 인하여 3번째 줄이 실행되게 됩니다.

3. raise_exception() 함수에 의해 예외가 발생하고 제어 흐름이 운영체제의 예외 처리기로 점프합니다.

4. 예외로 인해서 순서에 맞지 않게 실행된 명령은 폐기되지 않습니다.

5. 이 예외가 메모리 액세스 또는 다른 CPU 예외로 인해 발생했는지 여부에 관계없이 제어 흐름은 다음 사용자 공간 명령이 아닌 커널에서 계속됩니다.

6. 커널에서 실행이 되게 되고 캐시에 데이터가 올라가게 됩니다.

 

순차적 실행에서는 1번줄이 실행되고 예외가 발생하여 3번줄을 실행하지 않고 넘어갑니다.

; rcx = kernel address, rbx = probe array
xor rax, rax
retry:
mov al, byte [rcx]
shl rax, 0xc
jz retry
mov rbx, qword [rbx + rax]

위와 같은 코드이지만 어셈블리입니다.

 

분기 예측(Branch Prediction)

분기 예측은 파이프라이닝에서 한번 다뤘기 때문에 간단히만 설명하고 넘어가도록 하겠습니다.

 

원래는 분기문이 나올 때마다 분기 조건의 값을 확인하여 다음에 실행할 명령어의 위치(분기 위치, Branch Target)를 계산하고 그곳으로 이동하지만, 분기 예측은 각 분기문 별로 분기할 위치를 미리 예측하여 BTB(Branch Target Buffer)라는 곳에 저장해둡니다. 그리고 분기문을 실행할 때 추측 실행 이 가능한 경우에는 저장되어 있던 예측된 위치를 BTB에서 가져와 실행합니다. 분기 위치의 예측은 직전에 그 분기문이 실행될 때의 분기 위치를 참고해서 그대로 정하는 경우가 많습니다. 정확한 분기 위치는 매번 계산되므로 만약 예측이 잘못된 경우에는 실행결과는 폐기됩니다.

분기 예측으로 인해서 스펙터 취약점이 발생합니다.

다른 유저 프로그램 메모리를 훔쳐보는 취약점입니다.

x86과 ARM 아키텍처에 전부 적용됩니다.

멜트다운보다 덜 치명적이고 구현하기 어렵지만 막기도 어렵습니다.

 

공격

if (x < array1_size)			//#1
	y = array2[array1[x] * 256];	//#2
  1. #1 의 조건이 참이 되도록 x를 설정하여 코드를 여러번 반복시켜 분기예측버퍼(BTB)에 조건문이 참인 위치를 넣습니다. (Branch Target Injection)
  2. array1이 타겟 프로그램의 메모리 영역을 향하도록 x값을 설정합니다 (Bound Check Bypass)
  3. #1의 조건이 거짓이지만 분기예측 에 의해 #2가 실행됩니다.
  4. 3번에서 명령실행 결과 array1의 값이 캐시에 올라갑니다.
  5. Flush+Reload기법을 이용해 타겟 프로그램의 메모리값을 추출합니다.

스펙터 공격의 어려움

  • 기본적으로 공격이 되는 대상 프로그램에서 문제가 존재하는 코드의 추측 실행이 되어야 하기 때문에, 실제 버그를 이용해 공격하려면 공격하려는 대상 프로그램을 세세하게 분석해야 됩니다
  • 프로그램이 돌아가는 CPU 아키텍쳐나 운영체제에 대해서도 자세히 알아야된다. 그래서 실제로는 취약점을 공격하긴 매우 어렵습니다.
728x90

'해킹 > 과제' 카테고리의 다른 글

2. UART 찾기, 칩 구분  (0) 2021.04.20
1. 부트로더, 커널, 파일시스템  (0) 2021.04.20
5. 비순차적 실행(Out-of-order Execution)  (0) 2021.04.17
4. 파이프라이닝(Pipelining)  (0) 2021.04.17
3. CPU의 명령어 처리 구조  (0) 2021.04.16

+ Recent posts