我是编写汇编代码/shellcode 的新手。 我的 shellcode 应该通过带有参数数组的系统调用 execve 生成 shell。 当我运行编译后的 shellcode 时,它似乎可以工作,我在命令行上打印了我的用户名,并且所有参数都是正确的,并使用 strace 工具进行了分析。
但是当我使用 shellcode 测试器运行 shellcode 时,它没有将正确的参数传递给 execve 函数,并且我无法生成 shell。
这是我的 64 位 shellcode:
section .text
global _start
_start:
;execve
; - rax = syscall number (59, 0x3b)
; - rdi = const char *filename
; - rsi = const char *const *argv
; - rdx = const char *const *envp
xor rax, rax
xor rdx, rdx
; //bin/sh
push rdx
mov rbx, 0x68732f6e69622f2f
push rbx
mov rdi, rsp
; -c
push rdx
sub rsp, 2
mov word [rsp], 0x632d
lea rsi, [rsp]
; whoami
push rdx
sub rsp, 6
mov word [rsp], 0x6877
mov dword [rsp+2], 0x696d616f
lea rcx, [rsp]
push rdx
push rcx
push rsi
push rdi
mov rsi, rsp
push 0x3b
pop rax
syscall
;exit
; - rax = syscall number (60, 0x3c)
; - rdi = int error_code
push 0x3c
pop rax
shl rdi, 0x1
neg rdi
syscall
这是我的 shellcodetester:
# include <stdio.h>
# include <string.h>
# include <unistd.h>
# include <sys/mman.h>
# define EXEC_MEM ((void *) 0x80000000)
int main() {
const unsigned char shellcode[] = "\x48\x89\xe5\x48\x31\xc0\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x52\x48\xbb\x2f\x2f\x62\x69\x2f\x73\x68\x53\x48\x89\xe7\x52\x48\x83\xec\x02\x66\xc7\x04\x24\x2d\x63\x48\x8d\x34\x24\x52\x48\x83\xec\x06\x66\xc7\x04\x24\x77\x68\xc7\x44\x24\x02\x6f\x61\x69\x48\x8d\x0c\x24\x52\x51\x56\x57\x48\x8d\x34\x24\x6a\x3b\x58\x0f\x05\x6a\x3c\x58\x48\xd1\xe7\x48\xf7\xdf\x0f\x05";
mmap(EXEC_MEM, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, -1, 0);
memcpy(EXEC_MEM, (void *)shellcode, strlen(shellcode)+1);
(*(int (*)())EXEC_MEM)();
return 0;
}
编译shellcode:
nasm -f elf64 -o './shell-64Bit.o' './shell-64Bit.asm' && ld -m elf_x86_64 -o './shell-64Bit' './shell-64Bit.o'
编译shellcodetester:
gcc -no-pie -fno-stack-protector -z execstack './shellcodetester.c' -o './shellcodetester'
转储 shellcode:
objdump -d './shell-64Bit'|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
我用gdb调试编译好的shellcodetester,用disas main分析main函数,并在main函数的最后一个调用指令处设置断点,然后用si单步执行shellcode指令。
我意识到我的数据从堆栈中弹出,并且寄存器由于未知原因而具有错误的值。
objcopy -Obinary './shell-64Bit' './shell-64Bit.bin'
hexdump -v -e '"\\""x" 1/1 "%02x" ""' './shell-64Bit.bin'
这对我有用!