Sari la conținut
Braincap
← Toate articolele

Named pipes: suprafața de atac Windows pe care o construiești singur

de Claudiu Hulea · IT Management Consultant

Ilustrație: un named pipe Windows între un client SYSTEM și un server controlat de atacator, care prin impersonation ajunge la un token de SYSTEM

Named pipes sunt un mecanism normal de comunicare între procese în Windows, folosit de servicii, agenți și aplicații de zi cu zi. Sunt și o suprafață de atac cu două fețe: una pe care o construiești singur în propriul software, alta pe care un atacator o folosește ca să devină SYSTEM. Amândouă sunt utilizări legitime ale sistemului de operare, și exact de aceea trec neobservate.

Ce sunt și de ce contează

Un named pipe e un canal de comunicare între procese pe aceeași mașină, expus de sistemul de operare printr-un nume de forma \\.\pipe\ceva. E rapid, e nativ și e peste tot: între un serviciu Windows și interfața lui, între un agent de fundal și un utilitar de linie de comandă, între componentele aceleiași aplicații. În unele configurații, un pipe poate fi accesibil și de la distanță, prin SMB, ceea ce lărgește suprafața dincolo de mașina locală.

Problema e că un pipe arată la fel indiferent cine e la capătul lui. Cine se conectează primul, cine ascultă, cine impersonează pe cine, toate sunt decizii pe care le iei tu în cod sau le vezi doar dacă le monitorizezi.

Fața 1: vulnerabilități pe care le construiești singur

Dacă scrii un serviciu care folosește named pipes, poți introduce singur câteva clase de defecte.

Pipe squatting. Un atacator creează un pipe cu numele pe care serverul tău legitim urmează să îl deschidă, înainte ca serverul să pornească. Clientul tău se conectează atunci la procesul atacatorului, nu la al tău. E posibil fiindcă, pe named pipes, un drept de scriere include implicit dreptul de a crea o instanță nouă cu același nume (FILE_CREATE_PIPE_INSTANCE). Remediul de cod e direct: creezi pipe-ul cu FILE_FLAG_FIRST_PIPE_INSTANCE, care eșuează dacă numele e deja luat, în loc să te alături tăcut unui pipe squatat.

Confused deputy. Un serviciu privilegiat, de exemplu unul care rulează ca LocalSystem, primește cereri prin pipe de la clienți mai puțin privilegiați și le execută cu drepturile lui. Dacă nu autorizezi fiecare comandă separat, un client obișnuit împrumută puterea serviciului.

Impersonation prost gestionat. Un server de pipe poate adopta contextul de securitate al clientului. Făcut greșit, devine chiar vectorul din a doua față, mai jos.

Denial of service. Conexiuni ținute deschise, cereri în rafală sau payload-uri declarate uriașe pot epuiza resursele serviciului.

Clienți de la distanță. Un pipe expus prin SMB acceptă conexiuni din rețea. Dacă serviciul presupune că vorbește doar cu procese locale, presupunerea e falsă.

Fața 2: primitivul de escaladare la SYSTEM

Aici named pipes trec din „bug în serviciul tău” în „unealtă în trusa atacatorului”.

Named pipe impersonation e un primitiv clasic de escaladare de privilegii la SYSTEM. Un atacator care rulează deja cod cu privilegiul SeImpersonatePrivilege, pe care multe conturi de serviciu îl au, creează un pipe și forțează un client privilegiat, de exemplu SYSTEM, să se conecteze la el. Apoi apelează ImpersonateNamedPipeClient, adoptă tokenul clientului, îl duplică într-un token primar și pornește un proces ca SYSTEM.

Tehnica nu e teoretică. E familia de exploit-uri cunoscută drept „Potato” și e integrată de mult în unelte ofensive: getsystem din Cobalt Strike, Metasploit, PoshC2. Precondiția e un punct de sprijin inițial care deține SeImpersonatePrivilege, deci e o mișcare de după compromiterea inițială, nu ușa de intrare.

Named pipes ca C2

A treia utilizare e comunicarea ascunsă. Un implant poate asculta pe un named pipe, oferind un canal de comandă fără porturi deschise și fără un beacon clasic spre exterior. Traficul e greu de distins de activitatea normală, fiindcă pipe-urile sunt peste tot în Windows.

