PureLogs Stealer

Thanks for your response. Check, rule doesn’t work here, otherwise we may encounter 126 byte packet like here.

Regarding the content mismatch check, I use negation so that I don’t encounter a null sequence before 40 00 00 00 and accidentally trigger it.

byte_extract: 8, -68, bytes0, relative;
byte_test: 8, =, bytes0, -80, relative;
byte_test: 8, !=, bytes0, -81, relative;


It is noticed that such a packet with these bytes (40 00 00 00) is exfiltrated twice in one stream.
And another strange story with isdataat, if you remove the "! "it also works 0_o
This is a link to the previous sample where the pointer has no value, either it is not equal to 1 or it is equal.

At the same place in the stream

isdataat:!1, relative;   =   isdataat:1, relative;

But If i change any value here, it won’t work, sometimes have to fuzzing the suricata))

isdataat:64, relative;              
isdataat:!65, relative;   

The miracles with the pointer continue, it is apparently only useful in combination equal to 64 and not equal to 65. So, in the stream rule it doesn’t matter !1 or 64, it still matches the same packet in the stream.

Considering the first sample in this message, I still suggest switching to the rules with a stream, using a “quantum” Schrödinger pointer (!1 = 1 superposition where he is both alive and dead) with two boundaries 64 and 65 and using 8 bytes. This happens because the stream contains a packet where condition isdataat: !1, relative is satisfied because it is of length 4, and packets where condition isdataat: 1, relative is satisfied because there are subsequent bytes. Therefore, I insist on matching exactly 64 bytes. Since there is only one such packet.

In this form, this rule works everywhere,

alert tcp $HOME_NET any -> $EXTERNAL_NET [1024:65535] (msg:"ET MALWARE [ANY.RUN] PureLogs Stealer Exfiltration (stream)";
flow:established,to_server, only_stream;

stream_size: server, <, 103;
stream_size: client, >, 30000;
content:"|40 00 00 00|"; fast_pattern;
content: !"|0000|"; within: 64;

isdataat:64, relative;
isdataat:!65, relative;

byte_extract: 8, -68, bytes0, relative;
byte_test: 8, =, bytes0, -80, relative;
byte_test: 8, !=, bytes0, -81, relative;

threshold:type limit, track by_src, seconds 360, count 1; 
classtype: trojan-activity;
reference: md5,44ae53e75958273246b11da00c75f3c9;
reference: url,app.any.run/tasks/ded1aeb9-55f5-47eb-b752-95bb288f3199;
sid: 2; rev: 1;)

Please check it, thank you very much! Don’t leave me in this confusing world of network traffic, always with you! ⋆୨୧˚