[Snort-devel] Snort reputation preprocessor not dropping blacklisted traffic/sessions

Seshaiah Erugu (serugu) serugu at ...3461...
Mon Sep 19 08:04:19 EDT 2016


Hi Ovidiu,

Thanks for reporting, we will fix this in future release.

Thanks,
Seshaiah Erugu.

From: Ovidiu Stanila [mailto:ovidiu.stanila at ...3671...]
Sent: Monday, September 19, 2016 4:40 PM
To: snort-devel at lists.sourceforge.net
Subject: [Snort-devel] Snort reputation preprocessor not dropping blacklisted traffic/sessions

Hello,

Recently we've implemented some block lists inside the Snort reputation and noticed some traffic was getting through. For example, this is a tcpdump sample for an access on SMTP from a blacklisted IP address:

1.169.x.x - external public IP address, blacklisted inside reputation
119.x.x.x - our public facing IP address
10.0.0.x   - Postfix server behind NAT ( -t nat -A PREROUTING -d 119.x.x.x -p tcp -m multiport --dport 25,465 -j DNAT --to-destination 10.0.0.x )


# tcpdump -nni eth0 port 25
17:31:58.672144 IP 1.169.x.x.12114 > 119.x.x.x.25: Flags [S], seq 434703129, win 65535, options [mss 1380,nop,nop,sackOK], length 0
17:31:58.672509 IP 119.x.x.x.25 > 1.169.x.x.12114: Flags [R.], seq 0, ack 434703130, win 0, length 0
17:32:00.302165 IP 1.169.x.x.12114 > 119.x.x.x.25: Flags [S], seq 1633824392, win 65535, options [mss 1380,nop,nop,sackOK], length 0
17:32:00.302493 IP 10.0.0.x.25 > 1.169.x.x.12114: Flags [R.], seq 0, ack 1633824393, win 0, length 0
17:32:00.302561 IP 1.169.x.x.12114 > 10.0.0.x.25: Flags [R.], seq 0, ack 0, win 0, length 0
17:32:06.506088 IP 1.169.x.x.12114 > 119.x.x.x.25: Flags [S], seq 1633824392, win 65535, options [mss 1380,nop,nop,sackOK], length 0
17:32:06.506272 IP 1.169.x.x.12114 > 10.0.0.x.25: Flags [S], seq 1633824392, win 65535, options [mss 1380,nop,nop,sackOK], length 0
17:32:06.506566 IP 10.0.0.x.25 > 1.169.x.x.12114: Flags [S.], seq 2415824715, ack 1633824393, win 29200, options [mss 1460,nop,nop,sackOK], length 0
17:32:06.506659 IP 119.x.x.x.25 > 1.169.x.x.12114: Flags [S.], seq 2415824715, ack 1633824393, win 29200, options [mss 1460,nop,nop,sackOK], length 0

Snort uses DAQ NFQ inline mode:


snort -m 122 -d -D -Q  -c /etc/snort/snort.conf


config daq: nfq
config daq_dir: /usr/lib64/daq
config daq_mode: inline

with the following iptables rules:

*mangle
-A PREROUTING -i eth0 -j ACCEPT
-A FORWARD -i eth0 -j ACCEPT
-A FORWARD -o eth0 -j ACCEPT
COMMIT

Snort reputation:

preprocessor reputation: \
   memcap 500, \
   priority blacklist, \
   nested_ip both, \
   white unblack, \
   blacklist $BLACK_LIST_PATH/black_list.txt


drop ( msg: "reputation: Packet is blacklisted"; sid: 1; gid: 136; rev: 1; metadata: rule-type preproc ; classtype:bad-unknown; )



Done some tests and this occurs when the client tries to connect again with the same source port after a RST is sent, e.g. source port 12114 in this case:

17:31:58.672144 IP 1.169.x.x.12114 > 119.x.x.x.25: Flags [S], seq 434703129, win 65535, options [mss 1380,nop,nop,sackOK], length 0
17:31:58.672509 IP 119.x.x.x.25 > 1.169.x.x.12114: Flags [R.], seq 0, ack 434703130, win 0, length 0
17:32:00.302165 IP 1.169.x.x.12114 > 119.x.x.x.25: Flags [S], seq 1633824392, win 65535, options [mss 1380,nop,nop,sackOK], length 0


After some debugging noticed that the reputation preprocessor reports this packet is dropped when actually it passes through:

