50

Imagine the following code:

ATTACKERDATA="$(cat attackerControlledFile.txt)"
echo "${ATTACKERDATA}"

An attacker can, through whatever arbitrary process, modify the contents of attackerControlledFile.txt to anything they desire. The content can be ASCII, UTF-8, Binary, etc. Anything is fine. The machine also assumes that it is infinitely fast, so even an extremely large file of multiple terrabytes would be read and printed immediately.

Is it possible for an attacker, regardless of how unlikely it would be, to exploit this somehow by modifying the content of attackerControlledFile.txt? "Somehow" refers to things like:

  • This code only works in bash
  • This code requires the output to be printed onto a specific terminal emulator
  • Etc.

Everything else assumes a reasonably sane system. This means that answers such as "If echo is an attacker-controlled binary that's actually malware" does not count, as the existence of malware is not exactly "reasonably sane". Answers that would require a specific software or version of that software to be present do count, as long as that software was not made for the purpose of exploitation.


A similar question asks Is it possible to use the Linux “echo” command maliciously?, but the accepted answer is actually about a flaw in the design of a web application. Furthermore, it requires the attacker to be able to do redirects, which as far as I know, this construct cannot do.

12
  • 9
    what if it's a million bells? while not dangerous, it's certainly annoying...
    – dandavis
    Jun 6, 2019 at 20:12
  • 2
    <bel> plays simultanously, so not that annoying
    – Jasen
    Jun 7, 2019 at 3:37
  • 2
    @dandavis You are free to assume an infinitely patient user as well ;)
    – user163495
    Jun 7, 2019 at 4:52
  • 3
    Will attackerControlledFile.txt always be a regular file? If it can be changed to a symlink or FIFO then there's a fairly straightforward DOS involving /dev/urand, which would also probably cripple any cryptographic code that an application on the same box might run. I'll type this up into a "proper" answer if it can be a symlink, but if not then I won't bother.
    – ymbirtt
    Jun 7, 2019 at 8:47
  • 5
    I'm not aware of any actual published exploit, but I've noticed that cat against a binary file can change PuTTY's settings. The attack surface here might be more than just the host OS.
    – Alex H.
    Jun 7, 2019 at 20:44

5 Answers 5

47

Is it possible for an attacker, regardless of how unlikely it would be, to exploit this somehow by modifying the content of attackerControlledFile.txt? "Somehow" refers to things like:

This code requires the output to be printed onto a specific terminal emulator

In fact, yes. Old terminals like vt100 have the ability to use ANSI escape sequences to do special things, like execute commands. The following site below documents this ability using a simple echo, like you describe.

https://www.proteansec.com/linux/blast-past-executing-code-terminal-emulators-via-escape-sequences/

The article is in depth with specific exploit instructions, but the general idea can be summarized from this excerpt from the site:

Dangerous Escape Sequences Terminal emulators support multiple features as described below [8]:

  • Screen Dumping: a screen dump escape sequence will open arbitrary file and write the current content of the terminal into the file. Some terminal emulators will not write to existing files, but only to new files, while others will simply overwrite the file with the new contents. An attacker might use this feature to create a new backdoor PHP file in the DocumentRoot of the web server, which can later be used to execute arbitrary commands.

  • Window Title: an escape sequence exists for setting the window title, which will change the window title string. This feature can be used together with another escape sequence, which reads the current window title and prints it to the current command line. Since a carriage return character is prohibited in the window title, an attacker can store the command in a window title and print it to the current command line, but it would still require a user to press enter in order to execute it. There are techniques for making the command invisible, like setting the text color to the same color as the background, which increases the changes of user pressing the enter key.

  • Command Execution: some terminal emulators could even allow execution of the command directly by using an escape sequence.

As pointed out in the comments, this particular exploit was fixed decades ago on modern terminal emulators. This just happened to be a simple example that a 30 second Google search revealed that nicely demonstrates the concept that there's still software at work that could be exploitable even in something as simple as displaying a file.

Theoretically, there could be other problems with modern terminal emulators (buffer overflows?) that might be exploitable.

10
  • 3
    +1 for the interesting info, however all examples in the above link make use of echo -e which OP is not using Jun 6, 2019 at 15:28
  • 6
    @CaffeineAddiction I don't know that the exploit requires -e to be used, and guess that echoing the binary contents of a file would also echo the special characters too. I'm also not familiar with all versions of echo written for every OS. The author is using the gnu echo, other versions may operate differently and allow the same escaped characters without the -e option. Jun 6, 2019 at 15:36
  • 14
    @CaffeineAddiction: echo sans -e can still echo any arbitrary bytes (except NUL) just by having those bytes passed to it on the command line — say, because those bytes were in an attacker-controlled binary file read into a variable that was then echoed.
    – jwodder
    Jun 6, 2019 at 23:15
  • 3
    @CaffeineAddiction Yes, that's because the author is trying to demonstrate the exploit using just characters he can print on a website. That means escaping the characters, and (on gnu echo) using the -e option. Jun 7, 2019 at 3:51
  • 4
    @GlennWillen Yes, I think that's a good point as well. The larger picture here is that even something innocuous as echoing a file has software behind the scene, interpreting what's going on. Theoretically, one could find a buffer overflow in a terminal program as well. Years ago, you could send people on IRC a ++ATH0 CTCP request, or a sometimes even a ping, and hangup their modem. That last one had to be fixed in the modem by requiring a pause. So there's often a lot of layers at work even in comparatively simple stuff Jun 7, 2019 at 4:12
