Beveiliging van Windows Interprocess-communicatie: Aanval op Named Pipes

Named pipes zijn een veelgebruikte methode voor communicatie tussen applicaties op dezelfde Windows-computer. Ze zijn snel, worden direct ondersteund door het besturingssysteem en zijn ideaal voor communicatie tussen Windows-services, desktopapplicaties, systeemvak-processen, command-line utilities en achtergrondagenten.

Een gangbaar ontwerp bestaat uit een bevoorrechte Windows-service als server van de named pipe, terwijl een gebruikersapplicatie als client fungeert. Ontwikkelaars beschouwen deze communicatie vaak als intern en dus betrouwbaar omdat beide processen op dezelfde computer draaien.

Echter, in de praktijk is de pipe toegankelijk in een omgeving waar veel ongeassocieerde processen onder verschillende gebruikers en sessies kunnen draaien.

Lokaal betekent niet betrouwbaar

Named pipes worden vaak gezien als privé omdat ze worden gebruikt voor communicatie op dezelfde computer. Deze aanname is onveilig.

Een Windows-werkstation kan processen draaien onder LocalSystem, beheerders, gewone gebruikers, service-accounts en gescheiden interactieve of externe sessies. Het kan ook externe software, scripts, diagnostische tools en malware bevatten die onder een gecompromitteerd account draaien.

Elke proces dat de naam van de pipe kent en voldoende toegangsrechten heeft, kan proberen verbinding te maken. Windows weet niet van nature welk programma de ontwikkelaar bedoeld heeft de pipe te gebruiken.

Daarom moet een named pipe worden gezien als een blootgestelde lokale interface. Voordat een verzoek verwerkt wordt, moet de applicatie bepalen wie er verbonden is, wat die identiteit mag doen en of de aangeleverde data veilig is.

Identiteit, Toegangscontrole en Bevoegdheidsgrenzen

Het risico is het grootst wanneer een bevoorrechte Windows-service communiceert met een minder bevoorrechte desktopapplicatie.

Een service die als LocalSystem draait kan mogelijk beschermde bestanden en registertoetsen wijzigen, processen starten, systeeminstellingen aanpassen, gegevens van andere gebruikers benaderen of communiceren met kernel-drivers. Wanneer deze operaties via een named pipe worden blootgesteld, wordt de pipe een API voor bevoorrechte functionaliteit.

Een geslaagde verbinding bewijst alleen dat de client toestemming had om de pipe te openen. Het bewijst niet dat:

  • de client de verwachte applicatie is;
  • de verbonden gebruiker is geautoriseerd;
  • de gevraagde operatie is toegestaan;
  • het aangeleverde commando veilig is.

Pipe-rechten moeten daarom expliciet worden gedefinieerd en beperkt tot de kleinst mogelijke set van identiteiten. Brede rechten voor Everyone, Authenticated Users, of alle interactieve gebruikers kunnen niet-gerelateerde processen toestaan de pipe te benaderen.

Authenticatie en autorisatie moeten ook gescheiden blijven. Een gebruiker kan mogelijk de servicestatus opvragen maar niet de service stoppen, beschermde instellingen wijzigen, processen starten of willekeurige bestanden benaderen. Gevoelige commando’s moeten individueel worden geautoriseerd.

Impersonatie kan helpen door operaties uit te voeren onder de beveiligingscontext van de client, maar moet zorgvuldig worden afgehandeld. De server moet verifiëren dat de impersonatie is geslaagd, het werk dat tijdens de impersonatie wordt verricht beperken en altijd naar de oorspronkelijke identiteit terugkeren.

Onbetrouwbare Servers, Commando’s en Data

De client moet de server net zo goed verifiëren als de server de client verifieert.

Een voorspelbare pipe-naam is slechts een identifier. Het is geen geheim en bewijst niet welk proces de pipe heeft gecreëerd. Een aanvaller kan een pipe maken met de verwachte naam voordat de legitieme server start, waardoor de client verbinding maakt met een process onder controle van de aanvaller.

De optie voor de eerste-pipe-instantiatie kan helpen detecteren dat de naam al is geclaimd, maar vervangt niet de juiste toegangscontroles of serveridentiteitsverificatie.

