I recently been trying to execute system commands using pure assembly. I managed to achieve it in a x32 bit binary as posted here: execute system command (bash) using assembly?
But Now I am trying to integrate that same procedure to a x64 bit binary. I might be very bad at art of googling but I couldn't find any article showing how to execute system commands in x64 bit.
Precisely said, below is what I did:
SECTION .data
SECTION .text
global main
main:
xor rax, rax
xor rdx, rdx
push rdx
mov rdi, 0x736c2f2f6369622f ; "sl/nib/"
push rdi
mov rbx, rsp
push rdx
mov rdi, 0x2f
push rdi
mov rsi, rsp
push rax
push rsi
push rbx
mov rcx, rsp
mov rax, 59
syscall
mov rax, 60
syscall
breakpoint at first syscall:
(gdb) x/20x $rsp
0x7fffffffe140: 0xffffe168 0x00007fff 0xffffe158 0x00007fff
0x7fffffffe150: 0x00000000 0x00000000 0x0000002f 0x00000000
0x7fffffffe160: 0x00000000 0x00000000 0x6369622f 0x736c2f2f
0x7fffffffe170: 0x00000000 0x00000000 0xf7e1bbbb 0x00007fff
0x7fffffffe180: 0x00000000 0x00000000 0xffffe258 0x00007fff
(gdb) x/20x $rcx
0x7fffffffe140: 0xffffe168 0x00007fff 0xffffe158 0x00007fff
0x7fffffffe150: 0x00000000 0x00000000 0x0000002f 0x00000000
0x7fffffffe160: 0x00000000 0x00000000 0x6369622f 0x736c2f2f
0x7fffffffe170: 0x00000000 0x00000000 0xf7e1bbbb 0x00007fff
0x7fffffffe180: 0x00000000 0x00000000 0xffffe258 0x00007fff
(gdb) x/20x $rsi
0x7fffffffe158: 0x0000002f 0x00000000 0x00000000 0x00000000
0x7fffffffe168: 0x6369622f 0x736c2f2f 0x00000000 0x00000000
Strace output:
execve("./system", ["./system"], 0x7ffd27c17790 /* 45 vars */) = 0
brk(NULL) = 0x5642527c2000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=104798, ...}) = 0
mmap(NULL, 104798, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fc05fca4000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320l\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1820104, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc05fca2000
mmap(NULL, 1832568, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fc05fae2000
mprotect(0x7fc05fb07000, 1642496, PROT_NONE) = 0
mmap(0x7fc05fb07000, 1339392, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x25000) = 0x7fc05fb07000
mmap(0x7fc05fc4e000, 299008, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16c000) = 0x7fc05fc4e000
mmap(0x7fc05fc98000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b5000) = 0x7fc05fc98000
mmap(0x7fc05fc9e000, 13944, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fc05fc9e000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7fc05fca3500) = 0
mprotect(0x7fc05fc98000, 12288, PROT_READ) = 0
mprotect(0x564250be4000, 4096, PROT_READ) = 0
mprotect(0x7fc05fce5000, 4096, PROT_READ) = 0
munmap(0x7fc05fca4000, 104798) = 0
execve(0x2f, [0x2f], NULL) = -1 EFAULT (Bad address)
exit(47) = ?
+++ exited with 47 +++
Since we are dealing with a 64 bit arc, then presuming that we might have to push a 64 bit NULL after every arguments too, right? I played around a little to push a 32 bit NULL to separate the arguments in the stack, but that didn't work as well.
Not sure what mistake am I committing that the script is not working :(
Any guidance are much appreciated.
I am using nasm
in a x64 bit kali linux
Huge thanks to @PeterCordes.
In 64 bit architecture, you can visit unistd_64.h
to find codes for system calls. which in this case for execve
the system call were 59.
strace helped a lot. with a bit of debugging, found out that the the executing file location /bin//ls
should be stored at rdi
and the arguments /bin//ls ./
should be stored at rsi
.
complete working code is below:
SECTION .data
SECTION .text
global main
main:
xor rax, rax
xor rdx, rdx
push rdx
mov rcx, 0x736c2f2f6e69622f ; "sl/nib/"
push rcx
mov rdi, rsp
;push rdx
mov rcx, 0x2f2e
push rcx
mov rsi, rsp
push rax
push rsi
push rdi
mov rsi, rsp
mov rax, 59
syscall
mov rax, 60
syscall
User contributions licensed under CC BY-SA 3.0