Log4j: de sleutel ligt onder de bloempot

Cybercrime haalt vaak alleen het landelijk dagblad als er een grote vis aan de haak is geslagen, bijvoorbeeld een universiteit die tegen losgeld is lamgelegd. Voor een lekenpubliek kan een journalist dan niet de diepte ingaan. Enerzijds omdat het al snel te technisch en te lang wordt, en anderzijds omdat de omstandigheden vaak in nevelen gehuld zijn. De getroffen partij wil immers niet nog verder in verlegenheid gebracht worden. Veel organisaties hebben hun beveiliging slecht op orde en bij de niet-technische lezer is het al niet veel beter. Hij weet dat hij niet de naam en verjaardag van zijn kinderen als wachtwoord moet nemen, maar veel verder gaat besef van digitale hygiëne niet. Je hebt dus nogal wat uit te leggen.

Het is dus best uniek als de kranten schrijven over een kwetsbaarheid in een nederig stuk software dat op miljoenen essentiële systemen geïnstalleerd is, maar dat de gewone burger niet kent. Log4j is een populair hulpprogramma binnen de Java programmeertaal, een library of module genaamd. Zoals een school niet zijn eigen meubilair en klaslokalen bouwt, zo bestaat ingewikkelde software vaak uit honderden van zulke generieke modules voor veelvoorkomende taken, gemaakt door derde partijen. En bij dat oude vertrouwde log4j had niemand in de gaten dat de reservesleutel van de achterdeur onder de spreekwoordelijke bloempot lag.

Uitleg voor specialisten waarin het probleem en de oplossing worden uitgelegd zijn er al zat. Vandaar mijn poging om het te duiden voor niet-techneuten vanuit mijn eigen ervaring als Java ontwikkelaar. Voor de duidelijkheid: ik ben geen beveiligingsexport. Waaruit bestaat deze zwakke plek en wat is er zo gevaarlijk aan? Ter inleiding een kleine omleiding door het land der fabelen.

In de horrorklassieker The Evil Dead uit 1981 vindt een groepje kampeerders een bandrecorder in een afgelegen boshut (waar anders?) met daarop het audiodagboek van een occulte wetenschapper die het Book of the Dead heeft ontdekt. Wie de teksten hardop voorleest roept een leger bosdemonen op. Uit sensatiezucht laten de jongeren de tape lopen en barst letterlijk de hel los. Heerlijk fout vermaak.

Het bekende paard van Troje is nog klassieker. Na tien jaar belegering verlaten de Grieken met de staart tussen de benen het strijdtoneel van Troje en laten als afscheidscadeau een houten paard achter, stiekem gevuld met hun beste krijgers. Tijdens een hiaat van gezond verstand rijden de Trojanen het geschenk klakkeloos de stadspoorten binnen. De rest is geschiedenis, nou ja, mythe.

Het vermogen om anderen jouw woorden te doen gehoorzamen, tot moord en zelfmoord aan toe, is populair in sciencefiction en horror. Bij computers komt er geen magie aan te pas. Die hebben net als de mythische Trojanen gewoon geen instinct voor kwade bedoelingen. De ergste digitale bedreigingen zijn vaak een combinatie van Evil Dead en het paard van Troje. We laten de vijand door de voordeur naar binnen en met een simpel commando legt deze vervolgens een compleet systeem plat. Hoe is dat mogelijk?

De software achter een grote webwinkel of de afsprakensite voor vaccinatie is anders dan de tekstverwerker op je laptop. Deze draait op een server: een krachtige machine ergens in een anoniem datacenter die duizenden gebruikers tegelijkertijd kan bedienen en alle instructies via het internet ontvangt, in plaats van één betrouwbare gebruiker achter een toetsenbord. De invulvelden en knoppen in jouw browser sturen een stroom aan instructies om het gedrag van die software te sturen, weliswaar binnen strikte grenzen. Je wil je bestelling voor vijf paar nieuwe sokken ophalen bij de lokale Albert Heijn, zonder cadeaupapier, en je betaalt per IDEAL. Al die binnenkomende gegevens moeten worden geïnterpreteerd als opdrachten aan het systeem. En daar zit ruimte voor misbruik. Soms kunnen kwaadwillende gebruikers via een simpel webformulier opdrachten laten uitvoeren die de ontwikkelaars nooit bedoeld hadden. Het systeem doet dan blindelings wat het wordt opgedragen en is zich niet bewust van de oorsprong of de bedoeling van de instructie.

Voor een concreet voorbeeld moet ik toch even de diepte in. Bijna elke website beheert gegevens die terug te voeren zijn op individuele gebruikers, al is het maar een lijst van inlognamen en wachtwoorden. Deze staan opgeslagen in een database, een term die we zowel voor de gegevens zelf gebruiken als voor de software waarmee je deze beheert. Oracle en Microsoft SQL-server zijn bijvoorbeeld veelgebruikte databases binnen grote organisaties. Zo’n database bestaan uit vele tabellen (te vergelijken met een spreadsheet, maar dan met miljoenen rijen), die afzonderlijk bijvoorbeeld naam/adresgegevens, producten, bestellingen en retouren bevatten. Om vanuit je eigen software gegevens op te slaan en uit te vragen spreken de meeste databases een gestandaardiseerde taal die bekendstaat als Structured Query Language (SQL). Een commando om het adres van een gebruiker met gebruikersnaam harry_1980 op te vragen ziet er bijvoorbeeld uit als SELECT ADDRESS,POSTCODE,CITY FROM USERS WHERE USERNAME = harry_1980. 

