ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [FTZ Level14 풀이]
    System/FTZ 2018. 2. 16. 02:07

    [Level14 Code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #include <stdio.h>
    #include <unistd.h>
     
    main()
    int crap;
      int check;
      char buf[20];
      fgets(buf,45,stdin);
      if (check==0xdeadbeef)
       {
         setreuid(3095,3095);
         system("/bin/sh");
       }
    }    
     
    cs


    Level14번 문제는 fgets( )에서 취약점이 발생한다.

    buf의 크기는 20인데, 표준입력으로 45Byte만큼의 데이터를 버퍼에 저장하고 있다.


    그리고 밑에 if문으로 check의 값이 [0xdeadbeef]로 변조될 시, system("/bin/sh")가 실행되는 것을 볼수 있다.

    따라서, 우리는 BOF로 check메모리를 deadbeef로 변조해주면 Level15권한의 쉘이 실행될 것이다.




    [buf와 check의 offset#1]

    자 그럼 버퍼의 크기는 20이고 바로위에 check이 선언되어 있으니

    버퍼에 20Byte만큼 dummy값을 주고 그 다음에 바로 deadbeef를 넣어주면 될까?


    [no deadbeef]

    결과는 No이다.

    그 이유는 컴파일러의 재량? 이라고 할 수 있다.

    지금 처럼 BOF가 발생해 값이 다른 변수영역에 침범하는 상황을 대비해서

    컴파일러가 컴파일 과정에서 변수와 변수사이에 dummy값을 넣어서 여유공간을 갖도록 만들기 때문이다.


    이런 컴파일과정에서 로직이 변하는 것을 방지하려면 변수를 volatile로 선언해주면 된다.

    자세한 내용 : [volatile 위키백과]




    [buf와 check의 offset#2]

    자 그럼 어떻게 구해야 할까?

    프로그램 실행 도중에 값을 입력받기 때문에 스택을 보면서 확인할 수는 없다.


    방법은 어셈블리를 보면서 계산해 보는 것이다.


    [attackme main]

    노란색 박스는 스택의 공간을 42(66d)만큼 확보해주고 있다.


    주황색 박스에서는 fgets( )를 호출하기 전에 [EBP-56]의 주소값을 EAX에 저장한 후

    EAX의 값을 스택에 저장해서 fgets( )에 인자값으로 넘기고 있다.

    여기에서 [EBP-56]이 buf배열의 시작점이란 것을 알 수 있다.


    그리고 초록색 박스에서는 [EBP-16]의 4Byte값과 deadbeef를 비교한 후

    JNE로 분기시키는 것을 볼 수 있다.

    여기에서 [EBP-16]부분이 check의 공간임을 알 수 있다.


    스택은 높은 주소에서 낮은주소로 쌓이는 특성을 고려해서 계산을 해보면

    [EBP-56]부터 [EBP-17]까지 40만큼의 공간이 두 변수의 offset일 것이다.


    자 그럼 다시 메모리변조를 시도해보자

    예상한대로 버퍼와 check의 offset은 40이 맞았다.


    이상으로 Level14 풀이를 마치도록 하겠다.





    'System > FTZ' 카테고리의 다른 글

    [FTZ Level16 풀이]  (0) 2018.02.16
    [FTZ Level15 풀이]  (0) 2018.02.16
    [FTZ Level13 풀이]  (0) 2018.02.16
    [FTZ Level12 풀이]  (0) 2018.02.15
    [FTZ Level11 풀이 ]  (0) 2018.02.15

    댓글

Designed by Tistory.