by Tan Chew Keong
Release Date: 2006-07-31
[en] [jp]
Summary
A vulnerability has been found in Lhaplus. When exploited, the vulnerability allows execution of arbitrary code when the user extracts a malicious LZH archive.
Tested Version
Lhaplus version 1.52 (Japanese)
Details
This advisory discloses a buffer overflow vulnerability in Lhaplus. The heap-based buffer overflow occurs when Lhaplus is reading the extended headers from a LZH file. Lhaplus does not validate the value of the "extended header size" read from a LZH file before using it to read extended-header data into a 256-bytes heap buffer. This causes a buffer overflow when the value of "extended header size" is larger than 256. Arbitrary code execution using the vulnerability has been confirmed on Win2K SP4.
In order to exploit this vulnerability successfully, the user must be convinced to extract a malicious LZH file.
The buffer overflow occurs in a function that resembles the following in Lhaplus.exe.
sub_4B64C8()
{
...
...
struct HEADER *lzhHeader;
char *buffer;
char extendedHeaderType;
..
..
..
if(lzhHeader->headerLevel == 0)
{
...
}
else if(lzhHeader->headerLevel == 1)
{
...
}
else if(lzhHeader->headerLevel == 2)
{
readData(handle, 2, &(lzhHeader->fileCRC));
readData(handle, 1, &(lzhHeader->OSID));
...
}
else
{
...
}
if(lzhHeader->headerLevel == 1 || lzhHeader->headerLevel == 2)
{
buffer = allocateMem(0x100); // 256 bytes
// Extended header reading loop
while(true)
{
// Read Extended Header Size from LZH file
bytesread = readData(handle, 2, &(lzhHeader->extendedHeaderSize));
if(lzhHeader->extendedHeaderSize == 0 || bytesread == 0)
break;
readData(handle, 1, &extendedHeaderType);
if(bytesread == 0)
break;
clearMemory(buffer, 0x100);
// NOTE: "lzhHeader->extendedHeaderSize" is read from the LZH file
// and not sanitised.
// This causes a heap-based buffer overflow if the value of the extended
// header size is > 0x100.
// Potential integer underflow can also occur due to the subtraction of 3
// from the extended header size value.
// i.e Must check lzhHeader->extendedHeaderSize > 3 and <= 0x100
bytesread = readData(handle, lzhHeader->extendedHeaderSize - 3, buffer);
...
if(extendedHeaderType == 1)
{
...
}
else if(extendedHeaderType == 2)
{
...
}
}
}
...
}
By overwriting saved pointers on the heap using the buffer overflow, it is possible to execute arbitrary code.
POC / Test Code
The following POC LZH file will exploit the vulnerability in Lhaplus to execute the harmless calculator (calc.exe). The POC has been successfully tested on Japanese Windows 2000 SP4.
Note: Due to the nature of the heap-based buffer overflow. Successful exploit is dependent on the current heap allocation. On certain systems, failed exploit may not crash the software or show any symptom.
Instructions:
- Download and save the lhaplusEXP.lzh POC file in C:\test (Do not change the filename)
- Open c:\test in Explorer.
- Double click on the POC file to extract it using Lhaplus.
- Successful exploit will run calculator (calc.exe). Failed exploit will crash Lhaplus.
Patch / Workaround
Update to version 1.53
Disclosure Timeline
2006-07-26 - Vulnerability Discovered.
2006-07-27 - Initial Vendor Notification.
2006-07-31 - Vendor Released Fixed Version.
2006-07-31 - Public Release.