In early June I’ve reported several security vulnerabilities in Nullsoft’s flagship product WinAmp to the devs. I received an amazing fast answer from the WinAmp Team acknowledging all reported security vulnerabilities. Only 5 days later I’ve received a private build including fixes for nearly all reported issues. Except one, but after sending a second exploit – poc the last issue has been fixed quickly too. All in all – and among all my already discovered and reported security flaws, the coordination process with Nullsoft was the most transparent and security-addicted, I ever had to deal with.
By the way…I gave them a tough timeframe of 14 days for a reliable security update (Google-Style baby 😀 ), which is very minimalistic compared to the code basis! At first this was only meant to test if a big vendor is able to hold such a timeline. And they did! They even produced it much faster to my surprise. Other vendors should start to take a leaf out of their work! Great job guys :-)!
Now the technical facts:
The first advisory [CVE-2013-4694] consolidates and describes multiple buffer overflow conditions in different libraries of WinAmp. But both mentioned bugs are completely different and one of them is a lot more heavily weighted than the other.
The first bug in CVE-2013-4694 is “remotely” exploitable – CVSSv2 score of 7,5 (AV:N/AC:L/Au:N/C:P/I:P/A:P)! But how and where to be careful ?
The application loads the directories in %PROGRAMFILES%\WinAmp\Skins on startup to determine the skins that have been installed and to list them in the application menu point "Skins" and in the Skins Browser. But the application does not properly validate the length of the directory name before passing it as argument to a lstrcpynW call in the library gen_jumpex.dll, which leads to a buffer overflow condition with possible code execution.
That’s all about it. A bad guy can send his victim a package containing an oversized directory name as the skin-name:
Finally…the applications uses a lstrcpynW (yep, it’s unicode based) call to basically work with the skin directory name to identify it in the folder – structure of WinAmp. Read this MS article to find out why this function could lead to the dangerous behaviour:
The application calls the vulnerable function @
.text:1001A5C0 call ds:lstrcpynW
which fills up the stack and finally RETs into the overwritten part of the stack:
.text:1001A5E9 leave .text:1001A5EA retn
…and that means control over EIP! But it’s a unicode based overflow with a limited scope of exploitation due to the nature of a unicode overflow…unless…someone finds a way to spray the heap or something like this 😉
The second bug isn’t as interesting as the first one, since it’s issued by entering an oversized string into one of the gui fields, which is a very unrealistic attack scenario…only interesting in sandbox-like environments or if the payload can be hidden using readable chars 😉
The second advisory [CVE-2013-4695] is a more complex vulnerability since it’s not a classic overflow scenario. It’s an invalid pointer dereference issue, which basically means that the attacker gets control over a specific part of a buffer which itself does not lead to any kind of code execution. But during the application flaw a pointer is called which dereferences a part of the controllable memory space…and THAT leads to real pwnage 😉
The application loads the contents of the %APPDATA%\WinAmp\links.xml on startup (the key lngId="default") and while browsing through the bookmarks in the Browser view of the GUI, but does not properly validate the length of the string loaded from the "" and "" keys before using them in a pointer call in the library gen_ff.dll, which leads to a invalid pointer dereference condition with possible code execution.
Also a complicated attack scenario, because the attacker has to copy an arbitrary links.xml somehow to the %appdata%\WinAmp directory. But after that, it’s quite easily to exploit. Some clicks here, some clicks there:
…and the application crashes. Deciphered:
The attacker has unicode control over ECX (00430043)! The content of ECX (more specific: the first 4 bytes “FF 30 51 E8”) are copied to EAX:
.text:073D0ED3 mov eax, [ecx]
and EAX (now contains “E8 51 30 FF” due to little endian) is pointer-called afterwards:
.text:073D0EE1 call dword ptr [eax]
…leading to code execution. Another happy hacking-day :-)!