-
[L.O.B] Level 19 - nightmareWargame/L.O.B 2022. 11. 11. 03:34반응형
Level 19 - nightmare를 풀어보자.
소스 코드를 보면 다음 Level은 xavius고, arg라는 힌트가 있다.
이번 Level은 제한 조건이 꽤나 많은 것 같다.
RET의 마지막 값에 \xbf, \x08의 사용을 금지해 스택을 건드리지 못하게 되어 있다.
다음으로 RET의 첫 번째 값이 \xc9, 두 번째 값이 \xc3인 것을 금하면서 라이브러리의 사용을 막는다고 한다.
그리고 stack destroyer를 통해 버퍼와 SFP를 초기화하고, RET 뒤의 스택을 초기화한다.


<xavius 소스 코드의 내용> 그렇다면 이 문제는 어떻게 푸는 것일까??
이 Level은 한 가지 특이점이 있다.
소스 코드의 상단 부분을 보면 argv의 값을 buffer에 넣는 것이 아닌 fgets 함수를 통해 buffer를 채운다.
이번에는 이 fgets 함수를 이용하면 될 것 같다.
구글링을 해보면 fgets 함수의 동작을 알 수 있다.
fgets 함수는 stdin에 입력값을 임시로 저장하고, 그것을 첫 번째 인자에 두 번째 인자 값만큼 넣는다.
이것의 의미를 이해하기 위해 fgets를 분석하여 stdin에 어떻게 값이 입력되는지 확인하여 문제를 해결하자.
gdb를 이용해 xavius 파일을 분석해보자.
더미 값은 없고, 특별한 동작도 없는 것 같은데 <main+21>의 fgets 함수의 인자를 확인해보자.
<main+6>이 stdin이라는 것을 알 수 있고, 0x8049a3c가 그 주소라는 것을 알 수 있다.

<xavius 파일 gdq 분석 및 stdin의 주소> 이 stdin이 어떻게 동작하는지 확인하기 위해 main에 break를 걸고 실행을 시켜보자.
x/x 명령으로 해당 메모리를 확인하면 stdin의 주소의 값을 알 수 있는데, 그것이 0x401068c0이다.
이것을 또 분석하기 위해 명령어를 입력하여 확인하면 아직은 특별한 값이 없다.

<stdin의 주소 분석> fgets 함수가 동작한 이후 stdin이 어떻게 작동했는지 확인하기 위해 <main+38>에 break를 건다.
c를 통해 입력값을 받을 수 있도록 한다. (파라미터 방식이 아닌, 표준입력 방식이기 때문)
입력 후 다시 stdin의 값을 확인하면 stdin의 시작점과 종료점의 주소를 알 수 있다.
1234를 입력했는데 5바이트의 차이가 나는 것은, stdin은 끝에 개행 문자('\n')가 들어가기 때문이다.

<stdin의 시작점> 이제 페이로드를 작성해보자.
표준입력 방식으로 페이로드를 구성하는데, RET에 stdin의 시작점의 주소를 넣어주도록 한다.
이것을 통해 입력한 값이 stdin에 저장되고, 그것이 RET에서 eip가 옮겨져 실행되도록 유도하는 것이다.
작성한 페이로드로 프로그램을 실행시키면 xavius의 권한으로 쉘이 실행된다.
my-pass를 입력하면 비밀번호가 나탄난다.

<나타난 비밀번호> 반응형'Wargame > L.O.B' 카테고리의 다른 글
[L.O.B] Level 20 - xavius (0) 2022.11.14 [L.O.B] Level 18 - succubus (0) 2022.11.10 [L.O.B] Level 17 - zombie_assassin (1) 2022.11.10 [L.O.B] Level 16 - assassin (0) 2022.11.06 [L.O.B] Level 15 - giant (0) 2022.11.06