spp_reputation.c:802: REPUTATION Start ********************************************
spp_reputation.c:628: Lookup address: 119.x.x.x
reputation_config.c:1948: Reputation Info: Reputation Info: 3,0,0,0,->
spp_reputation.c:826: REPUTATION End **********************************************
fpdetect.c:1665: Detecting on TcpList
sp_tcp_flag_check.c:353:            <!!> CheckTcpFlags: sp_tcp_flag_check.c:365: No match
fpdetect.c:218:    => Got rule match, rtn type = 3, evalIndex = 3, passIndex = 2
detect.c:1230:         <!!> Generating Alert and dropping! "(spp_reputation) packets blacklisted"

Looking through the reputation preprocessor code, noticed this:

snort-2.9.8.3/src/dynamic-preprocessors/reputation/spp_reputation.c:

746:static inline void ReputationProcess(SFSnortPacket *p)
...
761:    else if (BLACKLISTED == decision)
762:    {
763:        uint32_t flags = SSNFLAG_DETECTION_DISABLED;
764: ALERT(REPUTATION_EVENT_BLACKLIST,REPUTATION_EVENT_BLACKLIST_STR);
765:#ifdef POLICY_BY_ID_ONLY
766:        _dpd.inlineForceDropSession(p);
767:        flags |= SSNFLAG_FORCE_BLOCK;
768:#endif
769:        // disable all preproc analysis and detection for this packet
770:        _dpd.disablePacketAnalysis(p);
771:        _dpd.sessionAPI->set_session_flags( p->stream_session, flags );
772:        reputation_stats.blacklisted++;
773:    }

The SSNFLAG_FORCE_BLOCK flag isn't passed through to the session preprocessor, only SSNFLAG_DETECTION_DISABLED, which, from what I understand, just disables packet analysis and lets the packet through:

snort-2.9.8.3/src/preprocessors/spp_session.c

1398:    if( flags & SSNFLAG_FORCE_BLOCK )
1399:    {
1400:        DisablePacketAnalysis( p );
1401:        /* Detect will turn on the perfmonitor preprocessor when this function returns */
1402:        scb->enabled_pps = PP_PERFMONITOR;
1403:        Active_ForceDropSession();
1404:    }
1405:    else if( flags & SSNFLAG_DETECTION_DISABLED )
1406:    {
1407:        DisablePacketAnalysis( p );
1408:        /* Detect will turn on the perfmonitor preprocessor when this function returns */
1409:        scb->enabled_pps = PP_PERFMONITOR;
1410:    }

" flags |= SSNFLAG_FORCE_BLOCK" is conditioned by POLICY_BY_ID_ONLY which is never set and thus the flag is never used during compilation.

I've patched the reputation preprocessor with the following:

--- src/dynamic-preprocessors/reputation/spp_reputation.c  2016-03-18 23:54:32.000000000 +1000
+++ src/dynamic-preprocessors/reputation/spp_reputation.c  2016-09-17 06:47:00.120212173 +1000
@@ -760,14 +760,13 @@
     }
     else if (BLACKLISTED == decision)
     {
-        uint32_t flags = SSNFLAG_DETECTION_DISABLED;
+        uint32_t flags = SSNFLAG_FORCE_BLOCK;
ALERT(REPUTATION_EVENT_BLACKLIST,REPUTATION_EVENT_BLACKLIST_STR);
 #ifdef POLICY_BY_ID_ONLY
         _dpd.inlineForceDropSession(p);
-        flags |= SSNFLAG_FORCE_BLOCK;
+        _dpd.disablePacketAnalysis(p);
 #endif
         // disable all preproc analysis and detection for this packet
-        _dpd.disablePacketAnalysis(p);
         _dpd.sessionAPI->set_session_flags( p->stream_session, flags );
         reputation_stats.blacklisted++;
     }

and recompiled Snort.

With this change no more traffic passes through from blacklisted IP addresses.

Maybe there's a reason why this is set up like it is, but for our setup this patch did the trick without affecting any Snort inner working.

Upcoming Snort release 2.9.9 uses the same logic inside reputation preprocessor. It would be nice if this change could be integrated in the next release to fix the reputation preprocessor.

Best regards,
Ovidiu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.snort.org/pipermail/snort-devel/attachments/20160919/51d73ca9/attachment.html>


More information about the Snort-devel mailing list