一、前言
Unix和类Unix操作系统提供的ptrace系统调用支持一个进程控制另一个进程,常被用于程序调试、分析和监测工具,例如gdb、strace等。通过ptrace可以查看和修改被控制进程的内部状态,因此渗透攻击在注入shellcode时也会使用ptrace。本文介绍一种Linux下使用ptrace隐藏注入shellcode的技术和防御方法。
二、背景
不同版本操作系统有各自实现ptrace系统调用的方式,本文只关注Linux环境,因此先简单说明Linux下ptrace系统调用的用法。首先定义控制进程(tracer)和被控制进程(tracee),tracer可以观察和控制tracee的执行流程,检查和修改tracee的内存和寄存器内容,一个tracee只能关联(attach)一个tracer,一个tracer可以关联多个tracee。需要注意的是Linux下一个tracee实际是一个线程,一个包含多个线程的进程中每个线程可以单独关联各自的tracer。所有ptrace功能通过一个接口函数调用,格式如下:
long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
第一个参数request包含调用的具体功能,后续三个参数的含义和第一个参数相关,不同功能需要设置相应的参数,详细定义可以查看操作系统文档(man
ptrace)。图1演示了tracer控制一个tracee的过程。
图1 ptrace控制流程
tracer调用PTRACE_ATTACH功能关联指定的tracee,向tracee发送SIGSTOP信号,并调用waitpid等待tracee状态改变;
-
当tracee状态变成STOP,waitpid返回;
-
tracer调用PTRACE_SYSCALL功能让tracee进入单步执行状态,并调用waitpid等待tracee状态改变;
-
重复步骤2)和步骤3);
-
tracer调用PTRACE_DETACH功能让tracee恢复运行,并解除关联。
步骤3)中tracer可以检查和修改tracee的内