Ruby script for auditd EXECVE logs

I want to make a ruby script that makes an extra field for "command" that it parses out of the message that auditd creates, however it does not work and I am unable to figure out why.

example log:
type=EXECVE msg=audit(1676645236.583:93680): argc=2 a0="hostname" a1="-f"

part of the logstash config in question:

mutate {
          add_field => { "command" => "" }
}

                if "type=EXECVE" in [message] {
                        ruby {
                                code => '
def filter(event)
    if event.get("message").include?("type=execve")
      args = ""
      99.times do |i|
        break unless event.include?("a" + (i+0).to_s)
        args += event.get(("a" + (i+0).to_s) + " ")
      end
      event.set("command", args.strip)

      event.remove("a%{[0-9]+}")
    end

    return [event]
end'
                         }
                }

Ruby script:

def filter(event)
  if event.get("message").include?("type=execve")
    args = ''
    99.times do |i|
      break unless event.include?('a' + (i+0).to_s)
      args += event.get(('a' + (i+0).to_s) + ' ')
    end
    event.set('command', args.strip)
    event.remove("a%{[0-9]+}")
  end
  return [event]
end

current output:

A ruby filter can use inline code (the code/init options) or a script in a file (the path option).

With the path option you define a filter method that returns an array of events and it gets called for each event.

With the code/init options you write a lambda that references a variable called event. You use event.get/set/remove etc. to modify it.

You have written code in the first form but invoke it using the second. That will not work. For every event your function will get redefined, but not called.

When using init/code define functions in the init block and call them in the code block.

I would implement this using

    kv { source => "message" target => "[@metadata][kvData]" }
    if [@metadata][kvData][type] == "EXECVE" {
        ruby {
            code => '
                argc = event.get("[@metadata][kvData][argc]").to_i
                command = ""
                (0 ... argc).each { |x| command += event.remove("[@metadata][kvData][a#{x}]") + " " }
                event.set("command", command.chop)
            '
        }
    }

Incredible, thank you. It works

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.