Back to Intelligence

GSocket C2 on Linux Servers: Detection, Hunting, and Remediation Guide for Stealthy Post-Exploit Persistence

SA
Security Arsenal Team
November 13, 2026
21 min read

Microsoft's security research team has documented an active and growing trend that should concern every organization running Linux infrastructure: threat actors are deploying GSocket (Global Socket) — a legitimate open-source networking tool — as a stealthy, encrypted command-and-control channel on compromised servers. The critical insight here is that this activity persists after the original vulnerability used for initial access has been identified and patched. Your remediation is incomplete if you haven't hunted for the persistence mechanisms the attacker left behind.

This is not a theoretical concern. This is an observed, active TTP being used in real intrusions right now, and it exploits a fundamental blind spot in most organizations' incident response playbooks: the assumption that patching the entry vector ends the incident.

If your organization runs internet-facing Linux servers — web servers, application servers, cloud VMs, containers, or network appliances — this post is directly relevant to you. Read on for detection logic, hunt queries, and a concrete remediation playbook.


What Is GSocket and Why Are Attackers Using It?

GSocket (Global Socket, available at github.com/hackerschoice/gsocket) is an open-source tool originally designed for legitimate remote access and file transfer across NAT and firewall boundaries. It creates encrypted, persistent connections through firewalls and NAT gateways without requiring port forwarding, using relay servers to broker connections between endpoints.

Here's why threat actors have adopted it as a post-exploitation tool:

  • NAT/Firewall Traversal: GSocket is designed to punch through NAT and firewalls. The compromised host initiates an outbound connection to a GSocket relay — meaning no inbound firewall rule changes are needed and the traffic appears as outbound HTTPS-like connections.
  • End-to-End Encryption: All GSocket traffic is encrypted using SRP (Secure Remote Password) authentication and AES-256. Network-based detection of the payload content is effectively impossible.
  • No Installation Required: GSocket binaries are statically compiled and can be dropped as a single file. No package manager interaction, no dependency chain, no installation artifacts in system logs.
  • Stealth by Design: GSocket processes can masquerade as legitimate system processes. The tool supports running under arbitrary process names, making casual process listing inspection unreliable.
  • Persistence Without Cron or systemd: While GSocket can be configured with standard persistence mechanisms, the tool itself maintains long-lived connections that survive reboots if paired with even a minimal startup hook.
  • Legitimate-Looking Traffic: The outbound connections to GSocket relay infrastructure use standard TLS on port 443, blending with legitimate HTTPS traffic at the network layer.

The key point for defenders: GSocket is not malware in the traditional sense. It won't be flagged by most signature-based antivirus. It doesn't exploit a vulnerability itself. It's a legitimate tool being weaponized, which means detection must be behavioral and contextual, not signature-based.


Attack Chain: How GSocket Gets Deployed

Based on the Microsoft Security Blog reporting, the observed attack chain follows a consistent pattern:

  1. Initial Access: The attacker exploits a vulnerability in an internet-facing service — this could be a web application vulnerability, an unpatched service, weak SSH credentials, or any other initial access vector. This is the vulnerability you'll eventually find and patch.

  2. Post-Exploitation Foothold: After gaining code execution on the target Linux server, the attacker downloads the GSocket binary. This is typically done via curl, wget, or a base64-encoded payload piped through a shell. The binary is placed in a location designed to avoid casual inspection — common locations include /tmp/, /dev/shm/, /var/tmp/, or directories with names designed to look legitimate (e.g., /usr/lib/.cache/, hidden directories in web roots).

  3. GSocket Deployment: The attacker executes the GSocket binary (typically gs-netcat or a renamed variant) with parameters to establish a persistent connection through the GSocket relay network. The process is often renamed or uses the -D (daemon) flag to detach from the terminal.

  4. Persistence Establishment: The attacker may create a systemd service, cron job, rc.local entry, or bashrc profile modification to ensure GSocket restarts after reboots. In some observed cases, the persistence mechanism is deliberately minimal — a single line added to an existing legitimate service file.

  5. Ongoing Access: The attacker now has an encrypted, persistent remote access channel that survives patching of the original vulnerability. They can return at any time to execute commands, exfiltrate data, deploy additional payloads, or pivot to other systems.

This is why your incident response process is failing if it stops at patching. The vulnerability was the door; GSocket is the key the attacker made copies of before you changed the lock.


Technical Indicators: What to Look For

