BOF
Buffer OverFlow
프로그램이 실행될 때 입력받는 값이 버퍼를 가득 채우다 못해 넘쳐서, 버퍼 이후의 공간을 침범하는 현상
그렇게 버퍼를 넘어가서 다른 곳을 침범한 값들은 해당 부분에 원래 있던 값을 덮어씌워 버린다.
덮어씌워진 부분이 return address라면?
악의적인 동작을 하는 함수가 있는 곳으로 return 해버린다면?
-> 버퍼 오버 플로우 공격
nc pwnable.kr 9000
wget http://pwnable.kr/bin/bof
wget http://pwnable.kr/bin/bof.c
wget : 'Web Get'의 약어로 웹 상의 파일을 다운로드 받을 때 사용
다운 받은 bof 파일을 실행해보면
입력하라는 게 떠서 입력해보면 프로그램이 끝나버린다.
다시 실행해서 엄청 길게 입력해보면
충돌했다고 경고가 뜬다.
gedit bof.c 명령으로 bof의 코드를 살펴보자
main 함수를 보면 func 함수를 호출하는데 인자로 0xdeadbeef를 넘기고
func 함수를 이어서 보면 char 변수 32바이트를 선언하고 overflow me 라는 문자열을 출력한 뒤에 gets로 overflowme를 받는다. 옆에 주석 있는거 보면 gets 부분을 공격하라는 것을 직관적으로 알 수 있다.
그 뒤에는 if else 문으로 main에서 받아온 인자(0xdeadbeef)가 0xcafebabe와 같으면 /bin/sh를 실행하고, 아니면 Nah를 출력하는 것을 알 수 있다.
+) if else 문에서 gets에서 받아온 거랑 비교하는게 아니라 main 함수에서 받아온 인자와 비교하는 것이기 때문에 0xcafebabe를 프로그램에 입력하는 것은 의미 없음
그래서 결국 이 문제 풀려면 gets 부분에 overflow를 내야 한다. 그 뒤 key 값을 0xcafebabe로 변경하면 된다.
gets 함수가 bof 가능한 이유
gets 함수는 값을 받아올 때 개행 문자나 파일 끝을 만나기 전까지를 기준으로 가져온다.
따로 크기를 검사하지 않아서 overflowme[32]에 할당된 크기를 초과해서 입력할 수 있기 때문에 취약하다.
근데 얼마나 초과해야하는지 생각해야 함
overflowme[32]랑 0xdeadbeef 까지 사이 거리 알아보기
gdb 사용
call이 4번 있는데, 코드 보면 알 수 있음 (순서대로 printf, gets, system, printf)
첫 번째 call 다음 lea 보면 eax에 ebp-0x2c 저장 (이 주소가 오버플로우 시작 주소)
두 번째 call이 gets 함수고, 다음 cmp(if문)보면 0xcafebabe와 비교하는 ebp+0x8이 key
overflowme[32]랑 0xdeadbeef 까지 사이 거리는 (ebp+0x8) - (ebp-0x2c) 하면 알 수 있다.
(ebp+0x8) - (ebp-0x2c) = 0x8 + 0x2c
= 8+44
= 52
+) 다른 방식으로 구하는 방법
cmp 부분 오른쪽 보면 40만큼 떨어졌다고 알 수 있다.
그래서 gdb에서 b *func+40으로 breakpoint 걸어주고 실행
임의 값 넣어주면
cmp에서 멈춤(breakpoint 걸었으니까)
x/30x $esp로 esp 보면 내가 임의로 넣은 값이 넣어진 거 볼 수 있고 deadbeef 위치도 같이 보임
거기서 바로 주소 구하고 빼주면 간단
key는 cafebabe이지만 리틀 엔디안 방식이니까 be,ba,fe,ca 이런 순서로 들어가야 한다.
코드 작성
코드 실행
'Pwnable' 카테고리의 다른 글
[Pwnable] ropasaurusrex (0) | 2021.05.26 |
---|---|
[dreamhack] basic_exploitation_001 (0) | 2021.05.18 |
[Pwnable] GDB로 코드 분석 (0) | 2021.05.11 |
[Pwnable] GDB 사용방법 정리 (0) | 2021.05.11 |
[pwnable.kr] collision (0) | 2021.05.05 |
댓글