Buffer Overflow 공격

- 고전적인 방법

가장 고전적인 방법은 NOP를 이용하는 것이다. NOP는 No Operation의 약자로 기계어 코드가 다른 코드와 섞이지 않게 하는 역할을 한다. 따라서 CPU가 NOP를 만나면 아무런 수행을 하지 않고 유효한 instruction을 만날 때까지 한 바이트씩 이동한다.

 

쉘 코드의 시작 주소를 정확하게 알 수 없기 때문에 이러한 NOP의 특성을 이용해서 buffer overflow 공격을 실행하는 것이다. 쉘 코드의 앞을 NOP로 채우고 return address를 NOP가 채워져 있는 영역 어딘가의 주소로 바꾸면 EIP는 NOP를 지나 쉘 코드가 있는 곳을 가리키게 된다.

 

 

- 환경변수를 이용하는 방법

*nic 계열의 쉘에서 환경변수는 포인터로 참조된다. 그래서 메모리 어딘가에 환경변수는 항상 저장되어 있다. 이러한 특성을 이용해서 buffer overflow 공격을 실행할 수 있다.

 

환경변수를 하나 만들고 이 환경변수에다 쉘 코드를 넣은 다음 공격 대상 프로그램에 환경변수의 주소를 return address에 넣어주면 쉘 코드를 실행할 수 있다.

 

환경변수는 스택의 상단에 위치하기 때문에 프로그램을 실행했을 때 stack pointer는 환경변수 아래쪽을 가리킨다. 따라서 새로 만든 환경변수에 쉘 코드와 NOP를 넣고, stack pointer를 return address에 넣어주면 EIP가 NOP를 지나 쉘 코드 시작점에 도달하게 된다.

 

 

- Return into libc 기법

Return into libc 기법은 non-executable stack 보호 기법이나 일부 IDS(intstruction detection system)에서 네트워크를 통해 쉘 코드가 유입되는 것을 차단하는 보호 기법을 뚫기 위한 방법으로 제안되었다.

 

앞에서 설명한 stack overflow 공격 기법들은 non-executable stack 방어 기법에 의해 공격이 막힌다. non-executable stack 기법은 스택 영역에 있는 코드를 실행하지 못하게 하는 기법이기 때문에 stack segment에 쉘 코드를 넣는 stack overflow 방식은 공격이 막힐 수밖에 없다. 이러한 공격 방어 기법들을 우회하기 위해 나온 것이 바로 Return into libc 기법이다.

 

Return into libc 기법도 overflow 공격에 기반한다. 버퍼를 overflow시켜 return address 영역에 실행시키고자 하는 libc 함수의 주소를 넣어주는 것이다. return address에서 libc 함수로 넘어갈 때 인자값을 가지고 가는데, 이 인자값이 저장되는 위치에 원하는 인자를 삽입하면 된다.    인자의 위치는 buffer나 이전 함수의 base pointer, argument가 있는 영역 어디든 될 수 있다. 

복사했습니다!