Process Indicators

  • Processes named gs-netcat, gsocket, gs-sftp, gs-mount, or renamed variants running from non-standard paths
  • Processes with command-line arguments containing GSocket flags: -s (secret/seed), -k (key file), -D (daemon mode), -q (quiet), -l (listen), -i (interactive shell)
  • Processes running from /tmp/, /dev/shm/, /var/tmp/, or hidden directories
  • Long-running processes with established outbound TLS connections that don't correspond to known application behavior
  • Processes masquerading as legitimate system services but running from unusual paths or with unusual parent processes

Network Indicators

  • Outbound TLS connections on port 443 to IP addresses or domains not associated with known business services
  • Persistent, long-duration outbound connections that maintain state for hours or days (GSocket maintains persistent connections rather than periodic beacons)
  • Connections to known GSocket relay infrastructure (the default relay is at gsocket.io infrastructure, though actors may run private relays)
  • TLS connections that don't match expected SNI patterns for the server's role

File System Indicators

  • Statically compiled ELF binaries in temporary or hidden directories
  • GSocket binaries are typically 2-5 MB, statically linked, and may have names designed to blend in (e.g., kworker, systemd-helper, cron-update)
  • Files with execution permissions in world-writable directories
  • Modified systemd unit files, cron entries, or shell profile files referencing unusual binary paths

Persistence Indicators

  • New or modified systemd service files (/etc/systemd/system/, /usr/lib/systemd/system/)
  • Cron entries in /etc/cron.d/, /etc/crontab, or user crontabs referencing unusual binaries
  • Modifications to ~/.bashrc, ~/.bash_profile, /etc/rc.local, or /etc/profile.d/ scripts
  • Entries in /etc/init.d/ or systemd targets that weren't created by package management

Detection & Response

SIGMA Rules

YAML
---
title: GSocket C2 Binary Execution on Linux
id: 8f3a2b17-4c5d-4e6f-9a1b-2c3d4e5f6a7b
status: experimental
description: Detects execution of GSocket (gs-netcat) binaries or renamed variants with characteristic command-line arguments used for establishing encrypted C2 channels.
references:
  - https://www.microsoft.com/en-us/security/blog/2026/11/11/global-socket-how-threat-actors-weaponizing-gsocket-stealthy-c2/
  - https://attack.mitre.org/techniques/T1105/
  - https://attack.mitre.org/techniques/T1572/
author: Security Arsenal
date: 2026/11/12
tags:
  - attack.command_and_control
  - attack.t1105
  - attack.t1572
logsource:
  category: process_creation
  product: linux
detection:
  selection_binary:
    Image|endswith:
      - '/gs-netcat'
      - '/gsocket'
      - '/gs-sftp'
      - '/gs-mount'
  selection_args:
    CommandLine|contains:
      - 'gs-netcat'
      - 'gsocket'
  selection_flags:
    CommandLine|contains:
      - ' -s '
      - ' -D '
    CommandLine|re: 'gs-netcat.*-s\s+[A-Za-z0-9]{20,}'
  condition: selection_binary or selection_args or (selection_flags and selection_flags)
falsepositives:
  - Legitimate use of GSocket by system administrators for remote access (should be documented and whitelisted)
  - Developers testing GSocket in development environments
level: high
---
title: Suspicious Process Executing from Temporary or Hidden Directory on Linux
id: 2b4c6d8e-1f3a-4b5c-9d7e-8f2a3b4c5d6e
status: experimental
description: Detects execution of ELF binaries from temporary directories, shared memory, or hidden paths commonly used by threat actors to deploy GSocket and other post-exploitation tools on Linux servers.
references:
  - https://www.microsoft.com/en-us/security/blog/2026/11/11/global-socket-how-threat-actors-weaponizing-gsocket-stealthy-c2/
  - https://attack.mitre.org/techniques/T1059/
  - https://attack.mitre.org/techniques/T1036/
author: Security Arsenal
date: 2026/11/12
tags:
  - attack.defense_evasion
  - attack.t1036
  - attack.execution
  - attack.t1059
logsource:
  category: process_creation
  product: linux
detection:
  selection_path:
    Image|startswith:
      - '/tmp/'
      - '/var/tmp/'
      - '/dev/shm/'
      - '/run/shm/'
  selection_hidden:
    Image|contains: '/.'
    Image|startswith:
      - '/usr/lib/'
      - '/opt/'
      - '/var/www/'
      - '/home/'
  filter_legitimate_tmp:
    Image|startswith:
      - '/tmp/.X11-unix/'
      - '/tmp/.ICE-unix/'
      - '/tmp/snap.'
    Image|contains:
      - '/.cache/'
      - '/.config/'
      - '/.local/'
      - '/node_modules/'
  filter_package_managers:
    ParentImage|endswith:
      - '/dpkg'
      - '/apt'
      - '/apt-get'
      - '/yum'
      - '/dnf'
      - '/rpm'
      - '/pip'
      - '/npm'
      - '/snapd'
  condition: (selection_path or selection_hidden) and not filter_legitimate_tmp and not filter_package_managers
