How a Simple Vulnerability Scan Crashed My Server – And How I Fixed It

How an automated hacking attempt brought down my WordPress site, and the step-by-step security hardening that prevented it from happening again.

The Silent Crash

It started with a familiar WordPress error that every site owner dreads: “Error establishing a database connection.” My site was completely down. No warning, no gradual slowdown – just offline.

Little did I know that this wasn’t a hosting issue or misconfiguration, but rather a security incident that had been brewing for hours.

The Investigation Begins

Step 1: Immediate Diagnosis

systemctl status mysql
# Output: inactive (dead)

MySQL had crashed. A simple restart brought the site back, but that was just treating the symptom. I needed the root cause.

Step 2: Digging into the Logs

The MySQL error log revealed the smoking gun:

2025-10-26T01:47:17.278972Z [ERROR] [InnoDB] Cannot allocate memory for the buffer pool
2025-10-26T01:47:17.280154Z [ERROR] [InnoDB] Plugin initialization aborted with error Generic error

Memory exhaustion. But why?

Step 3: Connecting the Dots

The system logs told the rest of the story:

Oct 26 01:45:15 server kernel: apache2 invoked oom-killer:
Oct 26 01:45:16 server kernel: out_of_memory: Killed process 21415 (mysqld)

The Out-of-Memory killer had terminated MySQL to save the system. But what consumed all the memory?

The Real Culprit: Automated Vulnerability Scanning

The Apache error log revealed the attack pattern:

[Tue Oct 28 07:20:46.385500 2025] script '/var/www/html/wp-content/plugins/xadm-log.php' not found
[Tue Oct 28 07:20:54.675026 2025] script '/var/www/html/wp-admin/xadm-log.php' not found
[Tue Oct 28 08:41:37.862015 2025] script '/var/www/html/wp-plain.php' not found
[Tue Oct 28 17:49:47.870481 2025] script '/var/www/html/php-info.php' not found

What was happening:

  • Automated bots were scanning for common backdoors and vulnerable files
  • Each request spawned Apache/PHP processes
  • The 1GB RAM server couldn’t handle the concurrent load
  • Memory exhaustion triggered the OOM killer
  • MySQL was the casualty

The Attack Pattern Analysis

The attackers were probing for:

  • Information disclosure: phpinfo.php, info.php, pinfo.php
  • Common backdoors: xadm-log.php, wp-plain.php, postnews.php
  • Framework vulnerabilities: app_dev.php, frontend_dev.php

Geographical distribution:

  • 51.38.121.102 (France)
  • 45.138.16.215 (Russia/Netherlands)
  • 43.157.203.73 (Hong Kong) – Most aggressive
  • And several others…

The Security Hardening Solution

1. Immediate IP Blocking

sudo ufw deny from 51.38.121.102
sudo ufw deny from 45.138.16.215
sudo ufw deny from 43.157.203.73

2. Fail2Ban Automated Protection

Configuration:

sudo nano /etc/fail2ban/jail.d/wordpress.conf
[wordpress-hard]
enabled = true
port = http,https
filter = wordpress
logpath = /var/log/apache2/error.log
maxretry = 2
bantime = 86400
findtime = 600

[wordpress-soft]

enabled = true port = http,https filter = wordpress logpath = /var/log/apache2/error.log maxretry = 5 bantime = 3600 findtime = 600

Filter definition:

# /etc/fail2ban/filter.d/wordpress.conf
[Definition]
failregex = ^.*script '.*/.*\.php' not found or unable to stat.*client <HOST>
ignoreregex =

3. Resource Optimization

MySQL memory tuning:

# /etc/mysql/my.cnf

[mysqld]

innodb_buffer_pool_size = 64M key_buffer_size = 16M tmp_table_size = 16M max_connections = 30

Apache process limiting:

# /etc/apache2/mods-available/mpm_prefork.conf
<IfModule mpm_prefork_module>
    StartServers            2
    MinSpareServers         2
    MaxSpareServers         5
    MaxRequestWorkers       30
    MaxConnectionsPerChild  1000
</IfModule>

The Results

Before Protection:

  • Downtime: could be for days unnoticed
  • Manual intervention required: Yes
  • Recurrence: Likely

After Protection:

  • Automatic blocking: IPs banned within minutes of detection
  • Zero downtime: Attacks handled automatically
  • Resource stability: No more memory exhaustion

Fail2Ban in Action:

2025-10-28 22:24:37,521 fail2ban.actions: NOTICE  [sshd] Ban 134.209.200.154
# WordPress bans now happen automatically for vulnerability scanners

Key Takeaways

  1. Monitor Your Logs: Regular log review catches attacks before they cause damage
  2. Security Through Obscurity Isn’t Enough: Even “failed” attacks can take down your server
  3. Automate Defense: Manual IP blocking doesn’t scale against distributed attacks
  4. Right-Size Your Resources: Know your server’s limits and configure services accordingly
  5. Defense in Depth: Combine Fail2Ban, firewall rules, and service hardening

Prevention Checklist

  • [ ] Install and configure Fail2Ban
  • [ ] Set up log monitoring alerts
  • [ ] Harden MySQL and Apache configurations
  • [ ] Implement a Web Application Firewall (WAF)
  • [ ] Regular security audits and updates
  • [ ] Resource monitoring with alerts

Conclusion

What seemed like a random server crash was actually a security event. The attack wasn’t sophisticated – just automated, persistent, and resource-intensive enough to overwhelm an unprepared system.

The solution wasn’t complex either: proper monitoring, automated defense, and resource management. The entire protection system was implemented with open-source tools and about an hour of configuration.

Your server will get scanned. The question isn’t if, but when – and whether you’re prepared to handle it automatically.



Posted

in

by

Tags:

Comments

Leave a Reply

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