[하루한줄] CVE-2024-21778: Realtek rtl819x Jungle SDK에서 발생한 Heap-based buffer overflow 취약점

URL

https://talosintelligence.com/vulnerability_reports/TALOS-2024-1911

Target

  • LevelOne WBR-6013 RER4_A_v3411b_2T2R_LEV_09_170623
  • Realtek rtl819x Jungle SDK v3.4.11

Explain

rtl819x Jungle SDK는 라우터에 사용되는 SDK(Software Development Kit)로 웹서버로는 Boa를 사용합니다. 무선 공유기인 LevelOne WBR-6013에 이 SDK가 사용되었으며 라우터의 환경설정을 변경하기 위해 /boafrm/formUploadConfig API를 사용해서 환경설정 파일을 업로드하게 되는데 이 파일을 파싱하는 과정에서 취약점이 발생합니다.

환경설정 파일에는 다양한 옵션들이 TLV(type, length, value) 형식으로 저장되어 있으며 아래의 mid_init_vaule 함수를 통해 데이터가 복사됩니다.

File: apmib.c
static int mib_init_value(unsigned char *ptlv_data_value, unsigned short tlv_len, const mib_table_entry_T *mib_tbl, void *data)
{
    /*[...]*/
    switch (mib_tbl->type)
    {
        case BYTE_T:
        case BYTE_ARRAY_T:
        case DWORD_ARRAY_T:
            pChar = (unsigned char *) data;
[1]         memcpy(data, ptlv_data_value, tlv_len);			
            break;
     /*[...]*/
    }

    return 1;
}

위 코드에서 memcpy의 인자로 사용되는 tlv_len은 파일에서 유래한 값으로 데이터가 복사될 메모리인 data의 크기보다 크지 않은지 확인하는 부분이 없는 것을 볼 수 있습니다.

data가 가리키는 메모리는 고정된 크기를 가지는 힙 버퍼로 아래의 apmib_load_csconf 함수에서 0x924d 크기로 할당됩니다.

File: apmib.c
char *apmib_load_csconf(void)
{
    /*[...]*/
    if(memcmp(compHeader.signature, COMP_CS_SIGNATURE, COMP_SIGNATURE_LEN) == 0 ) //check whether compress mib data
    {
[2]     curMibData = malloc(sizeof(APMIB_T)+1); // 1: checksum
    /*[...]*/
[3]     if(tlv_checksum == 1 && mib_tlv_init(pmib_tl, expFile+sizeof(PARAM_HEADER_T), (void*)curMibData, tlv_content_len) == 1) /* According to pmib_tl, get value from expFile to hwMibData. parse total len is  tlv_content_len*/
	    {
    /*[...]*/

[2]에서 malloc으로 할당된 버퍼가 [3]에서 호출되는 mid_tlv_init의 인자로 사용되고 이는 다시 mid_init_value 호출의 인자(data)로 사용됩니다.

따라서 TLV 데이터의 길이를 0x924d보다 크게 설정하게 된다면 data가 가리키는 힙 메모리에서 버퍼 오버플로우를 발생시킬 수 있고 예시로 사용된 DWORD_ARRAY_T 타입 외에도 다양한 타입에서 같은 방식으로 오버플로우가 발생합니다. 또한 오버플로우되는 데이터와 데이터의 길이를 제어할 수 있기 때문에 인접한 힙 청크의 데이터를 덮어쓰는 등의 방식으로 임의 코드 실행으로도 이어질 수 있습니다.