falsepositives:
  - Build processes compiling and testing binaries in /tmp
  - Container runtimes executing binaries from tmpfs mounts
  - Some monitoring agents deploy to temporary paths
level: medium
---
title: GSocket Persistence via Systemd Service or Cron
id: 5e7f9a1b-3c4d-5e6f-7a8b-9c0d1e2f3a4b
status: experimental
description: Detects creation or modification of systemd service files or cron entries that reference binaries in non-standard paths, consistent with GSocket persistence mechanisms.
references:
  - https://www.microsoft.com/en-us/security/blog/2026/11/11/global-socket-how-threat-actors-weaponizing-gsocket-stealthy-c2/
  - https://attack.mitre.org/techniques/T1053/
  - https://attack.mitre.org/techniques/T1543/
author: Security Arsenal
date: 2026/11/12
tags:
  - attack.persistence
  - attack.t1053.003
  - attack.t1543.002
logsource:
  category: file_event
  product: linux
detection:
  selection_systemd:
    TargetFilename|startswith:
      - '/etc/systemd/system/'
      - '/usr/lib/systemd/system/'
      - '/run/systemd/system/'
    TargetFilename|endswith: '.service'
  selection_cron:
    TargetFilename|startswith:
      - '/etc/cron.d/'
      - '/var/spool/cron/'
    TargetFilename: '/etc/crontab'
  selection_shell_rc:
    TargetFilename:
      - '/etc/rc.local'
      - '/etc/profile'
    TargetFilename|endswith:
      - '/.bashrc'
      - '/.bash_profile'
      - '/.profile'
  filter_package_managed:
    TargetFilename|contains:
      - '/usr/lib/systemd/system/'
    Image|endswith:
      - '/dpkg'
      - '/apt'
      - '/rpm'
      - '/yum'
      - '/dnf'
      - '/systemd'
  condition: (selection_systemd or selection_cron or selection_shell_rc) and not filter_package_managed
falsepositives:
  - System administrators creating custom service files
  - Configuration management tools (Ansible, Puppet, Chef) deploying services
  - Application installers creating systemd units
level: medium

KQL Hunt Query (Microsoft Sentinel / Defender)

The following query hunts for GSocket deployment and C2 activity across multiple data sources. It correlates process execution, network connections, and file creation events. This assumes you have Linux sysmon, auditd, or Defender for Endpoint data flowing into Sentinel.

KQL — Microsoft Sentinel / Defender
// Hunt: GSocket C2 Deployment and Activity on Linux Servers
// Correlates process execution, network connections, and persistence artifacts
// Timeframe: Last 14 days (adjust as needed)

let timeframe = 14d;

// Stage 1: Identify potential GSocket binary drops in suspicious locations
let SuspiciousFileDrops =
    DeviceFileEvents
    | where TimeGenerated > ago(timeframe)
    | where FolderPath has_any ("/tmp/", "/var/tmp/", "/dev/shm/", "/run/shm/")
    | where FileName !has_any (".log", ".tmp", ".pid", ".lock", ".sock")
    | project FileDropTime=TimeGenerated, DeviceId, DeviceName, FileName, FolderPath, InitiatingProcessFileName, InitiatingProcessCommandLine, SHA256;

// Stage 2: Identify GSocket process execution or execution from suspicious paths
let SuspiciousProcessExec =
    DeviceProcessEvents
    | where TimeGenerated > ago(timeframe)
    | where ProcessCommandLine has_any ("gs-netcat", "gsocket", "gs-sftp", "gs-mount")
       or (FolderPath has_any ("/tmp/", "/var/tmp/", "/dev/shm/") 
           and ProcessCommandLine has_any ("-s ", "-D", "-q", "-i"))
       or (FileName in~ ("gs-netcat", "gsocket", "gs-sftp", "gs-mount"))
    | project ProcessExecTime=TimeGenerated, DeviceId, DeviceName, 
              FileName, ProcessCommandLine, FolderPath,
              InitiatingProcessFileName, InitiatingProcessCommandLine,
              InitiatingProcessParentFileName, AccountName, ProcessId;

