The name of cat utility is derived from its function to concatenate files, so nothing about kittens, i'm sorry!

Cover image courtesy of Ivo The Cat



cat is a tool which reads data from one locations and writes it to another.
Usually it is used to read text from a file and write it to STDOUT, and it also supports some control characters, such as line-feeds \f, newlines \n and carriage returns \r.

Let's try to focus on of rendering carriage return \r characters: \r will move the cursor back to the beginning of the line, and characters printed thereafter will be written over anything that was printed previously.

So, if we create a textfile containing a string, plus a \r character and another string, a cat of this file will display only the second string, because the first will be overwritten.

For example, with this simple python script:

#!/usr/bin/env python
hidden_string = "echo 'This is an hidden string!'"
visible_string = "echo 'This is a visible string!'"
with open("joke.sh", "w") as f:
    output = "#!/bin/sh\n"
    output += hidden_string + ";" + visible_string + " #\r" + visible_string + " " * (len(hidden_string) + 3) + "\n" #add spaces in order to overwrite the entire hidden string
    f.write(output)
print ("Done!")

We are able to write a bash script that displays a result if processed with cat but performs more operations if executed:

andrea@Lucille:~/Projects/CatJoke$ ./catjoke.py
Done!
andrea@Lucille:~/Projects/CatJoke$ ls
catjoke.py  joke.sh
andrea@Lucille:~/Projects/CatJoke$ cat joke.sh
#!/bin/sh
echo 'This is a visible string!'
andrea@Lucille:~/Projects/CatJoke$ bash joke.sh
This is an hidden string!
This is a visible string!

This is a simple joke, however it may also have some security impacts: when downloading a script from the Internet, most users checks the content of the script using the cat command.
So, a bad actor can use this trick to embed malicious code into a script seemingly safe.

Luckily, the same file opened with an editor reveals the real content, and also cat is able (-A) to display file content ignoring the control characters:

andrea@Lucille:~/Projects/CatJoke$ cat -A joke.sh
#!/bin/sh
echo 'This is an hidden string!';echo 'This is a visible string!' #^Mecho 'This is a visible string!'


References