应通过父子进程关系链(java fork shell)结合selinux avc拒绝日志定位异常:先用ausearch查java发起的execve及关联bash/sh调用,再过滤jenkins、maven等误报,最后用ps、jcmd、jstack溯源验证。

要筛选由特定 Java 进程派生的异常 shell 行为(如非预期的 /bin/sh、/bin/bash 启动),关键不是直接用 comm=java,而是抓住“Java 进程 fork 出 shell”这一父子关系链,并结合 SELinux 拒绝(AVC)或 syscall 审计上下文来识别异常。因为 Java 本身不常直接执行 shell,一旦出现,往往意味着反射调用 Runtime.exec() 或 ProcessBuilder,这在安全审计中属于高风险行为。
定位父进程为 Java 的 shell 调用
Java 进程启动 shell 时,audit 日志中通常会记录两条关联事件:一条是 Java 进程(comm="java")触发了 execve 系统调用,另一条是新生成的 shell 进程(如 comm="bash")被创建。需用 -i 解析并关联:
- 查最近所有由 java 进程发起的 execve 调用:
sudo ausearch -m execve -ts recent -i | grep -A2 "comm=\"java\""
关注其exe=字段确认是否为真实 Java 应用(而非仅 java 命令),再看下一行的argc=和参数列表,识别是否含/bin/sh、bash、sh -c等 - 反向查:找出所有
comm="sh"或comm="bash"的记录,并向上追溯其父进程:sudo ausearch -m execve -ts recent -i | awk '/comm="(sh|bash)"/ {getline; if (/ppid=/) print $0}' | grep -E "comm=\"java\"|ppid="[0-9]+
结合 AVC 拒绝锁定高危 Java-shell 组合
若系统启用了 SELinux,Java 进程本不应有权限执行 shell。此时 AVC denied 日志会暴露违规行为:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 提取所有涉及 java 进程且目标为 shell 的拒绝事件:
sudo ausearch -m avc -ts recent -i | awk '/comm="java"/ && /exe="\/bin\/(sh|bash)"/ {print; getline; print}' - 重点看
tcontext(目标上下文)是否为shell_exec_t或bin_t,而scontext(源上下文)为java_t或unconfined_t——这类组合违反默认策略,属典型异常
排除常见误报与噪声
并非所有 java → shell 都是恶意的。需过滤掉运维和开发场景:
- 跳过已知安全工具:如 Jenkins、Maven、IDE 启动的 shell,可通过
cwd=或exe=路径识别(例如exe="/var/lib/jenkins/jenkins.war") - 忽略调试行为:含
strace、gdb、java -agentlib的记录,它们可能触发临时 shell - 过滤测试框架:如
comm="java"且args="org.junit.runner.JUnitCore"可暂标记为低风险
验证与溯源建议
找到可疑记录后,进一步确认实际影响范围:
- 用 PID 反查完整进程树:
sudo ps -ef --forest | grep -A5 -B5 "PID_HERE" - 检查该 Java 进程加载的 JAR 或类:
sudo jcmd PID VM.native_memory summary或sudo ls -l /proc/PID/cwd /proc/PID/exe - 若确认为异常行为,建议立即用
kill -STOP PID冻结进程,并导出堆栈:sudo jstack PID > java_pid_stack.txt
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










