Information

We have found a critical vulnerability in WinRAR product that leads to Remote Code Execution.
The vulnerability resides in a third party dll name unacev2.dll which responsible on extracting “.ace” archives (ACE format)
The vulnerability allows to a crafted ACE archive file to be extracted to an arbitrary location and ignores the destination folder (Path Traversal),
during the extraction process.
It leads to Remote Code Execution, for example, by extracting an executable to the Startup folder in Windows OS (instead of to the the destination folder).

Background

Each compressed file in an ACE archive contains “filename” field, this field of the ACE format represent the relative path to the decompressed file (after extraction)
WinRAR pass to unacev2.dll 4 pointers to callback function resides in WinRAR code.
These callback function are called by unacev2.dll during the extraction process and the filename field of each compressed file
is passed to this callback.
The return value form the callback functions determines if the specific compressed file is allowed to be extracted or not.
WinRAR callback validates the filename path by checking for “problematic characters” like paths that start with
“/” or “" and also checks for forbidden patterns such as “/../” or other similar attempts for path traversal.
Whenever it finds such patterns it returns a stop status to unacev2.dll (ACE_CALLBACK_RETURN_CANCEL).

In addition to the validator callbacks, unacev2.dll contains its own validators as well.
In the case of path traversal, it simply skips “problematic patterns”. For example, it checks for “c:"
in the begging of the file name.

For example if the name of the file in the ace archive is “c:\some_folder\some_file.txt” and the output directory
is “c:\temp” the extracted file will be written to “c:\temp\some_folder\some_file.txt”.
Note: “c:" was omitted by unacev2.dll.

Bug #1:

unacev2.dll performs file path checks in different locations. Each check however, omits the "problematic patterns" like "C:\"
only once. Meaning that the "new path" (the omitted path) could stay problematic after the check is performed.

For instance, if the file name is "c:\c:\some_folder\some_file.txt" and the output folder is the same "c:\temp" 
the file will be written to "c:\some_folder\some_file.txt" and *UNEXPECTEDLY* the output directory will be ignored. 
It is ignored because of a bug (i.e. bug #2) in unacev2.dll.

Bug #2:

Before creating and/or writing the file, unacev2.dll uses sprintf to concat the output directory to the final
filename (after the skipping process). Here is an example: 
"
sprintf(final_file_name, "%s%s", output_dir, filename);
"
However, before it calls to the sprintf it calls to a validation function named GetDevicePathLen, 
that checks the length of the drive name in the relative path, for example:
-	the function returns 3  ("c:\") for this path: “C:\some_folder\some_file.ext”
-	the function returns 1  ("\") for this path: “\some_folder\some_file.ext”
-	the function returns 15 ("\\LOCALHOST\C$\") for this path: “\\LOCALHOST\C$\some_folder\some_file.ext”
-	the function returns 21 ("\\?\Harddisk0Volume1\") for this path: “\\?\Harddisk0Volume1\some_folder\some_file.ext”
-	the function returns 0  ("") for this path: “some_folder\some_file.ext”

in cases that the return value from GetDevicePathLen is greater than 0, like the above example, 
except the last one, the relative path of the extracted file will be considered as full path, 
because the destination folder is replaced in those cases to an empty string during the call to sprintf, 
and this leads to Path Traversal vulnerability.
the return value from GetDevicePathLen is greater than 0, the sprintf looks like this:
"
sprintf(final_file_path, "%s%s", "", file_relative_path);
"
instead of:
"
sprintf(final_file_path, "%s%s", destination_folder, file_relative_path);
"

This means that the filename field will actually be treated as a fullpath to the file/directory that should be written/created.

Bug #3

When the filename field is c:\\\ip\some_folder\some_file.ext, unacev2.dll will connect to an SMB server at the specified ip address and will create
the file/directory at the specified path. The final path will be \\ip\some_folder\some_file.ext because the first "c:\" will be omitted by unacev2.dll
as explain earlier in bug #1.

PoC


there is a Poc file named poc.rar
upon extraction of the poc.rar via WinRAR, it ignores the destination folder and extracts a file named poc_file.txt to “c:\windows\temp”


Attachments:
poc.rar

References:
https://research.checkpoint.com/extracting-code-execution-from-winrar/
https://www.rarlab.com/rarnew.htm
http://cve.mitre.org/cgi-bin/cvename.cgi?name=2018-20250