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/frontend] Categorize payload by architecture #1612

Merged
merged 4 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.openbas.migration;

import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;
import org.springframework.stereotype.Component;

import java.sql.Connection;
import java.sql.Statement;

@Component
public class V3_44__Add_column_executable_arch extends BaseJavaMigration {

@Override
public void migrate(Context context) throws Exception {
Connection connection = context.getConnection();
Statement statement = connection.createStatement();
statement.execute("ALTER TABLE payloads ADD executable_arch varchar(255);");
statement.execute("UPDATE payloads SET executable_arch = 'x86_64' WHERE payload_type ='Executable';");
}
isselparra marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import java.util.List;

@RestController
@RequestMapping("/api/atomic_testings")
@RequestMapping("/api/atomic-testings")
@PreAuthorize("isAdmin()")
@RequiredArgsConstructor
public class AtomicTestingApi extends RestBehavior {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ private void selectForInjectorContract(
injectorContractPayloadJoin.get("type").alias("payload_type"),
payloadCollectorJoin.get("type").alias("collector_type"),
injectorContractInjectorJoin.get("type").alias("injector_contract_injector_type"),
attackPatternIdsExpression.alias("injector_contract_attack_patterns")
attackPatternIdsExpression.alias("injector_contract_attack_patterns"),
injectorContractPayloadJoin.get("executableArch").alias("payload_executable_arch")
).distinct(true);

// GROUP BY
Expand All @@ -146,7 +147,8 @@ private List<InjectorContractOutput> execInjectorContract(TypedQuery<Tuple> quer
tuple.get("payload_type", String.class),
tuple.get("collector_type", String.class),
tuple.get("injector_contract_injector_type", String.class),
tuple.get("injector_contract_attack_patterns", String[].class)
tuple.get("injector_contract_attack_patterns", String[].class),
tuple.get("payload_executable_arch", Endpoint.PLATFORM_ARCH.class)
))
.toList();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.openbas.rest.injector_contract.output;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.openbas.database.model.Endpoint;
import io.openbas.database.model.Endpoint.PLATFORM_TYPE;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
Expand Down Expand Up @@ -33,6 +34,9 @@ public class InjectorContractOutput {
@JsonProperty("injector_contract_attack_patterns")
private List<String> attackPatterns;

@JsonProperty("injector_contract_arch")
private Endpoint.PLATFORM_ARCH arch;

public InjectorContractOutput(
String id,
Map<String, String> labels,
Expand All @@ -41,7 +45,8 @@ public InjectorContractOutput(
String payloadType,
String collectorType,
String injectorType,
String[] attackPatterns) {
String[] attackPatterns,
Endpoint.PLATFORM_ARCH arch) {
this.id = id;
this.labels = labels;
this.content = content;
Expand All @@ -50,5 +55,6 @@ public InjectorContractOutput(
this.injectorType = injectorType;

this.attackPatterns = attackPatterns != null ? new ArrayList<>(Arrays.asList(attackPatterns)) : new ArrayList<>();
this.arch = arch;
}
}
81 changes: 51 additions & 30 deletions openbas-api/src/main/java/io/openbas/rest/payload/PayloadApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.openbas.database.model.*;
import io.openbas.database.repository.*;
import io.openbas.integrations.PayloadService;
import io.openbas.rest.exception.BadRequestException;
import io.openbas.rest.exception.ElementNotFoundException;
import io.openbas.rest.helper.RestBehavior;
import io.openbas.rest.payload.form.PayloadCreateInput;
Expand Down Expand Up @@ -91,25 +92,26 @@ public Payload payload(@PathVariable String payloadId) {
@PreAuthorize("isPlanner()")
@Transactional(rollbackOn = Exception.class)
public Payload createPayload(@Valid @RequestBody PayloadCreateInput input) {
switch (input.getType()) {
case "Command":
switch (PayloadType.fromString(input.getType())) {
case PayloadType.COMMAND:
Command commandPayload = new Command();
commandPayload.setUpdateAttributes(input);
commandPayload.setAttackPatterns(fromIterable(attackPatternRepository.findAllById(input.getAttackPatternsIds())));
commandPayload.setTags(iterableToSet(tagRepository.findAllById(input.getTagIds())));
commandPayload = payloadRepository.save(commandPayload);
this.payloadService.updateInjectorContractsForPayload(commandPayload);
return commandPayload;
case "Executable":
case PayloadType.EXECUTABLE:
Executable executablePayload = new Executable();
executablePayload.setUpdateAttributes(input);
executablePayload.setAttackPatterns(fromIterable(attackPatternRepository.findAllById(input.getAttackPatternsIds())));
executablePayload.setTags(iterableToSet(tagRepository.findAllById(input.getTagIds())));
executablePayload.setExecutableFile(documentRepository.findById(input.getExecutableFile()).orElseThrow());
PayloadCreateInput validatedInput = validateExecutableCreateInput(input);
executablePayload.setUpdateAttributes(validatedInput);
executablePayload.setAttackPatterns(fromIterable(attackPatternRepository.findAllById(validatedInput.getAttackPatternsIds())));
executablePayload.setTags(iterableToSet(tagRepository.findAllById(validatedInput.getTagIds())));
executablePayload.setExecutableFile(documentRepository.findById(validatedInput.getExecutableFile()).orElseThrow());
executablePayload = payloadRepository.save(executablePayload);
this.payloadService.updateInjectorContractsForPayload(executablePayload);
return executablePayload;
case "FileDrop":
case PayloadType.FILE_DROP:
FileDrop fileDropPayload = new FileDrop();
fileDropPayload.setUpdateAttributes(input);
fileDropPayload.setAttackPatterns(fromIterable(attackPatternRepository.findAllById(input.getAttackPatternsIds())));
Expand All @@ -118,15 +120,15 @@ public Payload createPayload(@Valid @RequestBody PayloadCreateInput input) {
fileDropPayload = payloadRepository.save(fileDropPayload);
this.payloadService.updateInjectorContractsForPayload(fileDropPayload);
return fileDropPayload;
case "DnsResolution":
case PayloadType.DNS_RESOLUTION:
DnsResolution dnsResolutionPayload = new DnsResolution();
dnsResolutionPayload.setUpdateAttributes(input);
dnsResolutionPayload.setAttackPatterns(fromIterable(attackPatternRepository.findAllById(input.getAttackPatternsIds())));
dnsResolutionPayload.setTags(iterableToSet(tagRepository.findAllById(input.getTagIds())));
dnsResolutionPayload = payloadRepository.save(dnsResolutionPayload);
this.payloadService.updateInjectorContractsForPayload(dnsResolutionPayload);
return dnsResolutionPayload;
case "NetworkTraffic":
case PayloadType.NETWORK_TRAFFIC:
NetworkTraffic networkTrafficPayload = new NetworkTraffic();
networkTrafficPayload.setUpdateAttributes(input);
networkTrafficPayload.setAttackPatterns(fromIterable(attackPatternRepository.findAllById(input.getAttackPatternsIds())));
Expand All @@ -139,6 +141,24 @@ public Payload createPayload(@Valid @RequestBody PayloadCreateInput input) {
}
}

private static PayloadCreateInput validateExecutableCreateInput(PayloadCreateInput input) {
Optional<Endpoint.PLATFORM_ARCH> maybeArch = Optional.ofNullable(input.getExecutableArch());
if (maybeArch.isPresent()) {
return input;
} else {
throw new BadRequestException("Executable arch is missing");
}
}

private static PayloadUpdateInput validateExecutableUpdateInput(PayloadUpdateInput input) {
Optional<Endpoint.PLATFORM_ARCH> maybeArch = Optional.ofNullable(input.getExecutableArch());
if (maybeArch.isPresent()) {
return input;
} else {
throw new BadRequestException("Executable arch is missing");
}
}

@PutMapping("/api/payloads/{payloadId}")
@PreAuthorize("isPlanner()")
@Transactional(rollbackOn = Exception.class)
Expand All @@ -149,34 +169,35 @@ public Payload updatePayload(
payload.setAttackPatterns(fromIterable(attackPatternRepository.findAllById(input.getAttackPatternsIds())));
payload.setTags(iterableToSet(tagRepository.findAllById(input.getTagIds())));
payload.setUpdatedAt(Instant.now());
switch (payload.getType()) {
case "Command":
switch (PayloadType.fromString(payload.getType())) {
case PayloadType.COMMAND:
Command payloadCommand = (Command) Hibernate.unproxy(payload);
payloadCommand.setUpdateAttributes(input);
payloadCommand = payloadRepository.save(payloadCommand);
this.payloadService.updateInjectorContractsForPayload(payloadCommand);
return payloadCommand;
case "Executable":
case PayloadType.EXECUTABLE:
PayloadUpdateInput validatedInput = validateExecutableUpdateInput(input);
Executable payloadExecutable = (Executable) Hibernate.unproxy(payload);
payloadExecutable.setUpdateAttributes(input);
payloadExecutable.setExecutableFile(documentRepository.findById(input.getExecutableFile()).orElseThrow());
payloadExecutable.setUpdateAttributes(validatedInput);
payloadExecutable.setExecutableFile(documentRepository.findById(validatedInput.getExecutableFile()).orElseThrow());
payloadExecutable = payloadRepository.save(payloadExecutable);
this.payloadService.updateInjectorContractsForPayload(payloadExecutable);
return payloadExecutable;
case "FileDrop":
case PayloadType.FILE_DROP:
FileDrop payloadFileDrop = (FileDrop) Hibernate.unproxy(payload);
payloadFileDrop.setUpdateAttributes(input);
payloadFileDrop.setFileDropFile(documentRepository.findById(input.getFileDropFile()).orElseThrow());
payloadFileDrop = payloadRepository.save(payloadFileDrop);
this.payloadService.updateInjectorContractsForPayload(payloadFileDrop);
return payloadFileDrop;
case "DnsResolution":
case PayloadType.DNS_RESOLUTION:
DnsResolution payloadDnsResolution = (DnsResolution) Hibernate.unproxy(payload);
payloadDnsResolution.setUpdateAttributes(input);
payloadDnsResolution = payloadRepository.save(payloadDnsResolution);
this.payloadService.updateInjectorContractsForPayload(payloadDnsResolution);
return payloadDnsResolution;
case "NetworkTraffic":
case PayloadType.NETWORK_TRAFFIC:
NetworkTraffic payloadNetworkTraffic = (NetworkTraffic) Hibernate.unproxy(payload);
payloadNetworkTraffic.setUpdateAttributes(input);
payloadNetworkTraffic = payloadRepository.save(payloadNetworkTraffic);
Expand Down Expand Up @@ -207,34 +228,34 @@ public Payload upsertPayload(@Valid @RequestBody PayloadUpsertInput input) {
existingPayload.setAttackPatterns(fromIterable(attackPatternRepository.findAllByExternalIdInIgnoreCase(input.getAttackPatternsExternalIds())));
existingPayload.setTags(iterableToSet(tagRepository.findAllById(input.getTagIds())));
existingPayload.setUpdatedAt(Instant.now());
switch (existingPayload.getType()) {
case "Command":
switch (PayloadType.fromString(existingPayload.getType())) {
case PayloadType.COMMAND:
Command payloadCommand = (Command) Hibernate.unproxy(existingPayload);
payloadCommand.setUpdateAttributes(input);
payloadCommand = payloadRepository.save(payloadCommand);
this.payloadService.updateInjectorContractsForPayload(payloadCommand);
return payloadCommand;
case "Executable":
case PayloadType.EXECUTABLE:
Executable payloadExecutable = (Executable) Hibernate.unproxy(existingPayload);
payloadExecutable.setUpdateAttributes(input);
payloadExecutable.setExecutableFile(documentRepository.findById(input.getExecutableFile()).orElseThrow());
payloadExecutable = payloadRepository.save(payloadExecutable);
this.payloadService.updateInjectorContractsForPayload(payloadExecutable);
return payloadExecutable;
case "FileDrop":
case PayloadType.FILE_DROP:
FileDrop payloadFileDrop = (FileDrop) Hibernate.unproxy(existingPayload);
payloadFileDrop.setUpdateAttributes(input);
payloadFileDrop.setFileDropFile(documentRepository.findById(input.getFileDropFile()).orElseThrow());
payloadFileDrop = payloadRepository.save(payloadFileDrop);
this.payloadService.updateInjectorContractsForPayload(payloadFileDrop);
return payloadFileDrop;
case "DnsResolution":
case PayloadType.DNS_RESOLUTION:
DnsResolution payloadDnsResolution = (DnsResolution) Hibernate.unproxy(existingPayload);
payloadDnsResolution.setUpdateAttributes(input);
payloadDnsResolution = payloadRepository.save(payloadDnsResolution);
this.payloadService.updateInjectorContractsForPayload(payloadDnsResolution);
return payloadDnsResolution;
case "NetworkTraffic":
case PayloadType.NETWORK_TRAFFIC:
NetworkTraffic payloadNetworkTraffic = (NetworkTraffic) Hibernate.unproxy(existingPayload);
payloadNetworkTraffic.setUpdateAttributes(input);
payloadNetworkTraffic = payloadRepository.save(payloadNetworkTraffic);
Expand All @@ -244,8 +265,8 @@ public Payload upsertPayload(@Valid @RequestBody PayloadUpsertInput input) {
throw new UnsupportedOperationException("Payload type " + existingPayload.getType() + " is not supported");
}
} else {
switch (input.getType()) {
case "Command":
switch (PayloadType.fromString(input.getType())) {
case PayloadType.COMMAND:
Command commandPayload = new Command();
commandPayload.setUpdateAttributes(input);
if( input.getCollector() != null ) {
Expand All @@ -256,7 +277,7 @@ public Payload upsertPayload(@Valid @RequestBody PayloadUpsertInput input) {
commandPayload = payloadRepository.save(commandPayload);
this.payloadService.updateInjectorContractsForPayload(commandPayload);
return commandPayload;
case "Executable":
case PayloadType.EXECUTABLE:
Executable executablePayload = new Executable();
executablePayload.setUpdateAttributes(input);
if( input.getCollector() != null ) {
Expand All @@ -268,7 +289,7 @@ public Payload upsertPayload(@Valid @RequestBody PayloadUpsertInput input) {
executablePayload = payloadRepository.save(executablePayload);
this.payloadService.updateInjectorContractsForPayload(executablePayload);
return executablePayload;
case "FileDrop":
case PayloadType.FILE_DROP:
FileDrop fileDropPayload = new FileDrop();
fileDropPayload.setUpdateAttributes(input);
if( input.getCollector() != null ) {
Expand All @@ -280,7 +301,7 @@ public Payload upsertPayload(@Valid @RequestBody PayloadUpsertInput input) {
fileDropPayload = payloadRepository.save(fileDropPayload);
this.payloadService.updateInjectorContractsForPayload(fileDropPayload);
return fileDropPayload;
case "DnsResolution":
case PayloadType.DNS_RESOLUTION:
DnsResolution dnsResolutionPayload = new DnsResolution();
dnsResolutionPayload.setUpdateAttributes(input);
if( input.getCollector() != null ) {
Expand All @@ -291,7 +312,7 @@ public Payload upsertPayload(@Valid @RequestBody PayloadUpsertInput input) {
dnsResolutionPayload = payloadRepository.save(dnsResolutionPayload);
this.payloadService.updateInjectorContractsForPayload(dnsResolutionPayload);
return dnsResolutionPayload;
case "NetworkTraffic":
case PayloadType.NETWORK_TRAFFIC:
NetworkTraffic networkTrafficPayload = new NetworkTraffic();
networkTrafficPayload.setUpdateAttributes(input);
if( input.getCollector() != null ) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.openbas.rest.payload.form;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.openbas.database.model.Endpoint;
import io.openbas.database.model.Endpoint.PLATFORM_TYPE;
import io.openbas.database.model.Payload.PAYLOAD_SOURCE;
import io.openbas.database.model.Payload.PAYLOAD_STATUS;
Expand Down Expand Up @@ -50,6 +51,9 @@ public class PayloadCreateInput {
@JsonProperty("command_content")
private String content;

@JsonProperty("executable_arch")
private Endpoint.PLATFORM_ARCH executableArch;

@JsonProperty("executable_file")
private String executableFile;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.openbas.rest.payload.form;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.openbas.database.model.Endpoint;
import io.openbas.database.model.Endpoint.PLATFORM_TYPE;
import io.openbas.database.model.PayloadArgument;
import io.openbas.database.model.PayloadPrerequisite;
Expand Down Expand Up @@ -32,6 +33,9 @@ public class PayloadUpdateInput {
@JsonProperty("command_content")
private String content;

@JsonProperty("executable_arch")
private Endpoint.PLATFORM_ARCH executableArch;

@JsonProperty("executable_file")
private String executableFile;

Expand Down
4 changes: 2 additions & 2 deletions openbas-api/src/main/java/io/openbas/schema/SchemaApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@
@RequestBody @Valid @NotNull List<String> filterNames) throws ClassNotFoundException {
String completeClassName = "io.openbas.database.model." + className;
if (filterableOnly) {
return SchemaUtils.schema(Class.forName(completeClassName))
return SchemaUtils.schemaWithSubtypes(Class.forName(completeClassName))

Check warning on line 26 in openbas-api/src/main/java/io/openbas/schema/SchemaApi.java

View check run for this annotation

Codecov / codecov/patch

openbas-api/src/main/java/io/openbas/schema/SchemaApi.java#L26

Added line #L26 was not covered by tests
.stream()
.filter(PropertySchema::isFilterable)
.filter(p -> filterNames.isEmpty() || filterNames.contains(p.getJsonName()))
.map(PropertySchemaDTO::new)
.toList();
}
return SchemaUtils.schema(Class.forName(completeClassName))
return SchemaUtils.schemaWithSubtypes(Class.forName(completeClassName))

Check warning on line 33 in openbas-api/src/main/java/io/openbas/schema/SchemaApi.java

View check run for this annotation

Codecov / codecov/patch

openbas-api/src/main/java/io/openbas/schema/SchemaApi.java#L33

Added line #L33 was not covered by tests
.stream()
.filter(p -> filterNames.isEmpty() || filterNames.contains(p.getJsonName()))
.map(PropertySchemaDTO::new)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public class InjectHelperTest {
void injectsToRunTest() {
// -- PREPARE --
Exercise exercise = new Exercise();
exercise.setName("Exercice name");
exercise.setName("Exercise name");
exercise.setStart(Instant.now());
exercise.setFrom("test@test.com");
exercise.setReplyTos(List.of("test@test.com"));
Expand Down
Loading