스택/버퍼 오버플로우 버그와 서버 아키텍쳐의 선택

방준영의 이미지

x86 아키텍쳐의 아주 고약한 점중 하나가 실행 비트를 페이지 단위로 매길 수가 없다는 점입니다. 세그먼트 단위로만 되지요[1]. 이것때문에 보안 버그중 대부분을 차지하는 스택/버퍼 오버플로우 버그가 x86에서는 계속 골칫거리가 되고 있습니다. 특히 서버에서는 그 심각성이 더하지요.

그런데 페이지 단위로 실행 비트를 매길 수 있는 아키텍쳐는 버퍼 오버플로우의 위험성이 거의 원천적으로 사라집니다. 그런 아키텍쳐에서는 스택/힙 안에 고의로 코드를 넣고 실행을 시도하면 그냥 세그폴트가 나면서 프로그램이 죽어 버립니다. 이렇게 되면 아무리 버퍼 오버플로우 버그가 많은 프로그램이라도 그 방법만으로는 외부에서 뚫고 들어올 수가 없지요. 많이 쓰이고 있는 아키텍쳐중에서 썬의 SPARC가 바로 그런 기능을 제공한다고 하네요. 여기서 질문은, 금전적 여유가 있는 회사라면 서버로 SPARC 아키텍쳐를 채용하는 게 자연스러운 것 아닐까요? 그럼에도 불구하고 통계치로는 x86 서버의 비율이 압도적으로 높더군요. 서버 관리자로서 여러분은 어떻게 생각하시나요.

[1] 세그먼테이션을 이용하여 x86에서도 실행 불가능한 스택/힙을 구현하는 방법이 최근에는 나와 있지만, 구현 원리가 다소간 제약 사항이 있습니다.

verotas의 이미지

서버 관리자는 아니지만, 재미있는 이야기인 것 같아 잠시 껴봅니다.

뜬금 없이 Tannenbaum vs Linus 토론이 생각나는군요. 몇 년만 있으면 사람들이 전부 훌륭하고도 멋진 RISC 칩을 장착한 데스크탑 기계를 쓰고 있을텐데 뭐하러 그 후진 386에서만 돌아가는 장난감을 만드는데 시간을 낭비하냐고...

그런데 세월이 흘러 영원할 것 같았던 Sun은 분기 적자 전환 소식이 들리더니 창립 멤버들이 떠나고, 급기야 흡수합병설이 나도는 지경에 이르렀습니다. RISC vs CISC 같은 고전적인 얘긴 차치하고라도 Sun이 꾸준히 보여줬던 선도적이고 인상적인 기술혁신과 더불어 시장에서 거뒀던 성공을 생각해 보면, 최근의 부진과 상대적으로 순탄하게 나아가고 있는 인텔의 모습은 상당히 아이러니해 보이기도 합니다.

끄적이다보니 전혀 딴 소리가 되고 있군요 ^^;

