Lots of Spam with hidden html/text defeating Spam Assassin

SYSTEM INFORMATION
OS type and version Ubuntu Linux 24.04.4
Webmin version 2.621
Usermin version 2.521
Virtualmin version 8.1.0 Professional
Theme version 26.22
Apache version 2.4.58
Package updates All installed packages are up to date

Is it just me, or does it seem like sometime in the last month spam email has become very good at defeating the SpamAssasin server in Virtualmin?

I started noticing this about a month ago, and attributed it to all the data hacks happening as well as AI spam.. But a few days ago I was poking around the logs and found warnings in the β€˜var/log/mail/log’

2026-03-27T17:05:21.770949-07:00 liberty spamd[463985]: check: dns_block_rule RCVD_IN_ZEN_BLOCKED_OPENDNS hit, creating /root/.spamassassin/dnsblock_zen.spamhaus.org (This means DNSBL blocked you due to too many queries. Set all affected rules score to 0, or use "dns_query_restriction deny zen.spamhaus.org" to disable queries)

…for all of the default SpamAssassin dnsbl lists. So after some research I found that adding

dns_server 127.0.0.1

to β€˜/etc/spamassassin/local.cf’ would fix this, which it did absolutely stop all spam email. I said β€œoh, that was the problem”.

Then 3 days later all the spam is back now. I re-checked the logs and the original 'dns_block_rule ’ errors are not there, but the spam is still getting past Spam assassin.

I started looking at the headers of the spam emails, and noticed a few things:

-Their from address, and server is never the same (not a suprise)
-They all pass the β€˜score’ and β€˜bayes’ tests

X-Spam-Status: No, score=3.5 required=5.0 tests=BAYES_50,DKIM_SIGNED,
	DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,
	HTML_FONT_LOW_CONTRAST,HTML_MESSAGE,RCVD_IN_MSPIKE_BL,
	RCVD_IN_MSPIKE_ZBI,RCVD_IN_SBL,SPF_HELO_PASS,SPF_PASS,URIBL_SBL_A

They all have a lot of hidden html/text that resembles a email communication chain back and forth between two people. I think this is what is getting it bast the SA filters. I’ve pasted a full header example below.

The majority of what is here is not visible in the email, the only visible part is the email section about Omaha Steaks…

I do not see any settings for SA to stop this other than turning on Bayes. Is there a way to combat this in SA?

Email Header:

Return-Path: <omahasteaksample@yogalevels.com>
X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on
	server.redacted.com
X-Spam-Level: ***
X-Spam-Status: No, score=3.5 required=5.0 tests=BAYES_50,DKIM_SIGNED,
	DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,
	HTML_FONT_LOW_CONTRAST,HTML_MESSAGE,RCVD_IN_MSPIKE_BL,
	RCVD_IN_MSPIKE_ZBI,RCVD_IN_SBL,SPF_HELO_PASS,SPF_PASS,URIBL_SBL_A
	autolearn=no autolearn_force=no version=4.0.0
X-Original-To: email@redacted.com
Delivered-To: email.com@server.redacted.com
Authentication-Results: redacted.com;
	dkim=pass (2048-bit key; unprotected) header.d=yogalevels.com header.i=omahasteaksample@yogalevels.com header.a=rsa-sha256 header.s=mtaxjcwx5mpom header.b=kzIYAjot;
	dkim-atps=neutral
Received: from mx1.yogalevels.com (legend9025.texasrealestatr.com [202.168.82.50])
	by redacted.com (Postfix) with ESMTP id B79216414BC
	for <email@redacted.com>; Mon, 30 Mar 2026 11:00:17 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; s=mtaxjcwx5mpom; d=yogalevels.com;
 h=Date:To:Reply-To:From:List-Unsubscribe:MIME-Version:Subject:Message-ID:
 Content-Type; i=omahasteaksample@yogalevels.com;
 bh=sjcpvaYqeIxVa5jh4CeY03/VCUx4XC2VJG2RA3uaVcg=;
 b=...redacted...