Berichten die via de pipe worden ontvangen, moeten ook als onbetrouwbare input worden behandeld. Zelfs een geauthenticeerde client kan:

  • slecht gevormde of te grote payloads sturen;
  • ongeldige bestands- of registerpaden;
  • niet-ondersteunde commando-combinaties;
  • corrupte geserialiseerde objecten;
  • waarden ontworpen om foutcondities te activeren.

Een bevoorrechte service die dergelijke input direct omzet in bestands-, register-, proces- of command-line-opties kan een verwarde adjunct worden: de aanvaller levert de instructie, terwijl de service de bevoegdheden levert.

Verzoeken moeten strikte berichtomkadering, begrensde formaten, whitelist van commando’s, schema-validatie, padnormering, operatie-specifieke autorisatie en veilige foutafhandeling gebruiken.

Beschikbaarheid en Externe Blootstelling

Named-pipe-beveiliging beperkt zich niet tot bevoegdheidsvergroting en ongeautoriseerde commando’s.

Een kwaadaardig of defect proces kan herhaaldelijk verbinding maken, verbindingen open houden, onvolledige berichten sturen of verzoeken indienen die buitensporig veel CPU, geheugen of kernelbronnen gebruiken.

De server moet, waar nodig, gebruikmaken van verbindingslimieten, time-outs, annulering, begrensde berichtgroottes, gecontroleerde gelijktijdigheid en snelheidslimieten.

Het is ook onveilig aan te nemen dat elke named pipe alleen toegankelijk is vanaf de lokale computer. Windows named pipes kunnen in sommige configuraties externe toegang ondersteunen.

Pipes die uitsluitend voor lokale IPC bedoeld zijn, moeten expliciet netwerkidentiteiten blokkeren zoals NT AUTHORITYNETWORK, of een mechanisme gebruiken dat lokale-only communicatie garandeert.

Het juiste dreigingsmodel is simpel: elke verbinding met een named pipe moet als mogelijk vijandig gezien worden totdat de client of server-identiteit, rechten, gevraagde operatie en berichtinhoud allemaal zijn geverifieerd.

Wanneer een Named Pipe een Beveiligingsgrens Wordt

Een named pipe wordt een beveiligingsgrens wanneer de processen aan beide kanten met verschillende bevoegdheden draaien of onder verschillende vertrouwensniveaus opereren.

Een veelvoorkomend voorbeeld is een Windows-service die als LocalSystem draait en een desktopapplicatie die onder een standaardgebruikersaccount draait. De service kan beschermde bestanden en registertoetsen wijzigen, processen starten, systeemwijde configuratie veranderen, toegang krijgen tot gegevens van andere gebruikers of communiceren met een kernel-driver. Normaal gesproken kan de desktopapplicatie die operaties niet zelf uitvoeren.

Wanneer de service commando’s accepteert via een named pipe, wordt de pipe een interface naar die bevoorrechte mogelijkheden. Elke zwakte in de pipe’s rechten, identiteitscontroles, commandovalidering of autorisatielogica kan een onbetrouwbaar lokaal proces in staat stellen de privileges van de service te misbruiken.

Een geslaagde verbinding bewijst niet dat de client de verwachte applicatie is. Het bewijst alleen dat het verbindende proces voldoende toestemming had om de pipe te openen. Een ander proces onder hetzelfde gebruikersaccount kan exact dezelfde toegang hebben. De server moet daarom de beveiligingsidentiteit achter de verbinding valideren in plaats van te vertrouwen op de procesnaam, executable pad of geheimhouding van de pipe-naam.

De server moet ook elke operatie afzonderlijk autoriseren. Een client die de servicestatus mag opvragen, mag niet automatisch de service stoppen, de beschermde configuratie wijzigen, een proces starten of om toegang tot een willekeurig bestand vragen.

Authenticatie bepaalt wie er verbonden is; autorisatie bepaalt wat die identiteit mag doen.

Dit onderscheid is vooral belangrijk wanneer de server paden, opdrachtregelargumenten, registerlocaties, uitvoerbare namen of geserialiseerde commando’s verwerkt die door de client worden gecontroleerd. Zonder strikte validatie kan de service een verwarde adjunct worden: de client kiest de actie, maar de bevoorrechte service voert deze uit.

Toegangscontrole en Clientautorisatie

