欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[翻译]Windows exploit开发系列教程第十五部分:内核利用程序之UAF

[翻译]Windows exploit开发系列教程第十五部分:内核利用程序之UAF

点击查看原文

Windows exploit开发系列教程第十五部分:内核利用程序之UAF

欢迎回到Windows exploit开发系列教程的第十五部分。今天我们来学习基于@HackSysTeam's驱动漏洞的另一种利用姿势。本文我们将写一个UAF(释放后重用)漏洞的exp,这也是首个较为复杂的漏洞课程。我建议读者耐心回顾一下下方列出的资料,它们提供了内核池内存以及保留对象相关知识的易于理解的说明。搭建环境的更多细节请参考本系列教程的第十部分。

侦查挑战

本文的侦查这部分有点不太一样,该UAF漏洞中有相当数量的驱动函数卷入进来。我们会逐一审视,最终酌情提供一些细节。

NTSTATUS AllocateUaFObject() {

    NTSTATUS Status = STATUS_SUCCESS;

    PUSE_AFTER_FREE UseAfterFree = NULL;

    PAGED_CODE();

    __try {

        DbgPrint("[+] Allocating UaF Object\n");

        // Allocate Pool chunk

        UseAfterFree = (PUSE_AFTER_FREE)ExAllocatePoolWithTag(NonPagedPool,

                                                              sizeof(USE_AFTER_FREE),

                                                              (ULONG)POOL_TAG);

        if (!UseAfterFree) {

            // 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(USE_AFTER_FREE));

            DbgPrint("[+] Pool Chunk: 0x%p\n", UseAfterFree);

        }

        // Fill the buffer with ASCII 'A'

        RtlFillMemory((PVOID)UseAfterFree->Buffer, sizeof(UseAfterFree->Buffer), 0x41);

        // Null terminate the char buffer

        UseAfterFree->Buffer[sizeof(UseAfterFree->Buffer) - 1] = '\0';

        // Set the object Callback function

        UseAfterFree->Callback = &UaFObjectCallback;

        // Assign the address of UseAfterFree to a global variable

        g_UseAfterFreeObject = UseAfterFree;

        DbgPrint("[+] UseAfterFree Object: 0x%p\n", UseAfterFree);

        DbgPrint("[+] g_UseAfterFreeObject: 0x%p\n", g_UseAfterFreeObject);

        DbgPrint("[+] UseAfterFree->Callback: 0x%p\n", UseAfterFree->Callback);

    }

    __except (EXCEPTION_EXECUTE_HANDLER) {

        Status = GetExceptionCode();

        DbgPrint("[-] Exception Code: 0x%X\n", Status);

    }

    return Status;

}

函数分配了非分页内存池块,并用'A'字符填充,指派了一个回调函数指针并添加了一个null结束符。IDA中基本一致,下面的截图可以用来参考。注意对象尺寸是0x58字节,池标签为"Hack"(小端)。

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功