由于是第一次写这样的教程性文章,会有很多不足之处,希望理解,感谢各位的批评指正
简单来说,可以把ATT&CK看成一个表格,如下图所示,表头是诸如侦察目标资源准备等攻击者的目的与攻击路径,而表中内容则是实现这些目的的技术,或者说攻击手法

通过查阅框架,可以了解攻击者的行为手段,推断他的行为意图从而更有针对性地对失陷主机进行排查
在正式开始之前还需要了解一些名词
优先把目光放到持久化(图中是持续控制,翻译问题)(TA0003)和提权 (TA0004),这是在失陷主机中最容易捕获到的痕迹(除非攻击者只进行一次攻击那他很闲了),接下来则关注以下技术
剩下的后面再说吧
对手可能会滥用
cron实用程序来执行任务调度,以初始或定期执行恶意代码。(引用: 20 macOS Common Tools and Techniques)cron实用程序是类Unix操作系统的基于时间的作业调度程序。crontab文件包含要运行的cron条目和指定的执行时间。任何crontab文件都存储在特定于操作系统的文件路径中。 对手可能会在Linux或Unix环境中使用cron在系统启动时或定期执行程序以实现持久性。
cron在linux主要包含两个部分
crontab
/etc/cron*
涉及两个命令:
编辑定时任务
crontab -e
运行后即可进入编辑器

其中,m h dom mon dow 分别代表 分/时/月中某一天(day of month)/月/周中某一天(day of week)
例:*/1 * * * * 就代表每隔1分中执行command
查看定时任务
crontab -l
运行后即可查看当前用户的定时任务

这个值得是存放在/etc目录下的cron文件,包含cron.dcron.dailycron.hourlycron.monthlycron.weeklycron.yearlycronbtab(与上述crontab不同)
使用
ls /etc/cron*
就可以进行查看

