首页
社区
课程
招聘
[原创]HEVD内核漏洞学习(3)类型混淆
发表于: 2020-10-28 10:49 6300

[原创]HEVD内核漏洞学习(3)类型混淆

2020-10-28 10:49
6300

第三部分讲type confusion(类型混淆)漏洞 这是之前没有接触过的类型的漏洞

它的定义是 当一段代码没有验证对象类型时 并在没有进行类型检查的情况下盲目使用它 进而导致type confusion 导致表达的类型作为一片内存区域 此时将我们的函数指针或数据放入内存之中 就会导致代码执行

TriggerTypeConfusion
函数使用了UNION 然后在没有设置回调对象的情况下 就给Status赋值 导致直接使用ObjectType的值 而ObjectType指向恶意代码时就可以利用

我们对以下函数下断点

运行到图中处 然后查看KernelTypeConfusionObject结构体的内容 其中第二项即为ObjectType的地址 也就是我们shellcode的地址

对于类型混淆的话需要进一步了解的 看这里

这次用的官方的exp 这里顺带说一下 我用本机的vs2019编译的 在编译前更改了这些 好像也不用改 但我还是改了qaq


其实这里exp的话 自己写好些 wjllz师傅就是自己写的 我这边环境还是什么问题就无法提权 也没想纠结太长时间

成功利用

前面已经说的很清楚了 在安全版本中 已经正确的设置了回调指针 导致无法控制

这算是第一次接触到类型混淆漏洞吧 其实这个例子讲的很简明 所以很好利用

