在 x64 位程序集中执行系统命令?

Execute system command in x64 bit assembly?

我最近一直在尝试使用纯汇编来执行系统命令。我设法在此处发布的 x32 位二进制文​​件中实现了它:

但现在我正在尝试将相同的过程集成到 x64 位二进制文​​件中。我可能不擅长谷歌搜索,但我找不到任何展示如何在 x64 位中执行系统命令的文章。

准确的说,下面是我做的:

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

第一个系统调用处的断点:

(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

跟踪输出:

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, "7ELF[=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=]>[=12=][=12=][=12=][=12=]0l[=12=][=12=][=12=][=12=][=12=]"..., 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 +++

既然我们正在处理 64 位弧,那么假设我们也可能必须在每个参数之后推送一个 64 位 NULL,对吧? 我尝试了一些方法来推送一个 32 位 NULL 来分隔堆栈中的参数,但效果不佳。

不确定我犯了什么错误,脚本不工作:(

非常感谢任何指导。

我在 x64 bit kali linux

中使用 nasm

非常感谢@PeterCordes。

  1. 在64位架构中,您可以访问unistd_64.h查找系统调用的代码。在这种情况下,execve 的系统调用是 59.

  2. strace 帮了大忙。通过一些调试,发现执行文件位置 /bin//ls 应该存储在 rdi 并且参数 /bin//ls ./ 应该存储在 rsi.

完整的工作代码如下:

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