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 |