Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[backend] Microsoft Defender collector not working (#1686) #1912

Merged
merged 10 commits into from
Nov 26, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,6 @@ public ExecutionProcess process(
.type(EXPECTATION_SIGNATURE_TYPE_PROCESS_NAME)
.value(executionEndpoint.getProcessName())
.build());
injectExpectationSignatures.add(
InjectExpectationSignature.builder()
.type(EXPECTATION_SIGNATURE_TYPE_COMMAND_LINE)
.value(exploitResult.getCommand())
.build());
break;
case "Executable":
Executable payloadExecutable =
Expand Down Expand Up @@ -202,11 +197,6 @@ public ExecutionProcess process(
.type(EXPECTATION_SIGNATURE_TYPE_PROCESS_NAME)
.value(executionEndpoint.getProcessName())
.build());
injectExpectationSignatures.add(
InjectExpectationSignature.builder()
.type(EXPECTATION_SIGNATURE_TYPE_COMMAND_LINE)
.value(exploitResult.getCommand())
.build());
}
computeExpectationsForAsset(
expectations,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor;
import lombok.extern.java.Log;
import org.hibernate.Hibernate;
import org.springframework.stereotype.Component;

@Component(OpenBASImplantContract.TYPE)
Expand Down Expand Up @@ -242,113 +241,22 @@
List<Expectation> expectations = new ArrayList<>();
assets.forEach(
(asset, isInGroup) -> {
Optional<InjectorContract> contract = inject.getInjectorContract();

Check warning on line 244 in openbas-api/src/main/java/io/openbas/injectors/openbas/OpenBASImplantExecutor.java

View check run for this annotation

Codecov / codecov/patch

openbas-api/src/main/java/io/openbas/injectors/openbas/OpenBASImplantExecutor.java#L244

Added line #L244 was not covered by tests
List<InjectExpectationSignature> injectExpectationSignatures = new ArrayList<>();

inject
.getInjectorContract()
.ifPresent(
injectorContract -> {
if (injectorContract.getPayload() != null) {
// Put the correct number in inject status
int totalActionsCount = 0;
switch (injectorContract.getPayload().getType()) {
case "Command":
Command payloadCommand =
(Command) Hibernate.unproxy(injectorContract.getPayload());
injectExpectationSignatures.add(
InjectExpectationSignature.builder()
.type(EXPECTATION_SIGNATURE_TYPE_PARENT_PROCESS_NAME)
.value("obas-implant-" + inject.getId())
.build());
injectExpectationSignatures.add(
InjectExpectationSignature.builder()
.type(EXPECTATION_SIGNATURE_TYPE_COMMAND_LINE)
.value(
Base64.getEncoder()
.encodeToString(payloadCommand.getContent().getBytes()))
.build()); // Add parsing: base64 for example
totalActionsCount = totalActionsCount + 1;
if (payloadCommand.getPrerequisites() != null) {
totalActionsCount =
totalActionsCount + payloadCommand.getPrerequisites().size();
}
if (payloadCommand.getCleanupCommand() != null
&& !payloadCommand.getCleanupCommand().isEmpty()) {
totalActionsCount = totalActionsCount + 1;
}
break;
case "Executable":
Executable payloadExecutable =
(Executable) Hibernate.unproxy(injectorContract.getPayload());
injectExpectationSignatures.add(
InjectExpectationSignature.builder()
.type(EXPECTATION_SIGNATURE_TYPE_FILE_NAME)
.value(payloadExecutable.getExecutableFile().getName())
.build());
totalActionsCount = totalActionsCount + 2;
if (payloadExecutable.getPrerequisites() != null) {
totalActionsCount =
totalActionsCount + payloadExecutable.getPrerequisites().size();
}
if (payloadExecutable.getCleanupCommand() != null
&& !payloadExecutable.getCleanupCommand().isEmpty()) {
totalActionsCount = totalActionsCount + 1;
}
// TODO File hash
break;
case "FileDrop":
FileDrop payloadFileDrop =
(FileDrop) Hibernate.unproxy(injectorContract.getPayload());
injectExpectationSignatures.add(
InjectExpectationSignature.builder()
.type(EXPECTATION_SIGNATURE_TYPE_FILE_NAME)
.value(payloadFileDrop.getFileDropFile().getName())
.build());
totalActionsCount = totalActionsCount + 1;
if (payloadFileDrop.getPrerequisites() != null) {
totalActionsCount =
totalActionsCount + payloadFileDrop.getPrerequisites().size();
}
if (payloadFileDrop.getCleanupCommand() != null
&& !payloadFileDrop.getCleanupCommand().isEmpty()) {
totalActionsCount = totalActionsCount + 1;
}
// TODO File hash
break;
case "DnsResolution":
DnsResolution payloadDnsResolution =
(DnsResolution) Hibernate.unproxy(injectorContract.getPayload());
// TODO this is only generating the signature for the first hostname
// Problem is: we are not supporting multiple signatures of the same type
// with "AND" parameters, and this can be in multiple alerts downstream in
// security platforms
// Tech pain to refine
injectExpectationSignatures.add(
InjectExpectationSignature.builder()
.type(EXPECTATION_SIGNATURE_TYPE_HOSTNAME)
.value(payloadDnsResolution.getHostname().split("\\r?\\n")[0])
.build());
totalActionsCount =
totalActionsCount
+ payloadDnsResolution.getHostname().split("\\r?\\n").length;
if (payloadDnsResolution.getPrerequisites() != null) {
totalActionsCount =
totalActionsCount + payloadDnsResolution.getPrerequisites().size();
}
if (payloadDnsResolution.getCleanupCommand() != null
&& !payloadDnsResolution.getCleanupCommand().isEmpty()) {
totalActionsCount = totalActionsCount + 1;
}
break;
default:
throw new UnsupportedOperationException(
"Payload type "
+ injectorContract.getPayload().getType()
+ " is not supported");
}
execution.setExpectedCount(totalActionsCount);
}
});
if (contract.isPresent()) {
Payload payload = contract.get().getPayload();

Check warning on line 248 in openbas-api/src/main/java/io/openbas/injectors/openbas/OpenBASImplantExecutor.java

View check run for this annotation

Codecov / codecov/patch

openbas-api/src/main/java/io/openbas/injectors/openbas/OpenBASImplantExecutor.java#L248

Added line #L248 was not covered by tests
antoinemzs marked this conversation as resolved.
Show resolved Hide resolved
if (payload == null) {
log.info(
String.format("No payload for inject %s was found, skipping", inject.getId()));
return;

Check warning on line 252 in openbas-api/src/main/java/io/openbas/injectors/openbas/OpenBASImplantExecutor.java

View check run for this annotation

Codecov / codecov/patch

openbas-api/src/main/java/io/openbas/injectors/openbas/OpenBASImplantExecutor.java#L250-L252

Added lines #L250 - L252 were not covered by tests
}
injectExpectationSignatures = spawnSignatures(inject, payload);
execution.setExpectedCount(
payload.getPrerequisites().size()

Check warning on line 256 in openbas-api/src/main/java/io/openbas/injectors/openbas/OpenBASImplantExecutor.java

View check run for this annotation

Codecov / codecov/patch

openbas-api/src/main/java/io/openbas/injectors/openbas/OpenBASImplantExecutor.java#L254-L256

Added lines #L254 - L256 were not covered by tests
+ (payload.getCleanupCommand() != null ? 1 : 0)
+ payload.getNumberOfActions());

Check warning on line 258 in openbas-api/src/main/java/io/openbas/injectors/openbas/OpenBASImplantExecutor.java

View check run for this annotation

Codecov / codecov/patch

openbas-api/src/main/java/io/openbas/injectors/openbas/OpenBASImplantExecutor.java#L258

Added line #L258 was not covered by tests
}
computeExpectationsForAsset(
expectations, content, asset, isInGroup, injectExpectationSignatures);
});
Expand All @@ -360,4 +268,28 @@
expectations, content, assetGroup, new ArrayList<>())));
return new ExecutionProcess(true, expectations);
}

private List<InjectExpectationSignature> spawnSignatures(Inject inject, Payload payload) {
List<InjectExpectationSignature> signatures = new ArrayList<>();
List<String> knownPayloadTypes =
Arrays.asList("Command", "Executable", "FileDrop", "DnsResolution");

Check warning on line 275 in openbas-api/src/main/java/io/openbas/injectors/openbas/OpenBASImplantExecutor.java

View check run for this annotation

Codecov / codecov/patch

openbas-api/src/main/java/io/openbas/injectors/openbas/OpenBASImplantExecutor.java#L273-L275

Added lines #L273 - L275 were not covered by tests

/*
* Always add the "Parent process" signature type for the OpenBAS Implant Executor
*/
signatures.add(
createSignature(
EXPECTATION_SIGNATURE_TYPE_PARENT_PROCESS_NAME, "obas-implant-" + inject.getId()));

Check warning on line 282 in openbas-api/src/main/java/io/openbas/injectors/openbas/OpenBASImplantExecutor.java

View check run for this annotation

Codecov / codecov/patch

openbas-api/src/main/java/io/openbas/injectors/openbas/OpenBASImplantExecutor.java#L280-L282

Added lines #L280 - L282 were not covered by tests

if (!knownPayloadTypes.contains(payload.getType())) {
throw new UnsupportedOperationException(
"Payload type " + payload.getType() + " is not supported");

Check warning on line 286 in openbas-api/src/main/java/io/openbas/injectors/openbas/OpenBASImplantExecutor.java

View check run for this annotation

Codecov / codecov/patch

openbas-api/src/main/java/io/openbas/injectors/openbas/OpenBASImplantExecutor.java#L285-L286

Added lines #L285 - L286 were not covered by tests
}
return signatures;

Check warning on line 288 in openbas-api/src/main/java/io/openbas/injectors/openbas/OpenBASImplantExecutor.java

View check run for this annotation

Codecov / codecov/patch

openbas-api/src/main/java/io/openbas/injectors/openbas/OpenBASImplantExecutor.java#L288

Added line #L288 was not covered by tests
}

