Custom Active Response Script

273 views
Skip to first unread message

Norah nox

unread,
Jul 6, 2023, 9:58:21 AM7/6/23
to Wazuh mailing list
Hi 
I am using wazuh's custom active response script for windows, the one which turn the python file into executable file: 
#!/usr/bin/python3
# Copyright (C) 2015-2022, Wazuh Inc.
# All rights reserved.

# This program is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public
# License (version 2) as published by the FSF - Free Software
# Foundation.

import os
import sys
import json
import datetime
from pathlib import PureWindowsPath, PurePosixPath

if os.name == 'nt':
    LOG_FILE = "C:\\Program Files (x86)\\ossec-agent\\active-response\\active-responses.log"
else:
    LOG_FILE = "/var/ossec/logs/active-responses.log"

ADD_COMMAND = 0
DELETE_COMMAND = 1
CONTINUE_COMMAND = 2
ABORT_COMMAND = 3

OS_SUCCESS = 0
OS_INVALID = -1

class message:
    def __init__(self):
        self.alert = ""
        self.command = 0


def write_debug_file(ar_name, msg):
    with open(LOG_FILE, mode="a") as log_file:
        ar_name_posix = str(PurePosixPath(PureWindowsPath(ar_name[ar_name.find("active-response"):])))
        log_file.write(str(datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S')) + " " + ar_name_posix + ": " + msg +"\n")


def setup_and_check_message(argv):

    # get alert from stdin
    input_str = ""
    for line in sys.stdin:
        input_str = line
        break

    write_debug_file(argv[0], input_str)

    try:
        data = json.loads(input_str)
    except ValueError:
        write_debug_file(argv[0], 'Decoding JSON has failed, invalid input format')
        message.command = OS_INVALID
        return message

    message.alert = data

    command = data.get("command")

    if command == "add":
        message.command = ADD_COMMAND
    elif command == "delete":
        message.command = DELETE_COMMAND
    else:
        message.command = OS_INVALID
        write_debug_file(argv[0], 'Not valid command: ' + command)

    return message


def send_keys_and_check_message(argv, keys):

    # build and send message with keys
    keys_msg = json.dumps({"version": 1,"origin":{"name": argv[0],"module":"active-response"},"command":"check_keys","parameters":{"keys":keys}})

    write_debug_file(argv[0], keys_msg)

    print(keys_msg)
    sys.stdout.flush()

    # read the response of previous message
    input_str = ""
    while True:
        line = sys.stdin.readline()
        if line:
            input_str = line
            break

    write_debug_file(argv[0], input_str)

    try:
        data = json.loads(input_str)
    except ValueError:
        write_debug_file(argv[0], 'Decoding JSON has failed, invalid input format')
        return message

    action = data.get("command")

    if "continue" == action:
        ret = CONTINUE_COMMAND
    elif "abort" == action:
        ret = ABORT_COMMAND
    else:
        ret = OS_INVALID
        write_debug_file(argv[0], "Invalid value of 'command'")

    return ret


def main(argv):

    write_debug_file(argv[0], "Started")

    # validate json and get command
    msg = setup_and_check_message(argv)

    if msg.command < 0:
        sys.exit(OS_INVALID)

    if msg.command == ADD_COMMAND:

        """ Start Custom Key
        At this point, it is necessary to select the keys from the alert and add them into the keys array.
        """

        alert = msg.alert["parameters"]["alert"]
        keys = [alert["rule"]["id"]]

        """ End Custom Key """

        action = send_keys_and_check_message(argv, keys)

        # if necessary, abort execution
        if action != CONTINUE_COMMAND:

            if action == ABORT_COMMAND:
                write_debug_file(argv[0], "Aborted")
                sys.exit(OS_SUCCESS)
            else:
                write_debug_file(argv[0], "Invalid command")
                sys.exit(OS_INVALID)

        """ Start Custom Action Add """

        with open("ar-test-result.txt", mode="a") as test_file:
            test_file.write("Active response triggered by rule ID: <" + str(keys) + ">\n")

        """ End Custom Action Add """

    elif msg.command == DELETE_COMMAND:

        """ Start Custom Action Delete """

        os.remove("ar-test-result.txt")

        """ End Custom Action Delete """

    else:
        write_debug_file(argv[0], "Invalid command")

    write_debug_file(argv[0], "Ended")

    sys.exit(OS_SUCCESS)


if __name__ == "__main__":
    main(sys.argv)

This created a file named as custom-ar.exe which was to be pasted in bin folder of active response.
and the Api request I am passing is via shuffle :

{
  "command": "custom-ar60",

"alert": {
  "cmd": "net start MSSQLSERVER",
  "callback": "${webhook_url}"
}
 }

I basically want to restart the sql service once they are stopped manually or automatically in WINDOWS. 
I was able to do it for Linux but for windows this is not working for me.
I also added the block of codes in manager 
<command>
<name>windows-custom-ar</name>
<executable>custom-ar.exe</executable>
<timeout_allowed>yes</timeout_allowed>
</command>

<active-response>
<disabled>no</disabled>
<command>windows-custom-ar</command>
<location>local</location>
<rules_id>100107</rules_id>
<timeout>60</timeout>
</active-response>
I feel in the script (custom-ar) there is something missing for running this command in cmd because I am getting the active response alerts in wazuh but nothing is working in the backend that is the sql service was not started.

Is there any other approach?? I would really appreciate if I could get a generalised script for any type of active response I want by simply pushing any json via shuffle.

Norah nox

unread,
Jul 6, 2023, 10:16:18 AM7/6/23
to Wazuh mailing list

{
  "command": "windows-custom-ar60",

"alert": {
  "cmd": "net start MSSQLSERVER",
  "callback": "${webhook_url}"
}
 }

Sorry the shuffle command is this ... From shuffle the command is being sent successfully but it is not executed only is generating the alert in wazuh

John Soliani

unread,
Jul 6, 2023, 11:55:41 AM7/6/23
to Wazuh mailing list
Hello Norah,

  I will take a look and run some tests on this and will reply to you as soon as possible.

Regards,
John.-

Message has been deleted

John Soliani

unread,
Jul 24, 2023, 11:03:27 AM7/24/23
to Wazuh mailing list

Hello Norah,

When customizing AR commands, the first thing to test is that the command works when it is executed manually in the wazuh-agent active-response/bin folder.

Lastly, there is a way to run Python scripts directly on the agent (Linux, macOS, and Windows), here’s the documentation for Windows agents that should work for your needs:

Configurations on the manager should be something similar to these:

<ossec_config> <command> <name>custom-ar</name> <executable>launcher.cmd</executable> <extra_args>custom-ar.py</extra_args> <timeout_allowed>yes</timeout_allowed> </command> <active-response> <disabled>no</disabled> <command>custom-ar</command> <location>local</location> <rules_id>503</rules_id> <timeout>60</timeout> </active-response> </ossec_config>

Bear in mind that exe binary files in Windows are risky, they could get infected by a virus at any time, also, Python scripts will open doors to many custom implementations in the future that can be developed and tested really easily.

Hope this helps.

Reply all
Reply to author
Forward
0 new messages