Description

Software vulnerabilities are an inherent challenge in the realm of programming, often lurking in the intricacies of even the most well-developed and established codebases. Recently we discovered an integer underflow bug in the PPMD codec of the 7zip software on Linux. Although a direct attack may seem difficult, this discovery highlights the importance of proper code analysis.

This bug was fixed in 7zip version 23.00. Even though the analysis was performed using Linux other operating systems should be affected in a similar way. All versions prior 23.00 are therefore considered vulnerable.

The discovery of the integer underflow bug, located within the Ppmd7.c file of 7zip, was unveiled through coverage-guided fuzzing. This technique, utilizing the power of the afl++ fuzzer, has become instrumental in efficiently revealing potential vulnerabilities in complex software systems. Within the context of this discovery, the variable numPs, declared as an unsigned integer, appears to trigger an underflow when decremented at line 543 of the codebase.

Technical Details

After subjecting 7zip to extensive fuzzing for nearly a week, varying the settings and input files, the third fuzzing session yielded the discovery of numerous crashes. A total of 26 crashes were unveiled, all stemming from the same underlying bug within the PPMD codec utilized in 7zip.

afl++ fuzzing session 7zip with apfl image

The third (and sucessfull) fuzzing session targeted the 7zip extract function with an apfs image file as the input. I came up with this idea by reading the changelog.

7zip changelog showing an interesting new feature

If you have a mac it is pretty easy to create such a file and throw it into the fuzzer as follows.

afl-fuzz -i afl_in -o afl_out -- ./7zz e @@ 

After applying the afl-tmin tool to minimize the crash files, the following proof of concept (PoC) was derived, capable of triggering the identified crash.

┌──(kali㉿kali)-[~/…/_o/afl_out/default/crashes]
└─$ xxd minimized   
00000000: 377a bcaf 271c 0030 0000 0000 0000 0000  7z..'..0........
00000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000020: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
00000030: 3030 3030 3030 3030 3030 0030 3030 3030  0000000000.00000
00000040: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
00000050: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
00000060: 3030 3030 3030 3030 3030 1706 1a01 0930  0000000000.....0
00000070: 0007 0b01 0001 2303 0401 0500 3030 3030  ......#.....0000
00000080: 0c30 0000                                .0..

You can download the PoC here and trigger the crash on Linux as follows.

./7zz e minimized

When debugging the crash with gdb, we can pinpoint the crash on the assembly level. The following assembly listing shows where the crash happens. We can see that the value 1 is subtracted from the variable DWORD PTR [rbp-0x10],0x1 (This is the variable numPs that we can later see in the source code), followed by an attempt to access the array QWORD PTR [rpb+rax*8-0x240] (This is the variable ps[–numPs] in the source code). Due to the integer underflow the address referenced by the calculation [rbp+rax*8-0x240] is invalid, which results in a segmentation fault.

7zip gdb debugging on assembly level

Assembly listing where the crash happens. In line 848 the value numPs is decremented. The crash happens at line 855 due to an invalid read operation.

Examining the source code within the Ppmd7.c file of 7zip, it can be seen that the variable numPs , is initially set to 0 and undergoes a decrement operation in line 543 (SetSuccessor(ps[--numPs], REF(c1));) of the following source code listing. This results in an underflow of the variable which causes an invalid read operation of the array ps[--numPs].

7zip vulnerable code causing integer overflow

Despite the apparent vulnerability, further research revealed that the bug might not be exploitable in any significant way directly. However, previous investigations have shown that several other software projects have integrated the PPMD codec of 7zip into their codebase. Notably, numerous antivirus providers have incorporated this algorithm into their products to analyze compressed files. These essential software applications rely significantly on the robustness and stability of their scanning mechanisms, as a potential crash could enable attackers to exploit vulnerabilities and bypass antivirus defenses deliberately.

CVE-2023-31102 has been assigned to this vulnerability.

Conclusion

The integer underflow bug found in the 7zip PPMD codec emphasizes the importance of rigorous code examination and continuous software refinement. While the bug may not present an immediate danger, it underscores the potential risks in complex codebases.