Created nimble package and installation instructions.
This commit is contained in:
29
conquest.nimble
Normal file
29
conquest.nimble
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# Package
|
||||||
|
|
||||||
|
version = "0.1.0"
|
||||||
|
author = "Jakob Friedl"
|
||||||
|
description = "Command & control framework written in Nim"
|
||||||
|
license = "MIT"
|
||||||
|
srcDir = "src"
|
||||||
|
|
||||||
|
# Build tasks
|
||||||
|
|
||||||
|
import os, strformat
|
||||||
|
task server, "Build conquest server binary":
|
||||||
|
let cqRoot = getCurrentDir()
|
||||||
|
exec fmt"nim c -d:CONQUEST_ROOT={cqRoot} src/server/main.nim"
|
||||||
|
|
||||||
|
task client, "Build conquest client binary":
|
||||||
|
discard
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
|
||||||
|
requires "nim >= 2.2.4"
|
||||||
|
|
||||||
|
requires "prompt >= 0.0.1"
|
||||||
|
requires "argparse >= 4.0.2"
|
||||||
|
requires "parsetoml >= 0.7.2"
|
||||||
|
requires "nimcrypto >= 0.6.4"
|
||||||
|
requires "tiny_sqlite >= 0.2.0"
|
||||||
|
requires "prologue >= 0.6.6"
|
||||||
|
requires "winim >= 3.9.4"
|
||||||
@@ -3,9 +3,8 @@
|
|||||||
name = "cq-default-profile"
|
name = "cq-default-profile"
|
||||||
|
|
||||||
# Important file paths and locations
|
# Important file paths and locations
|
||||||
conquest_directory = "/mnt/c/Users/jakob/Documents/Projects/conquest"
|
private-key-file = "data/keys/conquest-server_x25519_private.key"
|
||||||
private_key_file = "/mnt/c/Users/jakob/Documents/Projects/conquest/data/keys/conquest-server_x25519_private.key"
|
database-file = "data/conquest.db"
|
||||||
database_file = "/mnt/c/Users/jakob/Documents/Projects/conquest/data/conquest.db"
|
|
||||||
|
|
||||||
# General agent settings
|
# General agent settings
|
||||||
[agent]
|
[agent]
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ Basic API-only Commands
|
|||||||
- [x] mv : Move a file
|
- [x] mv : Move a file
|
||||||
- [x] cp : Copy a file
|
- [x] cp : Copy a file
|
||||||
- [ ] cat/type : Display contents of a file
|
- [ ] cat/type : Display contents of a file
|
||||||
- [ ] env : Display environment variables
|
- [x] env : Display environment variables
|
||||||
- [ ] ps : List processes
|
- [x] ps : List processes
|
||||||
- [ ] whoami : Get UID and privileges, etc.
|
- [ ] whoami : Get UID and privileges, etc.
|
||||||
|
|
||||||
- [ ] token : Token impersonation
|
- [ ] token : Token impersonation
|
||||||
|
|||||||
29
docs/INSTALL.md
Normal file
29
docs/INSTALL.md
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# Installation Guide
|
||||||
|
|
||||||
|
1. Clone the Conquest repository
|
||||||
|
```
|
||||||
|
git clone https://github.com/jakobfriedl/conquest
|
||||||
|
cd conquest
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Install Nim
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl https://nim-lang.org/choosenim/init.sh -sSf | sh
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Install Nimble dependencies
|
||||||
|
```
|
||||||
|
nimble install -d
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Build conquest binaries
|
||||||
|
```
|
||||||
|
nimble server
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Start the Conquest server with a C2 Profile
|
||||||
|
```
|
||||||
|
./bin/server -p ./data/profile.toml
|
||||||
|
```
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# Compiler flags
|
# Compiler flags
|
||||||
-d:agent
|
-d:agent
|
||||||
-d:release
|
-d:release
|
||||||
-d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
|
-d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
|
||||||
-o:"/mnt/c/Users/jakob/Documents/Projects/conquest/bin/monarch.x64.exe"
|
-o:"/mnt/c/Users/jakob/Documents/Projects/conquest/bin/monarch.x64.exe"
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import terminal, strformat, strutils, sequtils, tables, system, osproc, streams, parsetoml
|
import terminal, strformat, strutils, sequtils, tables, system, osproc, streams, parsetoml
|
||||||
|
|
||||||
|
import ../globals
|
||||||
import ../core/logger
|
import ../core/logger
|
||||||
import ../db/database
|
import ../db/database
|
||||||
import ../../common/[types, utils, profile, serialize, crypto]
|
import ../../common/[types, utils, profile, serialize, crypto]
|
||||||
@@ -51,10 +52,13 @@ proc replaceAfterPrefix(content, prefix, value: string): string =
|
|||||||
proc compile(cq: Conquest, placeholderLength: int): string =
|
proc compile(cq: Conquest, placeholderLength: int): string =
|
||||||
|
|
||||||
let
|
let
|
||||||
cqDir = cq.profile.getString("conquest_directory")
|
configFile = fmt"{CONQUEST_ROOT}/src/agent/nim.cfg"
|
||||||
configFile = fmt"{cqDir}/src/agent/nim.cfg"
|
exeFile = fmt"{CONQUEST_ROOT}/bin/monarch.x64.exe"
|
||||||
exeFile = fmt"{cqDir}/bin/monarch.x64.exe"
|
agentBuildScript = fmt"{CONQUEST_ROOT}/src/agent/build.sh"
|
||||||
agentBuildScript = fmt"{cqDir}/src/agent/build.sh"
|
|
||||||
|
# Update conquest root directory in agent build script
|
||||||
|
var buildScript = readFile(agentBuildScript).replaceAfterPrefix("CONQUEST_ROOT=", CONQUEST_ROOT)
|
||||||
|
writeFile(agentBuildScript, buildScript)
|
||||||
|
|
||||||
# Update placeholder and configuration values
|
# Update placeholder and configuration values
|
||||||
let placeholder = PLACEHOLDER & "A".repeat(placeholderLength - (2 * len(PLACEHOLDER))) & PLACEHOLDER
|
let placeholder = PLACEHOLDER & "A".repeat(placeholderLength - (2 * len(PLACEHOLDER))) & PLACEHOLDER
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import times, strformat, strutils, prompt, terminal
|
import times, strformat, strutils, prompt, terminal
|
||||||
import std/[dirs, paths]
|
import std/[dirs, paths]
|
||||||
|
|
||||||
|
import ../globals
|
||||||
import ../../common/[types, profile]
|
import ../../common/[types, profile]
|
||||||
|
|
||||||
proc makeAgentLogDirectory*(cq: Conquest, agentId: string): bool =
|
proc makeAgentLogDirectory*(cq: Conquest, agentId: string): bool =
|
||||||
try:
|
try:
|
||||||
let cqDir = cq.profile.getString("conquest_directory")
|
createDir(cast[Path](fmt"{CONQUEST_ROOT}/data/logs/{agentId}"))
|
||||||
createDir(cast[Path](fmt"{cqDir}/data/logs/{agentId}"))
|
|
||||||
return true
|
return true
|
||||||
except OSError:
|
except OSError:
|
||||||
return false
|
return false
|
||||||
@@ -13,8 +14,7 @@ proc makeAgentLogDirectory*(cq: Conquest, agentId: string): bool =
|
|||||||
proc log*(cq: Conquest, logEntry: string) =
|
proc log*(cq: Conquest, logEntry: string) =
|
||||||
let
|
let
|
||||||
date = now().format("dd-MM-yyyy")
|
date = now().format("dd-MM-yyyy")
|
||||||
cqDir = cq.profile.getString("conquest_directory")
|
agentLogPath = fmt"{CONQUEST_ROOT}/data/logs/{cq.interactAgent.agentId}/{date}.session.log"
|
||||||
agentLogPath = fmt"{cqDir}/data/logs/{cq.interactAgent.agentId}/{date}.session.log"
|
|
||||||
|
|
||||||
# Write log entry to file
|
# Write log entry to file
|
||||||
let file = open(agentLogPath, fmAppend)
|
let file = open(agentLogPath, fmAppend)
|
||||||
|
|||||||
@@ -134,12 +134,16 @@ proc init*(T: type Conquest, profile: Profile): Conquest =
|
|||||||
cq.agents = initTable[string, Agent]()
|
cq.agents = initTable[string, Agent]()
|
||||||
cq.interactAgent = nil
|
cq.interactAgent = nil
|
||||||
cq.profile = profile
|
cq.profile = profile
|
||||||
cq.keyPair = loadKeyPair(profile.getString("private_key_file"))
|
cq.keyPair = loadKeyPair(CONQUEST_ROOT & "/" & profile.getString("private-key-file"))
|
||||||
cq.dbPath = profile.getString("database_file")
|
cq.dbPath = CONQUEST_ROOT & "/" & profile.getString("database-file")
|
||||||
return cq
|
return cq
|
||||||
|
|
||||||
proc startServer*(profilePath: string) =
|
proc startServer*(profilePath: string) =
|
||||||
|
|
||||||
|
# Ensure that the conquest root directory was passed as a compile-time define
|
||||||
|
when not defined(CONQUEST_ROOT):
|
||||||
|
quit(0)
|
||||||
|
|
||||||
# Handle CTRL+C,
|
# Handle CTRL+C,
|
||||||
proc exit() {.noconv.} =
|
proc exit() {.noconv.} =
|
||||||
echo "Received CTRL+C. Type \"exit\" to close the application.\n"
|
echo "Received CTRL+C. Type \"exit\" to close the application.\n"
|
||||||
@@ -154,7 +158,6 @@ proc startServer*(profilePath: string) =
|
|||||||
cq = Conquest.init(profile)
|
cq = Conquest.init(profile)
|
||||||
|
|
||||||
cq.info("Using profile \"", profile.getString("name"), "\" (", profilePath ,").")
|
cq.info("Using profile \"", profile.getString("name"), "\" (", profilePath ,").")
|
||||||
cq.info("Using private key \"", profile.getString("private_key_file"), "\".")
|
|
||||||
|
|
||||||
except CatchableError as err:
|
except CatchableError as err:
|
||||||
echo err.msg
|
echo err.msg
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
import os
|
||||||
import ../common/types
|
import ../common/types
|
||||||
|
|
||||||
# Global variable for handling listeners, agents and console output
|
# Global server context
|
||||||
|
const CONQUEST_ROOT* {.strdefine.} = ""
|
||||||
var cq*: Conquest
|
var cq*: Conquest
|
||||||
@@ -2,5 +2,4 @@
|
|||||||
-d:server
|
-d:server
|
||||||
--threads:on
|
--threads:on
|
||||||
-d:httpxServerName=""
|
-d:httpxServerName=""
|
||||||
--outdir:"../bin"
|
-o:"bin/server"
|
||||||
-o:"server"
|
|
||||||
Reference in New Issue
Block a user