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

Commit

Permalink
Sliver 1.6 parser (alpha) and sample dataset (#190)
Browse files Browse the repository at this point in the history
Co-authored-by: Courtney Carpenter <[email protected]>
  • Loading branch information
GoldingAustin and ccarpenter28 authored Sep 26, 2023
1 parent e992cdb commit 06b6991
Show file tree
Hide file tree
Showing 31 changed files with 1,276 additions and 339 deletions.
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

0 comments on commit 06b6991

Please sign in to comment.