Un an de acces neautorizat, descoperit în prima săptămână de mentenanță

Un email obișnuit de contact, primit prin formularul de pe site-ul nostru: un site cu două subdomenii construite pe WordPress, lăsat fără mentenanță de câteva luni, „nefuncțional” pe alocuri. Genul de solicitare pe care o primim frecvent — un site de prezentare pentru o firmă de arhitectură și dezvoltare imobiliară, cu portofoliul de proiecte afișat pe unul din subdomenii, un al doilea subdomeniu cu conținut suplimentar. Nimic, la prima vedere, ieșit din comun.

Ce a urmat, în prima săptămână de acces la cont, a fost una dintre cele mai extinse investigații de securitate pe care le-am făcut anul acesta — nu pentru că am căutat probleme, ci pentru că fiecare strat pe care îl curățam scotea la iveală încă unul dedesubt. Povestim cazul, anonimizat, pentru că tiparul descoperit acolo nu e unic — e, din păcate, exact genul de situație în care se pot regăsi mulți proprietari de site-uri WordPress lăsate „pe pilot automat” prea mult timp.

Simptomul inițial, mult mai mic decât problema reală

Reclamația inițială a clientului era punctuală: paginile individuale de proiecte imobiliare de pe unul din subdomenii nu afișau corect informația — apărea doar o imagine și un titlu, fără suprafață, valoare investiție, sau descrierea proiectului, câmpuri care ar fi trebuit să fie acolo. Ipoteza inițială, complet rezonabilă din perspectiva unui client fără cunoștințe tehnice: „ceva s-a stricat”, posibil o problemă de licență la un plugin premium folosit pentru construirea acelor pagini.

Diagnosticul tehnic a confirmat rapid că nu era vorba despre o licență expirată — șablonul folosit pentru acele pagini exista, licența era validă, dar conținutul efectiv al șablonului era incomplet, ca și cum cineva ar fi construit doar jumătate din structură și ar fi lăsat restul necompletat. O problemă de conținut, nu una tehnică de configurare — genul de lucru care, în mod normal, ar cere doar o reconstrucție punctuală a acelui șablon specific.

Dar pentru a înțelege exact ce ar fi trebuit să conțină acel șablon, aveam nevoie de acces complet la cont — și odată ajunși acolo, imaginea s-a schimbat complet.

Primul semnal serios: un fișier care nu ar fi trebuit să existe

Printre fișierele din directorul principal al site-ului, un fișier cu numele „.hta” — nu genul de nume pe care WordPress sau vreun plugin legitim l-ar genera vreodată. Codificat în base64, o tehnică standard de ascundere folosită pentru a face codul periculos ilizibil la o inspecție rapidă. Decodificat, fișierul se dovedea a fi o poartă de acces ascunsă (backdoor), construită specific pentru o tehnică numită „cloaking” — afișarea unui conținut complet diferit pentru motoarele de căutare (Google, în principal) față de ce vedea un vizitator normal, și redirecționarea vizitatorilor veniți din rezultatele de căutare către pagini spam, controlate de un server extern.

Practic, oricine căuta pe Google ceva legat de site-ul clientului risca să fie redirecționat, fără să știe, către conținut complet nelegat de afacerea reală — un tipar clasic de abuz „negative SEO”, care nu doar afectează reputația site-ului compromis, ci poate duce, în timp, la penalizări din partea Google, odată ce acest comportament e detectat automat.

A doua descoperire: o poartă de acces completă, nu doar o redirecționare

Verificând jurnalele de erori ale serverului, am găsit urme ale unui fișier numit generic, ascuns printre fișierele normale ale unuia dintre subdomenii — un webshell, adică o unealtă completă care oferă unui atacator control aproape total asupra site-ului: încărcare de fișiere noi, executare de comenzi, modificare de conținut, totul de la distanță, fără nicio autentificare legitimă necesară. Jurnalele arătau exact momentul în care acest fișier fusese folosit pentru a încerca scrierea altor fișiere periculoase pe server.

