SOT

SOT

SOAR
Security Orchestration, Automation and Response

Automation of response to information security incidents using dynamic playbooks and information security tools, building an attack chain and with an object-oriented approach

NG SOAR
Next Generation SOAR

Automation of response to information security incidents with built-in basic correlation (SIEM), vulnerability Scanner (VS), collection of raw events directly from information security tools, dynamic playbooks, building an attack chain and an object-oriented approach. AM and VM are included

AM
Asset Management

Description of the IT landscape, detection of new objects on the network, categorization of assets, inventory, life cycle management of equipment and software on automated workstations and servers of organizations

VS
Vulnerability Scanner

Scanning information assets with enrichment from any external services (additional scanners, The Data Security Threats Database and other analytical databases) to analyze the security of the infrastructure.

VM
Vulnerability Management

Building a process for detecting and eliminating technical vulnerabilities, collecting information from existing security scanners, update management platforms, expert external services and other solutions

FinCERT
Financial Computer Emergency Response Team

Bilateral interaction with the Central Bank, namely the transfer of information about incidents and receipt of prompt notifications/bulletins from the regulator

GovCERT
Government Computer Emergency Response Team

Bilateral interaction with the state coordination center for computer incidents, namely the transfer of information about incidents and receipt of prompt notifications/bulletins from the regulator

Mail us to sales@securityvision.ru or get demo presentation

How Zeek and Malcolm help you not only passively analyse network traffic, but also respond to threats in a timely manner

How Zeek and Malcolm help you not only passively analyse network traffic, but also respond to threats in a timely manner
06.03.2025

Vasily Larin, Security Vision


Intrusion detection systems (IDSs) are one of the most important network security links in a company's infrastructure. They can be integrated into complex hardware devices, such as the now popular Next Generation Firewalls (NGFW), or they can exist as stand-alone information security products (ISPs). This article describes the Zeek PSB. Typically, Zeek is used to collect traffic that will be analysed by SOC analysts. But this article shows that Zeek can also be used as an intrusion prevention system by interacting with various security mechanisms on the host. The article also describes another solution, Malcolm, which is closely related to Zeek. Malcolm is a traffic analysis system that includes solutions such as Zeek, Suricata, and visualisation components that show real-time traffic changes. When properly configured, Malcolm can be a good and relatively free solution that can be built into the SOC department of a medium or small company.


Description of Zeek


Zeek (formerly known as Bro) is an open-source solution for analysing traffic on a network. One of the main advantages is that Zeek provides a large set of log files. Each log file contains specific network activity: HTTP sessions, DNS requests, TLS connections, TLS certificate information, and more. In addition to logs, Zeek has built-in features for a number of analysis and detection tasks. It can extract files from HTTP sessions, detect malware by interacting with external registries, report vulnerable software versions found on the network, identify popular websites, applications, and more.


In addition to this powerful out-of-the-box functionality, Zeek is a fully customisable and extensible traffic analysis platform. Zeek provides users with a subject-oriented scripting language to solve arbitrary analytical problems. Zeek runs on standard hardware and therefore provides a good alternative to expensive solutions. Zeek is specifically targeted at high-speed, high-volume network monitoring. Zeek is written in C++ and is distributed under the BSD licence.


Zeek Architecture


Fig. 1 Zeek architecture


Zeek's architecture is divided into two main components. The first component is the event engine. It helps to divide a network packet into several high-level events. These events reflect network activity, i.e. they describe what has been seen in the network packet. The event engine component includes a number of subcomponents: input sources, packet analysis, session analysis, and file analysis. Packet analysis handles lower level protocols, starting at the data link layer. Session analysis examines application layer protocols such as HTTP, FTP, etc. File analysis analyses the contents of files transferred during a session. The event engine provides a plugin architecture that allows you to extend Zeek's capabilities as needed.


The second major component of Zeek is a script interpreter that executes a set of event handlers written in the Zeek scripting language. These scripts can monitor various activities on the network and in the process, for example, execute an external programme (create a blocking rule in a firewall).