În combinație cu SMB, named pipes devin cale de mișcare laterală: un implant de pe o mașină vorbește cu altul prin pipe, iar canalul arată ca administrare Windows normală. E exact genul de comunicare pe care un EDR o vede greu, fiindcă nu are o semnătură clară pe care să o prindă.

Cum te aperi

Apărarea are, la fel ca atacul, două fețe.

Dacă construiești un serviciu cu named pipes:

  • Creează pipe-ul cu FILE_FLAG_FIRST_PIPE_INSTANCE, ca să nu te alături unui pipe squatat.
  • Pune un security descriptor restrictiv (DACL), care limitează cine se poate conecta.
  • Verifică identitatea clientului, contul Windows și procesul, nu doar că s-a conectat cineva.
  • Autorizează fiecare comandă separat și separă validarea de execuția privilegiată.
  • Validează strict intrarea și încadrează mesajele (message framing).
  • Pune limite de conexiuni, timeout-uri și control de resurse.
  • Respinge explicit clienții de la distanță, dacă serviciul e local.

Dacă aperi o flotă:

  • Least privilege pe SeImpersonatePrivilege. E cheia întregului primitiv de escaladare. Conturile care nu au nevoie de el nu ar trebui să îl aibă.
  • Monitorizează crearea și conectarea de pipe-uri (Sysmon Event ID 17 și 18) și impersonation-ul pornit din procese neașteptate.
  • Alertează pe nume de pipe cunoscute de unelte de C2 și pe tipare de impersonation anormale. Există reguli de detecție gata făcute, de exemplu în Elastic, pentru rogue named pipe impersonation.

Ce reținem

Named pipes sunt utile și legitime, și tocmai de aceea sunt o suprafață de atac bună: arată normal din ambele capete. Lecția e aceeași ca la orice graniță de încredere din sistem. Nu presupune cine e la celălalt capăt, verifică-i identitatea, autorizează fiecare acțiune și dă fiecărui proces doar privilegiul de care are nevoie. E aceeași disciplină ca „verifică efectul, nu configurarea”, aplicată la nivel de IPC.

Vrei să știi ce servicii și ce named pipes rulează de fapt în parcul tău, și cine se poate conecta la ele? Scrie-ne și pornim de la un audit.

Surse

Întrebări frecvente

Ce este un named pipe și de ce e o suprafață de atac?

Un named pipe e un canal de comunicare între procese pe aceeași mașină Windows, expus printr-un nume de forma \\.\pipe\ceva. E rapid, nativ și peste tot (servicii, agenți, utilitare), iar în unele configurații e accesibil și de la distanță prin SMB. E o suprafață de atac fiindcă arată la fel indiferent cine e la capătul lui: cine se conectează primul, cine ascultă și cine impersonează pe cine sunt decizii pe care le iei în cod sau le vezi doar dacă le monitorizezi.

Ce este pipe squatting?

Un atacator creează un pipe cu numele pe care serverul tău legitim urmează să îl deschidă, înainte ca serverul să pornească, iar clientul tău se conectează la procesul atacatorului. E posibil fiindcă un drept de scriere pe named pipes include implicit dreptul de a crea o instanță nouă cu același nume (FILE_CREATE_PIPE_INSTANCE). Remediul de cod: creezi pipe-ul cu FILE_FLAG_FIRST_PIPE_INSTANCE, care eșuează dacă numele e deja luat.

Cum duce un named pipe la SYSTEM?

Prin named pipe impersonation, un primitiv clasic de escaladare de privilegii. Un atacator care rulează deja cod cu SeImpersonatePrivilege (pe care multe conturi de serviciu îl au) creează un pipe, forțează un client privilegiat, de exemplu SYSTEM, să se conecteze, apoi apelează ImpersonateNamedPipeClient, adoptă tokenul clientului, îl duplică și pornește un proces ca SYSTEM. E familia „Potato”, integrată în Cobalt Strike, Metasploit și PoshC2.

Cum mă apăr?

Dacă scrii un serviciu: creează pipe-ul cu FILE_FLAG_FIRST_PIPE_INSTANCE, pune un DACL restrictiv, verifică identitatea clientului, autorizează fiecare comandă separat și separă validarea de execuția privilegiată. Dacă aperi o flotă: least privilege pe SeImpersonatePrivilege, monitorizează crearea și conectarea de pipe-uri (Sysmon Event ID 17 și 18), și alertează pe impersonation din procese neașteptate și pe nume de pipe cunoscute de unelte de C2.

Articole similare