Een named-pipe-server moet beslissen wie er mag verbinden voordat deze begint met het verwerken van berichten. Dit begint met een expliciete beveiligingsdescriptor die alleen toegang verleent aan de benodigde Windows-identiteiten, zoals een specifieke gebruikers-SID, service-account, beheerdersgroep of inlogsessie.

De pipe’s DACL controleert de toegang tot beide uiteinden van de named pipe. Wanneer een client probeert te verbinden, vergelijkt Windows het toegangstoken van de client en de gevraagde rechten met die DACL. Vertrouwen op de standaarddescriptor is riskant omdat de rechten breder kunnen zijn dan de applicatie vereist.

Toegang tot de pipe autoriseert niet automatisch elk beschikbaar commando. Een client mag statusinformatie opvragen, terwijl toestemming wordt geweigerd om configuraties te wijzigen, processen te starten of beschermde bestanden te benaderen. Autorisatie moet daarom voor elke gevoelige operatie worden uitgevoerd en niet alleen bij het tot stand brengen van de verbinding.

Voor lokale applicatie-naar-applicatiecommunicatie kunnen de applicaties ook het proces inspecteren dat is verbonden met het tegenoverliggende uiteinde van de pipe:

  • de server kan GetNamedPipeClientProcessId aanroepen;
  • de client kan GetNamedPipeServerProcessId aanroepen.

Deze Windows-API’s retourneren de proces-ID die geassocieerd is met de verbonden client of server. Ze moeten alleen worden aangeroepen nadat de pipe-verbinding tot stand is gebracht.

De volgende C#-helper haalt de peer PID op met behulp van native Windows-API’s:

csharp
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetNamedPipeClientProcessId(SafePipeHandle pipe, out uint clientProcessId);

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetNamedPipeServerProcessId(SafePipeHandle pipe, out uint serverProcessId);

We kunnen ook een andere functie uit kernel32.dll, QueryFullProcessImageName, aanroepen om het uitvoerbare pad op te halen uit een proceshandle die is geopend met PROCESS_QUERY_INFORMATION of PROCESS_QUERY_LIMITED_INFORMATION. Het geretourneerde pad kan dan worden vergeleken met de verwachte uitvoerlocatie als een aanvullende verificatiestap.

Aan de serverkant moet verificatie plaatsvinden direct nadat de verbinding is geaccepteerd en voordat commando’s worden gelezen of uitgevoerd.

Het verwachte uitvoerbare bestand moet zich in een map bevinden die standaardgebruikers niet kunnen wijzigen. Anders kan een aanvaller het bestand vervangen en toch het verwachte pad behouden.

Voor sterkere verificatie kan de applicatie ook de Authenticode-handtekening van het uitvoerbare bestand valideren of deze vergelijken met een goedgekeurde cryptografische hash. Windows biedt WinVerifyTrust voor het valideren van gesigneerde uitvoerbare bestanden.

Echter, een PID- en uitvoerpadcontrole moet een secundaire controle blijven en niet het primaire autorisatiemechanisme. Veiligheidsonderzoek heeft aangetoond dat het mogelijk is om de PID te spoofen die wordt gerapporteerd voor een named-pipe-client en manieren om een verbonden pipe-handvat over te dragen aan een ander proces. De geretourneerde PID kan het proces identificeren dat de verbinding heeft geopend zonder te bewijzen welk proces momenteel elk bericht verstuurt.

Een veilige implementatie moet daarom verschillende controles combineren:

  • een expliciete en beperkende pipe DACL;
  • verificatie van de Windows-identiteit of SID van de client;
  • autorisatie voor elk bevoorrecht commando;
  • strikte validatie van berichtinhoud;
  • optionele PID-, uitvoerpad-, handtekenings- of hashverificatie als verdediging in de diepte.

De verbinding moet worden geweigerd wanneer identiteitsverificatie mislukt of niet kan worden voltooid. Een bevoorrechte service mag nooit terugvallen op het accepteren van het verzoek enkel en alleen omdat de pipe-verbinding zelf is geslaagd.

Behandeling van Pipe-berichten als Onbetrouwbare Input

Het verifiëren van het proces dat is verbonden met een named pipe maakt de berichten niet automatisch veilig. De legitieme applicatie kan zijn gecompromitteerd, een kwetsbaarheid bevatten of gebruikerd-gecontroleerde data via de pipe verzenden. Een kwaadwillig proces kan ook een geldig pipe-handvat verkrijgen of overerven.

