【发布时间】:2020-02-19 19:39:15
【问题描述】:
我最近一直在尝试使用纯汇编执行系统命令。我设法在 x32 位二进制文件中实现它,如下所示:execute system command (bash) using assembly?
但现在我正在尝试将相同的过程集成到 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
Strace 输出:
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 +++
既然我们处理的是 64 位弧,那么假设我们可能也必须在每个参数之后推入 64 位 NULL,对吗? 我玩了一点,推送一个 32 位 NULL 来分隔堆栈中的参数,但效果不佳。
不知道我犯了什么错误,脚本不工作:(
非常感谢任何指导。
我在x64 bit kali linux 中使用nasm
【问题讨论】:
-
rax=0x0b=11 / 系统调用是 munmap。使用
strace调试进行系统调用的程序。 -
@PeterCordes 系统调用 0x0b 是否应该是别的东西?我明白 64 位系统调用是不同的,例如 0x04 是 32 位写入的,但 0x01 是 64 位的。
-
eax=0x0b / int 0x80 是 execve,所以显然这就是您在该代码的 64 位端口中想要的。 (显然,这是您调用可执行文件而不是 munmap 所需的系统调用)。检查文档和/或
asm/unistd_32.h与asm/unistd_64.h。当然调用约定也不同,不同的寄存器。阅读有关 64 位系统调用的教程。 -
@PeterCordes, ty
unistd_64.h真的很有帮助。所以,59假设系统调用execve很好,更新我的脚本。但仍然无法正常工作,还将 strace 输出添加到我的问题中。我想问题出在execve(0x2f, [0x2f], NULL) = -1 EFAULT (Bad address),对吧?
标签: linux assembly x86-64 nasm