我试图在对一些 64 位代码调用 /bin/bash
时传递参数。我无法使用 .data
部分,这对我来说有点棘手。我看过各种代码示例,但没有一个非常清楚(这里是初学者)。我想调用的是 /bin/bash -c id
。
当我尝试将第二个参数保留为空时,我的代码有效,但当我添加它时,出现以下错误:
execve("/bin/bash", [0x7361622f6e69622f, 0x646920632d2068, 0x7361622f6e69622f, 0x68], NULL) = -1 EFAULT (Bad address)
编译:nasm -f elf64 -o test.o test.asm;ld -o test test.o
section .text
global _start
_start:
mov rax,59
lea rdi,[rel bin]
lea rsi,[rel msg]
syscall
align 8
msg db '/bin/bash -c /bin/id',0
bin db '/bin/bash',0
请您参考如下方法:
execve 的第二个参数是字符串指针数组的地址(char **
或 char *argv[]
) 。您已为其指定了单个字符串的地址 (char *
)。
还有execve(2)
采用第三个参数,环境列表。正如手册页所述,argv 和/或 envp 可以为 NULL,Linux 将其视为等同于空列表(指向内存中 NULL 的有效指针)。
应该是这样的:
mov rax, 59
lea rdi, [rel bin]
lea rsi, [rel args]
xor edx, edx ; Linux accepts NULL instead of a pointer to NULL
syscall
; section .rodata
align 8
args dq bin, arg1, arg2, 0
arg1 db '-c',0
arg2 db '/bin/id',0
bin db '/bin/bash',0
如果您正在编写 shellcode,请注意,指令(非负 rel32
寻址模式和 32 位立即数)和数据。
如果您不编写 shellcode(将代码和数据一起提取到平面二进制文件中),请将数据放在单独的部分中,最好将 .rodata
放在只读数据中。