This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:

Student ID: SLAE-1290


The assignment consists in creating a bindshell shellcode which binds on a port, executes a shell on incoming connection and allows to easily configure the listening port.

First of all, let’s create a bindshell C program to understand how a bindshell works.

That is my C source code:

Let’s build it:

Run it and connecting from another terminal:

It works! Now we need to work on this program to “convert” it in a shellcode. This program uses many functions in external libraries and we need to transform them in syscall. They are:

  • socket
  • bind
  • listen
  • accept
  • dup2
  • execve
  • close ( To skip because it is not mandatory)

Let’s start from socket syscall. It creates an endpoint for communication and returns a descriptor.Socket syscall number is 359.

It needs 3 arguments: domain,type,protocol. PF_INET domain is 2. SOCK_STREAM type is 1, protocol is 0. Let’s create the first piece of our assembly shellcode:

Now the bind syscall (n. 361). It allows to assign an address to a specific socket descriptor. It also needs three arguments. The socket descriptor, sockaddr structure and size of the structure.

Listen syscall (n. 363) is pretty easy. It marks the socket as a passive socket; this means it is able to accept incoming connections. Two arguments are needed, the socket descriptor and the backlog.

Instead of accept, accept4 syscall is used (n. 364) which extracts and manage connection requests for a listening socket. It needs three arguments, the socket descriptor, a sockaddr structure and the structure length. The last two are not mandatory and could be set to null.

Time for the dup2 syscall (n. 63) to redirect the input,error and output standards to socket descriptor. Two arguments, old filedescriptor and new file descriptor. Since we need to repeat the syscall three times we can simplify the whole thing creating a loop.

It is the turn of execve (n.11), to execute the real shell.

We can skip the close syscall to limit the size of our shellcode.

Putting all together:

Now we need to build the nasm file and link it.

Everything seems to be okay. Let’s dump the shellcode and put it in a C program to test if it works.

No nulls. Perfect!

We need to compile it with the gcc options -fno-stack-protector and -zexecstack.

The shellcode works perfectly!

Last part of assignment is to create a wrapper script to easily edit the shellcode port number. I decided to make this in C.




Share it