Om deze reden moet elk bericht dat door een named pipe wordt ontvangen als onbetrouwbare input worden behandeld. De server moet zowel de structuur van het bericht als de beoogde operatie valideren voordat een bevoorrechte actie wordt uitgevoerd.

Een gevaarlijke implementatie kan een verzoek deserializeren en direct uitvoeren:

csharp
PipeRequest request = Deserialize(data);

File.WriteAllText(request.Path, request.Content);

Zelfs wanneer request de verwachte structuur heeft, blijven waarden zoals Path en Content door de client gecontroleerd. Een bevoorrechte service kan daardoor worden opgedragen om bestanden buiten de toepassingsdirectory te overschrijven, beschermde configuratie te wijzigen of buitensporige schijfruimte te gebruiken.

De veiligere aanpak is om nauw gedefinieerde commando’s te gebruiken en elk veld te valideren:

csharp
private static void ProcessRequest(PipeRequest request)
{
if (request == null)
throw new InvalidDataException("Het verzoek ontbreekt.");

switch (request.Command)
{
    case PipeCommand.UpdateConfiguration:
        ValidateConfiguration(request.Configuration);
        UpdateApprovedConfiguration(request.Configuration);
        break;

    case PipeCommand.GetStatus:
        ReturnApplicationStatus();
        break;

    default:
        throw new InvalidDataException("Niet-ondersteund commando.");
}

}

Het protocol moet algemene bewerkingen vermijden zoals:

plaintext
WriteFile(path, content)
StartProcess(path, arguments)
SetRegistryValue(key, name, value)
ExecuteCommand(command)

Deze commando’s laten de client zowel de bevoorrechte operatie als de doelstelling kiezen. Geef de voorkeur aan applicatiespecifieke verzoeken waarvan het toegestane gedrag door de server wordt gecontroleerd:

plaintext
UpdateApplicationConfiguration(configuration)
RequestApplicationRepair()
InstallApprovedUpdate(updateId)
GetServiceStatus()

Beveiliging en Afstandstoegang

Een named-pipe-eindpunt kan beschermd zijn tegen ongeautoriseerde commando’s en toch kwetsbaar blijven voor denial-of-service-aanvallen. Een aanvaller heeft niet altijd toestemming nodig om een bevoorrechte actie uit te voeren; het verhinderen van legitieme toepassingen om met de service te communiceren, kan voldoende zijn om het product te verstoren.

Een kwaadwillend of defect proces kan herhaaldelijk verbinding maken met de pipe, alle beschikbare instanties bezetten, verbindingen openhouden zonder volledige berichten te versturen of continu opnieuw verbinden nadat de verbinding is verbroken. Zodra elke serverinstantie is bezet, kunnen legitieme clients mogelijk geen verbinding meer maken.

Hetzelfde risico bestaat na het accepteren van een verbinding. Een client kan gegevens zeer langzaam verzenden, een te grote payload opgeven, halverwege een bericht stoppen of de server overspoelen met geldige maar dure verzoeken. Zonder limieten kunnen deze gedragingen threads, taken, geheugen, CPU-tijd, handvatten en interne vragenlijsten verbruiken.

Named-pipe-buffers gebruiken ook de kernel non-paged pool. Het aantal pipe-instanties en de hoeveelheid gebufferde data is daarom beperkt door systeembronnen. Het creëren van een onbegrensd aantal instanties of het selecteren van onnodig grote buffers kan bijdragen aan het uitputten van middelen.

Een verdedigingsinstantie moet duidelijke limieten vaststellen voor:

  • gelijktijdige verbindingen en pipe-instanties;
  • bericht- en veldgroottes;
  • tijd om een verzoek te vestigen en te voltooien;
  • hangende verzoeken per client;
  • gelijktijdige dure operaties;
  • verzoekfrequentie;
  • interne wachtrijcapaciteit.

Blokkerende operaties moeten ondersteuning bieden voor annulering en mogen niet onbeperkt wachten op meer data van de client. Wanneer een client een tijd-, grootte- of verzoeklimiet overschrijdt, moet de server die verbinding beëindigen en zijn bronnen onmiddellijk vrijgeven.