private static InjectExpectationSignature createSignature(
String signatureType, String signatureValue) {
return InjectExpectationSignature.builder().type(signatureType).value(signatureValue).build();

Check warning on line 293 in openbas-api/src/main/java/io/openbas/injectors/openbas/OpenBASImplantExecutor.java

View check run for this annotation

Codecov / codecov/patch

openbas-api/src/main/java/io/openbas/injectors/openbas/OpenBASImplantExecutor.java#L293

Added line #L293 was not covered by tests
antoinemzs marked this conversation as resolved.
Show resolved Hide resolved
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,12 @@ public InjectExpectation computeExpectation(
@NotBlank final String sourceName,
@NotBlank final String result,
@NotBlank final Boolean success) {
if (success) {
computeResult(
expectation, sourceId, sourceType, sourceName, result, expectation.getExpectedScore());
expectation.setScore(expectation.getExpectedScore());
} else if (expectation.getScore() == null) {
computeResult(expectation, sourceId, sourceType, sourceName, result, 0.0);
expectation.setScore(0.0);
} else {
computeResult(expectation, sourceId, sourceType, sourceName, result, expectation.getScore());
}
double actualScore =
success
? expectation.getExpectedScore()
: expectation.getScore() == null ? 0.0 : expectation.getScore();
computeResult(expectation, sourceId, sourceType, sourceName, result, actualScore);
expectation.setScore(actualScore);
return this.update(expectation);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,12 @@ public DnsResolution() {}
public DnsResolution(String id, String type, String name) {
super(id, type, name);
}

/*
* the DNS resolution payload expects one action carried out per listed hostname
*/
@Override
public int getNumberOfActions() {
return this.getHostname().split("\\r?\\n").length;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -184,4 +184,12 @@ public Payload(String id, String type, String name) {
this.id = id;
this.type = type;
}

/*
* return the number of actions a given payload is expected to achieve
* by default this is 1, e.g. one command, one file drop etc...
*/
public int getNumberOfActions() {
antoinemzs marked this conversation as resolved.
Show resolved Hide resolved
return 1;
}
}