[하루한줄] CVE-2022-0778: OpenSSL 무한 루프 유도를 통한 서비스 거부 공격 취약점
URL
https://github.com/drago-96/CVE-2022-0778
Target
- OpenSSL 1.0.2
- OpenSSL 1.1.1
- OpenSSL 3.0
Explain
OpenSSL에서 공격자가 조작된 인증서를 통해 무한 루프를 발생시켜 서비스 거부를 유도할 수 있는 취약점이 발견되었습니다.
이 취약점은 인증서 파싱시 사용되는 BN_mod_sqrt
함수로 인해 발생하였습니다.
설명에 앞서 a, p에 대하여 $r^2 = a \pmod p$ 를 만족하는 r 을 modular 제곱근이라고 합니다.
BN_mod_sqrt
함수는 Tonelli–Shanks algorithm을 이용해 modular 제곱근을 찾는 함수입니다.
문제가 되는 부분은 $b^{2^i} = 1 \pmod p$ 를 만족하는 i를 찾는 과정에서 발생합니다.
// crypto/bn/bn_sqrt.c L310-L318
while (!BN_is_one(t)) {
i++;
if (i == e) {
ERR_raise(ERR_LIB_BN, BN_R_NOT_A_SQUARE);
goto end;
}
if (!BN_mod_mul(t, t, t, p, ctx))
goto end;
}
알고리즘에 따르면 고정된 e와 증가하는 i에 대해 해당 loop는 i == e
인 시점에 끝나야 합니다.
하지만 특수한 입력값을 주어 i=1, e=1
인 상태로 해당 loop에 진입하도록 유도한다면 무한 loop가 발생하여 서비스 거부가 발생하게 됩니다.
해당 취약점은 i == e
를 종료 조건으로 가지는 for문으로 바꾸는 방법으로 패치되었습니다.
/* Find the smallest i, 0 < i < e, such that b^(2^i) = 1. */
for (i = 1; i < e; i++) {
if (i == 1) {
if (!BN_mod_sqr(t, b, p, ctx))
goto end;
} else {
if (!BN_mod_mul(t, t, t, p, ctx))
goto end;
}
if (BN_is_one(t))
break;
}
/* If not found, a is not a square or p is not prime. */
if (i >= e) {
ERR_raise(ERR_LIB_BN, BN_R_NOT_A_SQUARE);
goto end;
}
Reference
본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.