首页
社区
课程
招聘
[翻译]RPC Bug挖掘实例研究 - 第一部分
2019-1-31 09:01 9976

[翻译]RPC Bug挖掘实例研究 - 第一部分

2019-1-31 09:01
9976

原文:https://www.fortinet.com/blog/threat-research/the-case-studies-of-microsoft-windows-remote-procedure-call-serv.html

翻译:玉林小学生                   校对:Nxe


        2018年8月,一个网名为SandboxEscaper的研究者公开了一个Windows本地提权0-day。在0-day被公开在网上的几周内,该漏洞的利用工具就被恶意软件作者大量使用。如ESET所说,这件事在InfoSec社区引起了一些混乱。这件事也引起了FortiGuard实验室的注意。

        FortiGuard实验室相信理解这个攻击的原理有助于其它研究者找到与SandboxEscaper发现的Windows Task Scheduler中类似的漏洞。本文我们将介绍找到滥用RPC服务的一个符号链接进行提权的漏洞的方法。

        该漏洞表明Windows Task Scheduler在一个RPC(Remote Procedure Calls) 服务提供的RPC API中有缺陷。事实上,大多数RPC服务由system权限的系统进程提供,准许低权限的RPC客户端与其进行交互。和其它软件一样,这些RPC服务易被拒绝服务、内存破坏和逻辑错误一类的问题影响。也就是说攻击者能够利用RPC服务中存在的脆弱性。

        这个0-day被如此迅速如此大范围利用的一个原因是其基于的攻击点很容易被利用。它由一个程序的逻辑错误引起,使用正确的工具和技术很容易地发现这个问题。这类特殊的提权脆弱性只需一个链接到特权文件或目录的符号链接就可以进行利用,将最终导致一个普通用户进行特权提升。如果感兴趣,Google Project Zero的James Forshaw分享了许多关于符号链接攻击的资源。

RPC服务运行时和静态分析预备知识

        当开始一个新研究时,在动手自己写工具前通常先从scratch找找看是否有可以利用的开源工具。幸运的是,微软RPC是一个著名的协议,研究者在过去许多年间对其进行了大量的逆向研究。研究者开源了一款叫RpcView的工具,这是一个识别Windows操作系统上运行的RPC服务的很好的工具。这是我最爱的RPC工具之一,有许多有用的功能,如:搜索RPC接口全局统一标识符(UUID)、搜索RPC接口名。

        然而,在一个文章中反编译并介绍所有RPC信息与我们的目标无关。幸运的是,通过阅读源代码,我们发现作者已经在工具中包含了我们需要的功能,但默认没有开启且只能通过一个特殊的命令行参数在调试模式下触发。由于这个限制,我们在RpcView GUI开启并修改原来的DecompileAllInterfaces函数。如果你对使用这个功能感兴趣,可以在我们的Github中找到我们订制的RpcView工具。我们现在可以在下一节介绍Decompile All Interfaces (反编译所有接口)功能的好处了。


图一:使用RpcView反编译所有接口功能

        分析一个RPC服务器的行为时,我们通常调用RPC接口导出的API。我们感兴趣的那些与RPC服务器的交互,可以通过利用RPC客户端向服务器发送RPC请求来实现,然后使用SysInternals里的Process Monitor工具来观察行为。我认为,使用脚本比使用C/C++写一个需要编译的RPC客户端更方便,后者很消耗时间。

        我们选择使用PythonForWindows。它以python方式对一些Windows功能提供了抽象,这个功能依赖于python的ctypes。它里面也包含一个RPC库,提供了一些很方便的函数节约了写RPC客户端的时间。例如,一个传统的RPC客户端需要定义接口定义语言,并且需要人工实现绑定操作,这些通常涉及C++代码。看下面的代码列表一和代码列表二,里面列出了使用脚本和以最小的错误处理代码编程实现RPC客户端的不同。

import sys
import ctypes
import windows.rpc
import windows.generated_def as gdef
from windows.rpc import ndr

StorSvc_UUID =  r"BE7F785E-0E3A-4AB7-91DE-7E46E443BE29"
		
class SvcSetStorageSettingsParameters(ndr.NdrParameters):
	MEMBERS = [ndr.NdrShort, ndr.NdrLong, ndr.NdrShort, ndr.NdrLong]
									
