반응형 FTZ22 FTZ Level 20 마지막 문제입니다. 힌트를 보면 프로그램은 생각보다 간단한듯한데 fgets의 옵션에 79가 있네요... 최대 길이를 79바이트로 제한했습니다. 버퍼오버플로우가 안되는 듯 하네요ㅠㅠ 그런데 이때 printf함수를 보면 인자를 사용했죠? 여기서 포맷스트링 버그가 발생합니다. 여기서 printf(bleh); 이렇게 함수를 사용하게 되면 문자열을 출력하다가 %x 등을 만나면 이들을 문자열로 보지 않고 서식문자로 인식해버립니다. 문자열을 출력하다가 이 문자들(%d, %x, %s 등)을 만나면 메모리의 다음 4바이트를 참조해서 출력하는 것입니다. 메모리 구조를 살펴보기 위해서 gdb를 사용합니다. 확인이 안되네요. 그럼 지금까지의 힌트를 가지고 구조를 유추해보면 RET4 SFP4 DUMMY? bleh80 DUMMY.. 2021. 8. 9. FTZ Level 19 FTZ Level 19에 접속하여 힌트를 봅니다. 이제 소스만 보고도 구조가 대충 그려지네요. gdb를 사용하여 더미가 20byte인것도 확인합니다. 메모리 구조는 RET4 SFP4 Dummy20 buf20 입니다. 간단한 소스입니다. 그런데 평소처럼 eggshell과 getenv를 사용했는데 아무런 반응이 없습니다. 다시 소스를 보니 seteruid가 없네요;; 그렇다면 seteruid를 설정하는 쉘코드를 eggshell에 같이 넣어주면 됩니다. ㅎㅎ grep을 이용해 레벨 20의 uid를 확인합니다. grep level20 /etc/passwd uid를 설정하는 코드를 만들어서 쉘코드로 작성하여 줍니다. 작성한 프로그램을 gcc에 -static -g 옵션을 주어 컴파일 한 후, gdb로 main 함수.. 2021. 8. 9. FTZ Level 18 Level 18에 접속해서 힌트를 봅니다. 이전과는 다르게 길이가 제법 되는 코드들이 나오는데요;; 우선 check는 string 뒤에 위치합니다. 그럼으로 기존의 버퍼오버플로우를 시키는 방식은 사용할 수 없습니다. 이를 해결하기 위해 case문이 있네요 이 부분 입니다. 메모리 0x08이 입력되면 count--가 됩니다.(버퍼를 한개 빼주는 역활입니다.) 그리고 string[count-1] = x; 가 되는 것이죠. 그렇다면 string[-1] = x;의 경우 string의 시작주소보다 1바이트 낮은 곳에 x의 값이 저장됩니다. string[-2]의 경우는 2바이트 낮은 곳이겠지요. 그럼으로 0x08을 이용하여 cout--를 일으켜 check에 deadbeef를 넣어주면 됩니다. 메모리 구조를 보면 R.. 2021. 8. 9. FTZ Level 17 Level 17에 접속해서 힌트를 보면 Level 16에서의 코드에서 shell함수가 빠진 형태입니다. 그렇다면 메모리 구조는 비슷할 것입니다. buf의 20byte와 더미값 20byte를 채운 후, 포인터함수 부분을 환경변수로 등록해놓은 쉘코드의 주소를 넣어주면 됩니다. 쉘코드가 실행시키게 하면 되는 것입니다. 에그쉘과 getenv를 사용하면 됩니다. (python -c 'print "A"*40 + "쉘코드 주소"';cat)|./attackme 2021. 8. 9. FTZ Level 16 Level 16에 접속해서 파일들과 힌트를 봅니다. 함수 2개와 main 함수 1개 가 있네요 그런데 메인 함수를 보면 전 레벨의 메모리 구조와 비슷하다는 것을 눈치챌 수 있습니다. main 함수에서 포인트 함수를 호출하는게 보입니다. 그렇다면 여기서 버퍼오버플로우를 일으켜서 포인터함수를 호출하는 부분의 주소를 shell()함수 주소로 바꾸어주면 쉘창이 나타난다고 생각해볼 수 있습니다. (전 레벨의 프로그램과 비슷하므로 buf와 포인터 함수 사이의 더미는 20byte라고 생각했습니다.) 프로그램을 gdb를 사용해 shell함수의 시작 주소를 찾습니다. shell+1의 0x080484d0이 되겠군요. 그럼 바로 코드를 작성해봅시다. (python -c 'print "A"*40 + "\xd0\x84\x04\.. 2021. 8. 9. FTZ Level 15 Level 15에 접속하여 파일과 힌트를 봅니다. 14와 똑같은데 단한가지 다른게 포인터 변수 check입니다. 포인터를 사용했기 때문에 check에는 deadbeef가 있는 주소를 넣어주면 된다고 생각합니다. 우선 gdb를 뜯어보면 Level14와 메모리 구조는 똑같습니다. 여기서 main+32를 살펴보면 cmpl어셈블리 명령어를 사용하여 eax값을 비교 하고 있습니다. 이 프로그램은 0xdeadbeef가 하드코딩 되어있어 프로그램 속에 내제 되어 있습니다. 그러므로 내제되어있는 0xdeadbeef값의 주소를 찾으면 되는 것이지요 gdb에서 x/x를 이용하여 주소를 찾아줍니다. 찾으니 0x080484b2가 나오네요 Level14에서 사용했던 코드에서 Check부분의 값만 바꿔 줍니다. (python -.. 2021. 8. 9. 이전 1 2 3 4 다음 반응형