Am șters acel webshell, dar căutarea nu s-a oprit acolo. Pe același subdomeniu, alte două fișiere goale, rămășițe ale unor încercări eșuate de a planta payload-uri suplimentare — semn că atacatorul, sau atacatorii, reveniseră de mai multe ori, nu într-un singur incident izolat.

Verificând și celelalte două instalări WordPress separate ale aceluiași cont (site-ul principal și al doilea subdomeniu), tiparul s-a repetat: încă un webshell, de data asta deghizat sub un nume care imita un fișier legitim de WordPress, dar plasat într-un director greșit — exact genul de detaliu care trădează un fișier periculos pentru cineva care știe ce caută, dar trece complet neobservat pentru un ochi neantrenat. Verificat separat, printr-un antivirus local, fișierul a fost confirmat și clasificat explicit drept o amenințare severă, de tip acces complet la distanță.

Un cont de administrator „legitim”, deturnat complet

Una dintre cele mai importante descoperiri ale investigației nu a fost tehnică, ci contextuală: un cont de administrator WordPress, activ pe unul din subdomenii, care la prima vedere părea suspect — un nume străin, fără nicio legătură aparentă cu afacerea. Ipoteza inițială, evidentă: un cont fals, creat de atacator pentru acces persistent.

Investigând istoricul contului, realitatea era mai complicată și, într-un fel, mai îngrijorătoare: acel cont nu era fals — era contul original al dezvoltatorului care construise site-ul, cu ani în urmă, folosit legitim pentru paginile inițiale ale site-ului. Contul rămăsese activ, cu drepturi depline de administrator, mult timp după ce relația cu acel dezvoltator se încheiase, probabil, iar parola lui, la un moment dat, fusese compromisă — un scenariu extrem de comun, mai ales dacă acea parolă fusese refolosită și în altă parte, compromisă printr-o breșă complet neconectată la site-ul clientului nostru.

Odată recuperat controlul asupra acelui cont, atacatorul îl folosise pentru a publica aproape șaptezeci de articole spam pe blogul site-ului, plus o pagină întreagă dedicată promovării unor site-uri de pariuri online, în mai multe limbi diferite — italiană, cehă, poloneză, franceză, turcă — clasicul tipar de „spam farming”, în care un site legitim, cu autoritate reală în ochii motoarelor de căutare, e exploatat pentru a împinge artificial vizibilitatea unor pagini complet nelegate de afacerea reală.

Cel mai îngrijorător aspect: activitatea nu era un incident vechi, închis — ultimele articole spam publicate aveau doar câteva zile vechime față de momentul investigației noastre. Accesul neautorizat era, la momentul descoperirii, încă activ.

De ce nimeni nu observase, atât de mult timp

O întrebare firească: cum a putut o compromitere de o asemenea amploare — webshell-uri multiple, un cont de administrator deturnat, aproape șaptezeci de articole spam publicate — să rămână complet neobservată atât de mult timp? Răspunsul, descoperit treptat pe parcursul investigației, ține de o combinație nefericită de decizii tehnice mai vechi.

Printre fișierele funcționale ale site-ului, am găsit un mic modul (mu-plugin, tehnic vorbind — un tip special de plugin care rulează mereu, indiferent de activările manuale obișnuite) care avea un singur rol: dezactivarea completă a tuturor actualizărilor automate ale WordPress — nucleu, plugin-uri, teme, traduceri. Nu era, în sine, un fișier periculos sau malițios — părea, mai degrabă, o decizie tehnică luată la un moment dat de un dezvoltator anterior, poate din dorința de a controla manual momentul actualizărilor, o practică nu neapărat greșită în sine, dar extrem de riscantă fără o disciplină strictă de verificare și aplicare manuală ulterioară a acelor actualizări.

