[英]GDB - Assembly program returns /bin/sh: 0: Can't open �
I am presently learning 64-bit assembly language from the related Pentester Academy course. 我目前正在从相关的Pentester学院课程中学习64位汇编语言。 The code I'm working on creates the following error when ran in GDB: 我正在处理的代码在GDB中运行时会产生以下错误:
/bin/sh: 0: Can't open [Inferior 1 (process 4049) exited with code 0177] / bin / sh:0:无法打开-[以代码0177退出的劣等1(进程4049)]
I have googled the error and exit code and haven't found anything helpful. 我已经在错误和退出代码上搜索了Google,但没有发现任何有用的信息。 I tried analyzing the code in GDB over and over, but all the right values seem to be in the right registers. 我试图一遍又一遍地分析GDB中的代码,但是所有正确的值似乎都在正确的寄存器中。 I can't seem to find what's wrong. 我似乎找不到任何问题。
You can find the code below. 您可以在下面找到代码。 My goal is simply to invoke the execve syscall using the jump-call-pop technique. 我的目标只是使用Jump-call-pop技术调用execve syscall。
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'
EDIT: 编辑:
Here is how I built the program: 这是我构建程序的方式:
nasm -f elf64 -o execve_stack_jcp.o execve_stack_jcp.asm
ld -o execve_stack_jcp execve_stack_jcp.o
I then use objdump -M intel -d execve_stack_jcp
to output the disassembly which I then input in this c program: 然后,我使用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;
}
Finally, I compile the c program using: 最后,我使用以下命令编译c程序:
gcc -fno-stack-protector -z execstack -o shellcode shellcode.c
execve in Linux is defined this way: Linux中的execve是这样定义的:
int execve(const char *filename, char *const argv[], char *const envp[]); int execve(const char *文件名,char * const argv [],char * const envp []);
[snip] [剪断]
argv is an array of argument strings passed to the new program. argv是传递给新程序的参数字符串数组。 By convention, the first of these strings (ie, argv[0]) should contain the filename associated with the file being executed. 按照约定,这些字符串中的第一个(即argv [0])应包含与正在执行的文件关联的文件名。 envp is an array of strings, conventionally of the form key=value, which are passed as environment to the new program. envp是一个字符串数组,通常形式为key = value,这些字符串作为环境传递到新程序。 The argv and envp arrays must each include a null pointer at the end of the array . argv和envp数组必须在数组末尾都包含一个空指针 。
If you were to run your program through strace ./shellcode
you'd probably see something similar to this: 如果要通过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 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变量* /])= 0
You'll notice the second argument argv
has a bunch of extra entries in the array. 您会注意到第二个参数argv
在数组中有很多额外的条目。 This is because you didn't NULL terminate the argv
array. 这是因为您没有使用NULL终止argv
数组。 To correct this you could modify your code by pushing 0 (via RAX ) onto the stack like this: 要更正此问题,您可以通过如下方式通过将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
If you were to run this change through strace
again you'd see something like: 如果您再次通过strace
运行此更改,则会看到类似以下内容的内容:
execve("/bin/sh", ["/bin/sh"], [/* 0 vars */]) = 0 execve(“ / bin / sh”,[“ / bin / sh”],[/ * 0 vars * /])= 0
This should end up being a successful execve
call. 这应该最终是成功的execve
调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.