해킹 공부/시스템 해킹

FTZ 해커스쿨 level9 - 버퍼오버플로우(GDB 이용)

O'bin 2021. 11. 14. 21:32

id :  level9

pw :  apple

 

 

 

<나의 풀이 기록>

 1.  파일 목록 확인(ls) 후 힌트 파일 내용 확인(cat hint)

 

 

힌트에 나와있는 /usr/bin/bof의 소스를 살펴보면 아래와 같다.

더보기

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

main(){

  char buf2[10];           //문자 배열 buf2 선언
  char buf[10];            //문자 배열 buf 선언

  printf("It can be overflow : ");     
  fgets(buf,40,stdin);                          // 입력받은 값을 buf에 저장, 입력 가능 최대 사이즈 40

  if ( strncmp(buf2, "go", 2) == 0 )      // buf2의 값 2개와 go 비교해서 같으면,
   {
        printf("Good Skill!\n");
        setreuid( 3010, 3010 );            // set real user id(RUID) and effective user id(EUID)
        system("/bin/bash");               // 위에서 설정된 권한으로 쉘 열기
   }

}

 

 

 

 2.  /usr/bin/bof 파일을 실행해 보면

 

 

값을 입력할 수 있는데, 정답이 아닌 값을 입력하면 프로그램이 종료되어버린다.

 

 

 

 

 3.  이 문제를 해결하기 위해선 위 소스코드 분석에서 알 수 있듯이 buf2 맨 앞에 go가 들어가야 한다.

그런데 buf2에 값을 입력할 방법이 없다.  It can be overflow : 뒤에 입력하는 값은 buf에 저장된다. 

 

 해결방법을 찾기 위해 이 프로그램을 자세히 살펴봤다.

 

 

bof 파일은 level9에선 실행만 가능할 뿐 읽기도 불가능하다.

 

 

 

 

 

 4.  처음 힌트에서 bof파일의 소스코드를 알려줬으니 직접 내용이 똑같은 파일을 만들기로 했다.

 

vi 파일명.c 로 파일 편집기 열기(나는 bof.c로 했다)

파일 내용 입력(위 힌트에서 소스코드 부분 드래그 하고 마우스 오른쪽 버튼을 누르면 자동으로 복사&붙여넣기가 한번에 이루어진다.)

:wq 입력해 편집기 종료

gcc -g -o 실행파일이름 소스파일이름.c (나의 경우는 gcc -g -o bof1 bof.c 입력) : 컴파일 후 실행파일 생성

이렇게 하고 파일 목록을 확인하면(ls) 실행파일 bof1과 소스파일 bof.c가 있는 것을 볼 수 있다.

 

 

 

 5.  gdb를 이용해 프로그램을 어셈블리어로 분석해 볼 수 있다.

 

 GDB란? 

유닉스 기반의 시스템에서 동작하는 이식성있는 디버거로, 에이다, C, C++, 포트란 등의 여러 프로그래밍 언어 지원 

GDB는 컴퓨터 프로그램의 실행을 추적하고 수정할 수 있는 많은 기능들을 제공

사용자는 프로그램의 내부 변수들의 값을 주시하거나 변경할 수 있으며, 프로그램의 일반적인 실행 과정과 독립적으로 함수를 호출할 수도 있다.

 

gdb 실행파일이름 입력 시 gdb가 실행된다.

 

 

 

set disassembly-flavor intel : intel 문법 적용

disas main : main함수 디버깅(disassembly)

gdb를 종료하려면 quit을 입력하면 된다.

위 두가지를 입력하면 어셈블리어로 분석된 main함수를 볼 수 있다.

 

 

이 중 주목해야 할 부분이 바로 빨간 네모 안의 내용인 buf와 buf2의 주소이다. 

먼저 선언된 buf2의 주소가 40부터이고 나중에 선언된 buf의 주소가 24부터이다.

두 주소의 차이가 16만큼 나는 것을 볼 수 있다.

따라서 프로그램 실행 후 값을 입력하면 buf로 들어가지만

입력된 값의 크기가 16을 넘어서면 그때부터는 buf2의 공간을 침범해 buf2에 들어가게 된다.

 

따라서 16개의 문자로 buf를 꽉 채우고 그 뒤에 go를 입력하면 go는 buf2에 들어가 if 조건이 성립한다.

 

 

 

 6.  버퍼 오버 플로우(buffer over flow)를 이용해서 문제를 풀어봤다.

 

 

무작위 문자 16개 입력 후 go를 넣어주면 buf2 맨 앞에 go가 들어가 if문이 성립후 level10의 쉘 열림

 

 

my-pass로 비밀번호 획득

 

 

 

 

<풀이 요약>

1. 파일 목록 확인(ls), 힌트 파일 확인(cat hint)
2. 힌트 내용 /usr/bin/bof 실행
3. bof 파일 정보 확인
4. bof파일과 같은 내용 파일 생성
5. gdb로 프로그램 내용 분석
6. 버퍼오버플로우 이용해 비밀번호 획득

 

 

 

 

 

본격적인 버퍼오버플로우 문제를 처음 푼 것 같은데 솔직히 많이 어려웠고, 인터넷 정답을 읽고도 이해하는데 오래걸렸다. 많이 부족하다는 사실을 뼈저리게 느꼈다..^^ 리눅스 수업 열심히 들을걸... 재수강 해야지... 그땐 진짜 열심히 들어야지.......

그래도 내 블로그에 정리하면서 여기 있는 내용만큼은 습득한 것 같다. 몇번 더 읽어보고 버퍼 오버플로우에 대해서도 자료들을 더 찾아봐야겠다.