// Stage 3: Identify outbound TLS connections from suspicious processes
let SuspiciousNetwork =
    DeviceNetworkEvents
    | where TimeGenerated > ago(timeframe)
    | where RemotePort == 443
    | where ActionType == "ConnectionSuccess"
    | where InitiatingProcessFolderPath has_any ("/tmp/", "/var/tmp/", "/dev/shm/")
       or InitiatingProcessFileName in~ ("gs-netcat", "gsocket", "gs-sftp", "gs-mount")
    | summarize ConnectionCount=count(), 
                RemoteIPs=make_set(RemoteIP, 10), 
                RemoteURLs=make_set(RemoteUrl, 10),
                FirstConnection=min(TimeGenerated),
                LastConnection=max(TimeGenerated)
    by DeviceId, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine;

// Stage 4: Identify persistence mechanism creation
let PersistenceArtifacts =
    DeviceFileEvents
    | where TimeGenerated > ago(timeframe)
    | where FolderPath has_any ("/etc/systemd/system/", "/etc/cron.d/", "/var/spool/cron/")
       or FileName in~ ("crontab", "rc.local")
    | where ActionType in ("FileCreated", "FileModified")
    | where InitiatingProcessFileName !in~ ("dpkg", "apt", "apt-get", "yum", "dnf", "rpm", "snapd", "systemctl", "systemd")
    | project PersistTime=TimeGenerated, DeviceId, DeviceName, FileName, FolderPath, InitiatingProcessFileName, InitiatingProcessCommandLine;

// Correlate all stages
SuspiciousProcessExec
| join kind=leftouter SuspiciousNetwork on DeviceId
| join kind=leftouter PersistenceArtifacts on DeviceId
| join kind=leftouter SuspiciousFileDrops on DeviceId
| project ProcessExecTime, DeviceName, FileName, ProcessCommandLine, FolderPath,
          InitiatingProcessFileName, InitiatingProcessCommandLine,
          ConnectionCount, RemoteIPs, RemoteURLs, FirstConnection, LastConnection,
          PersistTime, FileName1, FolderPath1, InitiatingProcessFileName1,
          FileDropTime, FileName2, FolderPath2
| order by ProcessExecTime desc

Additional Syslog-based query for environments ingesting Linux auth and syslog data:

KQL — Microsoft Sentinel / Defender
// Hunt: GSocket artifacts in Syslog and auth logs
// Looks for process execution, suspicious connections, and service installation events

let timeframe = 14d;

union isfuzzy=true
    (Syslog
    | where TimeGenerated > ago(timeframe)
    | where SyslogMessage has_any ("gs-netcat", "gsocket", "gs-sftp")
    | project TimeGenerated, Computer, ProcessName, SyslogMessage, Source="Syslog"),
    (CommonSecurityLog
    | where TimeGenerated > ago(timeframe)
    | where DestinationPort == 443
    | where DeviceAction == "permit"
    | where SourceHostName has_any ("tmp", "shm")
       or Message has_any ("gs-netcat", "gsocket")
    | project TimeGenerated, Computer=SourceHostName, ProcessName=ApplicationProtocol, SyslogMessage=Message, Source="CEF"),
    (SecurityEvent
    | where TimeGenerated > ago(timeframe)
    | where EventID == 4688
    | where CommandLine has_any ("gs-netcat", "gsocket", "/tmp/", "/dev/shm/")
       and CommandLine has_any ("-s ", "-D", "-q")
    | project TimeGenerated, Computer, ProcessName=NewProcessName, SyslogMessage=CommandLine, Source="WinEvent")
| order by TimeGenerated desc

Velociraptor VQL Hunt

The following VQL artifact hunts for GSocket processes, suspicious network connections, and persistence artifacts on Linux endpoints. Deploy this as a hunt across your Linux fleet.

VQL — Velociraptor
-- Hunt: GSocket C2 Detection on Linux Endpoints
-- Targets: Running processes, network connections, persistence mechanisms, file artifacts
-- Author: Security Arsenal
-- Date: 2026-11-12

-- Section 1: Find running GSocket processes or suspicious processes from temp directories
LET suspicious_processes =
SELECT Pid, Ppid, Name, Exe, CommandLine, Username, CreateTime,
       "RunningProcess" AS ArtifactType
