:(){ :|:& };: # <--- DANGER DANGER DANGER
The code above will waste your CPU almost immediately, running it up to 100% while crashing your system out due to repeatedly spawning processes in seconds. There is absolutely no way you can protect yourself if you are unfortunate enough to run it. The coolest thing about this is, if you break it down it makes total sense from a scripting perspective. But at a quick glance, it almost looks like some sort of weird REGEX pattern. You could drop this on a targe to run at boot via ~/.profile or ~/.bashrc (CPU killing on boot), or drop it in as a cron job at random times throughout the day/week as an annoyance attack. I mean, you could do some really nasty shit with this one if you sat and put some thought into it. But I’m gonna cover some of the topics that it builds on before getting into the meat and bones so, if thats boring to you - skip towards the end.
THE BIG BAD TERMINAL EMULATOR IS BACK
I get it though, honestly. As a young kid, I was fascinated by the things that could be done in the terminal. Hell, I even thought it was ‘cool’ - almost like speaking another language just, with the ability to do things where graphical counterparts - while pretty - just seemed so.. slow. And clunky. And resource intensive.
My experience is not one that parallels many others. I’ve written on the topic numerous times at this point - but there seems to be a great divide when considering those who use computers and actively learn how to command the terminal, and those who don’t. The split is simple enough - most every power user will have some kind of knowledge of even fundamental scripting and CLI shell use. The general user is typically turned off by the idea - dare I say even frightened of it.
You’ve maybe heard some horror stories. With great power comes great responsibility. You can cook your files in one single line, even irrepritably damage hardware. Now it’s rare this sort of thing happens, but it’s absolutely plausible. I should know. *In a rush, I started dd image write to the wrong partition, one of my Encrypted LVM partitions and absolutely wrecked my system to the the point it was too much hassle to try and recover. Probably wasn’t even possible given the circumstances. And by the way - this isn’t just limited to linux systems. This can be achieved on Windows as well. In fact, the only systems you’d probably have to actively try to totally corrupt would be Apple (iOS/MacOS). These systems are sandboxed and, you don’t really have much more privilige than destroying your own files. It’s that way by design - totally noob proofed.
SCRIPTING
One of the beautiful outcomes of working with the CLI is of course the ability to script - this could be in bash, powershell, python, etc. Think of a script as a set of commands running and collected as one file. When someone works through the terminal, they’re basically scripting in an interactive way - on the fly as needed. When a bunch of instructions are collected into a file and run for automation, this is considered a script. It differs from a ‘program’, in that typically when we think of applications/programs/software, we are talking about one or more pieces of linked and compiled coded. The compiler interprets the instructions and links it all together to create your application. Scripting doesn’t deal with the compiling aspect. The shell interprets the commands and no compilation is necessary.
USE CASES
I’m not writing to go on about scripting however I think for many people who might read this, who aren’t familiar with this sort of thing, they may be scratching their heads wondering what’s the point of learning this if they don’t even know command line in general. Well there is reason! Mac users are probably familiar with this method of installation via copying a script displayed on a website. The image below gives you a quick reminder:
Here, you click the button, it copies it to your clipboard and you copy it into your terminal. These often contain one liners which download a script they’ve written and pipe it as a stream into the command interpreter without the need to download the script first, set it as an executable file, run the script, remove the script, etc.
I’m gonna go ahead and caution you from doing this sort of thing. That’s the point of this article. Especially if you are using administrative/root privaliges while installing some software or running a script - you best be reviewing that script and seeing what it’s doing in behind
The site shown above was subject to an attack last year which a clone site and a very similar URL was able to trick google into getting a promoted top level ad when people searched for brew. So say you want to download it, you google search ‘brew linux’, first link that pops up has the correct address so you click it. Well somehow, these guys were able to use the ‘advertisement’ chain to reroute said user to thier cloned site. Their cloned site contained malicious malware in the command you copy to install brew. There is an in depth article I’ll have to dig up on it, but it’s a classic example of really thinking twice about running anything you don’t fully trust. It’s just the nature of the game I suppose.
OBFUSCATION
So, you find yourself in a position you want to stir some trouble but you know your target is going to read anything that might present itself and easily discern malicious code from non malicious code. What do you do? Obfuscation! Now in my experience, obfuscation is typically a red flag in and of itself - especially with respect to payloads, but it certainly can offer some sort of disquise from what is being done. But what’s coola bout this is it’s obfuscation without actually obfuscating anything - it’ll make more sense in a sec.
Let’s break the command down. Oh yeah, this is bash shell script by the way:
:(){ :|:& };: # <- This is a function declaration
Symbol |
What (Is It) |
Description |
: |
Function Name (before Parentheses) |
In bash, you define functions as: fooBar(){ … }. There is nothing that states a function name can’t be a single colon. But do note, there are characters that are off limits, ‘:’ isn’t one of them. |
() |
Parenthesis |
In bash, signifies a function definition. In other programming languages you might define expected input types for said function, in bash these are never filled with anything. If you see a () in bash, you are likely looking at a function definition. There are advanced use cases such as running subshells where parentheses are used, but this is not common. Running the function, you omit the () |
{} |
Braces |
Following the parenthesis, braces define the body of the function. Everything inside the ‘{‘ and ‘}’ is considered the function code, and will run top to bottom when the function is called (below its definition in the script) |
| |
Pipe |
Pipes are an intermediate topic with respect to shell scripting. You can think of it like this. [COMMAND_1] | [COMMAND_2] . |
& |
Single Ampersand |
A single ampersand following command(s) in bash pushes the process to the ‘background’. It removes it from the screen and lets it run without any data displaying on the screen. At this point you need to use special commands like ‘fg’ or ‘bg’ or reptyr with the process id (PID) to bring it back in focus. This is handy if you want to run a process in paralell with another - instead of waiting for it to finish before starting the next chain in the program. |
; |
Semicolon |
Semicolons represent an ‘end of line’. You can write all your bash code on one line if you feel inclined by substituting a semicolon for every time you’d normall drop to the next line. eg. if [ $x -lt 10 ]; then ((x++)); echo “x is $x”; else echo “x is larger than or equal to ten”; fi; |
SO WHAT HAPPENS IF YOU RUN IT?
# Function: :()
:() {
# This is the code that will be executed when ':' is run
# Remember, the '()' is only needed to define it. Now by
# running ':', the function will run.
# Step 2 <- Not a mistake
# The line below says 'Pipe function :() output into function :()'
#
# Step 3
# Drop to background with function :() #
:|:&
};:
The ending, in order to keep the code on the same line a semicolon is used after the closing brase. This acts as a new line, and directly after that a semicolon is placed. Note - This is actually Step 1. In bash, you have to define your functions before you run them, so the last semicolon is the trigger.
When ‘:’ is run, the function will pipe (effectively nothing) into itself, and spawn a new PID. Everytime the ‘:’ function is run, it runs itself twice. So it will never effectively stop.. Over and over and over again, it’ll spawn processes and clog your ram/slaw your CPU. Because there is little to actually process, it’ll burn your resources up insanely fast. Just think about how many processes modern computers could open in a second haha.
Yeah, this one is fun. Cause like I said - it looks like a regex pattern.
Anyway, I thought that one was a bit more fun to discuss than you’re typical ‘sudo rm -rf /‘ style dangerous commands.