-
[L.O.B] Level 12 - golemWargame/L.O.B 2022. 11. 2. 07:50반응형
Level 12 - golem을 풀어보자.
새로운 공격 기법이 나타났다!!
소스 코드를 보면 다음 Level은 darkknight이고, FPO라는 힌트가 있다.
간략히 보자면 problem_child 함수의 내용은 40 바이트 크기의 char형 buffer에 src를 41 바이트 복사한다.
그 후 buffer를 출력하며 종료되는데, main 함수에서 이 함수를 실행시킨다.
앞의 Level들과 비교하자면 소스 코드의 길이는 굉장히 줄었고, 제약 조건도 하나밖에 없다.

<darkkinght 소스 코드의 내용> gdb 분석을 통해 dummy 값을 포함해 좀 더 자세히 알아보자.
그런데, 소스 코드 자체가 짧아서 그런지 gdb에 나타나는 내용도 굉장히 간단하다.
문제에 대한 접근을 어떻게 하면 좋을까??


<darkknight 파일 gdb 분석> 소스 코드에서 FPO라는 힌트가 있었다.
FPO란, Frame Pointer Overflow라고 한다.
이것은 스택을 이용할 때에 중요한 개념인 스택 프레임의 SFP를 이용한 공격이다.
FTZ를 풀면서 간략하게 설명했는데, SFP는 Saved Frame Pointer를 뜻하며 이전 함수의 Base Pointer를 가진다.
FPO는 두 가지 조건이 필요하다.
1. SFP 영역에 1Byte 이상의 Overflow가 발생
2. 메인 함수와 서브 함수가 필요
스택은 이용할 때 스택 프레임을 형성한다.
이 스택 프레임을 형성할 때 함수 프롤로그, 함수 에필로그의 과정을 거친다.
위 두 과정은 기본 개념이므로 구체적인 설명은 생략하도록 하자. (구글링을 통해 쉽게 찾을 수 있다.)
풀이를 위해 필요한 함수 에필로그 과정은 간단한 설명이 필요할 것 같다.
[함수 에필로그]
더보기함수 에필로그는 두 단계를 거친다
1. leave : mov esp, ebp -> pop ebp
- ebp의 값을 esp에 복사함으로써 두 레지스터가 모두 SFP를 가리키게 한다.
- pop 명령어를 통해 ebp는 SFP의 값을 가지면서 이전 함수의 ebp를 가리키게 된다.
- pop 명령어를 통해 esp는 가리키던 SFP에 +4를 하여 RET를 가리키게 된다.
2. ret : pop eip -> jmp eip
- pop 명령어를 통해 eip는 RET의 값을 가진다.
- pop 명령어를 통해 esp는 가리키던 RET에 +4를 한 곳을 가리키게 된다.
위에서 SFP는 이전 함수의 Base Pointer를 가진다고 했다.
이 값을 쉘 코드가 있는 주소로 변경하면 공격이 실행될 것이다.
공격을 위해 buffer의 시작 주소를 알아야 한다.
소스 코드에서 buffer는 서브 함수인 problem_child에 있으므로 break를 서브 함수의 leave에 걸어보자.
다음으로 NOP를 41개 입력하여 buffer의 시작 주소를 알아보도록 한다.
0xbffffac4에서 buffer가 시작되는 것을 알 수 있다.

<buffer의 시작 위치> 페이로드는 간단히 작성할 수 있다.
앞 부분 40 바이트를 NOP와 쉘 코드로 채우고, 1 바이트를 변조해 추가해주면 된다.
서브 함수의 에필로그 과정에서 esp는 leave, ret에 의해 두 번 +4 바이트가 적용된다.
그래서 변조해 줄 1 바이트는 0xbffffac4의 마지막 0xc4에서 8 바이트를 뺀 0xbc가 되는 것이다.
15 바이트의 NOP + 25 바이트의 쉘 코드 + 1 바이트 (변조 SFP)를 넣어 프로그램을 실행시키면 쉘이 실행된다.
my-pass를 입력하니 비밀번호가 나타났다.

<나타난 비밀번호> 반응형'Wargame > L.O.B' 카테고리의 다른 글
[L.O.B] Level 14 - bugbear (0) 2022.11.05 [L.O.B] Level 13 - darkknight (0) 2022.11.04 [L.O.B] Level 11 - skeleton (2) 2022.11.01 [L.O.B] Level 10 - vampire (0) 2022.10.20 [L.O.B] Level 9 - troll (0) 2022.10.20