해당 내용은 드림핵의 강의 내용을 정리했습니다
라이브러리
라이브러리는 컴퓨터 시스템에서, 프로그램들이 함수나, 변수를 공유해서 사용할 수 있게 한다. C프로그램에선 printf, scanf, strlen, memcpy, malloc 등이 자주 사용된다.
C 표준 라이브러리 libc는 우분투에 기본적으로 설치된 라이브러리이다.
링크
프로그래밍 언어에서 컴파일의 마지막 단계라고 알려져있다. 프로그램에서 어떤 라이브러리 함수를 사용하면, 호출된 함수와 실제 라이브러리의 함수가 링크 과정에서 연결된다.
리눅스에서 C 소스 코드는 전처리, 컴파일, 어셈블 과정을 거쳐 ELF 형식을 갖춘 오브젝트 파일(object file)로 번역된다. 오브젝트 파일은 실행 가능한 형식이지만, 함수의 선언이 stdio.h에 있어서 심볼로는 기록되어 있지만 자세한 내용은 기록되지 않아서 실행할 수 없다.
libc에서 함수의 정의를 찾아 연결하는데, libc를 같이 컴파일하지 않았음에도 libc에서 심볼을 탐색한 것은, libc가 있는 경로를 표준 라이브러리 경로에 포함되어 있기 때문이다. gcc는 소스 코드를 컴파일할 때 표준 라이브러리의 라이브러리 파일을 모두 탐색한다.
결론 : 링크를 거친 후 프로그램에서 함수를 호출할 때, 함수가 정의가 있는 libc에서 함수의 코드를 찾고 해당 코드를 실행.
라이브러리와 링크의 종류
라이브러리는 동적 라이브러리와 정적 라이브러리로 구분된다. 동적 라이브러리 링크는 동적 링크, 정적 라이브러리 링크는 정적 링크라고 한다.
동적 링크
동적 링크된 바이너리를 실행하면 동적 라이브러리가 프로세스의 메모리에 매핑된다. 실행 중에 라이브러리의 함수를 호출하면 매핑된 라이브러리에서 호출할 함수의 주소를 찾고, 그 함수를 실행한다.
정적 링크
정적 링크를 하면 바이너리에 정적 라이브러리의 필요한 모든 함수가 포함되고, 해당 함수를 호출할 때, 라이브러리를 참조하는게 아닌 자신의 함수를 호출하는 것처럼 호출가능하다. 또한 라이브러리에서 원하는 함수를 찾지 않아도 되니 탐색의 비용이 절감되는 듯하지만, 여러 바이너리에서 라이브러리를 사용하면 라이브러리 복제가 여러번 이루어져서 용량을 낭비하게 된다.
PLT와 GOT
PLT와 GOT는 라이브러리에서 동적 링크된 심볼의 주소를 찾을 때 사용하는 테이블이다.
- 바이너리 실행하면 ASLR에 의해 라이브러리가 임의의 주소에 매핑
- 라이브러리 함수 호출 시 함수의 이름을 바탕으로 라이브러리에서 심볼들을 탐색
- 해당 함수의 정의 발견 시 그 주소로 실행 흐름 옮김
이 모든 과정은 RUNTIME RESOLVE라고 한다.
그런데 만약 반복적으로 호출되는 함수의 정의를 매번 탐색하면 비효율 적이기에 ELF는 GOT라는 테이블을 두고, resolve된 함수의 주소를 해당 테이블에 저장한다. 이후 다시 해당 함수 호출 하면 저장된 주소를 꺼내서 사용한다.
시스템 해킹의 관점에서 본 PLT와 GOT
PLT와 GOT은 동적 링크된 바이너리에서 라이브러리 함수의 주소를 찾고, 기록할 때 사용되는 중요한 테이블이다.
하지만 PLT에서 GOT를 참조하여 역참조하여 실행 흐름을 옮길 때 GOT 값을 검증하지 않는다는 약점이 있다
GOT 엔트리에 저장된 값을 공격자가 임의로 변경할 수 있으면 이후에 동일한 라이브러리를 사용할 때 해당 위치로 이동해서 실행하게 된다!
gdb에서 라이브러리를 찾아가는 함수에 가서 got 명령어를 사용하여 GOT의 주소를 찾고, 그 주소를 변환시키면 해당 함수가 실행된 이후에 그 주소로 이동한다.
'시스템해킹' 카테고리의 다른 글
dreamhack ssp_001 writeup (0) | 2023.11.16 |
---|---|
dreamhack ssp_000 writeup (0) | 2023.11.16 |
pwnable.kr bof writeup (0) | 2023.11.16 |
[LAZENCA] ROP-x64 part.4 (2) | 2023.11.09 |
[LAZENCA] ROP-x64 part.3 (0) | 2023.11.09 |