3

Can anyone explain what this means:

SHELL=/bin/bash script -q /dev/null

It is used to upgrade a shell in a CTF in HTB:

 SHELL=/bin/bash script -q /dev/null
 Ctrl-Z
 stty raw -echo
 fg
 reset
 xterm

It is similar as in this article: Upgrading Simple Shells to Fully Interactive TTYs, but I don't understand what it does.

man script says:

NAME
       script - make typescript of terminal session
SYNOPSIS
       script [options] [file]

   script makes a typescript of everything displayed on your terminal.  It is useful for students
   who need a hardcopy record of an interactive session as proof of an assignment, as  the  type‐
   script file can be printed out later with lpr(1).

and

   -q, --quiet
          Be quiet (do not write start and done messages to standard output).
5
  • Could it be that you are missing quotes ? Setting SHELL defines the shell but because of the missing quotes the shell would become /bin/bash and after that the command script -q /dev/null will be executed. Putting it on 1 line just makes it confusing.
    – Garo
    Commented Jul 17, 2020 at 20:53
  • 1
    And the -q option would be an option to script, not to bash Commented Jul 17, 2020 at 22:45
  • Yes, you're right. This I missed too. The quotes are not missing. It's mainly about the command script I think to understand it. Commented Jul 18, 2020 at 1:44
  • And @KamilMaciorowski it's the latter one. I correct it in the question. Thanks for the hint. Commented Jul 18, 2020 at 1:52
  • 1
    @Garo, SHELL="/bin/bash script -q /dev/null" wouldn't work with any program that just uses SHELL as is to name the program used as a shell (without doing shell-style splitting itself). And SHELL=/bin/bash, then script -q /dev/null on another line is different, you'd need to export the SHELL variable then. That command is written just as it's meant to be.
    – ilkkachu
    Commented Jul 18, 2020 at 11:37

1 Answer 1

3

So, the context here seems to be that you have a plain TCP connection to a shell running somewhere, maybe using something like netcat in your end. By "plain" I mean that the shell (its stdin/stdout) is directly connected to the network socket, not through something like SSH that would provide a pseudo-terminal (pty) for the shell.

The pseudo-terminal is important, because that's the layer where all the smarts happen, like processing ^C and ^Z etc.

SHELL=/bin/bash script -q /dev/null

This runs script with the environment variable SHELL set to /bin/bash and the arguments -q and /dev/null. The point of script is to record everything a shell session gets as input and prints as output, and to do that, it uses as pty. It also passes everything through while running. Creating that pty is the point here, not the actual record which is sent to /dev/null. -q just makes script not print a message at startup.

Ctrl-Z

Assuming we were connected to the remote via netcat, the local terminal is probably in a mode where it processes ^Z. So this suspends the local netcat process.

stty raw -echo

Then we put the local terminal in raw mode, so that it doesn't interfere with the remote pty.

fg

and start netcat again. Now, we have a shell with a pty open on the remote end, and the local terminal doesn't interfere with it.

reset

Reset the remote terminal, I'm not sure if this is necessary. In the article you linked to, they seemed to need it, but it worked ok for me without it.

Resetting the local terminal after ending the remote script may be harder, because then you have the local terminal in raw mode, running netcat connected on the remote, and a hard time killing that netcat. But then you can just kill the local xterm/screen window/whatever your shell was running in. Or may be run exec script instead on the remote.

2
  • Wow, awesome explanation. So just to have a full understading: The point of SHELL=/bin/bash script is to get a pty? @ilkkachu Just to let you know, could not vote cast +1 because if have to less reputation. I also changed the title to make it more searchable Commented Jul 19, 2020 at 11:20
  • @MatthiasAltmann, the point of running script is to get a pty (on the remote). The SHELL=/bin/bash just makes sure script starts Bash (and not /bin/sh which might be another shell), and the -q option and the /dev/null filename just make the output cleaner and don't leave any extra files laying about.
    – ilkkachu
    Commented Jul 19, 2020 at 18:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .