Log Viewer

Monitor and search through operation logs and events.

A command-line tool for analyzing and correlating C2 agent command logs, providing insights into agent activity, command execution, and system performance.

Features

  • Log Correlation: Automatically correlates commands with their outputs using command IDs
  • Multiple Output Formats: Text, JSON, CSV, and table formats
  • Advanced Filtering: Filter by agent, hostname, IP, username, command type, OS, and session
  • Real-time Following: Follow logs in real-time (like tail -f)
  • Statistics: View command execution statistics and agent summaries
  • Date Range Support: Analyze logs from specific date ranges
  • Agent Enrichment: Automatically enriches logs with cached agent information

Log Location

Logs are stored in different locations depending on context:

ContextPath
Inside Docker containers/app/logs/commands/
On the host machineserver/docker/logs/commands/

The log directory is mounted as a volume, so logs persist across container restarts.


Installation

If Go is not installed locally, build using Docker:

cd /path/to/NexusC2
docker run --rm -v $(pwd)/server:/src -w /src golang:1.25-alpine \
    go build -o /src/logviewer ./cmd/logviewer

The binary will be created at server/logviewer.

Building Locally

If Go 1.25+ is installed:

cd server
go build -o logviewer ./cmd/logviewer

Basic Usage

View Recent Logs

# From host machine - specify the host log path
./logviewer -dir ./docker/logs/commands

# Inside Docker container - uses default path
./logviewer

View Specific Log File

./logviewer -file ./docker/logs/commands/commands_2026-01-15.log

Show Statistics

./logviewer -dir ./docker/logs/commands -stats

Example output:

=== Command Execution Statistics ===
Total commands: 11
Completed: 11
Pending: 0
Errors: 0
Avg response time: 11.204 seconds
Min response time: 4.710 seconds
Max response time: 18.755 seconds

=== Agent Statistics ===
Total unique agents: 1

Top agents by command count:
  04c0c127 (fsdev) - 192.168.21.129: 11 commands

Show Agent Summary

./logviewer -dir ./docker/logs/commands -agents

Example output:

=== Agent Summary ===
Agent     Hostname  External IP     Internal IP     OS     User    Commands  Sessions  Last Seen
04c0c127  fsdev     192.168.21.129  192.168.21.129  linux  nexus   11        1         01/15 19:40

Follow Logs in Real-time

./logviewer -dir ./docker/logs/commands -follow

Filtering

Filter by Agent

./logviewer -dir ./docker/logs/commands -agent 04c0c127

Filter by Multiple Criteria

# Find all commands from a specific host by a specific user
./logviewer -dir ./docker/logs/commands -host fsdev -user nexus

# Find all BOF commands on Windows systems
./logviewer -dir ./docker/logs/commands -type bof -os windows

# Filter by IP address (matches internal or external)
./logviewer -dir ./docker/logs/commands -ip 192.168.21.129

# Filter by session ID
./logviewer -dir ./docker/logs/commands -session session_04c0c127

Date Range Queries

# Last 7 days (default)
./logviewer -dir ./docker/logs/commands

# Specific date range
./logviewer -dir ./docker/logs/commands -from 2026-01-10 -to 2026-01-15

# Single day
./logviewer -dir ./docker/logs/commands -from 2026-01-15 -to 2026-01-15

Output Formats

Default Text Output

./logviewer -dir ./docker/logs/commands

Shows correlated command executions with full context:

=== Command Execution ===
Command ID: 1
Agent ID: 04c0c127-bc90-4f6b-b318-722949e18dce
User: nexus
Hostname: fsdev
IPs: 192.168.21.129 / 192.168.21.129
OS: linux
Session: session_04c0c127..._1768441601
Command: pwd
Sent: 2026-01-15T01:46:57Z
Status: completed
Output received: 2026-01-15T01:47:03Z
Response time: 6.076 seconds
Output size: 27 bytes
Output:
/home/sean/Desktop/payloads

JSON Output

./logviewer -dir ./docker/logs/commands -json
# or
./logviewer -dir ./docker/logs/commands -format json

CSV Export

./logviewer -dir ./docker/logs/commands -format csv > commands_export.csv

Table Format

./logviewer -dir ./docker/logs/commands -format table

Verbose Output

./logviewer -dir ./docker/logs/commands -v

Special Views

Show Only Pending Commands

./logviewer -dir ./docker/logs/commands -pending

Show Only Errors

./logviewer -dir ./docker/logs/commands -errors

Sorting Options

# Sort by time (default)
./logviewer -dir ./docker/logs/commands -sort time

