Detecting a packet after reassembled

I’m running suricata in IDS mode, and I’m using the following settings:

  • inline: no, bypass: no, depth: 5k

Assuming that long request packets are sent and simply, each packet is 1500 bytes , packets from 1 to 4500 bytes (3 packets) are reassembled and detected, but packets of 4501~6000 byte are discarded by the depth setting, so detection is not possible. After that, 6001~end byte are normally detected.

When testing using ips mode in af-packet, all are detected because of the sliding windows method. But I couldn’t use IPS mode because I have to use all of napatech card ports as RX.

When using ids mode, I wonder if a packet reaches the depth are excluded from investigation, and whether ips mode can be used with all ports of napatech card used for RX.

You are talking about the stream.reassembly.depth setting?
I always assumed that Suricata would drop all packets after it reached the depth limit or the memcap.
Is picking up the tcp stream again after reaching the depth related to the midstream work?
Have you set stream.midstream to true? Do you get the same result with it set to false?

With the setting below, midstream was able to detect both true and false packets from 1 to 7 packets.

Bypass: no
Raw: Yes
Depth: 0k

I expected to create a new stream if midstream was set to true. And if it was “bypass:no, midstream:false”, I expected the sliding window method to be detected, and I want to check if this is true.

And if it was “bypass:no, midstream:true”, also it was found that a packet spanning the depth was dropped.

I am having a hard time understanding some things.
What do you mean with true and false packets?
Could you share the rules you are using?

The packet spanning the depth being dropped is what I would expect. No matter the midstream setting.
That sounds like the entire point of the depth setting. You do not want to waste detection resources looking >X bytes into the stream.

Picking the stream up again after the depth is reached is what would surprise me. That would to my understanding invalidate the depth option.

What I was saying was that if the depth was 0k, all the rules 1 to 7 were detected both when the midstream was true and false.
(I didn’t express it well)

I think this is detected not because of midstream setting, but because bypass is set to no. For example, if bypass:yes and depth:5k, as you said, packets over 5k are not detected.
However, if bypass:no and depth:5k are used, a packet that spanning at 5k is not detected, and all other packets after that are detected.
I want to know whether up to 5k is recombined and detected, and packets after that are detected by sliding windows.


In addition, I explain the method of the test I did.
I simply used a policy to detect a string, and made 7 rules as follows.

ex:
alert tcp any any -> any any (msg:"1th_packet"; content:"1!"; sid:1;)
alert tcp any any -> any any (msg:"2th_packet"; content:"2!"; sid:2;)
...

And I sent the post body data as follows.
A number was put in each packet (about 1500 bytes) so that all of the above rules were detected.

 1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 ... (filled with about 1500 bytes of exclamation marks)
 2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 ... (filled with about 1500 bytes of exclamation marks)

I did some testing today.

I created the same rules as you did. From packet 1-10.
Traffic generated with nc in one end and this script:

import socket
s = socket.socket()
s.connect(("10.10.0.1", 1337))
for i in range(1, 11):
    s.sendall((str(i) + "!" * 1490 + "\n").encode("utf-8"))
s.close()

Suricata version 6.0.2, default config except for memcaps, thread number, no randomized chunk size and disabled checksums.

Now I get some really strange results that I don’t understand.
depth: 5k gives me alerts on packet 5-10
depth: 10k gives me alerts on packet 9-10
depth: 15k gives me alerts on packet 1-10

midstream: to either true or false has no effect.
bypass: true gives me no alerts on depth < 15k

bypass result is expected. Can’t really understand why I’m missing the alerts before the depth limit is reached. I would also expect the midstream option to influence the results. E.g. midstream: false should result in no detections after the depth has been reached.

I think you need to check the raw option in the reassembly configuration to detect packets before depth.

I wonder (1) if the previous packet is recombined based on the depth and the subsequent packet is detected by the sliding windows method, and I want to know (2) if there is a way to detect the packet over the depth.