Door Anoniem: Nog tijd over om dit 'in één klap op te lossen' met een verhelderende / stapsgewijze toelichting (the way it works)?
Zeg maar of het volgende je vertelt wat je weten wilde:
De code leest exif data uit een (specifiek, geprepareerd) plaatje. Dit is zeg maar het transport om de achterdeur naar binnen te krijgen. Eenmaal binnen wordt de achterdeur inelkaar gezet door een onderdeel van de exif data als regular expression te gebruiken (tweede argument) op een ander onderdeel (eerste argument). Er wordt hier vreemde, onvertrouwde data als regular expression gebruikt. Conclusie: Het tweede argument aan preg_replace mag dus nooit "ergens anders" vandaan komen.
Die combinatie levert een resultaat op wat als php code wordt geinterpreteerd. Er bestaat namelijk een optie (/e) die je aan een regular expression kan plakken waarmee de preg_replace dat doet. Dat op zich maakt de functie gevaarlijk. Er wordt hier dus code uitgevoerd die slinks in een geprepareerd plaatje gestopt is.
Die code blijkt uit het uitpakken van base64 data te bestaan (de tweede uitpakronde, de eerste was dat regex-gerommel), met daaromheen nog maar een eval(). Dus wat er in die base64 data staat wordt ook nog eens uitgevoerd na het uitpakken.
En wat staat er in die base64 data? Een instructie om te kijken of er een http-post-parameter "zz1" bestaat, en zo ja die uit te pakken ("stripslashes"), en een derde eval.
Waarmee de achterdeur dus zo werkt dat je een pagina waar'ie in zit aanroept met een specifieke parameter. Die parameter stop je php code in, en die voert'ie dan uit. Dus om een url als http://example.com/hier/is/de/achterdeur.php?zz1=phpcode() (maar dan als POST, niet als GET) vragen voert "phpcode()" uit.
Daarmee is preg_replace niet onschuldig te noemen wegens het bestaan van die "/e" vlag, en moet vreemde en dus onvertrouwbare data als regular expression inzetten onmiddelijk rode lichten laten branden en sirenes doen loeien. De significantie van het plaatje is dat daar het venijn in verborgen zit, zodat het zichtbare gedeelte van de achterdeur maar uit twee onschuldig-ogende functieaanroepen bestaan.
Andere programmas zullen vaak niet eens naar de exif data kijken, of zich wellicht verslikken in wat er in staat. Het plaatje is specifiek voor dit doel geprepareerd, door de gewenste velden de gewenste waarden te geven. Het is ook niet belangrijk wat er in dat plaatje staat of zelfs hoe een browser het laat zien--best kans dat dat nergens gebeurt. Het is alleen maar de verpakking.
Het plaatje hoeft alleen maar ergens te staan waar die exif_read_data()-aanroep erbij kan. Volgens de handleiding: Mag geen URL zijn, dus ergens op het bestandssysteem waar de php draait. Dat is ook het geval in het voorbeeld. Wellicht dat je met een regel extra een plaatje van elders kan halen en die lokaal opslaan, maar dat maakt de zichtbare code weer ingewikkelder.
Deze achterdeur is vrij specifiek php, gezien alle code in php is geschreven. Werkt overal waar php werkt. Dat is dus windows, linux, mac, ... zolang er maar php op draait. En al goed, er moet ook exif support aanwezig zijn.
Dit is niet specifiek afhankelijk van jpeg, het zou kunnen werken met alle formaten waar exif_read_data() exif data uit kan lezen. Wellicht dat je het ook met andere velden zou kunnen doen, maar dat mag iemand die exif beter kent dan ik vertellen.
Deze specifieke truuk detecteren is een ding, maar zo in z'n algemeen exif data doorspitten is iets heel anders. Je zou, bijvoorbeeld, kunnen zoeken op velden die eindigen met "/e", maar wellicht dat "/ei" of "/ue" ook wel goed genoeg werkt en dan kijkt je detectie er toch ineens overheen.
1GYYopciYLMZB1mUTgZta7WpgMa78Smwt3