Port Binding Shellcode — SecurityTube Linux Assembly Expert 32 bit — Exercise 1

In this exercise we will go through the basics of a port binding shellcode and understand the motivation behind it. This is one of the foundational shellcode in the sense that this is an easy or simple entry into a victim/compromised machine which gives us the ability to do RCE(Remote Code Execution). As a matter of fact, if this is accomplished, there is a lot more left to desire with regards to the security of the victim/compromised host. The code has to be executed on the victim machine and the code opens up a TCP port to listen on. An attacker needs to know the IP and the port the machine is listening on to connect to and abuse it.

This basic shellcode does only one thing — spawns a shell over the network when the attacker/operator connects to the port its listening on. This is a simple shellcode but not trivial. The sequences involved are the normal standing up a TCP service to listen on a particular port. This means we need to do some socket programming as a PIE(Position Independent Executable) code. This sounds complicated, but in reality its something we all know theoretically but the implementation is a little different( a little challenging since its assembly code, x86 in this case). Let’s see.

A network service(TCP in this case) has to invoke the following system calls in sequence, ‘socket’, ‘bind’, ‘listen’, ‘accept’, ‘dup2’, ‘execve’.

Template, Comments and Defines

‘socket’ — creates the socket interface for a particular family and protocol that client programs can use to communicate.

socket() sys call with Args

‘bind’ — associates a particular port and other parameters to the socket descriptor obtained in the previous call.

bind() sys call with Args

‘listen’ — puts the socket descriptor into listening mode, so that its ready to be operational.

listen() sys call with Args

‘accept’ — this is the main driver that blocks and waits for incoming connections. As soon as a client connects successfully a socket descriptor is created that denoted the particular client connection. Note : This socket description is different from the listening socket descriptor. This descriptor is what identifies individual clients so that the operating system/client can communicate to the other end of this channel.

accept() sys call with Args

‘dup2' — this system call is what prepares for the magic to happen. It duplicates the 3 standard file descriptors(STDIN, STDOUT and STDERR) in the context of the running program such that the socket descriptor becomes an alias to all these 3 standard file descriptors.

dup2() sys call with Args

‘execve’ — the magic, this is the system call that executes the binary specified and inherits all the env variables and open file descriptors from the parent, remember we duped the standard file descriptors? Now any program invoked by execve has the standard file descriptors but are now pointing to the ones we set up in the previous call. So in effect all our standard file descriptors have become an alias to the socket descriptor. Any communications on these are proxied over the socket descriptor to the other end of the network. Did I say magic?

Detection: This kind of vulnerability is pretty rare these days with multiple tiered security like EDRs, Firewalls and Host/Network based rules/whitelisting. Its very difficult for an intruder to just connect to the machine and abuse it.

Please check the following github repo for the entire set of source files and helper scripts to generate and test the shellcode.


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

Student ID: SLAE -1100



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store