在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
答案 0 :(得分:3)
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,请注意,它在指令(非负0
寻址模式和32位立即数)和数据中都包含多个rel32
字节。
如果您不编写shellcode(要与代码和数据一起提取为平面二进制文件),请将数据放在单独的部分中,最好是.rodata
用于只读数据。