GDB - 汇编程序返回/ bin / sh:0:无法打开�

时间:2017-04-09 04:38:58

标签: linux gcc assembly x86-64 shellcode

我目前正在学习相关的Pentester学院课程中的64位汇编语言。我正在处理的代码在GDB中运行时会产生以下错误:

  

/ bin / sh:0:无法打开�   [Inferior 1(流程4049)退出,代码为0177]

我已经搜索了错误并退出了代码,并且没有发现任何有用的信息。我试着一遍又一遍地分析GDB中的代码,但所有正确的值似乎都在正确的寄存器中。我似乎无法找到错误。

您可以在下面找到代码。我的目标只是使用jump-call-pop技术调用execve系统调用。

global _start
section .text

_start:

jmp bash

code:

xor rax, rax
pop rdi
mov [rdi +7], al    

push rdi
mov rsi, rsp
push rax
mov rdx, rsp
mov al, 59
syscall 

bash:

call code 
string:     db      '/bin/shABBBBBBBBCCCCCCCC' 

编辑:

以下是我构建程序的方法:

nasm -f elf64 -o execve_stack_jcp.o execve_stack_jcp.asm 
ld -o execve_stack_jcp execve_stack_jcp.o

然后我使用objdump -M intel -d execve_stack_jcp输出反汇编,然后我在此c程序中输入:

#include <stdio.h>
#include <string.h>

unsigned char code[] = \
"\xeb\x13\x48\x31\xc0\x5f\x88\x47\x07\x57\x48\x89\xe6\x50\x48\x89\xe2\xb0\x3b\x0f\x05\xe8\xe8\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x41\x42\x42\x42\x42\x42\x42\x42\x42\x43\x43\x43\x43\x43\x43\x43\x43";

int main(void) {

printf("Shellcode length: %d\n", (int)strlen(code));

int (*ret)() = (int(*)())code;

ret();

return 0;
}

最后,我使用:

编译c程序
gcc -fno-stack-protector -z execstack -o shellcode shellcode.c

1 个答案:

答案 0 :(得分:2)

Linux中的

execve以这种方式定义:

  

int execve(const char * filename,char * const argv [],   char * const envp []);

     

[剪断]

     

argv是传递给新程序的参数字符串数组。按照惯例,这些字符串中的第一个(即argv [0])应该包含与正在执行的文件相关联的文件名。 envp是一个字符串数组,通常格式为key = value,它们作为环境传递给新程序。 argv envp数组必须在数组末尾中包含空指针

如果您要通过strace ./shellcode运行程序,那么您可能会看到类似的内容:

  

execve(“/ bin / sh”,[“/ bin / sh”,“\ 270”,“\ 1”,“\ 353 \ 23H1 \ 300_ \ 210G \ 7WH \ 211 \ 346PH \ 211 \ 342 \ 260; \ 17 \ 5 \ 350 \ 350 \ 377 \ 377 \ 377 / bin / s“......],[/ * 0 vars * /])= 0

你会注意到第二个参数argv在数组中有一堆额外的条目。这是因为你没有 NULL 终止argv数组。要纠正这个问题,您可以通过将0(通过 RAX )推送到堆栈来修改代码,如下所示:

xor rax, rax 
pop rdi
mov [rdi +7], al

push rax      ; NULL terminates the `argv` array
push rdi
mov rsi, rsp
push rax
mov rdx, rsp

如果您再次通过strace运行此更改,则会看到以下内容:

  

execve(“/ bin / sh”,[“/ bin / sh”],[/ * 0 vars * /])= 0

这最终应该是一次成功的execve电话。