y0u_bat

CVE-2015-0235 GHOST 취약점 본문

System

CVE-2015-0235 GHOST 취약점

유뱃 2016. 2. 16. 23:50

 CVE-2015-0235 GHOST 취약점 설명


c 라이브러리인 glibc안에 __nss_hostname_digits_dots() 함수 내부에서 버퍼오버플로우 취약점이 존재한다.


아래 함수에 #ifdef HANDLE_DIGITS_DOTS 가 매크로 정의 되어 있다.


- inet/gethstbynm.c

- inet/gethstbynm2.c

- inet/gethstbynm_r.c

- inet/gethstbynm2_r.c

 - inet/gethstbynm3_r.c


gethostbyname() 과 gethostbyname2() 를 통해서  힙영역 버퍼를 오버플로우 할수있으며,

gethostbyname_r() 과 gethostbyname2_r()를 통해서는 사용자가 제공해주는 버퍼를 덮을 수 있다.



__nss_hostname_digits_dots() 함수에서 취약한 코드를 보면


~

~

85  size_needed = (sizeof (*host_addr) + sizeof (*h_addr_ptrs) + strlen(name) + 1);

~

~

121  host_addr = (host_addr_t *) *buffer;

122  h_addr_ptrs = (host_addr_list_t *)((char *) host_addr + sizeof (*host_addr));

123  h_alias_ptr = (char **) ((char *) h_addr_ptrs + sizeof (*h_addr_ptrs));

124  hostname = (char *) h_alias_ptr + sizeof (*h_alias_ptr);

~

~

~

157  resbuf->h_name = strcpy(hostname,name);

~

~


85라인을 보면 버퍼크기를 게산하는 도중 sizeof(*h_alias_ptr)를 빼먹는 실수가 있다. 

 


그래서 157라인에 strcpy(hostname,name)를 할때 제대로 된 크기만큼 복사하기 때문에, 

32비트 운영체제 경우 4바이트, 64비트 운영체제 경우 8바이트 만큼 오버플로우가 된다.


해당취약점을 터트리기 위한 조건

  1. 숫자 0~9 와 점(.) 으로 되어 있어야 한다.
  2. 끝은 null로 되어 있어야 한다.
  3. 첫번째 글자는 숫자로 되어 있어야 한다.
  4. inet_athon() 함수에서 정상적으로 파싱되어야 한다.
  5. 버퍼 크기가 충분히 커야 된다.


취약 여부 검사


#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);

}


대응방안


취약한 버전 glibc를  업데이트 하고 해당라이브러리를 포함하여 컴파일한 프로그램들은 취약하지 않는 

glibc 버전을 이용하여 재컴파일 해야 된다.



참고자료


[1] http://www.openwall.com/lists/oss-security/2015/01/27/9

[2] http://training.nshc.net/KOR/Document/vuln/20140129_GHOST_Vulnerability_CVE-2015-0235.pdf

[3] http://lunatine.net/glibc-ghost-vulnerability/





Comments