FROM pslist()
WHERE CommandLine =~ '(gs-netcat|gsocket|gs-sftp|gs-mount)'
   OR Name =~ '(gs-netcat|gsocket|gs-sftp|gs-mount)'
   OR (Exe =~ '^/(tmp|var/tmp|dev/shm|run/shm)/' 
       AND CommandLine =~ '(-s\s|-D|-q|-i)')
   OR (Exe =~ '^/(tmp|var/tmp|dev/shm)/'
       AND Name !~ '(\.log|\.tmp|\.pid|snap|X11)')

-- Section 2: Find established outbound TLS connections from suspicious processes
LET suspicious_connections =
SELECT Pid, Name, Exe,
       local_address, local_port,
       remote_address, remote_port,
       status,
       "NetworkConnection" AS ArtifactType
FROM netstat()
WHERE remote_port == 443
  AND status =~ 'ESTABLISHED'
  AND (Exe =~ '^/(tmp|var/tmp|dev/shm)/'
       OR Name =~ '(gs-netcat|gsocket|gs-sftp)')

-- Section 3: Check systemd services for suspicious entries
LET systemd_services =
SELECT FullPath AS ServicePath,
       Name AS ServiceName,
       "SystemdService" AS ArtifactType
FROM glob(globs='/etc/systemd/system/*.service')
WHERE ServiceName !~ '(apache|nginx|mysql|postgresql|redis|docker|containerd|kubelet|ssh|cron|rsyslog|systemd-|snap|NetworkManager|chrony|ntpd|firewalld|auditd|polkit|dbus|accounts|bluetooth|cups|gdm|lightdm|ModemManager|networkd|resolved|timesyncd|udev|upower|wpa)'

-- Section 4: Check for recently modified cron files
LET cron_artifacts =
SELECT FullPath AS CronPath,
       Mtime AS ModifiedTime,
       "CronPersistence" AS ArtifactType
FROM glob(globs='/etc/cron.d/*')
WHERE Mtime > now() - 1209600  -- Last 14 days

-- Section 5: Check for executable files in suspicious locations
LET suspicious_files =
SELECT FullPath AS FilePath,
       Size AS FileSize,
       Mtime AS ModifiedTime,
       "SuspiciousFile" AS ArtifactType
FROM glob(globs='/tmp/*,/var/tmp/*,/dev/shm/*')
WHERE Size > 1000000  -- Larger than 1MB (GSocket binaries are typically 2-5MB)
  AND FilePath !~ '(\.log|\.tmp|\.pid|\.lock|\.sock|X11|ICE|snap)'

-- Combine all findings
SELECT * FROM suspicious_processes
UNION ALL
SELECT Pid, NULL, Name, Exe, NULL, NULL, NULL, ArtifactType FROM suspicious_connections
UNION ALL
SELECT NULL, NULL, ServiceName, ServicePath, NULL, NULL, NULL, ArtifactType FROM systemd_services
UNION ALL
SELECT NULL, NULL, NULL, CronPath, NULL, NULL, ModifiedTime, ArtifactType FROM cron_artifacts
UNION ALL
SELECT NULL, NULL, NULL, FilePath, NULL, NULL, ModifiedTime, ArtifactType FROM suspicious_files

Remediation Script

Deploy this bash script on Linux servers to detect, contain, and remediate GSocket infections. This script is designed to be run as root on suspected compromised systems.

Bash / Shell
#!/bin/bash
# GSocket C2 Detection and Remediation Script
# Security Arsenal - 2026-11-12
# Run as root on suspected compromised Linux servers
# WARNING: Review output before taking action. This script identifies but does not
# automatically remove findings unless --remediate flag is passed.

set -euo pipefail

RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
NC='\033[0m'

REMEDIATE=false
if [[ "${1:-}" == "--remediate" ]]; then
    REMEDIATE=true
    echo -e "${YELLOW}[!] REMEDIATION MODE ENABLED - suspicious processes will be killed${NC}"
fi

LOGFILE="/var/log/gsocket_hunt_$(date +%Y%m%d_%H%M%S).log"
echo "=== GSocket C2 Detection Script ===" | tee "$LOGFILE"
echo "Hostname: $(hostname)" | tee -a "$LOGFILE"
echo "Date: $(date)" | tee -a "$LOGFILE"
echo "" | tee -a "$LOGFILE"

# --- SECTION 1: Detect running GSocket processes ---
echo -e "${YELLOW}[*] Section 1: Scanning for GSocket processes...${NC}" | tee -a "$LOGFILE"

GSOCKET_PIDS=$(ps aux | grep -E '(gs-netcat|gsocket|gs-sftp|gs-mount)' | grep -v grep | awk '{print $2}' || true)

