Skip to content
This repository has been archived by the owner on Oct 20, 2023. It is now read-only.

Sliver 1.6 parser (alpha) and sample dataset #190

Merged
merged 7 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .moon/tasks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ tasks:
runDepsInParallel: false
runInCI: false
build-client-library:
command: 'tsup-node ./src/index.ts --minify --format esm'
command: 'tsc --project tsconfig.json --module esnext --sourceMap --outDir @out(0)'
inputs:
- '@globs(sources)'
- '@globs(assets)'
Expand All @@ -189,7 +189,7 @@ tasks:
runDepsInParallel: false
runInCI: false
watch-library:
command: 'tsup-node ./src/index.ts --watch --clean --minify --format esm'
command: 'tsc-watch --project tsconfig.json --module esnext --sourceMap --outDir @out(0)'
inputs:
- '@globs(sources)'
- '@globs(assets)'
Expand Down Expand Up @@ -238,7 +238,7 @@ tasks:
start-node:
env:
NODE_ENV: development
command: 'tsup-node src --clean --splitting --sourcemap --watch --onSuccess "yarn node --enable-source-maps dist" --ignore-watch "src/**/*.test.ts"'
command: 'tsc-watch --project tsconfig.json --module commonjs --sourceMap --outDir dist --onSuccess "yarn node --enable-source-maps dist"'
inputs:
- '@globs(sources)'
- '@globs(tests)'
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{"time":"2023-09-20T06:51:01.285066093Z","level":"DEBUG","msg":"http","type":"command"}
{"time":"2023-09-20T06:51:01.28839426Z","level":"INFO","msg":"Starting HTTP :80 listener ...\n"}
{"time":"2023-09-20T06:51:01.391682177Z","level":"INFO","msg":"Successfully started job #1\n"}
{"time":"2023-09-20T06:51:18.725030504Z","level":"INFO","msg":"Beacon fcefd6d0 BURNING_OXEN - 10.0.0.2:55844 (2c6ab9987174) - linux/amd64 - Wed, 20 Sep 2023 06:51:18 UTC","type":"event"}
{"time":"2023-09-20T06:51:26.687264841Z","level":"DEBUG","msg":"use fcefd6d0","type":"command"}
{"time":"2023-09-20T06:51:26.694869049Z","level":"INFO","msg":"Active beacon BURNING_OXEN (fcefd6d0-f246-419a-8634-eb0804d4275b)\n"}
{"time":"2023-09-20T06:51:29.390068884Z","level":"DEBUG","msg":"ls","type":"command"}
{"time":"2023-09-20T06:51:29.414300301Z","level":"INFO","msg":"Tasked beacon BURNING_OXEN (1802352b)"}
{"time":"2023-09-20T06:51:57.145476008Z","level":"DEBUG","msg":"tasks","type":"command"}
{"time":"2023-09-20T06:51:57.154961425Z","level":"INFO","msg":" ID State Message Type Created Sent Completed "}
{"time":"2023-09-20T06:51:57.155117758Z","level":"INFO","msg":"========== ========= ============== =============================== ====== ==========="}
{"time":"2023-09-20T06:51:57.155136216Z","level":"INFO","msg":" 1802352b \u001b[1mpending\u001b[0m Ls Wed, 20 Sep 2023 06:51:29 UTC "}
{"time":"2023-09-20T06:51:57.155158466Z","level":"INFO","msg":"%!(EXTRA []interface {}=[])"}
{"time":"2023-09-20T06:52:35.213722262Z","level":"INFO","msg":"BURNING_OXEN completed task 1802352b","type":"event"}
{"time":"2023-09-20T06:52:35.216409804Z","level":"INFO","msg":"\r\u001b[2K\r"}
{"time":"2023-09-20T06:52:35.217814054Z","level":"INFO","msg":"/home/sliver (13 items, 69.6 MiB)"}
{"time":"2023-09-20T06:52:35.218980137Z","level":"INFO","msg":"================================="}
{"time":"2023-09-20T06:52:35.219900554Z","level":"INFO","msg":"drwxr-xr-x :sliver .cache <dir> Wed Sep 20 00:50:07 +0000 2023\ndrwxr-xr-x :sliver .config <dir> Wed Sep 20 00:49:29 +0000 2023\ndrwxr-xr-x :sliver .msf4 <dir> Sun Sep 10 03:09:01 +0000 2023\ndrwx------ :sliver .sliver <dir> Wed Sep 20 06:52:35 +0000 2023\ndrwx------ :sliver .sliver-client <dir> Wed Sep 20 00:50:01 +0000 2023\n-rwx------ :sliver BORING_SCORN 17.6 MiB Wed Sep 20 00:50:21 +0000 2023\n-rwx------ :sliver BURNING_OXEN 17.4 MiB Wed Sep 20 00:55:59 +0000 2023\n-rwx------ :sliver EARLY_QUESTION 17.2 MiB Wed Sep 20 03:21:16 +0000 2023\n-rw-r--r-- :sliver run.sh 99 B Wed Sep 20 01:19:37 +0000 2023\n-rw-r--r-- :sliver run2.sh 174 B Wed Sep 20 01:25:16 +0000 2023\n-rw-r--r-- :sliver run3.sh 61 B Wed Sep 20 01:25:29 +0000 2023\n-rw-r--r-- :sliver run5.sh 52 B Wed Sep 20 01:27:26 +0000 2023\n-rwx------ :sliver TIRED_GUN 17.5 MiB Wed Sep 20 00:50:43 +0000 2023\n"}
{"time":"2023-09-20T06:52:35.221062887Z","level":"INFO","msg":"%!(EXTRA []interface {}=[])"}
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('Duplicate Campaign', () => {

// Upload another campaign with the same name
cy.get('[cy-test=add-campaign-btn]').click();
cy.get('[cy-test=create-new-camp]').select(3);
cy.get('[cy-test=create-new-camp]').select(4);
cy.get('[cy-test=new-camp-name]').click().type(camp);
cy.fixture(fileName, { encoding: null }).as('myFixture');
cy.get('[cy-test=browse-for-file]').selectFile('@myFixture');
Expand Down
4 changes: 2 additions & 2 deletions applications/redeye-e2e/src/support/campaignCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Cypress.Commands.add('clickAboutOnCampaignCard', () => {
//UPLOAD CAMPAIGN DB FILE
Cypress.Commands.add('uploadCampaign', (camp, fileName) => {
cy.get('[cy-test=add-campaign-btn]').click();
cy.get('[cy-test=create-new-camp]').select(3);
cy.get('[cy-test=create-new-camp]').select(4);
cy.get('[cy-test=new-camp-name]').click().type(camp);
cy.fixture(fileName, { encoding: null }).as('myFixture');
cy.get('[cy-test=browse-for-file]').selectFile('@myFixture');
Expand All @@ -58,7 +58,7 @@ Cypress.Commands.add('uploadFolder', (camp, fileName) => {
//UPLOAD CAMPAIGN DB FILE
Cypress.Commands.add('uploadCampaignBlue', (camp, fileName) => {
cy.get('[cy-test=add-campaign-btn]').click();
cy.get('[cy-test=create-new-camp]').select(3);
cy.get('[cy-test=create-new-camp]').select(4);
cy.get('[cy-test=new-camp-name]').click().type(camp);
cy.fixture(fileName, { encoding: null }).as('myFixture');
cy.get('[cy-test=browse-for-file]').selectFile('@myFixture');
Expand Down
2 changes: 1 addition & 1 deletion applications/server/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
"secret": "supertopsecretdonttellanyone",
"redTeam": true,
"databaseMode": "DEV_PERSIST",
"parsers": ["cobalt-strike-parser", "brute-ratel-parser"],
"parsers": ["sliver-parser", "cobalt-strike-parser", "brute-ratel-parser"],
"production": false
}
1 change: 1 addition & 0 deletions applications/server/moon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ dependsOn:
- 'migrations'
- 'cobalt-strike-parser'
- 'brute-ratel-parser'
- 'sliver-parser'
- 'parser-core'
tasks:
build:
Expand Down
3 changes: 2 additions & 1 deletion applications/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@redeye/cobalt-strike-parser": "workspace:*",
"@redeye/migrations": "workspace:*",
"@redeye/models": "workspace:*",
"@redeye/parser-core": "workspace:*"
"@redeye/parser-core": "workspace:*",
"@redeye/sliver-parser": "workspace:*"
}
}
6 changes: 5 additions & 1 deletion applications/server/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ export const withTempDir = async <T>(fn: (dir: string) => T) => {
return await fn(dir);
} finally {
setTimeout(() => {
fs.rm(dir, { recursive: true, force: true });
try {
fs.rm(dir, { recursive: true, force: true });
} catch (e) {
console.log('Error deleting temp directory', e);
}
}, 5000);
}
};
Expand Down
7 changes: 6 additions & 1 deletion applications/server/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
"@redeye/models": ["../../packages/models/src/index.ts"],
"@redeye/models/*": ["../../packages/models/src/*"],
"@redeye/parser-core": ["../../parsers/parser-core/src/index.ts"],
"@redeye/parser-core/*": ["../../parsers/parser-core/src/*"]
"@redeye/parser-core/*": ["../../parsers/parser-core/src/*"],
"@redeye/sliver-parser": ["../../parsers/sliver-parser/src/index.ts"],
"@redeye/sliver-parser/*": ["../../parsers/sliver-parser/src/*"]
}
},
"references": [
Expand All @@ -49,6 +51,9 @@
},
{
"path": "../../parsers/parser-core"
},
{
"path": "../../parsers/sliver-parser"
}
]
}
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
],
"bin": {
"brute-ratel-parser": "parsers/brute-ratel-parser/dist/index.js",
"cobalt-strike-parser": "parsers/cobalt-strike-parser/dist/index.js"
"cobalt-strike-parser": "parsers/cobalt-strike-parser/dist/index.js",
"sliver-parser": "parsers/sliver-parser/dist/index.js"
},
"scripts": {
"moon": "$(yarn bin moon)",
Expand Down Expand Up @@ -83,6 +84,7 @@
"node-fetch": "^2.6.1",
"open": "^8.4.0",
"path-to-regexp": "^6.2.0",
"protobufjs": "^7.2.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-error-boundary": "^3.1.1",
Expand Down Expand Up @@ -199,8 +201,8 @@
"supports-color": "^9.0.2",
"ts-jest": "^29.1.0",
"ts-node": "^10.9.1",
"tsup": "^6.7.0",
"tsx": "^3.12.7",
"tsc-watch": "^6.0.4",
"tsx": "^3.12.10",
"typedoc": "^0.24.8",
"typedoc-plugin-markdown": "^3.15.4",
"typescript": "^5.0.4",
Expand Down
2 changes: 2 additions & 0 deletions packages/models/src/projectModels/Server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ export class Server {
name,
id,
parsingPath,
displayName,
}: Pick<Server, 'name' | 'parsingPath'> & Partial<Pick<Server, 'id' | 'displayName'>>) {
this.id = id ?? randomUUID();
this.name = name;
this.parsingPath = parsingPath;
this.displayName = displayName;
}

@Field(() => String)
Expand Down
50 changes: 50 additions & 0 deletions parsers/sliver-parser/moon.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
dependsOn:
- 'models'
- 'parser-core'
tasks:
build:
deps:
- ~:build-node
start-dev:
local: true
deps:
- ^:build
- ~:start-node
options:
runInCI: false
runDepsInParallel: false
generate-entities:
command: 'yarn node --loader ts-node/esm src/generate-entities.ts'
deps:
- ~:build
test:
deps:
- ~:test-jest
release-mac:
deps:
- ~:build
outputs:
- /release/mac/parsers/sliver-parser
options:
runInCI: false
release-linux:
deps:
- ~:build
outputs:
- /release/linux/parsers/sliver-parser
options:
runInCI: false
release-windows:
deps:
- ~:build
outputs:
- /release/windows/parsers/sliver-parser
options:
runInCI: false
release-all:
deps:
- ~:release-mac
- ~:release-linux
- ~:release-windows
options:
runInCI: false
19 changes: 19 additions & 0 deletions parsers/sliver-parser/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "@redeye/sliver-parser",
"version": "0.0.1-alpha.0",
"bin": "./dist/index.js",
"pkg": {
"assets": [
"../../node_modules/better-sqlite3/**/*.*",
"../../../node_modules/better-sqlite3/**/*.*"
],
"compress": "GZip"
},
"files": [
"dist"
],
"dependencies": {
"@redeye/models": "workspace:*",
"@redeye/parser-core": "workspace:*"
}
}
38 changes: 38 additions & 0 deletions parsers/sliver-parser/src/generate-entities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { MikroORM } from '@mikro-orm/core';
import { defineConfig } from '@mikro-orm/better-sqlite';
import { resolve } from 'node:path';

(async () => {
const orm = await MikroORM.init(
defineConfig({
discovery: {
// we need to disable validation for no entities
warnWhenNoEntities: false,
},
dbName: resolve(
__dirname,
'..',
'..',
'..',
'applications',
'redeye-e2e',
'src',
'fixtures',
'sliver',
'sliver.db'
),
// ...
})
);
const generator = orm.getEntityGenerator();
await generator.generate({
// @ts-ignore
entitySchema: true,
bidirectionalRelations: true,
identifiedReferences: true,
esmImport: true,
save: true,
baseDir: resolve(__dirname, 'sliver-entities'),
});
await orm.close(true);
})();
15 changes: 15 additions & 0 deletions parsers/sliver-parser/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#! /usr/bin/env node

import { Command } from 'commander';
import { registerCampaignCommand } from './parse-campaign.command';
import { registerInfoCommand } from './info.command';
import { registerValidateFilesCommand } from './validate-files.command';
const program = new Command();
program
.name('RedEye - Sliver Parser')
.description('CLI to parse Sliver DB & Log Files')
.version('0.0.1', '-v, --version', 'output the current version');
registerCampaignCommand(program);
registerInfoCommand(program);
registerValidateFilesCommand(program);
program.parse();
36 changes: 36 additions & 0 deletions parsers/sliver-parser/src/info.command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { Command } from 'commander';
import type { ParserInfo } from '@redeye/parser-core';
import {
ParserMessageTypes,
ServerDelineationTypes,
UploadType,
ValidationMode,
writeParserMessage,
} from '@redeye/parser-core';

export const registerInfoCommand = (program: Command) => {
const infoCommand = program.command('info');

infoCommand.action(() => {
writeParserMessage(ParserMessageTypes.Data, aboutInfo);
});
};

const aboutInfo: ParserInfo = {
version: 1,
id: 'sliver-parser',
name: 'Sliver Parser',
uploadForm: {
serverDelineation: ServerDelineationTypes.Database,
enabledInBlueTeam: false,
tabTitle: 'Sliver',
fileUpload: {
type: UploadType.Directory,
validate: ValidationMode.Parser,
description: 'Upload the Sliver log folder containing a sliver.db file and json_*.log files',
},
fileDisplay: {
editable: true,
},
},
};
26 changes: 26 additions & 0 deletions parsers/sliver-parser/src/parse-campaign.command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { Command } from 'commander';
import { ParserMessageTypes, writeParserMessage } from '@redeye/parser-core';
import { parseSliverFiles } from './parser/parse-sliver-files';

type CommandCallbackOptions = {
folder?: string;
};

export const registerCampaignCommand = (program: Command) => {
const campaignCommand = program.command('parse-campaign');
campaignCommand.option(
'-f, --folder </absolute/path/to/folder>',
'The folder containing a Sliver campaign, includes a sliver.db file and json_*.log files',
(value) => value.replaceAll('"', '')
);

campaignCommand.action(campaignCommandAction);
};

const campaignCommandAction = async (options: CommandCallbackOptions) => {
if (options.folder) {
writeParserMessage(ParserMessageTypes.Data, await parseSliverFiles(options.folder));
} else {
writeParserMessage(ParserMessageTypes.Error, 'No folder specified');
}
};
Loading
Loading