Van Joomla-lek naar webshell: hoe één upload je hele website kan overnemen
Een websitehack begint vaak klein.
Niet met een kapotte homepage. Niet met een groot rood scherm. Niet met een melding van Google. Vaak begint het met één bestandje dat ergens staat waar het niet hoort.
Een PHP-bestand in een tijdelijke map. Een vreemd script in een uploadfolder. Een afbeelding die helemaal geen gewone afbeelding blijkt te zijn. Of een oude Joomla-extensie die ineens wordt misbruikt om code op de server te plaatsen.
En vanaf dat moment is het geen “klein lekje” meer.
Dan kan een aanvaller van buitenaf ineens grip krijgen op de webserver.
Wat is er aan de hand bij zo’n Joomla-aanval?
Joomla is, net als WordPress, een CMS. Je bouwt er websites mee, je beheert pagina’s, je uploadt afbeeldingen en je gebruikt extensies om extra functies toe te voegen.
En juist die extensies maken een website krachtig, maar ook kwetsbaar.
Een goed voorbeeld daarvan is JCE, de Joomla Content Editor. Dat is een veelgebruikte editor waarmee websitebeheerders content, afbeeldingen en bestanden kunnen beheren. In juni 2026 kwam er een kritieke kwetsbaarheid naar buiten in JCE: CVE-2026-48907. Volgens NVD kan deze kwetsbaarheid ertoe leiden dat ongeauthenticeerde gebruikers nieuwe editorprofielen kunnen aanmaken, wat uiteindelijk kan resulteren in het uploaden en uitvoeren van PHP-code. De Joomla CNA-score staat op CVSS 10.0 Critical; NVD toont daarnaast een CVSS 3.1-score van 9.8 Critical.
Dat is het soort lek waarbij je niet denkt: “We kijken volgende maand wel even.”
Dat is het soort lek waarbij bots het internet scannen op kwetsbare websites voordat de gemiddelde ondernemer überhaupt weet dat er iets speelt.
Hoe werkt zo’n aanval in gewone mensentaal?
Normaal gesproken mag een uploadfunctie alleen veilige bestanden accepteren. Bijvoorbeeld een JPG, PNG of PDF.
Maar bij een lek in zo’n upload- of editorfunctie kan een aanvaller proberen om iets anders naar binnen te smokkelen. Niet een gewone afbeelding, maar code. Soms wordt die code vermomd als afbeelding. Soms wordt een bestand eerst geüpload met een veilige naam of extensie en daarna op een andere manier verwerkt. Soms wordt er misbruik gemaakt van een importfunctie, profielinstelling of tijdelijke map.
Het einddoel is simpel:
de aanvaller wil een PHP-bestand op de server krijgen dat hij via de browser kan aanroepen.
Zodra dat lukt, praat de aanvaller niet meer alleen met Joomla. Dan praat hij met de webserver zelf.
Van “decoded image” naar PHP-code
Bij dit soort aanvallen zie je vaak dat de payload wordt verstopt of verpakt.
Een bestand lijkt dan op het eerste gezicht een afbeelding, upload, cachebestand of tijdelijk bestand. Maar na verwerking of decoding blijkt er PHP-code uit te komen. Die PHP-code wordt vervolgens ergens binnen de website geplaatst, vaak in een map waar de webserver bij kan.
In het onderzochte incident stonden er twee verdachte PHP-bestanden in de tijdelijke map van de website:
/home/vhosts/[website]/httpdocs/tmp/lanciaudsdPMKj0.php
/home/vhosts/[website]/httpdocs/tmp/lanciauDnKDH4h5.php
De scan herkende deze bestanden als PHP malware en ze stonden vrijwel op hetzelfde moment in httpdocs/tmp/. De bestandsnamen begonnen allebei met lanciau, wat in dit onderzoek als belangrijke indicator is meegenomen.
Belangrijk om eerlijk te blijven: met alleen de beschikbare bestanden is niet hard bewezen welk exacte request deze bestanden heeft geschreven. Daarvoor zijn accesslogs, PHP-FPM-logs, WAF-logs of quarantinekopieën nodig. Maar het patroon past wel bij een scenario waarbij een kwetsbare upload- of editorfunctie is misbruikt om code binnen de webroot te plaatsen.
Wat is een webshell?
Een webshell is een achterdeur in de vorm van een webbestand.
Voor een normale bezoeker is er niets te zien. De website lijkt gewoon te werken. Maar de aanvaller weet precies welk verborgen bestand hij moet openen.
Via die webshell kan hij, afhankelijk van de serverrechten:
bestanden bekijken, bestanden aanpassen, nieuwe bestanden uploaden, mappen doorzoeken, databasegegevens proberen te lezen, serverinformatie bekijken en soms zelfs commando’s uitvoeren.
In de aangetroffen code stond een complete PHP-webshell met de naam BYTE_BUNK Shell v4.0. Die shell bevatte functies voor bestandsbeheer, uploaden, downloaden, bewerken, verwijderen, hernoemen, permissies aanpassen, databaseverbindingen testen, netwerkpoorten scannen en command execution via meerdere PHP-methodes.
Dat is dus geen “verdacht bestandje”.
Dat is een beheerpaneel voor een aanvaller.
Wat is dan een reverse webshell?
Een gewone webshell werkt meestal zo:
de aanvaller opent de webshell via de browser en stuurt daar opdrachten naartoe.
Een reverse webshell werkt andersom.
Daarbij probeert de gehackte webserver zelf verbinding te maken naar een systeem van de aanvaller. Dat is gevaarlijk, omdat veel servers inkomend verkeer redelijk blokkeren, maar uitgaand verkeer vaak gewoon toestaan. De firewall zegt dan eigenlijk: “Deze website maakt zelf verbinding naar buiten, dat zal wel goed zijn.”
Maar dat is het dus niet.
Bij een reverse shell kan de aanvaller een interactieve verbinding krijgen alsof hij achter de server zit. Niet altijd als root, maar wel als de gebruiker waaronder de website draait. En dat is vaak al genoeg om enorme schade aan te richten.
Denk aan:
- configuratiebestanden uitlezen;
- databasewachtwoorden vinden;
- klantgegevens bekijken;
- extra backdoors plaatsen;
- spam- of phishingbestanden hosten;
- malware downloaden vanaf externe servers;
- andere websites op dezelfde hostingomgeving bekijken;
- de server gebruiken als springplank naar nieuwe slachtoffers.
In de aangetroffen webshell is geen vaste hardcoded command-and-control-server bewezen. Er stond dus niet één vaste server in de code waar automatisch contact mee werd gemaakt. Wel bevatte de shell functies waarmee een aanvaller handmatig netwerkverbindingen kon testen of via command execution alsnog tools zoals curl, wget of andere systeemcommando’s had kunnen gebruiken, als die beschikbaar waren.
Dat verschil is belangrijk.
Niet elk webshellbestand is automatisch een reverse shell. Maar een webshell kan wel gebruikt worden om een reverse shell of andere vervolgpayload te starten.
Welke IP-adressen vielen op?
In de Joomla-logs waren veel mislukte loginpogingen te zien. Dat past bij brute-force of credential-stuffing: automatisch proberen in te loggen met bekende of geraden wachtwoorden.
Een aantal IP-adressen sprongen eruit:
51.79.180.236 600 pogingen
146.70.98.109 83 pogingen
130.195.221.166 73 pogingen
169.150.208.180 63 pogingen
188.214.122.88 62 pogingen
109.111.197.20 52 pogingen
159.26.107.10 41 pogingen
138.199.33.241 41 pogingen
74.118.126.17 36 pogingen
159.26.107.55 24 pogingen
180.149.228.70 20 pogingen
Vooral 51.79.180.236 viel op door het hoge aantal mislukte Joomla-logins. In totaal waren er 1.129 joomlafailure-regels gevonden in de Joomla-logs.
Dat bewijst nog niet dat dit specifieke IP-adres de webshell heeft geplaatst. Maar het laat wel zien dat de website actief werd aangevallen.
En dat is precies het probleem met oude CMS-websites: ze worden niet pas aangevallen als iemand jouw bedrijf kent. Ze worden aangevallen omdat bots automatisch zoeken naar bekende zwakke plekken.
Wat gebeurt er als de aanvaller eenmaal op de webserver zit?
Vanaf dat moment verandert de situatie compleet.
Voor de ondernemer voelt het misschien nog als “mijn website is gehackt”. Maar technisch gezien moet je denken: “iemand heeft mogelijk toegang gehad tot mijn hostingomgeving.”
Dat betekent dat je niet alleen het verdachte bestand moet verwijderen. Je moet jezelf afvragen:
- Heeft de aanvaller de databaseconfiguratie gezien?
- Zijn er databasewachtwoorden gelekt?
- Zijn er extra administratoraccounts aangemaakt?
- Zijn er nieuwe PHP-bestanden geplaatst?
- Zijn er cronjobs toegevoegd?
- Zijn er redirects geplaatst in
.htaccess? - Zijn er phishingpagina’s geüpload?
- Zijn er mailfuncties misbruikt?
- Zijn andere websites op dezelfde hosting geraakt?
- Is de website onderdeel geworden van spam, malware of een botnet?
Een webshell is vaak niet het eindpunt van de aanval.
Het is het begin van controle.
Waarom “we halen het bestandje weg” niet genoeg is
Dit is de grootste fout die vaak wordt gemaakt.
Een hoster of beheerder vindt een vreemd bestand, verwijdert het en zet de website weer online.
Maar als de ingang nog openstaat, is de website morgen opnieuw besmet.
Bij een JCE-achtig lek kan het probleem bijvoorbeeld zitten in een kwetsbare extensie. Bij een brute-force-aanval kan het probleem zitten in een zwak wachtwoord. Bij FTP-misbruik kan het probleem zitten in gelekte hostinggegevens. En bij een verkeerd ingerichte server kan het probleem zitten in mappen waar PHP helemaal niet zou mogen draaien.
Daarom moet je bij een webshell altijd denken in twee lagen:
Eerst de schade beperken.
Daarna de ingang sluiten.
Doe je alleen het eerste, dan ben je aan het dweilen terwijl de kraan openstaat.
Waarom een WAF hier zo belangrijk is
Een WAF, een Web Application Firewall, zit vóór je website.
Die kijkt naar het verkeer dat binnenkomt en probeert verdachte requests tegen te houden voordat ze Joomla, WordPress of een andere applicatie bereiken.
Dat is belangrijk, want bij kritieke lekken is snelheid alles.
Een CMS-update of extensie-update moet natuurlijk gebeuren. Maar in de praktijk lopen veel websites achter. Soms omdat niemand het onderhoud doet. Soms omdat een update de site kan breken. Soms omdat de klant niet eens weet welke extensies er draaien.
Een WAF kan dan helpen als preventieve laag.
Niet als wondermiddel. Niet als excuus om nooit meer te updaten. Maar wel als extra beschermlaag die verdachte patronen, bekende exploitpogingen, rare uploadrequests, afwijkende URL’s en ongewenste bestandsuitvoering kan blokkeren voordat ze de website bereiken.
En dat is precies waar BeterBeschermd.com voor bedoeld is.
Wat doet BeterBeschermd wel en niet?
BeterBeschermd is geen belofte dat je website nooit meer geraakt kan worden.
En BeterBeschermd is ook geen forensische onderzoeksdienst die standaard malware-analyses, opschoonrapporten of diepe incidentresponse uitvoert.
De kracht zit juist aan de voorkant.
Preventie.
Een WAF-oplossing die vóór de website wordt geplaatst, zodat aanvallen niet direct op je kwetsbare Joomla-, WordPress- of maatwerksite landen. Zeker bij oudere websites, legacy-systemen of websites waar updates lastig zijn, kan zo’n extra laag het verschil maken tussen “aanval geblokkeerd” en “webshell geüpload”.
Als er echt iets mis is, kan er natuurlijk worden gekeken naar een passende oplossing. Maar het uitgangspunt blijft:
Beter preventief dan als redmiddel.
De les van deze aanval
Een kritieke kwetsbaarheid in een Joomla-extensie is geen theoretisch probleem.
Het kan betekenen dat een aanvaller zonder normale beheerlogin code op de server krijgt. Die code kan een webshell worden. Die webshell kan leiden tot servertoegang. En servertoegang kan leiden tot datadiefstal, spam, phishing, malware, reputatieschade en een website die onderdeel wordt van een botnet.
De website hoeft daarbij niet eens direct stuk te zijn.
Sterker nog: de gevaarlijkste hacks zijn vaak de hacks waarbij de website gewoon blijft werken.
Want zolang niemand iets merkt, blijft de achterdeur open.
Conclusie
Een Joomla-site met oude extensies, uploadmogelijkheden en geen extra beschermlaag is een aantrekkelijk doelwit.
Niet omdat jouw bedrijf per se beroemd is. Maar omdat bots continu zoeken naar bekende lekken. Als jouw website daarop reageert, ben je aan de beurt.
Een WAF voorkomt niet dat onderhoud nodig is. Maar het zorgt wel voor een belangrijke extra verdedigingslaag vóór je website. Juist bij kritieke lekken, zero-days en oude CMS-omgevingen kan dat het verschil maken.
Daarom is het slimmer om je website vooraf te beschermen dan pas in actie te komen als er al een webshell staat.




