
Corruption de mémoire tas OpenSSL-src avec opération de clé privée RSA : CVE-2022-2274
OpenSSL-src-rust est un code source et une logique pour construire OpenSSL à partir des sources, écrit en rust et empaqueté en tant que crate. Il existe actuellement deux branches maintenues, correspondant aux deux versions maintenues d'OpenSSL qui sont main qui construit OpenSSL 3.0 et release/111 qui construit OpenSSL 1.1.1.
La version OpenSSL 3.0.4 a introduit un bogue sérieux dans l'implémentation RSA pour les processeurs X86_64 supportant les instructions AVX512IFMA. Ce problème rend incorrecte l'implémentation RSA avec des clés privées de 2048 bits sur ces machines et une corruption de mémoire se produira lors du calcul. En conséquence de la corruption de mémoire, un attaquant pourrait être en mesure de déclencher une exécution de code à distance sur la machine effectuant le calcul. Les serveurs SSL/TLS ou autres serveurs utilisant des clés privées RSA de 2048 bits fonctionnant sur des machines supportant les instructions AVX512IFMA de l'architecture X86_64 sont affectés par ce problème.
Cette vulnérabilité a fait échouer et planter la construction d'OpenSSL version 3.0 en utilisant openssl-src-rust sur la machine supportant les instructions AVX512IFMA de l'architecture X86_64.
openssl-src(Rust)
>= 300.0.8, < 300.0.9
(GHSA-735f-pg76-fxc4)Les procédures pour reproduire l'erreur ou le plantage sont les suivantes :
Construire OpenSSL-3.0.4 sur un processeur AVX512 (cette démonstration utilise un Core i7-1065G7) avec :
CFLAGS="-O3 -g -fsanitize=address" ./config
make
Exécuter un test :
make V=1 TESTS=test_exp test
Le sanitizer se plaint :
==481618==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60c000089400 at pc 0x7f01e32a9509 bp 0x7fff643ec100 sp 0x7fff643ec0f8
READ of size 8 at 0x60c000089400 thread T0
#0 0x7f01e32a9508 in bn_select_words crypto/bn/rsaz_exp.h:64
#1 0x7f01e32a9508 in bn_reduce_once_in_place crypto/bn/rsaz_exp.h:74
#2 0x7f01e32a9508 in ossl_rsaz_mod_exp_avx512_x2 crypto/bn/rsaz_exp_x2.c:223
#3 0x7f01e3287dc8 in BN_mod_exp_mont_consttime_x2 crypto/bn/bn_exp.c:1448
#4 0x4042c3 in test_mod_exp_x2 test/exptest.c:260
#5 0x40611a in run_tests test/testutil/driver.c:370
#6 0x4039ba in main test/testutil/main.c:30
#7 0x7f01e2c29319 in __libc_start_call_main (/usr/lib/libc.so.6+0x29319)
#8 0x7f01e2c293e4 in __libc_start_main_impl (/usr/lib/libc.so.6+0x293e4)
#9 0x403c40 in _start (/home/xry111/sources/lfs/openssl-3.0.4/test/exptest+0x403c40)
0x60c000089400 is located 0 bytes to the right of 128-byte region [0x60c000089380,0x60c000089400)
allocated by thread T0 here:
#0 0x7f01e3ae5107 in __interceptor_malloc ../../../../libsanitizer/asan/asan_malloc_linux.cpp:69
#1 0x7f01e34aa7a8 in CRYPTO_zalloc crypto/mem.c:197
SUMMARY: AddressSanitizer: heap-buffer-overflow crypto/bn/rsaz_exp.h:64 in bn_select_words
Shadow bytes around the buggy address:
0x0c1880009230: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa
0x0c1880009240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c1880009250: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
0x0c1880009260: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa
0x0c1880009270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c1880009280:[fa]fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
0x0c1880009290: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa
0x0c18800092a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c18800092b0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
0x0c18800092c0: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa
0x0c18800092d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==481618==ABORTING
Il a été proposé par le découvreur du problème que des commits précédents dans le code OpenSSL auraient pu introduire le bogue. Le commit visait à corriger BN_mod_exp_consttime pour qu'il ne produise pas de résultat non réduit. La fonction bn_reduce_once_in_place a provoqué la corruption de mémoire tas.
@@ -220,6 +220,9 @@ int ossl_rsaz_mod_exp_avx512_x2(BN_ULONG *res1,
from_words52(res1, factor_size, rr1_red);
from_words52(res2, factor_size, rr2_red);
bn_reduce_once_in_place(res1, /*carry=*/0, m1, storage, factor_size);
bn_reduce_once_in_place(res2, /*carry=*/0, m2, storage, factor_size);
Ceci a été corrigé avec une mise à jour trouvée dans ce commit qui indiquait que bn_reduce_once_in_place attend le nombre de BN_ULONG, mais factor_size est la taille en bits des modules. Cette mise à jour a été incluse dans OpenSSL 3.0.5 publié le 12 octobre 2022.
@@ -257,6 +257,9 @@ int ossl_rsaz_mod_exp_avx512_x2(BN_ULONG *res1,
from_words52(res1, factor_size, rr1_red);
from_words52(res2, factor_size, rr2_red);
/* bn_reduce_once_in_place expects number of BN_ULONG, not bit size */
factor_size /= sizeof(BN_ULONG) * 8;
bn_reduce_once_in_place(res1, /*carry=*/0, m1, storage, factor_size);
bn_reduce_once_in_place(res2, /*carry=*/0, m2, storage, factor_size);
Un attaquant pourrait théoriquement exploiter cette vulnérabilité en envoyant une transmission sur un réseau (par exemple, un réseau TCP/IP). Une exploitation réussie pourrait entraîner :
| Gravité | Critique 9.8 / 10 |
|---|
| Vecteur d'attaque | Réseau |
| Complexité d'attaque | Faible |
| Privilèges requis | Aucun |
| Interaction utilisateur | Aucun |
| Portée | Inchangée |
| Confidentialité | Élevée |
| Intégrité | Élevée |
| Disponibilité | Élevée |