Comodo是一款功能强大的个人防火墙。 Comodo防火墙的NtDeleteFile、NtCreateFile和NtSetThreadContext函数没有正确地验证参数,本地攻击者可能利用此漏洞导致防火墙不可用。 NtDeleteFile只接收了一个参数,也就是指向OBJECT_ATTRIBUTES结构的指针,这些属性会包含ObjectName和SECURITY_DESCRIPTOR。例如,以下是Comodo在NtDeleteFile所设置的钩子: /----------- NTDeleteFile (POBJECT_ATTRIBUTES ObjectAttributes) .text:0001ACB0 push 1Ch .text:0001ACB2 push offset stru_1E3F0 .text:0001ACB7 call __SEH_prolog .text:0001ACBC xor ebx, ebx .text:0001ACBE inc ebx .text:0001ACBF mov [ebp+var_1C], ebx .text:0001ACC2 xor esi, esi .text:0001ACC4 mov [ebp+var_24], esi .text:0001ACC7 mov [ebp+var_20], ebx .text:0001ACCA mov [ebp+var_28], esi .text:0001ACCD mov [ebp+ms_exc.disabled], esi .text:0001ACD0 call ds:ExGetPreviousMode .text:0001ACD6 mov edi, [ebp+ObjectAttributes] - -----------/ 这里执行了很多ProbeForRead检查判断结构指针是否有效(EDI仍有指向OBJECT_ATTRIBUTES结构的指针): /----------- .... .text:0001AD25 push edi ; ObjectAttributes .text:0001AD26 call sub_1A692 ; Here it passes the OBJECT_ATTRIBUTES structure pointer to the next...
Comodo是一款功能强大的个人防火墙。 Comodo防火墙的NtDeleteFile、NtCreateFile和NtSetThreadContext函数没有正确地验证参数,本地攻击者可能利用此漏洞导致防火墙不可用。 NtDeleteFile只接收了一个参数,也就是指向OBJECT_ATTRIBUTES结构的指针,这些属性会包含ObjectName和SECURITY_DESCRIPTOR。例如,以下是Comodo在NtDeleteFile所设置的钩子: /----------- NTDeleteFile (POBJECT_ATTRIBUTES ObjectAttributes) .text:0001ACB0 push 1Ch .text:0001ACB2 push offset stru_1E3F0 .text:0001ACB7 call __SEH_prolog .text:0001ACBC xor ebx, ebx .text:0001ACBE inc ebx .text:0001ACBF mov [ebp+var_1C], ebx .text:0001ACC2 xor esi, esi .text:0001ACC4 mov [ebp+var_24], esi .text:0001ACC7 mov [ebp+var_20], ebx .text:0001ACCA mov [ebp+var_28], esi .text:0001ACCD mov [ebp+ms_exc.disabled], esi .text:0001ACD0 call ds:ExGetPreviousMode .text:0001ACD6 mov edi, [ebp+ObjectAttributes] - -----------/ 这里执行了很多ProbeForRead检查判断结构指针是否有效(EDI仍有指向OBJECT_ATTRIBUTES结构的指针): /----------- .... .text:0001AD25 push edi ; ObjectAttributes .text:0001AD26 call sub_1A692 ; Here it passes the OBJECT_ATTRIBUTES structure pointer to the next function. sub_1A692 .text:0001A692 push 28h .text:0001A694 push offset stru_1E3C0 .text:0001A699 call __SEH_prolog .text:0001A69E xor edi, edi .... .text:0001A6B3 mov [ebp+ms_exc.disabled], edi .text:0001A6B6 push 72747052h ; Tag .text:0001A6BB mov ebx, 400h .text:0001A6C0 push ebx ; NumberOfBytes .text:0001A6C1 push 1 ; PoolType .text:0001A6C3 call ds:ExAllocatePoolWithTag ; Allocates memory to hold the data retrieved by ZwQueryObject .text:0001A6C9 mov esi, eax .text:0001A6CB mov [ebp+var_28], esi .text:0001A6CE cmp esi, edi .text:0001A6D0 jz short loc_1A74F .text:0001A6D2 mov edi, [ebp+ObjectAttributes] .text:0001A6D5 mov eax, [edi+OBJECT_ATTRIBUTES.RootDirectory] ; Here, the code retrieves the RootDirectory\'\'s field value from the structure, controled by us. .text:0001A6D8 test eax, eax .text:0001A6DA jz short loc_1A71B .text:0001A6DC push 0 ; ReturnLength .text:0001A6DE push ebx ; ObjectInformationLength .text:0001A6DF push esi ; ObjectInformation ; buffer where ZwQueryObject will put the object information .text:0001A6E0 push 1 ; ObjectInformationClass ; Specifies an OBJECT_INFORMATION_CLASS value that determines the type ; of information returned in the ObjectInformation buffer. It\'\'s using ; an undocumented type (OBJECT_NAME_INFORMATION) which returns an UNICODE_STRING structure .text:0001A6E2 push eax ; ObjectHandle ; Now, the user-controlled handle \'\'ll be used here to identify the object by ZwQueryObject, .text:0001A6E3 call ds:ZwQueryObject .text:0001A6E9 mov [ebp+var_20], eax .text:0001A6EC test eax, eax .text:0001A6EE jl short loc_1A746 - -----------/ 代码没有正确地验证ZwQueryObject所接收到的数据,攻击者可以通过各种句柄调用函数以获得空结构,导致在代码试图引用Buffer字段时系统出现崩溃。 /----------- .text:0001A6F0 movzx eax, [esi+UNICODE_STRING.Length] .text:0001A6F3 shr eax, 1 .text:0001A6F5 mov ecx, [esi+UNICODE_STRING.Buffer] .text:0001A6F8 movzx eax, word ptr [ecx+eax*2-2] ; Here is the problem .text:0001A6FD mov [ebp+var_30], eax .text:0001A700 cmp ax, 5Ch .text:0001A704 jz short loc_1A725 - -----------/