Skip to content

Commit

Permalink
Implement rest of OCSF model
Browse files Browse the repository at this point in the history
Signed-off-by: Chase Engelbrecht <[email protected]>
  • Loading branch information
engechas committed Mar 13, 2024
1 parent ae96e81 commit 4656adc
Show file tree
Hide file tree
Showing 5 changed files with 295 additions and 12 deletions.
3 changes: 3 additions & 0 deletions data-prepper-plugins/rule-engine/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ dependencies {
implementation 'com.fasterxml.jackson.core:jackson-core'
implementation 'com.fasterxml.jackson.core:jackson-databind'
implementation libs.commons.lang3
implementation 'org.projectlombok:lombok:1.18.26'
compileOnly 'org.projectlombok:lombok:1.18.26'
annotationProcessor 'org.projectlombok:lombok:1.18.26'
}

generateGrammarSource {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,60 @@
import org.opensearch.dataprepper.model.record.Record;
import org.opensearch.dataprepper.plugins.processor.model.datatypes.OCSF;

import java.util.Map;

public class OCSFConverter {
public OCSF convert(final Record<Event> record) {
final Event event = record.getData();
final String apiOperation = event.get("/api/operation", String.class);
final String apiServiceName = event.get("/api/service/name", String.class);

return new OCSF(apiOperation, apiServiceName);
return OCSF.builder()
.metadataProductVersion(event.get("/metadata/product/version", String.class))
.metadataProductName(event.get("/metadata/product/name", String.class))
.metadataProductVendorName(event.get("/metadata/product/vendor_name", String.class))
.metadataProductFeatureName(event.get("/metadata/product/feature/name", String.class))
.metadataUid(event.get("/metadata/uid", String.class))
.metadataProfiles(event.getList("/metadata/profiles", String.class))
.metadataVersion(event.get("/metadata/version", String.class))
.time(event.get("/time", Long.class))
.cloudRegion(event.get("/cloud/region", String.class))
.cloudProvider(event.get("/cloud/provider", String.class))
.dstEndpoint(event.get("/dst_endpoint", String.class))
.httpRequestUserAgent(event.get("/http_request/user_agent", String.class))
.srcEndpointUid(event.get("/src_endpoint/uid", String.class))
.srcEndpointIp(event.get("/src_endpoint/ip", String.class))
.srcEndpointDomain(event.get("/src_endpoint/domain", String.class))
.className(event.get("/class_name", String.class))
.classUid(event.get("/class_uid", Integer.class))
.categoryName(event.get("/category_name", String.class))
.categoryUid(event.get("/category_uid", Integer.class))
.severityId(event.get("/severity_id", Integer.class))
.severity(event.get("/severity", String.class))
.user(event.get("/user", String.class))
.activityName(event.get("/activity_name", String.class))
.activityId(event.get("/activity_id", Integer.class))
.typeUid(event.get("/type_uid", Integer.class))
.typeName(event.get("/type_name", String.class))
.status(event.get("/status", String.class))
.statusId(event.get("/status_id", Integer.class))
.mfa(event.get("/mfa", Boolean.class))
.apiResponseError(event.get("/api/response/error", String.class))
.apiResponseMessage(event.get("/api/response/message", String.class))
.apiOperation(event.get("/api/operation", String.class))
.apiVersion(event.get("/api/version", String.class))
.apiServiceName(event.get("/api/service/name", String.class))
.apiRequestUid(event.get("/api/request/uid", String.class))
.resources(event.getList("/resources", OCSF.Resource.class))
.actorUserType(event.get("/actor/user/type", String.class))
.actorUserName(event.get("/actor/user/name", String.class))
.actorUserUid(event.get("/actor/user/uid", String.class))
.actorUserUuid(event.get("/actor/user/uuid", String.class))
.actorUserAccountUid(event.get("/actor/user/account_uid", String.class))
.actorUserCredentialUid(event.get("/actor/user/credential_uid", String.class))
.actorSessionCreatedTime(event.get("/actor/session/created_time", Long.class))
.actorSessionMfa(event.get("/actor/session/mfa", Boolean.class))
.actorSessionIssuer(event.get("/actor/session/issuer", String.class))
.actorInvokedBy(event.get("/actor/invoked_by", String.class))
.actorIdpName(event.get("/actor/idp/name", String.class))
.unmapped((Map<String, String>) event.get("/unmapped", Map.class))
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,161 @@
package org.opensearch.dataprepper.plugins.processor.model.datatypes;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;

import java.util.List;
import java.util.Map;

@Builder
public class OCSF extends DataType {
private final String metadataProductVersion;
private final String metadataProductName;
private final String metadataProductVendorName;
private final String metadataProductFeatureName;
private final String metadataUid;
private final List<String> metadataProfiles;
private final String metadataVersion;
private final Long time;
private final String cloudRegion;
private final String cloudProvider;
private final String dstEndpoint;
private final String httpRequestUserAgent;
private final String srcEndpointUid;
private final String srcEndpointIp;
private final String srcEndpointDomain;
private final String className;
private final Integer classUid;
private final String categoryName;
private final Integer categoryUid;
private final Integer severityId;
private final String severity;
private final String user;
private final String activityName;
private final Integer activityId;
private final Integer typeUid;
private final String typeName;
private final String status;
private final Integer statusId;
private final Boolean mfa;
private final String apiResponseError;
private final String apiResponseMessage;
private final String apiOperation;
private final String apiVersion;
private final String apiServiceName;

public OCSF(final String apiOperation, final String apiServiceName) {
super();
this.apiOperation = apiOperation;
this.apiServiceName = apiServiceName;
}
private final String apiRequestUid;
private final List<Resource> resources;
private final String actorUserType;
private final String actorUserName;
private final String actorUserUid;
private final String actorUserUuid;
private final String actorUserAccountUid;
private final String actorUserCredentialUid;
private final Long actorSessionCreatedTime;
private final Boolean actorSessionMfa;
private final String actorSessionIssuer;
private final String actorInvokedBy;
private final String actorIdpName;
private final Map<String, String> unmapped;

@Override
public Object getValue(final String fieldName) {
switch (fieldName) {
case "metadata.product.version": return metadataProductVersion;
case "metadata.product.name": return metadataProductName;
case "metadata.product.vendor_name": return metadataProductVendorName;
case "metadata.product.feature.name": return metadataProductFeatureName;
case "metadata.uid": return metadataUid;
case "metadata.profiles": return metadataProfiles;
case "metadata.version": return metadataVersion;
case "time": return time;
case "cloud.region": return cloudRegion;
case "cloud.provider": return cloudProvider;
case "dst_endpoint": return dstEndpoint;
case "http_request.user_agent": return httpRequestUserAgent;
case "src_endpoint.uid": return srcEndpointUid;
case "src_endpoint.ip": return srcEndpointIp;
case "src_endpoint.domain": return srcEndpointDomain;
case "class_name": return className;
case "class_uid": return classUid;
case "category_name": return categoryName;
case "category_uid": return categoryUid;
case "severity_id": return severityId;
case "severity": return severity;
case "user": return user;
case "activity_name": return activityName;
case "activity_id": return activityId;
case "type_uid": return typeUid;
case "type_name": return typeName;
case "status": return status;
case "status_id": return statusId;
case "mfa": return mfa;
case "api.response.error": return apiResponseError;
case "api.response.message": return apiResponseMessage;
case "api.operation": return apiOperation;
case "api.version": return apiVersion;
case "api.service.name": return apiServiceName;
default: throw new IllegalArgumentException("Field " + fieldName + " does not exist in class " + getClass().getName());
case "api.request.uid": return apiRequestUid;
case "resources": return resources;
case "actor.user.type": return actorUserType;
case "actor.user.name": return actorUserName;
case "actor.user.uid": return actorUserUid;
case "actor.user.uuid": return actorUserUuid;
case "actor.user.account_uid": return actorUserAccountUid;
case "actor.user.credential_uid": return actorUserCredentialUid;
case "actor.session.created_time": return actorSessionCreatedTime;
case "actor.session.mfa": return actorSessionMfa;
case "actor.session.issuer": return actorSessionIssuer;
case "actor.invoked_by": return actorInvokedBy;
case "actor.idp.name": return actorIdpName;
case "unmapped": return unmapped;
default: return handleOtherFields(fieldName);
}
}

private Object handleOtherFields(final String fieldName) {
final String[] parts = fieldName.split("\\.");
if (parts.length == 0 || !"unmapped".equals(parts[0])) {
throw new IllegalArgumentException("Field " + fieldName + " does not exist in class " + getClass().getName());
}

if (parts.length == 1) {
return unmapped;
}

return unmapped.get(parts[1]);
}

public static class Resource {
private String uid;
@JsonProperty("account_uid")
private String accountUid;
private String type;

public Resource() {
}

public String getUid() {
return uid;
}

public void setUid(String uid) {
this.uid = uid;
}

public String getAccountUid() {
return accountUid;
}

public void setAccountUid(String accountUid) {
this.accountUid = accountUid;
}

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
{
"metadata": {
"product": {
"version": "1.08",
"name": "cloudtrail",
"vendor_name": "AWS",
"feature": {
"name": "Management"
}
},
"uid": "44c4dfed-03e1-4307-bf66-12ce2f917fca",
"profiles": ["cloud"],
"version": "1.0.0-rc.2"
},
"time": 1706588794000,
"cloud": {
"region": "us-east-1",
"provider": "AWS"
},
"dst_endpoint": null,
"http_request": {
"user_agent": "AWS Internal"
},
"src_endpoint": {
"uid": null,
"ip": null,
"domain": "AWS Internal"
},
"class_name": "api_activity",
"class_uid": 3005,
"category_name": "Identity & Access Management",
"category_uid": 3,
"severity_id": 1,
"severity": "Informational",
"user": null,
"activity_name": "Other",
"activity_id": 99,
"type_uid": 300599,
"type_name": "User Access Management: Other",
"status": "Success",
"status_id": 1,
"mfa": null,
"api": {
"response": {
"error": null,
"message": null
},
"operation": "CreateIPSet",
"version": null,
"service": {
"name": "guardduty.amazonaws.com"
},
"request": {
"uid": "d37919f9-5ade-491c-992a-806cb8bb4a4b"
}
},
"resources": [
{
"uid": "70c28d56-3c27-4d48-9f62-15fc507c1ff5",
"account_uid": "888888888888",
"type": "AWS::GuardDuty::IpSet"
}
],
"actor": {
"user": {
"type": "IAMUser",
"name": null,
"uid": "3615781c-4c24-4660-951f-736f4ee445af",
"uuid": "01fac3b9-b1be-4884-beef-1b8abf53676d",
"account_uid": "888888888888",
"credential_uid": "0b4a8d4f-4103-4623-9883-cdab4d754b07"
},
"session": {
"created_time": 1706588794000,
"mfa": false,
"issuer": "9e25818e-3d90-42dd-9f4b-96b116f117a1"
},
"invoked_by": "AWS Internal",
"idp": {
"name": null
}
},
"unmapped": {
"userIdentity.sessionContext.sessionIssuer.type": "Role",
"eventType": "AwsApiCall",
"userIdentity.sessionContext.sessionIssuer.userName": "744632ad-2e3a-4380-8794-77a83d32dbf3",
"userIdentity.sessionContext.sessionIssuer.principalId": "2d69306c-8e3a-4b95-a615-598c948c420e",
"c55c046e-3941-406e-b15e-012cc50c027e": "b9276fbf-ba3f-4266-89c1-35070984bd67",
"4fd308de-048b-47ec-b1ba-e558f063568d": "144ac1aa-b273-4342-8a56-e47628b407a5",
"834c24ae-3e9a-4067-ba1b-a1a46033da69": "48127b36-6d65-44a2-a554-e9860717e048"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

public abstract class Rule {
private final Predicate<DataType> ruleCondition;
private final Predicate<DataType> evaluationCondition;
private final Predicate<DataType> evaluationCondition;

public Rule(final Predicate<DataType> ruleCondition, final Predicate<DataType> evaluationCondition) {
this.ruleCondition = ruleCondition;
Expand Down

0 comments on commit 4656adc

Please sign in to comment.