Date: Mon, 30 Mar 2026 14:00:07 -0400
To: email@redacted.com
Reply-To: omahasteaksample@yogalevels.com
List-Unsubscribe-Post: List-Unsubscribe=One-Click
From: Omaha Steak Sample <omahasteaksample@yogalevels.com>
List-Unsubscribe: <https://unsubscribe.yogalevels.com/vktxmkst>
MIME-Version: 1.0
Subject: 0maha-Steak's Brings You A Steak SampIer - 0nly 5OO Remaining - This Day 0nly
Message-ID: <aimxyhyfue_770540iaimxyhyfueokstfohvq@yogalevels.com>
Content-Type: multipart/alternative; boundary="----=_HtmlBoundarytstlibcl7244"
X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (redacted.com [0.0.0.0]); Mon, 30 Mar 2026 11:00:18 -0700 (PDT)

------=_HtmlBoundarytstlibcl7244
Content-Type: text/plain; charset="UTF-8"

Thanks for asking about the meeting schedule for next week.

I checked the room list this morning, and the small conference room is open on Tuesday and Thursday after lunch. If that works for everyone, I think Tuesday would be smoother because Sam said he needs Wednesday to finish the draft notes. We should also leave a little extra time at the start since people usually trickle in with questions from the earlier session.

As for the outline, I would keep it simple: quick introductions, recap of the pending items, then a short walkthrough of the updated checklist. I can bring the printed agenda if you want, and I can also jot down action items while everyone talks. If you want me to send reminders, just tell me whether morning or late afternoon is better for the group, and I will put something together that feels clear and easy to follow.

Omaha Steaks

Hand-selected cuts, prepared with care

Your Omaha Steaks sampler details

Recipients may receive a gourmet steak sampler provided at no charge. Omaha Steaks is making 500 gourmet boxes available, one sampler per household, and this offer ends Tomorrow.

See whatÒ€ℒs included

This message confirms that participants may receive an Omaha Steaks Gourmet Sampler, with each box normally priced over $600 and covered by the program for this offer. If you use this email, you will not be billed for the sampler, and quantities are determined by program allocation.

Each cut is hand-selected and flash-frozen to lock in exceptional flavor. Please note that only one sampler may be sent to each household, and the available allocation is set at 500 boxes for this announcement period ending Tomorrow.

Inside Your Box

6 Top Sirloins

4 Filet Mignons

4 New York Strips

4 Ribeyes

Availability is based on the stated program allocation and household limit.

Thanks for taking a moment to review this announcement.

Γ‚ 

I meant to answer your question about the workshop plan in more detail.

Yes, a shorter session would probably work better, especially if the main goal is to gather input rather than cover every topic at once. I would start with the practical items first, like who is bringing materials, who is greeting people at the door, and whether we need extra chairs pulled in before everyone arrives. That usually keeps things calm and avoids a rushed start.

For the discussion portion, I think it helps to keep each section focused on one problem at a time. If the team jumps between ideas too quickly, the notes become hard to sort later. I can organize the talking points into three small sections and leave room at the end for follow-up questions. If you want, send me the rough timing you had in mind and I can turn it into a clean outline with easy transitions so it feels orderly without being too formal.

