stack smashing detected.. -_-;

조만간 MOU 체결한 업체에 나가서 포팅도 해야하고...해서 built-in function 목록을 점검하면서 테스트 해보고 있습니다.


당연히 되는걸로 알고 있었는데.. 가서 돌려보니 안되어서.. '어랏?' 하는 것만큼 벙찌고 스타일 구기는것도 없으니까요.. -_-;;


그래서 mod() built-in function을 테스트 하는 도중 발생하는 에러... 


Nuclear launch detected.. -_-; 도 아니고...  


(테스트 코드입니다.. -_-;)

*** stack smashing detected ***: ./a.out terminated
======= Backtrace: =========
/lib/libc.so.6(__fortify_fail+0x37)[0x7f00a3d46617]
/lib/libc.so.6(__fortify_fail+0x0)[0x7f00a3d465e0]
./a.out[0x40055f]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:06 204531329 /home/mirr187/test/etc2/a.out
00600000-00601000 rw-p 00000000 08:06 204531329 /home/mirr187/test/etc2/a.out
00601000-00622000 rw-p 00601000 00:00 0 [heap]
7f00a3a4b000-7f00a3a58000 r-xp 00000000 08:01 1425431 /lib/libgcc_s.so.1
7f00a3a58000-7f00a3c58000 ---p 0000d000 08:01 1425431 /lib/libgcc_s.so.1
7f00a3c58000-7f00a3c59000 rw-p 0000d000 08:01 1425431 /lib/libgcc_s.so.1
7f00a3c59000-7f00a3db1000 r-xp 00000000 08:01 1426568 /lib/libc-2.7.so
7f00a3db1000-7f00a3fb1000 ---p 00158000 08:01 1426568 /lib/libc-2.7.so
7f00a3fb1000-7f00a3fb4000 r--p 00158000 08:01 1426568 /lib/libc-2.7.so
7f00a3fb4000-7f00a3fb6000 rw-p 0015b000 08:01 1426568 /lib/libc-2.7.so
7f00a3fb6000-7f00a3fbb000 rw-p 7f00a3fb6000 00:00 0
7f00a3fbb000-7f00a3fd8000 r-xp 00000000 08:01 1426565 /lib/ld-2.7.so
7f00a41cb000-7f00a41cd000 rw-p 7f00a41cb000 00:00 0
7f00a41d5000-7f00a41d8000 rw-p 7f00a41d5000 00:00 0
7f00a41d8000-7f00a41da000 rw-p 0001d000 08:01 1426565 /lib/ld-2.7.so
7fffac1c4000-7fffac1d9000 rw-p 7ffffffea000 00:00 0 [stack]
7fffac1fe000-7fffac1ff000 r-xp 7fffac1fe000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted

자.. 그동안 신봉하며 사용하고 있던 valgrind 를 돌려보았습니다...


==6708== Process terminating with default action of signal 6 (SIGABRT)
==6708== at 0x4E59095: raise (in /lib/libc-2.7.so)
==6708== by 0x4E5AAEF: abort (in /lib/libc-2.7.so)
==6708== by 0x4E93A7A: (within /lib/libc-2.7.so)
==6708== by 0x4F14616: __fortify_fail (in /lib/libc-2.7.so)
==6708== by 0x4F145DF: __stack_chk_fail (in /lib/libc-2.7.so)
==6708== by 0x40055E: sub (stack_smash.c:11)
--6708-- REDIR: 0x4e9eb90 (free) redirected to 0x4c22ac0 (free)


좋아~! 딱 걸렸어~ 11라인이란 말이지... 하고 코드를 쳐다봅니다..


1 #include <stdio.h>
2 #include <string.h>
3
4 void sub()
5 {
6        char ptr[200];
7        char ptr2[100];
8
9        memset(ptr, 0x00, sizeof(ptr));
10        memset(ptr2, 0x00, sizeof(ptr));
11 }
12
13 int main()
14 {
15       sub();
16 }


순간 멍......;;


자.. 그러면.. 다음은 gdb~


gdb> bt
#0 0x00007ff4ed8d9095 in raise () from /lib/libc.so.6
#1 0x00007ff4ed8daaf0 in abort () from /lib/libc.so.6
#2 0x00007ff4ed913a7b in ?? () from /lib/libc.so.6
#3 0x00007ff4ed994617 in __fortify_fail () from /lib/libc.so.6
#4 0x00007ff4ed9945e0 in __stack_chk_fail () from /lib/libc.so.6
#5 0x000000000040055f in sub () at stack_smash.c:11
#6 0x0000000000000000 in ?? ()
gdb>

다시.. 멍.. . -_-aaaa


break point 설정해서 한줄씩.. 한줄씩.. 따라가봅시다...


