
Libreria POC semplice per eseguire chiamate arbitrarie proxyandole tramite NdrServerCall2 o simili.
Per creare un metodo generale per eseguire codice locale e remoto, abbiamo progettato un metodo di esecuzione del codice relativamente oscuro, che internamente chiamiamo RpcCraft (Self) e RpcExec (Remote Process). Questa tecnica sfrutta una metodologia ben nota tra gli sviluppatori di exploit, abusando delle chiamate del server RPC (Remote Procedure Call) come NdrServerCall2 o NdrServerCallAll per eseguire codice arbitrario.
All'interno di RPCRT4.dll, funzioni come NdrServerCall2, NdrServerCallAll e NdrServerCallNdr64 (un alias di NdrServerCallAll) sono implementate come wrapper per invocare dinamicamente funzioni relative alle funzionalità del server. Queste funzioni accettano un singolo argomento, un puntatore a una struttura RPC_MESSAGE.
Struttura RPC_MESSAGE:
typedef struct _RPC_MESSAGE {
RPC_BINDING_HANDLE Handle;
unsigned long DataRepresentation;
void *Buffer;
unsigned int BufferLength;
unsigned int ProcNum;
PRPC_SYNTAX_IDENTIFIER TransferSyntax;
void *RpcInterfaceInformation;
void *ReservedForRuntime;
RPC_MGR_EPV *ManagerEpv;
void *ImportContext;
unsigned long RpcFlags;
} RPC_MESSAGE, *PRPC_MESSAGE;
Per inizializzare il runtime senza associarsi a un servizio, viene utilizzata la funzione PerformRpcInitialization. Questa funzione inizializza internamente le strutture necessarie senza richiedere un binding manuale.
Questa versione pubblica della tecnica è stata sviluppata come POC per dimostrarne la fattibilità, e attualmente genera un'eccezione su NdrGetBuffer a causa di un Binding Handle mancante. Questo può essere gestito in diversi modi, ma l'implementazione corrente fa:
int FetchReturnValue(const PEXCEPTION_POINTERS ExceptionInfo) {
ExceptionInfo->ContextRecord->EFlags |= (1 << 16);
g_ReturnValue = (PVOID)ExceptionInfo->ContextRecord->Rax;
return EXCEPTION_CONTINUE_EXECUTION;
}
L'invocazione RPC è protetta da CFG, il che significa che per ottenere un'esecuzione di codice completa e senza restrizioni, è necessario marcare il target come valido con SetProcessValidCallTargets o applicare una patch a RpcInvokeCheckICall.
Il progetto RpcProxyInvoke dimostra una tecnica alternativa che può essere abusata per implementare una libreria in stile RailGun. Sebbene l'implementazione pubblica non sia perfetta, può servire come base per ulteriori sviluppi.
Questo progetto è concesso in licenza con la licenza MIT - vedere il file LICENSE per i dettagli.