------=_HtmlBoundarytstlibcl7244
Content-Type: text/html; charset="UTF-8"

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="x-ua-compatible" content="ie=edge">
</head>
<body style="margin:0; padding:0; background-color:#faf6f0; font-family:Arial, Helvetica, sans-serif; color:#2f2f2f;">
<div style="clip-path: inset(100%); clip: rect(1px, 1px, 1px, 1px); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px; font-family: 'Arial Black', Gadget, sans-serif;">
Thanks for asking about the meeting schedule for next week.<br>
I checked the room list this morning, and the small conference room is open on Tuesday and Thursday after lunch. If that works for everyone, I think Tuesday would be smoother because Sam said he needs Wednesday to finish the draft notes. We should also leave a little extra time at the start since people usually trickle in with questions from the earlier session.<br>
As for the outline, I would keep it simple: quick introductions, recap of the pending items, then a short walkthrough of the updated checklist. I can bring the printed agenda if you want, and I can also jot down action items while everyone talks. If you want me to send reminders, just tell me whether morning or late afternoon is better for the group, and I will put something together that feels clear and easy to follow.
</div>
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="background-color:#faf6f0; margin:0; padding:0;">
  <tr>
    <td align="center" style="padding:24px 12px 32px 12px;">
      <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="620" style="width:100%; max-width:620px; background-color:#ffffff; border:1px solid #e3dbd2;">
        <tr>
          <td style="padding:0;">
            <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%">
              <tr>
                <td align="center" style="padding:30px 24px 14px 24px; border-bottom:1px solid #d9d1c8;">
                  <div style="font-size:34px; line-height:38px; font-weight:700; color:#8d191f; letter-spacing:0.4px;">
                    <span style="color:#8d191f;">Omaha</span> <span style="color:#8d191f;">Steaks</span>
                  </div>
                  <div style="font-size:14px; line-height:22px; color:#6f6f6f; padding-top:8px;">Hand-selected cuts, prepared with care</div>
                </td>
              </tr>
              <tr>
                <td style="padding:26px 28px 10px 28px;">
                  <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%">
                    <tr>
                      <td style="border-left:4px solid #c9a046; padding:2px 0 2px 14px;">
                        <div style="font-size:28px; line-height:36px; font-weight:700; color:#2a2a2a;">Your Omaha Steaks sampler details</div>
                        <div style="font-size:16px; line-height:25px; color:#5f5f5f; padding-top:8px;">Recipients may receive a gourmet steak sampler provided at no charge. Omaha Steaks is making 500 gourmet boxes available, one sampler per household, and this offer ends Tomorrow.</div>
                      </td>
                    </tr>
                  </table>
                </td>
              </tr>
              <tr>
                <td align="center" style="padding:16px 28px 8px 28px;">
                  <table role="presentation" cellpadding="0" cellspacing="0" border="0">
                    <tr>
                      <td align="center" bgcolor="#8d191f" style="border-radius:8px; box-shadow:0 2px 6px rgba(0,0,0,0.10);">
                        <a href="http://www.yogalevels.com/stepahead_main/6xoet5fy" style="display:inline-block; padding:14px 24px; font-size:16px; line-height:18px; font-weight:700; color:#ffffff; text-decoration:none; border-radius:8px;">See whatÒ€ℒs included</a>
                      </td>
                    </tr>
                  </table>
                </td>
              </tr>
              <tr>
                <td style="padding:12px 28px 0 28px;">
                  <div style="font-size:15px; line-height:24px; color:#3a3a3a;">This message confirms that participants may receive an Omaha Steaks Gourmet Sampler, with each box normally priced over $600 and covered by the program for this offer. If you use this email, you will not be billed for the sampler, and quantities are determined by program allocation.</div>
                </td>
              </tr>
              <tr>
                <td style="padding:14px 28px 0 28px;">
                  <div style="font-size:15px; line-height:24px; color:#3a3a3a;">Each cut is hand-selected and flash-frozen to lock in exceptional flavor. Please note that only one sampler may be sent to each household, and the available allocation is set at 500 boxes for this announcement period ending Tomorrow.</div>
                </td>
              </tr>
              <tr>
                <td style="padding:24px 28px 8px 28px;">
                  <div style="font-size:20px; line-height:24px; font-weight:700; color:#2b2b2b;">Inside Your Box</div>
                </td>
              </tr>
              <tr>
                <td style="padding:0 28px 18px 28px;">
                  <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="border:1px solid #d8d0c7; border-radius:10px;">
                    <tr>
                      <td width="50%" style="padding:14px 16px; font-size:15px; line-height:22px; color:#2f2f2f; background-color:#f5efe6; border-right:1px solid #d8d0c7; border-bottom:1px solid #d8d0c7;">6 Top Sirloins</td>
                      <td width="50%" style="padding:14px 16px; font-size:15px; line-height:22px; color:#2f2f2f; background-color:#faf6f0; border-bottom:1px solid #d8d0c7;">4 Filet Mignons</td>
                    </tr>
                    <tr>
                      <td width="50%" style="padding:14px 16px; font-size:15px; line-height:22px; color:#2f2f2f; background-color:#faf6f0; border-right:1px solid #d8d0c7;">4 New York Strips</td>
                      <td width="50%" style="padding:14px 16px; font-size:15px; line-height:22px; color:#2f2f2f; background-color:#f5efe6;">4 Ribeyes</td>
                    </tr>
                  </table>
                </td>
              </tr>
              <tr>
                <td style="padding:0 28px 24px 28px;">
                  <div style="font-size:13px; line-height:20px; color:#737373;">Availability is based on the stated program allocation and household limit.</div>
                </td>
              </tr>
              <tr>
                <td align="center" style="padding:0 28px 20px 28px;">
                  <div style="font-size:14px; line-height:22px; color:#666666;">Thanks for taking a moment to review this announcement.</div>
                </td>
              </tr>
              <tr>
                <td style="height:12px; line-height:12px; font-size:12px; background-color:#8d191f;">&nbsp;</td>
              </tr>
            </table>
          </td>
        </tr>
      </table>
      <div style="display:none; max-height:0; overflow:hidden;"><img src="http://www.yogalevels.com/_/open/np1-2GRV9oUtbm23dVYVQx7Kr6DcnJ.gif" width="1" height="1" alt="" style="display:block;width:1px;height:1px;border:0;overflow:hidden;" /></div>
    </td>
  </tr>
