Remote code execution (RCE), explained: vad det är och hur man förhindrar det

Remote code execution (RCE) är en klass av programvarusäkerhetsfel/sårbarheter. RCE-sårbarheter gör det möjligt för en skadlig skådespelare att utföra valfri kod på en fjärrmaskin via LAN, WAN eller internet. RCE tillhör den bredare klassen av sårbarheter för exekvering av godtycklig kod (ACE). Med internet blir allestädes närvarande, men RCE sårbarheter inverkan växer snabbt. Så, RCEs är nu förmodligen den viktigaste typen av ACE-sårbarhet.

som så är fallet ville vi ta en mer detaljerad titt på de olika typerna av RCE-sårbarheter och möjliga motåtgärder.

RCE-klassificering efter ursprung

de flesta, om inte alla, av de kända RCE-sårbarheterna har ett litet antal bakomliggande orsaker.

dynamisk kodkörning

dynamisk kodkörning tenderar att vara den vanligaste attackvektorn som leder till RCE. De flesta programmeringsspråk har något sätt att generera kod med kod och köra den på plats. Detta är ett mycket kraftfullt koncept som hjälper till att lösa många komplexa problem. En skadlig tredje part kan dock enkelt missbruka den för att få RCE-funktioner.

ofta är koden som genereras vid körning baserad på viss användarinmatning. Oftast innehåller koden den inmatningen i någon form. En skadlig skådespelare, som inser att den dynamiska kodgenereringen kommer att använda sig av en given ingång, kan ge giltig kod som en ingång för att attackera din ansökan. Om användaringångarna inte granskas, kommer den koden att köras på målmaskinen.

i stort sett orsakar dynamisk kodkörning två huvudklasser av RCE-sårbarheter: direkt och indirekt.

direkt

vid direkt dynamisk kodkörning är den skadliga aktören medveten om att deras inmatning skulle användas vid kodgenerering.

indirekt

ett indirekt fall, återigen, kokar ner till dynamisk kodgenerering inklusive användaringångar. Användarinmatningen passerar emellertid genom ett eller flera lager. Några av lagren kan till och med omvandla den ingången innan den slutar med dynamisk kodgenerering. Dynamisk kodgenerering kan också vara en bieffekt och inte den primära användningen av ingången. Som sådan är det inte riktigt uppenbart för användaren som tillhandahåller ingången att ingången kommer att användas som ett byggsten i ett kodavsnitt som ska utföras på en fjärrmaskin.

deserialisering

deserialisering är ett mycket bra exempel på detta scenario. Till synes ingen dynamisk kodgenerering bör ske vid deserialisering. Det är faktiskt fallet när det serialiserade objektet endast innehåller datafält av primitiva typer eller andra objekt av det slaget. Saker blir dock mer komplicerade när metoder / funktioner för ett objekt serialiseras. Deserialisering kommer då vanligtvis att innehålla någon form av dynamisk kodgenerering.

du kanske tror att dynamiska språk är det enda stället där funktionsserialisering är vettigt. Problemet kommer då att vara av begränsad omfattning. Men det är också ett användbart scenario på statiska språk. Det är något svårare att uppnå på ett statiskt språk men överlägset inte omöjligt.

ganska ofta består implementeringen av deserialiseringsgenererade proxyobjekt/funktioner. Att generera objekt / funktioner vid körning är ett fall av dynamisk kodgenerering. Så om de data som ska deserialiseras kommer från en begäran från en fjärrmaskin, kan en skadlig skådespelare ändra den. Noggrant utformade serialiserade kodavsnitt kan injiceras som lurar den dynamiska kodgenereringen för att utföra dem när de åberopas som en del av deserialiseringen.

Minnessäkerhet

en annan orsak till RCE-sårbarheter har att göra med minnessäkerhet. Minnes säkerhet innebär att förhindra kod från att komma åt delar av minnet att det inte initiera eller få som en ingång. Intuitivt kan du förvänta dig att brist på minnessäkerhet leder till obehörig dataåtkomst. Operativsystemet och den underliggande hårdvaran använder dock minne för att lagra faktisk körbar kod. Metadata om kodkörning lagras också i minnet. Att få tillgång till denna typ av minne kan resultera i ACE och eventuellt RCE. Så vilka är de främsta orsakerna bakom minnessäkerhetsfrågor?

Programvarudesignfel

Programvarudesignfel är en typ av minnessäkerhetssårbarhet där det finns ett designfel i någon underliggande komponent. Oftare än sällan, det skulle vara en kompilator, tolk, eller virtuell maskin, eller potentiellt operativsystemet kärna eller bibliotek. Det finns ett antal olika brister som hör till denna klass. Vi kommer att ta en mer detaljerad titt på vad som förmodligen är den vanligaste.

buffertspill eller buffertöverläsning

