ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [F.T.Z] Level 16
    Wargame/F.T.Z 2022. 9. 30. 11:42
    반응형

    Level 16을 풀어보자.

    Level이 올랐지만, 생각보다 Level 16은 쉽게 풀렸다.

     

    hint를 보고, 소스 코드를 분석해보자.

    먼저 shell, printit 이라는 두 개의 함수가 선언되어 있다.

    함수의 내용은 간단하니 넘어가도록 하자.

    main 함수 안을 보면, call 포인터에 printit 함수를 저장한다.

    그리고 buf 배열을 선언한 후, fgets 명령어를 통해 buf에 값을 넣는다.

    끝으로 call 함수를 불러내는 것으로 소스 코드가 끝나는데, printit 함수가 실행될 것으로 보인다.

    <Level 16의 hint>

     

    gdb를 통해 더 분석을 해보자.

    main 함수에 대해서 먼저 보도록 하자.

    <main+6>을 보면 0x8048500이라는 주소값을 ebp-16 주소에 넣는다.

    그리고 <main+36>을 보면 그 주소값을 eax에 넣고 <main+39>에서 저장된 함수를 call 한다.

    이것을 보면 <main+6>은 소스 코드에서 call* 주소에 printit 함수를 넣는다는 의미인 것을 알 수 있다.

    다음으로, <main+39>가 call 주소에 저장된 printit 함수를 불러낸다는 의미인 것을 알 수 있다.

    <main 함수의 gdb 분석>

     

    main 함수의 gdb에서 <main+6>의 0x8048500 주소가 printit이 맞는지 확인해보자.

    disas printit으로 printit 함수를 확인한다. (ctrl+l 명령어로 터미널이 clear 되는 것을 글을 쓰면서 알게 됐다..)

    printit의 시작점인 <printit+0>의 주소를 보니 0x08048500인 것을 보니, 소스 코드 해석이 맞았던 것 같다.

    <printit 함수의 gdb 분석>

     

    그렇다면 이 문제를 해결하는 방법은 무엇일까?

    call 포인터에 printit 주소값이 아닌 shell 주소값을 넣어주면 해결될 것 같다는 생각이 든다.

    이제 disas shell 명령어로 sehll의 주소값을 알아보자.

    shell의 주소값은 0x080484d0이다.

    <shell 함수의 gdb 분석>

     

    이제 페이로드를 입력해보자.

    buf와 call 포인터의 거리인 40 바이트만큼 NOP를 채워준다.

    그리고, shell의 주소값을 넣어주어, call 포인터가 가르키는 주소를 바꾸어준다.

    그 후 my-pass를 입력하면 Level 17의 비밀번호가 나타난다.

    <나타난 비밀번호>

     

    생각보다 문제가 쉽게 풀렸기 때문에 구글링을 해보자.

    이 문제의 의미는 포인터를 변조하는 것이라고 한다.

    아무래도 이런 유형의 문제는 FTZ에서 처음이다보니 이번에는 간단하게 답이 나온 것 같다.

    c 언어에서 포인터가 가장 어렵다고 느꼈고, 지금도 부족하기 때문에 앞으로도 언어 공부를 더 해야겠다.

    반응형

    'Wargame > F.T.Z' 카테고리의 다른 글

    [F.T.Z] Level 18  (0) 2022.10.05
    [F.T.Z] Level 17  (0) 2022.10.01
    [F.T.Z] Level 15  (0) 2022.09.29
    [F.T.Z] Level 14  (0) 2022.09.28
    [F.T.Z] Level 13  (1) 2022.09.26

    댓글

Designed by Tistory.