Return Address Overwrite
Description Exploit Tech: Return Address Overwrite에서 실습하는 문제입니다.
dreamhack.io
rao.c

코드 해석
- Stack Buffer Over Flow 가 발생할 수 있는 코드이다.
- x64 체제이다.
- main 함수에서 scanf("%s", buf); 에서 문자열의 길이를 지정하지 않았기 때문에 취약점이 발생할 수 있다.
이는 함수의 문자열 길이를 길게 주게 되면 main 함수의 반환 주소를 덮을 수 있다는 뜻이다.
문제 해석
Stack Buffer Over Flow 취약점을 발생시켜 buffer 가 정리될 때 get_shell() 함수로 return 되게 스택을 덮어쓰면 되는 문제이다.
해결방안

n 개를 정확히 입력 받는 형태로 사용하여 buffer 보다 큰 크기의 입력 데이터를 방지한다.
취약점 트리거
먼저, 발견한 취약점을 발현시키는 것을 트리거라고 한다.

'A' 를 5개 입력했을 때 정상적으로 프로그램이 종료된다.

'A' 를 64개 이상 입력했을 때 프로그램이 비정상적으로 종료된다.
- 이는 프로그램이 잘못된 메모리 주소에 접근했다는 의미이며, 프로그램에 버그가 발생했다는 신호이다.
- (core dumped) 는 코어파일(core) 을 생성했다는 것으로, 프로그램이 비정상적으로 종료됐을 때, 디버깅을 돕기 위해 운영체제가 생성해주는 것이다.
스택 프레임 구조 파악
주목해서 봐야 할 코드는 scanf 에 인자를 전달하고 있는 부분이다.

노란색 네모 박스 친 부분을 살펴보면, buf 에 rbp-0x30 이 존재하는 것을 알 수 있다.
이것들을 바탕으로 스택 프레임 구조를 살펴보겠다.

- 사용자의 입력이 들어갈 스택의 위치인 buf 는 rbp-0x30 이고, buf 가 0x30 만큼 할당되어 있다.
- 이후 주소이므로 0x8 인 SFP 가 저장되고 rbp+0x8 에 return address 가 저장된다.
get_shell() 주소 확인

get_shell() 의 주소가 0x4006aa 임을 확인했다.
※ 코드를 컴파일 한 후 진행하면 get_shell() 주소가 0x4011dd 로 나오고 페이로드가 실패하니 컴파일을 하지 않도록 주의한다. 많은 삽질 후 얻은 결과이므로 주의하자....
페이로드

페이로드를 작성해 보았다.
- 문자열 buf 를 'A' 로 0x30 을 채워준다.
- 문자열 'B' 로 0x8 을 SFP 로 채워준다.
- 리틀엔디언으로 get_shell() 주소를 넣어준다.
여기서 엔디언이 뭔지 간단히 짚고 넘어가도록 하겠다.
엔디언
메모리에서 데이터가 정렬되는 방식을 엔디언이라고 한다.
엔디언은 리틀엔디언과 빅엔디언이 있다.
- 리틀엔디언 : 데이터의 MSB 가 가장 높은 주소에 저장된다.
- 빅엔디언 : 데이터의 MSB 가 가장 낮은 주소에 저장된다.
- MSB : Most Significat Byte (가장 왼쪽의 바이트) 이다.
간단한 예를 들어보자.

결과

정상적으로 flag 값을 도출할 수 있다.
'Pwnable > Dreamhack' 카테고리의 다른 글
| [Dreamhack] Return to Shellcode (0) | 2023.08.25 |
|---|---|
| [Dreamhack] basic_exploitation_000 (0) | 2023.08.24 |
| [Dreamhack] basic_exploitation_001 (0) | 2023.08.24 |
| [Dreamhack] shell_basic (0) | 2023.07.20 |