Limieten moeten worden toegepast voordat dure werkzaamheden beginnen. Zo moet de server een buitensporige verklaarde payload-grootte weigeren voordat het de bijbehorende buffer toewijst. Evenzo moeten autorisatie en basisverzoek validatie plaatsvinden vóór toegang tot de harde schijf, procescreatie, cryptografisch werk, databasequery’s of communicatie met een kernel-driver.

De applicatie moet ook vermijden om één onbeperkte workerthread voor elke verbinding te maken. Een begrensd gelijktijdigheidsmodel voorkomt dat een groot aantal verbonden clients de thread pool van het proces uitput of een ongecontroleerde achterstand veroorzaakt. Snelheidslimieten kunnen worden toegepast per verbinding, proces, gebruikersidentiteit of inlogsessie, afhankelijk van de architectuur van de toepassing.

Beschikbaarheidscontroles moeten echter niet alleen afhankelijk zijn van de client-PID. Een proces kan herhaaldelijk opnieuw starten, meerdere processen gebruiken of verbindingen tot stand brengen onder hetzelfde gebruikersaccount. Verschillende signalen moeten mogelijk samen worden overwogen en de server moet een globale limiet handhaven, zelfs wanneer er per cliënt controle is.

Een ander vaak over het hoofd gezien risico is externe toegankelijkheid. Windows named pipes zijn niet per definitie beperkt tot communicatie binnen de lokale computer. Ze kunnen ook ondersteuning bieden voor communicatie tussen computers via een netwerk en Microsoft verklaart dat named pipes mogelijk op afstand toegankelijk zijn wanneer de Windows Server-service draait.

Dit betekent dat het gebruik van een lokale pipe-naam op zichzelf geen garantie biedt voor communicatie uitsluitend lokaal. Een pipe die bedoeld is voor communicatie tussen een lokale service en een lokale desktopapplicatie, moet die eis expliciet afdwingen.

Natuurlijke pipe-servers kunnen PIPE_REJECT_REMOTE_CLIENTS specificeren, waardoor Windows automatisch verbindingen met externe clients afwijst. Zonder die optie kunnen externe clients worden geaccepteerd en geëvalueerd aan de hand van de beveiligingsdescriptor van de pipe.

De toegangscontrolelijst van de pipe kan ook toegang weigeren aan de NT AUTHORITYNETWORK-identiteit. Waar toegang beperkt moet blijven tot één interactieve sessie, kan de server toegang verlenen aan de juiste inlog-SID in plaats van aan brede groepen die door lokale en externe gebruikers worden gedeeld.

Deze bescherming moet gecombineerd worden in plaats van als alternatieven behandeld te worden:

  • externe clients bij pipe creatie afwijzen wanneer de API dit ondersteunt;
  • netwerkidentiteiten weigeren in de beveiligingsdescriptor van de pipe;
  • alleen toegang verlenen aan de benodigde gebruikers of inlogsessies;
  • de identiteit van het verbonden proces verifiëren;
  • verbinding, time-out, grootte en gelijktijdigheidslimieten toepassen.

Bescherming tegen denial-of-service en beperkingen op afstandtoegang maken deel uit van het beveiligingsmodel van de pipe. Een named-pipe-server is niet veilig alleen omdat ongeautoriseerde commando’s worden afgewezen. Het moet ook beschikbaar blijven voor legitieme clients en afdwingen of verbindingen van buiten de lokale computer zijn toegestaan.

Ontwerpen van een Veilige Named-Pipe-Architectuur

Een veilige named-pipe-ontwerp moet zowel het aantal blootgestelde operaties als de hoeveelheid bevoorrechte code die direct door de client gecontroleerde data verwerkt minimaliseren. De pipe moet fungeren als een nauwe communicatiegrens, niet als een algemene interface naar het besturingssysteem.

Een praktische architectuur scheidt verbindingsafhandeling, validatie, autorisatie en bevoorrechte uitvoering:

De client mag nooit rechtstreeks communiceren met algemeen bevoorrechte functionaliteit. In plaats daarvan moet het een nauw gedefinieerd verzoek indienen bij de pipe-gateway. De gateway valideert het formaat van het bericht en stuurt alleen een gestructureerd verzoek door naar de autorisatielaag. Bevoorrecht werk begint pas nadat alle beveiligingscontroles zijn geslaagd.

