Detection rules › Elastic

Suspicious Perl Command Execution

Source
github.com/elastic/protections-artifacts

This rule monitors for suspicious Perl command executions by detecting the start of a Perl process with a command line argument that contains keywords commonly used by attackers to execute malicious code. These command line arguments include operations to execute code, create subprocesses, and encode or decode data.

MITRE ATT&CK coverage

Rule body

[rule]
description = """
This rule monitors for suspicious Perl command executions by detecting the start of a Perl process with a command line
argument that contains keywords commonly used by attackers to execute malicious code. These command line arguments
include operations to execute code, create subprocesses, and encode or decode data.
"""
id = "13c404cb-7631-4a33-8b59-5545e9a8a598"
license = "Elastic License v2"
name = "Suspicious Perl Command Execution"
os_list = ["linux"]
version = "1.0.15"

query = '''
process where event.type == "start" and event.action == "exec" and
process.executable like ("/bin/perl*", "/usr/bin/perl*", "/usr/local/bin/perl*") and
process.args == "-e" and process.command_line like~ (
  "*system(*", "*exec(*", "*IO.popen(*", "*Open3.popen3(*", "*spawn(*", "*eval(*",
  "*load(*IO::*", "*load(*Marshal*", "*load(*Fiddle*", "*load(*Zlib*", "*load(*Base64*",
  "*zlib.inflate(*", "*zlib.deflate(*", "*zlib.decompress(*", "*zlib.uncompress(*", "*zlib.compress(*",
  "*Marshal.load(*", "*Fiddle.dlopen(*", "*Fiddle::Function.new(*", "*base64*", "*zlib*", 
  "*net/http*", "*socket.new*", "*open-uri*", "*pack(*"
) and not (
  process.working_directory like~ (
    "/builds/*", "/root/.perl-cpm/*/MIME-tools-*", "/root/.cpan*", "/scratch/*", "/emulator/snmpAgent/net-snmp*",
    "/data1/Axway/TSIM/is/instances/*", "/build/linux-x86_64/__build__/__vmbuild__"
  ) or
  process.command_line like (
    "perl -e eval { use MIME::Base64; print 1; }", "/home/*/bin/sendEmail*", "*transfer fish server*",
    """perl -e $|=1; print "### 100 transfer fish server\n"; while(<STDIN>) { last if /^__END__/; $code.=$_; } exit(eval($code))""",
    "*base64.h*", "*zlib.h*", "*/user/*/Programs/agama/py/schwarzlib.py*", "/usr/bin/perl -MExtUtils::Command -e mkpath -- blib/lib/auto/Compress/Raw/Zlib"
  ) or
  process.parent.name in ("make", "filter_stderr") or
  process.parent.executable like (
    "/var/lib/docker/overlay2/*", "/usr/local/lp/apps/sonarpush-helpers/spectre-meltdown-checker.sh",
    "/usr/sbin/debootstrap", "/usr/bin/xterm", "/usr/bin/xargs", "/var/lib/dpkg/info/sudo.postinst", "/usr/bin/gmake",
    "/usr/bin/gxargs", "/home/*/.vscode-server/*/codex", "/home/*/.npm-global/*/codex", "/usr/local/lib/node_modules/*/codex", "/usr/bin/runc", 
    "/home/*/.nvm/versions/node/*/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex"
  ) or
  process.parent.command_line like~ ("*testfun()*", "sh -c bash -c testfun*", "/usr/bin/perl t/utf8.t", "*/usr/sap/.call/_call.localhost.*") or
  process.parent.args in ("/usr/bin/parallel", "/usr/sbin/debootstrap") or
  (process.working_directory like "/hana/shared/VN3/*" and process.command_line like "perl -e use MIME::Base64; print decode_base64($ARGV[0]*")
)
'''

min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"