# Sort by agent ID
./logviewer -dir ./docker/logs/commands -sort agent

# Sort by hostname
./logviewer -dir ./docker/logs/commands -sort host

# Sort by IP
./logviewer -dir ./docker/logs/commands -sort ip

# Sort by username
./logviewer -dir ./docker/logs/commands -sort user

# Sort by command
./logviewer -dir ./docker/logs/commands -sort command

# Reverse sort order
./logviewer -dir ./docker/logs/commands -sort time -reverse

Command Flags Reference

FlagDescriptionDefault
-dirLog directory path/app/logs/commands
-fileSpecific log fileToday’s log
-agentFilter by agent ID (partial match)None
-hostFilter by hostname (partial match)None
-ipFilter by IP (partial match)None
-userFilter by username (partial match)None
-typeFilter by command type (ls, pwd, bof, etc.)None
-osFilter by OSNone
-sessionFilter by session IDNone
-formatOutput format: text, json, csv, tabletext
-jsonOutput as JSON (shortcut for -format json)false
-vVerbose output (show all fields)false
-statsShow statisticsfalse
-agentsShow agent summaryfalse
-pendingShow pending commands onlyfalse
-errorsShow errors onlyfalse
-followFollow log file in real-timefalse
-fromStart date (YYYY-MM-DD)7 days ago
-toEnd date (YYYY-MM-DD)Today
-sortSort by: time, agent, host, ip, user, commandtime
-reverseReverse sort orderfalse

Log File Structure

Logs are stored as JSON lines (one JSON object per line) with the following fields:

{
  "timestamp": "2026-01-15T01:46:57.316514126Z",
  "type": "command",
  "agent_id": "04c0c127-bc90-4f6b-b318-722949e18dce",
  "username": "nexus",
  "command": "pwd",
  "command_id": 1,
  "command_type": "pwd",
  "hostname": "fsdev",
  "external_ip": "192.168.21.129",
  "internal_ip": "192.168.21.129",
  "os": "linux",
  "arch": "amd64",
  "process": "https_go_amd64_HTTPS_payload.bin",
  "pid": "398071",
  "integrity": "medium",
  "session_id": "session_04c0c127..._1768441601"
}

Log Entry Types

TypeDescription
connectionNew agent connection with full agent details
checkinAgent heartbeat/check-in
commandCommand issued to an agent
outputCommand output received from agent
errorError during command execution

Log Rotation

Daily Rotation

  • New log file created at midnight each day
  • Format: commands_YYYY-MM-DD.log

Size-based Rotation

  • Default maximum file size: 100MB
  • When exceeded, files are numbered sequentially:
    • commands_2026-01-15.log (first file)
    • commands_2026-01-15_1.log (first rotation)
    • commands_2026-01-15_2.log (second rotation)

Automatic Archiving

  • Previous day’s logs are automatically compressed to archive/commands_YYYY-MM-DD.tar.gz
  • Original files are deleted after successful archiving

Integration with Other Tools

Export for External Analysis

# Export to JSON for processing with jq
./logviewer -dir ./docker/logs/commands -format json | jq '.[] | select(.command_type=="bof")'

# Export to CSV for Excel/Google Sheets
./logviewer -dir ./docker/logs/commands -format csv > analysis.csv

# Pipe to grep for additional filtering
./logviewer -dir ./docker/logs/commands | grep -i "error"

Scheduled Reports

Create a cron job for daily reports:

0 2 * * * /path/to/logviewer -dir /path/to/logs/commands -stats -format json > /path/to/reports/daily_$(date +%Y%m%d).json

Troubleshooting

No logs found

  • Verify the log directory path is correct
  • On host: server/docker/logs/commands/
  • In Docker: /app/logs/commands/
  • Check the date range includes existing logs
  • Ensure log files follow naming convention: commands_YYYY-MM-DD.log

Missing agent information in some entries

  • Agent information is cached when agents first connect
  • After service restarts, checkin entries may lack enriched data until the agent reconnects
  • Full agent context is restored on the next connection event

Duplicate commands in output

  • The correlator automatically deduplicates based on command ID
  • Use -v to see command IDs and verify correlation

ComponentFile Path
Log Viewer Sourceserver/cmd/logviewer/main.go
Logger Implementationserver/internal/common/logging/command_logger.go
Log Correlatorserver/internal/common/logging/correlator.go
Log Directory (Host)server/docker/logs/commands/
Log Archivesserver/docker/logs/commands/archive/
to navigate to select ESC to close
Powered by Pagefind