if [[ -n "$GSOCKET_PIDS" ]]; then
    echo -e "${RED}[!] FOUND: GSocket processes running!${NC}" | tee -a "$LOGFILE"
    ps aux | grep -E '(gs-netcat|gsocket|gs-sftp|gs-mount)' | grep -v grep | tee -a "$LOGFILE"
    for pid in $GSOCKET_PIDS; do
        echo "  PID: $pid" | tee -a "$LOGFILE"
        echo "  Binary: $(readlink -f /proc/$pid/exe 2>/dev/null || echo 'N/A')" | tee -a "$LOGFILE"
        echo "  Cmdline: $(cat /proc/$pid/cmdline 2>/dev/null | tr '\0' ' ' || echo 'N/A')" | tee -a "$LOGFILE"
        echo "  CWD: $(readlink -f /proc/$pid/cwd 2>/dev/null || echo 'N/A')" | tee -a "$LOGFILE"
        ls -la /proc/$pid/fd 2>/dev/null | head -20 | tee -a "$LOGFILE"
    done
    if $REMEDIATE; then
        for pid in $GSOCKET_PIDS; do
            echo -e "${RED}[!] Killing PID $pid${NC}" | tee -a "$LOGFILE"
            kill -9 "$pid" 2>/dev/null || true
        done
    fi
else
    echo -e "${GREEN}[+] No GSocket processes found${NC}" | tee -a "$LOGFILE"
fi

# --- SECTION 2: Detect processes running from suspicious paths ---
echo "" | tee -a "$LOGFILE"
echo -e "${YELLOW}[*] Section 2: Scanning for processes executing from temp/hidden paths...${NC}" | tee -a "$LOGFILE"

SUSPICIOUS_PIDS=$(find /tmp /var/tmp /dev/shm /run/shm -type f -executable 2>/dev/null | while read -r f; do
    pidof "$(basename "$f")" 2>/dev/null || true
done | sort -u || true)

# Also check /proc for executables mapped from suspicious paths
for pid_dir in /proc/[0-9]*/exe; do
    pid=$(echo "$pid_dir" | cut -d/ -f3)
    exe_path=$(readlink -f "$pid_dir" 2>/dev/null || true)
    if [[ "$exe_path" =~ ^/(tmp|var/tmp|dev/shm|run/shm)/ ]]; then
        if [[ ! "$exe_path" =~ (snap|X11|ICE|\.log|\.tmp) ]]; then
            echo -e "${RED}[!] Suspicious process from temp path: PID=$pid, Path=$exe_path${NC}" | tee -a "$LOGFILE"
            cat "/proc/$pid/cmdline" 2>/dev/null | tr '\0' ' ' | tee -a "$LOGFILE"
            echo "" | tee -a "$LOGFILE"
        fi
    fi
done

# --- SECTION 3: Check network connections ---
echo "" | tee -a "$LOGFILE"
echo -e "${YELLOW}[*] Section 3: Checking for suspicious outbound TLS connections...${NC}" | tee -a "$LOGFILE"

if command -v ss &>/dev/null; then
    ss -tnp state established '( dport = :443 )' 2>/dev/null | while read -r line; do
        if echo "$line" | grep -qE '(tmp|shm|gs-netcat|gsocket)'; then
            echo -e "${RED}[!] Suspicious TLS connection: $line${NC}" | tee -a "$LOGFILE"
        fi
    done
    # Show all established outbound 443 connections for review
    echo "  All established outbound :443 connections:" | tee -a "$LOGFILE"
    ss -tnp state established '( dport = :443 )' 2>/dev/null | tee -a "$LOGFILE"
fi

# --- SECTION 4: Check for GSocket files on disk ---
echo "" | tee -a "$LOGFILE"
echo -e "${YELLOW}[*] Section 4: Scanning for GSocket binaries on disk...${NC}" | tee -a "$LOGFILE"

GSOCKET_FILES=$(find / -maxdepth 4 -type f \( -name 'gs-netcat' -o -name 'gsocket' -o -name 'gs-sftp' -o -name 'gs-mount' \) 2>/dev/null || true)

# Also check for large executables in temp directories
TEMP_EXECS=$(find /tmp /var/tmp /dev/shm /run/shm -type f -executable -size +1M 2>/dev/null || true)

if [[ -n "$GSOCKET_FILES" ]]; then
    echo -e "${RED}[!] FOUND: GSocket binary files!${NC}" | tee -a "$LOGFILE"
    echo "$GSOCKET_FILES" | while read -r f; do
        echo "  File: $f" | tee -a "$LOGFILE"
        ls -la "$f" | tee -a "$LOGFILE"
        file "$f" | tee -a "$LOGFILE"
        md5sum "$f" | tee -a "$LOGFILE"
        sha256sum "$f" | tee -a "$LOGFILE"
    done