crontab命令与/etc/crontab的区别:
crontab命令只能编辑当前用户的定时任务,而/etc/crontab可以指定任意用户的定时任务,并且只有root可以修改
对手可能会修改 SSH
authorized_keys文件以在受害者主机上保持持久性。Linux 发行版和 macOS 通常使用基于密钥的身份验证来保护 SSH 会话的身份验证过程以进行远程管理。SSH 中的authorized_keys文件指定可用于登录配置该文件的用户帐户的 SSH 密钥。此文件通常位于用户主目录下的<user-home>/.ssh/authorized_keys。(引用: SSH Authorized Keys) 用户可以编辑系统的 SSH 配置文件,将指令 PubkeyAuthentication 和 RSAAuthentication 修改为值“yes”以确保启用公钥和 RSA 身份验证。SSH 配置文件通常位于/etc/ssh/sshd_config下。 对手可能会直接使用脚本或 shell 命令修改 SSHauthorized_keys文件以添加他们自己提供的公钥。在云环境中,对手可能能够通过命令行界面或 REST API 修改特定虚拟机的 SSH authorized_keys 文件。例如,通过使用 Google Cloud CLI 的“add-metadata”命令,对手可以向用户帐户添加 SSH 密钥。(引用: Google Cloud Add Metadata)(引用: Google Cloud Privilege Escalation) 类似地,在 Azure 中,对手可以通过向 API 发送 PATCH 请求来更新虚拟机的 authorized_keys 文件。(引用: Azure Update Virtual Machines) 这确保了拥有相应私钥的对手可以通过 SSH 以现有用户身份登录。(引用: Venafi SSH Key Abuse)(引用: Cybereason Linux Exim Worm) 这也可能导致权限提升,其中虚拟机或实例具有与请求用户不同的权限。 如果通过云 API 或命令行界面修改 authorized_keys 文件,对手可能会在目标虚拟机上实现权限提升,如果他们向更高权限的用户添加密钥。 SSH 密钥也可以添加到网络设备上的帐户,例如使用ip ssh pubkey-chain网络设备 CLI 命令。(引用: cisco_ip_ssh_pubkey_ch_cmd)
这个则是需要启动ssh公钥认证登录,启动后~/.ssh下就会生成authorized_keys文件,攻击者就可以在其中添加自己的公钥实现后续的免密登录
对手可能会在 Web 服务器上植入 Web shell 以建立对系统的持久访问。Web shell 是放置在公开可访问的 Web 服务器上的 Web 脚本,允许对手访问 Web 服务器作为进入网络的网关。Web shell 可能提供一组功能来执行或在托管 Web 服务器的系统上提供命令行界面。(引用: volexity_0day_sophos_FW) 除了服务器端脚本,Web shell 可能还有一个客户端界面程序,用于与 Web 服务器通信(例如,China Chopper Web shell 客户端)。(引用: Lee 2013)
这个嘛就很熟悉了,在web目录下放一个webshell,就不多说了。一般apache/nginx的web目录会存放在/var/www下,tomcat则是放置在tomcat自己的目录内,要是实在找不到可以用find搜一下
对手可能会创建或修改systemd服务,以作为持久性的一部分反复执行恶意负载。Systemd是一个系统和服务管理器,通常用于管理后台守护进程(也称为服务)和其他系统资源。(引用: Linux man-pages: systemd January 2014) Systemd是许多Linux发行版上的默认初始化(init)系统,取代了遗留的init系统,包括SysVinit和Upstart,同时保持向后兼容。 Systemd使用扩展名为.service的单元配置文件来编码有关服务进程的信息。默认情况下,系统级单元文件存储在根拥有的目录(/)的/systemd/system目录中。用户级单元文件存储在用户拥有的目录($HOME)的/systemd/user目录中。(引用: lambert systemd 2022) 在.service单元文件中,以下指令用于执行命令:(引用: freedesktop systemd.service) * ExecStart、ExecStartPre和ExecStartPost指令在服务由systemctl手动启动或在系统启动时执行,如果服务设置为自动启动。 * ExecReload指令在服务重新启动时执行。 * ExecStop、ExecStopPre和ExecStopPost指令在服务停止时执行。 对手已经创建了新的服务文件,更改了.service文件指令执行的命令,并修改了.service文件执行的用户指令,这可能导致权限提升。对手还可能在这些目录中放置符号链接,使systemd能够找到这些负载,无论它们在文件系统中的位置。(引用: Anomali Rocke March 2019)(引用: airwalk backdoor unix systems)(引用: Rapid7 Service Persistence 22JUNE2016) .service文件的User指令可用于以特定用户身份运行服务,这可能会根据特定用户/组权限导致权限提升。
简单的来说就是攻击者使用systemctl命令加载了一个恶意服务,这个恶意服务可能是修改了原先的服务文件,也可能是攻击者新建的服务文件。而在linux中,服务文件通常存放在/etc/systemd/system和/usr/lib/systemd/system下,并以.service为后缀

这边以sshd.service为例子

**[Unit]**描述了服务的元数据,可以看到服务的简介与依赖项等信息
[Service]则是告诉服务如何运行,重点关注ExecStart字段,他定义了服务执行的二进制文件以及参数,攻击者可在这里植入后门,例:
ExecStart=/tmp/backdoor
然后使用systemctl daemon-reload重载服务再systemctl enable backdoor设置后门服务的开机自启
[Install] 中的WantedBy=multi-user.target则代表着服务开机自启,在linux中,如果执行了systemctl enable [service]命令,就会在multi-user.target.wants目录下创建一个软链接

