Find and Remove Malicious Code

Find and Remove Malicious Code (Hacked WP Plugin Scripts)

Storyteller Media covers SEO, online business, and marketing. When you use our links, we may earn an affiliate commission. Learn more

Earlier today I had notifications from Malcare that five of my sites had been hacked. As I dove in, I found two unique scripts had been inserted into these sites.

Malcare, String locator, and phpMyAdmin helped me successfully find and remove malicious code from five WordPress sites. Here’s how I did it.

malicious eval code on wordpress site

Find Malicious Malware Code

We use three layers of security to keep our portfolio of sites safe.

We’ve been Malcare customers for many years. And about 5 years ago, we added Patchstack as an additional layer. And our host, Cloudways, also has a function to identify security risks with installed plugins.

It was the Malcare app that discovered this hack and notified me by email twice.

In tracking this hack, I found that old plugins (that I uninstalled years ago) remained in the WordPress install. And it was one of these that created a security risk on my sites.

Find and Remove Malicious Code
This is a screenshot of the message inside of my Malcare account.

Social Warfare was the source of the hack across all 5 sites.

Here is the code that showed up on two of my sites:

malicious eval code wordpress wp_options
Here’s a screenshot of malicious eval code that was injected into my WordPress wp_options table

And this code showed up on three sites. This was all in the same location (social_warfare inside of wp_options).

To remove the hack, I deleted the six related tables generated by the Social Warfare plugin.

  • social_warfare_settings
  • widget_swp_popular_posts_widget
  • social_warfare_dismissed_notices
  • swp_json_cache
  • socialWarfareOptions
  • swp_registered_options

Locating the String of Malicious Code

When I searched for the code inside of phpMyAdmin, I was unable to locate it. Malcare was able to identify that it was in wp_options but that was all. I asked hosting tech support to locate it, and they were also unable. But they did recommend the plugin String locator – which worked great.

To find the location of the string, I used the String locator plugin and I searched in All database tables, with the search string >eval(

Of course, the search string will vary depending on the script that you’re looking for.

This brought up the single result.

String locator search result
String locator search result

4 Ways to Remove Malicious Code from WordPress

There are four ways to remove the problem code. These methods involve editing or deleting tables:

  1. Edit: You can manually edit the database entry by clicking on the link in the File/Table column. I don’t recommend this because there is the potential to really mess things up.
  2. Edit: You can copy the ID / Line number and look that up under phpMyAdmin (accessed via your host). In my search result, the line number was 193659, but yours will be different. When the corresponding line comes up, click Edit. You should be able to locate the script in the option_value. You can delete this from here, but I don’t recommend it. This is similar to option 1.
  3. Delete: Inside of phpMyAdmin, select the option_id that has the problem code. Then, click Delete. In my case, I searched again for social_warfare (and the variant swp), found five more line numbers, selected them both, and deleted them.
  4. Edit/Delete: Click Clean All Malware inside of Malware.com
String locator code location wordpress
Notice the database location, as identified by String locator.
locate wordpress wp_options malicious code
I copied and pasted the line ID into phpMyAdmin and located the corrupted table.
delete malicious wordpress code
And then I deleted the malicious WordPress code that was injected into the old plugin

Learn more about the WordPress wp_options table.

4 Things to Know When Editing wp_options

There are a couple of things you need to know before you start editing or deleting database entries.

  1. Make a full site backup before starting. My host WPEngine has that built-in function – running backups every 24 hours. And Malcare also takes a daily backup. This way, if my database editing goes wrong, I can restore the most recent version of my site.
  2. A note about Check All option in phpMyAdmin. Even if only two fields are showing, the Check All box will select every option_id, including those that aren’t visible on screen. This will do more than just break your site – it will delete the whole structure and it will need to be restored or rebuilt. Be careful inside of phpMyAdmin.
  3. Make sure that you don’t delete an option_id entry for a plugin that is fundamental to the function of your site. Deleting entries in phpMyAdmin can make a mess of your site.
  4. When searching the wp_options tables, the search function is lazy. To fix this, go to Number of Rows, select 500, then scroll to the bottom. Now return to the top, and the search feature will now find everything on that page.

After deleting the option_id (or the automated Malcare function), run the String locator query again. It should come back with this message: “Your search was completed, but no results were found.”

String locator no bad scripts found wordpress
String locator no bad scripts found wordpress

Keeping your Database Clean

As I started digging, I realized that there were too many option_id entries. This site was first started in 2018 and I’ve used many plugins over the years. And they are all resident in wp_options.

Here are some that I found for plugins and themes that I’m no longer using.

  1. Social Warfare: 6 option_id entries
  2. Yuzo: 7 option_id entries. This Reddit entry from 2019 addresses the same malicious code problem that I had, but with the Yuzo plugin hack.
  3. OptinMonster
  4. MonsterInsights
  5. Thesis Theme
  6. Updraft: 50+ option_id entries
  7. Jetpack
  8. WP SEO
  9. One Signal
  10. Genesis
  11. Yoast
  12. Ninja Tables
  13. Trellis Theme
  14. Pretty Links
  15. Ad Inserter
  16. EZ TOC
  17. Am Image Fixer

I’ve started deleting these tables, but it’s slow work. And we run a lot of sites.

While I understand why some developers leave residue behind (in case you want to reinstall and keep the settings), this is a poor practice. Every theme and plugin should have the option to fully remove each option_id from wp_options when it is deleted from the database.

Poor developer practices lead to hacks like this one. From a plugin that I stopped using years ago, but continued vulnerable to their bad coding.

Your Turn

Have you discovered a hack or another malicious code insertion? I would love to hear how the fix went for you.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

Ready to Increase Site Earnings?

To get started, please book a Discovery Call. You’ll learn about our services and we’ll learn about your goals and challenges. We’ll see if your needs and our skills are a good fit. Your call will be with Bryan.

Your Discovery Call is the first step to generating more revenue with your site.

If you already know what you need, you can order those services here. These services include SEO audits, new site builds, and other marketing and SEO services.