ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • level 18. 풀이
    System hacking training/Hackerschool F.T.Z 2017. 12. 24. 20:40

    안녕하세요 살충제입니다.


    오랜만에 f.t.z를 풀어보네요..


    시험기간+프로젝트+발표준비로 너무 바쁜 하루를 보내왔습니다.ㅎㅎ


    시험은 끝났지만 여전히 바쁘네요..ㅠ_ㅠ


    아무튼 오늘 level 18을 풀이해보았는데요.


    풀이를 시작합니다. ^____________^



    로그인 후 hint 파일을 열어보시면..


    소스코드가 아주 길게 나옵니다.....ㅎ



    <hint 내용>


    #include <stdio.h>

    #include <sys/time.h>

    #include <sys/types.h>

    #include <unistd.h>

    void shellout(void);

    int main()

    {

      char string[100];

      int check;

      int x = 0;

      int count = 0;

      fd_set fds; -> 구조체/FD == 파일 디스크립터의 줄임 표현

      printf("Enter your command: ");

      fflush(stdout); -> 출력버퍼를 비우면서 목적지로 보내라(쓰라)고

      while(1)

        {

          if(count >= 100) -> count 변수가 100 이상이면 문자열 출력

            printf("what are you trying to do?\n");

          if(check == 0xdeadbeef)      -> check에 0xdeadbeef가 있으면 shellout() 호출

            shellout();

          else -> check != 0xdeadbeef

            {

              FD_ZERO(&fds); -> fd_set 으로 선언된 변수를 0으로 초기화

              FD_SET(STDIN_FILENO,&fds); -> 파일디스크립터 0(stdin) 설정


              if(select(FD_SETSIZE, &fds, NULL, NULL, NULL) >= 1) -> 변경된 데이터가 존재할 경우 if문 조건이 참

                {

                  if(FD_ISSET(fileno(stdin),&fds))

                    {

                      read(fileno(stdin),&x,1);

                      switch(x)

                        {

                          case '\r':

                          case '\n':

                            printf("\a");

                            break;

                          case 0x08: -> x가 0x08인 경우 count-- 를 실행한다.

                            count--;

                            printf("\b \b");

                            break;

                          default:

                            string[count] = x;   

                            count++;        -> if(count >= 100)  printf("what are you trying to do?\n");

                            break;

                        }

                    }

                }

            }

        }

    }


    void shellout(void)

    {

      setreuid(3099,3099);

      execl("/bin/sh","sh",NULL); -> 쉘프로그램 실행

    }


    /*

    int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

    int nfds -> 관리하는 파일의 개수를 등록한다. // FD_SETSIZE

    fd_set *readfds -> 읽을 데이터가 있는지 검사하기 위한 파일 목록 // &fds

    fd_set *writefds -> 쓰여진 데이터가 있는지 검사하기 위한 파일 목록 // NULL

    fd_set *exceptfds -> 파일에 예외 사항들이 있는지 검사하기 위한 파일 목록 // NULL 

    struct timeval *timeout -> NULL로 할 시 데이터가 있을때까지 무한정 기다리고, 멤버값이 모두 0이면 즉시 반환한다. // NULL

    만약 변경된 데이터가 있다면 해당 비트값이 1로 설정이 되고, 프로그램은 이 비트 값을 검사함으로써 어떤 파일 지정 번호에 변경된 데이터가 있는지 확인해서 읽기/쓰기를 하면 된다.

    select 함수는 데이터가 변경된 파일의 개수 즉 fd_set에서 비트 값이 1인 필드의 개수를 반환한다.

    */


    /*

    FD_ISSET() 는 fd_set으로 선언된 변수에 특정 FD값이 설정되어 있는지 확인할때 사용한다.

    예를 들어, FD값이 5인 경우 변수에 5값에 해당하는 비트가 1이 되어 있는지 확인하는 작업을 수행한다. 비트가 1인지 여부를 확인할때는 '비트 AND' 연산을 사용하며 해당 고유값에 해당하는 비트를 포함하는 fd_bits배열 항목에 비트 대응값을 AND 연산시켜서 결과가 0이면 설정이 안된것이고 0이 아니면 설정된 것이다.

    */


    저는 얼른 메모장에 옮겨서 소스코드 분석을 해보았습니다.

    ( 분석까지는...ㅎ그냥 봤습니다. )


    정리를 해보면 이 프로그램은 입력을 x로 받고 string[count] 에 저장합니다.


    문제를 풀기 위해선 check 에 deadbeef 가 들어있어야하네요.


    여기서 주의할점이 있는데요.


    바로 스택에 쌓이는 지역변수입니다.


    | char string[100]; |

    -----------------------

    |      int check;      |

    -----------------------

      |      int x = 0;     |

    ----------------------- 

     |  int count = 0;  |

    ----------------------

      |    fd_set fds;    |


    보시다시피 이런 구조로 선언이 되었는데


    스택에 쌓일때


    입력값이 저장되는 string[100]이 int check 변수보다 먼저 저장되기 때문에


    check에 deadbeef 를 넣을 수 없다는 점입니다. 


    하지만 답은 소스코드에 있었는데요.


    다시 소스코드를 보시면



    이와 같이 x에 0x08일 경우 count-- 로 count 값(초기값은 0이죠.)

    을 -1 하여 count == -1 입니다.


    스택 구조상 string 바로 밑에 check 변수가 위치해 있기 때문에

    string[0]의 위치에서 -1 하면 check에 도달하게 됩니다.


    그렇기 때문에 check에 deadbeef라는 문자열을 넣기 위해


    0x08을 4번 입력하여 check의 위치에 도달한 후

    deadbeef를 넣어주면 쉘을 띄울 수 있을것같습니다.


    그대로 한번 실행해 보면..!



    uid 가 level19로 쉘을 실행시킨것을 확인 할 수 있습니다.


    마지막으로 my-pass를 입력하여 다음 레벨의 비밀번호를 출력하면..!!



    Level19 Password is "swimming in pink" 라네요. *^^*


    이상 level18의 풀이도 마쳤습니다.


    질문은 댓글을 이용해주세용~










    반응형

    'System hacking training > Hackerschool F.T.Z' 카테고리의 다른 글

    level 20. 풀이  (1) 2018.01.20
    level 19. 풀이  (0) 2018.01.06
    level 17. 풀이  (0) 2017.12.03
    level 16. 풀이  (0) 2017.12.03
    level 15. 풀이  (2) 2017.11.26
Designed by Tistory.