GDB - 汇编程序 returns /bin/sh: 0: 无法打开 �
GDB - Assembly program returns /bin/sh: 0: Can't open �
我目前正在通过相关的 Pentester Academy 课程学习 64 位汇编语言。当 GDB 中 运行 时,我正在处理的代码会产生以下错误:
/bin/sh: 0: Can't open �
[Inferior 1 (process 4049) exited with code 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
execve in Linux 是这样定义的:
int execve(const char *filename, char *const argv[],
char *const envp[]);
[snip]
argv is an array of argument strings passed to the new program. By convention, the first of these strings (i.e., argv[0]) should contain the filename associated with the file being executed. envp is an array of strings, conventionally of the form key=value, which are passed as environment to the new program. The argv and envp arrays must each include a null pointer at the end of the array.
如果您通过 strace ./shellcode
运行 您的程序,您可能会看到与此 相似 的内容:
execve("/bin/sh", ["/bin/sh", "0", "", "3H10_0GWH16PH120;00777/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
调用。
我目前正在通过相关的 Pentester Academy 课程学习 64 位汇编语言。当 GDB 中 运行 时,我正在处理的代码会产生以下错误:
/bin/sh: 0: Can't open � [Inferior 1 (process 4049) exited with code 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
execve in Linux 是这样定义的:
int execve(const char *filename, char *const argv[], char *const envp[]);
[snip]
argv is an array of argument strings passed to the new program. By convention, the first of these strings (i.e., argv[0]) should contain the filename associated with the file being executed. envp is an array of strings, conventionally of the form key=value, which are passed as environment to the new program. The argv and envp arrays must each include a null pointer at the end of the array.
如果您通过 strace ./shellcode
运行 您的程序,您可能会看到与此 相似 的内容:
execve("/bin/sh", ["/bin/sh", "0", "", "3H10_0GWH16PH120;00777/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
调用。