]> git.ipfire.org Git - thirdparty/suricata-verify.git/commitdiff
tests/luaxform: Lua transform tests 2262/head 2514/head
authorJeff Lucovsky <jlucovsky@oisf.net>
Tue, 17 Sep 2024 12:56:36 +0000 (08:56 -0400)
committerJeff Lucovsky <jlucovsky@oisf.net>
Sun, 18 May 2025 13:17:16 +0000 (09:17 -0400)
This commit adds tests for new Lua transform
- Basic transform operation
- Ensure non-existent Lua scripts are detected
- Ensure Lua scripts without transform functions are detected
- Ensure Lua scripts properly receive optional transform arguments
- Ensure Lua scripts work with Suricata's Lua libraries

33 files changed:
tests/lua/lua-transform-01/README.md [new file with mode: 0644]
tests/lua/lua-transform-01/test.pcap [new file with mode: 0644]
tests/lua/lua-transform-01/test.rules [new file with mode: 0644]
tests/lua/lua-transform-01/test.yaml [new file with mode: 0644]
tests/lua/lua-transform-01/transform.lua [new file with mode: 0644]
tests/lua/lua-transform-02/README.md [new file with mode: 0644]
tests/lua/lua-transform-02/test.rules [new file with mode: 0644]
tests/lua/lua-transform-02/test.yaml [new file with mode: 0644]
tests/lua/lua-transform-03/README.md [new file with mode: 0644]
tests/lua/lua-transform-03/test.rules [new file with mode: 0644]
tests/lua/lua-transform-03/test.yaml [new file with mode: 0644]
tests/lua/lua-transform-03/transform.lua [new file with mode: 0644]
tests/lua/lua-transform-04/README.md [new file with mode: 0644]
tests/lua/lua-transform-04/test.rules [new file with mode: 0644]
tests/lua/lua-transform-04/test.yaml [new file with mode: 0644]
tests/lua/lua-transform-04/transform.lua [new file with mode: 0644]
tests/lua/lua-transform-05/transform.lua
tests/lua/lua-transform-06/README.md [new file with mode: 0644]
tests/lua/lua-transform-06/test.rules [new file with mode: 0644]
tests/lua/lua-transform-06/test.yaml [new file with mode: 0644]
tests/lua/lua-transform-06/transform.lua [new file with mode: 0644]
tests/lua/lua-transform-07/README.md [new file with mode: 0644]
tests/lua/lua-transform-07/test.rules [new file with mode: 0644]
tests/lua/lua-transform-07/test.yaml [new file with mode: 0644]
tests/lua/lua-transform-07/transform.lua [new file with mode: 0644]
tests/lua/lua-transform-08/README.md [new file with mode: 0644]
tests/lua/lua-transform-08/suricata.yaml [new file with mode: 0644]
tests/lua/lua-transform-08/test.pcap [new file with mode: 0644]
tests/lua/lua-transform-08/test.rules [new file with mode: 0644]
tests/lua/lua-transform-08/test.yaml [new file with mode: 0644]
tests/lua/lua-transform-08/transform-base64.lua [new file with mode: 0644]
tests/lua/lua-transform-08/transform-dataset.lua [new file with mode: 0644]
tests/lua/lua-transform-08/transform-hashlib.lua [new file with mode: 0644]