</table>
<div style="position:absolute; left:-9999px; top:-9999px; font-family: Georgia, Garamond, serif;">
I meant to answer your question about the workshop plan in more detail.<br>
Yes, a shorter session would probably work better, especially if the main goal is to gather input rather than cover every topic at once. I would start with the practical items first, like who is bringing materials, who is greeting people at the door, and whether we need extra chairs pulled in before everyone arrives. That usually keeps things calm and avoids a rushed start.<br>
For the discussion portion, I think it helps to keep each section focused on one problem at a time. If the team jumps between ideas too quickly, the notes become hard to sort later. I can organize the talking points into three small sections and leave room at the end for follow-up questions. If you want, send me the rough timing you had in mind and I can turn it into a clean outline with easy transitions so it feels orderly without being too formal.
</div>
</body>
</html>

------=_HtmlBoundarytstlibcl7244--
SYSTEM INFORMATION
OS type and version Ubuntu Linux 22.04.5
Webmin version 2.621
Usermin version 2.521
Virtualmin version 8.1.0 GPL
Theme version 26.22
Apache version 2.4.52
Package updates 1 package update is available, of which 1 is security update

Someone new is bombarding me with well known retail chain come-ons with membership extras.

I’m not hosting for public so my choices don’t result in irate phone calls, but it annoys me enough I chase them.

The new player has enough skill to configure their mail sending so it doesn’t trigger the easy, sloppy, lazy sending rules. They send so often I can’t imagine it being effective for tricking anyone to respond.

Standard rules don’t catch them.

I add _report_ to Message Modification so I can easily see what rules they are triggering.

I add weight to lots of rules that different spam triggers but for these guys I have to carefully choose short text strings in body or header and add them to Header and Body tests with a high number to overcome their otherwise good score.

If you put lower case [ i ] in the box after Match Expression it makes the expression not case sensitive.

Since I have been rather aggressive with my filters lately I am checking my junk for unintended casualties.

These guys are annoying enough I’ll chase them. So when they start with a new one I add several rules at a time based on what just got by.

1 Like

Arms race. SA is open source so occasionally β€˜something’ learns how to avoid a certain score and floods. SA adapts. Sigh…

The rules that I find really help are

SPF_NONE
SPF_FAIL
SPF_SOFTFAIL

I set them to 10 points and have auto delete on. I also set these globaly:

Webmin --> Servers --> SpamAssassin Mail Filter --> Header and Body Tests -> Advanced

2 Likes

So one of these spams I just received has these reports:

