程序集工作,但shellcode没有

时间:2017-09-17 16:53:29

标签: c gcc assembly nasm shellcode

我有一个x64处理器,我正在研究shellcode 我有以下代码:

section .text
  global _start

_start:
   push rax
   mov rbx, 0x68732f6e69622f2f
   shr rbx, 0x8
   push rbx
   mov rdi, rsp
   ;mov rdi, com

   mov al, 59
   syscall

使用foolowing命令编译时:

nasm -g -f elf64 execve.asm  

并与:

相关联
ld execve.o -o execve

运行正常。它打开一个shell。如果我从中获取shellcode:

"\x50\x48\xbb\x2f\x2f\x62\x69\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\xb0\x3b\x0f\x05"

并使用此C程序:

int main(void)
{
    const char shellcode[] = "\x50\x48\xbb\x2f\x2f\x62\x69\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\xb0\x3b\x0f\x05";

    (*(void (*)()) shellcode)();

    return 0;

} 编译它:

gcc -fno-stack-protector -z execstack -o ex2 ex.c

如果运行它会返回分段错误,但它应该执行shell。为什么? 感谢帮助!

2 个答案:

答案 0 :(得分:3)

您的独立程序集依赖于注册rsirdx被归零。 (正如您在http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/中看到的那样  sys_execve通过寄存器rdirsirdx获取三个参数,如果rdi是正确的文件名且rsi,Linux也会接受它}和rdx为零)。

程序启动时可能就是这种情况,但是当你从程序中运行指令时却不是这样 中间的一个程序。

因此,如果rsirdx中包含垃圾,则系统调用将失败并且指令流 将继续执行它在syscall指令之后找到的垃圾字节,最终导致崩溃(这确实是你的情况下发生的事情,因为你可以看到你是否通过{{1运行程序}})

使系统调用成功的最简单方法是将第二个和第三个参数清零:

gdb

对应的C代码:

section .text
  global _start

_start:
   xor rax, rax
   xor rsi, rsi ; zero 2nd argument
   xor rdx, rdx ; zero 3rd argument
   push rax
   mov rbx, 0x68732f6e69622f2f
   shr rbx, 0x8
   push rbx
   mov rdi, rsp

   mov al, 59
   syscall

答案 1 :(得分:0)

您遗漏了\x6e

这会导致segv,因为exec失败并且在系统调用之后没有返回。