티스토리 뷰

Linux에서는 프로세스가 운영체제 커널에 어떤 동작을 요청하기 위해 시스템을 호출하는 방법은 2가지가 있다.

하나는 libc(라이브러리)의 포장함수를 통해 호출하는 방법, 또 하나는 시스템 콜을 통해 직접 실행하는 방법이다.

 

포장함수란 무엇인가? 포장함수는 이름 그대로 포장된 함수이다. 편의성 또는 기능을 보다 확장하기 위해 기본적으로 동작을 요청하기 위한 시스템 콜에 특정 기능을 추가하여 포장한 함수이다.

운영체제 커널에 시스템 콜을 할 경우 어떤 동작 또는 서비스를 요청하여 실행할 수 있는데 이것을 위해 시스템 콜은 여러 개가 있으며 필요에 따라 쉽게 사용될 수 있도록 C 함수처럼 호출될 수 있도록 만들어져 있다.

따라서 포장함수는 시스템 콜을 함수처럼 내부에서 호출할 수 있도록 그대로 가져다 사용하고 그 밖의 특정 기능을 추가하여 포장한 함수이다.


시스템 콜의 갯수만 해도 상당히 많으며 이것을 포장한 포장함수는 정말로 무수히 많다. 

하지만 이 글은 포장 함수 gets와 fgets가 가져다 사용하는 시스템 콜에 의해 사용되는 임시 버퍼를 말하고자 하기 때문에 간단하게 이해하고 넘어가려고 한다.



아래는 gets와 fgets 함수를 가져와 사용한 간단한 예제 소스이다.




gets와 fgets 함수를 통해 각각 문자열 표준 입력을 받는 것을 볼 수 있다. 차이점은 gets와 fgets 함수의 사용유무 뿐이기 때문에 출력 결과는 동일하다. 다만, fgets 함수는 gets 함수와 달리 인자의 크기를 고려하고 있어 상황에 따라 BOF가 일어날 경우는 결과가 달라질 것 이다.



strace를 통해 두 개의 프로그램을 살펴보자.(easy = gets 함수, easy1 = fgets 함수)

실습 진행을 위해 방어기법 ASLR은 해제한 후 진행하였습니다.


둘 다 비슷한 표준 입력함수이며, 출력 결과 또한 동일하기 때문에 특별한 차이점은 없다. 

중요한 것은 빨간색 시긱 테두리가 둘러진 부분이다. 이 부분이 바로 gets와 fgets 함수를 통해서 표준 입력을 받는 부분인데 시스템 콜 중 하나인 read를 사용하여 표준 입력(첫 번째 인자가 표준 입력 디스크립트 0)을 받는 것을 볼 수 있다. 


시스템 콜 read는 기본적으로 임시 버퍼를 가지고 있다. 그리고 gets와 fgets 같은 포장함수는 내부에서 시스템 콜 read를 호출하기 때문에 결과적으로 read와 동일하게 임시 버퍼를 가지게 된다. 그리고 이 임시 버퍼의 주소는 mmap2가 반환하는 값이다.(ASLR을 해제한 상태이기 때문에 gets와 fgets 함수의 주소가 동일하다.)



mmap2가 반환한 값이 정말로 임시 버퍼인지 gdb를 통해 확인해 보도록 하자.



표준 입력 함수가 바로 종료된 직후인 main 함수의 62번째 부분에 Break Point를 지정한 후 실행시켰다. 이 때, 표준 입력은 이전 strace와 동일하게 World!를 입력하였다.


먼저, fgets를 통해 표준입력을 받는 문자열 버퍼 buf의 주소인 esp+0x18의 주소를 확인해 보자.

본래 fgets 함수를 통해 문자열 버퍼 buf에 표준 입력을 하고 있기 때문에 buf에 제대로 값이 들어간 것을 확인할 수 있다.


이번에는 strace를 통해 확인할 수 있었던 시스템 콜 read의 임시 버퍼를 확인해 보도록 하자. 임시 버퍼의 주소는 0xb7fd6000 이였다.

표준 입력의 대상 버퍼가 아님에도 불구하고 World!라는 문자열이 저장되어 있는 것을 볼 수 있다. gets나 fgets 함수를 통해 내포되어 있는 시스템 콜 read를 통해 임시 버퍼가 사용된 것을 볼 수 있다.



참고로 gets와 fgets 함수 만을 이용해서 예를 들게 되었지만 시스템 콜 read를 호출하는 포장 함수는 이외에도 여러가지가 많다. 또, read 함수를 사용하기 때문에 역시 임시 버퍼 또한 존재한다. 

표준 입력 함수를 여러 번 사용할 경우 종종 원하지 않던 결과를 볼 수 있는데 이유는 프로그램 실행 후 종료가 되기 전 까지 이 임시 버퍼가 계속하여 사용되기 때문에 이전의 값을 불러오기 때문에 발생하는 문제이다. 따라서 fflush 같은 함수로 이 임시 버퍼를 정리할 필요가 있는 것이다.

'System > Linux' 카테고리의 다른 글

ropgadget find  (0) 2016.01.06
32bit와 64bit의 차이  (0) 2015.12.29
쉘 스크립트  (0) 2015.11.30
gcc 컴파일러  (0) 2015.11.28
Xwindow 화면 전환 방법  (0) 2015.11.28
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31