Monitoring network activity with Zeek


Zeek is designed to view network traffic in real time. Although Zeek can handle captured packets stored in PCAP format, most users use Zeek to listen to one or more network interfaces, obtaining relevant logs as well as the contents of extracted files.


For training purposes, users can run Zeek on a separate computer used for general computing purposes and monitor network traffic passing through that computer. This is an easy way to familiarise yourself with the logs that Zeek generates. This approach is similar to running Tcpdump or Wireshark on a computer.


IS personnel call it a "sensor" and deploy it specifically to monitor network traffic.


Installing Zeek


The official Zeek developer community provides a wide range of installation options on Linux: install the official docker image, install using binary packages, or build from source.


This article describes how to install via binary packages for Debian 12. To install Zeek, the path to the official Zeek repository must be written in source.list.d, and a public key must be added.


echo 'deb http://download.opensuse.org/repositories/security:/zeek/Debian_12/ /' | sudo tee /etc/apt/sources.list.d/security:zeek.list

curl -fsSL https://download.opensuse.org/repositories/security:/zeek/Debian_12/Release.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/security_zeek.gpg > /dev/null

sudo apt update

sudo apt install zeek-7.0.5

For installation in other ways, you can check the official website.


Working with Zeek


To run Zeek on the command line, you can run the following command that listens for traffic on an interface: zeek -i eth0. Then after starting to listen for network traffic, Zeek starts writing logs to the folder where it is running.


Now let's take a closer look at what logs may be encountered. Zeek can write the following logs by default "out of the box":


   - conn.log

   - dns.log

   - http.log

   - files.log

   - ftp.log

   - ssl.log

   - x509.log

   - smtp.log

   - ssh.log

   - pe.log

   - dhcp.log

   - ntp.log

   - SMB Logs (plus DCE-RPC, Kerberos, NTLM)

   - irc.log

   - ldap.log and ldap_search.log

   - postgresql.log

   - quic.log

   - rdp.log

   - traceroute.log

   - tunnel.log

   - dpd.log

   - known_*.log and software.log

   - weird.log and notice.log

   - capture_loss.log and reporter.log


One of the main files is conn.log. It contains information about transport layer connections (TCP and UDP). All information is contained in the record type Conn::Info. This structure is very similar to the structure of the C language.


By default, logs are written in tabular format to a text file, which is not very convenient for analysis. To begin with, let's consider logs in JSON format, and then in tabular format. To get traffic records in JSON format, you need to execute the following command:


zeek -i enp0s3 LogAscii::use_json=T

Fig. 2 Logs in JSON format


Now in tabular (default).

Fig. 3 Logs in tabular format


Ts is the time the first packet was received, duration indicates how long the connection lasted, proto is the transport layer protocol, conn_state is the value of the connection (SF is the connection established and already completed), local_orig is a logical value (T or F) that indicates whether the connection is local (T) or remote (F), local_resp is a logical value (T or F) that indicates the response from the local network (T) or from the remote network (F).


The ssl.log file shows the encrypted traffic.

Fig. 4 Example of ssl.log in JSON format


One of Zeek's powerful features is the ability to extract content from network traffic and write it to disc as a file using the File Analysis plugin. File.log is a record of the files that Zeek looked at when inspecting network traffic. Analysts should configure Zeek to extract files by type so that they can be written to disc.


An example of retrieving a file from Zeek documentation:


Fig. 5 Example of files.log


The other logs are described in more detail in the documentation.


Using scripts to analyse traffic


Scripts can be run from the command line. For example, zeek -i enp0s8 /home/vas/zeekScript/scripts/main.zeek. This command passes an additional script besides the default scripts for more detailed traffic analysis.


This script analyses the TLS protocol to find out what sites the user is visiting. The script also contains a filter that allows blocking user connections when visiting certain sites. Blocking is performed by calling external commands, in this case the iptables utility. With the help of iptables, rules are created for the Netfilter ME using the nDPI module.


