Skip to content

Commit 3c1b91b

Browse files
committed
[backend] Implement garbage collectors on Tanium / CS to purge payloads / runtimes (#3812)
1 parent 88d02ae commit 3c1b91b

File tree

5 files changed

+191
-1
lines changed

5 files changed

+191
-1
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package io.openbas.executors.crowdstrike;
2+
3+
import io.openbas.executors.crowdstrike.client.CrowdStrikeExecutorClient;
4+
import io.openbas.executors.crowdstrike.config.CrowdStrikeExecutorConfig;
5+
import io.openbas.executors.crowdstrike.service.CrowdStrikeGarbageCollectorService;
6+
import io.openbas.service.AgentService;
7+
import jakarta.annotation.PostConstruct;
8+
import java.time.Duration;
9+
import lombok.RequiredArgsConstructor;
10+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
11+
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
12+
import org.springframework.stereotype.Service;
13+
14+
@ConditionalOnProperty(prefix = "executor.crowdstrike", name = "enable")
15+
@RequiredArgsConstructor
16+
@Service
17+
public class CrowdStrikeGarbageCollector {
18+
19+
private final CrowdStrikeExecutorConfig config;
20+
private final ThreadPoolTaskScheduler taskScheduler;
21+
private final CrowdStrikeExecutorClient client;
22+
private final AgentService agentService;
23+
24+
@PostConstruct
25+
public void init() {
26+
if (this.config.isEnable()) {
27+
CrowdStrikeGarbageCollectorService service =
28+
new CrowdStrikeGarbageCollectorService(this.config, this.client, this.agentService);
29+
this.taskScheduler.scheduleAtFixedRate(service, Duration.ofHours(6));
30+
}
31+
}
32+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package io.openbas.executors.crowdstrike.service;
2+
3+
import io.openbas.database.model.Endpoint;
4+
import io.openbas.executors.crowdstrike.client.CrowdStrikeExecutorClient;
5+
import io.openbas.executors.crowdstrike.config.CrowdStrikeExecutorConfig;
6+
import io.openbas.service.AgentService;
7+
import java.nio.charset.StandardCharsets;
8+
import java.util.Base64;
9+
import java.util.List;
10+
import lombok.extern.slf4j.Slf4j;
11+
import org.springframework.beans.factory.annotation.Autowired;
12+
import org.springframework.stereotype.Service;
13+
14+
@Slf4j
15+
@Service
16+
public class CrowdStrikeGarbageCollectorService implements Runnable {
17+
// Clean payloads older than 24 hours
18+
private static final String WINDOWS_COMMAND_LINE =
19+
"Get-ChildItem -Path \"C:\\Program Files (x86)\\Filigran\\OBAS Agent\\payloads\",\"C:\\Program Files (x86)\\Filigran\\OBAS Agent\\runtimes\" -Directory -Recurse | Where-Object {$_.CreationTime -lt (Get-Date).AddHours(-24)} | Remove-Item -Recurse -Force";
20+
private static final String UNIX_COMMAND_LINE =
21+
"find /opt/openbas-agent/payloads /opt/openbas-agent/runtimes -type d -mmin +1440 -exec rm -rf {} + 2>/dev/null";
22+
private final CrowdStrikeExecutorConfig config;
23+
private final CrowdStrikeExecutorClient client;
24+
private final AgentService agentService;
25+
26+
@Autowired
27+
public CrowdStrikeGarbageCollectorService(
28+
CrowdStrikeExecutorConfig config,
29+
CrowdStrikeExecutorClient client,
30+
AgentService agentService) {
31+
this.config = config;
32+
this.client = client;
33+
this.agentService = agentService;
34+
}
35+
36+
@Override
37+
public void run() {
38+
log.info("Running CrowdStrike executor garbage collector...");
39+
List<io.openbas.database.model.Agent> agents =
40+
this.agentService.getAgentsByExecutorType(
41+
CrowdStrikeExecutorService.CROWDSTRIKE_EXECUTOR_TYPE);
42+
log.info("Running CrowdStrike executor garbage collector on " + agents.size() + " agents");
43+
agents.forEach(
44+
agent -> {
45+
Endpoint endpoint = (Endpoint) agent.getAsset();
46+
switch (endpoint.getPlatform()) {
47+
case Windows -> {
48+
log.info("Sending Windows command line to " + endpoint.getName());
49+
this.client.executeAction(
50+
List.of(agent.getExternalReference()),
51+
this.config.getWindowsScriptName(),
52+
Base64.getEncoder()
53+
.encodeToString(WINDOWS_COMMAND_LINE.getBytes(StandardCharsets.UTF_16LE)));
54+
}
55+
case Linux, MacOS -> {
56+
log.info("Sending Unix command line to " + endpoint.getName());
57+
this.client.executeAction(
58+
List.of(agent.getExternalReference()),
59+
this.config.getUnixScriptName(),
60+
Base64.getEncoder()
61+
.encodeToString(UNIX_COMMAND_LINE.getBytes(StandardCharsets.UTF_8)));
62+
}
63+
}
64+
});
65+
}
66+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package io.openbas.executors.tanium;
2+
3+
import io.openbas.executors.tanium.client.TaniumExecutorClient;
4+
import io.openbas.executors.tanium.config.TaniumExecutorConfig;
5+
import io.openbas.executors.tanium.service.TaniumGarbageCollectorService;
6+
import io.openbas.service.AgentService;
7+
import jakarta.annotation.PostConstruct;
8+
import java.time.Duration;
9+
import lombok.RequiredArgsConstructor;
10+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
11+
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
12+
import org.springframework.stereotype.Service;
13+
14+
@ConditionalOnProperty(prefix = "executor.tanium", name = "enable")
15+
@RequiredArgsConstructor
16+
@Service
17+
public class TaniumGarbageCollector {
18+
19+
private final TaniumExecutorConfig config;
20+
private final ThreadPoolTaskScheduler taskScheduler;
21+
private final TaniumExecutorClient client;
22+
private final AgentService agentService;
23+
24+
@PostConstruct
25+
public void init() {
26+
if (this.config.isEnable()) {
27+
TaniumGarbageCollectorService service =
28+
new TaniumGarbageCollectorService(this.config, this.client, this.agentService);
29+
this.taskScheduler.scheduleAtFixedRate(service, Duration.ofHours(6));
30+
}
31+
}
32+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package io.openbas.executors.tanium.service;
2+
3+
import io.openbas.database.model.Endpoint;
4+
import io.openbas.executors.tanium.client.TaniumExecutorClient;
5+
import io.openbas.executors.tanium.config.TaniumExecutorConfig;
6+
import io.openbas.service.AgentService;
7+
import java.util.Base64;
8+
import java.util.List;
9+
import lombok.extern.slf4j.Slf4j;
10+
import org.springframework.beans.factory.annotation.Autowired;
11+
import org.springframework.stereotype.Service;
12+
13+
@Slf4j
14+
@Service
15+
public class TaniumGarbageCollectorService implements Runnable {
16+
// Clean payloads older than 24 hours
17+
private static final String WINDOWS_COMMAND_LINE =
18+
"Get-ChildItem -Path \"C:\\Program Files (x86)\\Filigran\\OBAS Agent\\payloads\",\"C:\\Program Files (x86)\\Filigran\\OBAS Agent\\runtimes\" -Directory -Recurse | Where-Object {$_.CreationTime -lt (Get-Date).AddHours(-24)} | Remove-Item -Recurse -Force";
19+
private static final String UNIX_COMMAND_LINE =
20+
"find /opt/openbas-agent/payloads /opt/openbas-agent/runtimes -type d -mmin +1440 -exec rm -rf {} + 2>/dev/null";
21+
private final TaniumExecutorConfig config;
22+
private final TaniumExecutorClient client;
23+
private final AgentService agentService;
24+
25+
@Autowired
26+
public TaniumGarbageCollectorService(
27+
TaniumExecutorConfig config, TaniumExecutorClient client, AgentService agentService) {
28+
this.config = config;
29+
this.client = client;
30+
this.agentService = agentService;
31+
}
32+
33+
@Override
34+
public void run() {
35+
log.info("Running Tanium executor garbage collector...");
36+
List<io.openbas.database.model.Agent> agents =
37+
this.agentService.getAgentsByExecutorType(TaniumExecutorService.TANIUM_EXECUTOR_TYPE);
38+
log.info("Running Tanium executor garbage collector on " + agents.size() + " agents");
39+
agents.forEach(
40+
agent -> {
41+
Endpoint endpoint = (Endpoint) agent.getAsset();
42+
switch (endpoint.getPlatform()) {
43+
case Windows -> {
44+
log.info("Sending Windows command line to " + endpoint.getName());
45+
this.client.executeAction(
46+
agent.getExternalReference(),
47+
this.config.getWindowsPackageId(),
48+
Base64.getEncoder().encodeToString(WINDOWS_COMMAND_LINE.getBytes()));
49+
}
50+
case Linux, MacOS -> {
51+
log.info("Sending Unix command line to " + endpoint.getName());
52+
this.client.executeAction(
53+
agent.getExternalReference(),
54+
this.config.getUnixPackageId(),
55+
Base64.getEncoder().encodeToString(UNIX_COMMAND_LINE.getBytes()));
56+
}
57+
}
58+
});
59+
}
60+
}

openbas-api/src/main/java/io/openbas/injectors/caldera/CalderaGarbageCollector.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
1212
import org.springframework.stereotype.Service;
1313

14-
@ConditionalOnProperty(prefix = "executor.caldera", name = "enable")
14+
@ConditionalOnProperty(prefix = "injector.caldera", name = "enable")
1515
@RequiredArgsConstructor
1616
@Service
1717
public class CalderaGarbageCollector {

0 commit comments

Comments
 (0)