Security_lab

gdb를 통한 Stack buffer overflow

부산대보금자리 2021. 7. 27. 14:19

버퍼는 데이터를 한 곳에서 다른 곳으로 전송하는 동안 일시 보관하는 메모리 영역이다. 이 버퍼는 항상 정해진 일정 크기를 가지는데, 이 '정해진 일정 크기'를 넘는 데이터를 입력하는 현상이 바로 버퍼 오버플로이다. 

따라서 버퍼 오버플로 공격은 '버퍼에 정해진 일정 크기 이상의 데이터를 입력하여 프로그램을 공격하는 행위'라고 할 수 있다. 

 

프로그램이 사용하는 버퍼는 메모리의 스택과 힙에 존재할 수 있다. 따라서 스택에 존재하는 버퍼 공격이나, 힙에 존재하는 버퍼 공격이냐에 따라 스택 버퍼 오버플로와 힙 버퍼 오버플로로 구분한다. 

 

먼저 스택 버퍼 오버플로 공격을 알아볼 것이다. 이 공격은 모든 경우에 가능하지 않고, 프로그래머가 취약한 특정 함수를 사용해야 가능하다. 그리하여 이론상 취약한 함수를 사용하지 않는 프로그래머만 있다면, 스택 버퍼 오버플로 공격은 훨씬 어렵겠지만 실제로는 그렇지 않다.

 

스택 버퍼 오버플로 공격에 취약한 예제 프로그램으로 그 원리를 살펴보자.

 

공격은 strcpy(buffer,argv[1])에서 일어난다. 그럼 최초 프로그램에서 strcpy함수를 실행할 때 어떤 변화를 가해 스택 버퍼 오버플로가 일어나는지 알아보자.

컴파일 : gcc bugfile.c -g -o bugfile

-g -o 옵션을 사용한 실행 파일의 용량이 -o 옵션만 사용할 때보다 크다.

gdb를 열고 list로 소스코드를 확인한다.

디버깅을 하기 위해 breaking 포인트를 설정해야 한다. 

list로 확인을 했으니 5번에 break를 건다.

그리고 main을 disass하여 코드를 확인한다. 

이후에는 strcpy를 확인해본다. 

 

이제는 브레이크 포인트까지 프로그램을 실행해보자. 

strcpy에서 break가 걸리고 이때의 각 변수 값과 스택 구조를 확인해보자 

레지스터 값도 확인해본다. 

레지스터 전체 값은 info reg명령어로 조회할 수 있다. 

특정 레지스터 값은 'info reg [레지스터 종류]'명령으로 확인한다.

또 'x/[조회하는 메모리 범위]xw [조회하는 메모리 지점]' 명령으로 스택을 확인할 수 있다.

참고로 esp는 스택의 크기를 조정할때 사용되는 레지스터입니다. 스택의 최상단 주소 값을 가지고 있으니 즉 스택의 크기를 나타냅니다.
ebp는 스택프레임 형태로 저장된 함수의 지역변수, 전달 인자를 참조하거나 값을 바꾸거나 할 때 사용하는 레지스터입니다

지금 하나의 word를 출력한 것으로 보인다. 16진수 하나당 4비트로 표현하여 총 4바이트가 1 word가 되는 것으로 보인다.

이제 다음 단계로 넘어간다.

s와 n 모두 다음 단계로 넘어가지만 s는 함수를 포함시 함수 내부로 이동하고 n은 함수를 완전히 실행하고 다음 행으로 이동한다.

c는 현재 위치에서 프로그램 끝 또는 브레이크 까지 실행한다.

다음과 같이 버퍼 앞부분이 바뀌어 있다. 이것은 정상적인 실행 구조라고 보면 된다.

 

이번에는 13개의 A를 입력해주었을때이다. buffer에는 10개의 A밖에 들어있지 않고 

나머지 A는 할당한 주소에서 ret이 있는 top 쪽으로 overflow 됐음을 짐작할 수 있다.

buffer위 ebp를 넘어간다면 segmentation fault가 일어날것이다. 

 

'Security_lab' 카테고리의 다른 글

버퍼 오버플로 공격 대응책  (0) 2021.07.28
gdb를 통한 heap buffer overflow  (0) 2021.07.27
레이스 컨디션 실습  (0) 2021.07.25
John the ripper,johnny 와 Hash  (0) 2021.07.23
SetUID  (0) 2021.07.21