Project

General

Profile

Actions

Bug #2858

open

app-layer-protocol:failed; doesn't match traffic with ALPROTO_UNKNOWN

Added by spencer walden almost 4 years ago. Updated over 3 years ago.

Status:
New
Priority:
Normal
Target version:
Affected Versions:
Effort:
Difficulty:
Label:

Description

I'm working on writing some signatures for some malware that uses a custom protocol. In my signatures, I'd like to be able to write "app-layer-protocol:failed;" in order to filter out traffic that has a known protocol associated with it. However, with that logic incorporated to my signatures, some of the signatures fail to fire. Upon inspection of these rule matches with and without that logic, I found that the rules that consistently fire are being "matched" with a protocol as ALPROTO_FAILED, and the ones that are not firing are not matched at all, and thus are labeled as having no app layer protocol, i.e. ALPROTO_UNKNOWN. There is no support for looking for traffic with app-layer-protocol:unknown; either. From my perspective, any traffic that has an "unknown" protocol, would be considered to have failed application layer protocol inspection. Therefore, I would like app-layer-protocol:failed; to match both traffic that has been classified as ALPROTO_UNKNOWN and ALPROTO_FAILED.

A tedious workaround to this thing would be to have something to the effect of
app-layer-protocol:!http; app-layer-protocol:!tls; app-layer-protocol:!smtp; app-layer-protocol:!ftp; ...
You get the idea. Unfortunately, that is a lot of extra logic to include in a signature, and also means the signature is not as easily maintained -- any additional protocols added to suricata would need to be NOT-ed out later.

I'm not sure if this is considered a feature or a bug... I felt it was a bug, as I expected my traffic to match against the signature whether application layer protocol detection failed or... ended up in an unknown state. Those are effectively the same state in my eyes, I understand that those might have different meanings within the code of suricata. Please let me know if I can help by providing any more information, clarifying anything, etc. I don't know how to label this in terms of effort or difficulty either; I ask that you please excuse my ignorance.

Thanks!


Files

alert-debug.log (4.18 KB) alert-debug.log Suricata's alert-debug.log spencer walden, 08/29/2019 10:17 PM
bash_i_php_webshell.pcap (17.9 KB) bash_i_php_webshell.pcap PCAP Showcasing an example use-case spencer walden, 08/29/2019 10:17 PM
fast.log (539 Bytes) fast.log Suricata's fast.log spencer walden, 08/29/2019 10:17 PM
proto.rules (1.22 KB) proto.rules Example Rules Showcasing the Problem. spencer walden, 08/29/2019 10:17 PM
Actions #1

Updated by Andreas Herz over 3 years ago

  • Assignee set to Community Ticket
  • Target version set to TBD
Actions #2

Updated by Andreas Herz over 3 years ago

Do you have some pcaps or specific cases that might help to reproduce the issue and work on a better implementation on code side?

Updated by spencer walden over 3 years ago

Andreas Herz wrote:

Do you have some pcaps or specific cases that might help to reproduce the issue and work on a better implementation on code side?

I can provide PCAP, and give the specific case I'm talking about, sure!
...However, I'm not sure it will help make implementation better code side. I'm just asking for the keyword "app-layer-protocol" with the argument/value of "failed" to match traffic that has been marked as either ALPROTO_UNKNOWN or ALPROTO_FAILED.

So, I've attached a PCAP of an example of traffic I'm looking at.
The case we're looking at here:
  • I've used a webshell I put on a webserver for testing purposes to spawn a reverse shell ("bash -i") back to me.
  • The shell is coming from port ephemeral port 50666 back to me at port 8080 where I'm controlling the shell.
  • I issue some standard Linux commands via the reverse shell.
  • I'm trying to write rules looking for these Linux commands.
  • There is no L7/Application Layer Protocol happening here, just raw TCP.
  • In order to cut down the amount of packets that Suricata should inspect, I wanted to use "app-layer-protocol:failed;" as a check to make sure there is no L7 protocol in play, as I'm using the "tcp" protocol keyword in the rule header
  • According to alert-debug.log, the protocol is determined to be 0, or ALPROTO_UNKNOWN

Additionally, I've attached the alert-debug.log file and the fast.log file associated with running the PCAP.
As you can see from the fast.log, only the signatures that don't have the check for "app-layer-protocol:failed;" properly fire on the traffic. In the alert-debug.log file, you can see that the signatures that did fire were the ones that don't check for an L7 protocol and that they claim the protocol is 0 -- See the line (FLOW APP_LAYER: DETECTED: FALSE, PROTO 0)

+================
TIME:              03/01/2019-01:13:39.800519
PCAP PKT NUM:      59
PKT SRC:           wire/pcap
SRC IP:            172.28.128.9
DST IP:            172.28.128.10
PROTO:             6
SRC PORT:          8080
DST PORT:          50666
TCP SEQ:           3373388884
TCP ACK:           1197728138
FLOW:              to_server: FALSE, to_client: TRUE
FLOW Start TS:     03/01/2019-01:13:36.705786
FLOW PKTS TODST:   5
FLOW PKTS TOSRC:   5
FLOW Total Bytes:  832
FLOW IPONLY SET:   TOSERVER: TRUE, TOCLIENT: TRUE
FLOW ACTION:       DROP: FALSE
FLOW NOINSPECTION: PACKET: FALSE, PAYLOAD: FALSE, APP_LAYER: FALSE
FLOW APP_LAYER:    DETECTED: FALSE, PROTO 0
PACKET LEN:        69
PACKET:
 0000  08 00 27 59 7D D1 08 00  27 5C B3 68 08 00 45 00   ..'Y}... '\.h..E.
 0010  00 37 C8 09 40 00 40 06  1A 6B AC 1C 80 09 AC 1C   .7..@.@. .k......
 0020  80 0A 1F 90 C5 EA C9 11  D4 54 47 63 E1 8A 80 18   ........ .TGc....
 0030  00 E3 E4 B5 00 00 01 01  08 0A 00 CC 1F 58 00 CB   ........ .....X..
 0040  F5 9A 6C 73 0A                                     ..ls.
ALERT CNT:           1
ALERT MSG [00]:      EXAMPLE No App Layer Protocol Check ls
ALERT GID [00]:      1
ALERT SID [00]:      6
ALERT REV [00]:      1
ALERT CLASS [00]:    Misc activity
ALERT PRIO [00]:     3
ALERT FOUND IN [00]: PACKET
ALERT IN TX [00]:    N/A
PAYLOAD LEN:         3
PAYLOAD:
 0000  6C 73 0A                                           ls.

According to the Suricata source code (https://github.com/OISF/suricata/blob/c1b30fe9fd4970043a546d05ab57e23c837998e1/src/app-layer-protos.h#L29) Protocol 0 is ALPROTO_UNKNOWN. However, since I've said I'm looking for "app-layer-protocol:failed;", which maps to ALPROTO_FAILED, my signatures don't fire.

What I'm asking for is a code change such that the keyword "app-layer-protocol:failed;" actually maps to see if the app-layer-protocol is either ALPROTO_UNKNOWN || ALPROTO_FAILED.

Sorry for the slow response, the email that you had made a comment got lost in my inbox...
Thanks for taking a look at this!

Actions

Also available in: Atom PDF