[하루한줄] CVE-2021-22555: Linux Kernel - Netfilter에서 발견된 OOB Write 취약점

URL

CVE-2021-22555: Turning \x00\x00 into 10000$

Target

  • linux kernel

Explain

리눅스 커널의 네트워크 프레임워크인 Netfliter는 네트워크 관련 연산들을 핸들러 형태로 구현할 수 있도록 hook을 제공합니다. 이러한 Netfilter의 서브시스템 중 iptables 지원을 위한 IPT_SO_SET_REPLACE 또는 IP6T_SO_SET_REPLACE를 호환 모드로 호출할 때 발생하는 OOB 취약점의 세부 정보가 공개되었습니다.

IPT_SO_SET_REPLACE/IP6T_SO_SET_REPLACE 를 호환 모드로 호출 시 네이티브로 처리하기 위해서는 구조체를 userland에서 커널로 복사하며 32bit에서 64bit로 변환합니다.

취약점은 변환 과정의 xt_compat_target_from_user() 함수에서 발생합니다.

1		void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr,
2						unsigned int *size)
3		{
4			const struct xt_target *target = t->u.kernel.target;
5			struct compat_xt_entry_target *ct = (struct compat_xt_entry_target *)t;
6			int pad, off = xt_compat_target_offset(target);
7			u_int16_t tsize = ct->u.user.target_size;
8			char name[sizeof(t->u.user.name)];
9		
10		t = *dstptr;
11		memcpy(t, ct, sizeof(*ct));
12		if (target->compat_from_user)
13			target->compat_from_user(t->data, ct->data);
14		else
15			memcpy(t->data, ct->data, tsize - sizeof(*ct));
16		pad = XT_ALIGN(target->targetsize) - target->targetsize;
17		if (pad > 0)
18			memset(t->data + target->targetsize, 0, pad);
19	
20		tsize += off;
21		t->u.user.target_size = tsize;
22		strlcpy(name, target->name, sizeof(name));
23		module_put(target->me);
24		strncpy(t->u.user.name, name, sizeof(t->u.user.name));
25	
26		*size += off;
27		*dstptr += tsize;
28	}

line 16에서 정렬된 targetsize의 차이를 계산한 뒤 line 18의 memset() 함수에서 계산된 차이만큼 NULL padding을 추가합니다. 그러나 target->targetsize 가 고려되지 않아 할당된 크기를 넘어 인접한 객체에 NULL을 쓸 수 있는 제한된 OOB write가 가능하며 이는 권한 상승으로 이어질 수 있습니다.

해당 취약점은 이전에 발견된 CVE-2016-3134/CVE-2016-4997와 유사한 것으로 알려졌습니다.



본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.