Refine profile structure.
This commit is contained in:
@@ -1,37 +1,78 @@
|
|||||||
# Conquest default configuration file
|
# Conquest default configuration file
|
||||||
|
# https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/malleable-c2_profile-language.htm#_Toc65482837
|
||||||
|
|
||||||
name = "cq-default-config"
|
name = "cq-default-profile"
|
||||||
|
|
||||||
|
# Important file paths and locations
|
||||||
conquest_directory = "/mnt/c/Users/jakob/Documents/Projects/conquest"
|
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"
|
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"
|
database_file = "/mnt/c/Users/jakob/Documents/Projects/conquest/data/conquest.db"
|
||||||
|
|
||||||
|
# General agent settings
|
||||||
[agent]
|
[agent]
|
||||||
sleep = 5
|
sleep = 5
|
||||||
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
|
||||||
|
# ----------------------------------------------------------
|
||||||
|
# HTTP GET
|
||||||
|
# ----------------------------------------------------------
|
||||||
|
# Defines URI endpoints for HTTP GET requests
|
||||||
[http-get]
|
[http-get]
|
||||||
uri = [
|
uri = [
|
||||||
"/tasks",
|
"/tasks",
|
||||||
"/api/v1.2/status.js"
|
"/api/v1.2/status.js"
|
||||||
]
|
]
|
||||||
|
|
||||||
[http-get.agent.headers]
|
# Defines where the heartbeat is placed within the HTTP GET request
|
||||||
Content-Type = "text/plain"
|
# Allows for data transformation using encoding (base64, base64url, ...), appending and prepending of strings
|
||||||
Authorization = { encoding = "base64url", prepend = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.", append = ".KMUFsIDTnFmyG3nMiGM6H9FNFUROf3wh7SmqJp-QV30" }
|
# Metadata can be stored in a Header (e.g. JWT Token, Session Cookie), URI parameter, appended to the URI or request body
|
||||||
|
[http-get.agent.heartbeat]
|
||||||
|
encoding = "base64url"
|
||||||
|
prepend = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
|
||||||
|
append = ".KMUFsIDTnFmyG3nMiGM6H9FNFUROf3wh7SmqJp-QV30"
|
||||||
|
placement = { type = "header", name = "Authorization" }
|
||||||
|
# placement = { type = "header", name = "Cookie" }
|
||||||
|
# placement = { type = "parameter", name = "id" }
|
||||||
|
# placement = { type = "uri-append" }
|
||||||
|
# placement = { type = "body" }
|
||||||
|
|
||||||
|
# Defines arbitrary URI parameters that are added to the request
|
||||||
|
[http-get.agent.parameters]
|
||||||
|
|
||||||
|
# Defines arbitrary headers that are added by the agent when performing a HTTP GET request
|
||||||
|
[http-get.agent.headers]
|
||||||
|
Cache-Control = "no-cache"
|
||||||
|
|
||||||
|
# Defines arbitrary headers that are added by the server
|
||||||
[http-get.server.headers]
|
[http-get.server.headers]
|
||||||
Server = "nginx"
|
Server = "nginx"
|
||||||
|
X-CONQUEST-VERSION = "0.1"
|
||||||
|
|
||||||
|
# Defines how the server's response to the task retrieval request is rendered
|
||||||
|
# Allows same data transformation options as the agent metadata, allowing it to be embedded in benign content
|
||||||
|
[http-get.server.output]
|
||||||
|
placement = { type = "body" }
|
||||||
|
|
||||||
|
# ----------------------------------------------------------
|
||||||
|
# HTTP POST
|
||||||
|
# ----------------------------------------------------------
|
||||||
|
# Defines URI endpoints for HTTP POST requests
|
||||||
[http-post]
|
[http-post]
|
||||||
uri = [
|
uri = [
|
||||||
"/results",
|
"/results",
|
||||||
"/api/v2/get.js"
|
"/api/v2/get.js"
|
||||||
]
|
]
|
||||||
|
request_methods = [
|
||||||
|
"POST",
|
||||||
|
"PUT"
|
||||||
|
]
|
||||||
|
|
||||||
[http-post.agent.headers]
|
[http-post.agent.headers]
|
||||||
Content-Type = "application/octet-stream"
|
Cache-Control = "no-cache"
|
||||||
|
|
||||||
[http-post.server.headers]
|
[http-post.server.headers]
|
||||||
Server = "nginx"
|
Server = "nginx"
|
||||||
Accept = "application/octet-stream"
|
X-CONQUEST-VERSION = "0.1"
|
||||||
|
|
||||||
|
[http-post.server.output]
|
||||||
|
placement = { type = "body" }
|
||||||
@@ -119,13 +119,13 @@ proc handleConsoleCommand(cq: Conquest, args: string) =
|
|||||||
|
|
||||||
cq.writeLine("")
|
cq.writeLine("")
|
||||||
|
|
||||||
proc header(cq: Conquest) =
|
proc header() =
|
||||||
cq.writeLine("")
|
echo ""
|
||||||
cq.writeLine("┏┏┓┏┓┏┓┓┏┏┓┏╋")
|
echo "┏┏┓┏┓┏┓┓┏┏┓┏╋"
|
||||||
cq.writeLine("┗┗┛┛┗┗┫┗┻┗ ┛┗ V0.1")
|
echo "┗┗┛┛┗┗┫┗┻┗ ┛┗ V0.1"
|
||||||
cq.writeLine(" ┗ @jakobfriedl")
|
echo " ┗ @jakobfriedl"
|
||||||
cq.writeLine("─".repeat(21))
|
echo "─".repeat(21)
|
||||||
cq.writeLine("")
|
echo ""
|
||||||
|
|
||||||
proc init*(T: type Conquest, profile: Profile): Conquest =
|
proc init*(T: type Conquest, profile: Profile): Conquest =
|
||||||
var cq = new Conquest
|
var cq = new Conquest
|
||||||
@@ -141,33 +141,36 @@ proc init*(T: type Conquest, profile: Profile): Conquest =
|
|||||||
|
|
||||||
return cq
|
return cq
|
||||||
|
|
||||||
proc startServer*(profile: string) =
|
proc startServer*(profilePath: string) =
|
||||||
|
|
||||||
# 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"
|
||||||
setControlCHook(exit)
|
setControlCHook(exit)
|
||||||
|
|
||||||
let profile = parseFile(profile).getTable
|
header()
|
||||||
# # dump table.getTable()
|
|
||||||
# let headers = table["http-get"]["agent"]["headers"].getTable()
|
|
||||||
# for key, value in headers:
|
|
||||||
# if value.kind == TomlValueKind.Table:
|
|
||||||
# echo value["encoding"]
|
|
||||||
# echo value["append"]
|
|
||||||
# echo value["prepend"]
|
|
||||||
# echo key
|
|
||||||
|
|
||||||
# Initialize framework
|
|
||||||
try:
|
try:
|
||||||
|
# Load and parse profile
|
||||||
|
let profile = parseFile(profilePath).getTable
|
||||||
|
styledEcho(fgGreen, styleBright, "[+] Using profile \"", profile["name"].getStr(), "\" (", profilePath ,").")
|
||||||
|
styledEcho(fgGreen, styleBright, "[+] ", profile["private_key_file"].getStr(), ": Private key found.")
|
||||||
|
|
||||||
|
# # dump table.getTable()
|
||||||
|
# let headers = table["http-get"]["agent"]["headers"].getTable()
|
||||||
|
# for key, value in headers:
|
||||||
|
# if value.kind == TomlValueKind.Table:
|
||||||
|
# echo value["encoding"]
|
||||||
|
# echo value["append"]
|
||||||
|
# echo value["prepend"]
|
||||||
|
# echo key
|
||||||
|
|
||||||
|
# Initialize framework context
|
||||||
cq = Conquest.init(profile)
|
cq = Conquest.init(profile)
|
||||||
|
|
||||||
except CatchableError as err:
|
except CatchableError as err:
|
||||||
echo err.msg
|
echo err.msg
|
||||||
quit(0)
|
quit(0)
|
||||||
|
|
||||||
# Print header
|
|
||||||
cq.header()
|
|
||||||
|
|
||||||
# Initialize database
|
# Initialize database
|
||||||
cq.dbInit()
|
cq.dbInit()
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ proc dbInit*(cq: Conquest) =
|
|||||||
|
|
||||||
""")
|
""")
|
||||||
|
|
||||||
cq.writeLine(fgGreen, "[+] ", cq.dbPath, ": Database created.")
|
cq.writeLine(fgGreen, styleBright, "[+] ", cq.dbPath, ": Database created.")
|
||||||
conquestDb.close()
|
conquestDb.close()
|
||||||
except SqliteError as err:
|
except SqliteError as err:
|
||||||
cq.writeLine(fgGreen, "[+] ", cq.dbPath, ": Database file found.")
|
cq.writeLine(fgGreen, styleBright, "[+] ", cq.dbPath, ": Database file found.")
|
||||||
|
|||||||
Reference in New Issue
Block a user