본문 바로가기

해킹 강의/포너블

[해킹 강의] 시스템 해킹, 포너블의 기본과 BOF 기본

안녕하세요 첫 포너블 강의 시작하게 되었습니다~~ 열심히 쓰도록 해보겠습니다. 와~~~

 

그러면 우선 처음에는 포너블이 무엇인가에 대해서와 BOF에 대해서 알아봅시다.

 

- 본 글은 C언어를 어느정도 숙지했다는 가정하에 글을 씁니다. -


자 이 글을 읽으시는 분은, 아마도 포너블이란 것을 처음 접하시는 분들일 것입니다. 그 중에는 이미 웹해킹이나, 다른 해킹들을 해보신 분들이 있을 것이고, 아예 포너블을 처음으로 시작하시는 분들도 계실겁니다. 좋습니다.

 

우선 포너블이 무엇인가에 대해서 간단하게 알아보도록하겠습니다.

 

포너블은 많이들 어렵다고 합니다. 그렇다면 왜 어려운 것일까요? 그러니까, 사실 웹해킹과 같은 포너블외의 해킹도 깊게 공부하면 매우 어렵다고는 합니다. 그런데 왜 유독 포너블이 어렵다는 이야기를 들을 까요?

 

포너블을 하기 위해서는 시스템에 돌아가는 프로그램을 분석하고, 취약점을 찾아내어서 공격해야 하는데, 이 과정에서 프로그램의 동작방식과 스택프레임, 레지스터, 어셈블리 등의 여러 지식들이 요구되기 때문에, 포너블이 어렵다고 하는 것은 보통 진입장벽이 높다는 이야기일 것입니다.

 

저 같은 경우는 포너블로 해킹을 시작했고, 지금도 주로 포너블을 하기 때문에, 다른 해킹들은 아직 잘 못합니다. 몰론 포너블을 잘한다는 것은 아니에요 아직 초보수준이지만, 제가 배운 것들을 쉽게 알수있게 공유하고 저도 또 배우게 된다면 좋을 것 같습니다.

 

어쨋든, 포너블의 목적은 쉘을 따내는 것이에요, 쉘이란 무엇일까요? 쉘은 리눅스에 있는 명령어 실행기같은 것입니다. 이런 쉘을 따내면, 시스템에 침입할 수 있게 되어 백도어를 남기거나, 루트 쉘을 따게 되면 그 시스템을 장악하게 되는 것입니다. 이 쉘을 따내기 위하여 프로그램의 취약점을 분석하고, 그 프로그램에 걸린 보호기법과 프로그램의 동작 방식에 따라서 공격을 하게 되는 것입니다.

 

여기까지 포너블의 기본적인 개념입니다. 그렇다면 우리는 시스템 해킹을 하기 위하여, 취약점을 공부해야 하는데요, 이 취약점을 공부하고 어떻게 공격할지 알아야, 해킹을 할 수 있기 때문입니다.

 

취약점에는 여러가지 종류가 있는데 가장 기본적인 것이 오늘 포스팅할 BOF라는 것이고, 그 외에 레이스컨디션, UAF, Double Free, Int format issue, format string bug 등이 있습니다. 언젠가 차차 포스팅할 날이 있을 겁니다. 그런데 보통 포너블 문제는 BOF를 거의 사용하기 때문에,(몰론 더 깊게 공부하게 되면 취약점이 매우 많다고 합니다.) BOF를 우선 아시면 됩니다.


그러면 BOF란 무엇일까요?

 

BOF는 Buffer Over Flow의 약자입니다. 말그대로 Buffer를 넘어버렸다는 뜻이에요.

 

C언어의 배열의 접근에 대한 공부를 하고 오시면 더 이해가 편할 수 있겠습니다.

 

스택에서 각 배열은 정해진 크기가 있습니다. 예를들자면

char * buf[256];

다음의 코드에서 buf의 크기는 256이죠. C언어를 잘 공부하셨다면 스택이란 메모리 영역에 대해 이름쯤은 들어보셨을 겁니다. buf라는 이름의 배열은 스택메모리에 저장이 됩니다.