Houd het Pipe-protocol Nauwe

Het pipe-protocol moet bedrijfsoperaties blootstellen in plaats van besturingssysteemprestaties.

Bijvoorbeeld, een applicatie kan legitiem de noodzaak hebben om een beleidsupdate aan te vragen, een goedgekeurde update te installeren, de servicestatus op te vragen of een specifieke configuratiewaarde bij te werken. Normaal gesproken heeft het geen onbeperkte commando’s nodig voor het schrijven van willekeurige bestanden, het wijzigen van willekeurige registertoetsen, het starten van willekeurige uitvoerbare bestanden of het uitvoeren van opdrachtregel instructies.

Nauwe operaties maken autorisatie en validatie praktisch. De server weet welke bronnen elk commando mag benaderen, welke velden worden verwacht en welke clientidentiteiten het mogen gebruiken.

Een goed protocol moet bevatten:

  • een expliciete protocolversie;
  • een vaste set van verzoektypes;
  • unieke verzoekidentificatoren;
  • begrensde payload-grootte;
  • voorspelbare antwoord- en foutenformaten;
  • duidelijke regels voor niet-ondersteunde of slecht gevormde berichten.

De server moet onbekende versies, commando’s, velden en statussen afwijzen in plaats van te proberen ze op een lenige wijze te interpreteren.

Scheid Toegangsrechten van Commando-Permissies

Toestemming om verbinding te maken met de pipe moet niet impliceren dat elke functie die via de pipe is blootgesteld, kan worden gebruikt.

De beveiligingsdescriptor van de pipe moet beperken welke Windows-identiteiten een verbinding mogen maken. Na verbinding moet de server de client identificeren en elk commando onafhankelijk autoriseren.

Dit maakt het mogelijk om verschillende vertrouwensniveaus te ondersteunen via dezelfde service. Zo kunnen gewone gebruikers alleen statusinformatie opvragen, terwijl alleen beheerders of een vertrouwde beheersproces beschermde instellingen kunnen wijzigen.

Voor bijzonder gevoelige operaties kan het gebruik van gescheiden named pipes de voorkeur hebben:

plaintext
Product.Status Alleen lezen informatie
Product.UserActions Gelimiteerde gebruikersoperaties
Product.Admin Administratieve operaties
Product.Internal Vertrouwde componentcommunicatie

Elke pipe kan dan zijn eigen toegangscontroles, berichtlimieten en ondersteunde commando’s hebben. Dit is meestal veiliger dan alle operaties achter één groot protocol te plaatsen en volledig te vertrouwen op interne commando-controles.

Het creëren van extra pipes verbetert echter niet automatisch de veiligheid. Elke nieuwe eindpunt vergroot het aanvaloppervlak en moet zelfstandig beschermd worden. Pipes moeten alleen gescheiden worden wanneer ze echt verschillende vertrouwensgrenzen vertegenwoordigen.

Gebruik Meerdere Lagen van Identiteitsverificatie

Geen enkele identiteitscontrole mag als definitief worden behandeld.

De architectuur mag combineren:

  • een beperkende pipe DACL;
  • de verbonden gebruiker’s SID;
  • de client’s inlogsessie;
  • de peer proces-ID;
  • het uitvoerbare pad;
  • de digitale handtekening van het uitvoerbare bestand;
  • applicatieniveau uitdaging en antwoord;
  • operatie-specifieke autorisatie.

Proces-ID- en uitvoerpadcontroles kunnen helpen onverwachte applicaties te detecteren, maar ze moeten verdediging-in-de-dieptecontroles blijven. Processen kunnen veranderen, handvatten kunnen worden overgenomen of overgedragen en een vertrouwd proces kan zelf gecompromitteerd zijn.

De sterkste beslissingen moeten gebaseerd zijn op Windows-beveiligingsidentiteiten en nauwkeurig gedefinieerde permissies, niet alleen op de schijnbare uitvoerbare naam.

Isoleren van Bevoorrechte Uitvoering

De component die verantwoordelijk is voor het lezen van pipemessages moet zo min mogelijk bevoorrecht werk verrichten.

