Skip to content

Hunting Dictionary Bots: Inside a Sophisticated WordPress Membership Attack

Posted on:May 27, 2026 at 12:00 PM

A screenshot of a WordPress membership signup form with a CAPTCHA and a WAF blocking a dictionary bot

Automated registration spam is shifting away from traditional brute-force tactics. Standard security layers often fail against modern bot scripts that pass visual challenges and bypass baseline web application firewalls. These advanced campaigns mimic legitimate human patterns to compromise open registration endpoints.

This post examines the mechanics of Dictionary Attack Bots, details the concrete risks they pose to membership platform integrity, and provides implementation code to secure your user tables.

The Membership Threat: Impact by the Numbers

Allowing automated registrations to pool in your database creates immediate operational hazards:


Anatomy of the Exploit: Dictionary Word Pairing

Traditional registration scripts rely on randomized character strings (e.g., xj947_ktr). Modern security filters identify and block these strings easily. To circumvent detection, this script uses coordinated dictionary pairings.

The bot engine generates identifiers by combining two distinct English dictionary terms, appended with a single or double digit: [Noun/Adj] + [Noun] + [Digit]. This structure targets validation suites that assume standard dictionary terms indicate human input.

Data from an active database trace reveals clear structural patterns across separate registration batches:

User IDRegistered UsernameTarget Domain NameStructural Formula
4372basketoption7koiot.de[Noun] + [Noun] + [Digit]
3537basketperch1koiot.de[Noun] + [Noun] + [Digit]
4341basketriver9koiot.de[Noun] + [Noun] + [Digit]
4481basketwomen0koiot.de[Noun] + [Noun] + [Digit]
4528actman4koiot.de[Noun] + [Noun] + [Digit]
N/Aadultmiddle4calculator.city[Adj] + [Noun] + [Digit]
N/Aactormuseum8bitingmites.org[Noun] + [Noun] + [Digit]

The script rotates target domains across separate waves, altering infrastructure footprints while maintaining the underlying username generation logic. The email handles often use standard human name formats (e.g., [email protected]) to blend in with valid registrations.


Defensive Engineering: Programmatic Remediation

Because these registration payloads exist entirely within the body of incoming POST requests, standard proxy layers cannot always parse or drop them based on payload content alone. Remediating this threat requires a defense-in-depth approach across your technical stack.

1. Application Layer Domain Restrictions

The fastest method for stopping active registration waves involves validating the registration array directly inside WordPress. Hooking into the registration_errors filter intercepts the registration process before the application executes a database transaction.

/**
 * Restrict known malicious domains from creating WordPress user accounts.
 * Drops the registration request before hitting the database.
 */
add_filter('registration_errors', 'devcharms_restrict_spam_domains', 10, 3);
function devcharms_restrict_spam_domains($errors, $sanitized_user_login, $user_email) {
    $banned_domains = [
        '24faw.com',
        'igtikrenai.com',
        'koiot.de',
        'temz.net',
        'emailmin.com',
        'calculator.city'
    ];

    $email_parts = explode('@', $user_email);
    $domain      = end($email_parts);

    if (in_array(strtolower($domain), $banned_domains)) {
        $errors->add(
            'banned_domain_error',
            __('<strong>ERROR</strong>: Registration parameters rejected.')
        );
    }

    return $errors;
}

2. Remediate Existing Users (Purge the Spam Already Inside)

Once these accounts exist, blocking new registrations won’t fix the damage already done to your tables and analytics. The simplest remediation path is to go to Admin → Users, search by the offending domain (for example @koiot.de), and bulk-delete the matching accounts.

This approach (Admin UI bulk delete or WP-CLI) is almost always safer than “just deleting rows” in the database. User emails and IDs can be duplicated across core and plugin tables, and a manual DB purge can leave orphaned metadata, broken relationships, or stale activity records—especially on community sites running BuddyPress, bbPress, membership plugins, or LMS/ecommerce add-ons.

Common places these users can persist include:

If you have WP-CLI access, you can do the same cleanup much faster from the command line by deleting users whose email matches a domain pattern:

wp user delete $(wp user list --search="*@koiot.de" --field=ID)