client.ts•106 kB
/**
* Cobalt Strike REST API Client
*/
import axios, { AxiosInstance, AxiosError } from 'axios';
import https from 'https';
import { CobaltStrikeConfig, Beacon, Listener, Session, TeamServerInfo, BeaconTask, Credential, TaskSummary, PayloadResult, Screenshot, Keystroke, Download } from '../types/index.js';
interface AuthToken {
access_token: string;
token_type: string;
expires_in: number;
expires_at?: number; // Calculated timestamp
}
export class CobaltStrikeClient {
private client: AxiosInstance;
private config: CobaltStrikeConfig;
private authToken: AuthToken | null = null;
constructor(config: CobaltStrikeConfig) {
this.config = config;
this.client = axios.create({
baseURL: config.url,
validateStatus: () => true, // Don't throw on any status
httpsAgent: config.verifySSL === false ? new https.Agent({ rejectUnauthorized: false }) : undefined,
});
// Add request interceptor to include Bearer token
this.client.interceptors.request.use(async (config) => {
// Skip interceptor for authentication endpoint to avoid infinite loop
if (config.url && config.url.includes('/api/auth/login')) {
return config;
}
// Ensure we have a valid token before making requests
await this.ensureAuthenticated();
if (this.authToken) {
config.headers = config.headers || {};
config.headers.Authorization = `Bearer ${this.authToken.access_token}`;
}
return config;
});
}
/**
* Authenticate and get access token
*/
private async authenticate(): Promise<AuthToken> {
const response = await this.client.post('/api/auth/login', {
username: this.config.username,
password: this.config.password,
duration_ms: 86400000, // 24 hours
});
if (response.status !== 200) {
throw new Error(`Authentication failed: ${response.statusText}`);
}
const token: AuthToken = response.data;
// Calculate expiration timestamp (subtract 60 seconds for safety margin)
token.expires_at = Date.now() + (token.expires_in * 1000) - 60000;
this.authToken = token;
return token;
}
/**
* Ensure we have a valid authentication token
*/
private async ensureAuthenticated(): Promise<void> {
// Check if token exists and is not expired
if (this.authToken && this.authToken.expires_at && Date.now() < this.authToken.expires_at) {
return; // Token is still valid
}
// Token expired or doesn't exist, authenticate
await this.authenticate();
}
/**
* Test connection to Cobalt Strike server
*/
async testConnection(): Promise<boolean> {
try {
await this.ensureAuthenticated();
// Test with beacons endpoint as version endpoint may not exist
const response = await this.client.get('/api/v1/beacons');
return response.status === 200;
} catch (error) {
return false;
}
}
/**
* Get teamserver information
*/
async getTeamServerInfo(): Promise<TeamServerInfo> {
const response = await this.client.get('/api/v1/info');
if (response.status !== 200) {
throw new Error(`Failed to get teamserver info: ${response.statusText}`);
}
return response.data;
}
/**
* List all beacons
*/
async listBeacons(): Promise<Beacon[]> {
const response = await this.client.get('/api/v1/beacons');
if (response.status !== 200) {
throw new Error(`Failed to list beacons: ${response.statusText}`);
}
// Map API response to our Beacon interface (bid -> id, etc.)
const beacons = Array.isArray(response.data) ? response.data : [];
return beacons.map((beacon: any) => ({
id: beacon.bid || beacon.id || '',
pid: beacon.pid || 0,
arch: beacon.beaconArch || beacon.arch || '',
user: beacon.user || '',
computer: beacon.computer || '',
internal: beacon.internal || '',
external: beacon.external || '',
last: beacon.lastCheckinTime || beacon.last || '',
note: beacon.note || '',
// Include additional fields from API
...beacon,
}));
}
/**
* Get beacon by ID
*/
async getBeacon(beaconId: string): Promise<Beacon> {
const response = await this.client.get(`/api/v1/beacons/${beaconId}`);
if (response.status !== 200) {
throw new Error(`Failed to get beacon: ${response.statusText}`);
}
const beacon = response.data;
// Map API response to our Beacon interface
return {
id: beacon.bid || beacon.id || beaconId,
pid: beacon.pid || 0,
arch: beacon.beaconArch || beacon.arch || '',
user: beacon.user || '',
computer: beacon.computer || '',
internal: beacon.internal || '',
external: beacon.external || '',
last: beacon.lastCheckinTime || beacon.last || '',
note: beacon.note || '',
// Include additional fields from API
...beacon,
};
}
/**
* Execute command on beacon
* Note: Uses execute endpoints for specific commands, or consoleCommand for generic commands
*/
async executeBeaconCommand(beaconId: string, command: string, args?: string[]): Promise<string> {
// Map common commands to their execute endpoints
const executeEndpoints: { [key: string]: string } = {
'ls': '/execute/ls',
'cd': '/execute/cd',
'pwd': '/execute/pwd',
'drives': '/execute/drives',
'cp': '/execute/cp',
'mv': '/execute/mv',
'rm': '/execute/rm',
'mkdir': '/execute/mkdir',
'ps': '/execute/ps',
};
const endpoint = executeEndpoints[command.toLowerCase()];
if (endpoint) {
// Use specific execute endpoint
const payload: any = {};
if (args && args.length > 0) {
if (command.toLowerCase() === 'ls' || command.toLowerCase() === 'cd') {
payload.path = args[0];
} else if (command.toLowerCase() === 'cp' || command.toLowerCase() === 'mv') {
payload.source = args[0];
payload.destination = args[1];
} else if (command.toLowerCase() === 'rm' || command.toLowerCase() === 'mkdir') {
payload.path = args[0];
}
}
const response = await this.client.post(`/api/v1/beacons/${beaconId}${endpoint}`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute command: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
} else {
// Use consoleCommand for generic commands
const payload: any = {
command: command,
};
if (args && args.length > 0) {
payload.arguments = args.join(' ');
}
const response = await this.client.post(`/api/v1/beacons/${beaconId}/consoleCommand`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute command: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
}
/**
* Get beacon task output
*/
async getBeaconTask(beaconId: string, taskId: string): Promise<BeaconTask> {
const response = await this.client.get(`/api/v1/beacons/${beaconId}/tasks/${taskId}`);
if (response.status !== 200) {
throw new Error(`Failed to get task: ${response.statusText}`);
}
return response.data;
}
/**
* List all listeners
*/
async listListeners(): Promise<Listener[]> {
const response = await this.client.get('/api/v1/listeners');
if (response.status !== 200) {
throw new Error(`Failed to list listeners: ${response.statusText}`);
}
return response.data;
}
/**
* Create a new listener
*/
async createListener(name: string, payload: string, port: number, host?: string): Promise<Listener> {
const payload_data: any = {
name: name,
payload: payload,
port: port,
};
if (host) {
payload_data.host = host;
}
const response = await this.client.post('/api/v1/listeners', payload_data);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to create listener: ${response.statusText}`);
}
return response.data;
}
/**
* Delete a listener
*/
async deleteListener(listenerId: string): Promise<boolean> {
const response = await this.client.delete(`/api/v1/listeners/${listenerId}`);
return response.status === 200 || response.status === 204;
}
/**
* Get beacon sessions/interactions
*/
async getBeaconSessions(beaconId: string): Promise<Session[]> {
const response = await this.client.get(`/api/v1/beacons/${beaconId}/sessions`);
if (response.status !== 200) {
throw new Error(`Failed to get sessions: ${response.statusText}`);
}
return response.data;
}
/**
* Kill a beacon
*/
async killBeacon(beaconId: string): Promise<boolean> {
const response = await this.client.delete(`/api/v1/beacons/${beaconId}`);
return response.status === 200 || response.status === 204;
}
/**
* Note a beacon
*/
async noteBeacon(beaconId: string, note: string): Promise<boolean> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/note`, { note });
return response.status === 200;
}
/**
* Get beacon output (console output)
*/
async getBeaconOutput(beaconId: string): Promise<string> {
const response = await this.client.get(`/api/v1/beacons/${beaconId}/output`);
if (response.status !== 200) {
throw new Error(`Failed to get beacon output: ${response.statusText}`);
}
return response.data.output || response.data;
}
/**
* List all credentials
*/
async listCredentials(): Promise<Credential[]> {
const response = await this.client.get('/api/v1/data/credentials');
if (response.status !== 200) {
throw new Error(`Failed to list credentials: ${response.statusText}`);
}
return response.data;
}
/**
* Get credential by ID
*/
async getCredential(credentialId: string): Promise<Credential> {
const response = await this.client.get(`/api/v1/data/credentials/${credentialId}`);
if (response.status !== 200) {
throw new Error(`Failed to get credential: ${response.statusText}`);
}
return response.data;
}
/**
* Create a new credential
*/
async createCredential(
user: string,
password: string,
realm: string,
host?: string,
note?: string,
source?: string
): Promise<Credential> {
const payload: any = {
user,
password,
realm,
};
if (host) payload.host = host;
if (note) payload.note = note;
if (source) payload.source = source;
const response = await this.client.post('/api/v1/data/credentials', payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to create credential: ${response.statusText}`);
}
// Credential creation returns empty body, so we need to find it by listing
// Return a placeholder - the actual ID should be retrieved by listing credentials
const credentials = await this.listCredentials();
const newCred = credentials.find(c => c.user === user && c.realm === realm);
if (newCred) {
return newCred;
}
// Fallback: return the payload with a placeholder ID
return {
id: 'unknown',
user,
password,
realm,
host,
note,
source,
};
}
/**
* Delete a credential
*/
async deleteCredential(credentialId: string): Promise<boolean> {
const response = await this.client.delete(`/api/v1/data/credentials/${credentialId}`);
return response.status === 200 || response.status === 204;
}
/**
* List all tasks (optionally filtered by beacon ID)
*/
async listTasks(beaconId?: string): Promise<TaskSummary[]> {
let url = '/api/v1/tasks';
if (beaconId) {
url = `/api/v1/beacons/${beaconId}/tasks/summary`;
}
const response = await this.client.get(url);
if (response.status !== 200) {
throw new Error(`Failed to list tasks: ${response.statusText}`);
}
return Array.isArray(response.data) ? response.data : [];
}
/**
* Get task by ID
*/
async getTask(taskId: string): Promise<any> {
const response = await this.client.get(`/api/v1/tasks/${taskId}`);
if (response.status !== 200) {
throw new Error(`Failed to get task: ${response.statusText}`);
}
return response.data;
}
/**
* Get task error
*/
async getTaskError(taskId: string): Promise<any> {
const response = await this.client.post(`/api/v1/tasks/${taskId}/error`, {});
if (response.status !== 200) {
throw new Error(`Failed to get task error: ${response.statusText}`);
}
return response.data;
}
/**
* Get task log
*/
async getTaskLog(taskId: string): Promise<any> {
const response = await this.client.post(`/api/v1/tasks/${taskId}/log`, {});
if (response.status !== 200) {
throw new Error(`Failed to get task log: ${response.statusText}`);
}
return response.data;
}
/**
* Get beacon tasks summary
*/
async getBeaconTasksSummary(beaconId: string): Promise<TaskSummary[]> {
const response = await this.client.get(`/api/v1/beacons/${beaconId}/tasks/summary`);
if (response.status !== 200) {
throw new Error(`Failed to get beacon tasks summary: ${response.statusText}`);
}
return Array.isArray(response.data) ? response.data : [];
}
/**
* Get beacon tasks detail
*/
async getBeaconTasksDetail(beaconId: string): Promise<any[]> {
const response = await this.client.get(`/api/v1/beacons/${beaconId}/tasks/detail`);
if (response.status !== 200) {
throw new Error(`Failed to get beacon tasks detail: ${response.statusText}`);
}
return Array.isArray(response.data) ? response.data : [];
}
/**
* Upload file to beacon
*/
async uploadFile(beaconId: string, localPath: string, remotePath: string): Promise<string> {
// Read file from local filesystem
const fs = await import('fs/promises');
const fileContent = await fs.readFile(localPath);
const base64Content = fileContent.toString('base64');
const fileName = localPath.split(/[/\\]/).pop() || 'file';
const payload = {
command: 'upload',
arguments: remotePath,
files: {
[fileName]: base64Content,
},
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/upload`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to upload file: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Download file from beacon
*/
async downloadFile(beaconId: string, remotePath: string): Promise<string> {
const payload = {
path: remotePath,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/download`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to download file: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Spawn a new beacon
*/
async spawnBeacon(beaconId: string, listener: string): Promise<string> {
const payload = {
listener: listener,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/beacon`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn beacon: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Spawn PowerShell command
*/
async spawnPowerShell(beaconId: string, commandlet: string, args?: string): Promise<string> {
const payload: any = {
commandlet: commandlet,
};
if (args) {
payload.arguments = args;
}
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/powershell`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn PowerShell: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Spawn command
*/
async spawnCommand(beaconId: string, command: string, args?: string): Promise<string> {
const payload: any = {
command: command,
};
if (args) {
payload.arguments = args;
}
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/command/run`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn command: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Spawn shell command
*/
async spawnShell(beaconId: string, command: string): Promise<string> {
const payload = {
command: command,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/command/shell`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn shell: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Spawn screenshot
*/
async spawnScreenshot(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/screenshot`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn screenshot: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Spawn hashdump
*/
async spawnHashdump(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/hashdump`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn hashdump: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Spawn Mimikatz
*/
async spawnMimikatz(beaconId: string, command: string): Promise<string> {
const payload = {
command: command,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/mimikatz`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn Mimikatz: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Spawn logon passwords dump
*/
async spawnLogonPasswords(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/logonPasswords`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn logon passwords: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Spawn process list
*/
async spawnProcessList(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/ps`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn process list: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute BOF (Beacon Object File) - string format
* BOF path should be like @artifacts/BOFs/whoami.x64.o or @files/filename.o
*/
async executeBOF(beaconId: string, bofPath: string, bofArgs?: string, files?: { [key: string]: string }): Promise<string> {
const payload: any = {
bof: bofPath,
};
if (bofArgs) {
payload.arguments = bofArgs;
}
if (files) {
payload.files = files;
}
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/bof/string`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute BOF: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Generate stager payload
*/
async generateStagerPayload(
listenerName: string,
architecture: 'x86' | 'x64',
output: string,
payloadFileName?: string
): Promise<PayloadResult> {
const payload: any = {
listenerName,
architecture,
output,
};
if (payloadFileName) {
payload.payloadFileName = payloadFileName;
}
const response = await this.client.post('/api/v1/payloads/generate/stager', payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to generate stager payload: ${response.statusText}`);
}
return response.data;
}
/**
* Generate stageless payload
*/
async generateStagelessPayload(
listenerName: string,
architecture: 'x86' | 'x64',
output: string,
exitFunction: 'Process' | 'Thread',
systemCallMethod: 'None' | 'Direct' | 'Indirect',
useListenerGuardRails: boolean,
payloadFileName?: string,
guardRails?: any
): Promise<PayloadResult> {
const payload: any = {
listenerName,
architecture,
output,
exitFunction,
systemCallMethod,
useListenerGuardRails,
};
if (payloadFileName) {
payload.payloadFileName = payloadFileName;
}
if (!useListenerGuardRails && guardRails) {
payload.guardRails = guardRails;
}
const response = await this.client.post('/api/v1/payloads/generate/stageless', payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to generate stageless payload: ${response.statusText}`);
}
return response.data;
}
/**
* Download payload file
*/
async downloadPayload(fileName: string): Promise<string> {
const response = await this.client.get(`/api/v1/payloads/${fileName}`, {
responseType: 'arraybuffer',
});
if (response.status !== 200) {
throw new Error(`Failed to download payload: ${response.statusText}`);
}
// Convert to base64
const buffer = Buffer.from(response.data);
return buffer.toString('base64');
}
/**
* List all screenshots
*/
async listScreenshots(): Promise<Screenshot[]> {
const response = await this.client.get('/api/v1/data/screenshots');
if (response.status !== 200) {
throw new Error(`Failed to list screenshots: ${response.statusText}`);
}
return Array.isArray(response.data) ? response.data : [];
}
/**
* Get screenshot by ID
*/
async getScreenshot(screenshotId: string): Promise<any> {
const response = await this.client.get(`/api/v1/data/screenshots/${screenshotId}`);
if (response.status !== 200) {
throw new Error(`Failed to get screenshot: ${response.statusText}`);
}
return response.data;
}
/**
* List all keystrokes
*/
async listKeystrokes(): Promise<Keystroke[]> {
const response = await this.client.get('/api/v1/data/keystrokes');
if (response.status !== 200) {
throw new Error(`Failed to list keystrokes: ${response.statusText}`);
}
return Array.isArray(response.data) ? response.data : [];
}
/**
* Get keystrokes by ID
*/
async getKeystrokes(keystrokeId: string): Promise<Keystroke> {
const response = await this.client.get(`/api/v1/data/keystrokes/${keystrokeId}`);
if (response.status !== 200) {
throw new Error(`Failed to get keystrokes: ${response.statusText}`);
}
return response.data;
}
/**
* Get keystrokes for a beacon
*/
async getBeaconKeystrokes(beaconId: string): Promise<Keystroke[]> {
const response = await this.client.get(`/api/v1/beacons/${beaconId}/keystrokes`);
if (response.status !== 200) {
throw new Error(`Failed to get beacon keystrokes: ${response.statusText}`);
}
return Array.isArray(response.data) ? response.data : [];
}
/**
* List all downloads
*/
async listDownloads(): Promise<Download[]> {
const response = await this.client.get('/api/v1/data/downloads');
if (response.status !== 200) {
throw new Error(`Failed to list downloads: ${response.statusText}`);
}
return Array.isArray(response.data) ? response.data : [];
}
/**
* Get download by ID
*/
async getDownload(downloadId: string): Promise<any> {
const response = await this.client.get(`/api/v1/data/downloads/${downloadId}`);
if (response.status !== 200) {
throw new Error(`Failed to get download: ${response.statusText}`);
}
return response.data;
}
/**
* Set beacon sleep time
*/
async setBeaconSleep(beaconId: string, sleep: number, jitter?: number): Promise<boolean> {
const payload: any = {
sleep: sleep,
};
if (jitter !== undefined) {
payload.jitter = jitter;
}
const response = await this.client.post(`/api/v1/beacons/${beaconId}/state/sleepTime`, payload);
return response.status === 200;
}
/**
* Set beacon spawn-to process
*/
async setBeaconSpawnTo(beaconId: string, arch: 'x86' | 'x64', path: string): Promise<boolean> {
const payload = {
arch: arch,
path: path,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/state/spawnto`, payload);
return response.status === 200;
}
async deleteBeaconSpawnTo(beaconId: string): Promise<boolean> {
const response = await this.client.delete(`/api/v1/beacons/${beaconId}/state/spawnto`);
return response.status === 200 || response.status === 204;
}
/**
* Set beacon parent process ID
*/
async setBeaconPPID(beaconId: string, pid: number): Promise<boolean> {
const payload = {
pid: pid,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/state/ppid`, payload);
return response.status === 200;
}
async deleteBeaconPPID(beaconId: string): Promise<boolean> {
const response = await this.client.delete(`/api/v1/beacons/${beaconId}/state/ppid`);
return response.status === 200 || response.status === 204;
}
/**
* Set beacon system call method
*/
async getBeaconSyscallMethod(beaconId: string): Promise<any> {
const response = await this.client.get(`/api/v1/beacons/${beaconId}/state/syscallMethod`);
if (response.status !== 200) {
throw new Error(`Failed to get beacon syscall method: ${response.statusText}`);
}
return response.data;
}
async setBeaconSyscallMethod(beaconId: string, method: 'None' | 'Direct' | 'Indirect'): Promise<boolean> {
const payload = {
method: method,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/state/syscallMethod`, payload);
return response.status === 200;
}
/**
* Get beacon jobs
*/
async getBeaconJobs(beaconId: string): Promise<any> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/state/jobs`, {});
if (response.status !== 200) {
throw new Error(`Failed to get beacon jobs: ${response.statusText}`);
}
return response.data;
}
/**
* Inject DCSync
*/
async injectDCSync(beaconId: string, domain?: string, user?: string): Promise<string> {
const payload: any = {};
if (domain) payload.domain = domain;
if (user) payload.user = user;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/dcsync`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject DCSync: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject net computers
*/
async injectNetComputers(beaconId: string, domain?: string): Promise<string> {
const payload: any = {};
if (domain) payload.domain = domain;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/net/computers`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject net computers: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject net users
*/
async injectNetUsers(beaconId: string, target: string): Promise<string> {
const payload = {
target: target,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/net/user`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject net users: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject net user detail
*/
async injectNetUserDetail(beaconId: string, target: string, user: string): Promise<string> {
const payload = {
target: target,
user: user,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/net/user/detail`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject net user detail: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject net groups
*/
async injectNetGroups(beaconId: string, target: string, groupName: string): Promise<string> {
const payload = {
target: target,
groupName: groupName,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/net/group`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject net groups: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject net sessions
*/
async injectNetSessions(beaconId: string, target: string): Promise<string> {
const payload = {
target: target,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/net/sessions`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject net sessions: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject net shares
*/
async injectNetShares(beaconId: string, target: string): Promise<string> {
const payload = {
target: target,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/net/share`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject net shares: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject net domain controllers
*/
async injectNetDomainControllers(beaconId: string, domain?: string): Promise<string> {
const payload: any = {};
if (domain) payload.domain = domain;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/net/domainControllers`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject net domain controllers: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject portscan
*/
async injectPortscan(beaconId: string, targets: string, ports: string): Promise<string> {
const payload = {
targets: targets,
ports: ports,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/portscan`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject portscan: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject keylogger
*/
async injectKeylogger(beaconId: string, pid: number): Promise<string> {
const payload = {
pid: pid,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/keylogger`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject keylogger: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject chromedump
*/
async injectChromedump(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/chromedump`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject chromedump: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject net view
*/
async injectNetView(beaconId: string, target?: string): Promise<string> {
const payload: any = {};
if (target) payload.target = target;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/net/view`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject net view: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject net logons
*/
async injectNetLogons(beaconId: string, target: string): Promise<string> {
const payload = {
target: target,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/net/logons`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject net logons: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute steal token
*/
async executeStealToken(beaconId: string, pid: number): Promise<string> {
const payload = {
pid: pid,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/stealToken`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute steal token: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute make token
*/
async executeMakeToken(beaconId: string, domain: string, username: string, password: string): Promise<string> {
const payload = {
domain: domain,
username: username,
password: password,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/makeToken/logonName`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute make token: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute rev2self
*/
async executeRev2Self(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/rev2self`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute rev2self: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute get system
*/
async executeGetSystem(beaconId: string, technique?: string): Promise<string> {
const payload: any = {};
if (technique) payload.technique = technique;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/getSystem`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute get system: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute get privs
*/
async executeGetPrivs(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/getPrivs`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute get privs: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute kill process
*/
async executeKillProcess(beaconId: string, pid: number): Promise<string> {
const payload = {
pid: pid,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/killProcess`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute kill process: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute clipboard
*/
async executeClipboard(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/clipboard`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute clipboard: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute setenv
*/
async executeSetEnv(beaconId: string, name: string, value: string): Promise<string> {
const payload = {
name: name,
value: value,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/setenv`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute setenv: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute timestomp
*/
async executeTimestomp(beaconId: string, file: string, accessTime?: string, modifyTime?: string): Promise<string> {
const payload: any = {
file: file,
};
if (accessTime) payload.accessTime = accessTime;
if (modifyTime) payload.modifyTime = modifyTime;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/timestomp`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute timestomp: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute checkin
*/
async executeCheckIn(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/checkIn`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute checkin: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute exit
*/
async executeExit(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/exit`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute exit: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute reg query
*/
async executeRegQuery(beaconId: string, path: string): Promise<string> {
const payload = {
path: path,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/reg/query`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute reg query: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute reg queryv
*/
async executeRegQueryV(beaconId: string, path: string, value: string): Promise<string> {
const payload = {
path: path,
value: value,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/reg/queryv`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute reg queryv: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute SOCKS4 start
*/
async executeSOCKS4Start(beaconId: string, port: number): Promise<string> {
const payload = {
port: port,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/socks4Start`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute SOCKS4 start: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute SOCKS5 start
*/
async executeSOCKS5Start(beaconId: string, port: number): Promise<string> {
const payload = {
port: port,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/socks5Start`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute SOCKS5 start: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute SOCKS stop
*/
async executeSOCKSStop(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/socksStop/onTeamserver`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute SOCKS stop: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute link SMB
*/
async executeLinkSMB(beaconId: string, target: string, pipe?: string): Promise<string> {
const payload: any = {
target: target,
};
if (pipe) payload.pipe = pipe;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/link/smb`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute link SMB: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute link TCP
*/
async executeLinkTCP(beaconId: string, target: string, port: number): Promise<string> {
const payload = {
target: target,
port: port,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/link/tcp`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute link TCP: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute unlink
*/
async executeUnlink(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/unlink`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute unlink: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute reverse port forward start
*/
async executeRPortFwdStart(beaconId: string, bindPort: number, forwardHost: string, forwardPort: number): Promise<string> {
const payload = {
bindPort: bindPort,
forwardHost: forwardHost,
forwardPort: forwardPort,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/rportfwdStart/onTeamserver`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute rportfwd start: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute reverse port forward stop
*/
async executeRPortFwdStop(beaconId: string, bindPort: number): Promise<string> {
const payload = {
bindPort: bindPort,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/rportfwdStop/onTeamserver`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute rportfwd stop: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Set beacon DNS mode
*/
async setBeaconDNSMode(beaconId: string, mode: 'auto' | 'dns' | 'dns6'): Promise<boolean> {
const payload = {
mode: mode,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/state/dnsMode`, payload);
return response.status === 200;
}
/**
* Set beacon block DLLs
*/
async setBeaconBlockDLLs(beaconId: string, enable: boolean): Promise<boolean> {
const endpoint = enable ? 'enable' : 'disable';
const response = await this.client.post(`/api/v1/beacons/${beaconId}/state/blockdlls/${endpoint}`, {});
return response.status === 200;
}
/**
* Set beacon beacon gate
*/
async setBeaconBeaconGate(beaconId: string, enable: boolean): Promise<boolean> {
const endpoint = enable ? 'enable' : 'disable';
const response = await this.client.post(`/api/v1/beacons/${beaconId}/state/beaconGate/${endpoint}`, {});
return response.status === 200;
}
/**
* Get system information
*/
async getSystemInformation(): Promise<any> {
const response = await this.client.get('/api/v1/config/systeminformation');
if (response.status !== 200) {
throw new Error(`Failed to get system information: ${response.statusText}`);
}
return response.data;
}
/**
* Get profile
*/
async getProfile(): Promise<string> {
const response = await this.client.get('/api/v1/config/profile');
if (response.status !== 200) {
throw new Error(`Failed to get profile: ${response.statusText}`);
}
return response.data.profile || response.data || '';
}
/**
* Update profile
*/
async updateProfile(profile: string): Promise<boolean> {
const payload = {
profile: profile,
};
const response = await this.client.put('/api/v1/config/profile', payload);
return response.status === 200;
}
/**
* Get killdate
*/
async getKilldate(): Promise<string> {
const response = await this.client.get('/api/v1/config/killdate');
if (response.status !== 200) {
throw new Error(`Failed to get killdate: ${response.statusText}`);
}
return response.data.killdate || response.data || '';
}
/**
* Set killdate
*/
async setKilldate(killdate: string): Promise<boolean> {
const payload = {
killdate: killdate,
};
const response = await this.client.put('/api/v1/config/killdate', payload);
return response.status === 200;
}
/**
* Get teamserver IP
*/
async getTeamserverIP(): Promise<string> {
const response = await this.client.get('/api/v1/config/teamserverIp');
if (response.status !== 200) {
throw new Error(`Failed to get teamserver IP: ${response.statusText}`);
}
return response.data.ip || response.data.teamserverIp || response.data || '';
}
/**
* Set teamserver IP
*/
async setTeamserverIP(ip: string): Promise<boolean> {
const payload = {
ip: ip,
};
const response = await this.client.put('/api/v1/config/teamserverIp', payload);
return response.status === 200;
}
/**
* Reset data
*/
async resetData(): Promise<boolean> {
const response = await this.client.delete('/api/v1/config/resetData');
return response.status === 200 || response.status === 204;
}
// ========== Token Store Operations ==========
/**
* Execute token store use
*/
async executeTokenStoreUse(beaconId: string, tokenId: string): Promise<string> {
const payload = {
tokenId: tokenId,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/tokenStore/use`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to use token: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute token store steal
*/
async executeTokenStoreSteal(beaconId: string, pid: number): Promise<string> {
const payload = {
pid: pid,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/tokenStore/steal`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to steal token: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute token store steal and use
*/
async executeTokenStoreStealAndUse(beaconId: string, pid: number): Promise<string> {
const payload = {
pid: pid,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/tokenStore/stealAndUse`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to steal and use token: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute token store remove
*/
async executeTokenStoreRemove(beaconId: string, tokenId: string): Promise<string> {
const payload = {
tokenId: tokenId,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/tokenStore/remove`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to remove token: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute token store remove all
*/
async executeTokenStoreRemoveAll(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/tokenStore/removeAll`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to remove all tokens: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute make token UPN
*/
async executeMakeTokenUPN(beaconId: string, upn: string, password: string): Promise<string> {
const payload = {
upn: upn,
password: password,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/makeToken/upn`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to make token (UPN): ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
// ========== Advanced Inject Operations ==========
/**
* Inject beacon
*/
async injectBeacon(beaconId: string, pid: number, listener: string): Promise<string> {
const payload = {
pid: pid,
listener: listener,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/beacon`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject beacon: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject DLL
*/
async injectDLL(beaconId: string, pid: number, dllPath: string): Promise<string> {
const payload = {
pid: pid,
dllPath: dllPath,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/dll`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject DLL: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject shellcode
*/
async injectShellcode(beaconId: string, pid: number, shellcode: string): Promise<string> {
const payload = {
pid: pid,
shellcode: shellcode,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/shellcode`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject shellcode: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject Mimikatz
*/
async injectMimikatz(beaconId: string, command: string): Promise<string> {
const payload = {
command: command,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/mimikatz`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject Mimikatz: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject hashdump
*/
async injectHashdump(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/hashdump`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject hashdump: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject logon passwords
*/
async injectLogonPasswords(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/logonPasswords`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject logon passwords: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
// ========== Advanced Spawn Operations ==========
/**
* Spawn beacon as user
*/
async spawnBeaconAsUser(beaconId: string, listener: string, domain: string, username: string, password: string): Promise<string> {
const payload = {
listener: listener,
domain: domain,
username: username,
password: password,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/beacon/asUser`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn beacon as user: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Spawn beacon under process
*/
async spawnBeaconUnder(beaconId: string, listener: string, pid: number): Promise<string> {
const payload = {
listener: listener,
pid: pid,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/beacon/under`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn beacon under process: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Spawn command run as
*/
async spawnCommandRunAs(beaconId: string, command: string, domain: string, username: string, password: string): Promise<string> {
const payload = {
command: command,
domain: domain,
username: username,
password: password,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/command/runAs`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn command run as: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Spawn DCSync
*/
async spawnDCSync(beaconId: string, domain?: string, user?: string): Promise<string> {
const payload: any = {};
if (domain) payload.domain = domain;
if (user) payload.user = user;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/dcsync`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn DCSync: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Spawn keylogger
*/
async spawnKeylogger(beaconId: string, pid: number): Promise<string> {
const payload = {
pid: pid,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/keylogger`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn keylogger: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
// ========== Elevate Operations ==========
/**
* Get elevate beacon info
*/
async getElevateBeacon(beaconId: string): Promise<any> {
const response = await this.client.get(`/api/v1/beacons/${beaconId}/elevate/beacon`);
if (response.status !== 200) {
throw new Error(`Failed to get elevate beacon: ${response.statusText}`);
}
return response.data;
}
/**
* Elevate beacon
*/
async elevateBeacon(beaconId: string, listener: string, technique?: string): Promise<string> {
const payload: any = {
listener: listener,
};
if (technique) payload.technique = technique;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/elevate/beacon`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to elevate beacon: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Get elevate command info
*/
async getElevateCommand(beaconId: string): Promise<any> {
const response = await this.client.get(`/api/v1/beacons/${beaconId}/elevate/command`);
if (response.status !== 200) {
throw new Error(`Failed to get elevate command: ${response.statusText}`);
}
return response.data;
}
/**
* Elevate command
*/
async elevateCommand(beaconId: string, command: string, technique?: string): Promise<string> {
const payload: any = {
command: command,
};
if (technique) payload.technique = technique;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/elevate/command`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to elevate command: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
// ========== Remote Exec Operations ==========
/**
* Get remote exec beacon info
*/
async getRemoteExecBeacon(beaconId: string): Promise<any> {
const response = await this.client.get(`/api/v1/beacons/${beaconId}/remoteExec/beacon`);
if (response.status !== 200) {
throw new Error(`Failed to get remote exec beacon: ${response.statusText}`);
}
return response.data;
}
/**
* Remote exec beacon
*/
async remoteExecBeacon(beaconId: string, target: string, listener: string): Promise<string> {
const payload = {
target: target,
listener: listener,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/remoteExec/beacon`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to remote exec beacon: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Get remote exec command info
*/
async getRemoteExecCommand(beaconId: string): Promise<any> {
const response = await this.client.get(`/api/v1/beacons/${beaconId}/remoteExec/command`);
if (response.status !== 200) {
throw new Error(`Failed to get remote exec command: ${response.statusText}`);
}
return response.data;
}
/**
* Remote exec command
*/
async remoteExecCommand(beaconId: string, target: string, command: string): Promise<string> {
const payload = {
target: target,
command: command,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/remoteExec/command`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to remote exec command: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
// ========== Listener-Specific Operations ==========
/**
* Create HTTP listener
*/
async createListenerHTTP(name: string, port: number, host?: string): Promise<any> {
const payload: any = {
name: name,
port: port,
};
if (host) payload.host = host;
const response = await this.client.post('/api/v1/listeners/http', payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to create HTTP listener: ${response.statusText}`);
}
return response.data;
}
/**
* Get HTTP listener
*/
async getListenerHTTP(name: string): Promise<any> {
const response = await this.client.get(`/api/v1/listeners/http/${name}`);
if (response.status !== 200) {
throw new Error(`Failed to get HTTP listener: ${response.statusText}`);
}
return response.data;
}
/**
* Update HTTP listener
*/
async updateListenerHTTP(name: string, port?: number, host?: string): Promise<boolean> {
const payload: any = {};
if (port !== undefined) payload.port = port;
if (host !== undefined) payload.host = host;
const response = await this.client.put(`/api/v1/listeners/http/${name}`, payload);
return response.status === 200;
}
/**
* Delete HTTP listener
*/
async deleteListenerHTTP(name: string): Promise<boolean> {
const response = await this.client.delete(`/api/v1/listeners/http/${name}`);
return response.status === 200 || response.status === 204;
}
/**
* Create HTTPS listener
*/
async createListenerHTTPS(name: string, port: number, host?: string): Promise<any> {
const payload: any = {
name: name,
port: port,
};
if (host) payload.host = host;
const response = await this.client.post('/api/v1/listeners/https', payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to create HTTPS listener: ${response.statusText}`);
}
return response.data;
}
/**
* Get HTTPS listener
*/
async getListenerHTTPS(name: string): Promise<any> {
const response = await this.client.get(`/api/v1/listeners/https/${name}`);
if (response.status !== 200) {
throw new Error(`Failed to get HTTPS listener: ${response.statusText}`);
}
return response.data;
}
/**
* Update HTTPS listener
*/
async updateListenerHTTPS(name: string, port?: number, host?: string): Promise<boolean> {
const payload: any = {};
if (port !== undefined) payload.port = port;
if (host !== undefined) payload.host = host;
const response = await this.client.put(`/api/v1/listeners/https/${name}`, payload);
return response.status === 200;
}
/**
* Delete HTTPS listener
*/
async deleteListenerHTTPS(name: string): Promise<boolean> {
const response = await this.client.delete(`/api/v1/listeners/https/${name}`);
return response.status === 200 || response.status === 204;
}
/**
* Create DNS listener
*/
async createListenerDNS(name: string, host: string): Promise<any> {
const payload = {
name: name,
host: host,
};
const response = await this.client.post('/api/v1/listeners/dns', payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to create DNS listener: ${response.statusText}`);
}
return response.data;
}
/**
* Get DNS listener
*/
async getListenerDNS(name: string): Promise<any> {
const response = await this.client.get(`/api/v1/listeners/dns/${name}`);
if (response.status !== 200) {
throw new Error(`Failed to get DNS listener: ${response.statusText}`);
}
return response.data;
}
/**
* Update DNS listener
*/
async updateListenerDNS(name: string, host?: string): Promise<boolean> {
const payload: any = {};
if (host !== undefined) payload.host = host;
const response = await this.client.put(`/api/v1/listeners/dns/${name}`, payload);
return response.status === 200;
}
/**
* Delete DNS listener
*/
async deleteListenerDNS(name: string): Promise<boolean> {
const response = await this.client.delete(`/api/v1/listeners/dns/${name}`);
return response.status === 200 || response.status === 204;
}
/**
* Create SMB listener
*/
async createListenerSMB(name: string, pipe?: string): Promise<any> {
const payload: any = {
name: name,
};
if (pipe) payload.pipe = pipe;
const response = await this.client.post('/api/v1/listeners/smb', payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to create SMB listener: ${response.statusText}`);
}
return response.data;
}
/**
* Get SMB listener
*/
async getListenerSMB(name: string): Promise<any> {
const response = await this.client.get(`/api/v1/listeners/smb/${name}`);
if (response.status !== 200) {
throw new Error(`Failed to get SMB listener: ${response.statusText}`);
}
return response.data;
}
/**
* Update SMB listener
*/
async updateListenerSMB(name: string, pipe?: string): Promise<boolean> {
const payload: any = {};
if (pipe !== undefined) payload.pipe = pipe;
const response = await this.client.put(`/api/v1/listeners/smb/${name}`, payload);
return response.status === 200;
}
/**
* Delete SMB listener
*/
async deleteListenerSMB(name: string): Promise<boolean> {
const response = await this.client.delete(`/api/v1/listeners/smb/${name}`);
return response.status === 200 || response.status === 204;
}
/**
* Create TCP listener
*/
async createListenerTCP(name: string, port: number, host?: string): Promise<any> {
const payload: any = {
name: name,
port: port,
};
if (host) payload.host = host;
const response = await this.client.post('/api/v1/listeners/tcp', payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to create TCP listener: ${response.statusText}`);
}
return response.data;
}
/**
* Get TCP listener
*/
async getListenerTCP(name: string): Promise<any> {
const response = await this.client.get(`/api/v1/listeners/tcp/${name}`);
if (response.status !== 200) {
throw new Error(`Failed to get TCP listener: ${response.statusText}`);
}
return response.data;
}
/**
* Update TCP listener
*/
async updateListenerTCP(name: string, port?: number, host?: string): Promise<boolean> {
const payload: any = {};
if (port !== undefined) payload.port = port;
if (host !== undefined) payload.host = host;
const response = await this.client.put(`/api/v1/listeners/tcp/${name}`, payload);
return response.status === 200;
}
/**
* Delete TCP listener
*/
async deleteListenerTCP(name: string): Promise<boolean> {
const response = await this.client.delete(`/api/v1/listeners/tcp/${name}`);
return response.status === 200 || response.status === 204;
}
/**
* Create ExternalC2 listener
*/
async createListenerExternalC2(name: string, config?: string): Promise<any> {
const payload: any = {
name: name,
};
if (config) {
try {
payload.config = JSON.parse(config);
} catch {
payload.config = config;
}
}
const response = await this.client.post('/api/v1/listeners/externalC2', payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to create ExternalC2 listener: ${response.statusText}`);
}
return response.data;
}
/**
* Get ExternalC2 listener
*/
async getListenerExternalC2(name: string): Promise<any> {
const response = await this.client.get(`/api/v1/listeners/externalC2/${name}`);
if (response.status !== 200) {
throw new Error(`Failed to get ExternalC2 listener: ${response.statusText}`);
}
return response.data;
}
/**
* Update ExternalC2 listener
*/
async updateListenerExternalC2(name: string, config?: string): Promise<boolean> {
const payload: any = {};
if (config !== undefined) {
try {
payload.config = JSON.parse(config);
} catch {
payload.config = config;
}
}
const response = await this.client.put(`/api/v1/listeners/externalC2/${name}`, payload);
return response.status === 200;
}
/**
* Delete ExternalC2 listener
*/
async deleteListenerExternalC2(name: string): Promise<boolean> {
const response = await this.client.delete(`/api/v1/listeners/externalC2/${name}`);
return response.status === 200 || response.status === 204;
}
// ========== Advanced State Management ==========
/**
* Set beacon C2 host
*/
async getBeaconC2Host(beaconId: string): Promise<any> {
const response = await this.client.get(`/api/v1/beacons/${beaconId}/state/c2/host`);
if (response.status !== 200) {
throw new Error(`Failed to get beacon C2 host: ${response.statusText}`);
}
return response.data;
}
async setBeaconC2Host(beaconId: string, host: string): Promise<boolean> {
const payload = {
host: host,
};
const response = await this.client.put(`/api/v1/beacons/${beaconId}/state/c2/host`, payload);
return response.status === 200;
}
async postBeaconC2Host(beaconId: string, host: string): Promise<boolean> {
const payload = {
host: host,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/state/c2/host`, payload);
return response.status === 200;
}
async deleteBeaconC2Host(beaconId: string): Promise<boolean> {
const response = await this.client.delete(`/api/v1/beacons/${beaconId}/state/c2/host`);
return response.status === 200 || response.status === 204;
}
/**
* Hold C2 host
*/
async setBeaconC2HostHold(beaconId: string): Promise<boolean> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/state/c2/host/hold`, {});
return response.status === 200;
}
/**
* Release C2 host
*/
async setBeaconC2HostRelease(beaconId: string): Promise<boolean> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/state/c2/host/release`, {});
return response.status === 200;
}
/**
* Reset C2 host
*/
async setBeaconC2HostReset(beaconId: string): Promise<boolean> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/state/c2/host/reset`, {});
return response.status === 200;
}
/**
* Get C2 host profiles
*/
async getBeaconC2HostProfiles(beaconId: string): Promise<any> {
const response = await this.client.get(`/api/v1/beacons/${beaconId}/state/c2/host/profiles`);
if (response.status !== 200) {
throw new Error(`Failed to get C2 host profiles: ${response.statusText}`);
}
return response.data;
}
/**
* Set spoofed arguments
*/
async getBeaconSpoofedArguments(beaconId: string): Promise<any> {
const response = await this.client.get(`/api/v1/beacons/${beaconId}/state/spoofedArguments`);
if (response.status !== 200) {
throw new Error(`Failed to get beacon spoofed arguments: ${response.statusText}`);
}
return response.data;
}
async setBeaconSpoofedArguments(beaconId: string, arguments_: string): Promise<boolean> {
const payload = {
arguments: arguments_,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/state/spoofedArguments`, payload);
return response.status === 200;
}
async deleteBeaconSpoofedArguments(beaconId: string): Promise<boolean> {
const response = await this.client.delete(`/api/v1/beacons/${beaconId}/state/spoofedArguments`);
return response.status === 200 || response.status === 204;
}
/**
* Set C2 failover notification
*/
async setBeaconC2FailoverNotification(beaconId: string, enable: boolean): Promise<boolean> {
const endpoint = enable ? 'enable' : 'disable';
const response = await this.client.post(`/api/v1/beacons/${beaconId}/state/c2/failoverNotification/${endpoint}`, {});
return response.status === 200;
}
// ========== Additional Inject Operations ==========
/**
* Inject PowerShell unmanaged
*/
async injectPowerShellUnmanaged(beaconId: string, command: string): Promise<string> {
const payload = {
command: command,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/powershell/unmanaged`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject PowerShell unmanaged: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject screenshot
*/
async injectScreenshot(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/screenshot`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject screenshot: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject printscreen
*/
async injectPrintscreen(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/printscreen`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject printscreen: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject screenwatch
*/
async injectScreenwatch(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/screenwatch`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject screenwatch: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject browser pivot start
*/
async injectBrowserPivotStart(beaconId: string, pid: number): Promise<string> {
const payload = {
pid: pid,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/browserpivotStart`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject browser pivot start: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject SSH
*/
async injectSSH(beaconId: string, host: string, port: number, username: string, password: string): Promise<string> {
const payload = {
host: host,
port: port,
username: username,
password: password,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/ssh`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject SSH: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject SSH key
*/
async injectSSHKey(beaconId: string, host: string, port: number, username: string, key: string): Promise<string> {
const payload = {
host: host,
port: port,
username: username,
key: key,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/sshKey`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject SSH key: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject PTH (Pass-the-Hash)
*/
async injectPTH(beaconId: string, domain: string, username: string, hash: string): Promise<string> {
const payload = {
domain: domain,
username: username,
hash: hash,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/pth`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject PTH: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject post-ex DLL
*/
async injectPostExDll(beaconId: string, dllPath: string): Promise<string> {
const payload = {
dllPath: dllPath,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/postExDll`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject post-ex DLL: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject load DLL
*/
async injectLoadDll(beaconId: string, dllPath: string): Promise<string> {
const payload = {
dllPath: dllPath,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/loadDll`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject load DLL: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject net dclist
*/
async injectNetDclist(beaconId: string, domain?: string): Promise<string> {
const payload: any = {};
if (domain) payload.domain = domain;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/net/dclist`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject net dclist: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject net domain trusts
*/
async injectNetDomainTrusts(beaconId: string, domain?: string): Promise<string> {
const payload: any = {};
if (domain) payload.domain = domain;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/net/domainTrusts`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject net domain trusts: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject net local group
*/
async injectNetLocalGroup(beaconId: string, target: string, groupName: string): Promise<string> {
const payload = {
target: target,
groupName: groupName,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/net/localGroup`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject net local group: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Inject net time
*/
async injectNetTime(beaconId: string, target: string): Promise<string> {
const payload = {
target: target,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/inject/net/time`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to inject net time: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
// ========== Additional Execute Operations ==========
/**
* Execute beacon info
*/
async executeBeaconInfo(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/beaconInfo`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute beacon info: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute get UID
*/
async executeGetUid(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/getUid`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute get UID: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute job stop
*/
async executeJobStop(beaconId: string, jobId: string): Promise<string> {
const payload = {
jobId: jobId,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/jobStop`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute job stop: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute Kerberos ticket purge
*/
async executeKerberosTicketPurge(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/kerberos/ticket/purge`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute Kerberos ticket purge: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute Kerberos ticket use
*/
async executeKerberosTicketUse(beaconId: string, ticket: string): Promise<string> {
const payload = {
ticket: ticket,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/kerberos/ticket/use`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute Kerberos ticket use: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute PowerShell import
*/
async executePowerShellImport(beaconId: string, module: string): Promise<string> {
const payload = {
module: module,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/powershell/import`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute PowerShell import: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute net domain
*/
async executeNetDomain(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/net/domain`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute net domain: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute browser pivot stop
*/
async executeBrowserPivotStop(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/browserpivotStop`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute browser pivot stop: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute cancel file download
*/
async executeCancelFileDownload(beaconId: string, fileId: string): Promise<string> {
const payload = {
fileId: fileId,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/cancelFileDownload`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute cancel file download: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute SOCKS stop all
*/
async executeSOCKSStopAll(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/socksStop/all`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute SOCKS stop all: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
/**
* Execute SOCKS stop port
*/
async executeSOCKSStopPort(beaconId: string, port: number): Promise<string> {
const payload = {
port: port,
};
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/socksStop/${port}`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute SOCKS stop port: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
// ========== Utility Operations ==========
/**
* Get artifacts
*/
async getArtifacts(): Promise<any> {
const response = await this.client.get('/api/v1/artifacts');
if (response.status !== 200) {
throw new Error(`Failed to get artifacts: ${response.statusText}`);
}
return response.data;
}
/**
* Get beacon active downloads
*/
async getBeaconActiveDownloads(beaconId: string): Promise<any> {
const response = await this.client.get(`/api/v1/beacons/${beaconId}/activeDownloads`);
if (response.status !== 200) {
throw new Error(`Failed to get active downloads: ${response.statusText}`);
}
return response.data;
}
/**
* Clear beacon command queue
*/
async clearBeaconCommandQueue(beaconId: string): Promise<boolean> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/clearCommandQueue`, {});
return response.status === 200 || response.status === 201;
}
/**
* Get beacon help
*/
async getBeaconHelp(beaconId: string): Promise<any> {
const response = await this.client.get(`/api/v1/beacons/${beaconId}/help`);
if (response.status !== 200) {
throw new Error(`Failed to get beacon help: ${response.statusText}`);
}
return response.data;
}
/**
* Get beacon command help
*/
async getBeaconCommandHelp(beaconId: string, command: string): Promise<any> {
const response = await this.client.get(`/api/v1/beacons/${beaconId}/help/${command}`);
if (response.status !== 200) {
throw new Error(`Failed to get beacon command help: ${response.statusText}`);
}
return response.data;
}
// ========== Additional Spawn Operations ==========
async spawnCommandRunNoOutput(beaconId: string, command: string): Promise<string> {
const payload = { command };
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/command/runNoOutput`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn command runNoOutput: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnCommandRunUnder(beaconId: string, command: string, pid: number): Promise<string> {
const payload = { command, pid };
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/command/runUnder`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn command runUnder: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnChromedump(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/chromedump`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn chromedump: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnDotnetAssembly(beaconId: string, assembly: string, arguments_?: string): Promise<string> {
const payload: any = { assembly };
if (arguments_) payload.arguments = arguments_;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/dotnetAssembly`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn dotnet assembly: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnNetComputers(beaconId: string, domain?: string): Promise<string> {
const payload: any = {};
if (domain) payload.domain = domain;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/net/computers`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn net computers: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnNetDclist(beaconId: string, domain?: string): Promise<string> {
const payload: any = {};
if (domain) payload.domain = domain;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/net/dclist`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn net dclist: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnNetDomainControllers(beaconId: string, domain?: string): Promise<string> {
const payload: any = {};
if (domain) payload.domain = domain;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/net/domainControllers`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn net domain controllers: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnNetDomainTrusts(beaconId: string, domain?: string): Promise<string> {
const payload: any = {};
if (domain) payload.domain = domain;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/net/domainTrusts`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn net domain trusts: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnNetGroup(beaconId: string, target: string, groupName: string): Promise<string> {
const payload = { target, groupName };
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/net/group`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn net group: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnNetLocalGroup(beaconId: string, target: string, groupName: string): Promise<string> {
const payload = { target, groupName };
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/net/localGroup`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn net local group: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnNetLogons(beaconId: string, target: string): Promise<string> {
const payload = { target };
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/net/logons`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn net logons: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnNetSessions(beaconId: string, target: string): Promise<string> {
const payload = { target };
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/net/sessions`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn net sessions: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnNetShare(beaconId: string, target: string): Promise<string> {
const payload = { target };
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/net/share`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn net share: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnNetTime(beaconId: string, target: string): Promise<string> {
const payload = { target };
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/net/time`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn net time: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnNetUser(beaconId: string, target?: string): Promise<string> {
const payload: any = {};
if (target) payload.target = target;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/net/user`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn net user: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnNetUserDetail(beaconId: string, target: string, user: string): Promise<string> {
const payload = { target, user };
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/net/user/detail`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn net user detail: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnNetView(beaconId: string, target?: string): Promise<string> {
const payload: any = {};
if (target) payload.target = target;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/net/view`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn net view: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnPortscan(beaconId: string, targets: string, ports: string): Promise<string> {
const payload = { targets, ports };
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/portscan`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn portscan: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnPostExDll(beaconId: string, dllPath: string): Promise<string> {
const payload = { dllPath };
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/postExDll`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn postExDll: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnPowerShellUnmanaged(beaconId: string, command: string): Promise<string> {
const payload = { command };
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/powershell/unmanaged`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn PowerShell unmanaged: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnPrintscreen(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/printscreen`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn printscreen: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnPTH(beaconId: string, domain: string, username: string, hash: string): Promise<string> {
const payload = { domain, username, hash };
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/pth`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn PTH: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnScreenwatch(beaconId: string): Promise<string> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/screenwatch`, {});
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn screenwatch: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnShellcode(beaconId: string, shellcode: string): Promise<string> {
const payload = { shellcode };
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/shellcode`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn shellcode: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnSSH(beaconId: string, host: string, port: number, username: string, password: string): Promise<string> {
const payload = { host, port, username, password };
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/ssh`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn SSH: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async spawnSSHKey(beaconId: string, host: string, port: number, username: string, key: string): Promise<string> {
const payload = { host, port, username, key };
const response = await this.client.post(`/api/v1/beacons/${beaconId}/spawn/sshKey`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to spawn SSH key: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
// ========== BOF Pack/Packed Operations ==========
async executeBOFPack(beaconId: string, bofPath: string, arguments_?: string): Promise<string> {
const payload: any = { bofPath };
if (arguments_) payload.arguments = arguments_;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/bof/pack`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute BOF pack: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
async executeBOFPacked(beaconId: string, bofPath: string, arguments_?: string): Promise<string> {
const payload: any = { bofPath };
if (arguments_) payload.arguments = arguments_;
const response = await this.client.post(`/api/v1/beacons/${beaconId}/execute/bof/packed`, payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to execute BOF packed: ${response.statusText}`);
}
return response.data.taskId || response.data.task_id || response.data.id || '';
}
// ========== Additional Listener Operations ==========
async createListenerForeignHTTP(name: string, host: string, port: number): Promise<any> {
const payload = { name, host, port };
const response = await this.client.post('/api/v1/listeners/foreignHttp', payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to create Foreign HTTP listener: ${response.statusText}`);
}
return response.data;
}
async getListenerForeignHTTP(name: string): Promise<any> {
const response = await this.client.get(`/api/v1/listeners/foreignHttp/${name}`);
if (response.status !== 200) {
throw new Error(`Failed to get Foreign HTTP listener: ${response.statusText}`);
}
return response.data;
}
async updateListenerForeignHTTP(name: string, host?: string, port?: number): Promise<boolean> {
const payload: any = {};
if (host !== undefined) payload.host = host;
if (port !== undefined) payload.port = port;
const response = await this.client.put(`/api/v1/listeners/foreignHttp/${name}`, payload);
return response.status === 200;
}
async deleteListenerForeignHTTP(name: string): Promise<boolean> {
const response = await this.client.delete(`/api/v1/listeners/foreignHttp/${name}`);
return response.status === 200 || response.status === 204;
}
async createListenerForeignHTTPS(name: string, host: string, port: number): Promise<any> {
const payload = { name, host, port };
const response = await this.client.post('/api/v1/listeners/foreignHttps', payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to create Foreign HTTPS listener: ${response.statusText}`);
}
return response.data;
}
async getListenerForeignHTTPS(name: string): Promise<any> {
const response = await this.client.get(`/api/v1/listeners/foreignHttps/${name}`);
if (response.status !== 200) {
throw new Error(`Failed to get Foreign HTTPS listener: ${response.statusText}`);
}
return response.data;
}
async updateListenerForeignHTTPS(name: string, host?: string, port?: number): Promise<boolean> {
const payload: any = {};
if (host !== undefined) payload.host = host;
if (port !== undefined) payload.port = port;
const response = await this.client.put(`/api/v1/listeners/foreignHttps/${name}`, payload);
return response.status === 200;
}
async deleteListenerForeignHTTPS(name: string): Promise<boolean> {
const response = await this.client.delete(`/api/v1/listeners/foreignHttps/${name}`);
return response.status === 200 || response.status === 204;
}
async createListenerUserDefinedC2(name: string, config?: string): Promise<any> {
const payload: any = { name };
if (config) {
try {
payload.config = JSON.parse(config);
} catch {
payload.config = config;
}
}
const response = await this.client.post('/api/v1/listeners/userDefinedC2', payload);
if (response.status !== 200 && response.status !== 201) {
throw new Error(`Failed to create User-Defined C2 listener: ${response.statusText}`);
}
return response.data;
}
async getListenerUserDefinedC2(name: string): Promise<any> {
const response = await this.client.get(`/api/v1/listeners/userDefinedC2/${name}`);
if (response.status !== 200) {
throw new Error(`Failed to get User-Defined C2 listener: ${response.statusText}`);
}
return response.data;
}
async updateListenerUserDefinedC2(name: string, config?: string): Promise<boolean> {
const payload: any = {};
if (config !== undefined) {
try {
payload.config = JSON.parse(config);
} catch {
payload.config = config;
}
}
const response = await this.client.put(`/api/v1/listeners/userDefinedC2/${name}`, payload);
return response.status === 200;
}
async deleteListenerUserDefinedC2(name: string): Promise<boolean> {
const response = await this.client.delete(`/api/v1/listeners/userDefinedC2/${name}`);
return response.status === 200 || response.status === 204;
}
async getListener(name: string): Promise<any> {
const response = await this.client.get(`/api/v1/listeners/${name}`);
if (response.status !== 200) {
throw new Error(`Failed to get listener: ${response.statusText}`);
}
return response.data;
}
async deleteListenerByName(name: string): Promise<boolean> {
const response = await this.client.delete(`/api/v1/listeners/${name}`);
return response.status === 200 || response.status === 204;
}
// ========== Additional State Operations ==========
async getBeaconTokenStore(beaconId: string): Promise<any> {
const response = await this.client.post(`/api/v1/beacons/${beaconId}/state/tokenStore`, {});
if (response.status !== 200) {
throw new Error(`Failed to get beacon token store: ${response.statusText}`);
}
return response.data;
}
}