x86 서버 사용 비율이 압도적으로 높은 통계가 어딜 참조한 건지는 모르겠지만, 제 기억엔 불과 삼사년 전만 해도 그래도 서버는 역시 썬이지 하는 관리자들을 온라인에서나 오프라인에서나 심심찮게 만나볼 수 있었습니다. 요샌 많이 줄었지요. 그래서가 아닐까 싶습니다. 서버를 어떤 기종으로 도입할 건지를 전적으로 관리자 판단에 의존한다는 전제가 필요하겠지만, 그런 경우에 관리자한테 중요한 건 자기가 잘 알고 많이 다뤄본 기계라야 하는데, 리눅스/*BSD 덕분에 최근에 학교를 다닌 사람들은 x86 기계에서 돌아가는 OS로 이것저것 해본 경험들이 많이 쌓이게 됐고, 상대적으로 그 이전 시절에 귀하게 대접 받던 썬 ㅤㅇㅝㅋ스테이션 관리했던 전산실 조교 출신 관리자들보다는 x86 기반 시스템을 고를 확률이 높아진거 아닌가 싶습니다.

요점은, 관리자가 특정한 장비나 기계를 고르면 비록 소프트웨어가 야기할 수 있는 문제점을 줄여줄 수 있을지 모르지만 그런 이유로 특정 플랫폼을 고르거나 버리거나 할 일은 별로 없을 것 같다. 라는 얘길 하고 싶었는데 써놓고 다시 읽어 봐도 그런 얘기가 아니군요 ^^;;

The good is the enemy of the best.

cjh의 이미지

글쎄요. 적정 수준의 안정성만 보장한다면 굳이 Sun/HP과 같이 고가의 장비를 선택할 이유가 없습니다. 저도 학교 있을때에는 내내 스팍/알파만 만지고 살았지만 막상 사회 나와서 의사결정을 할 때에는 굳이 그런 제품을 선택하고픈 마음이 들지 않더군요. 이유는 성능과 가격입니다.

물론 규모가 커질수록 그런 점은 덜 생각해도 될 겁니다. 가격이 크게 중요하지 않다면 아무래도 유명 고가 브랜드 제품을 사용하고 싶은 것이(기술지원이라든가 뽀대 포함) 당연한 마음이겠지요. 같은 x86도 컴팩/HP장비는 쳐주면서 같은 가격의 동급 성능 이상의 조립 장비는 무조건 깎아내리는 경우도 있으니까요. 방준영님이 말씀하시는 부분까지 고려하는 서버 관리자는 거의 없지 않을까요? (그럴 정도면 아예 윈도는 쳐다보지도 않아야 정상...)

p.s. 만약 x86의 그런 문제가 영 마음에 걸렸다면 아마 OpenBSD는 x86플랫폼으로 아예 나오지 않았을 거라 생각합니다. :)

--
익스펙토 페트로눔

버려진의 이미지

sparc에서도 오버플로우가 가능하다고 알고 있습니다.

예를들면

http://khdp.org/docs/common_doc/BufferOverflow_on_Solaris_Sparc.pdf

opt의 이미지

언급하신 내용은 실제 사실과는 전혀 다른 내용으로 보입니다.

Sparc 은 실제로 x86 기종 다음으로 가장 많이 버퍼오버플로우 공격에 노출되어 있는 기종이며(공개되어 있는 exploit 의 양으로 볼 때), x86에 비해 적은 이유도 Sparc 아키텍쳐 자체가 버퍼오버플로우에 대한 bullet proof 한 특성을 제공하기 때문이기 보다는 단순히 Sparc 에 익숙한 공격자의 숫자가 x86 에 익숙한 공격자의 숫자보다 적기 때문입니다.

----
LUX ET VERITAS | Just for Fun!

김충길의 이미지

의사 결정권자들은 대부분 서버를 파는 영업측의 데이타에

의존하지 그 서버를 관리할 직원의 의사는 잘 듣지 않죠.

직원역시 책임 소재의 문제로 자기 의사를 제대로 말하지

않을 거 같습니다.

그리고 x86은 벌써 3G 까지 갔는데 sparc 이나 다른 RISC

계열은 아직 거보다 많이 못하잖아요. 비싸고..

요즘 IBM이 인텔칩을 장착한 서버 장사로 돌아 선 이유가

x86이 비용에 비해 성능이 잘 나오는 까닭이 아닐까요..

screen + vim + ctags 좋아요~

방준영의 이미지

위에서 "전혀 사실이 아니"라고 하신 것에 대해서는, SPARC 아키텍쳐가 페이지 단위로 실행 비트를 매길 수 있는 것은 사실입니다. 사실이고요. 8) 문제는 관련 정보를 훑어 보니 SPARC에서 돌아가는 OS(여기서는 솔라리스)가 그 기능을 제대로 못쓰고 있는 것 같다는 점입니다.

우선 x86에서 아주 쉽게 할 수 있는 스택 오버플로우 공격은 솔라리스에서는 스택 보호 기능을 켜면 불가능하다고 하는군요. 그런데 문제는, 이걸 우회하는 방법이 있다는 겁니다.

http://packetstormsecurity.nl/groups/horizon/stack.txt

이 문서에 보면 "환경 영역에다 셸코드를 집어넣고 이걸 strcpy를 이용해서 안전하게 실행 가능한 부분에다 복사한 다음 거기서 실행"한다고 되어 있는데, 안전하게 실행 가능한 부분이 있다는 것이 이해가 되지 않습니다. 이게 가능하다면 솔라리스에서는 .rodata 페이지에 실행 비트를 켜두고 있거나(셸코드를 바로 실행하려면), 읽기전용으로 맵된 페이지에 실행 비트를 켜고 있다는 (임의의 코드 영역에 셸코드를 덮어 씌우려면) 얘기지 않나요. 그렇게 될 경우 아무리 스택을 보호해 봐야 소용이 없는 일인데요. 제가 내용을 잘못 이해한 것일 수 있으니 읽어 보시고 비평해 주시면 감사하겠습니다.

버려진의 이미지

먼저 죄송하지만 언급하신 문서를 아직 읽어보지 못했습니다.
솔라리스, sparc 모르는 쪽이기는 하지만 간혹 보던 문서에 의지하여.. 8)

      Solaris (an OS developed by Sun Microsystems), as of Solaris 
      2.6, sparc Solaris includes a "protect_stack" option, but not an 
      equivalent "protect_heap" option.  Fortunately, the bss is not 
      executable (and need not be). 

예 방준영님께서 말씀하셨던 내용이네요. sparc에서의 힙오버플로우가 스택가드의 보호 범위를 벗어나나봅니다.

      There is a "StackGuard" (developed by Crispin Cowan et. al.), but 
      no equivalent "HeapGuard". 

그리고.. Procedure Linking Table..

   Another method is to use the PLT (Procedure Linking Table) which shares 
   the address of a function in the PLT.  I first learned the PLT method 
   from str (stranJer) in a non-executable stack exploit for sparc. 

아마 말씀하신 문서의 내용이 이것이 아닐까 싶습니다.

말씀하신 문서는 추후에 읽어보도록 하겠습니다. 지금은.. 시간이.. 고3입시생인데 예체능계라서 실기 준비를 해야 하거든요 8)

morris의 이미지

Quote:

방준영님께서 말씀하셨던 내용이네요. sparc에서의 힙오버플로우가 스택가드의 보호 범위를 벗어나나봅니다.

힙과 스택은 다른 영역이기때문에 당연하게 그렇게 스택가드는

힙을 보호하지 못합니다.

http://packetstormsecurity.nl/groups/horizon/stack.txt

문서의 내용은 register를 고쳐서 system함수로 /bin/sh를 부르는건데

보시다시피 우회할 방법은 많습니다.

굳지 스택을 못쓰게 하더라도, win2k3처럼 stack protection 기능을

넣어서 컴파일한 커널을 쓰더라도

버그가 존재하면 당연히 그걸 악용하는건 가능합니다. 다만 좀 어려워질뿐이죠

단순히 bof때문에 스팍을 선택한거라면 요즘 추세와는 그다지 맞지 않은거 같네요

요즘엔 단순히 http만 서비스하는데도 많고 데몬 자체의 취약성 보고가

예전보다 많이 줄어들었습니다.

그만큼 소스코드가 안전해지고 있다는 거겠죠.

오히려 cross site script나 virus, worm을 포함한 메일이 현대적인

네트워크에서 제일 큰 위협이죠

방준영의 이미지

pyj200 wrote:
      Solaris (an OS developed by Sun Microsystems), as of Solaris 
      2.6, sparc Solaris includes a "protect_stack" option, but not an 
      equivalent "protect_heap" option.  Fortunately, the bss is not 
      executable (and need not be). 

예 방준영님께서 말씀하셨던 내용이네요. sparc에서의 힙오버플로우가 스택가드의 보호 범위를 벗어나나봅니다.


그것이 아니고 솔라리스에서 힙은 원래부터 실행 불가능 상태로 맵되기 때문에 보호할 필요가 없다는 뜻 같네요.

Quote:
그리고.. Procedure Linking Table..

   Another method is to use the PLT (Procedure Linking Table) which shares 
   the address of a function in the PLT.  I first learned the PLT method 
   from str (stranJer) in a non-executable stack exploit for sparc. 

아마 말씀하신 문서의 내용이 이것이 아닐까 싶습니다.


기종에 따라 PLT가 쓰기 가능하고 쓰기 불가능한 것으로 알고 있습니다. SPARC ABI는 PLT에 뭔가를 써야 하나보죠? x86에서는 PLT가 읽기 전용이라 안전합니다.
verotas의 이미지

이렇게 되나요?

질문 :
1. sparc는 근본적으로 스택 오버플로우 공격 등에 더 잘 버틴다.
2. 그렇다면 관리자들은 서버를 고를 때 이런 점을 고려할 것인가?

저는 2.번에 대해 아닐 것이다 라고 대답을 했는데, 대체로 보니 1.에 대해서도 부정적인 답이 많은 것 같군요. 저는 방준영 님이 제기하신 문제에서 중요한 점은 2번이라고 보았는데, 아니었나 봅니다. ^^;;

1.에 대해 언급하자면, 저 역시 sparc이 x86보다 스택오버플로우에 대해 더 안전하다는 건 그저 비싼 장비를 팔기 위한 숱한 얘기들 가운데 하나라는 쪽에 걸겠습니다. 왜냐하면

첫번째, 제 눈으로 오버플로우가 너무나 손쉽게 되는 것을 목격했기 때문이고
두번째, 몇몇 언급하신 상대적 우월함 정도가 공격당하는 유형이나 빈도에서 결정적인 차이를 가져올 만큼 크다고 보지 않기 때문이며
세번째, 역시 보안은 기술이 아니라 과정(chain of processes)이기 때문입니다.

따라서, 2번 질문으로 돌아가자면, 결과적으로 공격을 당할 확률을 낮추거나 당했을 때 크게 당할 확률을 낮춰주지 못한다면 (그래서 집에 늦게 가는 날이 줄어들지 않는다면), 관리자 입장에서도 굳이 비싼 장비 꼭 사야한다고 우길 이유가 없어지지 않을까 합니다.

The good is the enemy of the best.

지리즈의 이미지

서버를 선택할 때 가장 중요한 것은
역쉬 AS죠...

There is no spoon. Neo from the Matrix 1999.

warpdory의 이미지

서버 선택할 때 가장 중요한 건 ... 책임 떠넘길 수 있는 거 .. 가 아닐까 합니다.
그래서 '비싼' HP/컴팩(이건 좀 싼가...) ... 이런 걸 쓰죠. 부품이나 스펙으로 따지면 용산에서 조립하는 것과 큰 차이가 없더라도 말이죠. 고장이다. 하면 전화 걸면 와서 어떻게든 뭔가 해주니깐요. - 물론 백업은 ... 알아서 해야...

학과 서버를 스팍 2 에서 용산 조립 컴퓨터에다가 리눅스로 구현을 했을 때 이스라엘 크래커들에게 당했었는데... 그때 나온 얘기.. '그러게 삼성컴퓨터로 했어야 한다니깐.' .. -_- 이더군요. 결국은 삼보껄로 낙찰(삼성은 너무 비싸서)됐는데... 이번엔 DSP 카드(아시는 분은 아실 겁니다. 모뎀, 사운드 카드 몽땅 내장되었던 카드)가 문제를 일으켰었죠. 그런데... 계약조건이 컴퓨터 케이스 뜯으면 A/S 불가였기 때문에 - 학교 거쳐 들어온 것들이 그런 게 많습니다. - 몇번의 A/S 를 거치고 ... 결국엔 그냥 다시 용산컴퓨터로 복귀 됐죠.


---------
귓가에 햇살을 받으며 석양까지 행복한 여행을...
웃으며 떠나갔던 것처럼 미소를 띠고 돌아와 마침내 평안하기를...
- 엘프의 인사, 드래곤 라자, 이영도

즐겁게 놀아보자.

김정균의 이미지

주제랑 맞을지는 모르겠지만.. glibc 에 heap protection patch 를 하는
프로젝트(?) 가 있더군요. 영어라서 대충만 봤는데.. ^^;

http//www.cs.ucsb.edu/~wkr/projects/heap_protection/

참고 해 보세요.

방준영의 이미지

여러분의 말씀들을 종합해 보니 결국 SPARC는 x86보다 별로 또는 전혀 보안면에서 우수하지 않다로 결론이 내려지네요. 페이지당 실행 비트라는 우수한 기능이 있음에도 불구하고 이 장점을 못살리고 있는 SPARC 아키텍쳐...

그런데 여전히 남는 의문은, 스택 오버플로우를 일으켜서 셸코드를 집어넣는 데 성공하더라도, 그 코드를 실행할 방법이 *전혀* 없다면, 어떠한 종류의 공격이든 시스템을 뚫을 수 없는 것 아닐까요? 앞서 SPARC 스택 보호 기능을 우회하는 방법의 경우 셸코드를 안전하게 실행할 수 있는 영역이 있는 것으로 서술되어 있는데, 이 영역이 존재하지 않는다면 레지스터를 어떻게 조작하더라도 공격이 무위로 끝나지 않겠느냐는 얘기죠. 이미 OpenBSD가 그런 기능을 구현했고, NetBSD도 이를 도입했으므로 앞으로 나올 두 OS의 보안 권고를 지켜보면 결과를 알 수 있을 것 같습니다(아마도 리눅스 배포판 중에도 비슷한 기능을 커널에 추가한 것이 있을 텐데 써본 적이 없어서 모르겠습니다).

pynoos의 이미지

http://news.com.com/2100-7355-5137832.html

http://news.empas.com/show.tsp/wo/20040112n01376/

위 기사가 이 쓰레드와 적합한것 같아서 링크를 달아 봅니다..

그런데, 위의 AMD, intel이 새로내놓는다는 기능이 페이지별 실행권한 조절가능과 그에 애한 OS의 구현형태로 되는 것인지는 살펴보지 않아서 모르겠군요.

redpig의 이미지

제가 아는게 없어서..

Quote:
페이지 단위로 실행 비트를 매길 수 있는 아키텍쳐는 버퍼 오버플로우의 위험성이 거의 원천적으로 사라집니다.

이부분이 잘 이해가 안되네요.ㅡㅡ;

제가 알고 있는 부분중에 솔라리스는 운영체제 자체에서 스택에서 임의의 코드(예를들어 쉘코드)를 실행을 못하도록 지원해주고 있다는 건데요.
하지만 리눅스에서도 여러 패치등을 통해 같은 혹은 보다 강력한 기능을 지원해주고 있죠.
그런데 이미 몇년전에 이걸 우회할수 있는 방법이 나와있습니다.
http://packetstormsecurity.nl/groups/horizon/stack.txt
이 문서에서 보면 return to libc라는 기법을 이용해서 쉘코드 없이 바로 쉘을 실행시키는걸 증명해주고 있죠.
즉 스택이나 힙에서 사용자의 코드를 실행못하게 하는건 이미 우회방법이 나와있습니다.