emp3r0r – Linux下的进程注入和持久化

背景
本文所介绍的内容是emp3r0r框架持久化模块的一部分。
Linux有一个独特的东西叫procfs
,把“Everything is a file”贯彻到了极致。从/proc/pid/maps
我们能查看进程的内存地址分布,然后在/proc/pid/mem
我们可以读取或者修改它的内存。
所以理论上我们只需要一个dd
和procfs
即可将代码注入一个进程,也确实有人写了相关的工具。
但既然Linux提供了一个接口(只有这么一个,不像你们Windows),我们在通常情况下直接调用它就可以了。
ptrace
对,这唯一的接口就是ptrace
。
这东西是用来操作进程的,大多用于调试器,它提供的功能足够我们完成本文所需的shellcode注入以及进程恢复了。
我们的思路是:
- attach到目标进程,将其接管
- 把shellcode写到
RIP
指向的位置,在此之前先备份原有的代码 - 恢复进程运行
- shellcode执行到中断,
trap
#SIGTRAP)并被我们接管 - 我们把原先的代码写回去,寄存器也都恢复
- 继续原进程的执行
进程的恢复
看了上面的思路,这个似乎并不难。但别忘了,你的shellcode搞乱的不只是这段text和寄存器,它至少还搞乱了原进程的的stack,而且shellcode可能会一直堵塞主线程,这样就永远也不会回到原进程的执行流程了。
而且有的shellcode会直接execve
从而干脆利落地让原进程成为虚无,你除了再execve
回去基本上别无它法了。
所以,我直接从原进程fork
出一个子进程,在子进程里执行我的shellcode,顺手恢复原进程,对进程的影响几乎可以忽略不计。
菜鸡的第一份shellcode
本菜鸡从未写过shellcode,是msfvenom
的忠实用户。
我寻思着第一份shellcode就不写烂大街的hello world了,直接写个能用的岂不美哉。
于是在duckduckgo和某开源社区大佬们的指导下,我逐渐明白了该怎么写,武器化之后,就有了这篇文章。
怎么写
啥语言
正常情况下都是用汇编来写,不过C也可以。某大佬推荐的是这样:

这样写显而易见的好处是,我们不用费心去操作栈了,数据可以由C来安排好。
本文使用纯汇编来做,这种方法以后有机会再尝试了。
编辑器
我当然直接用vim了,你们随便找个熟悉的文本编辑器都可以。
这里用的是nasm汇编器,使用Intel语法。
nasm
写shellcode的话,不用section .data
是最好的,省得多出来一堆