시스템 해킹실습 - 1. Buffer OverFlow (버퍼 오버플로우)

2024. 7. 15. 17:26Information Security 정보보안/Vulnerability Analysis 취약점 분석

728x90

배울내용:

버퍼 오버플로우 취약점

시스템 해킹

Buffer OverFlow

버퍼 오버플로우의 발생 원리

버퍼오버플로우 실습 

버퍼 오버플로우 방지 방법

메모리 취약점

버퍼 오버플로우 스택구조

 

 

그림출처: https://www.invicti.com/blog/web-security/buffer-overflow-attacks/

 

 

취약점은 공격 방법에 따라 크게 2가지로 구분된다

• Memory Corruption : 개발자가 의도하지 않은 방식으로 동작하여 메모리 공간을 사용하거나 읽는 등 메모리를 오염시키는 행위(Crash를 통해 판단)

• Logical Bug : 프로그램의 논리적 오류로 인해 발생하게 되는 취약점(Crash가 발생하지 않으며 발견하기 어려움)

 

 

 

 

 

이번글에서는 메모리의 경계를 넘어서 데이터를 읽거나 쓰는 경우 발생하는 취약점과 그외에 아래의 표에 보이는 몇가지를 실습을 해볼것이다. 가장먼저 버퍼 오버플로우 (Buffer Overflow) 다. 

 

 

 

 

 

버퍼 오버플로우의 발생 원리

 

버퍼 오버플로우의 발생원리가 대표적으로 3개가 있는데 

  1. 고정된 크기의 버퍼: 프로그래머가 고정된 크기의 버퍼(예: 배열)를 정의하지만, 입력 데이터의 크기를 확인하지 않고 버퍼에 데이터를 저장할 때 발생.
  2. 입력 검증 부족: 사용자의 입력을 제대로 검증하지 않고 버퍼에 복사할 때 발생. 예를 들어, strcpy 함수는 목적지 버퍼의 크기를 확인하지 않음.
  3. 경계 검사를 하지 않음: 데이터를 버퍼에 쓸 때 경계를 확인하지 않아서 발생한다.

 

 

 

 

우선 아래의 코드를 한번 분석해보자 

 

 

엄청 간단해보이지만 분석을 해보면 그렇게 간단해보이지는 않은것이다.

 

 

 

 

 

먼저 buf 를 할당하는게 보이고 gets(buf) 에서도 사용자 입력값을 넣을수있는데 길이제한이 없다 ( 길이제한쓸거면 fgets 함수) 

 

 

 

 

그럼 한번 코드를 실행해보자 

 

 

 

 

 

코드를 실행하니 Input Name: 이라는게 뜨고 거기에 원하는 이름을 넣고

엔터를 누르면 My name is [입력값] 이 출력이 된다.

 

이제 이 파일을 분석을 해봐야하니

gdb ./bof_ex 로 실행을 하고 disass main 으로 메인함수를 디스어셈블링 수행을 한다 

 

 

 

 

 

 

 

 

 

이렇게 보이게 된다. 

이제 분석을 하려면 breakPoint 를 설정해주고 ni 로 하나하나 실행해보자

 

 

 

 

브레이크 포인트를 걸고 해당지점까지 실행한뒤에 보면 

 

 

아래의 rbp , rsp 가 보이고 sub 로 0x10 만큼 할당해주는걸 볼수있다 (HEX 로 10 이면 DEX 로는 16 ) 

그리고 ox7ffffffffdeb0 와 같이 보이는 것들은 메모리 주소이다 

 

 

 

 

 

 

 

 

 

 

 

 

 

빨간색을 보면 16 크기의 스택을 생성하고 그안에서 0 으로 초기화 시켜준걸 오른쪽에 그림을 보면 쉽게 알수있다. 

 

 

 

 

 

 

 

 

그리고 아까 입력받는 곳에 A 를 16개를 입력하면 오른쪽에 그림과 같이 스택에 가득차게 되고 

 

 

 

 

 

 

retaddr 명령어로 돌아갈 주소를 출력하는데 주소 옆에  __libc_start_main+231_ 라고 적힌게 보이게 된다 

BOF (Buffer OverFlow) 에서는 위에 설명이 적힌 주소를 다른곳으로 바꿀수있다.  (변조)

 

 

 

 

 

 

 

   

그러면 이번엔 돌아갈주소와 rbp 주소도 A 로 가득채우고 싶다

 

 

 

기본적으로 rbp 주소와 돌아갈주소는 각각 8 의 크기를 가지고 있다 

그러면 rbp 주소를 가득채우면 돌아갈주소를 공격자가 원하는 장소로 넣을수있는 코드를 넣을수있다

 

 

 

그러면 이것이 버퍼 (16) + rbp (8) + 돌아갈주소(8)   총  32 에 버퍼와 rbp (24) 를 넣고 원하는 값을 넣으면

돌아갈주소에 원하는 값이 들어가게 되는 것이다. 

 

 

 

 

 

 

그러면 입력받는 값에 A X 16 개 , B X 8 개 , C X 8 개 를 하게 되면

AAAAAAAAAAAAAAAABBBBBBBBCCCCCCCC 이렇게 입력하게 되고

오른쪽 스택이 그려진 그림에 스택에는 A 로 가득차고, rbp 부분에는 B 로 그리고 변조하고자 하는 

리턴값에는 C 로 가득 채울수가있다

 

 

 

 

 

 

 

 

그러면 retaddr 로 리턴값을 출력하보면 기존에 __libc_start_main+231_ 이렇게 적힌게 아닌 CCCCCCCC 로 변조된걸 볼수있다. 이떄 CCCCCCCC가 아닌 공격자가 원하는 곳으로 이동시키는 코드를 넣어버리면 BOF 의 취약점을 이용한 공격을 하는 것이다. 

 

 

 

 

 

 

그렇게 이용해서 SARIMUSS 라는 것도 넣을수가있게 되는것이다 

 

버퍼 오버플로우 방지 방법

  • 경계 검사: 모든 입력 데이터의 크기를 확인하고, 버퍼의 경계를 넘지 않도록 검사를 수행.
  • 안전한 함수 사용: strcpy 대신 strncpy, gets 대신 fgets 등 크기 제한을 확인할 수 있는 안전한 함수 사용.
  • 스택 보호 기법: 스택 가드(canary) 등 스택의 무결성을 확인하는 기법을 사용.
  • 주소 공간 배치 난수화(ASLR): 메모리 주소를 무작위로 배치하여 예측하기 어렵게 만듦.
  • DEP(Data Execution Prevention): 데이터 영역에서 코드 실행을 방지하여 버퍼 오버플로우로 인한 코드 실행을 막음.
  • 정적 분석 도구: 코드 내의 잠재적인 버퍼 오버플로우 취약점을 찾기 위한 도구 사용.

 

 

728x90