Stel dat we in deze tabel USERS ook het wachtwoord van de gebruiker opslaan. Als eerste stap in het inlogproces geeft de gebruiker haar inlognaam en wachtwoord, want we willen zien of het opgeslagen wachtwoord overeenkomt met wat zij intypte. Het SQL-commando zal er ongeveer als volgt uitzien: select password from users where user = ??? We nemen de gebruikersnaam over uit het ingevulde webformulier en plakken dat aan bovenstaand commando. Slecht idee! Want nu geef je een hacker de mogelijkheid je commando te kapen door in plaats van een geldige inlognaam nog een paar kwaadaardige instructies erachter te plakken, bijvoorbeeld om een lijst van alle accounts te laten uitspugen of zelfs de hele tabel te wissen. Les 1 van programmeren met de database is dan ook om nooit klakkeloos informatie uit een formulier op te nemen in SQL-commando’s, maar dergelijke variabelen eerst door de database te laten ontdoen van ongeoorloofde instructies. Want achter elk veldje waar de gebruiker iets kan invullen zit misschien de gelegenheid om het systeem om zeep te helpen. Bij de meeste ontwikkelaars is die achterdocht helaas niet even sterk ontwikkeld.

Log4j is zo’n stuk software waar je als eindgebruiker al geen benul van hebt, maar waar je zelfs als ontwikkelaar nog weinig bij stilstaat. Het is als elke andere faciliterende dienst in een onderneming. Onmisbaar en onzichtbaar, en omdat het al zolang bestaat vertrouw je dat het veilig is. Log4j legt diagnostische meldingen (logberichten) over de werking van de software vast in een bestand of database. Programmacode stuurt regelmatig dergelijke meldingen naar log4j. Dat is noodzakelijk voor audit-doeleinden (wie deed wat op welk moment?) en om naderhand de oorzaak van problemen te achterhalen. De exacte inhoud van die logmeldingen wordt dikwijls bepaald door wat de gebruiker aanleverde: “gebruiker Jan deed drie onsuccesvolle inlogpogingen. Account geblokkeerd voor 30 minuten”. Je voelt het misschien al aankomen. Net als bij het SQL-commando om een wachtwoord op te zoeken wordt ‘Jan’ hier dynamisch ingevuld, d.w.z. naargelang de situatie. Je kunt allerhande commando’s toevoegen aan de loginstructie om gegevens op te halen en toe te voegen aan het log. Als je een webadres naar een kwaadaardig programmabestand gelogd wist te krijgen, was log4j zelfs zo behulpzaam om dit bestand te downloaden en uit te voeren, ook als het een virus was dat de complete controle overdroeg aan hackers.

In softwareland noemen we systemen graag krachtig en flexibel als hun gedrag niet in beton gegoten is, maar als je de functionaliteiten kunt oprekken door slimme instructies toe te staan, als een universele afstandsbediening die een power user ook kan programmeren. Maar flexibeler betekent ook kwetsbaarder, zoals een ingewikkelde belastingwet uitwegen mogelijk maakt die de wetgever nooit bedoeld had.

Er is al miljoenen jaren een wapenwedloop aan de gang tussen de antilopen en hun katachtige aartsvijanden. De antilope of tijger die niet snel genoeg rent wordt opgegeten of sterft de hongerdood, respectievelijk. Binnen de IT gaat de evolutie sneller. In de pioniersjaren van het web stelde beveiliging weinig voor. Dataverkeer was onversleuteld, wat betekent dat iedereen kon meelezen. Maar twintig jaar later zijn het niet meer de bètafaculteiten die research papers met elkaar deelden, maar leeft het hele volk (gedwongen) zijn leven online. De ontwikkelaars zoals ikzelf die in die hoogtijdagen het vak ingingen hebben wel wat slechte gewoontes af moeten leren. Voor de nieuwe generatie is het logisch dat grootscheepse oplichting een lucratief verdienmodel is.

Het gat in log4j was door de ontwikkelaars van die module binnen een dag gedicht, patched zoals dat heet. Er zat een pleister op. En het duurde niet lang voordat er wéér een lek aan het licht kwam, dat even snel werd gedicht. Het is vervolgens aan de beheerders van al die duizenden applicaties die log4j gebruiken om een nieuwe versie te installeren. In een efficiënte organisatie weten die beheerders precies waar welke modules gebruikt worden en welke versies er draaien. Een upgrade is dan een fluitje van een cent. Voor de meeste bedrijven betekende het een weekend overwerken met veel pizza en cola.

Mag je hier bang voor zijn? Ja, best wel.