禁用写权限且禁止显式syscall指令时如何通过shellcode读取文件
思路指引
先明确认知误区
Call Gate方案在标准Linux环境下不可行:Linux内核不会为用户态预留可直接调用的调用门,用户态本身没有权限访问或操作GDT中的调用门项,ASLR不是这条路的主要限制,本身设计上就不支持普通用户态程序用调用门做系统调用。
可行方向
- 复用现有内存中的syscall指令
你运行shellcode的进程地址空间内,必然存在已经映射的可执行代码段(比如libc库、vDSO页),这些代码段中本身就包含大量现成的syscall指令,很多还附带ret后缀组成syscall ; ret的短gadget。你只需要在原有shellcode需要写syscall的位置,替换为跳转到该gadget地址的指令即可,不需要自己在shellcode中写入0x0f05字节,完全可以绕过静态过滤。 - 直接调用vDSO中的系统调用包装函数
Linux的vDSO(虚拟动态共享对象)页默认映射到所有用户态进程地址空间,其中内置了open、sendfile、exit等常用系统调用的包装实现,你可以直接调用这些包装函数,不需要自己触发系统调用,函数内部已经封装了syscall逻辑,不会触发你提交的shellcode的字节过滤。vDSO的地址就算开启ASLR,也可以通过进程地址空间布局特征、栈残留指针等方式快速定位。 - 指令拆分绕过静态检测
如果过滤规则是仅静态匹配shellcode中的连续0x0f05/0x0f34/0x80cd字节序列,你可以用非连续生成执行流的方式绕过,比如利用短跳转在两条指令中间插入无意义的单字节指令,将syscall的两个字节拆分到不同的指令块中,执行时CPU会按顺序读取这两个字节组成syscall指令,但静态扫描时不会匹配到连续的特征字节。
内容的提问来源于stack exchange,提问作者endemwone
相关产品推荐
相关产品推荐