Fără actualizări automate și, aparent, fără nicio verificare manuală constantă, câteva plugin-uri instalate pe cele trei site-uri rămăseseră mult timp la versiuni vechi, vulnerabile — inclusiv unul cu un istoric public, documentat, de vulnerabilități critice grave, exact genul de plugin care, lăsat neactualizat, devine o poartă de intrare relativ simplă pentru cineva care scanează activ internetul după exact acest tip de vulnerabilitate cunoscută.

Combinația completă — actualizări dezactivate structural, un plugin vulnerabil neactualizat, și o parolă de administrator veche, probabil refolosită și compromisă altundeva — a creat exact contextul ideal pentru un acces neautorizat persistent, nedetectat luni de zile, poate chiar mai mult de un an, așa cum a arătat, ulterior, verificarea datelor exacte ale fișierelor periculoase găsite.

Cronologia reală, reconstituită din urme tehnice

Una dintre cele mai revelatoare descoperiri ale întregii investigații a venit, surprinzător, dintr-un backup vechi, păstrat pe hosting-ul anterior al clientului. Verificând acel backup pentru a recupera conținutul original al șablonului de proiecte imobiliare — subiectul care declanșase, inițial, întreaga solicitare — am descoperit că backup-ul respectiv conținea deja aceleași fișiere periculoase găsite în timpul curățării live, cu marcaje de timp clare.

Cel mai vechi fișier periculos identificat avea o dată de modificare cu aproape un an înainte de momentul în care clientul ne-a contactat inițial — ceea ce înseamnă că accesul neautorizat inițial se produsese cu mult timp înainte ca activitatea vizibilă (spam-ul publicat recent) să atragă, în sfârșit, atenția cuiva. Timp de aproape un an, cineva avusese, teoretic, acces complet la server, fără ca nimeni să observe — iar activitatea vizibilă din urmă cu câteva zile fusese, probabil, doar cea mai recentă „valorificare” a unui acces care exista, tăcut, de foarte mult timp.

Curățarea, pas cu pas, cu backup înainte de fiecare etapă majoră

Procesul de curățare a urmat o disciplină strictă, esențială pentru orice intervenție de acest tip: niciun pas ireversibil fără un backup complet, verificat, făcut înainte. Am descărcat local o copie completă a întregului cont, fișiere și baze de date, înainte de a începe orice modificare — o măsură de siguranță standard, dar cu atât mai importantă într-o situație în care nu știam încă, cu certitudine, cât de extinsă era compromiterea.

Am șters, pe rând, fiecare fișier periculos identificat pe cele trei instalări WordPress separate ale contului — webshell-urile găsite, fișierele goale rămase din încercări eșuate, modulul care dezactiva actualizările automate, și alte câteva fișiere suspecte găsite în directoare neobișnuite pentru conținut legitim WordPress. Am rotit complet toate cheile secrete de securitate ale WordPress (folosite pentru criptarea sesiunilor de autentificare) pe toate cele trei instalări, și am schimbat parolele bazelor de date — o măsură esențială pentru a invalida orice sesiune sau acces persistent care ar fi putut supraviețui doar ștergerii fișierelor.

Contul de administrator deturnat a primit o parolă complet nouă, iar adresa de email principală a site-ului, care aparținea tot dezvoltatorului original, nu clientului, a fost schimbată către o adresă controlată direct de client — un detaliu tehnic mic, dar cu implicații serioase de securitate, pentru că orice cerere de resetare a parolei ar fi ajuns, altfel, la o adresă asupra căreia clientul nu avea niciun control real.

Am actualizat, pe toate cele trei instalări, nucleul WordPress și toate plugin-urile la versiunile cele mai recente disponibile, eliminând exact vulnerabilitățile care permiseseră, foarte probabil, accesul inițial. Am forțat, de asemenea, redirecționarea completă către HTTPS pe toate cele trei domenii — o măsură de bază, dar care, surprinzător, nu era activă anterior.

