Script Interpreter Connection to Non-Standard Port

Detects the execution of a script interpreter followed by an outbound network connection to a raw IP address on a non-standard port. Many initial access scripts and malware implants connect directly to C2 or payload servers using non-standard ports to avoid detection.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2026/01/30"
  3integration = ["endpoint"]
  4maturity = "production"
  5updated_date = "2026/02/09"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10Detects the execution of a script interpreter followed by an outbound network connection to a raw IP address 
 11on a non-standard port. Many initial access scripts and malware implants connect directly to C2 or payload 
 12servers using non-standard ports to avoid detection.
 13"""
 14from = "now-9m"
 15index = ["logs-endpoint.events.process-*", "logs-endpoint.events.network-*"]
 16language = "eql"
 17license = "Elastic License v2"
 18name = "Script Interpreter Connection to Non-Standard Port"
 19note = """ ## Triage and analysis
 20
 21> **Disclaimer**:
 22> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
 23
 24### Investigating Script Interpreter Connection to Non-Standard Port
 25
 26This rule detects a macOS script interpreter launch (Python, Node, or Ruby) quickly followed by an outbound connection to a raw IP address over a non-standard port. It matters because implants and initial access scripts often bypass domain-based controls and blend into developer tooling while using unusual ports for C2. A common pattern is a one-liner Python or Node stager that beacons directly to an external IP on a high-but-not-ephemeral port (e.g., 4444/8081) to fetch or execute a second stage.
 27
 28### Possible investigation steps
 29
 30- Review the interpreter’s full command line, parent/ancestry, execution path, and working directory to determine whether this was an interactive developer action, a scheduled task, or a hidden launcher.  
 31- Identify the script/module being executed (including any temp paths or inline code), collect it for analysis, and check for obfuscation, encoded payloads, or remote-fetch logic.  
 32- Pivot on the destination IP and port to assess reputation, hosting/ASN, geolocation, and whether the host has contacted the same endpoint before or other endpoints on the same unusual port.  
 33- Correlate around the event time for follow-on activity such as file downloads, new processes, credential access attempts, persistence creation (LaunchAgents/LaunchDaemons), or security tool tampering.  
 34- Validate the initiating user context and host posture (new user/login, recent software installs, unsigned binaries, quarantine attributes, or MDM exceptions) to decide on containment and scoping to peer endpoints.
 35
 36### False positive analysis
 37
 38- A developer runs a short Python/Node/Ruby script with a single argument to test a service by connecting directly to a public IP on an application-specific port (e.g., staging APIs, custom web services, or test listeners), resulting in a raw-IP outbound connection outside common ports.  
 39- An administrative or diagnostic script (e.g., a quick health check or connectivity probe) executed via an interpreter uses an IP literal for reliability and targets a non-standard port for internal tooling exposed to the internet, producing the same interpreter-to-raw-IP network pattern without malicious intent.
 40
 41### Response and remediation
 42
 43- Isolate the affected macOS host from the network (or block only the observed destination IP:port at the firewall) and terminate the Python/Node/Ruby process that initiated the outbound raw-IP connection.  
 44- Acquire volatile and on-disk artifacts including the interpreter command line, referenced script file, current working directory contents, recent downloads, and any temporary directories used at execution time, then submit the script and any fetched payloads for malware analysis.  
 45- Hunt for persistence and re-infection by checking for new or modified LaunchAgents/LaunchDaemons, cron entries, login items, and recently added executable files, and remove/rollback any items tied to the interpreter or the suspicious IP:port.  
 46- Reset potentially impacted credentials and revoke active tokens for the initiating user if the script accessed keychain material, SSH keys, browser sessions, or cloud CLIs near the event time.  
 47- Restore the endpoint from a known-good snapshot or reimage if the script/payload cannot be confidently eradicated, then validate recovery by confirming no further connections to the same IP:port and no recurrence of the interpreter one-liner.  
 48- Escalate to IR leadership and initiate broader scoping if multiple hosts contact the same external IP:port, the destination is confirmed malicious, or persistence/credential theft is detected, and harden by restricting script interpreter execution via MDM, enforcing full disk access controls, and adding egress allow-listing for non-standard ports.
 49"""
 50references = [
 51    "https://github.com/blackorbird/APT_REPORT/blob/master/lazarus/2024-10-14%20Lazarus%20InvisibleFerret.pdf"
 52]
 53risk_score = 47
 54rule_id = "aa1e007a-2997-4247-b048-dd9344742560"
 55severity = "medium"
 56tags = [
 57    "Domain: Endpoint",
 58    "OS: macOS",
 59    "Use Case: Threat Detection",
 60    "Tactic: Command and Control",
 61    "Tactic: Execution",
 62    "Data Source: Elastic Defend",
 63    "Resources: Investigation Guide",
 64]
 65type = "eql"
 66query = '''
 67sequence by process.entity_id with maxspan=1m
 68  [process where host.os.type == "macos" and event.type == "start" and event.action == "exec" and 
 69    (process.name like~ "python*" or process.name in ("node", "ruby")) and 
 70    process.args_count == 2]
 71  [network where host.os.type == "macos" and event.type == "start" and 
 72    (process.name like~ "python*" or process.name in ("node", "ruby")) and 
 73    destination.domain == null and 
 74    not destination.port in (443, 80, 53, 22, 25, 587, 465, 8080, 8089, 8200, 9200) and 
 75    destination.port < 49152 and
 76    not cidrmatch(destination.ip, "240.0.0.0/4", "233.252.0.0/24", "224.0.0.0/4", "198.19.0.0/16", 
 77                  "192.18.0.0/15", "192.0.0.0/24", "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", 
 78                  "172.16.0.0/12", "192.0.2.0/24", "192.31.196.0/24", "192.52.193.0/24", 
 79                  "192.168.0.0/16", "192.88.99.0/24", "100.64.0.0/10", "192.175.48.0/24", 
 80                  "198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "::1", "FE80::/10", "FF00::/8")]
 81'''
 82
 83[[rule.threat]]
 84framework = "MITRE ATT&CK"
 85
 86  [rule.threat.tactic]
 87  name = "Command and Control"
 88  id = "TA0011"
 89  reference = "https://attack.mitre.org/tactics/TA0011/"
 90
 91  [[rule.threat.technique]]
 92  name = "Non-Standard Port"
 93  id = "T1571"
 94  reference = "https://attack.mitre.org/techniques/T1571/"
 95
 96[[rule.threat]]
 97framework = "MITRE ATT&CK"
 98
 99  [rule.threat.tactic]
100  name = "Execution"
101  id = "TA0002"
102  reference = "https://attack.mitre.org/tactics/TA0002/"
103
104  [[rule.threat.technique]]
105  name = "Command and Scripting Interpreter"
106  id = "T1059"
107  reference = "https://attack.mitre.org/techniques/T1059/"
108
109    [[rule.threat.technique.subtechnique]]
110    name = "Python"
111    id = "T1059.006"
112    reference = "https://attack.mitre.org/techniques/T1059/006/"
113
114    [[rule.threat.technique.subtechnique]]
115    name = "JavaScript"
116    id = "T1059.007"
117    reference = "https://attack.mitre.org/techniques/T1059/007/"

Triage and analysis

Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

Investigating Script Interpreter Connection to Non-Standard Port

This rule detects a macOS script interpreter launch (Python, Node, or Ruby) quickly followed by an outbound connection to a raw IP address over a non-standard port. It matters because implants and initial access scripts often bypass domain-based controls and blend into developer tooling while using unusual ports for C2. A common pattern is a one-liner Python or Node stager that beacons directly to an external IP on a high-but-not-ephemeral port (e.g., 4444/8081) to fetch or execute a second stage.

Possible investigation steps

  • Review the interpreter’s full command line, parent/ancestry, execution path, and working directory to determine whether this was an interactive developer action, a scheduled task, or a hidden launcher.
  • Identify the script/module being executed (including any temp paths or inline code), collect it for analysis, and check for obfuscation, encoded payloads, or remote-fetch logic.
  • Pivot on the destination IP and port to assess reputation, hosting/ASN, geolocation, and whether the host has contacted the same endpoint before or other endpoints on the same unusual port.
  • Correlate around the event time for follow-on activity such as file downloads, new processes, credential access attempts, persistence creation (LaunchAgents/LaunchDaemons), or security tool tampering.
  • Validate the initiating user context and host posture (new user/login, recent software installs, unsigned binaries, quarantine attributes, or MDM exceptions) to decide on containment and scoping to peer endpoints.

False positive analysis

  • A developer runs a short Python/Node/Ruby script with a single argument to test a service by connecting directly to a public IP on an application-specific port (e.g., staging APIs, custom web services, or test listeners), resulting in a raw-IP outbound connection outside common ports.
  • An administrative or diagnostic script (e.g., a quick health check or connectivity probe) executed via an interpreter uses an IP literal for reliability and targets a non-standard port for internal tooling exposed to the internet, producing the same interpreter-to-raw-IP network pattern without malicious intent.

Response and remediation

  • Isolate the affected macOS host from the network (or block only the observed destination IP:port at the firewall) and terminate the Python/Node/Ruby process that initiated the outbound raw-IP connection.
  • Acquire volatile and on-disk artifacts including the interpreter command line, referenced script file, current working directory contents, recent downloads, and any temporary directories used at execution time, then submit the script and any fetched payloads for malware analysis.
  • Hunt for persistence and re-infection by checking for new or modified LaunchAgents/LaunchDaemons, cron entries, login items, and recently added executable files, and remove/rollback any items tied to the interpreter or the suspicious IP:port.
  • Reset potentially impacted credentials and revoke active tokens for the initiating user if the script accessed keychain material, SSH keys, browser sessions, or cloud CLIs near the event time.
  • Restore the endpoint from a known-good snapshot or reimage if the script/payload cannot be confidently eradicated, then validate recovery by confirming no further connections to the same IP:port and no recurrence of the interpreter one-liner.
  • Escalate to IR leadership and initiate broader scoping if multiple hosts contact the same external IP:port, the destination is confirmed malicious, or persistence/credential theft is detected, and harden by restricting script interpreter execution via MDM, enforcing full disk access controls, and adding egress allow-listing for non-standard ports.

References

Related rules

to-top