fi

if [[ -n "$TEMP_EXECS" ]]; then
    echo -e "${YELLOW}[!] Large executable files in temp directories (review for GSocket):${NC}" | tee -a "$LOGFILE"
    echo "$TEMP_EXECS" | while read -r f; do
        if [[ ! "$f" =~ (snap|X11|ICE) ]]; then
            echo "  File: $f ($(stat -c%s "$f" 2>/dev/null) bytes)" | tee -a "$LOGFILE"
            file "$f" 2>/dev/null | tee -a "$LOGFILE"
            sha256sum "$f" 2>/dev/null | tee -a "$LOGFILE"
        fi
    done
fi

if [[ -z "$GSOCKET_FILES" && -z "$TEMP_EXECS" ]]; then
    echo -e "${GREEN}[+] No GSocket binaries or suspicious executables found${NC}" | tee -a "$LOGFILE"
fi

# --- SECTION 5: Check persistence mechanisms ---
echo "" | tee -a "$LOGFILE"
echo -e "${YELLOW}[*] Section 5: Checking persistence mechanisms...${NC}" | tee -a "$LOGFILE"

echo "  Recent systemd services (last 30 days):" | tee -a "$LOGFILE"
find /etc/systemd/system/ -name '*.service' -mtime -30 2>/dev/null | while read -r svc; do
    echo "  Service: $svc" | tee -a "$LOGFILE"
    grep -E '(ExecStart|ExecStartPre|ExecStartPost)' "$svc" 2>/dev/null | tee -a "$LOGFILE"
done