def SvcSetStorageSettings():
	print "[+] Connecting...."
	client = windows.rpc.find_alpc_endpoint_and_connect(StorSvc_UUID, (0,0))
	print "[+] Binding...."
	iid = client.bind(StorSvc_UUID, (0,0))
	params = SvcSetStorageSettingsParameters.pack([0, 1, 2, 0x77])
	print "[+] Calling SvcSetStorageSettings"
	result = client.call(iid, 0xb, params)
	if len(str(result)) > 0:
		print "   [*] Call executed successfully!"
		stream = ndr.NdrStream(result)
		res = ndr.NdrLong.unpack(stream)
		if res == 0:
			print "   [*] Success"
		else:
			print "   [*] Failed"
		
if __name__ == "__main__":
	SvcSetStorageSettings()

代码列表1: 使用PythonForWindows的RPC客户端SvcSetStorageSettings

RPC_STATUS CreateBindingHandle(RPC_BINDING_HANDLE *binding_handle)
{
    RPC_STATUS status;
    RPC_BINDING_HANDLE v5;
    RPC_SECURITY_QOS SecurityQOS = {};
    RPC_WSTR StringBinding = nullptr;
    RPC_BINDING_HANDLE Binding;

    StringBinding = 0;
    Binding = 0;
    status = RpcStringBindingComposeW(L"BE7F785E-0E3A-4AB7-91DE-7E46E443BE29", L"ncalrpc", nullptr, nullptr, nullptr, &StringBinding);
    if (status == RPC_S_OK)
    {
        status = RpcBindingFromStringBindingW(StringBinding, &Binding);
        RpcStringFreeW(&StringBinding);
        if (!status)
        {
            SecurityQOS.Version = 1;
            SecurityQOS.ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE;
            SecurityQOS.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;
            SecurityQOS.IdentityTracking = RPC_C_QOS_IDENTITY_STATIC;

            status = RpcBindingSetAuthInfoExW(Binding, 0, 6u, 0xAu, 0, 0, (RPC_SECURITY_QOS*)&SecurityQOS);
            if (!status)
            {
                v5 = Binding;
                Binding = 0;
                *binding_handle = v5;
            }
        }
    }

    if (Binding)
        RpcBindingFree(&Binding);
    return status;
}

