관리 메뉴

Bull

[System Hacking] PLT & GOT 간단하게 이해하기 본문

Computer Science/System Hacking

[System Hacking] PLT & GOT 간단하게 이해하기

Bull_ 2024. 5. 17. 13:24

got에 대해서 알고 있었지만 plt는 사실 잘 모르고 있었다.

 

python에서 pwntools을 쓰던 중 lib 동적링킹된 함수랑 실행파일에서 실행하는 함수랑 무슨 차이가 있는 건지 명확하게 나눠지지가 않아서 다시 공부했다.

 

dreamhack 학습자료와 여러 블로그 자료를 보면서 한 지식으로 수렴했다.

gdb로 보는 것 보다 ida로 보는 게 편했다.

 

이론적인 건 다른 블로그나 드림핵에서 잘 설명했으니 동작만 간단하게 설명한다.

Code


e = ELF('./validator_revenge')
libc = ELF('./libc-2.27.so')

read_got = e.got['read']
read_plt = e.plt['read']
read_libc_symbols = libc.symbols['read']

print(f'read_got: {hex(read_got)}')
print(f'read_plt: {hex(read_plt)}')
print(f'read_libc_symbols: {hex(read_libc_symbols)}')

pwn 워게임 풀때 e,libc가 헷갈린다면 e는 got,plt, libc는 symbols객체를 사용하면 된다.

e는 실행파일, libc는 라이브러리 파일. 대신 libc에서 구한 주소는 offset이다.

 

e로 실행하면서 plt는 libc에서 동적으로 함수를 불러와서 got에 저장한다.

read_got: 0x600fd0
read_plt: 0x400560
read_libc_symbols: 0x110180

주소를 확인해보자.

동작


1. GOT

ida로 0x600fd0주소를 확인해보았다. 실제로 read의 got가 적히는 주소이다.

처음 함수를 실행하기전에는 plt의 주소가 적혀있을 것이다.

 

why?

함수를 호출할 때는 got 부분을 호출하는데 got만 계속 호출하기 때문이다. (정확한 검증은 안했지만 일단 이렇게 이해한다.)

 

그렇다면 got에 적힌 plt주소로 갔다고 하자.

2.PLT

plt에는 동적으로 연결된 lib의 실제 함수 주소를 가져와 주는 집사를 부르는 주소가 있다.

이 집사(resolve)에 대해 궁금하다면 다른 자료를 참고하면 된다.

 

이제 이 집사는 libc의 실제 함수 주소를 GOT에 저장시켜준다.

자세히 들여다 보면 COLLAPSED FUNCTION이 보이는데 call procedure function를 말하는 것 같다.

아무튼 이렇게 동적 링킹된 lib에서 실제함수를 불러와 준다.

3. GOT

이제 got에는 실제 함수 libc에 대한 주소가 저장된다.

 

전체적인 흐름은 vmmap을 통해 보면 더 알기 쉽다.

 

0x400000 → plt가 적힌 부분인데 실행권한이 있어 모순이 없다.

0x601000 → got가 적힌 부분이다.

0x7ffff7fef000  → 아마 이곳에 실행권한이 있으니 실제 함수들이 있는 곳으로 추측된다.

동적링킹되는 이 주소에 오프셋을 구하면 된다. 이건 gdb라서 PIE가 없는 것 처럼나오지만 libc에 PIE가 걸려있으므로 이 lib의 시작지점을 구해야 다른 함수들도 오프셋을 통해 찾을 수 있다.

0x7ffff7fcf000  + 0x110180 는 0x7ffff7d147d0이 안되는 이유는 python에서 구한 lib와 pwndbg에서 실행한 lib랑 달라서 그렇다..

 

pwndbg에서 간단하게 lib를 적용시키는 방법을 찾아봤지만 직접 환경 구성하는 것 외에 없는 듯하다..