There be trolls ahead!

With the Pentesting with Kali (PWK) course complete and Offensive Security Certified Professional (OSCP) certification successfully achieved (write-up here), I now find myself in a state of limbo, asking myself “where to from here?”. There are a number of choices I need to make, and finding an answer to my questions is going to take some careful deliberation and time commitment. So whilst I ponder the why/who/where’s, I will be expending some random keystrokes concentrating on owning vulnhub boxes, ensuring I continue to keep my offsec tools sharpened.

The first of these boxen will be Tr0ll: 1.

The description from the author, Maleus (@maleus) is as follows:

Tr0ll was inspired by the constant trolling of the machines within the OSCP labs.

The goal is simple, gain root and get Proof.txt from the /root directory.

Not for the easily frustrated! Fair warning, there be trolls ahead!

Let the troll hunting begin!

First things first; what boxes are on the network? A quick and easy tool to achieve this is an ARP scanner tool called netdiscover.

netdiscover

With our target host (172.16.66.131) found, let’s enumerate which ports are open with nmap. I like to start with a full TCP portscan…

nmap_allports

… followed by executing an NSE script category known as vuln.

nmap_vulns

FTP (21), SSH (22), HTTP (80). Let’s start by opening a browser session to the webserver:

default_www

Nice… a taunting troll straight of the bat. From the NSE vuln scripts, we can see that the http-enum.nse script has found one file (robots.txt) and a directory (/secret/) of interest. Let’s take a quick look at the robots.txt file:

Nothing overly exciting there apart from the mention of a directory called /secret, which we have already enumerated. Let’s take a look at it:

www_secret_dir

Mad? Not yet, but I get a sneaking suspicion that I will be well and truly over trolls by the end of this. While it doesn’t look like HTTP is going to give us any immediate love, I always like to enumerate files/directories as much as I can just to make sure. My brute-force tool of choice at the moment is wfuzz, although you could achieve the same, if not similar results using OWASP’s Java driven GUI tool DirBuster or a CLI tool such as dirb.

wfuzz

Nothing new there unfortunately. Let’s move on to one of the other ports we exposed during our enumeration stage, FTP. The obvious first stage is to check if anonymous FTP is enabled:

ftp_anon

Good… we have anonymous FTP access. We do a directory listing and notice a file which may be of interest, lol.pcap. Next step, download the file and open it with wireshark. Looking at the capture file, we can see that someone has previously connected to the FTP server, and downloaded a file named secret_stuff.txt. From our previous directory listing, we know that this file no longer exists, so let’s take a look at the TCP stream. Frame 40 contains our ftp-data, and looking a little deeper into the packets we see the following content:

sup3rs3cr3tdirlol_wireshark

Well, well, well, aren't you just a clever little devil, you almost found the sup3rs3cr3tdirlol :-P\n\nSucks, you were so close... gotta TRY HARDER!\n

Arghhhhh…. “Try Harder” comes back to haunt me. sup3rs3cr3tdirlol hey? Sounds like a web directory to me.. let’s take a look.

sup3rs3cr3tdirlol_www

Onwards and upwards as they say. Let’s download the roflmao binary and take a look at what hints it may hold for us. For me, whenever I want to know more about a binary, I initially use the strings tool to find any printable characters. Running a strings on our roflmao binary returns the following:

strings_binary

Nothing overly interesting here. If we execute the binary, it will return “Find address 0x0856BF to proceed” to stdout. Having checked the FTP/HTTP/SSH services, I am not aware of any direct vulnerability/exploit which can be leveraged, which leads me to believe the address of 0x0856BF could be a another ‘secret’ directory which was not exposed during my previous dictionary attack with wfuzz. Let’s browse to the address as a directory:

0x0856BF_www

Interesting. Having a look in the good_luck/ directory we find a file name which_one_lol.txt with the following content:

good_luck_which_one_lol

What about the other directory, this_folder_contains_the_password? Hmm… it contains a file named Pass.txt with contents as follows:

this_folder_pass

Usernames and password perhaps? Let’s add all of the strings from which_one_lol.txt to a file called users, and the string Good_job_:) to a file called pass. We haven’t found any cgi-bin or other HTTP authentication method, so we’ll concentrate on brute-forcing FTP and SSH with these credentials. My tool of choice for brute-forcing basic services is ncrack. You could also use tools such as hydra or medusa. First up, FTP:

