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.

  • 9
    what if it's a million bells? while not dangerous, it's certainly annoying... – dandavis Jun 06 '19 at 20:12
  • 2
    plays simultanously, so not that annoying – Jasen Jun 07 '19 at 03:37
  • 2
    @dandavis You are free to assume an infinitely patient user as well ;) –  Jun 07 '19 at 04: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 07 '19 at 08:47
  • 2
    @ymbirtt It will always be a regular file. The attacker can control the contents of the file, not what the file points to. –  Jun 07 '19 at 12:27
  • Any printing of untrusted data (not only by echo) is a risk as not all terminal (emulators) are Safe against Key redefinition or Screen read out. It helps to filter out control characters (which also helps against beeps and corruption). – eckes Jun 07 '19 at 15:25
  • 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 07 '19 at 20:44
  • 2
    Possible duplicate of [Can "cat-ing" a file be a potential security risk?](https://security.stackexchange.com/questions/56307/can-cat-ing-a-file-be-a-potential-security-risk) – Sergiy Kolodyazhnyy Jun 08 '19 at 01:19
  • 1
    @ymbirtt In that case, the `cat` command and subprocess would terminate because the shell's buffer would fill up very quickly. The subsequent `echo` would do nothing because it would be operating on an empty string, not a string with an infinite (or even non-zero) size. – forest Jun 08 '19 at 03:10
  • Are we excluding social engineering attacks? ie: maybe `attackerControlledFile.txt` is a plain text document that describes (alleged) evidence that someone high up in the company is diddling IT Guy's wife, with the intent of creating strife that will lead to IT Guy quitting and opening a job position that Attacker can then apply for? (You did say something about "regardless of how unlikely it would be" =P) – Steve-O Jun 09 '19 at 14:30
  • @Steve-O Yes, you can exclude social engineering attacks. That wasn't the scope of my question. –  Jun 11 '19 at 08:10
  • Exploits of user controlled b8nary data on terminal emulators are listed here https://security.stackexchange.com/a/56391/16279 – eckes Jun 26 '19 at 16:59

5 Answers5

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.

Steve Sether
  • 21,480
  • 8
  • 50
  • 76
  • 3
    +1 for the interesting info, however all examples in the above link make use of `echo -e` which OP is not using – CaffeineAddiction Jun 06 '19 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. – Steve Sether Jun 06 '19 at 15:36
  • 1
    if you re-read the article, every example the author uses makes use of `echo -e` or `printf` ... the exploit simply will not work with out it ... `echo -e` states the following in its man pages `enable interpretation of backslash escapes` ... so pretty much the whole point of the article – CaffeineAddiction Jun 06 '19 at 22:16
  • 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 `echo`ed. – jwodder Jun 06 '19 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. – Steve Sether Jun 07 '19 at 03:51
  • It's worth clearly noting -- every modern system I've ever heard of has disabled all the dangerous escapes like this. You really have to reach way back to find an exploitable one. – Glenn Willen Jun 07 '19 at 03:58
  • 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 – Steve Sether Jun 07 '19 at 04:12
  • 1
    @SteveSether Funny story -- at least for a long time, the pause was patented by Hayes. So you could still nail people with off-brand modems. I got a friend of mine once as late as the 2000's this way, when he was visiting his family out in the middle of nowhere who still used dialup. Neither of us actually expected it to work. – Glenn Willen Jun 07 '19 at 04:17
  • bash test script http://codepad.org/5I0WdNDd – CaffeineAddiction Jun 07 '19 at 13:50
  • Even modern terminals, especially those based on `xterm`, can have vulnerabilities that may be exploited when printing arbitrary control codes. Although it's true that it's not nearly as common today as it was in the past, it's still something to look out for. – forest Jun 08 '19 at 03:09
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.

Peter Cordes
  • 890
  • 9
  • 12
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.

Jasen
  • 834
  • 5
  • 8
  • Please add a PoC, regardless of the assumptions made for the system. –  Jun 07 '19 at 04: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 07 '19 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.

CaffeineAddiction
  • 7,517
  • 2
  • 20
  • 40
  • 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. –  Jun 06 '19 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 – CaffeineAddiction Jun 06 '19 at 14:42
  • I can't seem to find a way to exploit this either. Too bad, that would have been cool to exploit. –  Jun 06 '19 at 14:45
  • the `cat` portion could most likly be exploited ... eg `echo '"ls' > attackerControlledFile.txt` – CaffeineAddiction Jun 06 '19 at 14:46
  • Just outputs `"ls` for me. –  Jun 06 '19 at 14:49
  • yah, not able to get it to work ... though gut feel is that is where the weakness is. Though its more likely to just truncate the data than do anything malicious because cat is still working with a pipe ... which cant be overflowed. – CaffeineAddiction Jun 06 '19 at 14:57
  • stdout is normally connected to a TTY (a terminal or pseudo-terminal). Unless you pipe the output, the only pipe is from `cat` into `bash` for `$(cat)`. (Which you can avoid with `var="$(< file.txt)"`, but no it's not dangerous, there's no shell expansion of the data that was read). Also, no, `cat` isn't by default line oriented. Or are there bad `cat` implementations that read whole lines even without `cat -n` to number output lines? – Peter Cordes Jun 07 '19 at 05:00
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.

bdsl
  • 595
  • 3
  • 7