X-Spam-Report: 
	* -0.0 SPF_HELO_PASS SPF: HELO matches SPF record
	* -0.0 SPF_PASS SPF: sender matches SPF record
	* -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from
	*      envelope-from domain
	* -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
	* -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's
	*       domain
	*  0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily
	*      valid
	*  0.1 RCVD_IN_SBL RBL: Received via a relay in Spamhaus SBL
	*      [45.74.20.159 listed in zen.spamhaus.org]
	*  0.1 URIBL_SBL_A Contains URL's A record listed in the Spamhaus SBL
	*      blocklist
	*      [URI: celldisk.com/45.74.20.159]
	*  0.2 BAYES_999 BODY: Bayes spam probability is 99.9 to 100%
	*      [score: 1.0000]
	*  3.5 BAYES_99 BODY: Bayes spam probability is 99 to 100%
	*      [score: 1.0000]
	*  0.0 HTML_MESSAGE BODY: HTML included in message
	*  0.0 HTML_FONT_LOW_CONTRAST BODY: HTML font color similar or identical to
	*       background
	* -0.0 DMARC_PASS DMARC pass policy
X-Spam-RBL-Check: <dns:159.20.74.45.zen.spamhaus.org> [127.0.0.2]

If if email’s sender ip is listed in spamhaus, and the Bayes filter says its 99.9-100% spam.. why did it not get classified as spam?

Seems like this should be a higher score than that, no?

3.5 BAYES_99 BODY: Bayes spam probability is 99 to 100%
	*      [score: 1.0000]

Those are the defaults. I don’t think they work well out of the box. I have to add weight to many of those. If you don’t watch the effects of what you set you will block good mail.

To change the value of a rule go to advanced mode and scroll down to SpamAssassin test scores. If you put the name of the test exactly as SpamAssassin uses it and put your number it will use yours.

Since I use my registrar’s name servers I don’t get to use a lot of the lists rules because they block the query.

Since these guys know how to avoid the normal filters I seem to only stop them with my own body tests. I couldn’t use some of the phrases I use if I was hosting anyone else email. My daughter’s domains on this server are not getting this batch. I’m probably not going to get any free gift cards. They will give up before I do and it will probably settle back down.

They are annoying enough and persistent enough I am about to start tracking ip’s and dropping ranges with firewallID

simple mode body tests

1 Like

So, out of curiosity I saved out 34 of these spam emails and had Claude Code analyse them (yes I sanitized them first).

Here is what was found:

Critical Finding #1 β€” Your local.cf Score Overrides Are Not Being Applied

  This is the most urgent issue. Your local.cf says:
  score BAYES_99 4
  score BAYES_999 4
  score RCVD_IN_SBL 4

  But the X-Spam-Report headers in every email show the default SA scores: BAYES_99 = 3.5, BAYES_999 = 0.2, RCVD_IN_SBL = 0.1. None of your overrides are
   being applied.

  If score BAYES_99 4 were active, 12 of these 34 emails would have scored β‰₯4.0 on that rule alone.

  Likely cause: spamd is running as a daemon and hasn't been restarted since you edited local.cf, or SA is reading a different local.cf path.

Looks like I forgot to restart spamd

Next:

