输错 PID,给云盾进程发送了kill signal:
root 26689 0.3 0.1 113180 9420 ? S<sl 10:34 0:08 /usr/local/aegis/aegis_client/aegis_11_83/AliYunDun
...
# kill -9 26689
-bash: kill: (26689) - Operation not permitted
咦,怎么啥不死,我是 root 呀。再尝试下systemctl stop aegis
,状态是inactive
了,但是进程还在 👻。
● aegis.service - Aegis Service
Loaded: loaded (/etc/systemd/system/aegis.service; enabled; vendor preset: disabled)
Active: inactive (dead) since Wed 2024-01-10 14:46:43 HKT; 24h ago
CGroup: /system.slice/aegis.service
├─26627 /usr/local/aegis/aegis_update/AliYunDunUpdate
├─26689 /usr/local/aegis/aegis_client/aegis_11_83/AliYunDun
└─26700 /usr/local/aegis/aegis_client/aegis_11_83/AliYunDunMonitor
好奇心来了,咋实现的呢?😯
strace 一下 strace kill -9 26689
没什么收获,
open("/usr/lib/locale/UTF-8/LC_CTYPE", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
kill(26689, SIGKILL) = -1 EPERM (Operation not permitted)
write(2, "kill: ", 6kill: ) = 6
write(2, "sending signal to 26689 failed", 30sending signal to 26689 failed) = 30
write(2, ": ", 2: ) = 2
write(2, "Operation not permitted\n", 24Operation not permitted
) = 24
云盾的二进制文件也删不掉:
# rm -f /usr/local/aegis/aegis_client/aegis_11_81/AliYunDun
rm: cannot remove 'AliYunDun': Operation not permitted
也对,这是个安全软件(HIDS),要是能这么简单被干掉,也太弱了。 想起有网友介意这类程序的,那我看大家的卸载清理指南不就可以了?
找到卸载脚本:
http://update.aegis.aliyun.com/download/uninstall.sh
stop_aegis_pkill()
就是普通的 kill 发个信号,不过接着执行的wait_aegis_exit()
里面的语句:
echo "wait AliYunDun process exit fail, possibly due to self-protection, please uninstall aegis or disable self-protection from the aegis console."
意思就是在控制台关闭掉就可以被 kill 了,那这应该是云盾进程自己控制的。 再往下看如何清理文件,看到了kprobe:
kprobeArr=(
"/sys/kernel/debug/tracing/instances/aegis_do_sys_open/set_event"
"/sys/kernel/debug/tracing/instances/aegis_inet_csk_accept/set_event"
"/sys/kernel/debug/tracing/instances/aegis_tcp_connect/set_event"
"/sys/kernel/debug/tracing/instances/aegis/set_event"
"/sys/kernel/debug/tracing/instances/aegis_/set_event"
"/sys/kernel/debug/tracing/instances/aegis_accept/set_event"
"/sys/kernel/debug/tracing/kprobe_events"
"/usr/local/aegis/aegis_debug/tracing/set_event"
"/usr/local/aegis/aegis_debug/tracing/kprobe_events"
)
看着眼熟,之前看动态调试相关的文章见过,没深入了解忘记了,原来如此。
# lsmod |grep -i ali
AliSecGuard 22400 2
果然有一个配套的内核模块。
检查一下event:
# trace-cmd list |grep -i aegis
kprobes:aegis_cn_netlink_send
kprobes:aegis_sys_execve
kprobes:aegis_proc_fork_connector
v2ex这个帖子中,网友提到了用kprobe 检测系统调用是HIDS 的主流实现方式,是我菜鸡了。
既然如此,那找一个开源的 HIDS 学习一下。
AgentSmith是LKM(可加载内核模块)的方式hook住Linux内核一些函数。由于它是使用kprobe的方式,它hook的函数不只是系统调用,还可以hook内核内部一些函数,而这些内部函数是某些系统调用的关键点调用。
kill 对kill/tkill系统调用挂钩,记录程序终止某个进程操作, 记录信息: 执行程序 目标进程 信号
先看这篇文章学习了下怎么写一个简单的 kprobe 例子,以便能略微看懂代码:
《Linux内核调试技术——kprobe使用与实现》。
翻了下Elkeid/driver/LKM/src/
找到了 kill_kprobe:
struct kprobe kill_kprobe = {
.symbol_name = P_GET_SYSCALL_NAME(kill),
.pre_handler = kill_pre_handler,
};
struct kprobe tkill_kprobe = {
.symbol_name = P_GET_SYSCALL_NAME(tkill),
.pre_handler = tkill_pre_handler,
};
再顺着就可以找到register_kill_kprobe
、kill_pre_handler()
等。
大概明白了逻辑,云盾是hook 了 kill 的系统调用,在里面实现了自保的逻辑。
也可以参考这个文章《 linux源码解读(十三):内核驱动module加载kprobe&字节跳动Elkied简要分析》。
这两篇译文写的也非常好,可以补充下 ftrace 的技能: