1. 풀이

- 사용자로부터 command를 입력받아 fflus(stdout)으로 출력

- count 값이 100 이상일 경우 printf() 출력, check 값이 "0xdeadbeef"일 경우 secllout() 호출, 두 가지 경우가 아닌 경우 else()를 실행하며, check 값을 "0xdeadbeef"로 변조해야 하는 것을 유추해 볼 수 있음.

- else 구문 분석

// 파일 디스크립터(FD)
// level18 파일 디스크립터 관련 변수 : fd_set fds
// 시스템으로부터 할당 받은 파일을 대표하는 0이 아닌 정수 값
// 프로세스에서 열린 파일의 목록을 관리하는 테이블의 인덱스
// 표준 입력=0, 표준 출력=1, 표준 에러=2로 정의되어있음
 else
        {
          // FD_ZERO(fd_set *set) : fd_set을 0으로 초기화
          // 각 fds를 0으로 초기화 (fd_set 배열 선언 후 쓰레기 값을 0으로 초기화)
          FD_ZERO(&fds);
        
          // FD_SET(int fd, fd_set *set) : fd_set변수의 fd번째의 비트를 1로 바꾼다.
          // 해당 fds를 1로 세팅
          FD_SET(STDIN_FILENO,&fds);

          // int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
          // 파일 디스크립터 구조체 모니터링 함수
          // int n : 검사할 파일디스크립터의 범위를 지정 (=검사할 파일의 개수)
          // fd_set *readfds : 수신할 데이터가 있는지 확인
          // fd_set *writefds : 송신할 데이터가 있는지 확인
          // fd_set *exceptfds : 예외가 있는지 확인 (0이면 체크하지 않음)
          // struct timeval *timeout : 무한 대기 상태를 방지하는 타임아웃 설정
          // 반환 값 : 변화가 발생한 파일디스크립터의 개수 (오류 발생 : -1, 타임 아웃 : 0 반환)
          // 즉, 변화된 파일 디스크립터의 개수가 1개 이상일 경우 수행되는 if문
          if(select(FD_SETSIZE, &fds, NULL, NULL, NULL) >= 1)
            {

              // FD_ISSET(int fd, fd_set *set) : fd_set에 fd가 포함되어 있는 지를 확인하는 함수
              // select함수가 호출된 후에는 처리가 가능한 fd만 남게되므로 읽기 또는 쓰기 준비가 되어 있는 지 여부를 알 수 있음
              // fd가 set에 설정되지 않은 경우 0을, set에 설정된 경우 0이 아닌 값을 반환
              if(FD_ISSET(fileno(stdin),&fds))
                {
 
                  // 표준 입력으로 1byte만큼 x에 저장
                  read(fileno(stdin),&x,1);
                  switch(x)
                    {
                      case '\r': // Carriage return : 다음 줄 가장 왼쪽으로 이동
                      case '\n': // Line Feed : 다음 줄로 이동하는 문자
                        printf("\a");
                        break;
                      case 0x08: // 0x08이 입력될 경우
                        count--;
                        printf("\b \b");
                        break;
                      default:
                        string[count] = x;
                        count++;
                        break;
                    }
                }
            }
        }

 

- gdb로 해당 파일을 분석해보면 우선 지역변수에 0x100, 즉 256byte의 공간을 할당

- 0xffffff90와 0x63(99)를 비교 즉, if(count >= 100)를 수행하 다음 분기를 결정하는 구간으로, 여기서 count는 0xffffff90인것을 알 수 있음

- $0xdeadbeef,0xffffff98(%ebp)를 비교 즉, if(check == 0xdeadbeef)를 수행하여 다음 분기를 결정하는 구간으로, 여기서 check는 0xffffff98에, shlleout()은 0x08048780에 위치해 있음을 알 수 있음

- 또한, 0xffffff10에 fds가 위치해있음을 알 수 있음

- switch(x) 문을 수행하는 부분으로, 0xffffff94에 x가, 0xffffff90에 string이 위치한다는 것을 확인할 수 있음

- 위 정보를 토대로 메모리 구조를 예측해보면 다음과 같음

 

- 현재 사용자의 입력을 받을 수 있는 부분은 x 값이며, check를 0xdeadbeef로 변조하여야 함

- 즉, x 값에 else 구문에서 확인한 0x08을 전달하여 check에 위치하도록 한 후 0xdeadbeef를 Little Endian 방식으로 전달

'문제풀이 > FTZ' 카테고리의 다른 글

FTZ Level20 풀이  (0) 2022.11.08
FTZ Level19 풀이  (0) 2022.11.08
FTZ Level17 풀이  (0) 2022.11.07
FTZ Level16 풀이  (0) 2022.11.05
FTZ Level15 풀이  (0) 2022.11.05

+ Recent posts