diff --git a/tests/lua/lua-transform-01/README.md b/tests/lua/lua-transform-01/README.md
new file mode 100644 (file)
index 0000000..9326f3a
--- /dev/null
@@ -0,0 +1 @@
+Lua transform test: returns input buffer in uppercase. The rule will match on the uppercase output
diff --git a/tests/lua/lua-transform-01/test.pcap b/tests/lua/lua-transform-01/test.pcap
new file mode 100644 (file)
index 0000000..b9eec15
Binary files /dev/null and b/tests/lua/lua-transform-01/test.pcap differ
diff --git a/tests/lua/lua-transform-01/test.rules b/tests/lua/lua-transform-01/test.rules
new file mode 100644 (file)
index 0000000..0f33f60
--- /dev/null
@@ -0,0 +1 @@
+alert http any any -> any any (msg:"TEST"; http.uri; luaxform:transform.lua;content:"EXEC_POST.PHP";  sid:1; rev:1;)
diff --git a/tests/lua/lua-transform-01/test.yaml b/tests/lua/lua-transform-01/test.yaml
new file mode 100644 (file)
index 0000000..5a80f13
--- /dev/null
@@ -0,0 +1,14 @@
+requires:
+  min-version: 8
+
+args:
+  - --set default-rule-path=${TEST_DIR}
+  - --set security.lua.allow-rules=true
+
+checks:
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature_id: 1
+        http.url: /exec_post.php
diff --git a/tests/lua/lua-transform-01/transform.lua b/tests/lua/lua-transform-01/transform.lua
new file mode 100644 (file)
index 0000000..cb21084
--- /dev/null
@@ -0,0 +1,7 @@
+function transform(input, args)
+    local bytes = #input
+    local offset = 0
+
+    local sub = string.sub(input, offset + 1, offset + bytes)
+    return string.upper(sub), bytes
+end
diff --git a/tests/lua/lua-transform-02/README.md b/tests/lua/lua-transform-02/README.md
new file mode 100644 (file)
index 0000000..10c8d07
--- /dev/null
@@ -0,0 +1 @@
+Lua transform: Ensure non-existent lua scripts are detected.
diff --git a/tests/lua/lua-transform-02/test.rules b/tests/lua/lua-transform-02/test.rules
new file mode 100644 (file)
index 0000000..c16f5a4
--- /dev/null
@@ -0,0 +1 @@
+alert http any any -> any any (msg:"TEST"; http.uri; luaxform:no_filetransform.lua;content:"EXEC_POST.PHP";  sid:1; rev:1;)
diff --git a/tests/lua/lua-transform-02/test.yaml b/tests/lua/lua-transform-02/test.yaml
new file mode 100644 (file)
index 0000000..fcfed6b
--- /dev/null
@@ -0,0 +1,20 @@
+requires:
+  min-version: 8
+
+args:
+  - --set default-rule-path=${TEST_DIR}
+  - --set security.lua.allow-rules=true
+  - --set logging.outputs.1.file.type=json
+  - -T
+
+exit-code: 1
+
+pcap: false
+checks:
+  - filter:
+      count: 1
+      filename: suricata.log
+      match:
+        event_type: engine
+        engine.message.__startswith: "couldn't load file"
+        engine.message.__find: "no_filetransform.lua: No such file or directory"
diff --git a/tests/lua/lua-transform-03/README.md b/tests/lua/lua-transform-03/README.md
new file mode 100644 (file)
index 0000000..136e591
--- /dev/null
@@ -0,0 +1 @@
+Lua transform test: ensure lua script has a transform function
diff --git a/tests/lua/lua-transform-03/test.rules b/tests/lua/lua-transform-03/test.rules
new file mode 100644 (file)
index 0000000..0f33f60
--- /dev/null
@@ -0,0 +1 @@
+alert http any any -> any any (msg:"TEST"; http.uri; luaxform:transform.lua;content:"EXEC_POST.PHP";  sid:1; rev:1;)
diff --git a/tests/lua/lua-transform-03/test.yaml b/tests/lua/lua-transform-03/test.yaml
new file mode 100644 (file)
index 0000000..eff4295
--- /dev/null
@@ -0,0 +1,20 @@
+requires:
+  min-version: 8
+
+args:
+  - --set default-rule-path=${TEST_DIR}
+  - --set security.lua.allow-rules=true
+  - --set logging.outputs.1.file.type=json
+  - -T
+
+pcap: false
+
+exit-code: 1
+
+checks:
+  - filter:
+      count: 1
+      filename: suricata.log
+      match:
+        engine.message.__find: "no transform function in script"
+        event_type: engine
diff --git a/tests/lua/lua-transform-03/transform.lua b/tests/lua/lua-transform-03/transform.lua
new file mode 100644 (file)
index 0000000..294f578
--- /dev/null
@@ -0,0 +1,7 @@
+function no_transform(input, args)
+    local bytes = #input
+    local offset = 0
+
+    local sub = string.sub(input, offset + 1, offset + bytes)
+    return string.upper(sub), bytes
+end
diff --git a/tests/lua/lua-transform-04/README.md b/tests/lua/lua-transform-04/README.md
new file mode 100644 (file)
index 0000000..ae099cc
--- /dev/null
@@ -0,0 +1 @@
+Ensure Lua transform receives optional transform function arguments
diff --git a/tests/lua/lua-transform-04/test.rules b/tests/lua/lua-transform-04/test.rules
new file mode 100644 (file)
index 0000000..2224c83
--- /dev/null
@@ -0,0 +1 @@
+alert http any any -> any any (msg:"TEST"; http.uri; luaxform:transform.lua, bytes 0, offset 2;content:"EXEC_POST.PHP";  sid:1; rev:1;)
diff --git a/tests/lua/lua-transform-04/test.yaml b/tests/lua/lua-transform-04/test.yaml
new file mode 100644 (file)
index 0000000..65b944f
--- /dev/null
@@ -0,0 +1,18 @@
+requires:
+  min-version: 8
+
+args:
+  - --set default-rule-path=${TEST_DIR}
+  - --set security.lua.allow-rules=true
+
+pcap: ../lua-transform-01/test.pcap
+
+checks:
+
+  - shell:
+      args: grep  "1 item.*  bytes 0" stdout | wc -l | xargs
+      expect: 1
+
+  - shell:
+      args: grep  "2 item.*  offset 2" stdout| wc -l | xargs
+      expect: 1
diff --git a/tests/lua/lua-transform-04/transform.lua b/tests/lua/lua-transform-04/transform.lua
new file mode 100644 (file)
index 0000000..96d63de
--- /dev/null
@@ -0,0 +1,10 @@
+function transform(input, args)
+    offset = 0
+    bytes = #input
+    for i, item in ipairs(args) do
+        print(i .. " item: " .. item)
+    end
+
+    local sub = string.sub(input, offset + 1, offset + bytes)
+    return string.upper(sub), bytes
+end
index fc7f577c4c28f1b8f14e9e8b9d29702a97d61284..6d49b79ec8778eaeceb32a2785dbd13c4dc1e675 100644 (file)
@@ -1,8 +1,3 @@
-function init (args)
-    local needs = {}
-    return needs
-end
-
-function transform(input_len, input, argc, args)
-    return nil
+function transform(input, args)
+    return nil, 0
 end