A script for Zeek can be created using the command:

zkg create --packagedir <zeekApp>

After execution, a folder with the script, tests and other service information is created. In the /scripts folder there is a __load__.zeek file - other scripts are connected to it, as well as the main.zeek file. The main.zeek file contains the main code of the programme.

Let's take a closer look at it.

Listing __load__.zeek

@load base/protocols/ssh

@load base/protocols/ssl

@load base/frameworks/netcontrol

@load policy/frameworks/netcontrol/catch-and-release.zeek

@load base/utils/exec.zeek

@load ./main


Listing main.zeek

Module App;

export {

    # Create an ID for our new stream. By convention, this is

    # called "LOG".

    redef enum Log::ID += { LOG };

    # Define the record type that will contain the data to log.

    type Info: record {

        time_hum: string &log;

        id: conn_id &log;

        server_name: string &log &optional;

    };

}

event NetControl::init(){

    local debug_plugin = NetControl::create_debug(T);

    NetControl::activate(debug_plugin, 0);

}

event NetControl::log_netcontrol(rec: NetControl::Info){

            print rec;

            if (rec?$cmd==T && rec$cmd=="ADD" && rec$state==NetControl::SUCCEEDED && rec?$action==T && rec$action=="NetControl::DROP" && rec$entity_type=="NetControl::ADDRESS" && rec$target==NetControl::FORWARD){

                        local ipAdd=rec$entity;

            when[ipAdd]((local resultAdd = Exec::run([$cmd="iptables -A FORWARD -j LOG --log-prefix=\"vk req from "+ipAdd+"\" && iptables -A FORWARD -m ndpi --proto vk -j DROP"])) && resultAdd$exit_code==0)

                        {

                                   ;

                        }

            timeout 5sec

                        {

                                   print "timeout";

                        }

            }

            if (rec?$cmd==T && rec$cmd=="REMOVE" && rec?$expire==T && interval_to_double(rec$expire)!=0.0 && rec$state==NetControl::SUCCEEDED && rec?$action==T && rec$action=="NetControl::DROP" && rec$entity_type=="NetControl::ADDRESS" && rec$target==NetControl::FORWARD){

                        local ipRemove=rec$entity;

            when[ipRemove]((local resultRemove = Exec::run([$cmd="iptables -D FORWARD -j LOG --log-prefix=\"vk req from "+ipRemove+"\" && iptables -D FORWARD -m ndpi --proto vk -j DROP"]))) && resultRemove$exit_code==0)

                        {

                                   ;

                        }

            timeout 5sec

                        {

                                    print "timeout";

                        }

            }

}

event ssl_established(c: connection)

{

            local format:string = "%F, %H:%M:%S";

            Log::write(App::LOG, [$time_hum=strftime(format,network_time()),$id=c$id, $server_name=c$ssl$server_name]);

            print fmt("A new ssl connection %s", c$ssl$server_name);

            if ( c$ssl$server_name == "vk.ru" ) {

            NetControl::drop_address(c$id$orig_h, 20sec);

                        print fmt("2A new ssl connection %s", c$id);

                        print fmt("3A new ssl connection %s", c$ssl$server_name);

            }

}

event zeek_init()

       {

            Log::create_stream(App::LOG, [$columns=App::Info, $path="app"]);

       }


The export keyword is needed to declare an Info structure (of type record) that can be accessed from different modules by specifying the module in which it is located with a colon. In this case it is App:Info. The structure contains three fields: time_hum, id and server_nameServer_name is equal to the Server Name Indication (SNI) value obtained from the TLS protocol.


There is also a keyword redef, which is used to add new constants to an enum. In this case it is necessary to create another log file called app.log.


Next are special functions with the keyword event. They differ from functions in the following aspects:

   - They may be scheduled and executed at a later date, so that their effect may not be immediately apparent after they are called.

   - They do not return values because they are not called directly, but rather scheduled for later execution.

   - Zeek_init() is the main function that starts as Zeek starts.


