Skip to content

Commit

Permalink
[backend] Finish the Tanium executor
Browse files Browse the repository at this point in the history
  • Loading branch information
SamuelHassine committed May 16, 2024
1 parent 829ef59 commit 630612b
Show file tree
Hide file tree
Showing 56 changed files with 208 additions and 177 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,12 @@ private Endpoint findAndRegisterAssetForExecution(@NotNull final Inject inject,
count++;
// Find an executor agent matching the asset
log.log(Level.INFO, "Listing agents...");
List<Agent> agents = this.calderaService.agents().stream().filter(agent -> agent.getExe_name().contains("executor") && (now().toEpochMilli() - Time.toInstant(agent.getCreated()).toEpochMilli()) < Asset.ACTIVE_THRESHOLD && agent.getHost().equals(assetEndpoint.getHostname()) && Arrays.stream(assetEndpoint.getIps()).anyMatch(s -> Arrays.stream(agent.getHost_ip_addrs()).toList().contains(s))).toList();
List<Agent> agents = this.calderaService.agents().stream().filter(agent ->
agent.getExe_name().contains("executor")
&& (now().toEpochMilli() - Time.toInstant(agent.getCreated()).toEpochMilli()) < Asset.ACTIVE_THRESHOLD
&& (agent.getHost().equals(assetEndpoint.getHostname()) || agent.getHost().split("\\.")[0].equals(assetEndpoint.getHostname().split("\\.")[0]))
&& Arrays.stream(assetEndpoint.getIps()).anyMatch(s -> Arrays.stream(agent.getHost_ip_addrs()).toList().contains(s))
).toList();
log.log(Level.INFO, "List return with " + agents.size() + " agents");
if (!agents.isEmpty()) {
for (int i = 0; i < agents.size(); i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ public class CalderaInjector {
public CalderaInjector(InjectorService injectorService, CalderaContract contract, CalderaInjectorConfig calderaInjectorConfig) {
Map<String, String> executorCommands = new HashMap<>();
executorCommands.put(Endpoint.PLATFORM_TYPE.Windows.name(), "$x=\"#{location}\";$location=$x.Replace(\"\\obas.exe\", \"\");[Environment]::CurrentDirectory = $location;$random=-join ((65..90) + (97..122) | Get-Random -Count 5 | % {[char]$_});$filename=\"obas-executor-$random.exe\";$server=\"" + calderaInjectorConfig.getPublicUrl() + "\";$url=\"$server/file/download\";$wc=New-Object System.Net.WebClient;$wc.Headers.add(\"platform\",\"windows\");$wc.Headers.add(\"file\",\"sandcat.go\");$data=$wc.DownloadData($url);[io.file]::WriteAllBytes($filename,$data) | Out-Null;New-NetFirewallRule -DisplayName \"Allow OpenBAS\" -Direction Inbound -Program \"$location\\$filename\" -Action Allow | Out-Null;New-NetFirewallRule -DisplayName \"Allow OpenBAS\" -Direction Outbound -Program \"$location\\$filename\" -Action Allow | Out-Null;Start-Process -FilePath \"$location\\$filename\" -ArgumentList \"-server $server -group red\" -WindowStyle hidden;");
executorCommands.put(Endpoint.PLATFORM_TYPE.Linux.name(), "x=\"#{location}\";location=$(echo \"$location\" | sed \"s#/obas##\");filename=obas-executor-$(tr -dc A-Za-z0-9 </dev/urandom | head -c 5; echo);server=\"" + calderaInjectorConfig.getPublicUrl() + "\";curl -s -X POST -H \"file:sandcat.go\" -H \"platform:linux\" $server/file/download > $location/$filename;chmod +x $location/$filename;nohup $location/$filename -server $server -group red &");
executorCommands.put(Endpoint.PLATFORM_TYPE.MacOS.name(), "x=\"#{location}\";location=$(echo \"$location\" | sed \"s#/obas##\");filename=obas-executor-$(tr -dc A-Za-z0-9 </dev/urandom | head -c 5; echo);server=\"" + calderaInjectorConfig.getPublicUrl() + "\";curl -s -X POST -H \"file:sandcat.go\" -H \"platform:darwin\" -H \"architecture:amd64\" $server/file/download > $location/$filename;chmod +x $location/$filename;nohup $location/$filename -server $server -group red &");
executorCommands.put(Endpoint.PLATFORM_TYPE.Linux.name(), "x=\"#{location}\";location=$(echo \"$x\" | sed \"s#/obas##\");filename=obas-executor-$(tr -dc A-Za-z0-9 </dev/urandom | head -c 5; echo);server=\"" + calderaInjectorConfig.getPublicUrl() + "\";curl -s -X POST -H \"file:sandcat.go\" -H \"platform:linux\" $server/file/download > $location/$filename;chmod +x $location/$filename;$location/$filename -server $server -group red &");
executorCommands.put(Endpoint.PLATFORM_TYPE.MacOS.name(), "x=\"#{location}\";location=$(echo \"$x\" | sed \"s#/obas##\");filename=obas-executor-$(tr -dc A-Za-z0-9 </dev/urandom | head -c 5; echo);server=\"" + calderaInjectorConfig.getPublicUrl() + "\";curl -s -X POST -H \"file:sandcat.go\" -H \"platform:darwin\" -H \"architecture:amd64\" $server/file/download > $location/$filename;chmod +x $location/$filename;$location/$filename -server $server -group red &");
Map<String, String> executorClearCommands = new HashMap<>();
executorClearCommands.put(Endpoint.PLATFORM_TYPE.Windows.name(), "$x=\"#{location}\";$location=$x.Replace(\"\\obas.exe\", \"\");[Environment]::CurrentDirectory = $location;cd \"$location\";Get-ChildItem -Recurse -Filter *executor* | Remove-Item");
executorClearCommands.put(Endpoint.PLATFORM_TYPE.Linux.name(), "x=\"#{location}\";location=$(echo \"$location\" | sed \"s#/obas##\");cd \"$location\"; rm *executor*");
executorClearCommands.put(Endpoint.PLATFORM_TYPE.MacOS.name(), "x=\"#{location}\";location=$(echo \"$location\" | sed \"s#/obas##\");cd \"$location\"; rm *executor*");
executorClearCommands.put(Endpoint.PLATFORM_TYPE.Linux.name(), "x=\"#{location}\";location=$(echo \"$x\" | sed \"s#/obas##\");cd \"$location\"; rm *executor*");
executorClearCommands.put(Endpoint.PLATFORM_TYPE.MacOS.name(), "x=\"#{location}\";location=$(echo \"$x\" | sed \"s#/obas##\");cd \"$location\"; rm *executor*");
try {
injectorService.register(
calderaInjectorConfig.getId(),
Expand Down
3 changes: 1 addition & 2 deletions openbas-api/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,7 @@ executor.tanium.api-key=<tanium-api-key>
executor.tanium.computer-group-id=1
executor.tanium.action-group-id=4
executor.tanium.windows-package-id=
executor.tanium.linux-package-id=
executor.tanium.mac-os-package-id=
executor.tanium.unix-package-id=

#############
# INJECTORS #
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,12 @@ public void run() {
endpoints.forEach(endpoint -> {
List<Endpoint> existingEndpoints = this.endpointService.findAssetsForInjectionByHostname(endpoint.getHostname()).stream().filter(endpoint1 -> Arrays.stream(endpoint1.getIps()).anyMatch(s -> Arrays.stream(endpoint.getIps()).toList().contains(s))).toList();
if (existingEndpoints.isEmpty()) {
this.endpointService.createEndpoint(endpoint);
Optional<Endpoint> endpointByExternalReference = endpointService.findByExternalReference(endpoint.getExternalReference());
if( endpointByExternalReference.isPresent() ) {
this.updateEndpoint(endpoint, List.of(endpointByExternalReference.get()));
} else {
this.endpointService.createEndpoint(endpoint);
}
} else {
this.updateEndpoint(endpoint, existingEndpoints);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,7 @@ public class TaniumExecutorConfig {

@Getter
@NotBlank
private Integer linuxPackageId;

@Getter
@NotBlank
private Integer macOsPackageId;
private Integer unixPackageId;

public String getGatewayUrl() {
return url + GATEWAY_URI;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"comment":"Exported from Tanium Server 7.6.1.6540 at 2024-05-16T20:24:14","version":2,"object_list":{"package_specs":[{"content_set":{"name":"Base"},"name":"OpenBAS Subprocessor (Unix)","display_name":"OpenBAS Subprocessor (Unix)","files":[],"file_templates":[],"command":"/bin/sh -c \"/bin/echo $1 | base64 -d | sh\"","command_timeout":60,"expire_seconds":660,"hidden_flag":0,"process_group_flag":0,"verify_group":{"name":"","and_flag":0,"not_flag":0,"type":0},"verify_expire_seconds":600,"skip_lock_flag":0,"parameter_definition":"{\"parameters\":[{\"defaultValue\":\"\",\"helpString\":\"\",\"label\":\"command\",\"maxChars\":\"\",\"promptText\":\"\",\"validationExpressions\":[{\"expression\":\".*\",\"helpString\":\"\",\"model\":\"com.tanium.models::ValidationExpression\",\"parameterType\":\"com.tanium.models::ValidationExpression\"}],\"parameterType\":\"com.tanium.components.parameters::TextInputParameter\",\"key\":\"$1\"}]}","metadata":[]},{"content_set":{"name":"Base"},"name":"OpenBAS Subprocessor (Windows)","display_name":"OpenBAS Subprocessor (Windows)","files":[],"file_templates":[],"command":"cmd.exe /d /c powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -NonInteractive -NoProfile -Command \"Invoke-Expression ([System.Text.Encoding]::UTF8.GetString([convert]::FromBase64String('$1')))\"","command_timeout":60,"expire_seconds":660,"hidden_flag":0,"process_group_flag":0,"verify_group":{"name":"","and_flag":0,"not_flag":0,"type":0},"verify_expire_seconds":600,"skip_lock_flag":0,"parameter_definition":"{\"parameters\":[{\"defaultValue\":\"\",\"helpString\":\"\",\"label\":\"command\",\"maxChars\":\"\",\"promptText\":\"\",\"validationExpressions\":[{\"expression\":\".*\",\"helpString\":\"\",\"model\":\"com.tanium.models::ValidationExpression\",\"parameterType\":\"com.tanium.models::ValidationExpression\"}],\"parameterType\":\"com.tanium.components.parameters::TextInputParameter\",\"key\":\"$1\"}]}","metadata":[]}]}}
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ public void launchExecutorSubprocess(@NotNull final Injector injector, @NotNull
this.taniumExecutorClient.executeAction(asset.getExternalReference(), this.taniumExecutorConfig.getWindowsPackageId(), Base64.getEncoder().encodeToString(command.getBytes()));
}
case Endpoint.PLATFORM_TYPE.Linux -> {
String command = injector.getExecutorCommands().get(Endpoint.PLATFORM_TYPE.Linux.name()).replace("\"#{location}\"", "$PWD.Path");
this.taniumExecutorClient.executeAction(asset.getExternalReference(), this.taniumExecutorConfig.getLinuxPackageId(), Base64.getEncoder().encodeToString(command.getBytes()));
String command = injector.getExecutorCommands().get(Endpoint.PLATFORM_TYPE.Linux.name()).replace("\"#{location}\"", "$(pwd)");
this.taniumExecutorClient.executeAction(asset.getExternalReference(), this.taniumExecutorConfig.getUnixPackageId(), Base64.getEncoder().encodeToString(command.getBytes()));
}
case Endpoint.PLATFORM_TYPE.MacOS -> {
String command = injector.getExecutorCommands().get(Endpoint.PLATFORM_TYPE.MacOS.name()).replace("\"#{location}\"", "$PWD.Path");
this.taniumExecutorClient.executeAction(asset.getExternalReference(), this.taniumExecutorConfig.getMacOsPackageId(), injector.getExecutorCommands().get(Endpoint.PLATFORM_TYPE.MacOS.name()));
String command = injector.getExecutorCommands().get(Endpoint.PLATFORM_TYPE.MacOS.name()).replace("\"#{location}\"", "$(pwd)");
this.taniumExecutorClient.executeAction(asset.getExternalReference(), this.taniumExecutorConfig.getUnixPackageId(), Base64.getEncoder().encodeToString(command.getBytes()));
}
default -> throw new RuntimeException("Unsupported platform: " + platform);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.*;
import java.util.logging.Level;

import static java.time.Instant.now;
Expand Down Expand Up @@ -90,7 +87,12 @@ public void run() {
endpoints.forEach(endpoint -> {
List<Endpoint> existingEndpoints = this.endpointService.findAssetsForInjectionByHostname(endpoint.getHostname()).stream().filter(endpoint1 -> Arrays.stream(endpoint1.getIps()).anyMatch(s -> Arrays.stream(endpoint.getIps()).toList().contains(s))).toList();
if (existingEndpoints.isEmpty()) {
this.endpointService.createEndpoint(endpoint);
Optional<Endpoint> endpointByExternalReference = endpointService.findByExternalReference(endpoint.getExternalReference());
if( endpointByExternalReference.isPresent() ) {
this.updateEndpoint(endpoint, List.of(endpointByExternalReference.get()));
} else {
this.endpointService.createEndpoint(endpoint);
}
} else {
this.updateEndpoint(endpoint, existingEndpoints);
}
Expand Down
2 changes: 1 addition & 1 deletion openbas-front/src/actions/assets/asset-helper.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { EndpointStore } from '../../admin/components/assets/endpoints/Endpoint';

export interface EndpointsHelper {
export interface EndpointHelper {
getEndpoints: () => EndpointStore[];
getEndpointsMap: () => Record<string, EndpointStore>;
}
10 changes: 5 additions & 5 deletions openbas-front/src/actions/helper.d.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import type { Challenge, Exercise, Organization, PlatformSettings, Tag, User } from '../utils/api-types';
import type { ScenarioStore } from './scenarios/Scenario';

export interface UsersHelper {
export interface UserHelper {
getMe: () => User;
getUsersMap: () => Record<string, User>;
}

export interface OrganizationsHelper {
export interface OrganizationHelper {
getOrganizations: () => Organization[];
getOrganizationsMap: () => Record<string, Organization>;
}

export interface TagsHelper {
export interface TagHelper {
getTag: (tagId: Tag['tag_id']) => Tag;
getTags: () => Tag[];
getTagsMap: () => Record<string, Tag>;
Expand All @@ -26,13 +26,13 @@ export interface LoggedHelper {
getPlatformSettings: () => PlatformSettings;
}

export interface ChallengesHelper {
export interface ChallengeHelper {
getChallengesMap: () => Record<string, Challenge>;
getChallenges: () => Challenge[];
getExerciseChallenges: (exerciseId: Exercise['exercise_id']) => Challenge[];
getScenarioChallenges: (scenarioId: ScenarioStore['scenario_id']) => Challenge[];
}

export interface DocumentsHelper {
export interface DocumentHelper {
getDocumentsMap: () => Record<string, Document>
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import TagsFilter from '../../common/filters/TagsFilter';
import SearchFilter from '../../../../components/SearchFilter';
import AssetGroupAddEndpoints from './AssetGroupAddEndpoints';
import { useHelper } from '../../../../store';
import type { UsersHelper } from '../../../../actions/helper';
import type { UserHelper } from '../../../../actions/helper';
import useDataLoader from '../../../../utils/hooks/useDataLoader';
import { fetchEndpoints } from '../../../../actions/assets/endpoint-actions';
import { useAppDispatch } from '../../../../utils/hooks';
Expand All @@ -16,7 +16,7 @@ import type { AssetGroupsHelper } from '../../../../actions/asset_groups/assetgr
import EndpointsList, { EndpointStoreWithType } from '../endpoints/EndpointsList';
import EndpointPopover from '../endpoints/EndpointPopover';
import useSearchAnFilter from '../../../../utils/SortingFiltering';
import type { EndpointsHelper } from '../../../../actions/assets/asset-helper';
import type { EndpointHelper } from '../../../../actions/assets/asset-helper';
import type { AssetGroupStore } from './AssetGroup';

const useStyles = makeStyles((theme: Theme) => ({
Expand Down Expand Up @@ -65,7 +65,7 @@ const AssetGroupManagement: FunctionComponent<Props> = ({
const dispatch = useAppDispatch();

// Fetching data
const { assetGroup, endpointsMap, userAdmin } = useHelper((helper: AssetGroupsHelper & EndpointsHelper & UsersHelper) => ({
const { assetGroup, endpointsMap, userAdmin } = useHelper((helper: AssetGroupsHelper & EndpointHelper & UserHelper) => ({
assetGroup: helper.getAssetGroup(assetGroupId),
endpointsMap: helper.getEndpointsMap(),
userAdmin: helper.getMe()?.user_admin ?? false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { SelectGroup } from 'mdi-material-ui';
import { useSearchParams } from 'react-router-dom';
import { useFormatter } from '../../../../components/i18n';
import { useHelper } from '../../../../store';
import type { TagsHelper, UsersHelper } from '../../../../actions/helper';
import type { TagHelper, UserHelper } from '../../../../actions/helper';
import type { AssetGroupStore } from './AssetGroup';
import ItemTags from '../../../../components/ItemTags';
import AssetGroupPopover from './AssetGroupPopover';
Expand All @@ -14,7 +14,7 @@ import { searchAssetGroups } from '../../../../actions/asset_groups/assetgroup-a
import AssetGroupManagement from './AssetGroupManagement';
import Breadcrumbs from '../../../../components/Breadcrumbs';
import PaginationComponent from '../../../../components/common/pagination/PaginationComponent';
import type { EndpointsHelper } from '../../../../actions/assets/asset-helper';
import type { EndpointHelper } from '../../../../actions/assets/asset-helper';
import type { SearchPaginationInput } from '../../../../utils/api-types';
import { initSorting } from '../../../../components/common/pagination/Page';
import SortHeadersComponent from '../../../../components/common/pagination/SortHeadersComponent';
Expand Down Expand Up @@ -80,7 +80,7 @@ const AssetGroups = () => {
const [searchId] = searchParams.getAll('id');

// Fetching data
const { userAdmin } = useHelper((helper: EndpointsHelper & UsersHelper & TagsHelper) => ({
const { userAdmin } = useHelper((helper: EndpointHelper & UserHelper & TagHelper) => ({
userAdmin: helper.getMe()?.user_admin ?? false,
}));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Endpoint } from '../../../../utils/api-types';

export type EndpointStore = Omit<Endpoint, 'asset_tags'> & {
export type EndpointStore = Omit<Endpoint, 'asset_executor', 'asset_tags'> & {
asset_tags: string[] | undefined;
asset_executor: string | undefined;
};
Loading

0 comments on commit 630612b

Please sign in to comment.