echo "" | tee -a "$LOGFILE"
echo "  Cron entries (non-standard):" | tee -a "$LOGFILE"
ls -la /etc/cron.d/ 2>/dev/null | tee -a "$LOGFILE"
crontab -l 2>/dev/null | tee -a "$LOGFILE"
for user_home in /home/*/; do
    user=$(basename "$user_home")
    crontab -u "$user" -l 2>/dev/null | while read -r line; do
        if echo "$line" | grep -qE '(tmp|shm|gs-netcat|gsocket|curl|wget|base64)'; then
            echo -e "${RED}[!] Suspicious cron entry for $user: $line${NC}" | tee -a "$LOGFILE"
        fi
    done
done

echo "" | tee -a "$LOGFILE"
echo "  Shell rc files with suspicious entries:" | tee -a "$LOGFILE"
for rcfile in /etc/rc.local /etc/profile /root/.bashrc /root/.bash_profile /home/*/.bashrc /home/*/.bash_profile; do
    if [[ -f "$rcfile" ]]; then
        if grep -qE '(tmp|shm|gs-netcat|gsocket|curl.*http|wget.*http|base64.*-d)' "$rcfile" 2>/dev/null; then
            echo -e "${RED}[!] Suspicious entries in $rcfile:${NC}" | tee -a "$LOGFILE"
            grep -nE '(tmp|shm|gs-netcat|gsocket|curl.*http|wget.*http|base64.*-d)' "$rcfile" 2>/dev/null | tee -a "$LOGFILE"
        fi
    fi
done

# --- SECTION 6: Check for hidden directories and files ---
echo "" | tee -a "$LOGFILE"
echo -e "${YELLOW}[*] Section 6: Scanning for hidden files and directories...${NC}" | tee -a "$LOGFILE"

find /tmp /var/tmp /dev/shm /usr/lib /opt -maxdepth 3 -name '.*' -type d 2>/dev/null | while read -r d; do
    if [[ ! "$d" =~ (\.cache|\.config|\.local|\.mozilla|\.ssh|\.gnupg|\.npm|\.cargo|\.rustup) ]]; then
        echo -e "${YELLOW}[!] Hidden directory: $d${NC}" | tee -a "$LOGFILE"
        ls -la "$d" 2>/dev/null | head -10 | tee -a "$LOGFILE"
    fi
done

# --- Summary ---
echo "" | tee -a "$LOGFILE"
echo "========================================" | tee -a "$LOGFILE"
echo -e "${GREEN}[+] Scan complete. Results logged to: $LOGFILE${NC}" | tee -a "$LOGFILE"
echo "" | tee -a "$LOGFILE"
echo "NEXT STEPS IF FINDINGS DETECTED:" | tee -a "$LOGFILE"
echo "1. Preserve evidence: capture memory (use avml or LiME), copy suspicious binaries" | tee -a "$LOGFILE"
echo "2. Isolate the host from the network (do NOT power off)" | tee -a "$LOGFILE"
echo "3. Review all network connections for lateral movement indicators" | tee -a "$LOGFILE"
echo "4. Check authentication logs for additional compromised accounts" | tee -a "$LOGFILE"
echo "5. Identify and patch the initial access vector" | tee -a "$LOGFILE"
echo "6. Rotate ALL credentials accessible from this host" | tee -a "$LOGFILE"
echo "7. Rebuild from known-good image if compromise is confirmed" | tee -a "$LOGFILE"

Remediation: Beyond Patching the Entry Point

If you've identified GSocket on a compromised system, here's your prioritized remediation playbook:

Immediate Actions (Within 1 Hour)

  1. Isolate the host — Do not power off. Disconnect from the network or apply egress firewall rules to block outbound 443 to unauthorized destinations. GSocket's value to the attacker is its persistent connection; severing it limits further damage.

  2. Capture forensic evidence — Before killing any processes, capture memory. Use avml (Microsoft's Acquire Volatile Memory for Linux) or LiME to create a memory image. Copy all suspicious binaries, service files, cron entries, and shell history to a forensic workstation.

  3. Kill GSocket processes — Terminate all identified GSocket processes. Note their PIDs, parent processes, and command-line arguments before termination.

  4. Remove persistence mechanisms — Delete or revert any modified systemd services, cron entries, rc.local modifications, and shell profile changes.

Short-Term Actions (Within 24 Hours)

  1. Identify the initial access vector — Review web server logs, authentication logs, and vulnerability scan results to determine how the attacker gained access. Patch that vulnerability.

  2. Rotate all credentials — Every credential that was accessible from the compromised host must be considered compromised. This includes SSH keys, API tokens, database credentials, service account passwords, and any credentials stored in configuration files or environment variables.

  3. Hunt for lateral movement — Review authentication logs on other systems for connections from the compromised host. Check for new SSH authorized_keys entries, unusual sudo activity, and SMB/NFS mount activity.

  4. Audit all internet-facing Linux servers — Run the detection script and Velociraptor hunt across your entire Linux fleet. If one server was compromised, assume the attacker attempted to compromise others using the same vector.

Long-Term Hardening (Within 1 Week)

  1. Implement egress filtering — Restrict outbound connections from servers to only required destinations. A web server typically doesn't need to initiate outbound TLS connections to arbitrary internet hosts. Use a firewall or proxy with a default-deny outbound policy.

  2. Deploy file integrity monitoring (FIM) — Tools like AIDE, Tripwire, or OSSEC can alert on new files created in sensitive directories and modifications to systemd services or cron configurations.

  3. Enable auditd with process execution logging — Configure Linux auditd to log all process executions (execve syscalls). Forward these logs to your SIEM. This is the single most impactful detection improvement for catching post-exploitation tooling deployment.

  4. Restrict execution from temporary directories — Mount /tmp, /var/tmp, and /dev/shm with the noexec flag where operationally feasible. This prevents execution of binaries dropped into these locations.

  5. Implement application allowlisting — Consider using tools like fapolicyd (File Access Policy Daemon) on RHEL/Fedora or AppArmor profiles to restrict which binaries can execute on production servers.

  6. Update your IR playbook — Add a mandatory post-remediation step to every incident involving Linux servers: "Hunt for persistence mechanisms including GSocket, web shells, cron backdoors, SSH key additions, and systemd service modifications. Verify removal before closing the incident."


The Bigger Picture: Patch ≠ Remediated

The GSocket campaign illustrates a fundamental truth that many organizations still haven't internalized: patching the vulnerability that let the attacker in does not remove the attacker. Once an adversary has achieved code execution on a system, their first priority is establishing persistence — mechanisms that survive patching, reboots, and even some cleanup efforts.

GSocket is particularly dangerous because it's not malware. It's a legitimate, open-source tool with valid use cases. It won't trigger antivirus alerts. It doesn't exploit a vulnerability. It looks like encrypted HTTPS traffic at the network layer. Detection requires behavioral analysis, threat hunting, and a security operations capability that goes beyond signature-based alerting.

If your organization's incident response process consists of "patch the vulnerability and move on," you are leaving attackers inside your network. Every Linux incident involving code execution should trigger a persistence hunt, and GSocket should be on your checklist.


Related Resources

Security Arsenal Managed SOC Services AlertMonitor Platform Book a SOC Assessment soc-mdr Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.