During our initial analysis of a virtual machine image for the application, we discovered a customized LUKS encryption mechanism meant to hinder reverse engineering of the application.
We were able to recover the LUKS decryption key by leveraging Qemu with dynamic analysis/debugging within GDB we still didn't understand how this decryption mechanism actually worked, as it appeared to be a modified version of LUKS. After performing some reverse engineering, we discovered some modifications made to the GRUB LUKS module that included a custom key-derivation algorithm.
It derived the key to decrypt the LUKS partition based on the LUKS header of the partition being decrypted.
We analyzed this key-derivation algorithm and developed a utility named sonicwall-nsv-decrypter that calculates the decryption key to decrypt a SonicWall NSv partition based on the LUKS file header.
This key can then be used with standard LUKS utilities such as cryptsetup to decrypt and analyze SonicWall NSv partitions containing the core filesystem and application code.
When we attempted this with the SonicWall NSv appliance we observed that the core partitions containing the application code and root filesystem were encrypted with LUKS encryption.
Figure 1 shows the output of the lsblk command when analyzing the virtual hard disk of the appliance which indicates the ROOT, OEM-CONFIG, OEM, and USR-A partitions were all encrypted with LUKS encryption.
Figure 1: An analysis of the virtual hard disk image containing the SonicWall NSv appliance indicated that all of the core partitions containing application code were encrypted using LUKS encryption.
We found the code responsible for LUKS decryption unsurprisingly in GRUB's luks.
Luckily for us, the code performed a check for a unique LUKS macro value, LUKS KEY ENABLED, right before invoking this decryption, which simplified building a binary search pattern for finding the code at runtime.
During our research into this peculiar behavior, we identified a blog post written by a user named CataLpa that describes their method of recovering the LUKS keys to decrypt the partitions of the SonicWall NSv appliance.
At a high level, this method involves running the appliance in Qemu and leveraging GDB to set a breakpoint on the grub crypto pbkdfv2 function that the LUKS module invokes.
At this point we analyzed the disassembly of the luks recover key function and identified the address of the grub crypto pbkdf2 function as being 0xBBE88320.
We placed a breakpoint on the grub crypto pbkdf2 function and then triggered decryption of the LUKS encrypted partitions using the grub recovery shell with the cryptomount command.
Figure 4: We then analyzed the luks recover key function and identified the address of the grub crypto pbkdf2 function at 0xBBE7D162, which moves the address of the grub crypto pbkdf2 function into the rax register.
Figure 6: A recovered LUKS passphrase passed to the grub crypto pbkdf2 function to derive a decryption key to decrypt a LUKS partition used by SonicWall NSv. Analyzing the SonicWall NSv GRUB LUKS Module.
Figure 7: At this point, even though we had recovered the LUKS decryption keys, we were deeply curious as to the origin of the LUKS decryption keys and how they were calculated.
We now understand that the developers had modified the LUKS module to read the LUKS header of the partition it was decrypting and then derive a decryption passphrase.
Figure 12: A custom implementation of the key derivation algorithm that the SonicWall NSv appliance's modified LUKS encryption module used.
Thanks to some overkill reverse engineering, we now have a general solution to decrypt LUKS partitions for all SonicWall NSv appliances that use this custom GRUB module.
This Cyber News was published on securityboulevard.com. Publication date: Tue, 05 Dec 2023 16:13:14 +0000