또 프로그램은 자동으로 그 만큼 메모리의 크기를 할당해 놓습니다.

 

그런데 이 메모리는 아쉽게도 배열의 길이를 기억하고 있을 수 가 없습니다. 그래서, buf 주소에 256보다 더 큰 Data를 쓴다고 해도 이를 감지할 방법이 없는 것입니다. 

 

크기가 256인 배열, buf에 보다 큰 Data가 들어왔다.

이런 문제를 일으키는 대표적인 코드는 다음과 같습니다.

scanf("%s", buf);
gets(buf);
fgets(buf, 1000, stdin);
read(0, buf, 1000); // in linux

다음과 같은 코드는 BOF를 발생시키는 코드입니다. C언어를 배우실 때, scanf만 쓰면 보안상 위험한 함수라고 하잖아요 그래서 _CRT_SECURE_NO_WARNINGS 라는 매크로도 정의하잖아요? 그 이유가 바로 BOF를 일으키기 때문입니다.

 

그런데 의아하실 수 있는 점은 이 BOF가 뭐가 문제길래 이렇게 유명할 까요 메모리에서 조금 더 쓰는 정도일 뿐인데 말입니다. 하지만 보안 문제에서 메모리를 조작할 수 있는 취약점은 아주 심각합니다. 스택메모리에는 buf만 있는 것이 아니라, 다른 변수들도 많이 있기 때문에, 이 변수들의 값을 해커가 원하는 값으로 변경할 수 있게 되고, 그러면 프로그램의 흐름을 원하는 대로 조작할 수 있는 것이죠.

 

심지어 스택메모리에는 변수들 뿐만 아니라 함수가 끝난후 실행할 '리턴주소'라는 부분이 있습니다. main함수를 포함한 함수들은 종료되고 나면 이 리턴주소에 적혀있는 부분으로 돌아가 다시 실행을 하는데, 이 리턴주소를 BOF로 조작하는 경우 실행되서는 안될 함수가 실행되기도하며, 또는 프로그래머가 프로그램에서 사용하지 않은 함수조차 사용할 수 있습니다. 그러면 다음을 봅시다.

 

system("/bin/sh");

다음의 코드는 system이라는 함수에 "/bin/sh"라는 인자를 주면서 실행하고 있습니다. 

system함수는 인자로 받은 문자열을 쉘안에서 실행시킵니다. (쉘은 위에서 말씀드렸듯이 리눅스의 명령어 입력기 같은 것입니다. 윈도우의 cmd 같은..)

 

또 쉘안에서 /bin/sh라는 명령어를 사용하는 경우, 그 쉘을 다시 한번 얻어서 실행합니다. 그러므로 프로그램내에서 저 코드를 실행하는 경우 프로그램 사용자가 shell을 얻어내는 것이죠.

 

그러면 정리해봅시다. 포너블의 목적은 쉘을 따내는 것입니다. BOF라는 취약점이 있는데 매우 심각한 취약점이기 때문에, 다른 변수들을 조작하는 것에 모자라 다른 함수를 원하는 대로 호출할 수도 있습니다.

 

그러면 해커가 BOF를 이용하여 위의 system함수를 실행시키는 경우에는 해커가 그 시스템의 쉘을 얻게되면서 해킹에 성공하게 되는 것이죠. 전체적인 흐름은 이렇습니다.

 

하지만 BOF를 막기위한 보호기법이 매우 많고 이들을 우회하는 방법도 매우 많습니다. 또 BOF가 매우 기본적인 취약점이라면, 그 외에 다른 취약점도 많습니다. 시스템 해커를 하려면 이를 모두 공부해야 합니다.

 

몰론 저도 아직 초보입니다만..

 

함께 공부합시다!

 

포스팅 재밌게 보셨다면~ 앞으로도 간간히 재밌는 포스팅 올리도록 할테니 구독해주시면 감사하겠습니다~

BOF가 어떻게 일어나는 지 더 정확하게 보여드리는 심화 강의도 생각중에 있습니다~

 

감사합니다!