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
execve在Linux中以这种方式定义:
INT的execve(常量字符*文件名,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 *瓦尔/])= 0
这应该结束了一个成功的execve
呼叫。
你是如何构建这些代码的? –
如果您使用RiP(相对)寻址,当然JMP/CALL/POP方法在64位代码中不是必需的。 –
如果你展示了如何构建和执行你的程序会有所帮助。但有一种观察是,用'execve'' argv'和'argp'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''但是有一点可以看出''你也需要NULL终止'argv'。所以**之前**'推rdi'你也应该'推rax' –