【发布时间】:2016-10-07 09:32:06
【问题描述】:
0x7fffffffeef8: xor %rsi,%rsi
0x7fffffffeefb: xor %rax,%rax <- now rax is 0
0x7fffffffeefe: movabs $0xff978cd091969dd1,%rbx <- rbx='/bin/dash'
0x7fffffffef08: neg %rbx
0x7fffffffef0b: push %rbx
0x7fffffffef0c: push %rsp
0x7fffffffef0d: pop %rdi <- rdi is string
0x7fffffffef0e: mov $0x3b,%al
0x7fffffffef10: syscall
(gdb) stepi
0x00007fffffffef08 in ?? ()
(gdb) stepi
0x00007fffffffef0b in ?? ()
(gdb) stepi
0x00007fffffffef0c in ?? ()
(gdb) stepi
0x00007fffffffef0d in ?? ()
(gdb) stepi
0x00007fffffffef0e in ?? ()
(gdb) stepi
0x00007fffffffef10 in ?? ()
(gdb) stepi
0x00007fffffffef12 in ?? ()
在0x7fffffffef10 中,存在系统调用指令。但是当我在 GDB 中使用 stepi 命令时,我从不执行 /bin/dash。我认为这个程序集应该执行/bin/dash。我误会了吗?
我上传了完整的汇编代码。我把xor %eax, %eax改成了xor %rax, %rax
我在汇编代码中添加了xor %rdx, %rdx。但我无法获得预期的结果。
process 1993 is executing new program: /bin/dash
[Inferior 1 (process 1993) exited normally]
(gdb)
结果是这样的,但我想要的是$而不是(gdb)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(void)
{
char str[256];
printf("Type sentence.\n");
gets(str);
printf("%s\n", str);
}
上面是插入了shell代码的程序。
我使用 Linux 16.04,x64 架构
【问题讨论】:
-
syscall很可能确实被执行了,但它的参数在某种程度上是错误的。您没有提供minimal reproducible example,所以我们无法确定。 -
除了
al=0x3b和rdi=rsp之外,您不会在代码中显示任何参数值。这甚至不足以确定调用了哪个系统调用函数。如果你足够幸运,在此之前rax几乎为零,它将执行execve。我认为它需要 3 个参数(我不确定要检查哪些文档来检查系统调用,因为 linux 源代码中有几个类似的 C 入口点)。看起来你误解了汇编的工作原理,以及在rsi/etc 中提供价值意味着什么。 -
我怀疑您的问题与 RDX (envp) 中的参数有关。您可能希望阅读execve 文档。我猜,当您将此代码作为程序运行时,您很幸运 RDX 恰好为 0(NULL)并且没有生成错误(如果出现错误,则返回值指示因此将在系统调用后的 RAX 中)。您可以通过
strace运行您的程序以查看系统调用、参数和返回值。您可能会发现它失败的原因。 -
在你的程序上运行
strace说明了什么。execve应该有一行。在syscall之后,RAX 中的返回值是多少?您可以通过发出以下命令来打开文本模式 windows gdb:layout asm,后跟layout reg。 -
大多数在 shell 代码中启动
/bin/sh的人并不是为了启动与用户的交互式终端。他们使用它来运行无需用户输入即可完成有趣事情的命令。由于您的用户输入来自文件,因此 shell 不会变成交互式的,也不会提供提示。
标签: assembly gdb 64-bit system-calls shellcode