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

问题描述:

我目前正在学习相关Pentester Academy课程的64位汇编语言。GDB - 汇编程序返回/ bin/sh:0:无法打开

/bin/sh的:0:当GDB跑到我工作的代码创建了以下错误无法打开 [劣质1(过程4049)退出,代码为0177]

我google了错误和退出代码,并没有发现任何有用的东西。我试着一遍又一遍分析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 
+2

你是如何构建这些代码的? –

+0

如果您使用RiP(相对)寻址,当然JMP/CALL/POP方法在64位代码中不是必需的。 –

+0

如果你展示了如何构建和执行你的程序会有所帮助。但有一种观察是,用'execve'' argv'和'argp'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''但是有一点可以看出''你也需要NULL终止'argv'。所以**之前**'推rdi'你也应该'推rax' –

execve在Linux中以这种方式定义:

INT的execve(常量字符*文件名,char * const的的argv [], char * const的envp []);

[剪断]

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

如果你是通过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 *瓦尔/])= 0

这应该结束了一个成功的execve呼叫。