In zeek_init() - a new logging stream with default filter is created using create_stream. It takes the first parameter id, which will be associated with the new logging stream. The second parameter is the structure to which the logs will be written after analysing the network traffic. Thus, a new logging stream appears in the App module. Also in the structure (type Info: record) you must specify the &log attribute for each field of the structure, otherwise these fields will not be included in the flow. Finally, in order to send data to the stream, the Log::write function must be called, which will write the structure with filled fields.


Consider the next eventNetControl::init(), which will come right after zeek_init(). NetControl is a framework for interacting with routers, firewalls and other network devices.


Fig. 6 NetControl architecture


The basic architecture of NetControl is shown in the figure above. NetControl sits between the user scripts (which use the event mechanism) and the network device (which can be either hardware or software) used to implement commands. NetControl supports a number of high-level calls, such as the NetControl::drop_address function or lower-level rule syntax. Once a rule is added to NetControl, it sends it to one or more of its backend servers. Each backend server is responsible for interacting with one hardware or software device. NetControl monitors rules throughout their lifecycle and reports status (such as success, failure, or timeout) to user scripts.


In order to use NetControl, at least one backend server must be enabled. In our case we will use the debug plugin, which outputs all actions to the standard output stream. The backend is initialised in NetControl::init() by calling the activate function, which takes the arguments: backend and call priority value.


The NetControl::log_netcontrol event is triggered after functions or events belonging to the NetControl framework are executed. In this event, the NetControl::Info framework is analysed. Two conditions are checked:

   1. The first condition checks if a rule with Drop action is successfully added in the FORWARD direction, i.e. network packets transiting through the sensor. If the condition succeeds, two DOE rules are created on the system using the iptables utility. One is designed to create a syslog entry about the blocking. The second rule blocks using the nDPI module.

   2. If it is time to delete a rule, the second condition is triggered. The time is determined by the condition (rec?$expire==T && interval_to_double(rec$expire)!=0.0). In this case, rules are removed from the DOE that were previously created after a certain time. In this time is specified in the NetControl::drop_address(c$id$orig_h, 20sec) function, i.e. they are deleted after 20 seconds.


The last event left is event ssl_established(c: connection). It captures TLS connections, which are subsequently written to the app.log. The structure fields are filled in: time converted into human-readable form, id, which is taken from the TLS connection, and server_name - SNI. Then there is a condition, in which the SNI is checked, equal to vk.ru, if it matches, then access is blocked for 20 seconds, as described above. You can also set the time value equal to, for example, 0 sec. In this case the rule will be set without time limits.


A schematic of the network in which Zeek's performance was tested.


Fig. 7 Network diagram


There was a Zeek sensor on the R2 router. It listens to the enp0s8 interface. On router R1 the route to the network 192.168.11.0.0/24 through 192.168.1.101 is written. It is also necessary to create a rule on R2: iptables -t nat -A POSTROUTING -o enp0s3 -s 192.168.11.0.0/24 -j MASQUERADE. R2 was a regular Debian machine with network packet routing configured on it.


  Fig. 8 Created traffic blocking rules


Fig. 9 Logs of the app.log file


As you can see from the log file, Zeek successfully analyses TLS traffic. NetControl also writes its own log file. It contains information about added rules, deleted rules, and plugin initialisation.


Fig. 10 Entries in the netcontrol.log file


Description Malcolm


Malcolm is an open source tool for traffic analysis and visualisation. It accepts network traffic data in the format of traffic dumps (PCAP), Zeek logs and Suricata alerts. Data is automatically normalised, enriched and correlated for analysis.


Network communications overview is provided through two intuitive interfaces: OpenSearch Dashboards, Arkime. The first is a flexible data visualisation plugin with dozens of ready-made dashboards that provides a quick overview of network protocols. Arkime is a powerful tool for searching and identifying sessions containing suspicious security incidents.


Malcolm works as a cluster of software containers - isolated "sandboxes", each performing a specific system function. This model contains simple scripts for configuration and management, so Malcolm is suitable for rapid deployment on a variety of platforms.


