본문으로 바로가기

[Basic] Buffer Over Flow Note - 1

category CTF/CTFs 2022. 6. 6. 02:07
728x90
반응형
이전 블로그에서 백업한 내용입니다

개요

BOF (Buffer Over Flow) 관련 공부 중에 예제를 보며 익혔던 내용들을 기록하고자 합니다. 
 

인접한 변수

목표는 buffer변수를 오버플로우 시키면 zero 변수의 값이 변하는지 관찰하는 것으로 시작했습니다. 소스 코드의 실행 결과 buffer 변수의 주소와 zero 변수의 주소가 출력되기 때문에 gdb를 통해서 zero 변수의 값을 바꾸려면 buffer 변수를 몇 바이트를 overflow 시켜야 되는지 알아보고자 합니다. 

gdb를 통해 알아보기 전에 대략 유추해봅시다. buffer변수에는 10바이트 (char 변수의 크기 1byte * 배열의 크기 10)가 할당되어있습니다. 여기서 일단 해 볼 수 있는 것은 10바이트를 넘게 입력해보는 것입니다. 

그림 1

첫 번째 이미지에 쓰인 문자의 개수는 9개 (9byte), 두 번째 이미지에 쓰인 문자의 개수는 14개 (14byte)

첫 번째 이미지에 입력된 9byte짜리 문자열은 buffer 변수의 10byte를 넘지 않아 zero 변수의 값이 변하지 않은 반면 '그림 2'에 입력된 문자열의 개수는 14개이므로 buffer 변수가 overflow 돼서 zero 변수가 바뀐 것을 확인할 수 있습니다. 

즉, buffer 변수와 zero 변수가 메모리 상 인접해 있다는 것을 알 수 있습니다. 

gdb 사용

buffer 변수와 zero 변수가 메모리 상으로 인접해 있다는 것을 gdb를 통해 알아봅시다.
(gdb) disas main
Dump of assembler code for function main:
   0x08048476 <+0>: push   ebp
   0x08048477 <+1>: mov    ebp,esp
   0x08048479 <+3>: push   ebx
   0x0804847a <+4>: sub    esp,0x10
   0x0804847d <+7>: call   0x80483b0 <__x86.get_pc_thunk.bx>
   0x08048482 <+12>: add    ebx,0x1b7e
   0x08048488 <+18>: mov    DWORD PTR [ebp-0x8],0x0
   0x0804848f <+25>: lea    eax,[ebp-0x12]
   0x08048492 <+28>: push   eax
   0x08048493 <+29>: lea    eax,[ebx-0x1a90]
   0x08048499 <+35>: push   eax
   0x0804849a <+36>: call   0x8048320 <printf@plt>
   0x0804849f <+41>: add    esp,0x8
   0x080484a2 <+44>: lea    eax,[ebp-0x8]
   0x080484a5 <+47>: push   eax
   0x080484a6 <+48>: lea    eax,[ebx-0x1a7c]
   0x080484ac <+54>: push   eax
   0x080484ad <+55>: call   0x8048320 <printf@plt>
   0x080484b2 <+60>: add    esp,0x8
   0x080484b5 <+63>: mov    eax,DWORD PTR [ebx-0x4]
   0x080484bb <+69>: mov    eax,DWORD PTR [eax]
   0x080484bd <+71>: push   eax
   0x080484be <+72>: push   0x40
   0x080484c0 <+74>: lea    eax,[ebp-0x12]
   0x080484c3 <+77>: push   eax
   0x080484c4 <+78>: call   0x8048330 <fgets@plt>
   0x080484c9 <+83>: add    esp,0xc
   0x080484cc <+86>: mov    eax,DWORD PTR [ebp-0x8]
   0x080484cf <+89>: push   eax
   0x080484d0 <+90>: lea    eax,[ebx-0x1a6a]
   0x080484d6 <+96>: push   eax
   0x080484d7 <+97>: call   0x8048320 <printf@plt>
   0x080484dc <+102>: add    esp,0x8
   0x080484df <+105>: mov    eax,0x0
   0x080484e4 <+110>: mov    ebx,DWORD PTR [ebp-0x4]
   0x080484e7 <+113>: leave  
   0x080484e8 <+114>: ret    
End of assembler dump.
gdb -q 옵션을 통해 어셈블된 main 함수의 코드를 확인할 수 있습니다. 처음 gdb를 사용하는 것이라면 익숙하지 않은 코드라 눈에 익지 않습니다. 여기서 찾아야 할 걸 두 가지로 추려 봅시다.
 
1. zero 변수의 메모리 주소
2. buffer 변수의 메모리 주소
 
zero 변수의 위치를 찾는 방법을 알면 buffer 변수의 위치를 찾을 수 있습니다. 맨 위의 소스 코드에서 zero 변수에는 초기값을 0을 준 것을 확인할 수 있습니다. 그러니 0을 집어넣는 어셈블리어 코드를 찾아보면 mov DWORD PTR[ebp-0x8], 0x0 을 생각해 볼 수 있습니다.  소스 코드에서는 zero 변수의 메모리 주소를 출력하고 있으므로 gdb의 examine 명령을 통해 ebp - 0x8 이 출력된 zero 변수의 메모리 주소랑 맞는지 확인해봅시다.

break point는 적당히 걸어주면 됩니다 저는 110 번째로 걸었습니다. ( break point 명령어 -> b *function + number)

소스 코드에서 zero 변수의 주소를 출력하고 있고 zero 변수가 들어있을 것 같은 위치 $ebp - 0x8의 주소를 확인합니다. 출력된 zero 변수와 예측한 zero 변수의 주소가 같은 걸 확인할 수 있습니다. 나아가 다음과 같이 buffer 변수와의 거리 차이도 확인할 수 있습니다.

맨 앞부분에서 언급했듯이 10바이트를 넘어 입력하면 zero 변수가 바뀌었습니다. gdb로 확인해본 결과 위의 zero 변수와 buffer 변수의 차이도 10바이트가 나는 것을 확인할 수 있습니다.

 

Note

gdb에서 레지스터 주소를 확인할 때 : p $reg1
Ex) p $esp ,p $ebp
728x90
반응형

'CTF > CTFs' 카테고리의 다른 글

[pwn][pwnable.kr] : 파일 디스크립터  (0) 2021.01.03
[gdb] : Break Point  (0) 2021.01.03
[N00bCTF][MISC]  (0) 2021.01.03
[ctfLearn][Review] : Inj3ction Time  (0) 2020.12.27
[weCTF2020] : Build Up  (0) 2020.12.26