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

Ovidiu Stanila ovidiu.stanila at ...3671...
Mon Sep 19 07:09:37 EDT 2016


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/5a5b6a15/attachment.html>


More information about the Snort-devel mailing list