那么排查的思路呢就是优先查看修改/创建时间比较新的服务,关注Execstart字段即可
/etc/systemd/system和/usr/lib/systemd/system的区别
/etc/systemd/system可以由root创建,或者使用systemctl命令生成,/usr/lib/systemd/system则是由包管理器生成/etc/systemd/system运行优先级比/usr/lib/systemd/system高,即两个目录内如有同名服务则优先运行/etc/systemd/system下的服务
对手可能通过执行由用户的 shell 触发的恶意命令来建立持久性。用户Unix Shell在会话的不同点执行几个配置脚本,基于事件。例如,当用户打开命令行界面或远程登录(例如通过 SSH)时,会启动登录 shell。登录 shell 从系统 (
/etc) 和用户的主目录 (~/) 执行脚本以配置环境。系统上的所有登录 shell 都使用 /etc/profile 启动。这些配置脚本以其目录的权限级别运行,通常用于设置环境变量、创建别名和自定义用户的环境。当 shell 退出或终止时,将执行其他 shell 脚本以确保 shell 正常退出。 对手可能会尝试通过将命令插入到 shell 自动执行的脚本中来建立持久性。以 bash 为例,大多数 GNU/Linux 系统的默认 shell,对手可能会将启动恶意二进制文件的命令添加到/etc/profile和/etc/profile.d文件中。(引用: intezer-kaiji-malware)(引用: bencane blog bashrc) 这些文件通常需要 root 权限才能修改,并且每次系统上的任何 shell 启动时都会执行。对于用户级权限,对手可以将恶意命令插入~/.bash_profile、~/.bash_login或~/.profile,这些命令在用户打开命令行界面或远程连接时会被调用。(引用: anomali-rocke-tactics)(引用: Linux manual bash invocation) 由于系统仅执行列表顺序中的第一个现有文件,因此对手使用~/.bash_profile来确保执行。对手还利用~/.bashrc文件,如果连接是远程建立的或打开了额外的交互式 shell(例如命令行界面中的新选项卡),则会额外执行。(引用: Tsunami)(引用: anomali-rocke-tactics)(引用: anomali-linux-rabbit)(引用: Magento) 一些恶意软件在程序终止时触发执行,对手可以使用~/.bash_logout文件在会话结束时执行恶意命令。 对于 macOS,此技术的功能类似,但可能利用 zsh,这是 macOS 10.15+ 的默认 shell。当打开 Terminal.app 时,应用程序会启动 zsh 登录 shell 和 zsh 交互式 shell。登录 shell 使用/etc/profile、/etc/zshenv、/etc/zprofile和/etc/zlogin配置系统环境。(引用: ScriptingOSX zsh)(引用: PersistentJXA_leopitt)(引用: code_persistence_zsh)(引用: macOS MS office sandbox escape) 然后,登录 shell 使用~/.zprofile和~/.zlogin配置用户环境。交互式 shell 使用~/.zshrc配置用户环境。退出时,执行/etc/zlogout和~/.zlogout。对于旧版程序,macOS 在启动时执行/etc/bashrc。
linux中的shell分为shbashzsh 三种,而每一种都有对应的配置文件,这些配置文件会在shell启动时运行,而攻击者就可以利用这一点实现后门的植入
这里以最常见的.bashrc 为例
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth
# append to the history file, don't overwrite it
shopt -s histappend
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000
# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize
# If set, the pattern "**" used in a pathname expansion context will
# match all files and zero or more directories and subdirectories.
#shopt -s globstar
# make less more friendly for non-text input files, see lesspipe(1)
#[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
debian_chroot=$(cat /etc/debian_chroot)
fi
# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
xterm-color|*-256color) color_prompt=yes;;
esac
# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
force_color_prompt=yes
if [ -n "$force_color_prompt" ]; then
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
# We have color support; assume it's compliant with Ecma-48
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
# a case would tend to support setf rather than setaf.)
color_prompt=yes
else
color_prompt=
fi
fi
# The following block is surrounded by two delimiters.
# These delimiters must not be modified. Thanks.
# START KALI CONFIG VARIABLES
PROMPT_ALTERNATIVE=twoline
NEWLINE_BEFORE_PROMPT=yes
# STOP KALI CONFIG VARIABLES
if [ "$color_prompt" = yes ]; then
# override default virtualenv indicator in prompt
VIRTUAL_ENV_DISABLE_PROMPT=1
prompt_color='\[\033[;32m\]'
info_color='\[\033[1;34m\]'
prompt_symbol=㉿
if [ "$EUID" -eq 0 ]; then # Change prompt colors for root user
prompt_color='\[\033[;94m\]'
info_color='\[\033[1;31m\]'
# Skull emoji for root terminal
#prompt_symbol=💀
fi
case "$PROMPT_ALTERNATIVE" in
twoline)
PS1=$prompt_color'┌──${debian_chroot:+($debian_chroot)──}${VIRTUAL_ENV:+(\[\033[0;1m\]$(basename $VIRTUAL_ENV)'$prompt_color')}('$info_color'\u'$prompt_symbol'\h'$prompt_color')-[\[\033[0;1m\]\w'$prompt_color']\n'$prompt_color'└─'$info_color'\$\[\033[0m\] ';;
oneline)
PS1='${VIRTUAL_ENV:+($(basename $VIRTUAL_ENV)) }${debian_chroot:+($debian_chroot)}'$info_color'\u@\h\[\033[00m\]:'$prompt_color'\[\033[01m\]\w\[\033[00m\]\$ ';;
backtrack)
PS1='${VIRTUAL_ENV:+($(basename $VIRTUAL_ENV)) }${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ';;
esac
unset prompt_color
unset info_color
unset prompt_symbol
else
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt
# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*|Eterm|aterm|kterm|gnome*|alacritty)
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
;;
*)
;;
esac
[ "$NEWLINE_BEFORE_PROMPT" = yes ] && PROMPT_COMMAND="PROMPT_COMMAND=echo"
/tmp/backdoor & #恶意代码的植入
# enable color support of ls, less and man, and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
export LS_COLORS="$LS_COLORS:ow=30;44:" # fix ls color for folders with 777 permissions
alias ls='ls --color=auto'
#alias dir='dir --color=auto'
#alias vdir='vdir --color=auto'
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
alias diff='diff --color=auto'
alias ip='ip --color=auto'
export LESS_TERMCAP_mb=$'\E[1;31m'# begin blink
export LESS_TERMCAP_md=$'\E[1;36m'# begin bold
export LESS_TERMCAP_me=$'\E[0m'# reset bold/blink
export LESS_TERMCAP_so=$'\E[01;33m'# begin reverse video
export LESS_TERMCAP_se=$'\E[0m'# reset reverse video
export LESS_TERMCAP_us=$'\E[1;32m'# begin underline
export LESS_TERMCAP_ue=$'\E[0m'# reset underline
fi
# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
# some more ls aliases
alias ll='ls -l'
alias la='ls -A'
alias l='ls -CF'
# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
elif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi
再中间插入一句/tmp/backdoor &即可实现自动运行后门
排查思路则是优先查看 /etc下的配置文件以及profile,他们全局有效因此需要重点排查,而主文件夹下的配置只对当前用户生效
对手可能会滥用配置,其中应用程序设置了 setuid 或 setgid 位,以便在不同(可能更高级别)用户的上下文中运行代码。在 Linux 或 macOS 上,当为应用程序二进制文件设置 setuid 或 setgid 位时,应用程序将以拥有用户或组的权限运行。(引用: setuid man page) 通常,应用程序在当前用户的上下文中运行,无论哪个用户或组拥有应用程序。然而,在某些情况下,程序需要在提升的上下文中执行才能正常运行,但运行它们的用户可能没有特定的所需权限。 与在 sudoers 文件中创建条目不同,这必须由 root 完成,任何用户都可以指定为自己的应用程序设置 setuid 或 setgid 标志(即Linux 和 Mac 文件和目录权限修改)。可以使用位掩码通过
chmod命令设置这些位,chmod 4777 [file]或通过简写命名,chmod u+s [file]。这将启用 setuid 位。要启用 setgid 位,可以使用chmod 2775和chmod g+s。 对手可以在自己的恶意软件上使用此机制,以确保他们能够在未来的提升上下文中执行。(引用: OSX Keydnap malware) 这种滥用通常是“shell 逃逸”或其他绕过具有受限权限的执行环境的操作的一部分。 或者,对手可能会选择查找和目标具有已启用 setuid 或 setgid 位的易受攻击的二进制文件(即文件和目录发现)。通过ls -l查看文件属性时,setuid 和 setgid 位用“s”而不是“x”表示。find命令也可以用于搜索此类文件。例如,find / -perm +4000 2>/dev/null可用于查找设置了 setuid 的文件,find / -perm +2000 2>/dev/null可用于查找设置了 setgid 的文件。然后,对手可能会滥用这些位已设置的二进制文件。(引用: GTFOBins Suid)
这边以常用的SUID为例,当对一个执行文件使用stat命令时,即可查看他的权限,这时就可以发现,除了常规的读写执行外还有一个标志位,这个标志位就是SUID

