Excute
먼저 문제로 주어진 파일을 실행시키면
어떤 함수를 호출할지 물어보고 값을 입력해주면 종료된다. 아마 취약점을 찾아 shell을 띄우거나 플래그를 출력할 수 있는 함수를 호출 해주면 될 것 같다.
적용되어있는 보호기법은 아래와 같다.
Analyze
IDA에 올려서 프로그램의 실행 흐름을 분석해보자
Main
- Line 9 : gets함수를 통해 길이를 제한하지 않고 입력을 받는다.
- Line 10 : select_func 함수에 앞서 입력받은 값을 인자로 전달해 준다.
Select_func
- Line 3,4 : char형 변수 dest와 함수 포인터 v3를 선언해준다.
- Line 6 : v3포인터 변수에 함수 two의 주소를 대입한다.
- Line 7 : strncpy함수를 호출에 인자로 받은 src를 0x1f만큼 dest에 복사해준다.
- Line 8~10 : dest의 값이 “one”일 경우 v3에 one함수의 주소를 대입해준다.
One
Two
one함수 two함수 모두 별다른 동작을 하지 않고 단순히 문자열 출력만을 수행한다.
Print_flag
앞서 언급한 것처럼 flag를 출력해주기 위한 함수가 존재한다. 따라서 print_flag함수가 실행 될수 있도록 exploit을 작성해주면 될 것이다.
Solve
문제 해결을 위해서는 궁극적으로 v3변수에 들어가는 주소를 print_flag함수로 변경해주어야한다. 먼저 IDA에서 함수들의 offset을 확인해보자
함수들의 offset을 살펴보면 two함수와 print_flag함수가 마지막 1byte만 다른 것을 확인 할 수 있다. 따라서 select_func함수에서 v3변수에 two함수의 주소를 대입해주므로 마지막 1byte만 조작해주면 성공적으로 flag를 획득 할 수 있을 것이다.
이제 마지막 1byte를 어떻게 변경시킬 것인지에 대한 고민을 해보아야 한다. 사실 문제 설계부터 딱 1byte만 조작 가능하도록 설정되어있다. IDA를 통해 selec_func함수 내의 지역변수의 스택내부에서 위치를 살펴보자.
여기서 dest는 ebp-2A위치에 v3는 ebp-C에 위치하는 것을 확인 할 수 있다. dest와 v3 사이의 거리를 계산 해보면 0x1E임을 확인 할 수 있는데 정작 strncpy함수가 복사해주는 길이는 0x1F이므로 1byte만큼 차이가 존재하는 것을 확인 할 수 있다. 따라서 dest에 dummy*30 + 0xD8을 넣을 수 있다면 문제가 성공적으로 해결 될 것이다.
해당 상황에서 스택의 구조와 공격 흐름은 아래와 같다.
성공적으로 flag가 출력 되는 것을 확인 할 수 있다.
'Wargmae > HackCTF' 카테고리의 다른 글
[Hack CTF – x64 Buffer Overflow] (0) | 2021.01.05 |
---|---|
[Hack CTF – 내 버퍼가 흘러넘친다!!!] (1) | 2021.01.03 |
[Hack CTF - Baisc_FSB] (0) | 2021.01.03 |
[Hack CTF - Basic_BOF #2] (0) | 2021.01.02 |
[Hack CTF - Basic_BOF # 1] (0) | 2021.01.02 |