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"
# Important file paths and locations
conquest_directory = "/mnt/c/Users/jakob/Documents/Projects/conquest"
private_key_file = "/mnt/c/Users/jakob/Documents/Projects/conquest/data/keys/conquest-server_x25519_private.key"
database_file = "/mnt/c/Users/jakob/Documents/Projects/conquest/data/conquest.db"
private-key-file = "data/keys/conquest-server_x25519_private.key"
database-file = "data/conquest.db"
# General agent settings
[agent]

View File

@@ -14,8 +14,8 @@ Basic API-only Commands
- [x] mv : Move a file
- [x] cp : Copy a file
- [ ] cat/type : Display contents of a file
- [ ] env : Display environment variables
- [ ] ps : List processes
- [x] env : Display environment variables
- [x] ps : List processes
- [ ] whoami : Get UID and privileges, etc.
- [ ] 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
-d:agent
-d:release
-d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
-d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
-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 ../globals
import ../core/logger
import ../db/database
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 =
let
cqDir = cq.profile.getString("conquest_directory")
configFile = fmt"{cqDir}/src/agent/nim.cfg"
exeFile = fmt"{cqDir}/bin/monarch.x64.exe"
agentBuildScript = fmt"{cqDir}/src/agent/build.sh"
configFile = fmt"{CONQUEST_ROOT}/src/agent/nim.cfg"
exeFile = fmt"{CONQUEST_ROOT}/bin/monarch.x64.exe"
agentBuildScript = fmt"{CONQUEST_ROOT}/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
let placeholder = PLACEHOLDER & "A".repeat(placeholderLength - (2 * len(PLACEHOLDER))) & PLACEHOLDER

View File

@@ -1,11 +1,12 @@
import times, strformat, strutils, prompt, terminal
import std/[dirs, paths]
import ../globals
import ../../common/[types, profile]
proc makeAgentLogDirectory*(cq: Conquest, agentId: string): bool =
try:
let cqDir = cq.profile.getString("conquest_directory")
createDir(cast[Path](fmt"{cqDir}/data/logs/{agentId}"))
createDir(cast[Path](fmt"{CONQUEST_ROOT}/data/logs/{agentId}"))
return true
except OSError:
return false
@@ -13,8 +14,7 @@ proc makeAgentLogDirectory*(cq: Conquest, agentId: string): bool =
proc log*(cq: Conquest, logEntry: string) =
let
date = now().format("dd-MM-yyyy")
cqDir = cq.profile.getString("conquest_directory")
agentLogPath = fmt"{cqDir}/data/logs/{cq.interactAgent.agentId}/{date}.session.log"
agentLogPath = fmt"{CONQUEST_ROOT}/data/logs/{cq.interactAgent.agentId}/{date}.session.log"
# Write log entry to file
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.interactAgent = nil
cq.profile = profile
cq.keyPair = loadKeyPair(profile.getString("private_key_file"))
cq.dbPath = profile.getString("database_file")
cq.keyPair = loadKeyPair(CONQUEST_ROOT & "/" & profile.getString("private-key-file"))
cq.dbPath = CONQUEST_ROOT & "/" & profile.getString("database-file")
return cq
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,
proc exit() {.noconv.} =
echo "Received CTRL+C. Type \"exit\" to close the application.\n"
@@ -154,7 +158,6 @@ proc startServer*(profilePath: string) =
cq = Conquest.init(profile)
cq.info("Using profile \"", profile.getString("name"), "\" (", profilePath ,").")
cq.info("Using private key \"", profile.getString("private_key_file"), "\".")
except CatchableError as err:
echo err.msg

View File

@@ -1,4 +1,6 @@
import os
import ../common/types
# Global variable for handling listeners, agents and console output
# Global server context
const CONQUEST_ROOT* {.strdefine.} = ""
var cq*: Conquest

View File

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