level18로 로그인하고 힌트를 보면 굉장히 긴 코드가 나온다. 다른 level에 없던 긴 코드에 조금 쫄았으나, 취약점은 굉장히 간단하다.
#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;
printf("Enter your command: ");
fflush(stdout);
while(1)
{
if(count >= 100)
printf("what are you trying to do?\n");
if(check == 0xdeadbeef)
shellout();
else
{
FD_ZERO(&fds);
FD_SET(STDIN_FILENO,&fds);
if(select(FD_SETSIZE, &fds, NULL, NULL, NULL) >= 1)
{
if(FD_ISSET(fileno(stdin),&fds))
{
read(fileno(stdin),&x,1);
switch(x)
{
case '\r':
case '\n':
printf("\a");
break;
case 0x08:
count--; // 취약점 발생 -1, -2 등 음수가 될 수 있다.
printf("\b \b");
break;
default:
string[count] = x; // 위 취약점을 통해 이전 주소의 메모리에 접근 가능
count++;
break;
}
}
}
}
}
}
보면 case문을 통해 사용자가 선택에 따른 분기를 만들어주는데 중요한 분기들만 살펴보겠다. 0x08을 입력한다면 count를 -해주고 default의 경우 char형 배열 string의 count 번째 요소의 값을 x로 써준다. 중요한 것은 만약 count가 음수라면 string 배열의 뒤에 있는 메모리에도 접근할 수 있다는 것인데 보면 check의 값이 0xdeadbeef라면 쉘을 얻게 해주는 조건문이 존재한다.
check를 변조하는 것 밖에는 답이 안보였기 때문에 gdb로 메모리를 살펴보기 전 시험삼아 string의 바로 뒤 4바이트를(인덱스 : -1 -2 -3 -4) 0xdeadbeef로 변조해보려고 했다.
안된다면 gdb로 메모리를 확인해서 정확한 거리를 구하려고 했는데 쉽게 풀렸다.
'Wargame > FTZ' 카테고리의 다른 글
[FTZ] level 19 (0) | 2021.06.09 |
---|---|
[FTZ] level 17 (0) | 2021.06.06 |
[FTZ] level 16 (0) | 2021.06.06 |
[FTZ] level 15 (0) | 2021.06.06 |
[FTZ] level 14 (0) | 2021.06.04 |