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
-bash: 1: command not found
-bash: 1: command not found
-bash: 112: command not found
-bash: 112: command not found
-bash: 1: command not found
-bash: 0x1: command not found
-bash: 2c1: command not found
-bash: 2c: command not found
-bash: 1: command not found
-bash: 1: command not found
-bash: 112: command not found
-bash: 112: command not found
-bash: 1: command not found
-bash: 0x1: command not found
-bash: 2c1: command not found
-bash: 2c1: command not found
-bash: 2c1: command not found
-bash: 2c1: command not found


This got me thinking that a specifically crafted binary file could 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 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 a few bytes of differences but there where almost 8 MB of differences printed to the screen) Later I tried, on purpose, to cat one of the files and got the same effect like I've pasted here.


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- 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- NA ivankovacevic$


FI9826W- 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 itself is a bit wrong of cat because obviously my prompt might have been even better "camouflaged." But it is less serious than 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 Codes: KERN_INVALID_ADDRESS at 0x00007fcb9a3ffffa

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 again.

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

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

calling cat on that one will cause Terminal to quit.

US site: http://foscam.us/downloads/FI9826W-
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

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

7 Answers 7


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 .


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.

Here's a neat way to use this, with bash's read to print an escape (as a prompt) then immediately read and split the reply into variables:

IFS=';' read -sdt -p $'\e[18t' csi8 rows cols
echo rows=$rows cols=$cols

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
bash: 0: command not found

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:

echo $'\x05' $'\e[>c' $'\e[6n' $'\e[x' $'\eGQ'

for me this causes 11 attempts to run various commands: 1, 2c82, 20710 (my rxvt version string), 0c5, 3R (5 and 3 were the cursor coords), 112 and 0x0.


With rxvt and most recent terminal emulators you should "only" be able to create a limited set of mostly numeric sequences. In old terminal emulators it was possible (some CVEs listed above) to access the clipboard, the window icon and titlebar text to construct more malicious strings for invocation (one current slight exception is if you set the answerbackString X resource string, but that cannot be directly set using this method). The flaw then is allowing arbitrary read and write access to something that passes for state or storage within escape sequences that stuff data into the input buffer.

rxvt requires compile time changes to activate, but urxvt helpfully has an -insecure command line option that enables some of the more exciting features:

$ echo $'\e]2;;uptime;\x07' $'\e[21;;t' $'\eGQ' 
bash: l: command not found
17:59:41 up 1448 days,  4:13, 16 users,  load average: 0.49, 0.52, 0.48
bash: 0: command not found

The three sequences are:

  1. \e]2;...\x07 set window title;
  2. \e[21;;t query window title, place in input buffer;
  3. \eGQ query graphics capability, which adds \n to input buffer.

Again, depending on terminal, other features such as font size, colors, terminal size, character set, alternate screen buffers and more may be accessible though escapes. Unintended modification of those is at least an inconvenience, if not an outright security problem. Current versions of xterm restrict potentially problematic features via "Allow*" resources.


Prior to v9.20, urxvt did not also guard read and write access to X properties (mostly used by window managers). Write read access (or more precisely, access to sequences which echo potentially arbitrary strings) now requires the -insecure option.

$ echo $'\e]3;xyzzy=uptime;date +%s;\x07'
$ xprop -id $WINDOWID xyzzy
xyzzy(UTF8_STRING) = 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x3b, 0x64, 0x61, 0x74, \
0x65, 0x20, 0x2b, 0x25, 0x73, 0x3b

This can be trivially used to stuff arbitrary strings into the terminal input buffer. When the escape sequence to query a property is invoked (along with helpful \eGQ which adds a newline):

 $ echo $'\e]3;?xyzzy\x07' $'\eGQ'
 $ 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
 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).


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'

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:

  • 2
    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... Commented Apr 22, 2014 at 22:45
  • 3
    I found the issue today (while searching for interesting format strings), no names or details until it's coordinated with the authors. Commented Apr 24, 2014 at 18:06
  • 2
    Will do. My speculative answer (no OS X machine to hand) on the segfault is withheld for the same reason. Commented Apr 24, 2014 at 18:13
  • 1
    Damn, I'm dying of curiosity now for both things. Would a i.imgur.com/eNoBclw.jpg do? :) Commented Apr 24, 2014 at 18:24
  • 2
    I am in contact with authors, I will update answer with promised details soon. Commented Apr 30, 2014 at 0:15