此时在root下使用chmod u+s example 为其赋予SUID,可以看到,权限从0777变成了4777,4就是root赋予他的SUID权限

那么他的作用是什么呢?简单的来讲当一个文件被赋予了root的suid后即4xxx那么任何用户执行这个文件都会以root权限运行,这就给了攻击者提权的入口,而我们就可以通过find / -perm +4000 2>/dev/null 查找这些文件
SUID和SGID的区别
SUID只作用于文件,SGID则可作用于目录 SUID可以将用户变为文件的所属者(标志位为4),SGID则是用户组(标志位为2)–
对手可能会执行 sudo 缓存和/或使用 sudoers 文件来提升权限。对手可能这样做是为了以其他用户身份执行命令或生成具有更高权限的进程。 在 Linux 和 MacOS 系统中,sudo(有时称为“超级用户执行”)允许用户从终端以提升的权限执行命令,并控制谁可以在系统上执行这些命令。
sudo命令“允许系统管理员委派权限,授予某些用户(或用户组)以 root 或其他用户身份运行某些(或所有)命令的能力,同时提供命令及其参数的审计跟踪。”(引用: sudo man page 2018) 由于 sudo 是为系统管理员设计的,因此它具有一些有用的配置功能,例如timestamp_timeout,这是sudo之间的时间间隔,以分钟为单位,然后它会重新提示输入密码。这是因为sudo具有缓存凭据的能力。Sudo 会在/var/db/sudo处创建(或触摸)一个文件,其中包含上次运行 sudo 的时间戳,以确定此超时。此外,还有一个tty_tickets变量,它将每个新的 tty(终端会话)视为隔离的。这意味着,例如,一个 tty 的 sudo 超时不会影响另一个 tty(您将不得不再次输入密码)。 sudoers 文件/etc/sudoers描述了哪些用户可以从哪些终端运行哪些命令。这还描述了用户可以以其他用户或组身份运行哪些命令。这提供了最低权限原则,使用户在大多数时间内以最低可能的权限运行,并且仅在需要时通过提示输入密码提升到其他用户或权限。然而,sudoers 文件还可以通过类似user1 ALL=(ALL) NOPASSWD: ALL的行指定何时不提示用户输入密码。(引用: OSX.Dok Malware) 但是,编辑此文件需要提升的权限。 对手还可以滥用这些机制的配置不当来提升权限而无需用户的密码。例如,可以监视/var/db/sudo的时间戳以查看它是否在timestamp_timeout范围内。如果是,则恶意软件可以执行 sudo 命令而无需提供用户的密码。此外,如果禁用tty_tickets,对手可以从该用户的任何 tty 执行此操作。 在野外,恶意软件已禁用tty_tickets以潜在地使脚本编写更容易,通过发出echo \'Defaults !tty_tickets\' >> /etc/sudoers。(引用: cybereason osx proton) 为了使此更改生效,恶意软件还发出了killall Terminal。从 macOS Sierra 开始,sudoers 文件默认启用了tty_tickets。
先说sudoers,这是一个存放在/etc目录下的一个文件,打开后可以看到如下字段

其中第一个ALL代表所有主机,(ALL:ALL) 代表所有用户与所有用户组,最后一个ALL则是所有命令,组合起来就构成了root权限
那么如果攻击者加入这么一行 hack ALL=(ALL:ALL) ALL 那么就相当于hack用户拥有了root的权限,这种提权方式会比修改/etc/passwd中的UID和GID要隐秘得多
sudo缓存则是利用了sudo 生成的时间戳票据,新系统通常存放在/run/sudo/ts目录下
ATT&CK 原站:MITRE ATT&CK®
ATT&CK 中文站:ATT&CK 中文版