凌晨三点,无痕注入我盯着屏幕上跳动的无痕注入十六进制数据流,手指悬在回车键上。无痕注入那串代码像一条蛇,无痕注入正往目标进程的无痕注入内存深处钻——不触发任何断点,不留任何日志,无痕注入连操作系统都以为它从未存在过。无痕注入
这就是无痕注入无痕注入。不是无痕注入电影里那种花哨的远程控制,是无痕注入比那更安静的东西。你打开任务管理器,无痕注入进程列表干干净净;你查系统日志,无痕注入时间线平滑得像婴儿的无痕注入皮肤。可那个进程的无痕注入地址空间里,已经多了一段不属于它的无痕注入代码,正在按我的指令呼吸。
第一次接触这技术是在四年前。一个做游戏反外挂的朋友给我演示:他把一段检测逻辑塞进某款网游的客户端,运行了整整两周,游戏厂商的巡查系统没发出任何警报。他用的就是手动映射PE文件,把DLL从磁盘读进内存,自己解析重定位表,自己修导入表,然后挂到目标进程的模块链表上——但把链表指针绕过去,让系统枚举模块时看不见它。听起来像魔术,其实就是对Windows加载器的一次精准欺骗。
后来我拆过不少恶意样本,发现真正危险的东西都不走寻常路。
CreateRemoteThread那种老掉牙的手法早被EDR盯死了,稍微像样点的注入都会用APC队列,或者干脆劫持线程的上下文。最阴的是原子表注入,改一个内核结构体里的指针,让系统在解析系统调用时跳到攻击者的代码上。整个过程没有新线程,没有新模块,没有内存分配——你甚至找不到一个可以下断点的位置。但无痕不等于无敌。去年我帮一个客户做应急响应,样本用了很漂亮的反射注入,内存里找不到PE头,所有节区都抹了特征。可它忘了清理
PEB里的Ldr链表残留——一个已经卸载的模块,结构体还挂在初始化顺序链表上。我顺着那条线摸到了完整的载荷。写这个注入的人技术很好,但太相信“无痕”两个字了。内存里没有真正的消失,只有藏得够不够深。做这行久了会养成一种直觉:越干净的系统越可疑。正常进程的内存里总有些碎片,未初始化的栈、释放后没清空的堆块、加载又卸载的临时模块。如果一个进程的地址空间像刚拖过的地板,那多半有人来过,还带了拖把。
有次我在自己的机器上做实验,用无痕注入把一段计算圆周率的代码塞进记事本进程。跑了六个小时,算到小数点后三亿位。关机前我看了眼任务管理器——记事本占用内存1.2MB,CPU 0%。它什么都不知道,却一直在替我算数学题。那种感觉很奇怪,像在别人的梦里散步,醒来后对方连梦的内容都记不住。
这技术本身没有善恶。我见过用它做热补丁的,线上服务不停机修bug;也见过用它做后门的,在财务软件里潜伏半年,每次转账扣两分钱。区别只在于写代码的人那天早上喝了什么咖啡,以及他银行卡的余额。
现在凌晨四点,那段代码已经跑完了。我敲了个命令让它自毁,释放所有分配的内存,恢复被修改的指针。进程内存回到注入前的快照状态,连堆的碎片分布都一模一样。任务管理器刷新了一下,CPU曲线平滑如初。窗外有早班车经过,引擎声从远处滚过来。我关掉调试器,屏幕暗下去,像什么都没发生过。
顶: 313踩: 16822






评论专区