NTSTATUS
TriggerTypeConfusion(
    _In_ PUSER_TYPE_CONFUSION_OBJECT UserTypeConfusionObject
)
{
    NTSTATUS Status = STATUS_UNSUCCESSFUL;
    PKERNEL_TYPE_CONFUSION_OBJECT KernelTypeConfusionObject = NULL;
 
    PAGED_CODE();
 
    __try
    {
        //
        // Verify if the buffer resides in user mode
        //
 
        ProbeForRead(
            UserTypeConfusionObject,
            sizeof(USER_TYPE_CONFUSION_OBJECT),
            (ULONG)__alignof(UCHAR)
        );
 
        //
        // Allocate Pool chunk
        //
 
        KernelTypeConfusionObject = (PKERNEL_TYPE_CONFUSION_OBJECT)ExAllocatePoolWithTag(
            NonPagedPool,
            sizeof(KERNEL_TYPE_CONFUSION_OBJECT),
            (ULONG)POOL_TAG
        );
 
        if (!KernelTypeConfusionObject)
        {
            //
            // Unable to allocate Pool chunk
            //
 
            DbgPrint("[-] Unable to allocate Pool chunk\n");
 
            Status = STATUS_NO_MEMORY;
            return Status;
        }
        else
        {
            DbgPrint("[+] Pool Tag: %s\n", STRINGIFY(POOL_TAG));
            DbgPrint("[+] Pool Type: %s\n", STRINGIFY(NonPagedPool));
            DbgPrint("[+] Pool Size: 0x%X\n", sizeof(KERNEL_TYPE_CONFUSION_OBJECT));
            DbgPrint("[+] Pool Chunk: 0x%p\n", KernelTypeConfusionObject);
        }
 
        DbgPrint("[+] UserTypeConfusionObject: 0x%p\n", UserTypeConfusionObject);
        DbgPrint("[+] KernelTypeConfusionObject: 0x%p\n", KernelTypeConfusionObject);
        DbgPrint("[+] KernelTypeConfusionObject Size: 0x%X\n", sizeof(KERNEL_TYPE_CONFUSION_OBJECT));
 
        KernelTypeConfusionObject->ObjectID = UserTypeConfusionObject->ObjectID;
        KernelTypeConfusionObject->ObjectType = UserTypeConfusionObject->ObjectType;
 
        DbgPrint("[+] KernelTypeConfusionObject->ObjectID: 0x%p\n", KernelTypeConfusionObject->ObjectID);
        DbgPrint("[+] KernelTypeConfusionObject->ObjectType: 0x%p\n", KernelTypeConfusionObject->ObjectType);
 
 
#ifdef SECURE
        //
        // Secure Note: This is secure because the developer is properly setting 'Callback'
        // member of the 'KERNEL_TYPE_CONFUSION_OBJECT' structure before passing the pointer
        // of 'KernelTypeConfusionObject' to 'TypeConfusionObjectInitializer()' function as
        // parameter
        //
 
        KernelTypeConfusionObject->Callback = &TypeConfusionObjectCallback;
        Status = TypeConfusionObjectInitializer(KernelTypeConfusionObject);
#else
        DbgPrint("[+] Triggering Type Confusion\n");
 
        //
        // Vulnerability Note: This is a vanilla Type Confusion vulnerability due to improper
        // use of the 'UNION' construct. The developer has not set the 'Callback' member of
        // the 'KERNEL_TYPE_CONFUSION_OBJECT' structure before passing the pointer of
        // 'KernelTypeConfusionObject' to 'TypeConfusionObjectInitializer()' function as
        // parameter
        //
 
        Status = TypeConfusionObjectInitializer(KernelTypeConfusionObject);                //漏洞点
#endif
 
        DbgPrint("[+] Freeing KernelTypeConfusionObject Object\n");
        DbgPrint("[+] Pool Tag: %s\n", STRINGIFY(POOL_TAG));
        DbgPrint("[+] Pool Chunk: 0x%p\n", KernelTypeConfusionObject);
 
        //
        // Free the allocated Pool chunk
        //
 
        ExFreePoolWithTag((PVOID)KernelTypeConfusionObject, (ULONG)POOL_TAG);
        KernelTypeConfusionObject = NULL;
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        Status = GetExceptionCode();
        DbgPrint("[-] Exception Code: 0x%X\n", Status);
    }
 
    return Status;
}
NTSTATUS
TriggerTypeConfusion(
    _In_ PUSER_TYPE_CONFUSION_OBJECT UserTypeConfusionObject
)
{
    NTSTATUS Status = STATUS_UNSUCCESSFUL;
    PKERNEL_TYPE_CONFUSION_OBJECT KernelTypeConfusionObject = NULL;
 
    PAGED_CODE();
 
    __try
    {
        //
        // Verify if the buffer resides in user mode
        //
 
        ProbeForRead(
            UserTypeConfusionObject,
            sizeof(USER_TYPE_CONFUSION_OBJECT),
            (ULONG)__alignof(UCHAR)
        );
 
        //
        // Allocate Pool chunk
        //
 
        KernelTypeConfusionObject = (PKERNEL_TYPE_CONFUSION_OBJECT)ExAllocatePoolWithTag(
            NonPagedPool,
            sizeof(KERNEL_TYPE_CONFUSION_OBJECT),
            (ULONG)POOL_TAG
        );
 
        if (!KernelTypeConfusionObject)
        {
            //
            // Unable to allocate Pool chunk
            //
 
            DbgPrint("[-] Unable to allocate Pool chunk\n");
 
            Status = STATUS_NO_MEMORY;
            return Status;
        }
        else
        {
            DbgPrint("[+] Pool Tag: %s\n", STRINGIFY(POOL_TAG));
            DbgPrint("[+] Pool Type: %s\n", STRINGIFY(NonPagedPool));
            DbgPrint("[+] Pool Size: 0x%X\n", sizeof(KERNEL_TYPE_CONFUSION_OBJECT));
            DbgPrint("[+] Pool Chunk: 0x%p\n", KernelTypeConfusionObject);
        }
 
        DbgPrint("[+] UserTypeConfusionObject: 0x%p\n", UserTypeConfusionObject);
        DbgPrint("[+] KernelTypeConfusionObject: 0x%p\n", KernelTypeConfusionObject);
        DbgPrint("[+] KernelTypeConfusionObject Size: 0x%X\n", sizeof(KERNEL_TYPE_CONFUSION_OBJECT));
 
        KernelTypeConfusionObject->ObjectID = UserTypeConfusionObject->ObjectID;
        KernelTypeConfusionObject->ObjectType = UserTypeConfusionObject->ObjectType;
 
        DbgPrint("[+] KernelTypeConfusionObject->ObjectID: 0x%p\n", KernelTypeConfusionObject->ObjectID);
        DbgPrint("[+] KernelTypeConfusionObject->ObjectType: 0x%p\n", KernelTypeConfusionObject->ObjectType);
 
 
#ifdef SECURE
        //
        // Secure Note: This is secure because the developer is properly setting 'Callback'
        // member of the 'KERNEL_TYPE_CONFUSION_OBJECT' structure before passing the pointer
        // of 'KernelTypeConfusionObject' to 'TypeConfusionObjectInitializer()' function as
        // parameter
        //
 
        KernelTypeConfusionObject->Callback = &TypeConfusionObjectCallback;
        Status = TypeConfusionObjectInitializer(KernelTypeConfusionObject);
#else
        DbgPrint("[+] Triggering Type Confusion\n");
 
        //
        // Vulnerability Note: This is a vanilla Type Confusion vulnerability due to improper
        // use of the 'UNION' construct. The developer has not set the 'Callback' member of
        // the 'KERNEL_TYPE_CONFUSION_OBJECT' structure before passing the pointer of
        // 'KernelTypeConfusionObject' to 'TypeConfusionObjectInitializer()' function as
        // parameter
        //
 
        Status = TypeConfusionObjectInitializer(KernelTypeConfusionObject);                //漏洞点
#endif
 
        DbgPrint("[+] Freeing KernelTypeConfusionObject Object\n");
        DbgPrint("[+] Pool Tag: %s\n", STRINGIFY(POOL_TAG));
        DbgPrint("[+] Pool Chunk: 0x%p\n", KernelTypeConfusionObject);
 
        //
        // Free the allocated Pool chunk
        //
 
        ExFreePoolWithTag((PVOID)KernelTypeConfusionObject, (ULONG)POOL_TAG);
        KernelTypeConfusionObject = NULL;
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        Status = GetExceptionCode();
        DbgPrint("[-] Exception Code: 0x%X\n", Status);
    }
 
    return Status;
}
typedef struct _KERNEL_TYPE_CONFUSION_OBJECT
{
    ULONG_PTR ObjectID;
    union
    {
        ULONG_PTR ObjectType;//控制该对象即可 控制为payload地址
        FunctionPointer Callback;
    };
} KERNEL_TYPE_CONFUSION_OBJECT, *PKERNEL_TYPE_CONFUSION_OBJECT;
typedef struct _KERNEL_TYPE_CONFUSION_OBJECT
{
    ULONG_PTR ObjectID;
    union

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2020-10-28 13:43 被Ring3编辑 ,原因:
收藏
免费 1
支持
分享
最新回复 (1)
雪    币: 7
活跃值: (4331)
能力值: ( LV9,RANK:270 )
在线值:
发帖
回帖
粉丝
2
6
2020-10-28 12:37
0
游客
登录 | 注册 方可回帖
返回
//