首页/安全/取证与溯源速查/完整命令行与参数伪装识别
Linux 取证135 条

完整命令行与参数伪装识别

/proc/<pid>/cmdline 保存启动参数原始字节,与 ps 显示对照可发现 argv 伪装、超长参数或命令行清空等规避手法。

取证与溯源速查安全更新于 2026-10-13

cmdline 存的是原始字节

/proc/<pid>/cmdline 保存进程启动时的参数原始内容,各参数之间用 NUL 字节分隔,文件末尾也有一个 NUL,所以直接 cat 会看到挤成一行的内容,需要用 tr 把 NUL 换成空格再读。它与 ps 显示的命令行来自同一份数据,但 ps 会做格式化处理,两者对照能发现 argv 被改写、参数超长截断或命令行整体被清空的情况。

不一致本身就是线索

进程可以在运行期间改写自己的命令行,把这个区域伪装成无害的样子,也可以在启动后把整段内容清零,让 ps 只显示一个方括号包裹的名称——这种形态原本是内核线程的特征,被人为模仿就值得深查。遇到 cmdline 为空时,先看 exe 链接指向哪个可执行文件,再结合进程树与打开的文件描述符判断。

基本信息

适用平台Linux(/proc 文件系统)
路径/proc/<pid>/cmdline
分隔符NUL 字节(0x00),需转换后才能正常阅读
对照来源ps -o args、/proc/<pid>/comm、/proc/<pid>/exe
权限普通用户只能读自己可访问的进程,完整采集需 root

典型使用场景

  • 可疑进程的命令行异常:确认是否被改写或清空
  • 参数超长导致 ps 截断:直接从 cmdline 读原始字节补齐
  • 确认进程真实意图:有些工具把目标地址写在参数里
  • 采集易失性数据:把全部进程的 cmdline 批量导出留档
  • 与父进程对照:看是谁拉起了这个进程以及传了什么参数

读取与对照

读取与对照
# NUL 转换为空格后阅读,末尾补一个换行
tr '\0' ' ' < /proc/1234/cmdline; echo

# 与 ps 的显示对照,两者不一致说明 argv 被改写
ps -p 1234 -o pid,ppid,args=

# 命令行空时,看可执行文件与进程状态
ls -l /proc/1234/exe
cat /proc/1234/comm

# 批量导出全部进程的命令行,作为易失性数据留存
for p in /proc/[0-9]*; do printf '%s | ' "${p##*/}"; tr '\0' ' ' < "$p/cmdline"; echo; done > /mnt/ev/cmdline-all.txt

相关文件对照

来源内容分析用法
/proc/<pid>/cmdline启动参数原始字节与 ps 对照发现改写或清空
/proc/<pid>/comm进程名(15 字符上限)常被用于伪装成内核线程形态
/proc/<pid>/exe可执行文件链接命令行不可信时的定位依据
/proc/<pid>/status进程状态与内存信息补充进程来源与运行状态
/proc/<pid>/environ环境变量常包含可执行文件所在目录与配置路径
cmdline 与 ps 一致并不等于可信:两者读的是同一份数据,被改写后会同时失真,需要结合 exe 链接、文件描述符与进程树交叉判断。
内核线程的 cmdline 本来就为空,且通常带方括号显示;判定为伪装前要先看 ppid 是否为 2(kthreadd)以及进程状态特征。

易错点

  • 不看 NUL 转换直接 cat:输出挤成一行,参数边界读不出来
  • 把空命令行直接判为恶意:内核线程本来就是这样,会大量误判
  • 只信 cmdline 不查 exe:被改写的命令行会把分析带向错误方向
  • 采集时未用 root:部分进程读不到内容,采集结果出现缺口却没发现
  • 采集动作不留时间戳:命令行属于易失性数据,没有采集时刻就无法评估时效

数据来源与参考

  • man 5 proc(/proc/pid/cmdline)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