[8] Memory Corruption - C (1) :: Off By One(OBO)

본 글은 DreamHack의 강의 내용을 요약한 글이므로 자세한 내용은 dreamhack.io 에서 학습하시길 바랍니다. 

 

해커들의 놀이터, Dreamhack

해킹과 보안에 대한 공부를 하고 싶은 학생, 안전한 코드를 작성하고 싶은 개발자, 보안 지식과 실력을 업그레이드 시키고 싶은 보안 전문가까지 함께 공부하고 연습하며 지식을 나누고 실력 향

dreamhack.io

 

학습목표

C언어에서 발생할 수 있는 Memory Corruption 취약점 중 Off By One을 알아본다.

 

1. Off By One이란?

경계 검사에서 하나의 오차가 있을 때 발생하는 취약점

버퍼의 경계 계산 또는 반복문에서의 반복 횟수 계산 시 < 가 아닌 <=를 쓰거나, 0부터 시작하는 index를 고려하지 않을 때 발생한다.

 

2. Off By One 실습

[기본코드]

- off-by-one-1.c

16바이트 size의 buf 배열에 데이터를 read 함수로 읽어들인 후, copy_buf 함수에서 만든 temp라는 배열에 복사하는 코드이다.

 

(1) copy_buf 함수 호출 시 buf의 시작주소와 buf 배열 사이즈를 인자로 넘겨준다.

 

(2) copy_buf 함수 내의 for문에서 1byte씩(index 하나씩) buf 배열의 데이터를 temp 배열로 복사하도록 한다.

 

(3) 이 때, 초기화된 i값은 0인데 for 조건식을 보면 i <= sz 로 되어 있다. 인자로 넘겨 받은 sz의 값은 buf 배열 size였던 16이므로 반복문은 i가 16인 경우까지 총 17번 반복하게 된다.

 

풀이

buf[0] ~ buf[15]를 복사받고 for문을 종료해야 하지만 i가 16인 경우도 <= 연산으로 참이 되버려 경계를 넘어서게 된다.

 

for문에서 temp[i]가 temp[16]에 buf[16]값을 대입하게 되면, 메모리 상에서 temp[15] 다음 주소에 해당하는 sfp영역에 값을 복사하게 된다. (Overflow)

input 창을 보면 0~F까지 16바이트의 data만 넣었는데

 

Stack을 살펴보면, 실제 17바이트의 데이터가 복사되면서 Overflow가 발생한 것을 확인할 수 있다.

Q. overflow 발생한 곳의 값이 0x0d (carrage return)로 되어 있는 것을 볼 수 있는데 스택프레임 구조 상 sfp가 위치하는 영역일 것으로 추정. sfp가 가리키는 주소 값이 0x0d면 어떤 현상이 일어나려나? -> 직접 코드 짜보고 구현 후에 gdb로 한번 볼 예정.

 

 

 

 

출처 : Memory Corruption - C (I) (DreamHack, https://dreamhack.io/learn/2/14#14)