Skip to content

Commit

Permalink
Add expiration time on automatic expectations
Browse files Browse the repository at this point in the history
  • Loading branch information
johanah29 committed Sep 26, 2024
1 parent 4ddee58 commit 65616c0
Show file tree
Hide file tree
Showing 2 changed files with 270 additions and 257 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,126 +38,130 @@
@RequiredArgsConstructor
public class CalderaContract extends Contractor {

public static final String TYPE = "openbas_caldera";

private final CalderaInjectorConfig config;
private final CalderaInjectorService injectorCalderaService;

@Override
public boolean isExpose() {
return this.config.isEnable();
public static final String TYPE = "openbas_caldera";

private final CalderaInjectorConfig config;
private final CalderaInjectorService injectorCalderaService;

@Override
public boolean isExpose() {
return this.config.isEnable();
}

@Override
public String getType() {
return TYPE;
}

@Override
public ContractConfig getConfig() {
Map<SupportedLanguage, String> labels = Map.of(en, "Caldera", fr, "Caldera");
return new ContractConfig(TYPE, labels, "#8b0000", "#8b0000", "/img/icon-caldera.png", isExpose());
}

@Override
public List<Contract> contracts() {
if (this.config.isEnable()) {
ContractConfig contractConfig = getConfig();
// Add contract based on abilities
return new ArrayList<>(abilityContracts(contractConfig));
}

@Override
public String getType() {
return TYPE;
}

@Override
public ContractConfig getConfig() {
Map<SupportedLanguage, String> labels = Map.of(en, "Caldera", fr, "Caldera");
return new ContractConfig(TYPE, labels, "#8b0000", "#8b0000", "/img/icon-caldera.png", isExpose());
}

@Override
public List<Contract> contracts() {
if (this.config.isEnable()) {
ContractConfig contractConfig = getConfig();
// Add contract based on abilities
return new ArrayList<>(abilityContracts(contractConfig));
return List.of();
}

// -- PRIVATE --

private ContractSelect obfuscatorField() {
List<Obfuscator> obfuscators = this.injectorCalderaService.obfuscators();
Map<String, String> obfuscatorChoices = obfuscators.stream()
.collect(Collectors.toMap(Obfuscator::getName, Obfuscator::getName));
return selectFieldWithDefault(
"obfuscator",
"Obfuscators",
obfuscatorChoices,
"base64"
);
}

private ContractExpectations expectations() {
// Prevention
Expectation preventionExpectation = new Expectation();
preventionExpectation.setType(PREVENTION);
preventionExpectation.setName("Expect inject to be prevented");
preventionExpectation.setScore(100.0);
preventionExpectation.setExpirationTime(21600L);
// Detection
Expectation detectionExpectation = new Expectation();
detectionExpectation.setType(DETECTION);
detectionExpectation.setName("Expect inject to be detected");
detectionExpectation.setScore(100.0);
detectionExpectation.setExpirationTime(21600L);
return expectationsField("expectations", "Expectations", List.of(preventionExpectation, detectionExpectation));
}

private List<Contract> abilityContracts(@NotNull final ContractConfig contractConfig) {
// Fields
ContractSelect obfuscatorField = obfuscatorField();
ContractAsset assetField = assetField("assets", "Assets", Multiple);
ContractAssetGroup assetGroupField = assetGroupField("assetgroups", "Asset groups", Multiple);
ContractExpectations expectationsField = expectations();

List<Ability> abilities = this.injectorCalderaService.abilities().stream()
.filter(ability -> !ability.getTactic().equals("openbas")).toList();
// Build contracts
return abilities.stream().map((ability -> {
ContractDef builder = contractBuilder();
builder.mandatoryGroup(assetField, assetGroupField);
builder.optional(obfuscatorField);
builder.optional(expectationsField);
List<PLATFORM_TYPE> platforms = new ArrayList<>();
ability.getExecutors().forEach(executor -> {
String command = executor.getCommand();
if (command != null && !command.isEmpty()) {
Matcher matcher = Pattern.compile("#\\{(.*?)\\}").matcher(command);
while (matcher.find()) {
if (!matcher.group(1).isEmpty()) {
builder.mandatory(ContractText.textField(matcher.group(1), matcher.group(1)));
}
}
}
return List.of();
}

// -- PRIVATE --

private ContractSelect obfuscatorField() {
List<Obfuscator> obfuscators = this.injectorCalderaService.obfuscators();
Map<String, String> obfuscatorChoices = obfuscators.stream().collect(Collectors.toMap(Obfuscator::getName, Obfuscator::getName));
return selectFieldWithDefault(
"obfuscator",
"Obfuscators",
obfuscatorChoices,
"base64"
);
}

private ContractExpectations expectations() {
// Prevention
Expectation preventionExpectation = new Expectation();
preventionExpectation.setType(PREVENTION);
preventionExpectation.setName("Expect inject to be prevented");
preventionExpectation.setScore(100.0);
// Detection
Expectation detectionExpectation = new Expectation();
detectionExpectation.setType(DETECTION);
detectionExpectation.setName("Expect inject to be detected");
detectionExpectation.setScore(100.0);
return expectationsField("expectations", "Expectations", List.of(preventionExpectation, detectionExpectation));
}

private List<Contract> abilityContracts(@NotNull final ContractConfig contractConfig) {
// Fields
ContractSelect obfuscatorField = obfuscatorField();
ContractAsset assetField = assetField("assets", "Assets", Multiple);
ContractAssetGroup assetGroupField = assetGroupField("assetgroups", "Asset groups", Multiple);
ContractExpectations expectationsField = expectations();

List<Ability> abilities = this.injectorCalderaService.abilities().stream().filter(ability -> !ability.getTactic().equals("openbas")).toList();
// Build contracts
return abilities.stream().map((ability -> {
ContractDef builder = contractBuilder();
builder.mandatoryGroup(assetField, assetGroupField);
builder.optional(obfuscatorField);
builder.optional(expectationsField);
List<PLATFORM_TYPE> platforms = new ArrayList<>();
ability.getExecutors().forEach(executor -> {
String command = executor.getCommand();
if (command != null && !command.isEmpty()) {
Matcher matcher = Pattern.compile("#\\{(.*?)\\}").matcher(command);
while (matcher.find()) {
if (!matcher.group(1).isEmpty()) {
builder.mandatory(ContractText.textField(matcher.group(1), matcher.group(1)));
}
}
}
if (!executor.getPlatform().equals("unknown")) {
PLATFORM_TYPE platform = toPlatform(executor.getPlatform());
if (!platforms.contains(platform)) {
platforms.add(platform);
}
} else {
if (executor.getName().equals("psh")) {
if (!platforms.contains(PLATFORM_TYPE.Windows)) {
platforms.add(PLATFORM_TYPE.Windows);
}
} else if (executor.getName().equals("sh")) {
if (!platforms.contains(PLATFORM_TYPE.Linux)) {
platforms.add(PLATFORM_TYPE.Linux);
}
} else if (executor.getName().equals("cmd")) {
if (!platforms.contains(PLATFORM_TYPE.Windows)) {
platforms.add(PLATFORM_TYPE.Windows);
}
}
}
});
Contract contract = executableContract(
contractConfig,
ability.getAbility_id(),
Map.of(en, ability.getName(), fr, ability.getName()),
builder.build(),
platforms,
true
);
contract.addAttackPattern(ability.getTechnique_id());
return contract;
})).collect(Collectors.toList());
}

@Override
public ContractorIcon getIcon() {
InputStream iconStream = getClass().getResourceAsStream("/img/icon-caldera.png");
return new ContractorIcon(iconStream);
}
if (!executor.getPlatform().equals("unknown")) {
PLATFORM_TYPE platform = toPlatform(executor.getPlatform());
if (!platforms.contains(platform)) {
platforms.add(platform);
}
} else {
if (executor.getName().equals("psh")) {
if (!platforms.contains(PLATFORM_TYPE.Windows)) {
platforms.add(PLATFORM_TYPE.Windows);
}
} else if (executor.getName().equals("sh")) {
if (!platforms.contains(PLATFORM_TYPE.Linux)) {
platforms.add(PLATFORM_TYPE.Linux);
}
} else if (executor.getName().equals("cmd")) {
if (!platforms.contains(PLATFORM_TYPE.Windows)) {
platforms.add(PLATFORM_TYPE.Windows);
}
}
}
});
Contract contract = executableContract(
contractConfig,
ability.getAbility_id(),
Map.of(en, ability.getName(), fr, ability.getName()),
builder.build(),
platforms,
true
);
contract.addAttackPattern(ability.getTechnique_id());
return contract;
})).collect(Collectors.toList());
}

@Override
public ContractorIcon getIcon() {
InputStream iconStream = getClass().getResourceAsStream("/img/icon-caldera.png");
return new ContractorIcon(iconStream);
}
}
Loading

0 comments on commit 65616c0

Please sign in to comment.