7z's LZMA compression algorithm with Bitdefender heap buffer overflow vulnerability-vulnerability warning-the black bar safety net

ID MYHACK58:62201788832
Type myhack58
Reporter 佚名
Modified 2017-08-24T00:00:00


Previously, in order to write that article about 7z PPMD compression algorithm vulnerability of the articles, I read a lot of the 7-Zip source code, and found a lot of very valuable information, this information can better help my analysis of anti virus products, vulnerability in it. So, I'm ready to use my hands in the grasp of these information to analyze the Bitdefender 7z module. I previously wrote an article about simplifying the file processing process of the article, and Bitdefender 7z PPMD compression algorithm stack buffer overflow vulnerabilities is also a by removing the detecting mechanism is actually removed is responsible for the detection of related source code to simplify the file processing process is a great example. In addition, this vulnerability also proved that sometimes the existing code, adding new code is a how difficult. In General, however, code changes are always inevitable, even if it is only modifying a small part of that is also need to consider a lot of factors, if considered inadequate, it is likely to affect the program's memory allocation and File Access Management. And herein the description of the vulnerability is a good example, because the program improper use of memory allocation function and further lead to the Bitdefender 7z Module 7-Zip source code causing heap buffer overflow. Vulnerability details analysis When Bitdefender 7z module in a 7z compressed document found a EncodedHeader, it will try to use the LZMA decoder for decompression. The module code seems to be based on 7-Zip source code for development, but Bitdefender's developers to code some changes. Note: EncodedHeader role is in a compressed document that contains more than one file of the plurality of header compression. About the 7z File format more content can be from 7-Zip source package in the DOC/7zFormat. txt get【portal】。 Simple to say, extract the 7z EncodedHeader the implementation process roughly as follows: 1. From 7z EncodedHeader read unpackSize; and 2. Distribution unpackSize number of bytes of data; 3. Use 7-Zip's own LZMA decoder to the C API to decode the stream data; Given below the code snippet shows the assignment of the function call process: 1DD02A845FA lea rcx, [rdi+128h] // 1DD02A84601 mov rbx, [rdi+168h] 1DD02A84608 mov [rsp+128h], rsi 1DD02A84610 mov rsi, [rax+10h] 1DD02A84614 mov [rsp+0E0h], r15 1DD02A8461C mov edx, [rsi] // 1DD02A8461E call SZ_AllocBuffer Everyone can recall the x64 architecture function calling conventions. Actually in this snippet, the first two shaping parameters is by rcx and rdx. SZ_AllocBuffer is Bitdefender 7z module in a function, this function can accept two parameters: The first parameter, the result is a pointer, this pointer points to the stored results of the memory address. The second argument size is the to be allocated memory space size. Next, let's take a look at the code for that function to achieve: 260ED3025D0 SZ_AllocBuffer proc near 260ED3025D0 260ED3025D0 mov [rsp+8], rbx 260ED3025D5 push rdi 260ED3025D6 sub rsp, 20h 260ED3025DA mov rbx, rcx 260ED3025DD mov edi, edx // 260ED3025DF mov rcx, [rcx] 260ED3025E2 test rcx, rcx 260ED3025E5 jz short loc_260ED3025EC 260ED3025E7 call near ptr irrelevant_function 260ED3025EC 260ED3025EC loc_260ED3025EC: 260ED3025EC cmp edi, 0FFFFFFFFh // 260ED3025EF jbe short loc_260ED302606 260ED3025F1 xor ecx, ecx 260ED3025F3 mov [rbx], rcx 260ED3025F6 mov eax, ecx 260ED3025F8 mov [rbx+8], ecx 260ED3025FB mov rbx, [rsp+30h] 260ED302600 add rsp, 20h 260ED302604 pop rdi 260ED302605 retn 260ED302606; ------------------------------------ 260ED302606 260ED302606 loc_260ED302606: 260ED302606 mov rcx, rdi // 260ED302609 call mymalloc //[rest of the function omitted] Please note that one of the mymalloc function, which is a wrapper function, it will eventually call malloc and returns the processing result. Obviously, developers want to SZ_ALLocBuffer a function of the size parameter of size at least 32 bits or more, and this is a 32-bit value. Attentive students may have discovered, the compiler did not succeed in the above code in{*}is the label of the place that is responsible for for comparison parameters for optimization. Taking into account here the comparison of the results also needs to be unsigned comparison jbe, which is very interesting. In SZ_AllocBuffer returns the processing result after the function LzmaDecode will be calling:

LzmaDecode(Byte dest, SizeT destLen, const Byte src, SizeT srcLen, / further arguments omitted /) Note that dest is SZ_AllocBuffer function allocates a buffer, destLen should be a pointer to the buffer size of the pointer. In the reference implementation, SizeT is defined as size_t is. Interestingly, Bitdefender 7z module at the same time use the 32-bit and 64-bit versions of SizeT, and the two versions there is a security vulnerability. I doubt that Bitdefender developers the purpose of this is to give the 32-bit and 64-bit engine provides different functional behavior and design. Next, the LZMA decoder will extract the parameters of the given src data stream, then thedestLen bytes of data written to the dest buffer, in which thedestLen is 7z EncodedHeader in a 64-bit unpackSize, and the end result is a heap buffer overflow vulnerability. To trigger the vulnerability In order to trigger this vulnerability, we created the 7z LZMA data stream containing a we need to write to the heap memory in the data. Next, we built a 7z EncodedHeader(unpackSize size of(1, so should be able to make a function SZ_AllocBuffer assigned a size of one byte of buffer space.

[1] [2] next