{"id":29754,"date":"2026-06-08T08:17:00","date_gmt":"2026-06-08T07:17:00","guid":{"rendered":"https:\/\/www.web-systems.pl\/hacked-wordpress-the-first-two-hours\/"},"modified":"2026-06-08T08:17:00","modified_gmt":"2026-06-08T07:17:00","slug":"hacked-wordpress-the-first-two-hours","status":"publish","type":"post","link":"https:\/\/www.web-systems.pl\/en\/hacked-wordpress-the-first-two-hours\/","title":{"rendered":"Hacked WordPress: the first two hours and what to do next"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">A phone call at seven in the morning, the store owner on the line: the site redirects to some casino, but only from Google, because typing the address in shows everything as normal. A classic. <strong>Hacked WordPress<\/strong> rarely looks spectacular. It usually runs quietly and comes to light by accident, through a customer complaint or a warning in the search results. What you do over the next two hours decides whether the case ends in a single day or keeps coming back for a quarter.<\/p>\n\n\n\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_86 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of contents<\/p>\n<span class=\"ez-toc-title-toggle\"><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.web-systems.pl\/en\/hacked-wordpress-the-first-two-hours\/#The_first_fifteen_minutes_stop_the_damage_do_not_delete_the_evidence\" >The first fifteen minutes: stop the damage, do not delete the evidence<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.web-systems.pl\/en\/hacked-wordpress-the-first-two-hours\/#Work_out_what_kind_of_infection_this_is_three_typical_scenarios\" >Work out what kind of infection this is: three typical scenarios<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.web-systems.pl\/en\/hacked-wordpress-the-first-two-hours\/#Hour_one_evidence_from_the_logs_and_the_database\" >Hour one: evidence from the logs and the database<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.web-systems.pl\/en\/hacked-wordpress-the-first-two-hours\/#Hour_two_cleaning_up_versus_restoring_from_a_backup\" >Hour two: cleaning up versus restoring from a backup<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.web-systems.pl\/en\/hacked-wordpress-the-first-two-hours\/#Closing_the_vector_or_why_a_site_gets_hacked_a_second_time\" >Closing the vector, or why a site gets hacked a second time<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.web-systems.pl\/en\/hacked-wordpress-the-first-two-hours\/#Consequences_beyond_the_server_Google_email_personal_data\" >Consequences beyond the server: Google, email, personal data<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.web-systems.pl\/en\/hacked-wordpress-the-first-two-hours\/#What_to_do_so_the_next_incident_does_not_start_from_zero\" >What to do so the next incident does not start from zero<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/www.web-systems.pl\/en\/hacked-wordpress-the-first-two-hours\/#Summary\" >Summary<\/a><\/li><\/ul><\/nav><\/div>\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_first_fifteen_minutes_stop_the_damage_do_not_delete_the_evidence\"><\/span>The first fifteen minutes: stop the damage, do not delete the evidence<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The reflex is always the same: find the strange files and delete them. And that is where the problem starts, because by deleting them you destroy the only material that would let you reconstruct the entry vector later. Without the modification date and without the contents of the uploaded script you are left guessing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The order that works: first cut off traffic, with maintenance mode or a rule on the web server. Then a snapshot of the whole directory and a dump of the database in its infected state. Only then start cleaning up, whether on your own or by outsourcing <a href=\"https:\/\/www.web-systems.pl\/en\/removing-viruses-from-a-website\/\">malware removal from your site<\/a> to someone who does it every day.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The snapshot has to land outside the production server. An archive sitting next to wp-content disappears along with everything else during a restore or, worse, gets read by the attacker. Do not change passwords before you have secured the logs &#8211; anyone with an active session is inside anyway, and you will lose records that the server does not keep forever.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Work_out_what_kind_of_infection_this_is_three_typical_scenarios\"><\/span>Work out what kind of infection this is: three typical scenarios<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The first variant is SEO spam living in the database. Redirects fire only for Googlebot or for traffic arriving from a search engine, hidden links sit in wp_options and wp_posts, and the owner browsing their own site sees nothing. Hence those reports coming from customers rather than from the editors.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The second is a backdoor in the files: code appended to the end of wp-config.php, a planted file pretending to be part of wp-includes, a single PHP script in the uploads directory, where no PHP has any business being. The third scenario is the simplest and the most often dismissed &#8211; a compromised administrator account or a freshly added user with that role, usually with an email address in an unfamiliar domain.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Hosting symptoms can be misleading. A sudden spike in transfer and a clogged mail queue are usually not a server failure but your own site sending out spam. Check that before the conversation turns to website maintenance and a move to a bigger package.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Hour_one_evidence_from_the_logs_and_the_database\"><\/span>Hour one: evidence from the logs and the database<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Access logs lined up against file modification dates can narrow the moment of entry down to a few minutes. You are looking for POST requests aimed at files in uploads or at oddly named scripts in the plugins directory. That is the most common first lead and it usually points straight at the vulnerable component.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the database you check a few places in a set order, starting with the most likely one:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>wp_users and wp_usermeta<\/strong> &#8211; the list of accounts, registration dates, assigned roles, especially entries added after the date from the logs.<\/li>\n<li><strong>wp_options with autoload = yes<\/strong> &#8211; this is where code that runs on every request lands, often base64 encoded.<\/li>\n<li><strong>Scheduled cron jobs<\/strong> &#8211; an entry that recreates the backdoor after every cleanup.<\/li>\n<li><strong>wp_posts and wp_postmeta<\/strong> &#8211; injected links, hidden blocks, swapped content in old posts.<\/li>\n<li><strong>API keys and integration credentials<\/strong> &#8211; treat everything that could be exported as already taken.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Hour_two_cleaning_up_versus_restoring_from_a_backup\"><\/span>Hour two: cleaning up versus restoring from a backup<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Manual cleaning only makes sense when you know the moment of entry and have a clean reference point: original core and plugin files to compare byte by byte. Without that you are scanning more than ten thousand files by eye and missing one line. Always that one line.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A backup from before the infection can be a trap too. If the backdoor sat on the server for weeks and the copy has a retention of a few days, you restore the site together with the problem and after two days you are back where you started.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When in doubt, a rebuild is safer: a fresh installation of the core and the plugins from official sources, moving over only content, media and verified child theme code. Themes and plugins from dubious sources, including &#8220;unlocked&#8221; premium versions, go on the list to be thrown out, not repaired. They have been the vector often enough that there is nothing left to discuss.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Closing_the_vector_or_why_a_site_gets_hacked_a_second_time\"><\/span>Closing the vector, or why a site gets hacked a second time<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A relapse after a few days almost always means one thing: the symptom was cleaned up, the cause stayed. The typical door left open? An outdated plugin with a publicly available exploit, an FTP account shared by three companies, a password from an old leak used again, or an API key forgotten in a repository.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Rotating the secrets covers everything at once: user passwords, the database password, the salt keys in wp-config.php, application passwords for the REST API, access to the hosting panel. A half-done swap only creates the illusion of order.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If other sites sit on the same hosting account, you check them together with the one that was attacked. The infection moves between directories within the account and comes back from a neighboring site that nobody remembered any more. An audit like that often shows that some of those sites are candidates for modernizing an old application rather than for another round of patching.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Consequences_beyond_the_server_Google_email_personal_data\"><\/span>Consequences beyond the server: Google, email, personal data<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Search Console shows a security warning and lets you submit the site for another review once it has been cleaned. Submitting it before the infection is actually gone only drags the case out, because the verification ends in a rejection.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A domain that sent out email spam ends up on blocklists and needs separate handling. The state of the site no longer matters here, delisting runs in parallel. And if the store or the forms processed personal data, the incident has a formal dimension and someone has to assess the duty to report it. Preferably the same day.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That leaves communication. Customers and partners find out faster than the owner assumes, usually from their own browser or from a warning in the results. A short, concrete message in your own words removes half the questions. Silence generates the rest.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_to_do_so_the_next_incident_does_not_start_from_zero\"><\/span>What to do so the next incident does not start from zero<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.web-systems.pl\/en\/web-hosting-and-email-hosting\/\">Hosting with regular backups<\/a> kept off the production server, with retention counted in weeks rather than days, and with restores tested regularly. A copy nobody has ever restored is a hypothesis, not a safeguard.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Plugin updates work when they are a process: a test environment, a review of the changes, a rollout on a set rhythm. Bursts once a quarter end in a jump across twenty versions at once and a broken page layout, so nobody repeats them afterwards.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The rest is ordinary access hygiene: separate accounts instead of one shared login, two-factor authentication for the admin panel and the hosting, PHP execution blocked in the uploads directory. File integrity monitoring and an alert when the number of administrators changes cut detection from weeks to hours, and that usually decides the scale of the cleanup.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Summary\"><\/span>Summary<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The first two hours decide whether the incident closes with a one-off cleanup or turns into months of relapses. The order never changes: cut off, secure the evidence, establish the vector, and only then restore.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Hacked WordPress is usually a symptom of neglected maintenance, not bad luck. A site that is never updated, with two plugins from outside the official directory and one password shared across the whole team, will find its attacker sooner or later. A team that looks after the site itself gains a lot from <a href=\"https:\/\/www.web-systems.pl\/en\/wordpress-woocommerce-training\/\">WordPress and WooCommerce training<\/a> that covers updates and access management.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you need someone to walk through an incident like this on the technical side, or to take over site maintenance permanently, get in touch with us. We also handle audits, integrations, automation and the modernization of applications that have outgrown their original design.<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>A phone call at seven in the morning, the store owner on the line: the site redirects to some casino, but only from Google, because typing the address in shows everything as normal. A classic. Hacked WordPress rarely looks spectacular. It usually runs quietly and comes to light by accident, through a customer complaint or [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":29706,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[838],"tags":[2095,1081,2109,901,2115,1192],"class_list":["post-29754","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-wordpress-en","tag-backdoor-en","tag-how-to","tag-malware-infection","tag-security","tag-seo-spam-en","tag-wordpress-en"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.web-systems.pl\/en\/wp-json\/wp\/v2\/posts\/29754","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.web-systems.pl\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.web-systems.pl\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.web-systems.pl\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.web-systems.pl\/en\/wp-json\/wp\/v2\/comments?post=29754"}],"version-history":[{"count":0,"href":"https:\/\/www.web-systems.pl\/en\/wp-json\/wp\/v2\/posts\/29754\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.web-systems.pl\/en\/wp-json\/wp\/v2\/media\/29706"}],"wp:attachment":[{"href":"https:\/\/www.web-systems.pl\/en\/wp-json\/wp\/v2\/media?parent=29754"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.web-systems.pl\/en\/wp-json\/wp\/v2\/categories?post=29754"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.web-systems.pl\/en\/wp-json\/wp\/v2\/tags?post=29754"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}