Transmission of logs to Malcolm, interaction with the web interface, is done via secure communication channels.


It is essentially an amalgamation of other common tools such as: Zeek, Arkime, Moloch, Elasticsearch, Logstash, Filebeat, Kibana, ClamAV, Docker and others.


Let's briefly describe the main components of Malcolm:

   - OpenSearch is software that allows you to search and analyse metadata in network traffic.

   - Logstash, Filebeat - Software to parse zeek logs and upload them to OpenSearch in a format that Arkime understands.

   - OpenSearch Dashboards - Software for creating additional ad-hoc visualisations and dashboards beyond those provided by Arkime viewer.

   - Zeek is an intrusion detection system.

   - Suricata is a PSB with an inbuilt threat detection engine.

   - Yara is software that allows you to create rules to detect malicious files.

   - Capa is a software that examines executable files and afterwards gives a detailed result.

   - ClamAV is an antivirus for scanning files that zeek has extracted from network traffic.

   - CyberChef is a web application for encrypting, encoding, compressing and analysing data.

   - NetBox - Software for modelling and documenting a network card.

   - Nginx is the reverse-proxy for accessing Malcolm components.

   - GeoLite2 is a database for ip location.


For clarity, the developers have provided a table of the components that populate Malcolm.


Figure 11 Components of the Malcolm ecosystem


Malcolm installation


To install Malcolm, you need to bend the official repository. Then go to the scripts folder and run the install.py file. During the configuration process, questions with yes/no answers will be asked. They are described in more detail in the documentation. After that you need to create a Nginx server user to access the web console and create self-signed certificates. All this is done with the help of scripts provided by Malcolm developers. After that we download the docker images.


This may take some time. Next, use the same scripts to launch Malcolm.


Malcolm requires a lot of resources. For minimum operation it needs 16 GB of RAM and 8 processor cores, according to Elasticsearch documentation. Once installed and running, Malcolm is ready to fully explore network packets, sessions.


  Fig. 12 Containers filling Malcolm


Malcolm allows you to analyse real-time traffic that is going on a particular interface. Since it includes the Zeek module, most of the log files are in the zeek format we discussed above.


Fig. 13 Summary of the network situation


Malcolm provides about 12 pre-defined dashboards (Dashboards). For example, there is a Dashboard - Connections, which shows the various connections established over a period of time. You can categorise connections by various attributes, such as ip address source, ip address destination, protocol, GeoIP and others.


  Fig. 14 Summary of connections from different countries by protocols


Figure 14 shows the protocols in pie charts, with the countries signed at the bottom.


Malcolm actually provides a great deal of visualisation. You can also create your own.


Arkime


In the initial configuration Arkime retrieves all session information. When Malcolm is opened, the current sessions are displayed. They can be filtered, e.g. by Zeek, Suricata filters.


Fig. 15 Session filtering in Akrime


In connections, you can view a graph of how network machines interact with each other. It is also possible to set filters on sessions, which will show the interaction of internal hosts with other internal or external hosts. Note that this module requires a lot of resources.


Fig. 16 Displaying connections by zeek filter.


Zeek log transfer via Syslog protocol


At the beginning of the article about Zeek, TLS session logging was configured. The log file contains information about which sites the user visits and at what time. This information can be transferred to Malcolm, for example, via the syslog protocol. To do this, configure rsyslog on the client, and when configuring Malcolm do not forget to assign ports for syslog (udp or tcp).


First, let's configure the log transfer to the remote server. Therefore, we will write the following config for rsyslog:


  Fig. 17 rsyslog settings


In this case, rsyslog reads the app.log file and transmits via udp to the Malcolm server.


To configure a syslog server in Malcolm, you must select the answer to the question "Should Malcolm accept logs and metrics from a Hedgehog Linux sensor or other forwarder?" during the configuration process.". - customise. After that set udp/tcp ports for rsyslog. You can also change the data in filebeat.env in the config folder and reboot Malcolm.


