Renowned bug hunter Tavis Ormandy from Google’s Project Zero team recently found a Critical security flaw In Mozilla’s encryption code.
Many software vendors rely on third-party open source encryption tools, such as OpenSSL, Or simply connect to the encryption libraries built into the operating system itself, such as Microsoft’s Secure channel (Schannel) on Windows or Apple Secure transport On macOS and iOS.
But Mozilla has always used it Its own cryptographic library, Known as NSS, Short for Network security services, Instead of relying on third-party or system-level code.
Ironically, this bug is exposed when affected applications go out to test the encryption authenticity of digital signatures provided by content senders such as emails, PDF documents or web pages.
In other words, the very protection of you, by pre-checking if a user or site you are dealing with is impersonating …
… can, in theory, lead to hacking by the user or site.
As Ormandi shows in his bug report, it’s trivial to crash an app by exploiting this bug, and it’s no harder to do what might be called a “controlled crash”, which can usually be complicated into RCE, short for Remote code execution.
The vulnerability is officially known as CVE-2021-43527, But Ormandi laughed at him BigSig, Because it involves a buffer overflow triggered by sending a digitally signed signature in a cryptographic key that is larger than the largest key that NSS is programmed to expect.
Reservoir overflow
Database browsing is enabled when a memory area that has only room for X bytes is accidentally filled in Y bytes of data, when Y> X.
Those “overflow” houses (YX) usually end up replacing a nearby block of memory that is already in use for something else, like an abundance of guests who do not behave badly at a hotel room party that eventually spill out into the hallway, burst into adjoining rooms, and generally Make themselves a nuisance.
Typically, this type of memory corruption causes the vulnerable app to deviate from its path to an unknown and unknown memory area where the operating system has no choice but to turn it off immediately, causing a simple crash.
But in RCE, attackers orchestrate the crash in such a way that they incorrectly route the app to the code they provided themselves.
RCE is like celebrating a rogue hotel that not only bursts into your room and creates a disturbance that wakes you up, but also intentionally exploits your temporary confusion by stealing your laptop and wallet under the guise of pretending to apologize while you chase them out.
The bad news is that any app that uses the NSS library may be affected by this bug, including most Mozilla apps and some other popular open source programs.
Mozilla explicitly lists the following as affected:
- Thunderbird, Mozilla’s own email client.
- LibreOffice, A popular free alternative to Microsoft Office.
- evolution, An open source calendar app.
- Evince, Displays popular multi-format documents for PDFs and images.
The good news, if you want to think about it this way, is this bug Cannot run in Firefox, So Mozilla’s popular browser is unaffected.
Of course, there are many other apps that are also vulnerable – for example, we are not sure if the apps are still active Sea Monkey The project, which is basically a Firefox-like browser and a Thunderbird-like email client packaged in a single app, is at risk.
What happened?
The bug stems from the code that made the assumption infamous, and often so dangerous “It’s so unlikely it’s almost certain it’s never going to happen, so it’s never going to happen, so there’s no need to check if it did.”.
When digitally signing authentication, NSS allocates a chunk of memory to store all data relevant to the calculations, including the public key and encryption required for authentication.
The space reserved for the public key is selected by calculating the size of the largest possible DSA key supported by NSS, the largest possible elliptical curve (EC) key supported by NSS, and the largest RSA key, and then using the largest of these Values to ensure a reservoir that is “always large enough”.
RSA keys are far more notorious than those of other cryptographic algorithms (this is one of the reasons why EC cryptography takes over RSA), usually reaching 2048 or even 4096 bits, instead of the 256 or 512 bits usually required for EC keys.
But RSA keys larger than 4096 bits are remarkably rare, not only because they will be much larger than they need to resist today’s cracking tools, but also because they are much slower to create and use than smaller keys, even on fast computers.
We have never seen, or even heard of, 16384-bit RSA keys used in real life, given that they are typically between 500 and 1000 slow to produce 2048-bit keys, which are still considered today to be commonly accepted for attack resistance.
Indeed, the public key pool allocated for NSS signature verification is 16384 bits long, a size that should be more than enough for many years …
… and the code that copies a public key into this repository therefore assumes that no one will bother creating a larger RSA key, so it does not interfere with checking that the key just received is indeed appropriate.
Fixing the bug was adding the size check code that should have been there all along.
What to do?
- NSS update. Many Linux distributions will have a central copy of the NSS library, but some of the installed applications may include and use their own versions of the library. You can search for the file
libnss3.so
To find how many NSS instances there are on your computer. Windows applications that use NSS will typically have their own versions; Look forNSS3.DLL
. You need version 3.73 or later, or ES6 3.68.1 if you are using the Extended Support Edition. For advice on how to locate NSS library files on your computer and how to check which version you have, see below. - Never skimp on error checking. The fact that most people do not generate huge cryptographic keys does not mean that no one will do it, whether they do it by mistake (which in this case will cause a denial of service attack by crashing your app) or by formatting (in order to hack into your computer intentionally).
Tips for finding and releasing NSS files
In Linux, you can search for copies of NSS library code with the find
command. The output from our system is shown as an example.
We have Firefox, Tor and LibreOffice installed, so we conclude from this output that Firefox and Tor have their own copies of the NSS library, while LibreOffice relies on the one provided by our distribution /usr/lib64
:
$ find / -type f -name 'libnss3.so' 2>/dev/null /usr/lib64/libnss3.so /opt/firefox/libnss3.so /opt/tor-browser_en-US/Browser/libnss3.so
In Windows, try the DIR
The command shown below, from a standard command line window (i.e. executable) CMD.EXE
, Not PowerShell).
We installed Firefox and LibreOffice, both of which contain their own copy of the NSS3 library file, so they will need to update using their download sources. Keep in mind that Firefox is not affected by this bug, but LibreOffice is.
C:Usersduck> DIR C:NSS3.DLL /S [. . .] Directory of c:Program FilesLibreOfficeprogram 19/11/2021 11:18 1,089,680 nss3.dll 1 File(s) 1,089,680 bytes Directory of c:Program FilesMozilla Firefox 19/11/2021 15:31 2,186,168 nss3.dll 1 File(s) 2,186,168 bytes Total Files Listed: 2 File(s) 3,275,848 bytes [. . .]
Identifying the internal version numbers of the NSS files that appear in a tour search can be tricky, given that the only reliable way to do this is to load the library and ask it to report itself.
On Linux
The code below worked for us in Linux. Save approx nsschk.c
, Compilation with gcc -o nsschk nsschk.c -ldl
, And run ./nsschk
With the NSS directory file that you want to check at the command prompt:
#include <stdio.h> #include <stdlib.h> #include <dlfcn.h> void bail(char *msg) { fprintf(stderr,"%sn",msg); exit(1); } int main(int argc, char **argv) { /* Use the command argument as the NSS library name, */ /* otherwise pick a sensible default for your distro. */ char *libname = argc>1 ? argv[1] : "/usr/lib64/libnss3.so"; printf("Using library file: %sn",libname); void *nsslib = dlopen(libname,RTLD_LAZY); if (nsslib == NULL) { bail("Can't dlopen() that file"); } int (*initfn)(char *dir) = dlsym(nsslib,"NSS_NoDB_Init"); char *(*getvfn)(void) = dlsym(nsslib,"NSS_GetVersion"); if (initfn == NULL) { bail("Can't find NSS_NoDB_Init function"); } if (getvfn == NULL) { bail("Can't find NSS_GetVersion function"); } if ((*initfn)(".") != 0) { bail("Failed to initialise NSS"); } printf("NSS Version: %sn",(*getvfn)()); return 0; }
Our NSS files (see above) appeared as follows:
$ ./nsschk Using library file: /usr/lib64/libnss3.so NSS Version: 3.73 $ ./nsschk /opt/firefox/libnss3.so Using library file: /opt/firefox/libnss3.so NSS Version: 3.71 $ ./nsschk /opt/tor-browser_en-US/Browser/libnss3.so Using library file: /opt/tor-browser_en-US/Browser/libnss3.so NSS Version: 3.68
The version managed in the distro, as it is used by the vulnerable LibreOffice, is up to date. Firefox and Tor will probably be updated soon by Mozilla and Tor Project respectively, but since both are probably immune to this bug, we see them for sure.
In macOS
On a Mac, you can use the same code, but you will need to explicitly tell macOS which directory to use for NSS directory files, or change the current directory to the location of libnss3
First file. Also, look for both libnss3.so
and libnss3.dylib
, Because both extensions are used in building macOS.
On our Mac test, for example, we searched for /Applications
Folder for NSS Libraries:
$ find /Applications -type f -name 'libnss3.*' /Applications/Firefox.app/Contents/MacOS/libnss3.dylib /Applications/LibreOffice.app/Contents/Frameworks/libnss3.dylib /Applications/Thunderbird.app/Contents/MacOS/libnss3.dylib /Applications/TorBrowser.app/Contents/MacOS/libnss3.dylib $ DYLD_LIBRARY_PATH=/Applications/Firefox.app/Contents/MacOS ./nsschk libnss3.dylib Using library file: libnss3.dylib NSS Version: 3.71 $ DYLD_LIBRARY_PATH=/Applications/Thunderbird.app/Contents/MacOS ./nsschk libnss3.dylib Using library file: libnss3.dylib NSS Version: 3.68 $ DYLD_LIBRARY_PATH=/Applications/TorBrowser.app/Contents/MacOS ./nsschk libnss3.dylib Using library file: libnss3.dylib NSS Version: 3.53.1 $ DYLD_LIBRARY_PATH=/Applications/LibreOffice.app/Contents/Frameworks ./nsschk libnss3.dylib Using library file: libnss3.dylib NSS Version: 3.55
In Windows
Some changes created code that worked for us in Windows. To ensure that Windows finds all the additional DLLs that NSS3.DLL
Library needs, change the library to where it is NSS3.DLL
The version is on, and turn on NSSCHK.EXE
The command in this directory.
#include <windows.h> #include <stdio.h> #include <stdlib.h> void bail(char *msg) { fprintf(stderr,"%sn",msg); exit(1); } int main(int argc, char **argv) { /* On Windows, we look for NSS3.DLL in the current */ /* directory only, to help ensure we find its friends */ char *libname = "./NSS3.DLL"; printf("Using library file: %sn",libname); HMODULE nsslib = LoadLibrary(libname); if (nsslib == NULL) { fprintf(stderr,"Error: %dn",GetLastError()); bail("LoadLibrary() failed on that file"); } int (*initfn)(char *dir) = GetProcAddress(nsslib,"NSS_NoDB_Init"); char *(*getvfn)(void) = GetProcAddress(nsslib,"NSS_GetVersion"); if (initfn == NULL) { bail("Can't find NSS_NoDB_Init() function"); } if (getvfn == NULL) { bail("Can't find NSS_GetVersion() function"); } if ((*initfn)(".") != 0) { bail("Failed to initialise NSS"); } printf("NSS Version: %sn",(*getvfn)()); return 0; }
Our results were as follows:
C:Usersduck>cd "Program FilesMozilla Firefox" C:Program FilesMozilla Firefox>UsersduckNSSCHK.EXE Using library file: ./NSS3.DLL NSS Version: 3.71 C:Program FilesMozilla Firefox>cd "Program FilesLibreOfficeprogram" C:Program FilesLibreOfficeprogram>UsersduckNSSCHK.EXE Using library file: ./NSS3.DLL NSS Version: 3.55
We conclude from the above output that LibreOffice in Windows is currently vulnerable (we downloaded the latest version to perform this test), so beware of an update alert and grab the new version as soon as a revised version is available.
Go to options > LibreOffice > Online update Dialog box and click [Check Now] To see if a new version is available.
You can also right-click NSS3.DLL
File in Windows Explorer and select property > Details, But the version string seems to depend on how the app package was constructed, so it may not reveal the true NSS version number.
For example, on our Windows computer, e NSS3.DLL
Delivered as part of the Firefox app marked with top-level Firefox version information; The LibreOffice DLL revealed the NSS-specific version string:
Right: NSS3.DLL properties in LibreOffice build.
>
.