Reconstrucția problemei inițiale, abia acum posibilă

Abia după finalizarea completă a curățării de securitate ne-am putut întoarce la problema inițială raportată de client — șabloanele incomplete de proiecte imobiliare. Pentru a reconstrui corect structura completă a acelor pagini, aveam nevoie de o referință funcțională, de dinainte ca problema să apară.

Hosting-ul anterior al clientului avea, din fericire, un sistem de backup-uri automate zilnice, cu istoric de câteva luni în urmă. Am restaurat, într-un mediu separat, izolat, complet nelegat de site-ul live, o copie a site-ului dintr-un moment în care șablonul respectiv funcționa corect — recuperând, astfel, structura exactă a câmpurilor lipsă: statutul proiectului, perioada de execuție, suprafața desfășurată, valoarea investiției, serviciile prestate. Informație pe care am confirmat-o, suplimentar, verificând și versiunea arhivată public a acelor pagini, așa cum apăreau înainte să se strice, exact pentru a ne asigura că reconstrucția reflectă fidel conținutul original, nu o presupunere aproximativă.

Interesant, chiar și acest mediu de testare izolat, folosit strict pentru recuperarea informației, a scos la iveală încă alte două fișiere periculoase, ascunse în structura backup-ului vechi — semn suplimentar al amplorii reale a compromiterii, detectate automat de sistemul nostru de monitorizare de securitate, activ constant pe toată infrastructura pe care lucrăm, exact genul de protecție discutată în ghidul despre găzduirea inclusă în pachetele noastre.

Rezultatul final și raportul complet către client

La finalul intervenției, am trimis clientului un raport tehnic complet — nu doar o listă seacă de acțiuni, ci o explicație clară a fiecărei descoperiri, a cronologiei reconstituite, și a motivului pentru care fiecare măsură fusese necesară. Transparența completă, chiar și atunci când veștile nu sunt neapărat plăcute, rămâne, în opinia noastră, singura abordare corectă într-o situație de securitate — clientul are dreptul să înțeleagă exact ce s-a întâmplat cu propriul site, nu doar să primească asigurarea vagă că „acum totul e bine”.

Șabloanele de proiecte imobiliare au fost reconstruite complet, cu toate câmpurile funcționale, pe site-ul live. Toate cele trei instalări WordPress rulează acum pe versiuni actualizate, cu actualizări automate active din nou. Contul de administrator compromis a fost securizat, iar adresa de email principală a site-ului corectată. Toate cele trei domenii forțează acum conexiuni criptate complete.

Discuția despre cost, și de ce am ales să nu urmăm cifra inițială

Diagnosticul inițial, înainte de a avea acces complet la cont, sugerase o intervenție relativ punctuală — repararea unui șablon incomplet, plus configurarea unei mentenanțe continue de bază. Pe măsură ce amploarea reală a compromiterii a devenit clară, am recalculat intervenția ca pe un proiect separat, cu un cost unic, dincolo de abonamentul lunar de mentenanță pe care clientul îl alesese deja — reflectând timpul real investit în investigație, curățare completă pe trei instalări separate, și reconstrucția conținutului pierdut.

Clientul a avut de ales, la finalul intervenției, între a achita acea taxă unică suplimentară sau a continua exclusiv cu abonamentul lunar de mentenanță deja activ. A decis să renunțe la a doua opțiune, păstrând doar abonamentul de bază — o decizie pe deplin legitimă din partea lui, iar noi am respectat-o fără nicio presiune ulterioară. Munca de curățare fusese deja făcută, corect și complet, indiferent de decizia finală asupra facturării — pentru că siguranța site-ului unui client nu poate fi condiționată retroactiv de o negociere de preț, odată ce problema fusese deja identificată și trebuia rezolvată.

