[하루한줄] CVE-2020-8625: Fifteen-year-old RCE bug

URL

CVE-2020-8625: A FIFTEEN-YEAR-OLD RCE BUG RETURNS IN ISC BIND SERVER

Target

BIND version 9.11 ~ 9.16

Explain

15년 전 ISC BIND 서버에서 4-byte 힙 오버플로우를 악용한 RCE 취약점(CVE-2006-5989)이 발견됐습니다. 해당 취약점에 대한 패치가 merge 되지 않아 방치됐고, 작년(2020년)에 CVE-2020-8625라는 번호로 패치됐습니다.

static int 
der_get_oid(const unsigned char *p, size_t len, oid *data, size_t *size) { 
// ... 
data->components = malloc(len * sizeof(*data->components));   // <-- (1) 
    if (data->components == NULL) { 
      return (ENOMEM); 
    } 
    data->components[0] = (*p) / 40;    // <-- (2) 
    data->components[1] = (*p) % 40; 
    --len;               // <-- (3) 
    ++p; 
    for (n = 2; len > 0U; ++n) { 
        unsigned u = 0; 
 
        do { 
            --len; 
            u = u * 128 + (*p++ % 128); 
        } while (len > 0U && p[-1] & 0x80); 
        data->components[n] = u;      // <-- (4) 
    } 
// ... 
}

힙 오버플로우 버그가 존재하는 lib/dns/spnego.c의 함수 der_get_old() 일부입니다.

(1): 배열형 버퍼를 할당하고 len 변수를 통해 버퍼에 남아있는 element 수를 추적합니다.

(2): 버퍼에 2개의 element를 담습니다.

(3): len의 값을 1번만 감소시킵니다.

(4): 한 개의 int element(4 byte) 만큼 오버플로우가 발생합니다.

해커는 서버로 조작된 request를 보내 der_get_old()가 할당하는 버퍼의 크기와 그 데이터를 조작할 수 있고, der_get_old()를 호출하는 loop count를 조작할 수 있으므로 연속된 힙 청크의 재할당을 유도해 exploit을 할 수 있습니다.