VOID RpcSetStorageSettings()
{
    RPC_BINDING_HANDLE handle;
    RPC_STATUS status = CreateBindingHandle(&handle);

    if (status != RPC_S_OK)
    {
        _tprintf(TEXT("[-] Error creating handle %d\n"), status);
        return;
    }

    RpcTryExcept
    {
	if (!SUCCEEDED(SvcSetStorageSettings(0, 1, 2, 0x77))
{
           _tprintf(TEXT("[-] Error calling RPC API\n"));
           return;
        }

    }
    RpcExcept(1)
    {
        
        RpcStringFree(&instanceid);

    }
    RpcEndExcept
}

代码列表2: 使用C++的RPC客户端SvcSetStorageSettings

        RPC客户端成功执行相应的RPC API后,我们使用Process Monitor监控它们行为。Process Monitor对动态分析很有帮助,它提供了基于事件的API运行时信息。需要提一下,Process Monitor有一个很少被人知道的功能,调用栈信息,如图2所示,使用它可以追踪事件的API调用信息。

图2:Process Monitor 的API 调用栈

        例如,在使用类似IDA的反汇编工具进行静态分析时,可以使用这里的地址和路径信息来精确定位对应的模块和函数。这样进行研究很有用,因为有时只使用Process Monitor的输出信息无法确定潜在的符号链接攻击模式。这是基于反汇编的静态分析能帮助我们发现条件竞争问题的原因,在本文第二部分会讨论这个问题。

微软Universal Telemetry Client(UTC)学习

        你听说过微软在Windows10中搜集客户信息、数据和文件访问详细信息么?你有考虑过这是如何实现的么?如果你感兴趣,可以读读这篇关于UTC背后机制的文章。

        开始下一阶段的分析前,我们先从RpcView GUI将所有RPC接口导出到一个文本文件。这个文件中包含所有可以从RPC服务器调用的RPC API。在输出的文件中,我们寻找可以接受宽字符作为输入的API,最终我们在diagtrack.dll中遇到了一个有趣的RPC接口。随后我们从RpcView GUI显示的描述信息中确定了,这个DLL组件负责实现UTC功能,特别是从名称Microsoft Windows Diagnostic Tracking中判断。


图3:RpcView揭示了UTC的DLL组件,并且其中的一个RPC接口接受宽字符作为输入

        记住我们的目标是找到一个API,接收一个文件路径作为输入并最终导致提权,正如Windows Task Scheduler的bug一样。但是满足这个条件的API有16个,如图3所示。显然,我们需要从这些API中过滤掉不感兴趣的。所以我们需要使用IDA进行静态分析以确定进一步分析的API。

我通常先定位到RpcServerRegisterIf函数,它用于在RPC服务器注册一个接口描述。接口描述包含指定RPC服务所拥有的RPC接口的定义。根据MSDN的文档所说,接口描述是该函数的第一个参数,由下面的RPC_SERVER_INTERFACE数据结构表示:

struct _RPC_SERVER_INTERFACE
{
    unsigned int Length;
    RPC_SYNTAX_IDENTIFIER InterfaceId;
    RPC_SYNTAX_IDENTIFIER TransferSyntax;
    PRPC_DISPATCH_TABLE DispatchTable;
    unsigned int RpcProtseqEndpointCount;
    PRPC_PROTSEQ_ENDPOINT RpcProtseqEndpoint;
    void *DefaultManagerEpv;
    const void *InterpreterInfo;
    unsigned int Flags;
};
        接口描述里的InterpreterInfo是一个指向MIDL_SERVER_INFO结构的指针,这个结构由一个DispatchTable指针组成,这个指针包含特定RPC接口所支持的接口API的信息,这里的确是我们要寻找的地方。
typedef struct  _MIDL_SERVER_INFO_
{

    PMIDL_STUB_DESC                     pStubDesc;
    const SERVER_ROUTINE*               DispatchTable;
    PFORMAT_STRING                      ProcString;
    const unsigned short*               FmtStringOffset;
    const STUB_THUNK*                   ThunkTable;
    PRPC_SYNTAX_IDENTIFIER              pTransferSyntax;
    ULONG_PTR                           nCount;
    PMIDL_SYNTAX_INFO                   pSyntaxInfo;
} MIDL_SERVER_INFO, *PMIDL_SERVER_INFO;

图4:在IDA中追踪导入表来判断DispatchTable 的动态图

        我们判定目标是以UtcApi为前缀的UTC接口API之后,如图4所示,我们尝试判断是否这些接口API里的每一个都会调用Access Control List (ACL) API,如SetNamedSecurityInfo和SetSecurityInfo。我们对这些ACL API感兴趣,因为它们用于修改对象的自主访问控制(DACL)安全描述符,无论对于文件、目录还是注册表对象。IDA里的另一个有用的功能是它的proximity视图,它以图形形式呈现一个函数调用图。我们使用proximity视图来寻找被上面提到的ACL API引用或调用的函数。

图5:IDA的Proximity视图显示diagtrack.dll中SetSecurityInfo与其它函数的调用关系

        然而,当我们试图寻找SetSecurityInfo和UtcApi之间的调用关联时,IDA没有产生有用的结果。经过深入分析,我们发现UtcApi将客户端的RPC请求放置到workitem队列中,之后会被异步线程处理。如图5所示,触发Microsoft::Diagnostic::EscalationWorkItem::Execute时将执行SetSecurityInfo。本质上,这是一个负责执行RPC客户端提交的权限提升请求的回调函数。

        从这点上说,我们需要弄明白如何提交一个权限提升请求。在尝试各种应用之后,我们偶然发现了Microsoft Feedback Hub,这是一个Windows默认自带的Universal Windows Platform (UWP)应用。在研究过程中,你会发现调试UWP应用很有用。不幸的是,你不能使用windbg直接打开或附加一个UWP应用。然而,可以通过PLMDebug工具开启UWP应用调试功能,这个工具来自Windows10 SDK调试工具集。你可以先通过Powershell内建cmdlet确定Feedback Hub的完整包家族名:

PS C:\Users\researcher> Get-AppxPackage | Select-String -pattern "Feedback"
Microsoft.WindowsFeedbackHub_1.1809.2971.0_x86__8wekyb3d8bbwe
PS C:\Users\researcher> cd "c:\Program Files\Windows Kits\10\Debuggers\x86"
PS C:\Program Files\Windows Kits\10\Debuggers\x86>
PS C:\Program Files\Windows Kits\10\Debuggers\x86> .\plmdebug.exe /query 
Microsoft.WindowsFeedbackHub_1.1809.2971.0_x86__8wekyb3d8bbwe
Package full name is Microsoft.WindowsFeedbackHub_1.1809.2971.0_x86__8wekyb3d8bbwe.
Package state: Unknown
SUCCEEDED
PS C:\Program Files\Windows Kits\10\Debuggers\x86>

        获得完整包名后,我们再次使用PLMDebug开启Feedback Hub的UWP调试:

c:\Program Files\Windows Kits\10\Debuggers\x86>plmdebug.exe /enabledebug Microsoft.WindowsFeedbackHub_1.1809.2971.0_x86__8wekyb3d8bbwe "c:\program files\windows kits\10\Debuggers\x86\windbg.exe"
Package full name is Microsoft.WindowsFeedbackHub_1.1809.2971.0_x86__8wekyb3d8bbwe.
Enable debug mode
SUCCEEDED

        下一次启动Feedback Hub时,应用将执行并自动附加到WinDbg。

图6:从Process Monitor的事件属性中确定API调用的偏移

        启动Feedback Hub后,我们一步步按照应用在屏幕上的指令向下执行,并开始在Process Monitor中看活动记录。这是一个好信号,这表明我们已经在追踪了。当我们查看图6中高亮的SetSecurityFile事件的调用栈时,在偏移0x15A091(diagtrack.dll的基地址可以在事件属性(Event Properties)的Process标签页找到)处发现了ACL API SetSecurityInfo的返回地址。正如你所看到的,这个偏移属于函数Microsoft::Diagnostics::Utils::FileSystem::SetTokenAclOnFile,如图6中反汇编所示,它也出现在图5的proximity视图中。这证明了我们可以利用Feedback Hub到达我们期望的代码路径。

        而且,Process Monitor的输出还告诉我们这个事件尝试设置文件对象的DACL,但是通过静态分析来找文件对象是如何产生的太耗时了。幸运的是,这个进程没有被Protected Process Light (PPL)机制保护,我们可以对svchost.exe附加一个有管理员权限的本地调试器,这个程序负责托管UTC服务。这就给了我们灵活性,可以通过动态调试UTC服务来了解文件路径产生的过程。

        在表象之下,通过Feedback Hub提交请求之后,所有feedback细节信息和附件将存在名字格式为%DOCUMENTS%\FeedbackHub\<guid>\diagtracktempdir<random_decimals>的临时目录。附加在diagtracktempdir之后的十进制随机数由BCryptGenRandom API产生,这意味着产生的数理论上不可预测。然而符号链接攻击有一个重要的限制,需要有预测文件或目录名的能力,所以diagtracktempdir目录名的随机性增加了符号链接脆弱性利用的困难。因此,我们转到其它过程中寻找其它潜在的问题。

        当我们尝试弄清楚diagtracktempdir的安全描述符如何设置时,我们发现将以固定的安全描述符串O:BAD:P(A;OICI;GA;;;BA)(A;OICI;GA;;;SY)来创建目录,这表明对象的DACL只能被管理员和本地的system用户访问。但是,如果设置了下面的注册表键,安全描述符检查将被忽略:

HKEY_LOCAL_MACHINE\Software\Microsoft\Diagnostics\DiagTaskTestHooks\Volatile
“NoForceCopyOutputDirAcl” = 1

        梳理一下,如果注册表键不存在,diagtracktempdir将被强制执行一个固定的安全描述符,否则将对目录使用默认的DACL并引起潜在的安全问题,并且创建目录时没有使用模拟令牌。也就是,如果你有一个任意注册表写脆弱性,你就可以跳过对该目录设置固定安全描述符。但这不是我们期望的,所以只好再看看Process Monitor:

图7:设置DACL并重命名diagtracktempdir目录

        基本上,我们可以总结图7中的操作如下:

1.         在本地system特权下授权当前登录用户对diagtracktempdir的访问

2.         在模拟令牌下,重命名diagtracktempdir到GUID格式的目录

3.         在模拟令牌下,收回当前登录用户对diagtracktempdir目录的访问权限

        下面的代码片段对于图7所示的操作:

bQueryTokenSuccessful = UMgrQueryUserToken(hContext, v81, &hToken);
if ( hToken && hToken != -1 )
{
//这里将给当前登录用户授权对指定句柄所代表目录的访问
bResultCopyDir = Microsoft::Diagnostics::Utils::FileSystem::SetTokenAclOnFile(&hToken, hDir, Sid, GRANT_ACCESS)
	if ( !ImpersonateLoggedOnUser(hToken) ) 
	{
		bResultCopyDir = 0x80070542;
	}
}
//重命名diagtracktempdir到GUID格式的文件名
bResultCopyDir = Microsoft::Diagnostics::Utils::FileSystem::MoveFileByHandle(SecurityDescriptor, v65, Length);
if ( bResultCopyDir >= 0 )
{
boolRenamedSuccessful = 1;
//这里撤销当前登录用户授权对指定句柄所代表目录的访问
bSetAclSucessful = Microsoft::Diagnostics::Utils::FileSystem::SetTokenAclOnFile(&hToken, hDir, Sid, REVOKE_ACCESS)	if (bSetAclSucessful)
{
    //清理并恢复原样
	return;
}
}
else
{
lambda_efc665df8d0c0615e3786b44aaeabc48_::operator_RevertToSelf(&hTokenUser);
//删除diagtracktempdir目录和内容
lambda_8963aeee26028500c2a1af61363095b9_::operator_RecursiveDelete(&v83);
}

代码列表3:授权然后收回对diagtracktempdir的访问权限

        从代码列表3中,我们能够知道什么情况下文件重命名操作会失败。如果bResultCopyDir小于0,将调用函数RecursiveDelete。还需要注意代码在调用RecursiveDelete之前调用RevertToSelf函数来停止令牌模拟,这意味着参数指定的目标目录和内容将被本地system权限删除,如果我们使用符号链接重定向diagtracktempdir到任意目录将能够进行任意文件删除。幸运的是,微软已经修复了这个潜在的重解析点删除问题。RecursiveDelete函数现在已经修复为明确跳过有FILE_ATTRIBUTE_REPARSE_POINT标志的目录或文件,这个标志是专门为连接点目录设置的。所以我们可以确认这个递归删除过程没有任何安全风险。

        由于我们无法在这里进行任意文件删除,我们决定展示如何写任意文件到diagtracktempdir目录。通过看代码,我们发现在递归删除过程完成后,UTC服务没有收回当前登录用户对diagtracktempdir的安全描述符。这是故意的,因为你不需要为一个将被删除的目录设置一个新的DACL,这是愚蠢的工作。但这也为攻击者留下了一个竞争条件机会,可以通过创建一个在同一目录的文件并占有句柄来阻止删除特权目录diagtracktempdir。RecursiveDelete函数在尝试打开和删除被占有句柄的文件时将遇到共享冲突并退出操作。最终,攻击者能够通过获得权限的diagtracktetempdir目录实现在一个权限受限目录释放并执行文件,如C:\WINDOWS\System32。

        那么下一个问题是,我们如何使得文件重命名操作失败?看看Microsoft::Diagnostics::Utils::FileSystem::MoveFileByHandle的内部实现,它基本就是对SetFileInformationByHandle的封装。这表示这个API调用的底层内核函数将以写权限持有父目录的文件句柄。例如,如果当前句柄引用到目录c:\blah\abc,那么将尝试以写权限获取c:\blah的文件句柄。然而,如果我们指定一个当前登录用户没有写权限的目录,Microsoft::Diagnostics::Utils::FileSystem::MoveFileByHandle将失败。下面的路径是很好地选择,他们是众所周知的特权目录,不准许普通用户创建目录:

  • C:\WINDOWS\System32

  • C:\WINDOWS\tasks

        当一些特权请求涉及写一些日志文件到我们控制的diagtracktempdir并且删除这些日志文件需要耗费一些时间时,赢得条件竞争的胜利应该没有问题。所以,只要我们成功创建一个目标目录内的句柄被占有的文件,就能够在现代系统和多核处理器下赢得竞争。

        接下来,我们需要找到方法通过编程使用UtcApi需要的正确参数来触发代码路径。由于能够调试并在RPC函数设置断点,Feedback Hub里的NdrClientCall使得工作变得简单了。调试器揭露了我们需要发送给UtcApi的scenario ID和提权路径。这种情况下,我们使用scenario ID {1881A45E-01FD-4452-ACE4-4A23666E66E3},它在任何UtcApi_EscalateScenarioAsync函数被触发的时候都出现,并且它导致了RPC服务中我们期望的代码路径。注意,可以通过特权路径参数控制在哪里创建diagtracktempdir。

Breakpoint 0 hit
eax=0c2fe7b8 ebx=032ae620 ecx=0e8be030 edx=00000277 esi=0c2fe780 edi=0c2fe744
eip=66887154 esp=0c2fe728 ebp=0c2fe768 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
Helper+0x37154:
66887154 ff15a8f08866    call    dword ptr [Helper!DllGetActivationFactory+0x6d31 (6688f0a8)] ds:0023:6688f0a8={RPCRT4!NdrClientCall4 (76a74940)}
0:027> dds esp l9
0c2fe728  66892398 Helper!DllGetActivationFactory+0xa021
0c2fe72c  66891dca Helper!DllGetActivationFactory+0x9a53
0c2fe730  0e8be030
0c2fe734  1881a45e // Scenario ID
0c2fe738  445201fd
0c2fe73c  234ae4ac
0c2fe740  e3666e66
0c2fe744  00000000
0c2fe748  032ae620 // Escalation path
0:027> du 032ae620
032ae620  "E:\researcher\Documents\Feedback"
032ae660  "Hub\{e04b7a09-02bd-42e8-a5a8-666"
032ae6a0  "b5102f5de}\{e04b7a09-02bd-42e8-a"
032ae6e0  "5a8-666b5102f5de}"
        最后,UtcApi_EscalateScenarioAsync的原型看起来如下:
long  UtcApi_EscalateScenarioAsync (
		[in] GUID SecnarioID, 
		[in] int16 unknown, 
		[in] wchar_t* wszEscalationPath
		[in] long unknown2, 
		[in] long unknown3, 
		[in] long num_of_keyval_pairs, 
		[in] wchar_t **keys, 
		[in] wchar_t **values) 

        将这些结合起来,我们POC的流程如下:

  • 创建一个无限循环线程监控目标目录,如C:\WINDOWS\SYSTEM32,目的是捕获目录名diagtracktempdir

  • 创建另一个无限循环线程,在创建句柄被占有的文件到C:\WINDOWS\SYSTEM32\diagtracktempdir{random_decimal}\z内
  • 调用UtcApi_EscalateScenarioAsync(1881A45E-01FD-4452-ACE4-4A23666E66E3)来触发Microsoft::Diagnostic::EscalationWorkItem::Execute
  • 如果我们赢得了竞争,C:\WINDOWS\SYSTEM32\diagtracktempdir{random_decimal}\z将被成功创建。

  • 之后,攻击者可以写和执行任意文件到特权目录C:\WINDOWS\SYSTEM32\diagtracktempdir{random_decimal} 来绕过合法性检查,一般假设%SYSTEM32%目录只包含合法的操作系统文件。

         POC的运行结果说明能够利用UTC服务在特权目录创建任意文件和目录到固定目录。

图8:POC准许在diagtracktempdir内创建任意文件

         重申一下,如MSRC所说,在不能同时控制或重命名diagtracktempdir目录时POC不会对Windows操作系统造成安全风险。然而,恶意软件作者通常利用不同的技术如UAC绕过来在系统目录下写文件来绕过启发式检测。事实上,当探索POC中使用的文件路径的其它选择,我们发现普通用户账户对C:\WINDOWS\SYSTEM32\Tasks有写和执行权限。但没有读权限---所以这个目录有常被恶意软件作者用来存储恶意文件的恶名。

结论

        在系列博客的第一部分,我们向你展示了我们使用各种工具和在线资源发现Windows RPC服务中潜在安全风险的过程。我们也列举了一些逆向一个RPC服务需要的基本知识。我们坚信RPC服务中还有其它潜在的安全风险。最终,我们决定要使Windows RPC服务更健壮。在系列博客的第二部分,我们将继续研究并改善我们的方法来发现其它RPC服务脆弱性。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
点赞2
打赏
分享
最新回复 (5)
雪    币: 351
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
五天 2019-1-31 09:04
2
0
占楼
雪    币: 19586
活跃值: (60153)
能力值: (RANK:125 )
在线值:
发帖
回帖
粉丝
Editor 2019-1-31 09:25
3
0
感谢分享!
雪    币: 310
活跃值: (1917)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
niuzuoquan 2019-1-31 09:32
4
0
mark
雪    币: 73
活跃值: (893)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hixhi 2019-1-31 09:42
5
0
mark
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wilway 2019-3-27 17:21
6
0
云里雾里
游客
登录 | 注册 方可回帖
返回