Menționăm acest aspect nu ca reclamă pentru generozitate, ci pentru că ilustrează o distincție pe care o considerăm esențială în relația cu orice client: diagnosticul și intervenția de urgență, atunci când e vorba despre securitatea reală a unui site aflat sub acces neautorizat activ, nu așteaptă finalizarea unei negocieri comerciale. Rezolvi întâi problema, discuți costul după — nu invers.

Ce înseamnă acest caz pentru orice site „lăsat un timp”

Tentația de a amâna mentenanța unui site care „pare că funcționează bine” e complet firească, mai ales pentru o afacere concentrată pe activitatea ei principală, nu pe detalii tehnice ale unui site construit cu ani în urmă. Cazul descris aici arată exact de ce această tentație poate deveni costisitoare: un site poate găzdui, tăcut, luni sau chiar ani de acces neautorizat activ, fără niciun semn vizibil pentru vizitatorul obișnuit sau chiar pentru proprietarul afacerii — până în momentul în care activitatea atacatorului devine, dintr-un motiv sau altul, suficient de vizibilă încât să nu mai poată fi ignorată.

Diferența dintre acest scenariu și unul cu final mult mai grav — pierderea completă a datelor, folosirea site-ului pentru distribuirea activă de malware către proprii vizitatori, sau o penalizare severă din partea Google pentru conținutul spam publicat — a ținut, în acest caz, mai mult de noroc decât de o descoperire timpurie intenționată. Clientul a apelat la noi pentru o problemă complet diferită, minoră în aparență, iar investigația extinsă a fost declanșată de diligența procesului nostru standard de acces la cont, nu de o suspiciune specifică asupra unei probleme de securitate.

E exact motivul pentru care recomandăm constant o verificare de securitate completă, nu superficială, la începutul oricărei colaborări noi de mentenanță — indiferent cât de „minoră” pare solicitarea inițială a clientului, indiferent cât de normal pare să funcționeze site-ul la prima vedere. Problema raportată e, adesea, doar vârful vizibil al unei situații mult mai complexe, îngropate în straturi pe care nimeni nu s-a mai gândit să le verifice.

Lecțiile reale ale acestui caz

Câteva concluzii merită reținute, dincolo de specificul acestui caz particular. Un site „care arată că funcționează” nu înseamnă un site nesigur — funcționarea vizuală normală și securitatea reală sunt complet independente una de cealaltă, iar un atacator competent evită, de regulă, activ orice modificare vizibilă care ar putea atrage atenția prematur.

Dezactivarea actualizărilor automate, chiar dacă motivată de intenții rezonabile la momentul deciziei, cere o disciplină de compensare la fel de riguroasă — verificare și aplicare manuală constantă — pe care puțini proprietari de site-uri o mențin realist, în timp, fără un serviciu dedicat de mentenanță continuă.

Conturile de administrator create de dezvoltatori anteriori, păstrate active mult timp după încheierea colaborării, reprezintă un risc real, adesea complet ignorat — o revizuire periodică a listei complete de utilizatori cu drepturi de administrator, discutată și în ghidul complet de securizare WordPress, ar fi putut semnala problema cu mult timp înainte de a deveni o breșă activă.

Și, poate cel mai important, un backup vechi, păstrat necontrolat pe un hosting anterior, poate deveni el însuși o sursă de reinfectare, dacă e restaurat fără o verificare de securitate prealabilă — exact motivul pentru care orice restaurare, chiar și una parțială, făcută în scop de recuperare a conținutului, ar trebui tratată cu aceeași precauție ca orice altă operațiune tehnică sensibilă asupra unui site.

Dacă bănuiești că site-ul tău ar putea ascunde probleme similare — mai ales dacă a trecut prin perioade lungi fără nicio mentenanță activă — scrie-ne. Un diagnostic real nu pornește niciodată de la presupunerea că „probabil e în regulă”, ci de la verificarea efectivă a fiecărui strat, exact așa cum am făcut și în acest caz.

Mastodon