Definitively yes.

New add 2020-01-25:

From time I've switched from LATIN-1 encoding to UTF-8 as default encoding in most of my systems, I've found some interresting features around this (there are now two lenght for one string)...

For sample, as I like to play with , I've asked why bash localization won't work with multilines strings. This bash feature present a bug, where workaround consist of using eval. If this is not a security flaw, this could become or produce one...

In every evolutions of almost anything (languages, libraries, tools, protocols, applications, hardware, installers, consoles, etc...) comme new features, with potentially new bugs...

Fortunately, they are as few as they are quickly corrected (near one-day from reveal), but they are!

So definitively yes, stay care!

Correct use of cat command.

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


$ cat -e suspectfile.raw
$ cat -e suspectfile.raw | less

or under :

$ less < <(cat -e suspectfile.raw)

or even

$ which less cat
$ rawless() { /usr/bin/less < <(/bin/cat -e "$@");}

or in one line

$ . <(printf 'rawless() { %s < <(%s -e "$@");}\n' $(which less cat))


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'

Or another ANSI sequence: CSI c (Device Attributes):

$ cat <<< $'\033[c'

will print an empty line, but on next line prompted, you will see 1;2c (or maybe with another numbers, depending on terminal used) as if you hitted them:

$ 65;1;9c█

... but with -e switch:

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

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

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

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


And a little function to test any chain:

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

So I could try:

$ for seq in $'\e['{c,{1..26}{n,t,x}};do
      trySeq "$seq";done

( Maybe with some harmless effects on your console ;)

Small practical sample

Imagine, some could put something like this in your environment:

$ source <(cat <(printf '%dc() {
 printf "You\\047ve been hitted: your passwd file hold %%d lines\\041\\n" \
      $(wc -l </etc/passwd)
 };\n' {0..100};printf 'alias %s=1c\n' {0..100};))

Then, if you

$ cat <<<$'\e[c'

$ 65;1;9c█

Cursor will stay at end of command prompt line.

From there, if you machinally hit Return instead of Ctrl+c, you will read something like:

$ 65;1;9c
You've been hitted: your passwd file hold 74 lines!
You've been hitted: your passwd file hold 74 lines!
You've been hitted: your passwd file hold 74 lines!
$ █

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.

  • 11
    Oh? Care to share details? To the extent that it's true, this is a critical security vulnerability in the terminal emulator.
    – tylerl
    Commented Apr 22, 2014 at 5:49
  • 1
    This is why some of the ANSI escape sequences are generally disabled in modern terminals/emulators.
    – keshlam
    Commented Apr 22, 2014 at 7:38
  • 6
    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. Commented Apr 22, 2014 at 12:39
  • 1
    When I type man cat all I see is that -e is "equivalent to -vE", but no info is given on -vE...
    – apnorton
    Commented Apr 22, 2014 at 18:35
  • 2
    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
    Commented Apr 22, 2014 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:


some more info here:


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

program -para meters < /path/file.ext
  • @Ruslan: He means the stdin of the command to which the screen contents are being piped.
    – jwodder
    Commented Apr 22, 2014 at 16:40
  • 1
    @JasperWallace: Cool info! Examples: To minimize Terminal.app: echo -e '\x1B[2t' To minimize-maximize echo -e '\x1B[2t\x1B[5t' :) Commented Apr 22, 2014 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.

  • 2
    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. Commented Apr 22, 2014 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?! Commented Apr 22, 2014 at 22:18
  • @IvanKovacevic Yes, see my addendum. ( My first answer was too quick. sorry ;) Commented Apr 22, 2014 at 23:34
  • 1
    @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. Commented Apr 23, 2014 at 2:58
  • And echo -e '\x1B[\x1BZ' also works every time. I suppose the CSI sequence resets it. Commented Apr 23, 2014 at 3:02
  • 1
    alias clear="echo -e '\ec'" Finally, a clear in cygwin <3 Commented Apr 24, 2014 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):

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)
2 Advanced video option (AVO)
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:


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'



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.

  • 1
    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. Commented Apr 23, 2014 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
    Commented Apr 23, 2014 at 16:58

You must log in to answer this question.

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