리눅스 취약점대응방안권고 15. 01. 29 / KISA 취약점점검팀 15. 01. 30 영향받는플랫폼 OS, FAQ 추가 개요 미국보안회사 에의해 시스템의 라이브러리 의특정함수에서임의코드를실행할수있는취약점이공개 해당취약점은 CVE-2015-0235 지정, 도메인네임을 IP로변환하는기능이포함된서비스 ( 메일, 웹등 ) 들은해당취약점에영향을받을수있음 취약점상세분석 리눅스계열에서사용하고있는 라이브러리에존재하는 함수에서잘못된메모리사용으로인해메모리변조가능 glibc 라이브러리 : GNU C 라이브러리로리눅스운영체제에서기본적으로사용하고있는라이브러리 nss_hostname_digits_dots 함수 : 도메인주소를 IP 주소로변환하는 gethostbyname 함수호출시호스트이름이 ip형태일경우, 내부적으로호출되는함수 함수내메모리사이즈연산이잘못되어메모리복사과정에서오버플로우발생 int nss_hostname_digits_dots(const char *name, struct hostent *resbuf, char **buffer, size_t *buffer_size, size_t buflen, struct hostent **result, enum nss_status *status, int af, int *h_errnop) // *buffer_size는기본적으로 1024 byte, *buffer는기본사이즈로할당되어있음 // size_needed가 *buffer_size보다큰경우에는 *buffer를 size_needed만큼메모리재할당 size_needed = ( sizeof(*host_addr) + sizeof(*h_addr_ptrs) + strlen(name) + 1 ); host_addr = (host_addr_t *)*buffer; h_addr_ptrs = (host_addr_list_t *)( (char *)host_addr + sizeof(*host_addr) );
h_alias_ptr = (char **)( (char *)h_addr_ptrs + sizeof(*h_addr_ptrs) ); // hostname의메모리시작주소연산시, // size_needed 에포함되지않은 sizeof(*h_alias_ptr) 추가 (4byte) hostname = (char *)h_alias_ptr + sizeof(*h_alias_ptr); // 추가된 sizeof(*h_alias_ptr) 에의해 strcpy 시 4바이트오버플로우발생 (32bit 기준 ) resbuf->h_name = strcpy(hostname, name); [ 취약한 glibc 소스코드 ] 32bit 운영체제기준 4byte 오버플로우 취약점에영향받는프로그램에서공격자가조작한문자열을인자로 함수를호출할경우 메모리변조를통해임의코드실행가능 영향받는 버전 버전의모든리눅스시스템 glibc 2.18~2.20 버전, 2.1.3 이하버전은취약하지않음 (2.(2~17) 버전에해당 ) getconf a grep glibc glibc 버전확인방법 ldd version
업데이트된후버전이바뀌지않는일부운영체제도있으니취약점확인 방법으로패치검증권고 영향받는 플랫폼 취약한 버전을사용하는기타리눅스시스템 취약점확인방법 를사용하는시스템에서터미널프로그램실행후아래내용을 로저장 /* ghosttest.c: GHOST vulnerability tester */ /* Credit: http://www.openwall.com/lists/oss-security/2015/01/27/9 */ #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #define CANARY "in_the_coal_mine" struct { char buffer[1024]; char canary[sizeof(canary)]; } temp = { "buffer", CANARY }; int main(void) { struct hostent resbuf; struct hostent *result; int herrno; int retval; /*** strlen (name) = size_needed - sizeof (*host_addr) - sizeof (*h_addr_ptrs) - 1; ***/ size_t len = sizeof(temp.buffer) - 16*sizeof(unsigned char) - 2*sizeof(char *) - 1; char name[sizeof(temp.buffer)];
memset(name, '0', len); name[len] = '\0'; retval = gethostbyname_r(name, &resbuf, temp.buffer, sizeof(temp.buffer), &result, &herrno); if (strcmp(temp.canary, CANARY)!= 0) { puts("vulnerable"); exit(exit_success); } if (retval == ERANGE) { puts("not vulnerable"); exit(exit_success); } puts("should not happen"); exit(exit_failure); } 파일을아래의명령어로컴파일실행 gcc o GHOST GHOST.c [GHOST.c 컴파일실행 ] gcc가설치되어있지않은경우, sudo apt-get install gcc 명령어로설치 아래의명령어로실행파일실행후취약점여부확인./GHOST [GHOST 실행 ] [CVE-2015-0235 에취약한화면 ] [CVE-2015-0235 에취약하지않은화면 ] 라이브러리에의존하는패키지및어플리케이션확인방법 lsof grep libc awk '{print $1}' sort uniq
[lsof 명령어를이용한 glibc 라이브러리확인방법 ] 해결방법 업데이트버전설치 취약한 버전을사용하고있는경우 운영체제제조사홈페이지를방문하여패치방법확인 CentOS Debian Redhat Ubuntu GUN C Library http://lists.centos.org/pipermail/centos/2015-january/149413.html https://security-tracker.debian.org/tracker/cve-2015-0235 https://rhn.redhat.com/errata/rhsa-2015-0090.html https://launchpad.net/ubuntu/+source/eglibc http://www.gnu.org/software/libc/ 패키지버전확인방법 OS 종류 CentOS / Redhat Ubuntu / Debian > rpm -qa grep glibc 패키지버전확인방법 > apt-cache show eglibc-source grep Version 운영체제제조사홈페이지를방문하여최신버전을확인하고, 아래방법을이용하여 현재버전을확인후최신버전이아닌경우, 패키지업데이트 패키지업데이트방법 OS 종류 CentOS / Redhat Ubuntu / Debian > yum install glibc 패키지업데이트방법 > apt-get clean && apt-get update && apt-get upgrade 패키지업데이트후시스템재부팅수행
상위버전라이브러리로컴파일 취약한버전의라이브러리를포함하여컴파일된프로그램의경우 상위버전의라이브러리로재컴파일이필요 취약점 GHOST 취약점대응 FAQ Q. 취약하지않은 glibc 2.18버전이 13.5.21. 패치가되었는데현재이슈가된이유는무엇인가요? 운영체제제조사들은 13년 GNU에서패치한 2.18버전을보안업데이트로인지하지않았으며, 15.1월확인후취약점패치적용 Q. glibc 취약점패치를해야하는이유가무엇인가요? 원격코드실행이가능한심각한취약점으로실제공격을성공시키기위한여러조건이필요하지만, 위험성이존재하기때문에패치를권장합니다. Q. 서비스중단이어려운데, 꼭재부팅을해야하나요? 불가피하게영향을받는서비스에한하여재가동하는것도가능하나, 서비스에대한완전한목록을찾기어렵기때문에업데이트후재부팅을권장합니다. Q. glibc 2.2가 2.17보다상위버전아닌가요? 2.2는 2.17보다하위버전이며, 2.(2~17) 버전으로이해하면됩니다. 2.20과 2.2(=2.02) 가혼선이없도록주의가필요합니다.