ftp_brute_goodluck

No luck there. Let’s try SSH:

ssh_brute_goodjob

No luck here either. Not due to the username/password combination being incorrect, but due to some type of lock out after x amount of failed SSH attempts. What a pain in the proverbial! I reboot the vulnerable VM and attack again, with the same result, confirming ‘something’ is killing our sessions after failed attempts. I’d put money on fail2ban being the culprit, but we’ll know for sure when we get a shell on this trolling box.

So what next? As the box is called tr0ll, I’m pretty certain SSH access via the found credentials is the answer, mainly due to the fact that it’s causing so much frustration. I painstakingly ssh to the host going through each usernames manually, with a password of Good_job_:). By the time I get to the end of the usernames, and after many frustrating reboots of the VM, I have two light bulb moments! Firstly, the author of the vulnerable host, Maleus, has a website called overflowsecurity.com. One of our possible usernames, and last in the list, was 'overflow'! The second light bulb moment was around the directory name of the possible password: this_folder_contains_the_password. Could it be that Pass.txt is the password, not the contents of the file?!

I bounce the VM one more time and attempt to ssh onto the host with a username of overflow and a password of Pass.txt:

shell_user_overflow

BAM! We have a low privileged shell…. well… for a short period.

damn_idle

Something is killing our SSH session periodically. We’ll get to that soon, but let’s continue to follow process. Once I get a privileged shell the very first part of my enumeration towards privilege escalation is look for any setuid files we can leverage from.

find_setuid

Nothing out of the ordinary stands out there. Next step is to look for the ‘unusual’. In this case, we have already identified ‘something’ is killing our sessions periodically, so let’s take a look at crontab.

crontab_cleaner_py

According to the cronlog, a script located in /lib/log/ is being called every two (2) minutes; cleaner.py. Let’s take a closer look at this script:

cleaner_py_edit

Looking at the code, every two (2) minutes the script, executed as root, removes any files in /tmp. Clever. /tmp is the common directory where any exploit code or privilege escalation scripts are generally stored due to the permissions of the folder. Not so clever, is the chmod 777 permissions given to the file, which in theory will allow us to edit the file. Voila! Thanks to poor permissions on the file, we are able to edit the file, which should be executed with root permissions. Now, during my enumeration stage, I found another binary which is not ‘normal’, lmao.py in /opt. Due to the root permissions on this file, I was unable to look at what the python script actually did, so leveraging upon the crontab execution of cleaner.py, I cat the script and redirect the output to /tmp/out.txt. Once executed, out.txt contained the following python code:

This annoying troll code was the reason we were getting session disconnects! The cronlog did not include this file in it’s output, so it can only be assumed root’s crontab is executing the file. Troll… arghhhhh!

Let’s get root!! Enter stage left what I call the setuid C Wrapper fatality move! I have used the following snippet of code more times than I care to count in order to obtain privilege escalation on *nix hosts. It’s tried, tested, and dependable.

As you can see, this script will execute /bin/bash with setgid/setuid of 0, aka root. All we need to do is compile the C code, and coerce root into changing the ownership and sticky bit, enabling a normal user to execute the script and obtain a root shell. Sounds wordy, but it’s not that complicated. To do this, we edit /lib/log/cleaner.py with the our chown/chmod commands, and let crontab perform it’s periodic magic.

The end result? A setuid binary as follows, which, when executed by our standard user overflow will give us a root shell.

got_root

We have root and we have the flag! Wooohooooo! The end I hear you say? Not for me… I need to put this troll to rest! crontab -e and let’s get rid of the damn lmao.py script from trolling sessions! :)

stop_lmao

Now it’s the end. The tr0ll has been slain! And for the record, it was fail2ban that was limiting our SSH brute-force attempts also.

Thank you so much Maleus for the challenge. It was great fun and lived up to it’s name of tr0ll. Thanks vulnhub for making the challenges available.

Until next time, tight lines and may you pop shells often.



2 Comments

  1. Greg wrote:

    Quick FYI, I couldn’t get your modified cleaner.py script to work without adding “cat” in front of “/opt/lmao.py”,