Postfix - non-SMTP command - Add signature

Issue #154 resolved
Javier created an issue

I’ve been watching in the maillog many scans on Postfix smtpd process:

Jun 21 12:00:56 acme postfix/submission/smtpd[20201]: warning: non-SMTP command from unknown[170.130.187.14]: GET / HTTP/1.1
Jun 21 14:31:24 acme postfix/submission/smtpd[22074]: warning: non-SMTP command from unknown[23.224.186.214]: \001\000\000i3t\000\000\000\000\000\022\000\020\000\000\rmy.i.p.p.p\000\005\000\005\001\000\000\0\000\005\000\005\001\000\000\0

It would be nice to have it added to the list.

I tried to modify the source but I’m lacking enough skills. It would be something like this:

 /* postfix */
"warning: non-SMTP command".*                               { BEGIN(INITIAL); return POSTFIX_NON_SMTP_CMD; }

Comments (6)

  1. Kevin Zheng
    • changed status to open

    Unfortunately, writing signatures requires a bit of working knowledge with lex/yacc. I should write a quick tutorial sometime.

    Could you explain what 'unknown' is? Is it the reverse DNS of the host, replaced with 'unknown' if the query returns NXDOMAIN?

    Could you also suggest a score for this attack? It’s not quite as serious as a “login failure”. In fact, I see this kind of “attack” all this time on enterprise networks that employ automated port scanners.

    Here’s what I have so far. The meat of the change is:

    +"warning: non-SMTP command from "{WORD}"["                      { BEGIN(postfix_nonsmtp); return POSTFIX_NON_SMTP_PREF; }
    +<postfix_nonsmtp>"]: ".*                                        { BEGIN(INITIAL); return POSTFIX_NON_SMTP_SUFF; }
    

    Then, we need to teach the parser (attack_parser.y) about this new signature that we have lexical tokens for:

     postfixmsg:
         POSTFIX_SASL_LOGINERR_PREF addr POSTFIX_SASL_LOGINERR_SUFF
       | POSTFIX_NO_AUTH_PREF addr ']'
    +  | POSTFIX_NON_SMTP_PREF addr POSTFIX_NON_SMTP_SUFF
       | POSTFIX_GREYLIST addr POSTFIX_GREYLIST_SUFF
       | POSTSCREEN_PREF addr POSTSCREEN_SUFF
       ;
    

    There are some places where we need to define lexical tokens and parser states:

    +%token POSTFIX_NON_SMTP_PREF POSTFIX_NON_SMTP_SUFF
    
    diff --git a/src/parser/attack_scanner.l b/src/parser/attack_scanner.l
    index 7fef2a0..ed75f6f 100644
    --- a/src/parser/attack_scanner.l
    +++ b/src/parser/attack_scanner.l
    @@ -42,7 +42,7 @@ static int getsyslogpid(char *syslogbanner, int length);
     %s sshguard_attack sshguard_block
     %s bind
      /* for Mail services */
    -%s dovecot_loginerr cyrusimap_loginerr exim_esmtp_autherr exim_esmtp_loginerr sendmail_relaydenied sendmail_authfailure postfix_loginerr postfix_greylist opensmtpd_failedcmd postscreen
    +%s dovecot_loginerr cyrusimap_loginerr exim_esmtp_autherr exim_esmtp_loginerr sendmail_relaydenied sendmail_authfailure postfix_loginerr postfix_nonsmtp postfix_greylist opensmtpd_failedcmd postscreen
    

    It’s good to write tests:

    diff --git a/src/parser/tests.txt b/src/parser/tests.txt
    index 22cd32f..084d22a 100644
    --- a/src/parser/tests.txt
    +++ b/src/parser/tests.txt
    @@ -285,6 +285,12 @@ M
     Sep  6 11:47:43 poseidon postfix/postscreen[14766]: HANGUP after 0.07 from [1.2.3.4]:55868 in tests after SMTP handshake
     260 1.2.3.4 4 10
     M
    +Jun 21 12:00:56 acme postfix/submission/smtpd[20201]: warning: non-SMTP command from unknown[1.2.3.4]: GET / HTTP/1.1
    +260 1.2.3.4 4 10
    +M
    +Jun 21 14:31:24 acme postfix/submission/smtpd[22074]: warning: non-SMTP command from unknown[1.2.3.4]: \001\000\000i3t\000\000\000\000\000\022\000\020\000\000\rmy.i.p.p.p\000\005\000\005\001\000\000\0\000\005\000\005\001\000\000\0
    +260 1.2.3.4 4 10
    +M
    
     #### OpenSMTPD
     38dd06274cde1fd7 smtp event=failed-command address=185.236.202.133 host=no-mans-land.m247.com command="AUTH LOGIN" result="503 5.5.1 Invalid command: Command not supported"
    

  2. Javier reporter

    Yes, it doesn't have a reverse DNS record. I tried to copy some of the syntax from attack_scanner and attack_parser but I couldn't do it.

    I got your gmail from FreeBSD ports however I preffered to contact you via Bitbucket.

    Thanks!

  3. Javier reporter

    Would you like me to help you write a basic step by step guide so more people can add signatures?

  4. Javier reporter

    I tried to follow the steps in the page you linked. I would add:

    . Steps to add a signature

    . explain what a token does (lexical?)

    . The name, the regular expression.

    . Why the regular expression has BEGIN(zzzzz) and so…

    Reading those files I one might understand what pieces to add however it would be more useful to understand the steps the program does and which steps from adding the signature impact in the steps of the parsing/detection.

  5. Log in to comment