10

If the output is going to a terminal, you have potentially lots of problems (regardless of how you print it, unless you strip special characters), as per other answers.

If the file can be gigantic, the attacker can make bash use a lot of RAM. Consider head -c 100000 instead of cat to set an upper limit of 100kB. Or head -c 10000 | cat -v (show non-printing characters as ^M or whatever; may break UTF-8 multi-byte characters).

If you want the data to potentially be giant, consider running that command directly (not inside a var=$() capture), with the output of cat connected to your stdout directly.


Since you have the data in shell variable, not being evaled inside double quotes, you're safe from some things.

e.g. command substitution won't work.

peter@volta:/tmp$ foo='$(touch bar)'
peter@volta:/tmp$ echo "${foo}"
$(touch bar)

An attacker can munge the output slightly by using the string -n, which echo will interpret as an option instead of literal data.

$ echo "-n"     # notice that this doesn't print a newline.
$ echo ""       # unlike a normal echo "" or echo with no args

$

But bash's builtin echo doesn't treat "-n foo" as an option; it's printed literally:

$ echo "-nabcd"
-nabcd

Since you expand the shell variable inside double quotes, there's no way for it to become multiple args for echo, like echo "-n" "leave the cursor at the end of this string"

Similarly -e isn't possible, and isn't a danger anyway because your file can already contain arbitrary binary data.


/bin/echo from GNU Coreutils supports a --version option, so if you're not using a shell builtin echo then an attacker could get your program to print software version info. If that output ends up in something attacker-visible, it discloses some info about the target system.


For these reasons, the recommendation for portably printing arbitrary data is:

printf "%s\n" "${ATTACKERDATA}"

Works on all POSIX shells, not subject to the system-specific vagaries of echo.

But note this does nothing about terminal vulnerabilities, it's just a safe way to write any data literally without echo munging it.

And binary data still treats \0 (a zero byte) as a terminator in most shells, because bash internally uses C strings. The OS execve interface also uses C strings, but shell builtins allow shells to bypass that for echo / printf, so it is possible for e.g. zsh to echo / printf binary data containing zero bytes.


And BTW, in bash you don't actually need cat to read a file. Command substitution with a redirect gets bash to do the reading itself.

ATTACKERDATA="$(< attackerControlledFile.txt)"

But if you want any processing, like head -c and/or cat -v, you should use a real command.

0
4

Some terminals can echo back screen content as-if typed.

Thus you can possibly force "typing" and thus command execution with the right terminal commands. I have done this on physical DEC VT62-ts. but have not tried to do it with the VT-52 mode of X-term

this exploit is well known, and is probably the reason why finger -l username strips all control characters (except newline and tab) from ~username/.plan etc

so yes it's dangerous. to make it safe pipe it through less or col etc.

2
  • Please add a PoC, regardless of the assumptions made for the system.
    – user163495
    Jun 7, 2019 at 4:54
  • I can't give you more than that annecdote, I lost my DEC "terminals and printers manual" in 2004, and my VT62-t in 1994.
    – Jasen
    Jun 7, 2019 at 10:43
2

No, echo used in the example above is fine

Echo simply prints a string to the pipe stdout (default)

per: https://superuser.com/a/699500/527937

Pipes can't overflow. A pipe is just a buffer (a certain amount of memory, most likely 64KB on a current system) between a producer and a consumer. If the producer produces faster than the consumer consumes, the producer is blocked (that means, the program will sleep) until the consumer makes room in the buffer again by reading from it.

As a side note, if you have a large ammount of data in 1x line ... cat can hang and/or consume an enormous amount of system memory.

7
  • 1
    A DoS was the most likely too. I recall that I once displayed a binary file on my terminal, and when it finally finished, I got lots of command not found errors, which left me wondering if there was a way to abuse it.
    – user163495
    Jun 6, 2019 at 14:40
  • these are most likly errors from echo and not bash, eg it encountered a backslash command that is not recognized as an option Jun 6, 2019 at 14:42
  • I can't seem to find a way to exploit this either. Too bad, that would have been cool to exploit.
    – user163495
    Jun 6, 2019 at 14:45
  • the cat portion could most likly be exploited ... eg echo '"ls' > attackerControlledFile.txt Jun 6, 2019 at 14:46
  • Just outputs "ls for me.
    – user163495
    Jun 6, 2019 at 14:49
0

The attacker could perform a content-injection attack, especially if they know what the shell prompt looks like.

By including something in the file that looks like is output from some other part of the system they might be able to decieve the user and get them to take some action.

You must log in to answer this question.