영향 받는 대상
OpenSSL 3.0.x Version (3.0.0 ~ 3.0.6)
취약점 전제 조건
해당 취약점의 경우 CA가 취약한 인증서로 서명되었거나 유효한 인증서가 아님에도 불구하고 통신을 진행할 경우에만 발생 가능한 취약점 입니다. 즉, 일반적인 환경에서 발생할 수 있는 취약점은 아닙니다.
위와 같은 이유로 OpenSSL에서도 최초 취약점 등급이었던 Critical을 High로 다운그레이드 하였습니다.
취약점 분석
해당 취약점은 Punycode Domain의 인증서 확인 및 이름 제약 조건 검사 함수인 ossl_a2ulabel에서 발생하는 취약점으로 Stack Buffer over Flow가 가능합니다. 다만, 덮어씌울 수 있는 값은 0x2e(.)으로 한정되어 있습니다.
ossl_a2ulabel에서 제약 조건을 검사하는 로직는 다음과 같습니다.
while (1) {
char *tmpptr = strchr(inptr, '.');
size_t delta = (tmpptr) ? (size_t)(tmpptr - inptr) : strlen(inptr);
if (strncmp(inptr, "xn--", 4) != 0) {
size += delta + 1;
if (size >= *outlen - 1)
result = 0;
if (result > 0) {
memcpy(outptr, inptr, delta + 1);
outptr += delta + 1;
}
} else {
unsigned int bufsize = LABEL_BUF_SIZE;
unsigned int i;
if (ossl_punycode_decode(inptr + 4, delta - 4, buf, &bufsize) <= 0)
return -1;
for (i = 0; i < bufsize; i++) {
unsigned char seed[6];
size_t utfsize = codepoint2utf8(seed, buf[i]);
if (utfsize == 0)
return -1;
size += utfsize;
if (size >= *outlen - 1)
result = 0;
if (result > 0) {
memcpy(outptr, seed, utfsize);
outptr += utfsize;
}
}
if (tmpptr != NULL) {
// Vulnerable Point
*outptr = '.';
outptr++;
size++;
if (size >= *outlen - 1)
result = 0;
}
}
if (tmpptr == NULL)
break;
inptr = tmpptr + 1;
}
해당 로직을 4가지의 로직으로 나눠볼 수 있습니다.
1. delimiter(.)을 기준으로 문자열 나누기
char *tmpptr = strchr(inptr, '.');
2. 분리된 문자열 내 xn-- 존재 여부 확인
if(strncmp(inptr,"xn--",4)!=0) {
3. 로직에 따라 outptr 변수에 문자열 저장
- xn-- 문자열이 존재하지 않을 경우
size += delta + 1;
if (size >= *outlen - 1)
result = 0;
if (result > 0) {
memcpy(outptr, inptr, delta + 1);
outptr += delta + 1;
}
- xn-- 문자열이 존재하는 경우
size += utfsize;
if (size >= *outlen - 1)
result = 0;
if (result > 0) {
memcpy(outptr, seed, utfsize);
outptr += utfsize;
}
4. xn-- 문자열이 존재할 경우 outptr 변수에 "." 문자 추가 저장
written_out++;
제약 조건 검사 로직에 따르면, 지금까지 복사된 크기를 나타내는 size 값이 outptr의 크기에 해당하는 outlen 값보다 같거나 클 경우 result 값을 0으로 설정하여 이후의 문자열이 복사되지 않도록 하는 로직이 존재하고 있습니다.
그러나 xn-- 문자열이 존재할 경우 outptr 변수에 "."을 추가로 저장하는 로직에서는 result의 값과는 상관없이 outptr에 "."을 추가하고 있어 Stack Buffer over Flow가 발생하였습니다.
다만, 덮어씌울 수 있는 값이 "."(0x2e)로 한정되어 있어 DoS는 가능하나 RCE의 가능성은 낮다고 판단됩니다.
취약점이 패치된 3.0.7 Version에서는 size 값이 outlen 값보다 작을 경우에만 변수에 저장하도록 패치를 진행하였습니다.
int maxsize = *outlen;
#define PUSHC(c) \
do \
if (size++ < maxsize) \
*outptr++ = c; \
else \
result = 0; \
while (0)
PUSHC(tmpptr != NULL ? '.' : '\0');
대응 방안
CVE-2022-3786 취약점은 OpenSSL Version을 3.0.7로 업그레이드 하는 것으로 피해를 방지할 수 있습니다.
'Hack > Network' 카테고리의 다른 글
[CVE-2023-23997] MS Outlook EoP(Elevation of Privilege) 취약점 (0) | 2023.03.17 |
---|---|
[VUE JS] source map 파일을 통한 Frontend 소스 코드 획득 (0) | 2023.02.21 |
[CVE-2022-3602] OpenSSL punycode Decoding Vulnerability (off-by-one) (0) | 2022.11.02 |
11월 1일 Releases 될 OpenSSL 취약점 정보 (0) | 2022.10.30 |
[Netfilter] MITM Tool With netfilter_queue (0) | 2022.08.28 |
댓글