우분투 glibc 취약점 패치방법 (Fix GHOST Vulnerability)
우분투 glibc 취약점 패치방법 (Fix GHOST Vulnerability)
2015년 1월 27일 CVE-2015-0235 이라는 취약점이 공개되었다.
https://wiki.ubuntu.com/SecurityTeam/KnowledgeBase/GHOST
Ubuntu Security Team wiki 에 따르면 해당 취약점은 1월 18일에 보고 되었고
1월 27일 대중에게 공개되었을 때 패치업데이트를 제공했다고 한다.
gethostbyname() 에서 사용하는 __nss_hostname_digits_dots() 함수에서 버퍼오버플로우가 일어난다고 한다.
뉴스에서 엄청난 취약점인것 처럼 보도하는데, gethostbyname()이 잘 안쓰는 함수이며, 악의적 사용자가 이 함수를 사용할 권한을 얻기도 매우 힘들다.
만약 이 취약점이 성공하였으면 해당 프로그램이 crash 된다. 예를 들어 ssh 같은 것이 crash 되서 서비스 불능이 됨.
1) 취약점 적용 범위
해당 취약점은 glibc-2.18 에서 패치되었음.
그러나 Ubuntu를 포함한 대부분의 운영체제 팀에서 보안 위험 사항을 알지 못해서 운영체제 패치로 적용하지 않음.
취약한 버전 : glibc-2.2 ~ glibc-2.17 (2 ~ 17까지 취약)
취약한 운영체제 : Ubuntu 10.04 LTS, 12.04 LTS.
Ubuntu 14.04 LTS 는 취약하지 않음. (처음부터 glibc-2.19 가 내장되어 있음.)
2) 나의 서버가 취약한지 확인하기
glibc 버전체크
ldd --version
ldd (Ubuntu EGLIBC 2.11.1-0ubuntu7.13) 2.11.1
취약한 것으로 판명됨.
3) 취약점 패치
APT 패키지 목록 갱신
apt-get update
시스템 업그레이드
apt-get dist-upgrade
재부팅
reboot
4) 패치 확인하기
아래 버전이거나 혹은 블로그 글 쓴 시점보다 미래에 나올 더 최신버전이면 패치가 된 것이고 안전하다.
아래 보는 바와 같이 2.18 이상으로 업데이트 한 것이 아니라 해당버전(2.11.1)에서 이번 취약점을 패치한 것일 뿐이다.
Ubuntu 10.04 LTS: 2.11.1-0ubuntu7.20
Ubuntu 12.04 LTS: 2.15-0ubuntu10.10
5) 취약점 테스트
간혹 내가 취약점 패치를 잘 했는지 꼭 눈으로 확인하고 싶으신 분들이 있으시더라.
그분들을 위해 테스트 소스를 첨부한다.
라엘이가 짠건 아니고 http://www.openwall.com/ 보안팀에서 공개한 소스이다.
/* 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 ghosttest.c -o ghosttest
./ghosttest
축하합니다! 당신은 취약합니다!
이런, 당신의 시스템은 안전하군요!