Afhandeling van verbindingen, deserialisatie, framing en basisvalidatie worden blootgesteld aan door de aanvaller gecontroleerde input. Door deze logica te scheiden van bevoorrechte operaties wordt de impact van een parser- of protocolkwetsbaarheid verminderd.

De laag voor bevoorrechte operaties moet alleen gevalideerde, sterk getypeerde instructies ontvangen. Het mag geen ruwe berichtenbuffers, willekeurige paden, opdrachtregels of geserialiseerde objecten direct van de client ontvangen.

Voor zeer gevoelige toepassingen kan het ontwerp verder gaan door de pipe-gateway en bevoorrechte worker in verschillende processen te scheiden. De gateway kan met verminderde privileges werken, binnenkomende verzoeken valideren, en alleen goedgekeurde operaties doorsturen naar een kleinere bevoorrechte component via een tweede beperkte kanaal.

Deze extra procesgrens vergroot de complexiteit, maar kan de hoeveelheid aanvalgerichte code die draait als LocalSystem of een ander krachtig account aanzienlijk verminderen.

Beheer de Levensduur van Elke Verbinding

Elke geaccepteerde verbinding moet een duidelijke en beperkte levenscyclus hebben:

  1. Accepteer de verbinding.
  2. Identificeer en valideer de tegenhanger.
  3. Pas verbindingsniveau restricties toe.
  4. Lees een begrensd verzoek.
  5. Autoriseer en valideer de gevraagde operatie.
  6. Voer de goedgekeurde actie uit.
  7. Geef een gecontroleerd antwoord.
  8. Ontkoppel of wacht op het volgende begrensde verzoek.

De server moet ongeauthenticeerde clients niet toestaan om verbindingen onbeperkt vast te houden. Idle timeouts, verzoekdeadlines, verbindingslimieten, annulering en begrensde wachtrijen moeten vanaf het begin onderdeel van de architectuur zijn.

Langdurige operaties moeten de lezer van de pipe niet onnodig geblokkeerd houden. De service kan het verzoek accepteren, een operatie-ID toewijzen en de client in staat stellen om voortgang te controleren via een afzonderlijk statusverzoek. Dit voorkomt dat één verbinding serverbronnen monopoliseert.

Maak de Server Autonoom

De client moet een uitkomst aanvragen, terwijl de server bepaalt hoe die uitkomst wordt bereikt.

Bijvoorbeeld, de client kan het installeren van een goedgekeurde update door middel van een ID-nummer aanvragen. De server moet de pakketlocatie resolveren, de handtekening verifiëren, het installatiecommando bepalen en de toegestane bestemming afdwingen. De client zou niet het uitvoerbare pad mogen opgeven, de download-URL, opdrachtregelargumenten en het doelmap.

Dit houdt beveiligingsgevoelige beslissingen binnen de vertrouwde component en vermindert het aantal door de cliënt gecontroleerde waarden die de privilegegrens overschrijden.

De server moet ook vermijden om te vertrouwen op eerder door de client gemaakte beveiligingsbeslissingen. Aanspraken zoals “de gebruiker is een beheerder”, “dit bestand is gesigneerd” of “dit pad is veilig” moeten onafhankelijk door de server worden geverifieerd.

Audit Veiligheidsrelevante Activiteiten

Een veilige architectuur moet voldoende informatie vastleggen om verdacht gedrag te onderzoeken zonder gevoelige gegevens te onthullen.

Nuttige auditgebeurtenissen omvatten:

  • geweigerde verbindingen;
  • mislukte identiteitscontroles;
  • ongeautoriseerde commando’s;
  • slecht gevormde of te grote berichten;
  • herhaalde time-outs;
  • onverwachte procesidentiteiten;
  • bevoorrechte operaties en hun resultaten;
  • abnormale vrowaarde verbinding of verzoekfrequenties.

Logs moeten de Windows-gebruiker, sessie, peer PID, commando-type en resultaat waar nodig identificeren. Ruwe geheimen, verificatietokens, en volledige gevoelige payloads moeten niet naar logs worden geschreven.

Herhaalde fouten kunnen wijzen op een aanval, maar kunnen ook een defecte clientversie of implementeerprobleem onthullen. Auditedata moet daarom zowel beveiligingsonderzoek als operationele probleemoplossing ondersteunen.

Aanbevolen Architectuur

