Created nimble package and installation instructions.

This commit is contained in:
Jakob Friedl
2025-08-22 10:48:00 +02:00
parent 0ccafaccdd
commit 5922a5b850
10 changed files with 85 additions and 20 deletions

29
conquest.nimble Normal file
View 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"

View File

@@ -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]

View File

@@ -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
View 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
```

View File

@@ -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"

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -2,5 +2,4 @@
-d:server -d:server
--threads:on --threads:on
-d:httpxServerName="" -d:httpxServerName=""
--outdir:"../bin" -o:"bin/server"
-o:"server"