Score:1

body_checks: How to filter base64 encoded content?

cn flag

The idiomatic answer is probably "don't - use a filter that decodes the message first", but as can be seen in the second answer to that question, it should also be possible with body_checks which is also what the BUILTIN_FILTER_README @ postfix.org says - and that's what I'd like to do.

Here's one that's been bugging me for quite some time:

--===============6489786132958404869==
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64

SmFnIGhhciByZWRhbiBza3Jpdml0IHRpbGwgZGlnLCBtZW4gZHUgc3ZhcmFyIG1pZyBpbnRlLiBM
w6V0IG1pZyB2ZXRhLCBqYWcgaGFyIG7DpWdyYSBzYWtlciBhdHQgYmVyw6R0dGEuIEtvbnRha3Rh
IG1pZyBpIG1pbiBwcml2YXRhIGUtcG9zdDogaXJlbmUub3NiZXJnNzNAZ21haWwuY29tCg==

--===============6489786132958404869==--

For this, I've added the body_checks rule:

/SmFnIGhhciByZWRhbiBza3Jpdml0IHRpbGwgZGlnLCBtZW4gZHUgc3ZhcmFyIG1pZyBpbnRl/ REJECT Spam

but it just won't catch it when it's in such a block. It caught one attempted delivery when the same string was embedded in an body: <div dir="ltr"><pre class="gmail-moz-quote-pre"><pre>SmFnIHZpbGwgcHJhdGEgbWVkIGRpZywgbWVuIGRldCBmaW5ucyBmw7ZyIG3DpW5nYSBtZWRkZWxh</pre> but that's the only time the rule has successfully caught this. I have added quite a few of these base64 encoded rules but none of them catch anything when embedded like above.

The base64 encoding in this particular case is always exactly the same, so I don't have to make a base64 tripple to catch variants, which I've done for other cases:

/aHR0cHM6Ly9jbGNrLnJ1|dHRwczovL2NsY2sucnUv|dHBzOi8vY2xjay5y/ REJECT Please remove the link to clck.ru

The above doesn't catch anything when embedded in a block like above either.

I've tried adding the main.cf setting

disable_mime_input_processing = yes

which seems to have improved things. It catches some of them now, but not all those than I can manually verify should catch messages that slips though the cracks.

Any idea why this doesn't work and what I can do about it? I'm using 3.6.4-1.fc35.

Ted Lyngmo avatar
cn flag
@anx In fact it does (or did - I just removed them). It had a few `DUNNO`s spread out that I don't remember why I put there. I've removed them now and will see if that makes a difference.
Ted Lyngmo avatar
cn flag
@anx Since I removed the `DUNNO`s, there has not been a single attempt to deliver any mails that previously by-passed my `body_checks` filter - but I still have a good feeling about it. The delivery attacks usually comes in bursts a couple of times per day so I'm confident that I'll be able to verify your hunch before my bounty expires if you'd like to write an answer to my question.
Score:1
fr flag
anx

There is a builtin feature for diagnosing postfix map lookups, specifically for body_checks as well. Pass the same map configuration you configured for your smtpd cleanup service to the postmap utility and add one or more -v for detailed output:

# postconf body_checks
body_checks=pcre:/etc/postfix/body.pcre
# cat known_bad.eml | postmap -v -b -q - pcre:/etc/postfix/body.pcre
...
postmap: dict_pcre_lookup: body.pcre: test line 1
postmap: dict_pcre_lookup: body.pcre: test line 2
postmap: dict_pcre_lookup: body.pcre: test line 3
test line 3 DUNNO

This will tell you, for each body line, which (if any) entry in your map matched against your line.

One possible reason your map might not behave the way you expect it to would be a too-broad match with DUNNO result preceding your intended REJECT spam result, instructing the cleanup server to proceed with the next line instead of trying further expressions.

Score:0
ru flag

Fell into the same trap once, blocking all emails beginning with "<!DOCTYPE html" :)

If it's dynamic content you'll be hard-pressed to find something later in the email, but if it's static a test-decode of one such message and re-encoding significant parts could help in finding a good matching string. Your main adversaries when doing so are line-breaks, which could occur just about anywhere depending on the position of the matching text.

I usually only do base64-matching in headers (subject mostly, UTF-8 headers tend to encode their subjects in base64), since splitting a header over multiple lines is rather unusual (but still possible).

You might find better help in external utilities like amavis or dspam (which both utilize spamassassin) , with bayes switched on. That would also help with the decoding part since decoders are built into these products.

Ted Lyngmo avatar
cn flag
Thanks! Note that it's not that my regex's do not match the content in the message body. If I copy the message source of a message that has slipped through to a file and run the `body_checks` regex:es manually, they catch it every time. I updated the question a little.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.