Verdict:Suspicious
Confidence:Medium
Executive Summary
The principal executable difference is transport and scheduling: A and C use a custom TCP session and sequential task handling; B uses HTTP polling and concurrent task workers. A also contains a duplicated-port address construction that normally prevents its configured destination from resolving. C has a valid numeric destination. All three have distinct embedded tokens and AES keys, but the same task-handler implementation.
Quiet autostart and hidden temporary capture/execution files are concerning alongside remote control. However, a security-testing agent is a credible alternative supported by the coherent task/protocol architecture and generated C2-payload build context. We do not establish a known malware family, common operator, actual compromise, build chronology, or AI generation. Unexpected copies should not be run; finding these files alone does not establish that their capabilities were exercised.
Scope and Coverage
A. Original identities and build context
The names below are the original uploaded filenames supplied with the artifacts. We recomputed each SHA-256 from its original bytes; filename suffixes were not used as identities.
ID | Original uploaded filename | SHA-256 | Size | Default application path |
A | beacon_linux_amd64_p_bd14ad64dcfc4e | 24266fa587849bb7099a82363d86439cd4574f4be93ed213f0f2a44bfce922b9 | 6,361,214 bytes | Custom TCP; malformed destination construction |
B | beacon_linux_amd64_p_eccebac21dfc41 | b39fe6c2c7227d1eb7afc0cba663e80470faba8bc96ce350b5113a2f87cf2918 | 6,361,214 bytes | HTTP polling; concurrent task workers |
C | beacon_linux_amd64_p_ff6101bcf4c44b | 5bd268e3738ec8702c290bbf6bbf4295fc3f09f22732a25343c30258804b20d5 | 6,361,214 bytes | Custom TCP; valid numeric destination |
All three are little-endian x86-64 Linux ELF executables, ELF type
EXEC, with entry VA 0x48b5c0, no declared ELF interpreter, and no dynamic-library dependencies. Embedded .go.buildinfo at file offset 0x5c6000 declares go1.26.5, CGO_ENABLED=0, GOOS=linux, GOARCH=amd64, and GOAMD64=v1. The separate Go detector's Go1_20 label corresponds to the recovered function-table format, not the embedded compiler-version string.The build metadata claims module
cyberstrike-ai and paths ending in build-db711062 (A), build-3a8f0f47 (B), and build-1d7ef605 (C). These are author-controlled provenance clues, not authenticated product identity, family attribution, operator linkage, or evidence of AI authorship.B. Static methodology and limitations
We used ELF parsing, SHA-256 hashing, Go function-table and reflection-metadata recovery, targeted decompilation, original-byte disassembly, exact-length Go-string extraction, Base64 decoding, and independent address-syntax validation. No Internet access or external reputation lookup was used. We did not use Go string-emulation tools because the requested analysis prohibited sample execution, including emulation.
Coverage measure | A | B | C |
Recovered main.* functions independently disassembled | 68 | 66 | 68 |
Bytes decoded across those complete function ranges | 31,424 | 33,984 | 31,424 |
Native analyzer code-section coverage | 98% | 98% | 98% |
Native analyzer unattributed bytes / regions | 35,140 / 809 | 35,057 / 809 | 35,140 / 809 |
Unresolved indirect branches in native analysis | 24 | 24 | 24 |
The full application slices were separately decoded to compensate for incomplete native analysis and Go-ABI decompiler errors. For example, original instructions store returned string lengths where decompilation suggested constant lengths, and the original persistence routine contains a
.bashrc write/close block omitted from its decompilation. We relied on the original instructions for those claims. Broader linked-code coverage remains incomplete; the scoped negative findings below are not whole-binary proofs.Important derived analysis outputs, not executable payloads, are:
analysis/recovered-configuration.json: original configuration locations, encoded keys, decoded keys, tokens, destinations, and Base64 round-trip checks.
analysis/{A,B,C}-main-verified.asmandanalysis/{A,B,C}-functions-verified.json: original-byte application disassembly and function ranges.
analysis/{A,B,C}-protocol-types-verified.json: independently recovered JSON layouts.
analysis/comparison-summary.json,analysis/task-handler-comparison.json, andanalysis/handler-literal-validation.json: implementation and literal comparisons.
analysis/capability-boundary-audit.jsonandanalysis/encoding-caller-audit.json: file/process/network boundaries and encoding-wrapper callers.
analysis/tcp-wire-verification.mdand its original-byte supporting disassemblies: independent TCP serialization and resolver verification.
Addresses below are virtual addresses, unless explicitly labeled as file offsets. A/C handler addresses coincide; B's separate addresses are shown where relevant. File offsets were obtained through ELF mappings rather than assumed image-base subtraction.
Artifact Relationships and Behavioral Sequence
These are independent executable builds, not three stages of a demonstrated execution chain. We found no startup invocation or dependency between the uploads in the mapped application code. Their relationship is shared implementation with different configuration and transport orchestration.
Startup requires a compatible Linux/amd64 execution environment; useful tasking also requires permitted network access and a compatible controller using the compiled protocol credentials. We found no argument/password requirement or root-only gate in the mapped startup functions.
isAdminProcess supplies effective-UID telemetry rather than elevating privileges. File, process, and persistence effects inherit the launching account's permissions; individual tasks have the additional utility/environment requirements listed below.The common sequence is:
- Initialize state; derive an identity from hostname, normalized MAC address, and PID; capture the initial working directory.
- Connect or poll using the compiled configuration and send host telemetry.
- Accept server-provided session/scheduling information. Fetch tasks only when the check-in response indicates tasks are available.
- Dispatch each task, collect output or file data, construct a result, and send it to the controller.
- Repeat with configurable sleep/jitter. Persistence, screenshots, relays, and further executable staging require corresponding tasks; they are not unconditional startup actions.
A/C:
main.main at 0x666040 enters runTCPBeaconForever at 0x666120. After a successful dial it sends the TCP preface and repeatedly checks in over that connection. tcpBeaconSessionLoop at 0x6667a0 calls handleTaskSyncTCP at 0x667580 directly for each task. That worker temporarily supplies the active connection to file-fetch operations. A check-in failure returns to connection close/retry. A long-running task can delay subsequent polling, although proxy handlers start background connection workers.B:
main.main at 0x666040 constructs an HTTP client and enters a polling loop. For each fetched task it creates a goroutine at 0x666263, through wrapper 0x666360 and worker handleTaskAsync at 0x669ae0. Workers can overlap one another and later polls; the launch loop has no task-concurrency budget or join. Results need not arrive in task-array order.No later executable was recovered. Additional code is supplied by future task data or a controller file ID; those bytes were not included in the uploads and were not fetched.
Capability and Implementation Comparison
A. Shared code is stronger evidence than matching names or hosting
All 37 compared dispatcher, handler, helper, and closure functions have matching instruction structure across A/B/C after narrowly normalizing RIP-relative data displacements and named direct-call/branch destinations. We independently checked 142 exact handler-literal comparisons, with no differences. This supports shared task implementation, not merely superficial string similarity.
Across the complete application slices, A/C share 68 function names; their only normalized instruction difference is in
runTCPBeaconForever, where the destination's immediate string length changes. A/B share 57 application functions; only main.main differs in that shared set, while their transport-specific orchestration functions differ separately. This normalization does not establish equality of every referenced data object; configuration values were recovered and compared independently.Difference | Interpretation |
Different keys, tokens, and generated build-directory identifiers | Configuration/build provenance changes; not evidence of separate operators or new task capabilities |
A's duplicated-port strings versus C's valid destination | Configuration-construction difference with real connection consequences; not a new command implementation |
A/C TCP session versus B HTTP check-in/task/result functions | Executable networking difference |
A/C direct task calls versus B goroutine-per-task launch | Executable scheduling difference |
B's shifted handler/type addresses and different function inventory | Build-layout/orchestration changes, not additional screenshot, persistence, or execution capabilities |
Retained TCP helpers in B and HTTP file-fetch code in A/C | Bundled helpers do not establish that normal startup selects those transports |
B. Shared task interface and host effects
executeTask is at A/C 0x669340, B 0x669da0. It performs case-sensitive task-name comparisons; unknown names return an unsupported-task error. Payload string fields use checked string assertions; numeric arguments use JSON-decoded numbers, converted from floating-point values to integers.Task(s) | Implemented behavior and prerequisites | Handler VA, A/C ; B |
exec, shell | Both run /bin/sh -c, capture combined stdout/stderr, and default to a 60-second timeout. shell additionally tracks a working directory; neither is an interactive terminal. Requires the shell, requested utilities, and account permissions. | 0x669a00, 0x669b60 ; 0x66a460, 0x66a5c0 |
pwd, cd, ls | Return/change a protected virtual working-directory string and list directory entries. cd verifies a directory; it does not call os.Chdir. ls is not a recursive traversal. | 0x669e80, 0x669f40, 0x66a220 ; 0x66a8e0, 0x66a9a0, 0x66ac80 |
ps, kill_proc | Run ps aux with a 30-second timeout; signal a supplied positive PID with SIGKILL. OS authorization applies. | 0x66a7c0, 0x66a840 ; 0x66b220, 0x66b2a0 |
upload | Controller to host: fetch bytes by file_id, then write/truncate remote_path, requesting mode 0644 for a new file. Does not create parent directories. | 0x66a980 ; 0x66b3e0 |
download | Host to controller: read the supplied remote_path, Base64-encode the entire file, and return it in the task result with its extension. | 0x66aba0 ; 0x66b600 |
screenshot | Execute external ImageMagick capture, Base64-encode its temporary PNG, and return the image. Requires utilities and usable X11 display access. | 0x66ad80 ; 0x66b7e0 |
sleep | Change future sleep/jitter settings; the handler does not itself sleep. | 0x66ae20 ; 0x66b880 |
port_fwd | Start/stop a loopback TCP listener forwarding connections to a task-supplied host/port. | 0x66b0c0 ; 0x66bb20 |
socks_start, socks_stop | Start/stop a loopback, unauthenticated SOCKS5 TCP CONNECT proxy; default port 1080. | 0x66be40, 0x66c200 ; 0x66c8a0, 0x66cc60 |
load_assembly | Decode inline Base64 data or retrieve file_id, write an executable temporary file, launch it directly, collect output, and attempt deferred removal. This is disk execution, not an in-process assembly host. | 0x66cde0 ; 0x66d840 |
persist | Install user crontab or .bashrc autostart, depending on method and success. | 0x66d620 ; 0x66e080 |
self_delete, exit | Immediate process termination; the delayed self-removal design is unreliable, as detailed below. | 0x66af80, dispatch call 0x6693f1 ; 0x66b9e0, dispatch call 0x669e51 |
Recovered Configuration and Network Protocols
A. Compiled destinations and defaults
Item | A | B | C |
Selected transport | tcp_beacon | http_beacon | tcp_beacon |
Actual TCP dial argument | [207.148.126.156:8199]:8199 | Not selected by mapped startup | 207.148.126.156:8199 |
Compiled HTTP base | http://207.148.126.156:8199:8199 | http://207.148.126.156:8199 | http://207.148.126.156:8199 |
Initial sleep / jitter | 5 seconds / 0% | 5 seconds / 0% | 5 seconds / 0% |
Destination evidence: A/C load their dial strings at instruction
0x66613a, then call net.DialTimeout at 0x666150 with a 45-second timeout. A's string is at VA 0x76665f, file 0x36665f, length 27; C's is at VA 0x76334e, file 0x36334e, length 20. HTTP-base string headers are A/C 0x77e110 and B 0x77e1c0; the complete recovered locations are in analysis/recovered-configuration.json.A's malformed-looking address deserves a precise qualification. Its linked
net.SplitHostPort accepts the brackets but leaves 207.148.126.156:8199 as the host. That is not a valid IP literal; the ordinary DNS-name path rejects its colon (isDomainName, 0x5568a0; validation call/branch 0x53fa21/0x53fa28). However, the linked resolver can satisfy a matching local hosts alias before DNS validation (goLookupIPFiles call 0x53f9ca, success branch 0x53f9d2). Therefore A's ordinary numeric/DNS path fails, but unconditional inability to connect is not established without the host's local resolver configuration. C does not require this exception for address parsing. Neither address was dialed during our analysis.All three carry this exact user-agent value:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36B sends it as an HTTP header. A/C include it in telemetry and retain it for the HTTP file helper; their selected TCP protocol is not browser HTTP. The value is generic and does not establish a family or browser origin.
B. Tokens and decoded encryption keys
These are compiled protocol credentials, not credentials harvested from a victim. The keys are stored as 44-byte Base64 text and decode to distinct 32-byte AES keys. We decoded the original bytes and verified that re-encoding reproduced each stored representation.
Sample | Compiled token | Decoded AES key, hexadecimal |
A | ccuLuUAB6mevyovDNGygc79yE-ikGp0MyqifygrGb2c | bcbb6b8aebecff170033973fb50f7c045c7e9dc4da20b43624bd43822a5431c1 |
B | v9PY_1nkdk8pemDNTTxj8Y_nPzSz1gT5JaM19EWykDg | 66e4b4f4829dafb98ad20c7a0b4f7f533207cac9c041762fcf00ab1a68d3ada4 |
C | BvPBtk2hFCnvUp80rFJNR-z9AWnw3TdBxdDhpb-3RFg | 1c1be3b721400d286c48a3b3497f7202e28267a1636d628dbc08f1ab8856b7f8 |
Original file offsets: tokens A
0x36e855, B 0x36e934, C 0x36e849; encoded AES keys A 0x36eeb7, B 0x36ef96, C 0x36eeab. The encoded representations, VAs, lengths, and validation results remain in analysis/recovered-configuration.json.The encryption wrapper is A/C
encryptGCM 0x668ac0, B 0x669260; decryption is A/C 0x668d20, B 0x6694c0. Calls to AES construction, GCM construction, cryptographic nonce generation, Seal/Open, and Base64 encoding establish this construction:Base64_standard_padded(nonce[12] || AES-256-GCM ciphertext || tag[16])Associated data is nil. Incoming messages are authenticated by GCM before returning their plaintext. This is a static reconstruction, not captured traffic, an interoperability test, or a comprehensive cryptographic-security assessment.
C. TCP versus HTTP transactions
Protocol aspect | A/C TCP | B HTTP |
Opening/framing | One connection preface CSB1, then four-byte big-endian encoded-body length plus body | Ordinary HTTP requests; body is raw encrypted Base64 text |
Check-in | JSON envelope with op = check_in, token, and nested check object | POST /check_in |
Task retrieval | Envelope with op = tasks, token, session_id | GET /tasks?session_id=... |
Result | Envelope with op = result, token, nested result object | POST /result |
Controller-file retrieval | Envelope with op = file, token, nested file object containing file_id | GET /file/<file_id> |
Token placement | Inside the encrypted JSON envelope | Explicit X-Implant-Token header |
Timing/error behavior | 360-second read deadline per round trip; connection retry after check-in failure | 60-second HTTP-client timeout; check-in/task fetch require HTTP 200 |
TCP evidence: preface write
0x666214; frame functions 0x666320/0x666460; round trip 0x666680; check-in builder 0x666960; task fetch 0x6671a0; result 0x6673a0; file fetch 0x6678c0. Encoded frame lengths must be positive and no greater than 67,108,864 bytes (64 MiB). The preface is not repeated in every frame.The TCP
check, result, and file properties are nested JSON, not Base64-encoded inner JSON. The builders assign the json.RawMessage type at 0x6feac0; its MarshalJSON implementation at 0x5ecf60 returns the nonnil JSON bytes. Individual fields such as file contents can still be Base64 strings.HTTP evidence: check-in
0x667a20, task fetch 0x668740, result 0x668ea0, and file helper 0x666ae0. B's transport disables keepalives and configures TLS certificate verification to be skipped (0x6660f3, 0x666106); the latter affects HTTPS requests or redirects, not its compiled plain-HTTP URL. Unlike check-in/task retrieval, reportResult drains/closes the response without checking its status or decrypting it; its worker has no report retry/queue path.B retains TCP framing/file helpers, but the recovered application references to its optional TCP connection state (
0xa114c0/0xa114c8) are only reads in fetchC2FileByID (0x666b32, 0x666f31, 0x666f38). We independently scanned all B application functions for stores and found none. Conversely, A/C's task worker sets an active TCP context, so their normal file-fetch task path uses TCP; the compiled HTTP bases are not evidence of a second active polling loop.D. Telemetry, task parsing, and results
Check-in reports hostname, username, Linux/amd64 platform, PID, executable basename, effective-UID-derived administrator status, internal IPv4 address, user agent, sleep/jitter, and metadata containing transport and working directory. The identity format is
%s-%s-%d using hostname/MAC/PID, not a random UUID. Missing identity/network details have fallbacks rather than a startup authorization gate.The response layout contains
session_id, next_sleep, next_jitter, has_tasks, and server_time. Positive next-sleep and nonnegative next-jitter values update scheduling. Task responses are an envelope containing tasks, whose entries have task_id, task_type, and payload. Results contain success, text or Base64 output/error, optional Base64 blob/extension, and start/end timestamps in epoch milliseconds. Invalid UTF-8 output is preserved through Base64 fields.These layouts were read from original Go reflection records: check-in response A/C
0x73a100, B 0x73a1a0; task A/C 0x7299a0, B 0x729a40; report A/C 0x7489a0, B 0x748a40. They establish accepted/produced data structures, not actual server replies.Key Findings
A. File collection, staging, and additional execution are real implementations
The
download handler reads the operator-supplied path at A/C 0x66ac0c, encodes the returned bytes at 0x66ac2e, and places them in the result. It can expose any file readable by the process if tasked; we did not find a dedicated credential-store targeting routine.upload passes the byte slice returned by fetchC2FileByID directly into os.WriteFile at A/C 0x66aaac, requesting mode 0644. Existing destination files can be overwritten. Transfer paths are used directly, unlike cd/ls and subprocesses, which use the virtual working directory. Relative transfer paths therefore remain relative to the process's actual startup directory.load_assembly is a misleadingly broad task name. Its actual path writes decoded bytes to $TMPDIR/.cs_<timestamp>, defaulting to /tmp, with requested new-file mode 0700, then invokes that file directly (os.WriteFile 0x66d0cc, exec.Command 0x66d164, CombinedOutput 0x66d203). Arguments use whitespace splitting, not shell-quoting rules. Deferred removal is at 0x66d5f6.This does not implement in-process CLR hosting, memory-only loading, or process injection. The supplied file must be runnable by the Linux execution environment, and the temporary filesystem must permit execution. Unlike
exec/shell, this handler has no timeout; it can block A/C's synchronous task path and postpone cleanup indefinitely. We cannot characterize any future payload without its bytes.B. Screenshot capture is implemented but environment dependent
At A/C
0x66ad8e, the handler selects this exact command, with a 30-second timeout:import -window root /tmp/.cs_ss.png 2>/dev/null && base64 /tmp/.cs_ss.png && rm -f /tmp/.cs_ss.pngIt returns trimmed command output as image data with suffix
.png. This is not a success-only stub. It depends on ImageMagick import, base64, rm, /bin/sh, writable temporary storage, and appropriate X11 display authorization. Missing GUI access or utility restrictions can prevent capture. Cleanup is chained with &&, so a failed step can leave the image behind; the handler does not validate the returned PNG contents.C. Persistence is task-triggered and user scoped
taskPersist calls A/C persistLinux 0x66d720, B 0x66e180. Accepted methods are auto, cron, and bashrc. auto first attempts cron, then falls back to .bashrc if the cron command fails.- Cron: formats an
@rebootcommand using the current executable path, merges it into the invoking user's crontab, and deduplicates entries withsort -u. The command execution call is A/C0x66d80a, with a 10-second timeout. It requires cron utilities/permission and a later reboot.
- Bash: appends
\n(nohup %s &>/dev/null &) # cs\nto the current user's.bashrc. Original instructions open it at A/C0x66d938, write at0x66d963, and close at0x66d976. It requires a writable home configuration and a later Bash session that sources it.
Neither branch copies the executable to a durable location, installs a system service, or establishes privilege escalation. The referenced executable must remain available. The
.bashrc branch ignores write/close errors, so its success text is not proof that persistence was installed. The only application caller of taskPersist is the dispatcher, not startup.D. Relaying supports network access but is not autonomous spread
Port forwarding binds
127.0.0.1:<local_port>, accepts local clients, and dials a task-specified destination with a 10-second timeout. SOCKS similarly binds loopback, defaults to port 1080, and implements unauthenticated SOCKS5 TCP CONNECT for IPv4, domain, and IPv6 destinations. Its session handler is A/C 0x66c2e0, B 0x66cd40.These are local TCP relays, not reverse tunnels multiplexed through C2, and they do not themselves authenticate to or exploit another host. SOCKS BIND and UDP ASSOCIATE are rejected. Its single-read greeting/request parsing is fragile under fragmented or coalesced traffic, and it installs no handshake/idle deadline. Stop operations close listeners, not already accepted sessions; existing relays can remain active.
E. Termination and timeout behavior have important limits
The common command runner uses
/bin/sh -c; timeout signals the shell with SIGKILL, not its whole descendant process tree. The signal call is A/C 0x6698a5. Commands can therefore leave descendants running.self_delete launches a goroutine whose intended action is sleep two seconds, then os.Remove (0x66b085, 0x66b094), but immediately invokes os.Exit(0) at A/C 0x66b02c. Normal process exit terminates that goroutine before removal. We therefore assess it as a working termination path but not a dependable delayed self-delete mechanism. It also does not remove persistence entries. The separate exit task terminates without a normal result report.Supported Indicators and Their Context
Indicator | Evidence and role | Interpretation limit |
The three full SHA-256 hashes in the identity table | Computed from the original uploads | Strong exact-file identifiers; do not substitute filename suffixes |
207.148.126.156, port 8199 | Compiled default controller destination; exact A/B/C constructions are documented above | No endpoint contact, ownership, availability, or common-operator inference |
CSB1 followed by length-framed encrypted Base64 traffic | A/C preface write and framing code | Protocol-context lead, not a proven family signature |
/check_in, /tasks, /result, /file/ with X-Implant-Token | B's HTTP operations and file helper | Paths individually are not unique; combine with host, headers, and sample evidence |
Per-sample tokens and keys | Original compiled configuration offsets and recovered configuration file | Distinguish these builds' protocol configuration, not their operators |
/tmp/.cs_ss.png | Screenshot capture/staging command | Potential local artifact only if the handler ran; not observed on a host |
Temporary .cs_ executable names; .bashrc marker # cs; @reboot reference to the beacon path | Additional-execution and persistence handlers | Contextual hunting leads, not unique proof of this implementation |
The generic browser user agent and claimed module/build names are context, not standalone high-confidence indicators. The submitted filenames need not be the filenames used on another system; check-in obtains the actual executable basename.
Security Weaknesses
- Recoverable protocol secrets and weak transport trust. Every sample embeds its token and symmetric key. B sends its token in a header over its compiled plain-HTTP connection and configures certificate verification to be skipped for HTTPS. GCM authenticates message bodies, but this does not make embedded secrets inaccessible or establish server-side authorization policy. An authorized deployment should use appropriately scoped/rotatable secrets, authenticated TLS, and constrained network exposure; server-side consequences cannot be audited from these clients alone.
- Unsafe temporary-file handling. Screenshot capture uses a fixed path, and additional execution uses a timestamp-based name with ordinary file writing rather than exclusive secure-temp creation. Concurrent tasks or local filesystem interference can cause collisions or unexpected file effects. Privileged use increases the potential impact. Authorized implementations should use private temporary directories, exclusive creation, and reliable cleanup.
- Fragile autostart construction. Persistence inserts the executable path without shell quoting; spaces, quotes, or shell metacharacters can break or alter the installed command. The Bash branch also ignores write/close failures. Authorized implementations should quote paths and verify the actual configuration write rather than trusting the returned success text.
Arbitrary shell execution, file access, and payload execution are intentional task capabilities here, not vulnerabilities inferred merely from their presence.
Checked and Not Found
These findings are limited to the fully decoded application slices, their task dispatch/data flow, exact-length literals, and file/process/network boundaries. We traced every application Base64-decoder call and GCM-wrapper caller; the automatic padded-XOR candidates were checked against original bytes and did not reveal an additional configuration population. No packer was recognized by file identification, and application instructions were statically recoverable. We did not attempt sample execution to strengthen any absence claim.
Dedicated behavior not found in that scope | Checks and result | Remaining qualification |
Credential-store/browser-wallet harvesting; keyboard, microphone, or camera capture | Complete dispatcher/handler review, referenced-literal search, and all application file/process boundary calls identified caller-selected file reading and screenshot capture, but no specialized routines for these other collection targets | A controller can still request secret files or run collection utilities through the generic commands/payload path |
Built-in privilege escalation or process injection | Application raw-syscall sites use PID/effective-UID discovery; mapped process operations launch child processes or signal PIDs. load_assembly writes and executes a file rather than injecting code | Starting the agent as root grants root's existing permissions; future commands/payloads are unknown |
Autonomous propagation | All application dial/listen sites map to controller communication or the described task/client-directed relays; no automated exploit/deployment sequence was found | Relays and remote commands can support operator-driven access to other systems |
Automated ransomware/wiping, dedicated security-tool disabling, or sandbox/debugger gates | Application encryption callers handle network messages; file-write provenance is server-supplied staging, temporary execution, or autostart text. We found no recursive encryption/wiping routine, security-target list, or custom analysis-environment gate in that code | Upload can overwrite files, kill_proc can terminate permitted targets, and shell commands can perform destructive or evasive actions; those effects are not ruled out |
The supporting boundary and encoding-caller inventories are saved in
analysis/capability-boundary-audit.json and analysis/encoding-caller-audit.json. Global native-analysis gaps and unsupplied task/payload content prevent treating these as universal guarantees.Alternative Explanations and Contrary Evidence
The strongest alternative to hostile use is a generated security-testing/post-exploitation agent. The implementation has a coherent task/report protocol, explicit task names, ordinary Go runtime/library code, and build metadata claiming a C2 payload-generation location. Its commands substantially match that purpose. These observations make a legitimate security-tool explanation credible, but the module claim alone does not authenticate it.
Conversely, the same program can remotely execute commands, extract files/screenshots, establish quiet autostart, and stage hidden temporary executables. Those properties warrant suspicion and preclude clearing it for general deployment without a trustworthy purpose and distribution context. The concern is the implemented design, not the shared IP address or filenames.
A's bad destination construction and the shared self-delete defect are contrary evidence to assuming a fully working operation, not evidence of harmless intent. B's retained TCP helpers and A/C's retained HTTP file helper also demonstrate why string presence alone would misstate their normal network behavior.
We do not assign a known malware-family name: the recovered code establishes a taskable Go remote-control implementation but does not provide a sufficiently distinctive, corroborated family match. Shared custom code supports an implementation relationship, not a common operator, campaign, compromise, or generation method.
Unknowns
- Historical execution and tasking: static startup/dispatch reconstruction cannot establish whether any sample ran, which tasks were issued, or which effects succeeded. Execution, handler invocation, and endpoint contact were expressly prohibited; no host telemetry or traffic capture was supplied.
- Controller behavior and compatibility: the endpoint was not contacted and no server was submitted. Whether it accepts both HTTP and
CSB1TCP on the configured port, accepts these credentials, or returns valid messages is unknown.
- A's target environment: passive syntax and linked-resolver analysis establish ordinary numeric/DNS failure and a local-hosts exception, but no actual hosts/NSS configuration was supplied. We cannot report an observed connection failure or absolute nonfunctionality.
- Further code and generic-command effects:
load_assembly, file staging, and shell tasks accept controller-provided content that is absent from the uploads. We analyzed those intake/execution paths, but no additional payload bytes exist here to characterize; fetching them would violate the analysis constraints.
- Whole-binary/source provenance: independent application disassembly addresses the main code paths, but native analysis remains incomplete as quantified above, and no authenticated source or known-good build was available for comparison. We do not authenticate the embedded project/compiler claims or rule out every possible behavior in linked code.
Verdict Rationale
We assess the set as suspicious with medium confidence. Each root contributes the same substantial remote-control capability set; B materially changes transport/concurrency, while A/C chiefly differ in configuration and its consequences. A's malformed default does not remove its implemented handlers, and no child behavior has been attributed to a parent without a recovered invocation path.
The code supports serious collection, execution, persistence, and network-access effects, with concealment-oriented details. It also remains internally consistent with a security-testing agent rather than demonstrating a separate, conclusive owner-hostile mechanism. That credible design alternative prevents an established-malicious conclusion; the concerning capabilities and quiet-use details prevent a benign clearance. This verdict does not depend on assuming unauthorized deployment, endpoint ownership, an unseen operator command, or an unrecovered payload's intent.
For an unexpected running instance, we would preserve its process/network evidence and inspect the invoking user's crontab,
.bashrc, relevant temporary files, and child processes. A returned stop/self-delete message is not sufficient containment: accepted proxy sessions, shell descendants, or persistence entries can survive the corresponding task behavior. We make no claim that any such artifacts or activity were observed in this investigation.About Delphos Labs Analysis
The Delphos platform analyzes compiled binaries directly and produces structured behavioral intelligence reports within minutes. This lets analysts understand what a binary does without manual analysis.
Request Access