欢迎来到 嗅灵易学

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

[翻译]Windows exploit开发系列教程第十三部分:内核利用程序之未初始化栈变量

[翻译]Windows exploit开发系列教程第十三部分:内核利用程序之未初始化栈变量

点击查看原文

Windows exploit开发系列教程第十三部分:内核利用程序之未初始化栈变量

欢迎回到Windows exp开发系列教材的第13部分。今天我们将编写一个基于HEVD有漏洞驱动的未初始化栈变量exp。调试环境的安装请参考第十部分。让我们开始吧!

  • NtMapUserPhysicalPages and Kernel Stack-Spraying Techniques (@j00ru) - here

侦查挑战

简单的看一下有问题的函数(here)。

NTSTATUS TriggerUninitializedStackVariable(IN PVOID UserBuffer) {

    ULONG UserValue = 0;

    ULONG MagicValue = 0xBAD0B0B0;

    NTSTATUS Status = STATUS_SUCCESS;

#ifdef SECURE

    // Secure Note: This is secure because the developer is properly initializing

    // UNINITIALIZED_STACK_VARIABLE to NULL and checks for NULL pointer before calling

    // the callback

    UNINITIALIZED_STACK_VARIABLE UninitializedStackVariable = {0};

#else

    // Vulnerability Note: This is a vanilla Uninitialized Stack Variable vulnerability

    // because the developer is not initializing 'UNINITIALIZED_STACK_VARIABLE' structure

    // before calling the callback when 'MagicValue' does not match 'UserValue'

    UNINITIALIZED_STACK_VARIABLE UninitializedStackVariable;

#endif

    PAGED_CODE();

    __try {

        // Verify if the buffer resides in user mode

        ProbeForRead(UserBuffer,

                     sizeof(UNINITIALIZED_STACK_VARIABLE),

                     (ULONG)__alignof(UNINITIALIZED_STACK_VARIABLE));

        // Get the value from user mode

        UserValue = *(PULONG)UserBuffer;

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

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

        // Validate the magic value

        if (UserValue == MagicValue) {

            UninitializedStackVariable.Value = UserValue;

            UninitializedStackVariable.Callback = &UninitializedStackVariableObjectCallback;

        }

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

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

#ifndef SECURE

        DbgPrint("[+] Triggering Uninitialized Stack Variable Vulnerability\n");

#endif

        // Call the callback function

        if (UninitializedStackVariable.Callback) {

            UninitializedStackVariable.Callback();

        }

    }

    __except (EXCEPTION_EXECUTE_HANDLER) {

        Status = GetExceptionCode();

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

    }

    return Status;

}

如果我们传入一个正确的魔数,它会填充变量以及回调参数。如果传递的值不正确那么就不会填充。这里的问题在于变量定义时并没有设置一个特定的初始值。由于该变量布局在栈上,它会拥有一个前调用函数遗留的随机垃圾值。注意到这样的一个检查(if UninitializedStackVariable.Callback...)毫无卵用并不能阻止其崩溃。

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

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

0 0 0 举报
复制成功