diff --git a/tests/lua/lua-transform-06/README.md b/tests/lua/lua-transform-06/README.md
new file mode 100644 (file)
index 0000000..423cac5
--- /dev/null
@@ -0,0 +1 @@
+Lua transform test: transform function returns 1 parameter when 2 are required.
diff --git a/tests/lua/lua-transform-06/test.rules b/tests/lua/lua-transform-06/test.rules
new file mode 100644 (file)
index 0000000..0f33f60
--- /dev/null
@@ -0,0 +1 @@
+alert http any any -> any any (msg:"TEST"; http.uri; luaxform:transform.lua;content:"EXEC_POST.PHP";  sid:1; rev:1;)
diff --git a/tests/lua/lua-transform-06/test.yaml b/tests/lua/lua-transform-06/test.yaml
new file mode 100644 (file)
index 0000000..f564e8c
--- /dev/null
@@ -0,0 +1,16 @@
+requires:
+  min-version: 8
+
+args:
+  - --set default-rule-path=${TEST_DIR}
+  - --set security.lua.allow-rules=true
+
+pcap: ../lua-transform-01/test.pcap
+
+checks:
+  - filter:
+      count: 0
+      match:
+        event_type: alert
+        alert.signature_id: 1
+        http.url: /exec_post.php
diff --git a/tests/lua/lua-transform-06/transform.lua b/tests/lua/lua-transform-06/transform.lua
new file mode 100644 (file)
index 0000000..7126ae0
--- /dev/null
@@ -0,0 +1,8 @@
+function transform(input, args)
+    local bytes = #input
+    local offset = 0
+
+    local sub = string.sub(input, offset + 1, offset + bytes)
+    -- Note -- only one value is returned when 2 are expected: buffer, byte-count
+    return string.upper(sub)
+end
diff --git a/tests/lua/lua-transform-07/README.md b/tests/lua/lua-transform-07/README.md
new file mode 100644 (file)
index 0000000..c9f52c1
--- /dev/null
@@ -0,0 +1,2 @@
+Ensure Lua transform receives optional transform function arguments. The Lua transform script
+is also provided as an example in the documentation.
diff --git a/tests/lua/lua-transform-07/test.rules b/tests/lua/lua-transform-07/test.rules
new file mode 100644 (file)
index 0000000..58cd4ab
--- /dev/null
@@ -0,0 +1 @@
+alert http any any -> any any (msg:"TEST"; http.uri; luaxform:transform.lua, bytes 12, offset 2;content:"XEC_POST.PHP";  sid:1; rev:1;)
diff --git a/tests/lua/lua-transform-07/test.yaml b/tests/lua/lua-transform-07/test.yaml
new file mode 100644 (file)
index 0000000..f58bfd9
--- /dev/null
@@ -0,0 +1,16 @@
+requires:
+  min-version: 8
+
+args:
+  - --set default-rule-path=${TEST_DIR}
+  - --set security.lua.allow-rules=true
+
+pcap: ../lua-transform-01/test.pcap
+
+checks:
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature_id: 1
diff --git a/tests/lua/lua-transform-07/transform.lua b/tests/lua/lua-transform-07/transform.lua
new file mode 100644 (file)
index 0000000..8776fae
--- /dev/null
@@ -0,0 +1,49 @@
+function init()
+end
+
+local function get_value(item, key)
+   if string.find(item, key) then
+          local _, value = string.match(item, "(%a+)%s*(%d*)")
+          if value ~= "" then
+                  return tonumber(value)
+          end
+   end
+
+   return nil
+end
+
+-- Arguments supported
+local bytes_key = "bytes"
+local offset_key = "offset"
+function transform(input, args)
+   local bytes = #input
+   local offset = 0
+
+   -- Look for optional bytes and offset arguments
+   for i, item in ipairs(args) do
+          local value = get_value(item, bytes_key)
+          if value ~= nil then
+                  bytes = value
+          else
+                  value = get_value(item, offset_key)
+                  if value ~= nil then
+                          offset = value
+                  end
+          end
+   end
+
+   local str_len = #input
+   if offset < 0 or offset > str_len then
+          print("offset is out of bounds: " .. offset)
+          return nil
+   end
+
+   local avail_len = str_len - offset
+   if bytes < 0 or bytes > avail_len then
+       print("invalid bytes " ..  bytes .. " or bytes exceeds available  length " .. avail_len)
+          return nil
+   end
+
+   local sub = string.sub(input, offset + 1, offset + bytes)
+   return string.upper(sub), bytes
+end
diff --git a/tests/lua/lua-transform-08/README.md b/tests/lua/lua-transform-08/README.md
new file mode 100644 (file)
index 0000000..3e44031
--- /dev/null
@@ -0,0 +1,4 @@
+Lua transform tests -- test using Suricata Lua libraries:
+- hashlib
+- base64
+- dataset
diff --git a/tests/lua/lua-transform-08/suricata.yaml b/tests/lua/lua-transform-08/suricata.yaml
new file mode 100644 (file)
index 0000000..9905eb1
--- /dev/null
@@ -0,0 +1,313 @@
+%YAML 1.1
+---
+
+stats:
+  enabled: yes
+  interval: 8
+
+# Configure the type of alert (and other) logging you would like.
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular #regular|syslog|unix_dgram|unix_stream|redis
+      filename: eve.json
+      # Enable for multi-threaded eve.json output; output files are amended with
+      # an identifier, e.g., eve.9.json
+      #threaded: false
+      #prefix: "@cee: " # prefix to prepend to each log entry
+      # the following are valid when type: syslog above
+      #identity: "suricata"
+      #facility: local5
+      #level: Info ## possible levels: Emergency, Alert, Critical,
+                   ## Error, Warning, Notice, Info, Debug
+      #ethernet: no  # log ethernet header in events when available
+      #redis:
+      #  server: 127.0.0.1
+      #  port: 6379
+      #  async: true ## if redis replies are read asynchronously
+      #  mode: list ## possible values: list|lpush (default), rpush, channel|publish, xadd|stream
+      #             ## lpush and rpush are using a Redis list. "list" is an alias for lpush
+      #             ## publish is using a Redis channel. "channel" is an alias for publish
+      #             ## xadd is using a Redis stream. "stream" is an alias for xadd
+      #  key: suricata ## string denoting the key/channel/stream to use (default to suricata)
+      #  stream-maxlen: 100000        ## Automatically trims the stream length to at most
+                                      ## this number of events. Set to 0 to disable trimming.
+                                      ## Only used when mode is set to xadd/stream.
+      #  stream-trim-exact: false     ## Trim exactly to the maximum stream length above.
+                                      ## Default: use inexact trimming (inexact by a few
+                                      ## tens of items)
+                                      ## Only used when mode is set to xadd/stream.
+      # Redis pipelining set up. This will enable to only do a query every
+      # 'batch-size' events. This should lower the latency induced by network
+      # connection at the cost of some memory. There is no flushing implemented
+      # so this setting should be reserved to high traffic Suricata deployments.
+      #  pipelining:
+      #    enabled: yes ## set enable to yes to enable query pipelining
+      #    batch-size: 10 ## number of entries to keep in buffer
+
+      # Include top level metadata. Default yes.
+      #metadata: no
+
+      # include the name of the input pcap file in pcap file processing mode
+      pcap-file: false
+
+      # Community Flow ID
+      # Adds a 'community_id' field to EVE records. These are meant to give
+      # records a predictable flow ID that can be used to match records to
+      # output of other tools such as Zeek (Bro).
+      #
+      # Takes a 'seed' that needs to be same across sensors and tools
+      # to make the id less predictable.
+
+      # enable/disable the community id feature.
+      community-id: false
+      # Seed value for the ID output. Valid values are 0-65535.
+      community-id-seed: 0
+
+      # HTTP X-Forwarded-For support by adding an extra field or overwriting
+      # the source or destination IP address (depending on flow direction)
+      # with the one reported in the X-Forwarded-For HTTP header. This is
+      # helpful when reviewing alerts for traffic that is being reverse
+      # or forward proxied.
+      xff:
+        enabled: no
+        # Two operation modes are available: "extra-data" and "overwrite".
+        mode: extra-data
+        # Two proxy deployments are supported: "reverse" and "forward". In
+        # a "reverse" deployment the IP address used is the last one, in a
+        # "forward" deployment the first IP address is used.
+        deployment: reverse
+        # Header name where the actual IP address will be reported. If more
+        # than one IP address is present, the last IP address will be the
+        # one taken into consideration.
+        header: X-Forwarded-For
+
+      types:
+        - alert:
+            # payload: yes             # enable dumping payload in Base64
+            # payload-buffer-size: 4 KiB  # max size of payload buffer to output in eve-log
+            # payload-printable: yes   # enable dumping payload in printable (lossy) format
+            # payload-length: yes      # enable dumping payload length, including the gaps
+            # packet: yes              # enable dumping of packet (without stream segments)
+            # metadata: no             # enable inclusion of app layer metadata with alert. Default yes
+            # If you want metadata, use:
+            # metadata:
+              # Include the decoded application layer (ie. http, dns)
+              #app-layer: true
+              # Log the current state of the flow record.
+              #flow: true
+              #rule:
+                # Log the metadata field from the rule in a structured
+                # format.
+                #metadata: true
+                # Log the raw rule text.
+                #raw: false
+                #reference: false      # include reference information from the rule
+            # http-body: yes           # Requires metadata; enable dumping of HTTP body in Base64
+            # http-body-printable: yes # Requires metadata; enable dumping of HTTP body in printable format
+            # websocket-payload: yes   # Requires metadata; enable dumping of WebSocket Payload in Base64
+            # websocket-payload-printable: yes # Requires metadata; enable dumping of WebSocket Payload in printable format
+
+            # Enable the logging of tagged packets for rules using the
+            # "tag" keyword.
+            tagged-packets: yes
+            # Enable logging the final action taken on a packet by the engine
+            # (e.g: the alert may have action 'allowed' but the verdict be
+            # 'drop' due to another alert. That's the engine's verdict)
+            # verdict: yes
+        # app layer frames
+        - frame:
+            # disabled by default as this is very verbose.
+            enabled: no
+            # payload-buffer-size: 4 KiB # max size of frame payload buffer to output in eve-log
+        - anomaly:
+            # Anomaly log records describe unexpected conditions such
+            # as truncated packets, packets with invalid IP/UDP/TCP
+            # length values, and other events that render the packet
+            # invalid for further processing or describe unexpected
+            # behavior on an established stream. Networks which
+            # experience high occurrences of anomalies may experience
+            # packet processing degradation.
+            #
+            # Anomalies are reported for the following:
+            # 1. Decode: Values and conditions that are detected while
+            # decoding individual packets. This includes invalid or
+            # unexpected values for low-level protocol lengths as well
+            # as stream related events (TCP 3-way handshake issues,
+            # unexpected sequence number, etc).
+            # 2. Stream: This includes stream related events (TCP
+            # 3-way handshake issues, unexpected sequence number,
+            # etc).
+            # 3. Application layer: These denote application layer
+            # specific conditions that are unexpected, invalid or are
+            # unexpected given the application monitoring state.
+            #
+            # By default, anomaly logging is enabled. When anomaly
+            # logging is enabled, applayer anomaly reporting is
+            # also enabled.
+            enabled: yes
+            #
+            # Choose one or more types of anomaly logging and whether to enable
+            # logging of the packet header for packet anomalies.
+            types:
+              # decode: no
+              # stream: no
+              # applayer: yes
+            #packethdr: no
+        - http:
+            extended: yes     # enable this for extended logging information
+            # custom allows additional HTTP fields to be included in eve-log.
+            # the example below adds three additional fields when uncommented
+            #custom: [Accept-Encoding, Accept-Language, Authorization]
+            # set this value to one and only one from {both, request, response}
+            # to dump all HTTP headers for every HTTP request and/or response
+            # dump-all-headers: none
+        - dns:
+            # Suricata 8.0 uses a new DNS logging format, to keep with
+            # the old format while you upgrade the version can be set
+            # to 2. See https://docs.suricata.io/en/latest/upgrade/8.0-dns-logging-changes.html
+            #version: 3
+
+            # Enable/disable this logger. Default: enabled.
+            #enabled: yes
+
+            # Control logging of requests and responses:
+            # - requests: enable logging of DNS queries
+            # - responses: enable logging of DNS answers
+            # By default both requests and responses are logged.
+            #requests: no
+            #responses: no
+
+            # Format of answer logging:
+            # - detailed: array item per answer
+            # - grouped: answers aggregated by type
+            # Default: all
+            #formats: [detailed, grouped]
+
+            # DNS record types to log, based on the query type.
+            # Default: all.
+            #types: [a, aaaa, cname, mx, ns, ptr, txt]
+        - tls:
+            extended: yes     # enable this for extended logging information
+            # output TLS transaction where the session is resumed using a
+            # session id
+            #session-resumption: no
+            # custom controls which TLS fields that are included in eve-log
+            # WARNING: enabling custom disables extended logging.
+            #custom: [subject, issuer, session_resumed, serial, fingerprint, sni, version, not_before, not_after, certificate, chain, ja3, ja3s, ja4, subjectaltname, client, client_certificate, client_chain, client_alpns, server_alpns]
+        - files:
+            force-magic: no   # force logging magic on all logged files
+            # force logging of checksums, available hash functions are md5,
+            # sha1 and sha256
+            #force-hash: [md5]
+        #- drop:
+        #    alerts: yes      # log alerts that caused drops
+        #    flows: all       # start or all: 'start' logs only a single drop
+        #                     # per flow direction. All logs each dropped pkt.
+            # Enable logging the final action taken on a packet by the engine
+            # (will show more information in case of a drop caused by 'reject')
+            # verdict: yes
+        - smtp:
+            #extended: yes # enable this for extended logging information
+            # this includes: bcc, message-id, subject, x_mailer, user-agent
+            # custom fields logging from the list:
+            #  reply-to, bcc, message-id, subject, x-mailer, user-agent, received,
+            #  x-originating-ip, in-reply-to, references, importance, priority,
+            #  sensitivity, organization, content-md5, date
+            #custom: [received, x-mailer, x-originating-ip, relays, reply-to, bcc]
+            # output md5 of fields: body, subject
+            # for the body you need to set app-layer.protocols.smtp.mime.body-md5
+            # to yes
+            #md5: [body, subject]
+
+        #- dnp3
+        - websocket
+        #- enip
+        - ftp
+        - rdp
+        - nfs
+        - smb
+        - tftp
+        - ike
+        - dcerpc
+        - krb5
+        - snmp
+        - rfb
+        - sip
+        - quic
+        - ldap
+        - arp:
+            enabled: no        # Many events can be logged. Disabled by default
+        - dhcp:
+            enabled: yes
+            # When extended mode is on, all DHCP messages are logged
+            # with full detail. When extended mode is off (the
+            # default), just enough information to map a MAC address
+            # to an IP address is logged.
+            extended: no
+        - ssh
+        - mqtt:
+            # passwords: yes           # enable output of passwords
+            # string-log-limit: 1KiB   # limit size of logged strings in bytes.
+                                       # Can be specified in KiB, MiB, GiB. Just a number
+                                       # is parsed as bytes. Default is 1 KiB.
+                                       # Use a value of 0 to disable limiting.
+                                       # Note that the size is also bounded by
+                                       # the maximum parsed message size (see
+                                       # app-layer configuration)
+        - http2
+        # dns over http2
+        - doh2
+        - pgsql:
+            enabled: no
+            # passwords: yes           # enable output of passwords. Disabled by default
+        - stats:
+            totals: yes       # stats for all threads merged together
+            threads: no       # per thread stats
+            deltas: no        # include delta values
+            # Don't log stats counters that are zero. Default: true
+            #null-values: false    # False will NOT log stats counters: 0
+        # bi-directional flows
+        - flow
+        # uni-directional flows
+        #- netflow
+
+        # Metadata event type. Triggered whenever a pktvar is saved
+        # and will include the pktvars, flowvars, flowbits and
+        # flowints.
+        #- metadata
+
+        # EXPERIMENTAL per packet output giving TCP state tracking details
+        # including internal state, flags, etc.
+        # This output is experimental, meant for debugging and subject to
+        # change in both config and output without any notice.
+        #- stream:
+        #   all: false                      # log all TCP packets
+        #   event-set: false                # log packets that have a decoder/stream event
+        #   state-update: false             # log packets triggering a TCP state update
+        #   spurious-retransmission: false  # log spurious retransmission packets
+
+# Datasets default settings
+datasets:
+  # Default fallback memcap and hashsize values for datasets in case these
+  # were not explicitly defined.
+  defaults:
+    #memcap: 100 MiB
+    #hashsize: 2048
+
+  rules:
+    # Set to true to allow absolute filenames and filenames that use
+    # ".." components to reference parent directories in rules that specify
+    # their filenames.
+    #allow-absolute-filenames: false
+
+    # Allow datasets in rules write access for "save" and
+    # "state". This is enabled by default, however write access is
+    # limited to the data directory.
+    #allow-write: true
+  versions-seen:
+    type: string
+
+security:
+  lua:
+    allow-rules: true
diff --git a/tests/lua/lua-transform-08/test.pcap b/tests/lua/lua-transform-08/test.pcap
new file mode 100644 (file)
index 0000000..b9eec15
Binary files /dev/null and b/tests/lua/lua-transform-08/test.pcap differ
diff --git a/tests/lua/lua-transform-08/test.rules b/tests/lua/lua-transform-08/test.rules
new file mode 100644 (file)
index 0000000..250177c
--- /dev/null
@@ -0,0 +1,7 @@
+# base64 encode: "/exec_post.php"
+alert http any any -> any any (msg:"TEST: base64 encode "; http.uri; luaxform:transform-base64.lua; content:"L2V4ZWNfcG9zdC5waHA=";  sid:1;)
+# sha256 encode: "/exec_post.php"
+alert http any any -> any any (msg:"TEST: sha256 encode"; http.uri; luaxform:transform-hashlib.lua; content:"3c09198a7be48f234b17995d5cc6e9614388b6c0915be55ede7e2df20d110dba";  sid:2;)
+# adds uri to dataset
+alert http any any -> any any (msg:"TEST: add uri to dataset"; http.uri; luaxform:transform-dataset.lua; content:"/exec_post.php";  sid:3;)
+alert http any any -> any any (msg:"TEST: uri in dataset"; http.uri; dataset:isset,versions-seen; sid:4;)
diff --git a/tests/lua/lua-transform-08/test.yaml b/tests/lua/lua-transform-08/test.yaml
new file mode 100644 (file)
index 0000000..325c4d8
--- /dev/null
@@ -0,0 +1,29 @@
+requires:
+  min-version: 8
+
+args:
+  - --set default-rule-path=${TEST_DIR}
+  - --set security.lua.allow-rules=true
+
+checks:
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature_id: 1
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature_id: 2
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature_id: 3
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        http.url: /exec_post.php
+        alert.signature_id: 4
diff --git a/tests/lua/lua-transform-08/transform-base64.lua b/tests/lua/lua-transform-08/transform-base64.lua
new file mode 100644 (file)
index 0000000..b351b2c
--- /dev/null
@@ -0,0 +1,6 @@
+local base64 = require("suricata.base64")
+
+function transform(input, args)
+    encoded = base64.encode(input)
+    return encoded, #encoded
+end
diff --git a/tests/lua/lua-transform-08/transform-dataset.lua b/tests/lua/lua-transform-08/transform-dataset.lua
new file mode 100644 (file)
index 0000000..9bace9a
--- /dev/null
@@ -0,0 +1,26 @@
+local dataset = require("suricata.dataset")
+
+function thread_init(args)
+    dataset_new, err = dataset.new()
+    if err ~= nil then
+        SCLogWarning("dataset warning: " .. err)
+        return 0
+    end
+    ret, err = dataset_new:get("versions-seen")
+    if err ~= nil then
+        SCLogWarning("dataset warning: " .. err)
+        return 0
+    end
+end
+
+function transform(input, args)
+    ret, err = dataset_new:add(input, #input)
+    if err ~= nil then
+        SCLogWarning("lua warning: " .. err)
+        return 0
+    end
+    if ret == 1 then
+        SCLogNotice(input .. " => " .. ret)
+    end
+    return ret
+end
diff --git a/tests/lua/lua-transform-08/transform-hashlib.lua b/tests/lua/lua-transform-08/transform-hashlib.lua
new file mode 100644 (file)
index 0000000..9d0c667
--- /dev/null
@@ -0,0 +1,17 @@
+local hashlib = require("suricata.hashlib")
+
+local function tohex(str)
+    local hex = {}
+    for i = 1, #str do
+        hex[i] = string.format("%02x", string.byte(str, i))
+    end
+    return table.concat(hex)
+end
+
+function transform(input, args)
+    local hash = hashlib.sha256_digest(input)
+    print(string.format("hash: \"%s\"\n", tohex(hash)))
+    local phash = tohex(hash)
+    return phash, #phash
+
+end