我目前正在学习相关的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
答案 0 :(得分:2)
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
电话。