jakec / dec 2020
Today, YouTube gawd John Hammond is walking us through a guest room with more privilege escalation. This time, by exploiting a flaw in the Linux kernel itself, i.e. the core of the operating system. Discovered in 2016, the Dirty COW vulnerability (CVE-2016-5195) will let us, the ordinary, non-privileged user, take complete control of the system. At the time, this exploit was a huge deal. "Who even USES Linux?" you say. "Everyone who isn't a HUGE DWEEB uses Windows or Mac right?" Actually, you use Linux every day. The Linux kernel is part of the Android OS as well as major cloud platforms like AWS on which much of the web depends. A vulnerability in the Linux kernel has broad implications!
Think of a kernel re: an operating system like a kernel of corn. It's the center of the whole deal, interfacing between programs and the hardware of a computer. But it's not just some heartless machine, it has feelings too. Whispering sweet nothings to your computer can drastically reduce incidents of kernel panic.
Fortunately it was patched in the same year. But while I said yesterday that all the average user has to do is make sure they keep their software up to date, there are times when that's much easier said than done. You might remember the WannaCry ransomware attacks in 2017 in which major infrastructure including hospitals were catastrophically halted. These critical systems were still using old Windows installations which were vulnerable to an exploit developed by the NSA and leaked by a hacker group called the Shadow Brokers. (NB: They only leaked it after Microsoft had released a patch.) Certainly, some of those installations hadn't been updated out of laziness/lack of best practices. But in a lot of cases, particularly hospitals, those systems were so essential they had to maintain 100% uptime. There was too much risk involved with updating them and potentially breaking their life-saving functionality that they remained unpatched. So even when a vulnerability is publicised, even when a patch has been released, a critical flaw in the core of a piece of software - especially an operating system - has serious and long-lasting dangers.
Today's challenge is a little more conceptual than usual. Rather than fixing Santa's tools and helping Elf McSkidy et al. test their security, we're following the footsteps of a familiar intruder to see how this machine was hacked using Dirty COW.
An nmap scan reveals the machine is running telnet, a hoary old service used to remotely connect to computers. The machine is also running SSH, which is more secure. Telnet should've been disabled, so let's try to connect to it.
It's not really considered best practice to include login credentials on the welcome screen of a connection. Once we log in, we can run a command like
cat /etc/*release and find out that the operating system the machine is running is Ubuntu 12.04, an old version of Linux.
ls lists the files in the current folder. Let's do
cat cookies_and_milk.txt to read that text file.
It's a message from THE GRINCH! Along with a bunch of code that, if you searched the web for some of it, would prove to be part of a Dirty COW exploit. It looks like the Grinch has already hacked this machine using Dirty COW.
We can go and find a copy of the exploit code online. We can copy it from here onto the target machine by running
nano dirty.c, which will create a blank text file called "dirty.c", and then pasting the code in and saving it. The exploit code is written in the C programming language, so we need to save it as a .c file on the machine. The comments in the source code helpfully tell us how to run it.
// Compile with:
// gcc -pthread dirty.c -o dirty -lcrypt
// Then run the newly create binary by either doing:
// "./dirty" or "./dirty my-new-password"
In other words, use the local C compiler (a program called gcc) to turn our dirty.c file into an executable binary called dirty. Then we run our new program with
This creates a shiny and brand new super user account for us to use that will give us control over the whole system. The default name for this user is "firefart". Let's not ask questions we're not ready to know the answers to and just leave it that way. Once we run the program and create the new "firefart" user, we can switch to it with
Now, remember that we logged in as Santa. Even though we've changed our user to firefart, we're still inside Santa's user directory. If you type in
pwd it will print the working directory to prove this: the result will be "/home/santa". We want to change to the root folder of the machine, so we change directory with
cd ~, check what's in the folder with
ls, and then read the text file in there with
That furry green ghoul has left us one final challenge. We need to create a file called 'coal' and then produce an md5 hash of the three files in this folder.
The Linux program
touch is used for changing timestamps on a file, but if the file doesn't exist, it will create a totally blank file with that name. So by typing in
touch coal we can create our blank 'coal' file.
Now we need to hash it. A hash is a fixed-length string converted from arbitrary length data. That's a fancy way of saying "No matter how many Things I put in (e.g. words, pieces of data, etc) the Thing that comes out will always be the same length." A hash function takes some input, applies an algorithm to it (in other words, a mathematical process; in this case, one called MD5), and the result is something completely (in theory) unique. This makes hashing a great way at authenticating data. Let's dive into why.
I send you a message that says, "I love you, Henry." Some time later, I get a reply from you. "Then consider this the end of our friendship. Goodbye forever." I'm confused. Why? What happened? The truth: my message was intercepted and someone changed it to say, "I hate you, Henry." My true meaning - and feelings - have been perverted. Hashing can solve this problem.
I send you a message that says, "I love you, Henry." But I also convert the message to an MD5 hash. The hash of the message is "06c9af95e33f0430786aa9b022b8cf1f". I post this hash on my blog. When you get my message, you can use the same algorithm to produce an MD5 hash of the message you received. You hash the altered message, "I hate you, Henry." It produces the hash "c4d1c34a7e3151432886ebe75cd23ead". That's NOT the hash I provided on my blog. Which means the message MUST have been tampered with.
And then, hope against hope, romance overwhelming your composure, you change the message yourself to what you thought it might've been. It's silly. Foolish, really. There's no way. You plug the message you suspect I sent you into an MD5 hash function. And there it is. "06c9af95e33f0430786aa9b022b8cf1f". The words "I love you, Henry" flooding your neurons with-
Anyway. The way hashing algorithms work is that any change in data fundamentally changes the output. Even changing one word in a sentence produces a completely different hash. So would changing even one letter. This isn't perfect -- you've probably already realised one flaw, that a malicious actor could also just alter the hash I posted to my blog, although that would take quite a lot of effort. For a lot of uses, though, it's a great and easy way to mathematically verify that we're looking at what we're meant to.
Tomorrow: enough with kernel exploits and algorithms. Let's see how much we can find out about someone using nothing but social media.