# Can “cat-ing” a file be a potential security risk?

I often use cat on the console to view the contents of files, and every now and then I accidentally cat a binary file which basically produces gibberish and system beeps. However today I've encountered a situation where the output from the cat utility got redirected to the console input so I got stuff like this:

-bash: 2c: command not found


...
...

This made me thinking that a specifically crafted binary file could in such a way create quite a mess on the system?!... Now I do realize using cat recklessly like this is not particularly smart, but I would actually like to know what is going on here. What characters did produce the effect of suddenly dumping the content on standard input...

Note: I was in Mac OS X terminal while doing this, I've actually called diff -a to compare two firmware rom images and print the differences out(I thought there would be just few bytes of differences but there where almost 8 MB od differences printed to the screen) Later I tried on purpose with the cat on one of the files and got the same effect like I've pasted here.

- UPDATE - - UPDATE - - UPDATE -

I've posted this here late at night yesterday and this morning I tried to replicate the behaviour and I can not. Unfortunately I can not be sure if some escape characters caused the gibberish from the binary to be executed on the console automatically or if at the end of the cat I just got a bunch of characters left(as If I've pasted them) on the command line and I've probably pressed enter accidentally to get a clear line...

When I try to cat the file in question now I get this when it completes(scroll right to see):

D?k(Fli9p?s?HT?78=!g??Ès3?&é??  =??7??K?̓Kü<ö????z(;???????j??>??ö?Ivans-MacBook-Pro:FI9826W-2.11.1.5-20140121 NA ivankovacevic$1;2c1;2c1;2;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c;1;1;112;112;1;0x1;2c1;2c;1;1;112;112;1;0x1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c  My actual prompt is: Ivans-MacBook-Pro:FI9826W-2.11.1.5-20140121 NA ivankovacevic$


Where:

FI9826W-2.11.1.5-20140121 NA


is the current working dir. As you see it was camouflaged in the binary gibberish and I might have pressed enter reflexively or something. This in it self is a bit wrong behaviour of cat because obviously my prompt might have been even better "camouflaged". But it is less serious then I initially thought. Although I'm still not 100% sure that it did not execute automatically last night when I tried, because there was also another peculiar thing that happened last night, before this. I've called cat on another very similar file that caused Terminal app to quit with:

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)


Now I'm thinking that maybe a combination of these two events have caused the auto execution of gibberish on the console. But I can not replicate that behaviour now again.

The files in question are firmwares for a Foscam IP camera, here are the links:

International site: http://foscam.com/Private/ProductFiles/FI9826W-2.11.1.5-20140120.zip
And then the file inside: FI9826W_app_ver1.11.0.40_OneToAll.bin

calling cat on that one will cause Terminal to quit.

and then the file: FI9826W_app_ver1.11.0.40_OneToAll_A.bin

cat-ing that one will cause that paste of 1;2c1;2c1;2;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c.... characters on the command line

• Ah, those comforting memories from a time where ANSI bombs where around and widely known... – PlasmaHH Apr 24 '14 at 8:32

Yes, it's a potential risk, see CVE-2003-0063, or CVE-2008-2383 or CVE-2010-2713, or CVE-2012-3515 or OSVDB 3881, or CVE-2003-0020 or any of the similar ones listed here... Some more in comments below also.

Update it's not just a potential risk, it's a real risk. rxvt-unicode (versions 2.7—9.19, patched in 9.20) allows read/write access to X window properties, this can enable user-assisted execution of arbitrary commands, this issue has been assigned CVE-2014-3121, more details here https://bugzilla.redhat.com/show_bug.cgi?id=1093287 .

More recently (October 2019) iTerm2 versions up to v3.3.5 were found to have the same class of problem: display of malicious content can enable the integrated tmux and permit command execution, see CVE-2019-9535.

This topic also has good coverage here: https://unix.stackexchange.com/questions/73713/how-safe-is-it-to-cat-an-arbitrary-file and a thorough analysis of the underlying problem from Gilles here: https://unix.stackexchange.com/questions/15101/how-to-avoid-escape-sequence-attacks-in-terminals .

## Explanation

What you are observing is a side-effect of how certain escape sequences behave: some of them stuff characters (usually also containing escape sequences) directly into the terminal input buffer. All in the name of backward compatibility, of course. The standard xterm escapes which are described using the term "Report <something>" do this. This behaviour permits programs to query/set terminal (or other) properties "in band" rather than via ioctls or some other API.

As if that wasn't bad enough, some such sequences can contain a newline, which means that whatever is reading from the terminal (your shell) will see what appears to be a complete user command.

These sequences can vary by terminal, but for rxvt and derived, the graphics query escape includes a newline (example using bash and $'' strings, see doc/rxvtRef.txt in the source) : $ echo $'\eGQ'$ 0


This escape sends \033G0\n into the terminal input buffer (or digit 1 instead of 0 if you have a graphics-capable rxvt).

So, combine this escape with other sequences which behave similarly:

$3;uptime;date +%s;0 bash: 3: command not found 17:23:56 up 1474 days, 6:47, 14 users, load average: 1.02, 1.20, 1.17 1400603036 bash: 0: command not found  Multiple commands, preserving whitespace and shell metacharacters. This can be exploited in a variety of ways, starting with cat-ing an untrusted binary of course, further ideas in H.D. Moore's short paper (2003). ## Followup For the escape sequence you ask about: 1;112;112;1;0x1;2 This is: Request Terminal Parameters (DECREQTPARM) and Send Device Attributes : $ echo $'\e[x'$'\e[0c'
;1;1;112;112;1;0x1;2c


The second one (\e[0c) is the same as ^E (using rxvt). There are some escape sequences in there too. the full sequence written for each is, respectively:

\e[1;1;1;112;112;1;0x
\e[?1;2c

• Good links! Here are some specific Apple ones cvedetails.com/cve/CVE-2005-1341 or cvedetails.com/cve/CVE-2009-1717 and probably there are more... – Ivan Kovacevic Apr 22 '14 at 22:45
• I found the issue today (while searching for interesting format strings), no names or details until it's coordinated with the authors. – mr.spuratic Apr 24 '14 at 18:06
• Will do. My speculative answer (no OS X machine to hand) on the segfault is withheld for the same reason. – mr.spuratic Apr 24 '14 at 18:13
• Damn, I'm dying of curiosity now for both things. Would a i.imgur.com/eNoBclw.jpg do? :) – Ivan Kovacevic Apr 24 '14 at 18:24
• I am in contact with authors, I will update answer with promised details soon. – mr.spuratic Apr 30 '14 at 0:15

Yes.

As you seem to be using a modern terminal emulator, some escape sequences could be used to modify Keyboard buffer.

There could be proper shell commands injected.

You could use argument -e of cat for safe operation, see man cat.

  -e     equivalent to -vE

-E, --show-ends
display $at end of each line -v, --show-nonprinting use ^ and M- notation, except for LFD and TAB  ### Addendum In fact, it was possible, but in a very old past... As this became an issue, these kinds of features was quickly removed, but... When you read command not found, this implies that something was effectively injected. The main injection feature that was not removed is the sequence indentify yourself, used in many VT-100 encapsulation. This sequence is Escape Z which will inject the string 1;2c into your keyboard buffer, which means VT-100 (in AVO convention). Speaking about cat, you could try: cat <<<$'\033Z'


and on next line prompted, you will see 1;2c (or maybe with another numbers, depending on terminal used) as if you hitted them.

... and

cat -e <<< $'\033Z' ^[Z$


Where -e => -vE, -v transform \033 into ^[ and -E put a $ sign at end of line (and nothing will be put on next line, you keyboard buffer is not affected). You may find lot of funny things at VT100 User Guide (like: cat <<<$'\033#8' ;)

(They was modern terminal! In some past... )

### Trying using bash

There is a little bash command for flushing keyboard buffer and get his content:

cat <<<$'\033Z';buf='';while read -t .1 -n 1 chr;do buf+="$chr";done;printf "\n>|%q|<\n" $buf ^[[?1;2c >|$'\E[?1;2c'|<


And a little function to test any chain:

trySeq() {
printf -v out "$1" echo -n "$out"
buf=""
do buf+="$char" done [ "$buf" ] && printf "\r|%q|->|%q|<\e[K\n" "$out" "$buf"
}


So I could try:

for i in {0..255};do trySeq "\e[${i}n";done |$'\E[5n'|->|$'\E[0n'|< |$'\E[6n'|->|$'\E[21;1R'|<  ### And now? From there, unfortunately, there is no standard. Every virtual terminal implementation could support full ANSI and/or full DEC standard... But as there are some security issues, many don't... You could observe some behaviour using one terminal that you wouldn't observe using another... xterm, linux console, gnome-terminal, konsole, fbterm, Terminal (Mac OS)... the list of terminal emulators is not so short! And each of them has its own bugs and limitations compared to DEC and ANSI standards. In pactice, you may find some virtual console that could be more featured than other and where keyboard injection could break your security. It's one of the reasons because I prefer to use alway same (old) xterm rather than other more featured tools. • Oh? Care to share details? To the extent that it's true, this is a critical security vulnerability in the terminal emulator. – tylerl Apr 22 '14 at 5:49 • This is why some of the ANSI escape sequences are generally disabled in modern terminals/emulators. – keshlam Apr 22 '14 at 7:38 • cat -e, good advice! I'm still interested if you could maybe expand your answer with an example of those escape sequences to modify the keyboard buffer which could possibly explain this. – Ivan Kovacevic Apr 22 '14 at 12:39 • When I type man cat all I see is that -e is "equivalent to -vE", but no info is given on -vE... – apnorton Apr 22 '14 at 18:35 • The convention is that single character flags can be grouped together, so -vE is the same as -v -E. i.e., the man page is telling you to look at the documentation for the -v and -E flags which mean "show non-printing characters using ^ and M- notation" and "Show line endings as a $ character", respectively. – Cookyt Apr 22 '14 at 18:42

"Real" glass terminals had an escape sequence to print the screen to a printer. They did this by running a command and pipeing the current screen contents to the stdin of the print command.

The command could be configured by another escape sequence.

The classic way of exploiting this was to create files with names that embedded the escape sequence to set the printer command and change it to some script of your choice and then have a 2nd file with the print escape sequence in it.

When someone then ran ls in that directory they would end up running your code. Which was nice if they were the root user!

In theory modern terminal emulators shouldn't do that kind of thing any more.

Terminal.app appears to be based on the NextStep nsterm, so it may have all kinds of weirdness in it.

Maybe try narrowing down which exact bytes are producing the command not found messages?

Looks like there are escape sequences to raise and lower the terminal:

http://the.taoofmac.com/space/apps/Terminal

http://invisible-island.net/ncurses/terminfo.src.html#toc-_Apple__Terminal_app

If you want to send content to a program's stdin,

program -para meters < /path/file.ext

• "current screen contents to it's stdin" — screen contents isn't stdin. – Ruslan Apr 22 '14 at 11:35
• @Ruslan: He means the stdin of the command to which the screen contents are being piped. – jwodder Apr 22 '14 at 16:40
• Then it should be its not it's – Ruslan Apr 22 '14 at 17:14
• @JasperWallace: Cool info! Examples: To minimize Terminal.app: echo -e '\x1B[2t' To minimize-maximize echo -e '\x1B[2t\x1B[5t' :) – Ivan Kovacevic Apr 22 '14 at 22:23

Typically there is no vulnerability, but obviously if you use it wrong, then you could create one.

Printing the contents of a binary file produces beeps because character 7 is the old terminal command to make the machine beep, and some terminal programs still honor that command. But by design, there's nothing there that can hurt you. In the worst case, simply open up a new terminal window to undo any mess that might have been created.

Now, if you somehow redirected the contents of a file to a command shell, that's another matter. You could do this by piping the output of something to /bin/bash (typically frowned upon from a security perspective) or you could have perhaps inadvertently copied and pasted it into your terminal. Also typically ill-advised.

But as long as you don't run the thing, you're fine.

• In this case I've just typed: cat <file_name>. So I did not paste some bogus command in the console, but check my update to the question that I've just wrote. – Ivan Kovacevic Apr 22 '14 at 14:38

What you are seeing is xterm control sequences.

Control sequences are activated when they are seen in output in the terminal; e.g., when you cat a file with bytes that are non-printable ASCII.

In your example, the control sequence is ESC Z (bytes 1B 5A) which returns the terminal ID -- as a command in the terminal.

You can try it yourself:

echo -e '\x1BZ'


(Alternatively you can write ESC as \e or Z as \x5A).

There are some other fun ones too:

echo -e '\eF' # move the prompt to the bottom of the terminal.
echo -e '\ec' # Reset the terminal

• Actually echo -e '\x1BZ' in my case just prints out an empty line. However echo -e '\x1B[\x1BZ' prints that "1;2c" on the command line which I was getting repeatedly after cat-ing that firmware binary file. That is <ESC> and [ which is known as <CSI> escape sequence, followed by <ESC> Z. However I have no idea what that 1;2c means. Is that the terminal ID?! – Ivan Kovacevic Apr 22 '14 at 22:18
• @IvanKovacevic Yes, see my addendum. ( My first answer was too quick. sorry ;) – F. Hauri Apr 22 '14 at 23:34
• @dr jimbob: I was not right, echo -e '\x1BZ' does work, but it has some strange behaviour on Mac OS X. If I issue it for the first time and delete the outputted characters, then press enter to get a clear new prompt(Because echoing that leaves some gibberish in-front of the prompt line also, or on the back, depends how you look at it). Then if I try to recall the last command with the up key, and call it again, it does not work anymore... Just a new-line gets printed. That is why I initially though it was not working, because I've called it already... On Linux it works regardlessly every time. – Ivan Kovacevic Apr 23 '14 at 2:58
• And echo -e '\x1B[\x1BZ' also works every time. I suppose the CSI sequence resets it. – Ivan Kovacevic Apr 23 '14 at 3:02
• alias clear="echo -e '\ec'" Finally, a clear in cygwin <3 – Qix Apr 24 '14 at 0:45

I'm gonna add this info here without actual intention to answer my own question. The characters that can get injected on the command line while printing some other characters, better know as escape sequences, are defined really good on this site(Thanks F. Hauri, for mentioning it):
http://vt100.net/docs/vt100-ug/chapter3.html

Under chapter: Reports

Cursor Position Report

Invoked by ESC [ 6 n
Response is ESC [ Pl ; Pc R
Pl = line number; Pc = column number

Status Report

Invoked by ESC [ 5 n
Response is ESC [ 0 n (terminal ok)
ESC [ 3 n (terminal not ok)

What Are You

Invoked by ESC [ c or ESC [ 0 c
Response is ESC [ ? 1 ; Ps c

Ps is the "option present" parameter with the following meaning:

Ps Meaning
0 Base VT100, no options
1 Processor options (STP)
3 AVO and STP
4 Graphics processor option (GPO)
5 GPO and STP
6 GPO and AVO
7 GPO, STP, and AVO

Alternatively invoked by ESC Z (not recommended). Response is the same.

ESC is ASCII decimal 27 or octal 33 or hexadecimal 1B.

So to get for example current cursor position printed out, or better said injected into your existing command line, you would call:

echo -e '\033[6n'


and the output would be something like this:

7;1R


You can move the cursor position with the following escape sequence

echo -e '\033[10;20H'


10 - row 10
20 - column 20

However it's not moving the column position(it does move through rows) because the terminal probably resets it to the beginning of the line. Anyhow, if you query the cursor position right after that it's going to "paste" on the console the set column position:

echo -e '\033[10;20H\033[6n'


output:

0;20R


That's how you can get different outputs injected('pasted') on the console, it is far from any real exploit since this will give only different number combinations that can be outputted, but then again maybe combined with something else. Who knows.

In my case where I've cat-ed the firmware image I got lots of: 1;2c Now I know that it is the "What Are You" report, of what my terminal is, where 2 means: Advanced video option(AVO).

All in all it's definitely better to avoid mindlessly cat-ing any file...
As already suggested(also by F. Hauri), at least use cat -e

There are obvious risks in piping a random file to an interpreter of any kind, but unix isn't set up to protect users from their own stupidity. Simply using cat filename may mess up your display but it shouldn't damage anything.

If you are using cat to view files and identify their type I would suggest that you learn about file ( tells you what the file is ) and less which will warn you if you are looking at binary data, and won't dump a 100Mb installer archive to your console. zless` will transparently open gzip files.

• Piping a random file to an interpreter(i.e. bash) is, of course, hugely dangerous. But it is not what we are discussing here. Only displaying content, with cat, which as history has shown CAN produce damages. Check the answer from mr.spuratic. – Ivan Kovacevic Apr 23 '14 at 14:08
• To add to paul's answer, it has been said lots of times, yet old habits die hard : don't use cat for this, use less or a text editor. – schaiba Apr 23 '14 at 16:58