Once configured, logs will start being sent to the Malcolm server. The network map is shown in Figure 18 below.


Fig. 18 Network diagram with Syslog server


  Fig. 19 Connection between Syslog server and client


This graph shows which clients are sending syslog logs.


Fig. 20 Sessions in the Arkime module


In the session tab you can see what information is transmitted via syslog protocol. You can see the time of the call, from which ip-address the call was made, port.


Using the solutions discussed above with Security Vision products


Zeek PSB logs can be transmitted, for example, via the syslog protocol to NGSOAR. Once the logs are received by NGSOAR, important information is extracted from them: protocol name, ports, source and destination ip addresses, application name, and so on. This information is processed by correlation rules, which, if triggered, create an incident for further analysis by analysts.     


Conclusions


In conclusion, there are two mechanisms for analysing traffic, and each of them is unique in its own way. Zeek allows us not only to analyse logs, but also to include ways to react to increased network activity by writing various scripts, for example, to analyse and then block sessions.


Malcolm's second solution includes a host of free software to analyse and visualise network activity. It can become one of the key elements in the network topology, checking not only the traffic passing through, but also collecting it from other devices. But before implementing Malcolm, you should take care of sufficient RAM.

Recommended

Protecting data and media from viruses and hacking
Protecting data and media from viruses and hacking
Basics of Cryptography: what is encryption, hash sum, digital signature
Basics of Cryptography: what is encryption, hash sum, digital signature
Vulnerability scanner
Vulnerability scanner
How hardening works and how it is integrated into information security processes
How hardening works and how it is integrated into information security processes
Spam protection for companies and households
Spam protection for companies and households
Mathematical risk modelling: shamanism or cybernetics?
Mathematical risk modelling: shamanism or cybernetics?
Comparative review: Shodan, ZoomEye, Netlas, Censys, FOFA and Criminal IP. Part 1
Comparative review: Shodan, ZoomEye, Netlas, Censys, FOFA and Criminal IP. Part 1
CyBOK. Chapter 2. Risk management and information security management. Part 2
CyBOK. Chapter 2. Risk management and information security management. Part 2
Features of the new version of the Vulnerability Management (VM) product on the Security Vision 5 platform
Features of the new version of the Vulnerability Management (VM) product on the Security Vision 5 platform
What is Bruteforce and how can I protect myself from it?
What is Bruteforce and how can I protect myself from it?
Spam - what it is, what it can be and whether it is useful
Spam - what it is, what it can be and whether it is useful
Scenarios of untyped UEBA attacks
Scenarios of untyped UEBA attacks

Recommended

Protecting data and media from viruses and hacking
Protecting data and media from viruses and hacking
Basics of Cryptography: what is encryption, hash sum, digital signature
Basics of Cryptography: what is encryption, hash sum, digital signature
Vulnerability scanner
Vulnerability scanner
How hardening works and how it is integrated into information security processes
How hardening works and how it is integrated into information security processes
Spam protection for companies and households
Spam protection for companies and households
Mathematical risk modelling: shamanism or cybernetics?
Mathematical risk modelling: shamanism or cybernetics?
Comparative review: Shodan, ZoomEye, Netlas, Censys, FOFA and Criminal IP. Part 1
Comparative review: Shodan, ZoomEye, Netlas, Censys, FOFA and Criminal IP. Part 1
CyBOK. Chapter 2. Risk management and information security management. Part 2
CyBOK. Chapter 2. Risk management and information security management. Part 2
Features of the new version of the Vulnerability Management (VM) product on the Security Vision 5 platform
Features of the new version of the Vulnerability Management (VM) product on the Security Vision 5 platform
What is Bruteforce and how can I protect myself from it?
What is Bruteforce and how can I protect myself from it?
Spam - what it is, what it can be and whether it is useful
Spam - what it is, what it can be and whether it is useful
Scenarios of untyped UEBA attacks
Scenarios of untyped UEBA attacks