Voor de meeste priviliged Windows-service-scenario’s bestaat een verdedigend ontwerp uit:

  • een lokale-only named pipe met een expliciete beveiligingsdescriptor;
  • aparte eindpunten voor materieel verschillende vertrouwensniveaus;
  • verificatie van zowel de Windows-identiteit als het peer-proces;
  • een versiegebonden, lengte-begrensde, applicatie-specifieke protocol;
  • autorisatie voor elk commando;
  • strikte validatie van elke door een klant gecontroleerde waarde;
  • korte en zorgvuldig gecontroleerde impersonatiescopes;
  • een kleine bevoorrechte uitvoeringslaag;
  • begrensde verbindingen, wachtrijen, en uitvoeringstijd;
  • beveiligingsgerichte auditlogging.

Het centrale principe is dat de named pipe de kleinste mogelijke interface tussen vertrouwensniveaus moet blootstellen. Een veilige architectuur probeert niet om willekeurige bevoorrechte operaties veilig te maken. Het vermijdt het in de eerste plaats blootstellen van willekeurige bevoorrechte operaties.

Praktische Named-Pipe Beveiligingschecklist

Voordat u applicatiefuncties via een named pipe blootstelt, controleer of het ontwerp alle volgende gebieden behandelt:

  • Definieer de vertrouwensgrens. Behandel de pipe als een blootgestelde lokale interface, vooral wanneer één kant met verhoogde bevoegdheden draait.
  • Beperk pijp toegang expliciet. Gebruik een nauwe beveiligingsdescriptor in plaats van te vertrouwen op standaardrechten of brede groepen zoals Everyone.
  • Weiger externe clients. Configureer de pipe voor alleen lokale communicatie en weiger netwerk-identiteiten wanneer externe toegang niet nodig is.
  • Verifieer beide uiteinden. Controleer de verbonden Windows identiteit en, waar nodig, bevestig het peer PID, uitvoerpad en digitale handtekening.
  • Vertrouw niet op de pipenaam. Een voorspelbare naam identificeert een eindpunt, maar authenticieert niet welk proces het heeft gecreëerd.
  • Autoriseer elk commando. Toestemming om verbinding te maken mag geen toegang verlenen tot alle door de server blootgestelde operaties.
  • Houd het protocol nauw. Bloot alleen applicatie-specifieke acties in plaats van willekeurige bestands-, register-, proces- of commando-uitvoeringsmogelijkheden.
  • Behandel alle berichten als onbetrouwbaar. Valideer framing, protocolversie, commandotype, payloadgrootte, veldwaarden, paden en objectaantallen.
  • Pas limieten vroeg toe. Weiger ongeldige groottes en niet-ondersteunde verzoeken voordat je geheugen alloceert of duur werk start.
  • Gebruik impersonatie zorgvuldig. Imiteer alleen wanneer de bewerking de toestemming van de client moet gebruiken, houd de scope klein en faal gesloten als de impersonatie mislukt.
  • Houd bevoorrechte uitvoering geïsoleerd. Scheid parsing en validatie van de code die bevoorrechte operaties uitvoert.
  • Beheer hulpbronnen gebruik. Beperk simultane verbindingen, hangende verzoeken, inactiviteit, uitvoeringstijd, wachtrijdiepte en verzoekfrequentie.
  • Geef gecontroleerde fouten terug. Voorkom het blootstellen van stacktraces, interne paden, tokens of andere gevoelige implementatiedetails.
  • Audit veiligheidsrelevante gebeurtenissen. Leg geweigerde verbindingen, mislukte identiteitscontroles, slecht gevormde verzoeken, ongeautoriseerde commando’s en bevoorrechte operaties vast.
  • Faal gesloten. Als identiteit, autorisatie, validatie of imitaties niet betrouwbaar kunnen worden voltooid, moet je het verzoek afwijzen.

Een veilige named-pipe-implementatie moet niet afhankelijk zijn van één bescherming. Het sterkste ontwerp combineert restrictieve toegangscontrole, eindpuntverificatie, autorisatie op operatieniveau, strikte inputvalidatie, beperkte hulpbronnenverbruik en smal afgebakende bevoorrechte functionaliteit.

---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
Opzoek naar de laatste updates uit onze securitylog?
Inhoud mede mogelijk gemaakt door OpenAI.