Add CVE-2026-50295_pre-release/readme.md
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
In the ZtDeviceStartModule() function of ztdns.sys, it calls IoCreateDevice() to create L"\\Device\\ZTDNS" device, and then calls NtSetSecurityObject() to a SecurityDescriptor to this device object. From this, only the members of Administrators, SYSTEM and Dnscache can open it.
|
||||
|
||||
The code snippet and debugging information is as follows.
|
||||
int ZtDeviceStartModule(void)
|
||||
{
|
||||
...
|
||||
DeviceName.Buffer = L"\\Device\\ZTDNS";
|
||||
Status = IoCreateDevice(DriverObject, 0, &DeviceName, 0x12u, 0, 0, &DeviceObject);
|
||||
Status = ObOpenObjectByPointer(DeviceObject, 0x240u, 0i64, 0x2000000u, 0i64, 0, &DeviceHandle);
|
||||
Status = NtSetSecurityObject(DeviceHandle, 4u, &gDeviceSecurityDescriptor);
|
||||
...
|
||||
}
|
||||
|
||||
1: kd> !object \device\ztdns
|
||||
Object: ffff850ad52366b0 Type: (ffff850acc6bfe00) Device
|
||||
ObjectHeader: ffff850ad5236680 (new version)
|
||||
HandleCount: 0 PointerCount: 4
|
||||
|
||||
Directory Object: ffffce0f782288f0 Name: ZTDNS
|
||||
1: kd> !devobj ffff850ad52366b0
|
||||
Device object (ffff850ad52366b0) is for:
|
||||
ZTDNS \Driver\ZTDNS DriverObject ffff850ad49d9b90
|
||||
Current Irp 00000000 RefCount 1 Type 00000012 Flags 00000040
|
||||
SecurityDescriptor ffffce0f8d816560 DevExt 00000000 DevObjExt ffff850ad5236800
|
||||
ExtensionFlags (0000000000)
|
||||
Characteristics (0000000000)
|
||||
Device queue is not busy.
|
||||
1: kd> !sd ffffce0f8d816560 0x1
|
||||
->Revision: 0x1
|
||||
->Sbz1 : 0x0
|
||||
->Control : 0x9004
|
||||
SE_DACL_PRESENT
|
||||
SE_DACL_PROTECTED
|
||||
SE_SELF_RELATIVE
|
||||
->Owner : S-1-5-32-544 (Alias: BUILTIN\Administrators)
|
||||
->Group : S-1-5-18 (Well Known Group: NT AUTHORITY\SYSTEM)
|
||||
->Dacl :
|
||||
->Dacl : ->AclRevision: 0x2
|
||||
->Dacl : ->Sbz1 : 0x0
|
||||
->Dacl : ->AclSize : 0x5c
|
||||
->Dacl : ->AceCount : 0x3
|
||||
->Dacl : ->Sbz2 : 0x0
|
||||
->Dacl : ->Ace[0]: ->AceType: ACCESS_ALLOWED_ACE_TYPE
|
||||
->Dacl : ->Ace[0]: ->AceFlags: 0x0
|
||||
->Dacl : ->Ace[0]: ->AceSize: 0x14
|
||||
->Dacl : ->Ace[0]: ->Mask : 0x001f01ff
|
||||
->Dacl : ->Ace[0]: ->SID: S-1-5-18 (Well Known Group: NT AUTHORITY\SYSTEM)
|
||||
|
||||
->Dacl : ->Ace[1]: ->AceType: ACCESS_ALLOWED_ACE_TYPE
|
||||
->Dacl : ->Ace[1]: ->AceFlags: 0x0
|
||||
->Dacl : ->Ace[1]: ->AceSize: 0x18
|
||||
->Dacl : ->Ace[1]: ->Mask : 0x001f01ff
|
||||
->Dacl : ->Ace[1]: ->SID: S-1-5-32-544 (Alias: BUILTIN\Administrators)
|
||||
|
||||
->Dacl : ->Ace[2]: ->AceType: ACCESS_ALLOWED_ACE_TYPE
|
||||
->Dacl : ->Ace[2]: ->AceFlags: 0x0
|
||||
->Dacl : ->Ace[2]: ->AceSize: 0x28
|
||||
->Dacl : ->Ace[2]: ->Mask : 0x0012019f
|
||||
->Dacl : ->Ace[2]: ->SID: S-1-5-80-859482183-879914841-863379149-1145462774-2388618682 (Well Known Group: NT SERVICE\Dnscache)
|
||||
|
||||
->Sacl : is NULL
|
||||
|
||||
|
||||
|
||||
But it does not specify FILE_DEVICE_SECURE_OPEN characteristic for the parameter DeviceCharacteristics of IoCreateDevice(). So unprivileged users can still use L"\\Device\\ZTDNS\\" or L"\\Device\\ZTDNS\\xxx" to open this device.
|
||||
|
||||
|
||||
|
||||
|
||||
Then sending Ioctl code 12800Bh calls ZtSetGlobalPropertiesFastIo() to set global properties:
|
||||
|
||||
struct _ZT_GLOBAL_PROPERTIES
|
||||
{
|
||||
bool fEnableFilters;
|
||||
bool fPersistFilters;
|
||||
bool fAuditMode;
|
||||
bool fAllowMdns;
|
||||
bool fAllowPlaintextDns;
|
||||
bool fBlockLocalIps;
|
||||
bool fAllowIcsDhcpServer;
|
||||
DWORD dwUnicastLifetime;
|
||||
DWORD MaxRecordAge;
|
||||
};
|
||||
|
||||
BOOLEAN __fastcall ZtSetGlobalPropertiesFastIo(
|
||||
...
|
||||
if ( InputBuffer && InputBufferLength32 == 0x10 && OutputBuffer && OutputBufferLength == 0x10 )
|
||||
{
|
||||
Status = ZtCaptureUserMemory(InputBuffer, 0x10ui64, 4u, PreviousMode, &CapturedProperties);
|
||||
if ( Status >= 0 )
|
||||
{
|
||||
Status = ZtTryProbeAlignment(OutputBuffer, 0x10ui64, PreviousMode);
|
||||
if ( Status >= 0 )
|
||||
{
|
||||
if...
|
||||
g_fEnableFilters = CapturedProperties.fEnableFilters;
|
||||
g_fPersistFilters = CapturedProperties.fPersistFilters;
|
||||
g_fAuditMode = CapturedProperties.fAuditMode;
|
||||
g_fAllowMdns = CapturedProperties.fAllowMdns;
|
||||
g_fBlockLocalIps = CapturedProperties.fBlockLocalIps;
|
||||
g_fAllowIcsDhcpServer = CapturedProperties.fAllowIcsDhcpServer;
|
||||
g_dwUnicastLifetime = CapturedProperties.dwUnicastLifetime;
|
||||
g_MaxRecordAge = CapturedProperties.MaxRecordAge;
|
||||
AllowPlaintextDns = 0;
|
||||
if ( g_fZtdnsSelfhostBranch )
|
||||
LOBYTE(AllowPlaintextDns) = CapturedProperties.fAllowPlaintextDns;
|
||||
*&g_fAllowPlaintextDns = AllowPlaintextDns;
|
||||
Status = ZtWfpConfigureFilters(CapturedProperties.fEnableFilters, Unused, FilterIds, &FilterIds[1]);
|
||||
if ( Status >= 0 )
|
||||
Status = ZtTryCopyUserMemory(OutputBuffer, FilterIds, PreviousMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
For example, setting g_fAuditMode=true can change the mode from Enforcement to Audit, this will permit all outbound connections.
|
||||
|
||||
void __fastcall ZtCalloutConnectClassify(
|
||||
...
|
||||
if ( ZtpAllowConnection(inFixedValues, inMetaValues) || g_fAuditMode )
|
||||
{
|
||||
actionType = 0x1002; // FWP_ACTION_PERMIT
|
||||
}
|
||||
else
|
||||
{
|
||||
actionType = 0x1001; // FWP_ACTION_BLOCK
|
||||
Veto = 1;
|
||||
}
|
||||
classifyOut->actionType = actionType;
|
||||
if ( Veto )
|
||||
classifyOut->rights &= ~1u;
|
||||
...
|
||||
}
|
||||
Reference in New Issue
Block a user