_______________________________________________________________________________
Error while running hook_stop:
Value can't be converted to integer.
0x0000000000400541 10 memset(ptr2, 0x00, sizeof(ptr));
gdb> n
_______________________________________________________________________________
Error while running hook_stop:
Value can't be converted to integer.
0x0000000000400546 10 memset(ptr2, 0x00, sizeof(ptr));
gdb> n
_______________________________________________________________________________
Error while running hook_stop:
Value can't be converted to integer.
11 }
gdb> n
_______________________________________________________________________________
Error while running hook_stop:
Value can't be converted to integer.
0x000000000040054f 11 }
gdb> n
_______________________________________________________________________________
Error while running hook_stop:
Value can't be converted to integer.
0x0000000000400558 11 }
gdb> n
_______________________________________________________________________________
Error while running hook_stop:
Value can't be converted to integer.
0x000000000040055a 11 }
gdb> n
*** stack smashing detected ***: /home/mirr187/test/etc2/a.out terminated
======= Backtrace: =========
/lib/libc.so.6(__fortify_fail+0x37)[0x7f9868e7b617]
/lib/libc.so.6(__fortify_fail+0x0)[0x7f9868e7b5e0]
/home/mirr187/test/etc2/a.out[0x40055f]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:06 204531329 /home/mirr187/test/etc2/a.out
00600000-00601000 rw-p 00000000 08:06 204531329 /home/mirr187/test/etc2/a.out
00601000-00622000 rw-p 00601000 00:00 0 [heap]
7f9868b80000-7f9868b8d000 r-xp 00000000 08:01 1425431 /lib/libgcc_s.so.1
7f9868b8d000-7f9868d8d000 ---p 0000d000 08:01 1425431 /lib/libgcc_s.so.1
7f9868d8d000-7f9868d8e000 rw-p 0000d000 08:01 1425431 /lib/libgcc_s.so.1
7f9868d8e000-7f9868ee6000 r-xp 00000000 08:01 1426568 /lib/libc-2.7.so
7f9868ee6000-7f98690e6000 ---p 00158000 08:01 1426568 /lib/libc-2.7.so
7f98690e6000-7f98690e9000 r--p 00158000 08:01 1426568 /lib/libc-2.7.so
7f98690e9000-7f98690eb000 rw-p 0015b000 08:01 1426568 /lib/libc-2.7.so
7f98690eb000-7f98690f0000 rw-p 7f98690eb000 00:00 0
7f98690f0000-7f986910d000 r-xp 00000000 08:01 1426565 /lib/ld-2.7.so
7f9869300000-7f9869302000 rw-p 7f9869300000 00:00 0
7f986930a000-7f986930d000 rw-p 7f986930a000 00:00 0
7f986930d000-7f986930f000 rw-p 0001d000 08:01 1426565 /lib/ld-2.7.so
7fff712fa000-7fff7130f000 rw-p 7ffffffea000 00:00 0 [stack]
7fff713ff000-7fff71400000 r-xp 7fff713ff000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]

Program received signal SIGABRT, Aborted.
_______________________________________________________________________________
Error while running hook_stop:
Value can't be converted to integer.
0x00007f9868dc0095 in raise () from /lib/libc.so.6


멍....... -_-;;;


물론.. sample code로 작성하였기에..달랑 16라인짜리이니.. 그냥 잡기에 부담 없지만...


실제 문제 발생한 코드는 제법 길었습니다.. -_-;;;


뭐... 일단.. 위와 유사한 문제가 나왔을 경우 어떤식으로 해결해야 하는지 확인해야할 사항을 점검해보자면... 다음과 같습니다..


1. stack smashing... (stack 이 깨졌습니다... -_-;; 즉.. overflow 발생 가능한 지점을 찾아봐야겠죠..)


2. 자.. overflow는 왜 발생할까요.. -_-;;  파악된 부분은 대략 이러합니다.

  1) gets()의 사용상에서 발생했다는 보고가 있음.. man page에도 gets() 대신에 fgets() 사용을 권장하고 있습니다.. -_-;

  2) memory 접근시 잘못된 크기의 접근

    - 여러가지가 있을 수 있습니다. memcpy, memset, strcpy 등등....

    즉.. memory 영역을 벗어난 범위까지.. (overflow) r/w 를 시도해서 발생...


3. stack smashing 이 발생한 function() 내부의 overflow이므로.. 해당 function()을 뒤지는 수밖에 없다.. -_-;;


위에서는 테스트 용도로 보기 쉽게..


100byte의 변수, 200byte 변수 요따위로 설정했지만.. 실제로 코딩중에는 저런식으로는 거의 사용 안하고

sizeof(var), strlen(var) 요딴식으로 많이 사용하다보니 충분히 실수할 수가 있습니다...ㅠㅠ


뭐.. 예를 들어 변수명...


tStr sRes[4];

tStr sReq;


와 같이 선언하고 

memset(&sRes, 0x00, sizeof(sRes));

memset(&sRet, 0x00, sizeof(sRes));


식으로 하면... stack smashing!!! 이 발생한다는거죠.. -_-;;;


테스트 결과 overflow하는 크기에 다라 SIGNAL은 각각 SIGABRT, SIGSEGV로 다르게 발생할 수 있습니다.. -_-;;


overflow하는 boundary 가 작은 경우에는 SIGSEGV, 큰 경우에는 SIGABRT, 극히 작은 경우에는 무사통과 될수도 있습니다만....

다른 메모리 영역에서 SIGSEGV가 발생할 수 있으므로 조심해야겠죠



by 아비숑 | 2010/07/22 16:25 | IT Life | 트랙백(1) | 덧글(2)

트랙백 주소 : http://mirr187.egloos.com/tb/2626586
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Tracked from at 2014/03/11 00:43

제목 : http://helenmccrory.org/
line5...more

Commented at 2010/10/28 16:33
비공개 덧글입니다.
Commented by 아비숑 at 2010/12/08 22:50
Stack N Smash 개발자는 아닙니다

그냥 일개 개발자일뿐 ㅡㅡa
이글루스를 자주 안 들어와서 덧글을 늦게 달았군요 ㅡㅡa

:         :

:

비공개 덧글

◀ 이전 페이지          다음 페이지 ▶



'="text/javascript" src="http://allblet2.allblog.net/allblet2.js">');