level 18
위에 PLT가 써있길래 PLT와 연관된 GOT Overwrite에서 열심히 공부했는데 이걸로 푸는 문제가 아니더군요 ㅋㅋ
아쉬워서 간단하게 어떤 원리인지만 적겠습니다.
GOT Overwrite
PLT : 어떠한 코드를 담고 있습니다.(GOT로 JMP하는 코드)
GOT : 실제 함수의 주소 또는 PLT+6의 주소를 담고 있습니다.
PLT의 주소에 포인터를 첨가해 원하는 주소를 가리키면 됩니다.(system 함수 등)
set *0x80~~ = 0x400~~
위에서 확인할 수 있듯이 set을 통해 프로그램 흐름을 바꾸는 것은 gdb 도구를 사용했을 때만 가능합니다.
따라서, 저는 이 기법으로 문제를 푸는것이 아니라는 판단을 하고, strcpy의 함수 원형을 확인했습니다.
char* strcpy(char* dest, const char* origin)
즉, 목적지에 출발지 값을 복사한다는 뜻이죠.
여기서 목적지와 출발지는 모두 주소입니다.
그러면 소스코드를 봅시다.
argv[1]의 45번째~48번째에는 strcpy 함수의 주소가 와야하고, 49번째 ~ 52번째에는 "A"가 4개 채워집니다.
즉, 이런 형태가 된다는 것이죠.
buffer(40) | SFP | &strcpy | "AAAA"
문자열 "AAAA"가 있는 위치는 strcpy가 끝난 뒤 이동할 다른 함수의 주소 위치이기도 합니다.
그렇다면 여기에 system 함수의 위치를 넣어야하겠죠?
또한, exit 함수의 위치도 알고 있어야하며, "/bin/sh\x00"의 위치도 알아야합니다.
다시 말해서, buffer에 순차적으로 &system, &exit, &"/bin/sh\x00", "\x90"*32를 준다는 의미입니다.
buffer에 쉘을 실행할 수 있는 조건을 만족하더라도 이 값들을 참조못한다면 의미가 없겠죠?
그래서 strcpy를 이용해 buffer의 값들을 "AAAA"가 있는 위치로 복사할 것입니다.
그러면 메모리에 채워지는 값들은 이러하겠죠.
&system | &exit | &"/bin/sh\x00" | "\x90"*32 | &strcpy | "AAAA" | &"AAAA" | &buffer
하나하나 알아가 보도록 하겠습니다.
먼저, system 함수와 exit 함수의 주소입니다.
system 함수는 0x40058ae0, exit 함수는 0x400391e0 이네요.
"/bin/sh\x00"의 주소는 0x400fbff9 이네요.
strcpy의 주소는 0x8048410 이네요.
인자는 이렇게 주었습니다.
buffer의 시작 주소는 0xbffffa80 이네요.
또한, "AAAA"의 주소는 0xbffffab0 이네요.
payload를 작성하겠습니다.
"\xe0\x8a\x05\x40" + "\xe0\x91\x03\x40" + "\xf9\xbf\x0f\x40" + "\x90"*32 + "\x10\x84\x04\x08" + "AAAA" + "\xb0\xfa\xff\xbf" + "\x80\xfa\xff\xbf"
바이너리가 실행되면서 뭔가 buffer의 위치가 변한 것 같네요.
core dump로 확인해보겠습니다.
앗 바이너리가 실행되면서 buffer의 위치가 변했네요.
buffer의 시작주소는 0xbffffa90, "AAAA"의 주소는 0xbffffac0 이네요.
다시 payload를 작성하겠습니다.
"\xe0\x8a\x05\x40" + "\xe0\x91\x03\x40" + "\xf9\xbf\x0f\x40" + "\x90"*32 + "\x10\x84\x04\x08" + "AAAA" + "\xc0\xfa\xff\xbf" + "\x90\xfa\xff\xbf"
성공!