Ghost 취약점이 발견되어, 사용자 주의를 당부 드립니다. 해당 취약점은 Linux glibc 라이브러리에서 발생한 것으로, 공격자가 시스템 상황을 모르는 상태에서 원격으로 시스템 제어 권한을 획득할 수 있습니다.
glibc이란?
glibc란 ‘GNU C library’의 약자로 GNU시스템과 Linux에서 사용하는 대표적인 C라이브러리입니다. Linux 시스템에서 가장 로우레벨 api로 거의 모든 운영 라이브러리가 glibc를 참조하고 있습니다.
Ghost(CVE-2015-0235) 취약점
해당 취약점은 gethostbyname*() 함수에서 발생하는 취약점으로, 취약점이 발생하면 sizeof(char*)개의 바이트가 오버플로우 됩니다. (주의할 것은 여기서 char*은 32비트 시스템에서는 4바이트를 말하며, 64비트 시스템에서는 8바이트를 말합니다.)
하지만 해당 취약점은 payload가 숫자(‘0’), 점(‘.’), 그리고 마침을 표현하는 빈칸(‘/0’)으로만 이루어져 있어야 한다는 전제조건이 있습니다. 사실 glibc를 타겟으로 한 공격은 2000년 11월 10일에 이미 발생했었으며, 2013년 5월 21일에 이미 패치가 진행되었습니다. (glibc 2.17버전에서 glibc 2.18버전 사이)
당시 사용자들은 이것이 보안 취약점이라는 것을 인지하지 못했습니다. 그 결과, 현재 대부분의 리눅스 버전들이 모두 해당 취약점을 갖고 있게 되었습니다.
패치 방법은 glibc자체를 업데이트 하면 됩니다. 하지만 해당 라이브러리에는 많은 서비스에서 사용하는 함수들이 포함되어 있고, 업데이트 후 반드시 재부팅을 해야하기 때문에 약간의 번거로움이 있습니다.
Gcc 버전 확인
1 2 3 4 5 6 7 |
<span style="color: rgb(0, 51, 0); font-size: 10pt;"><span style="color: #c20cb9; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif;"><span style="line-height: 15.4260005950928px;"><strong>[root@xinet gcc]# ldd --version ldd (GNU libc) 2.12 Copyright (C) 2010 Free Software Foundation, Inc. 이 프로그램은 공개 소프트웨어입니다; 복사조건은 소스를 참조하십시오. 상품성 이나 특정 목적에 대한 적합성을 비롯하여 어떠한 보증도 하지 않습니다. 만든 사람: Roland McGrath 및 Ulrich Drepper.</strong></span></span></span><span style="color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif;"><span style="font-size: 0.857em; line-height: 1.5em;"> </span></span> |
gcc 취약버전을 이용하는 o/s
A list of affected Linux distros
- RHEL (Red Hat Enterprise Linux) version 5.x, 6.x and 7.x
- CentOS Linux version 5.x, 6.x & 7.x
- Ubuntu Linux version 10.04, 12.04 LTS
- Debian Linux version 7.x
- Linux Mint version 13.0
- Fedora Linux version 19 or older
- SUSE Linux Enterprise 11 and older (also OpenSuse Linux 11 or older versions).
- SUSE Linux Enterprise Software Development Kit 11 SP3
- SUSE Linux Enterprise Server 11 SP3 for VMware
- SUSE Linux Enterprise Server 11 SP3
- SUSE Linux Enterprise Server 11 SP2 LTSS
- SUSE Linux Enterprise Server 11 SP1 LTSS
- SUSE Linux Enterprise Server 10 SP4 LTSS
- SUSE Linux Enterprise Desktop 11 SP3
- Arch Linux glibc version <= 2.18-1
자기 자신의 서버의 gcc 버전이 취약한지 아닌지 확인하는 방법
1 |
<span style="font-size: 12pt; color: rgb(0, 51, 0);">vi <span style="line-height: 1.5em;">ghosttest.c</span></span> |
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 29 30 31 32 33 34 35 36 37 38 39 40 41 |
<span style="font-size: 8pt;"><span style="color: #808080; font-style: italic;">/* ghosttest.c: GHOST vulnerability tester */</span> <span style="color: #808080; font-style: italic;">/* Credit: http://www.openwall.com/lists/oss-security/2015/01/27/9 */</span> <span style="color: #339933;">#include <netdb.h></span> <span style="color: #339933;">#include <stdio.h></span> <span style="color: #339933;">#include <stdlib.h></span> <span style="color: #339933;">#include <string.h></span> <span style="color: #339933;">#include <errno.h></span> <span style="color: #339933;">#define CANARY "in_the_coal_mine"</span> <span style="color: #993333;">struct</span> <span style="color: #66cc66;">{</span> <span style="color: #993333;">char</span> buffer<span style="color: #66cc66;">[</span><span style="color: #cc66cc;">1024</span><span style="color: #66cc66;">]</span>; <span style="color: #993333;">char</span> canary<span style="color: #66cc66;">[</span><span style="color: #993333;">sizeof</span><span style="color: #66cc66;">(</span>CANARY<span style="color: #66cc66;">)</span><span style="color: #66cc66;">]</span>; <span style="color: #66cc66;">}</span> temp = <span style="color: #66cc66;">{</span> <span style="color: #ff0000;">"buffer"</span>, CANARY <span style="color: #66cc66;">}</span>; <span style="color: #993333;">int</span> main<span style="color: #66cc66;">(</span><span style="color: #993333;">void</span><span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span> <span style="color: #993333;">struct</span> hostent resbuf; <span style="color: #993333;">struct</span> hostent *result; <span style="color: #993333;">int</span> herrno; <span style="color: #993333;">int</span> retval; <span style="color: #808080; font-style: italic;">/*** strlen (name) = size_needed - sizeof (*host_addr) - sizeof (*h_addr_ptrs) - 1; ***/</span> size_t len = <span style="color: #993333;">sizeof</span><span style="color: #66cc66;">(</span>temp.<span style="color: #202020;">buffer</span><span style="color: #66cc66;">)</span> - <span style="color: #cc66cc;">16</span>*<span style="color: #993333;">sizeof</span><span style="color: #66cc66;">(</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span><span style="color: #66cc66;">)</span> - <span style="color: #cc66cc;">2</span>*<span style="color: #993333;">sizeof</span><span style="color: #66cc66;">(</span><span style="color: #993333;">char</span> *<span style="color: #66cc66;">)</span> - <span style="color: #cc66cc;">1</span>; <span style="color: #993333;">char</span> name<span style="color: #66cc66;">[</span><span style="color: #993333;">sizeof</span><span style="color: #66cc66;">(</span>temp.<span style="color: #202020;">buffer</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">]</span>; memset<span style="color: #66cc66;">(</span>name, <span style="color: #ff0000;">'0'</span>, len<span style="color: #66cc66;">)</span>; name<span style="color: #66cc66;">[</span>len<span style="color: #66cc66;">]</span> = <span style="color: #ff0000;">'<span style="color: #000099; font-weight: bold;">\0</span>'</span>; retval = gethostbyname_r<span style="color: #66cc66;">(</span>name, &resbuf, temp.<span style="color: #202020;">buffer</span>, <span style="color: #993333;">sizeof</span><span style="color: #66cc66;">(</span>temp.<span style="color: #202020;">buffer</span><span style="color: #66cc66;">)</span>, &result, &herrno<span style="color: #66cc66;">)</span>; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">(</span>strcmp<span style="color: #66cc66;">(</span>temp.<span style="color: #202020;">canary</span>, CANARY<span style="color: #66cc66;">)</span> != <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span> puts<span style="color: #66cc66;">(</span><span style="color: #ff0000;">"vulnerable"</span><span style="color: #66cc66;">)</span>; exit<span style="color: #66cc66;">(</span>EXIT_SUCCESS<span style="color: #66cc66;">)</span>; <span style="color: #66cc66;">}</span> <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">(</span>retval == ERANGE<span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span> puts<span style="color: #66cc66;">(</span><span style="color: #ff0000;">"not vulnerable"</span><span style="color: #66cc66;">)</span>; exit<span style="color: #66cc66;">(</span>EXIT_SUCCESS<span style="color: #66cc66;">)</span>; <span style="color: #66cc66;">}</span> puts<span style="color: #66cc66;">(</span><span style="color: #ff0000;">"should not happen"</span><span style="color: #66cc66;">)</span>; exit<span style="color: #66cc66;">(</span>EXIT_FAILURE<span style="color: #66cc66;">)</span>; <span style="color: #66cc66;">}</span></span> |
gcc 인코딩
1 2 |
<strong><span style="font-size: 12pt; color: #003300;">$ gcc ghosttest.c -o ghosttest $ ./ghosttest</span></strong> |
취약버전이 아닌 경우 아래처럼 표시
1 |
<span style="color: rgb(255, 0, 0);"><strong><span style="font-size: 12pt;">not vulnerable</span></strong></span> |
취약버전이 나오는 버전의 경우 아래처럼 표시
1 |
<span style="font-size: 12pt;"><strong><span style="color: #ff0000;">vulnerable</span></strong></span> |
업데이트 진행 ( centos 6,7 버전의 경우 아래와 같이 진행하면 된다 )
1 |
<span style="color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif;"><span style="font-size: 12pt;"><strong><span style="letter-spacing: normal; line-height: 19.8378372192383px; color: #ff0000;">yum update glibc</span></strong></span><span style="font-size: 0.857em; font-weight: normal; letter-spacing: normal; line-height: 1.5em;"><br /></span></span> |