buffertspill (även känd som buffertöverläsning) är en ganska enkel och välkänd teknik för att bryta mot minnessäkerheten. Det utnyttjar en designfel eller en bugg för att skriva till minnescellerna som följer den faktiska änden av en minnesbuffert. Bufferten själv returneras från ett legitimt samtal till offentligt API. Bufferten fungerar emellertid endast som en ursprungspunkt för att beräkna de fysiska minnesadresserna för privata fält/medlemsvärden för något objekt eller programräknare. Deras relativa position till bufferten är antingen välkänd eller kan gissas. Att undersöka koden om den är tillgänglig eller felsöka programkörningen vid körning kan hjälpa en skadlig skådespelare att få relativa positioner.

så ett buffertspill möjliggör modifiering av minne som bör vara otillgängligt genom design. Den bufferten kan finnas i adressutrymmet för en annan maskin och ändras genom att anropa ett fjärr-API. Det ger åtkomst till fjärrmaskinens minne. Det finns uppenbarligen olika sätt att använda denna typ av åtkomst för att instrumentera en RCE. Det allmänna antagandet är att om en buffertspill sårbarhet existerar, är en RCE möjlig. Så kodägare bör fixa buffertspill ASAP, långt innan den faktiska RCE-attacken dyker upp.

Scope

oftare än sällan, buffertspill mål C/C++ kod eftersom dessa språk inte har inbyggda buffertstorlekskontroller. Många andra populära ramar och tekniker slutar använda C/C++ – bibliotek djupt ner under ytan som automatiskt gör dem sårbara för denna typ av attack.

nod.js är ett bra exempel på detta eftersom JavaScript runtime förutom att vara baserat på C/C++ också tillåter inbyggda C/C++-tillägg. På grund av detta kan en angripare noggrant skapa förfrågningarna till en nod.JS server för att orsaka buffertspill och därmed ändra systemminnet på den drabbade maskinen, vilket orsakar exekvering av godtycklig kod.

Hårdvarudesignfel

intressant nog kan minnessäkerhetsöverträdelser också uppstå på grund av hårdvarusäkerhetsdesignfel. Medan mindre vanliga och svårare att hitta, har sådana sårbarheter vanligtvis en extremt stor inverkan.

avböjande RCE-attacker

medan resultatet av varje RCE-attack är detsamma när det gäller en angripare som utför kod, är attackvektorerna mycket olika i naturen. Att blockera dem alla kräver betydande ansträngningar. Dessutom växer ansträngningen tillsammans med teknikstacken. Alla attackvektorer som beskrivs i detta inlägg är teknik-agnostiker. Alla implementeringar är dock teknikspecifika, och det är också försvarsmekanismerna.

så ett traditionellt tidsbesparande tillvägagångssätt är att övervaka nätverkstrafik för misstänkt innehåll istället för att övervaka varje slutpunkt med sin specifika teknik. En web application firewall (WAF) utför vanligtvis det här jobbet. Medan det sparar tid, kommer det också till ett pris—WAF är en flaskhals i nätverksprestanda, och den saknar all bakgrundsinformation tillgänglig vid den faktiska slutpunkten eller på applikations-och användarnivåerna. Därför kan WAF trafikanalys aldrig vara perfekt. Heuristik är oundviklig utan fullständig data, så antingen kommer inte alla hot att uppstå eller falska positiva kommer att uppstå, eller oftast båda.

flytta inuti appen: Sqreens tillvägagångssätt

Sqreen adresserar dessa WAF-brister utan att öka utvecklingskostnaden för slutanvändaren genom att flytta synligheten inuti applikationen, vilket ger mer komplett skydd med en teknikspecifik RASP och in-App WAF. Sqreens RASP och WAF körs inuti den faktiska webbapplikationen, API eller mikroservice som tar emot nätverkstrafik. Det kräver dock ingen kodändring. Den använder instrumentpunkter som är specifika för varje teknik (t.ex. JVM API för Java, v8 API för nod.js, etc.) för att ändra kod före körning vid körning. Således kan den övervaka och modifiera system-och nätverkshändelser samtidigt som den har hela sammanhanget med allt som händer i applikationen.

Således kan Sqreen upptäcka att appen använder komponenter med kända minnessäkerhetsproblem. Det kan också upptäcka de faktiska användaringångarna som gör det till de dynamiska kodkörningshändelserna. Naturligtvis är detta ett överlägset tillvägagångssätt för att upptäcka och förebygga RCEs jämfört med en traditionell WAF som endast har tillgång till nätverkstrafik.

inslagning upp

klart, RCE är en mycket potent attack vektor. Men lyckligtvis är det möjligt att försvara dig mot RCE-attacker också. Informationen ovan kan verkligen hjälpa till att bygga din försvarsstrategi. Om du är intresserad av andra attackvektorer och detaljer, kolla in våra tidigare inlägg på SQL injection, XXE och LFI.

Leave a Reply