【发布时间】:2017-04-09 04:38:57
【问题描述】:
我目前正在通过相关的 Pentester Academy 课程学习 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
【问题讨论】:
-
你是如何构建这段代码的?
-
当然,如果您使用 RiP(相对)寻址,则在 64 位代码中不需要 JMP/CALL/POP 方法。
-
如果您展示了如何构建和执行程序,将会有所帮助。但一个观察结果是,
execveargv和argp需要以 NULL 结尾的字符串列表,但您只能以 null 终止 argp(通过首先推送rax)。您也需要 NULL 终止argv。所以之前push rdi你也应该做push rax -
我看到你更新了你的问题。你看到我关于 null 终止字符串数组
argv的评论了吗? -
您好@MichaelPetch,感谢您的回答!无法理解我是如何错过的。附带说明一下,我知道 RIP 相对寻址技术,该程序仅用于了解 jump-call-pop 的工作原理;-)
标签: linux gcc assembly x86-64 shellcode