Critical Finding #2 β€” Your Bayes Database Is Being Actively Poisoned

  Two emails were auto-learned as ham by SA:
  - xandermaker.com (C0STC0 Meat Box): score=-2.1, autolearn=ham
  - nanohistory.com (EquityFirst): score=-2.0, autolearn=ham

  The spammer is doing two things to achieve this:

  Technique A β€” Hidden personal conversation text injected into the HTML, invisible to the reader but fully visible to Bayes:
  <div style="opacity:0; position:absolute; left:-9999px;">
    I checked the weather earlier and it looks much better for the weekend...
    I still need to confirm whether anyone has a folding table...
    Also, I remembered to set aside those extra plant pots for you.
  </div>
  Variations used: position:absolute; left:-9999px, letter-spacing:-9999px; word-spacing:-9999px; font-size:0, font-size:1px; text-indent:-9999px

  Technique B β€” Professionally written, spam-word-free content. The EquityFirst Financial emails read like legitimate financial advisories with no
  classic spam phrases. Bayes never learned this type.

  Immediate fix β€” Prevent further auto-learn poisoning:
  bayes_auto_learn_threshold_nonspam -3.0
  Default is 0.1; this change means only messages scoring ≀ -3.0 get auto-learned as ham, so ambiguous emails no longer poison the database.

  Also run sa-learn on these 34 emails to repair the damage:
  sa-learn --spam /path/to/spam-emails/*.eml

Infrastructure Analysis

  32 of the 34 emails are from the same spammer. The two compliance4alllearning.com emails are a different sender (webinar marketing company using
  Salesforce/VerticalResponse infrastructure) β€” I'll address those separately below.

  The Spammer's Fingerprint β€” Present in All 32 Emails

  1. Tracking pixel URL pattern β€” every single email: http://www.{domain}/_/open/{hash}.gif
  2. Unsubscribe URL pattern β€” every single email: https://unsubscribe.{domain}/{random8chars}
  3. HELO always matches sender domain β€” e.g., out2.newsgage.com for @newsgage.com β€” passes SPF_HELO_PASS
  4. All pass SPF, DKIM, DMARC β€” they own all the sending domains
  5. HTTP-only CTA links β€” http://www.{domain}/{path}/{random} β€” never HTTPS
  6. List-Unsubscribe-Post: List-Unsubscribe=One-Click β€” present in every email
  7. Message-ID always uses the sender domain β€” <randomstring@senderdomain.com>

  Sending IP Infrastructure

  Primary cluster β€” 45.74.20.0/24 (16 emails): All PTR records point to fake hotel/casino domain names:

  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚  Sending IP  β”‚           PTR hostname            β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 45.74.20.145 β”‚ balcony.majesticcasinohotell.com  β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 45.74.20.177 β”‚ larder.harmonycasinohotel.com     β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 45.74.20.205 β”‚ magenta.harmonycasinohotel.com    β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 45.74.20.228 β”‚ puddle.horizonhotelcasino.com     β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 45.74.20.224 β”‚ yawn.horizonhotelcasino.com       β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 45.74.20.246 β”‚ onion.horizonhotelcasino.com      β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 45.74.20.38  β”‚ loaf.luxehotelcasino.com          β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 45.74.20.59  β”‚ octagon.hotelcasinowaen.com       β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 45.74.20.128 β”‚ inviting.goldenresortcasinoes.com β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 45.74.20.108 β”‚ crochet.goldenresortcasinoes.com  β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

  This entire /24 is the same spam infrastructure. The hotel/casino domains exist only as PTR records β€” they're not real sites.

  Secondary IPs with PTR to junk new-gTLDs: .shop, .site, .online, .bond, .sbs, .website

  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚   Sending IP   β”‚         PTR hostname         β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 194.146.57.160 β”‚ moviefgt.site                β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 209.42.23.167  β”‚ pureniteclub.online          β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 192.250.228.98 β”‚ monobitcoin.shop             β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 45.154.25.111  β”‚ gapefowl.shop                β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 68.169.43.5    β”‚ getplumbernyc.site           β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 5.83.45.119    β”‚ helpingthepublic.sbs         β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 94.198.99.45   β”‚ bluestonesinriver.website    β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 94.198.99.46   β”‚ correctlanguagelesson.online β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 103.85.28.80   β”‚ gaantays.online              β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 63.143.38.172  β”‚ playsikzone.bond             β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

  Some IPs return "unknown" (no rDNS at all): 45.61.54.77, 185.48.249.68, 185.148.144.53

  Score Distribution β€” Why They're Slipping Through

  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ Score range  β”‚   Count   β”‚                   Pattern                    β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ -2.1 to -0.5 β”‚ 8 emails  β”‚ BAYES_00, no RBL hits β€” Bayes fully poisoned β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 0.4 to 1.8   β”‚ 8 emails  β”‚ BAYES_00 but URIBL hits keep score positive  β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 2.0 to 2.6   β”‚ 3 emails  β”‚ Partial Bayes + partial URIBL                β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ 3.2 to 3.8   β”‚ 13 emails β”‚ BAYES_99/999 firing but threshold is 4.0     β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

  The spammer has clearly calibrated their content against SA 4.0 β€” the 3.2–3.8 cluster is deliberately kept just below 4.0.

The spammer has clearly calibrated their content against SA 4.0 β€” the 3.2–3.8 cluster is deliberately kept just below 4.0.

Claude Code wrote out rules to add to the local.cf to stop these spams. I am going add them and see how it works. If anyone is interested I can post them..

FYI…

Its been ~24hrs with the new rules and the spam has ceased completely, with no false positives.

3 Likes