FTZ level19 문제 확인 이번 문제 소스코드는 단 3줄인데 buf[20]을 선언 후 gets로 여태까지의 다른 문제들과는 확연한 차이가 있다. 바로 setreuid 함수가 사용되어있지 않다는 것이다. 입력값의 길이를 확인하고 있지 않으므로 RET을 덮어쓸 수 있고 쉘 또한 실행시킬 수 있지만, 아래 캡쳐 이미지에서 보는 바와 같이 setreuid가 걸려있지 않았기 때문에 쉘 실행 권한 id가 동일한 level19임을 알 수 있다. setreuid에 대해서는 [해커스쿨 FTZ] level11 풀이 에서 설명한 바 있다. 따라서, 이번 문제는 코드에는 없는 setreuid와 system('/bin/sh')를 직접 실행시켜주어야 하는 문제이다. 그리고 그러기 위해선 RTL(Return to Librar..
FTZ level18 문제 확인 FTZ level18 문제는 코드가 갑자기 길어진다. 코드가 길지만 왜 이문제를 냈는지에 대한 관점으로 입력값을 어디서 받는지 스택상 버퍼가 어디에 위치하고 뭘 바꿔야 하는지만 살펴보면 걸러지는 코드가 많아서 긴건 아니다. #include #include #include #include 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..
FTZ level17 문제 확인 FTZ level16과 비슷해보이지만 하나 다른 점은 이번엔 shell() 없다는 것이다. shell() 함수 없이 call 함수 포인터 변수의 주소값을 어떠한 값으로 덮어써 쉘이 실행되게만 하면 된다. FTZ level17 문제 풀이 level17 풀이는 간단하다. 몇번 환경변수를 사용한 적이 있는데 환경변수에 쉘코드를 등록하고 환경변수의 주소를 덮어써주면 되는 것이다. 일단, 스택 구조부터 확인해보자. char buf[20] : 20바이트 (0x14) dummy : ? void *call : 4바이트 dummy : ? int crap : 4바이트 dummy : ? SFP : 4바이트 RET : 4바이트 입력해준 41414141 버퍼 시작부터 printit 함수 시작 주..
FTZ level16 문제 확인 FTZ level16은 11~15와는 조금 다른 형태의 문제가 출제되었다. call() 함수포인터를 printit() 함수로 지정해놨는데 printit() 함수는 "Hello there!"이라는 문자열을 출력하고 끝난다. 쉘획득을 위한 shell() 함수를 실행시키는 것이 level16의 목표이다. fgets가 있기때문에 48바이트까지는 입력할 수 있다. FTZ level16 문제 풀이 쉘획득을 위한 shell() 함수를 실행시키는 방법 중에 하나로 call() 함수 포인터의 값으로 들어있는 printit() 함수의 주소를 shell() 함수로 변경하는 것이다. 일단, 스택 구조부터 확인해보자. char buf[20] : 20바이트 (0x14) dummy : ? void ..
FTZ level15 문제 확인 level14와 다른점은, level14는 'check==0xdeadbeef' 로 check 변수의 주소값을 체크하는 것이었다면 level15는 check 변수의 주소값이 아닌 값이 0xdeadbeef 인지를 체크하고 있다. 즉, 0xdeadbeef를 메모리에서 찾은 후 그 주소값을 check 포인터 변수에 덮어써야하는 것이다. FTZ level15 문제 풀이 메모리는 이미 0xdeadbeef가 올라와있기 때문에 main 함수 내에서 주소를 찾아주면 된다. 또한, disas main으로 main함수의 어셈블리를 보면 dummy값을 알 수 있다. fgets의 첫번째 인자가 buf이므로 buf 주소는 0xffffffc8이고 그 밑에 cmp문의 0xfffffff0이 check ..
FTZ level14 문제 확인 취약점이 있는 fgets 함수를 이용해 bof를 수행하는 문제인데 check가 0xdeadbeef일 때, system 함수를 사용해 쉘을 실행시키고 있기 때문에 쉘코드를 쓰거나 RET까지 덮어줄 필요는 없어보인다. FTZ level14 문제 풀이 dummy를 잘 알아내는 것이 관건인 것 같은데 다 알아낼 필요는 없이 buf와 check 사이의 dummy 크기만 알아내면 된다. buf (str) : 20바이트 (0x14) dummy : ? buf (check) : 4바이트 dummy : ? buf (crap) : 4바이트 dummy : ? SFP : 4바이트 RET : 4바이트 사실 dummy 크기를 알아낼 필요도 없다. buf 뒤에 check 부분만 0xdeadbeef면 ..
FTZ level13 문제 확인 strcpy 함수가 사용되고 있는 것은 level11과 똑같아 보이는데 i 변수에 0x1234567을 저장해놓고 이 값이 변하면 동작하지 않도록 프로세스를 kill하고 있다. 즉, 0x1234567은 스택이 다른 값들로 덮어써지는 것을 막기 위한 일종의 스택가드라고 볼 수 있다. FTZ level14 문제 풀이 gdb로 실행시켜보면, 'sub 0x418, esp'에서 1048(0x418)-1024-4=20 이므로 i와 buf와 함께 dummy가 20바이트 (0x14) 존재하는 것을 알 수 있다. 하지만 dummy가 정확히 어디 위치하는지를 알아야 정확한 위치에 0x1234567을 써줄 수가 있다. strcpy 함수 호출 뒷부분에 bp를 걸어준 후 버퍼시작 주소를 대략 확인..
FTZ level12 문제 확인 level11과 마찬가지로 attackme 바이너리에 들어있는 gets 취약점을 사용해서 bof로 쉘을 획득해야하는 문제이다. FTZ level12 문제 풀이 gdb로 실행시켜보면, gets 함수를 호출하는 부분을 쉽게 확인 가능하다. 또한, str 버퍼는 256바이트를 할당해주었는데 'sub esp,0x108' 부분에서 dummy가 8바이트임을 알 수 있다. gets 함수 호출 뒤인 에 bp를 건 후 실행시켜 스택을 확인해본다. 0xbfffedd0 에 입력해준 A 값들을 확인할 수 있다. 하지만, 이번 문제도 어차피 랜덤스택(ASLR)이기 때문에 버퍼 주소는 계속 바뀐다. 일단 스택 상황은 아래와 같다. buffer (str) : 256바이트 (0x100) dummy :..
y2017년에 옛날 블로그에 작성했던 FTZ 풀이를 level11부터 옮깁니다. FTZ level11 문제 확인 FTZ Level11 부터는 bof로 풀 수 있는 문제들이 나온다. 디렉토리에 있는 파일들을 먼저 살펴보면, attackme라는 취약점이 존재하는 바이너리가 있고 setuid가 걸려있는 것으로 보인다. 그리고 hint 파일이 있는데 attackme의 소스코드인 것 같고 살펴보면 bof에 취약한 strcpy 함수를 사용하고 있다. char형 배열 str은 256 크기를 갖고 있는데 strcpy로 길이체크가 수행되지 않은 argv[1]을 str로 복사하고 있으니 버퍼오버플로우 취약점을 갖고 있는 것을 쉽게 확인할 수 있다. 여기서 한가지 알고 넘어가야 할 것은, 해당 바이너리의 취약점을 실행해서 ..