[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Stage 1: process

process where event.type == "start" and event.action == "exec" and
process.executable like ("/bin/perl*", "/usr/bin/perl*", "/usr/local/bin/perl*") and
process.args == "-e" and process.command_line like~ (
  "*system(*", "*exec(*", "*IO.popen(*", "*Open3.popen3(*", "*spawn(*", "*eval(*",
  "*load(*IO::*", "*load(*Marshal*", "*load(*Fiddle*", "*load(*Zlib*", "*load(*Base64*",
  "*zlib.inflate(*", "*zlib.deflate(*", "*zlib.decompress(*", "*zlib.uncompress(*", "*zlib.compress(*",
  "*Marshal.load(*", "*Fiddle.dlopen(*", "*Fiddle::Function.new(*", "*base64*", "*zlib*", 
  "*net/http*", "*socket.new*", "*open-uri*", "*pack(*"
) and not (
  process.working_directory like~ (
    "/builds/*", "/root/.perl-cpm/*/MIME-tools-*", "/root/.cpan*", "/scratch/*", "/emulator/snmpAgent/net-snmp*",
    "/data1/Axway/TSIM/is/instances/*", "/build/linux-x86_64/__build__/__vmbuild__"
  ) or
  process.command_line like (
    "perl -e eval { use MIME::Base64; print 1; }", "/home/*/bin/sendEmail*", "*transfer fish server*",
    """perl -e $|=1; print "### 100 transfer fish server\n"; while(<STDIN>) { last if /^__END__/; $code.=$_; } exit(eval($code))""",
    "*base64.h*", "*zlib.h*", "*/user/*/Programs/agama/py/schwarzlib.py*", "/usr/bin/perl -MExtUtils::Command -e mkpath -- blib/lib/auto/Compress/Raw/Zlib"
  ) or
  process.parent.name in ("make", "filter_stderr") or
  process.parent.executable like (
    "/var/lib/docker/overlay2/*", "/usr/local/lp/apps/sonarpush-helpers/spectre-meltdown-checker.sh",
    "/usr/sbin/debootstrap", "/usr/bin/xterm", "/usr/bin/xargs", "/var/lib/dpkg/info/sudo.postinst", "/usr/bin/gmake",
    "/usr/bin/gxargs", "/home/*/.vscode-server/*/codex", "/home/*/.npm-global/*/codex", "/usr/local/lib/node_modules/*/codex", "/usr/bin/runc", 
    "/home/*/.nvm/versions/node/*/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex"
  ) or
  process.parent.command_line like~ ("*testfun()*", "sh -c bash -c testfun*", "/usr/bin/perl t/utf8.t", "*/usr/sap/.call/_call.localhost.*") or
  process.parent.args in ("/usr/bin/parallel", "/usr/sbin/debootstrap") or
  (process.working_directory like "/hana/shared/VN3/*" and process.command_line like "perl -e use MIME::Base64; print decode_base64($ARGV[0]*")
)

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.command_linestarts_withperl -e use MIME::Base64; print decode_base64($ARGV[0]excludes:process.command_line field:"process.command_line" value:"perl -e use MIME::Base64; print decode_base64($ARGV[0]"
process.working_directorystarts_with/hana/shared/VN3/excludes:process.working_directory field:"process.working_directory" value:"/hana/shared/VN3/"
process.command_linewildcardperl -e eval { use MIME::Base64; print 1; }, /home/*/bin/sendEmail*, *transfer fish server*, perl -e $|=1; print "### 100 transfer fish server\n"; while(<STDIN>) { last if /^__END__/; $code.=$_; } exit(eval($code)), *base64.h*, *zlib.h*, */user/*/Programs/agama/py/schwarzlib.py*, /usr/bin/perl -MExtUtils::Command -e mkpath -- blib/lib/auto/Compress/Raw/Zlibexcludes:process.command_line
process.parent.argsin/usr/bin/parallel, /usr/sbin/debootstrapexcludes:process.parent.args field:"process.parent.args" value:"/usr/bin/parallel" field:"process.parent.args" value:"/usr/sbin/debootstrap"
process.parent.command_linewildcard*testfun()*, sh -c bash -c testfun*, /usr/bin/perl t/utf8.t, */usr/sap/.call/_call.localhost.*excludes:process.parent.command_line
process.parent.executablewildcard/var/lib/docker/overlay2/*, /usr/local/lp/apps/sonarpush-helpers/spectre-meltdown-checker.sh, /usr/sbin/debootstrap, /usr/bin/xterm, /usr/bin/xargs, /var/lib/dpkg/info/sudo.postinst, /usr/bin/gmake, /usr/bin/gxargs, /home/*/.vscode-server/*/codex, /home/*/.npm-global/*/codex, /usr/local/lib/node_modules/*/codex, /usr/bin/runc, /home/*/.nvm/versions/node/*/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codexexcludes:process.parent.executable
process.parent.nameinfilter_stderr, makeexcludes:process.parent.name field:"process.parent.name" value:"filter_stderr" field:"process.parent.name" value:"make"
process.working_directorywildcard/builds/*, /root/.perl-cpm/*/MIME-tools-*, /root/.cpan*, /scratch/*, /emulator/snmpAgent/net-snmp*, /data1/Axway/TSIM/is/instances/*, /build/linux-x86_64/__build__/__vmbuild__excludes:process.working_directory

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • exec
field:"EventType" kind:eq value:"exec"
event.typeeq
  • start
field:"event.type" kind:eq value:"start"
process.argseq
  • -e
field:"process.args" kind:eq value:"-e"
process.command_linewildcard
  • *Fiddle.dlopen(*
  • *Fiddle::Function.new(*
  • *IO.popen(*
  • *Marshal.load(*
  • *Open3.popen3(*
  • *base64*
  • *eval(*
  • *exec(*
  • *load(*Base64*
  • *load(*Fiddle*
  • *load(*IO::*
  • *load(*Marshal*
  • *load(*Zlib*
  • *net/http*
  • *open-uri*
  • *pack(*
  • *socket.new*
  • *spawn(*
  • *system(*
  • *zlib*
  • *zlib.compress(*
  • *zlib.decompress(*
  • *zlib.deflate(*
  • *zlib.inflate(*
  • *zlib.uncompress(*
field:"CommandLine" kind:wildcard
process.executablewildcard
  • /bin/perl*
  • /usr/bin/perl*
  • /usr/local/bin/perl*
field:"Image" kind:wildcard