我想在Ubuntu 64位上使用以下32位shellcode执行execve("/bin/dash", &"/bin/dash", NULL)

global _start

_start:
    xor eax, eax ; set eax = 0 to push a null without using 0x0
    push eax ; eax = null pointer

    mov edx, esp ; edx = null pointer

    ; push '/bin/dash' into stack
    ; but length of string actually needs to be divisible by 4,
    ; otherwise there will be a 0x00 in the string, so:
    ; push null pointer first, then
    ; push '////bin/dash' into stack
    push eax ; eax = null pointer
    push 0x68736164
    push 0x2f6e6962
    push 0x2f2f2f2f

    mov ebx, esp ; ebx = string pointer '////bin/dash'
    push ebx
    mov ecx, esp ; ecx = pointer to string pointer
    mov eax, 0xfffffff4 
    not eax ; eax = 0xb = pointer to execve
    int 0x80 ; interrupt system call


我用以下行编译汇编代码,然后提取机器代码:

$ nasm -felf32 shellcode.asm -o x.o && ld -m elf_i386 x.o -o shellcode
$ objdump -d shellcode -M intel -s
shellcode:     file format elf32-i386

Contents of section .text:
 8048060 31c05089 e2506864 61736868 62696e2f  1.P..Phdashhbin/
 8048070 682f2f2f 2f89e353 89e1b8f4 fffffff7  h////..S........
 8048080 d0cd80                               ..P             

Disassembly of section .text:

08048060 <_start>:
 8048060:   31 c0                   xor    eax,eax
 8048062:   50                      push   eax
 8048063:   89 e2                   mov    edx,esp
 8048065:   50                      push   eax
 8048066:   68 64 61 73 68          push   0x68736164
 804806b:   68 62 69 6e 2f          push   0x2f6e6962
 8048070:   68 2f 2f 2f 2f          push   0x2f2f2f2f
 8048075:   89 e3                   mov    ebx,esp
 8048077:   53                      push   ebx
 8048078:   89 e1                   mov    ecx,esp
 804807a:   b8 f4 ff ff ff          mov    eax,0xfffffff4
 804807f:   f7 d0                   not    eax
 8048081:   cd 80                   int    0x80


然后我试图用这个c文件执行我的shellcode:

#include <stdio.h>
#include <string.h>

char *shellcode = "\x31\xc0\x50\x89\xe2\x50\x68\x64\x61\x73\x68\x68\x62\x69\x6e\x2f\x68\x2f\x2f\x2f\x2f\x89\xe3\x53\x89\xe1\xb8\xf4\xff\xff\xff\xf7\xd0\xcd\x80";

int main()
{
    fprintf(stdout,"Length: %d\n",strlen(shellcode));
    (*(void  (*)()) shellcode)();
}


我编译了这个带有以下内容的文件:

gcc -m32 -fno-stack-protector test_shellcode.c -o test_shellcode


但这会导致分段错误。
我用gdb调试了shellcode,看起来我的shellcode可以正常工作,但是第一个使用寄存器alah的行导致分段错误。

我该如何解决?

评论

当您移动edx时,特别是您实际上将esp的值移入edx中。不是esp指向的值。要访问此值,请使用mov edx [esp]。

@ bart1e是的,这是因为edx函数的每个定义都需要指向null而不包含null(因为它实际上是一个内部没有值的数组,因此null指针会终止它)

#1 楼

错误的参数

我能够解决我的问题!

函数execve具有以下定义:

int execve(const char *filename, char *const argv[], char *const envp[]);`
      ^                   ^                    ^                   ^
     eax                 ebx                  ecx                 edx


因此第二个参数argv不仅仅是一个指针,它实际上是(多个)指针的数组。因此,ecx需要以null终止,但是我的代码中不是这种情况。我还发现ecx不需要指向字符串/bin/dash,而是可以将其设置为null。

因此参数需要设置为:

eax = 0x0b
ebx = "/bin/dash"
ecx = 0x00
ecd = 0x00


汇编器

我现在只有29个字节的工作代码如下:

global _start

_start:
    ; set eax = 0 without using 0x00
    xor eax, eax 
    push eax ; terminating null string & reference for null pointer

    ; set edc = pointer to null
    ; set edx = pointer to null
    mov ecx, esp
    mov edx, esp

    ; push '////bin/dash' into the stack
    push 0x68736164
    push 0x2f6e6962
    push 0x2f2f2f2f

    ; set ebx = string pointer to '////bin/dash'
    mov ebx, esp

    ; set ecx = pointer to string pointer to '////bin/dash'
    push ebx

    ; set eax = 0xb (function 'execve')
    mov al, 0xb
    int 0x80 ; interrupt system call


#2 楼

我认为只需替换mov eax, 0xfffffff4not eax