After watching an infosec talk off Iron Geek’s channel (big surprise) where someone talked about how 70%+ of their skills were learned by doing CTFs, I thought it was time for me to get going and fast.
This article is part diary and part walkthrough for the CTF I did.
CTF: Tr0ll
Where to get the VM: Vulnhub Tr0ll
Setup
For this CTF I used one machine, which was a Debian base along with VMware Workstation 11 for both the Tr0ll VM and for Kali.
What follows is the steps I used to get root and capture the flag. Along the way, I’ll pepper in my thoughts while doing this VM and include any other tools I used.
Step One: Where Art Thou?
So, I got the Tr0ll VM rocking and I’m ready for business. The first step is to figure out what IP I need to use to connect to the server. I read about NetDiscover, but ended up just using NMAP.
For those interested in NetDiscover and with a Debian-based system, you may need the following two installs:
1 | sudo apt-get install libnet1-dev |
Also, here’s a man page on Iron Geek for it.
To get the IP using NMAP, I did this:
1 | nmap -sP 172.16.65.1/24 |
I was then promptly given the target’s IP of: 172.16.65.128.
Step Two: Ports n Things
Next, I did another NMAP to figure out what ports were ready for action.
1 | nmap -sV -A 172.16.65.1/24 |
Results
1 | Nmap scan report for 172.16.65.128 |
My first step was to hit Robots.txt and see what goodies it might be trying to hide. The file had:
Disallow: \secret
Well, geez, I just have to visit /secret now right? I do and am greeted with this:
LOL. I’m being taunted already. Ok, time to step it up.
Since the web is currently a dead end, I’m pivoting over to FTP as there’s a juicy Anonymous FTP all ready to go.
FTP:
- Got 530 this FTP server is anonymous only. (hmmmm)
- Redid login with “anonymous” as user and just hit return for the pass. (booom, I’m in)
- Performed “ls” command and saw lol.pcap file sitting there.
- Performed “get lol.pcap /home/me/“ (to grab file for analysis)
- Opened the lol.pcap file in Wireshark and selected “Follow TCP Stream”
- FTP-DATA in frame 40 has a message containing: sup3rs3cr3tdirlol
- I decided to re-visit the web and start by going to /sup3rs3cr3tdirlol — Jackpot. There’s a file called: roflmao
- Downloaded the bin file and opened it in Gedit to take a look. LOL All sorts of stuff. Ok, there’s a better way.
- I learned about the command strings, which is awesome. Check this out.
1 | $ strings roflmao |
The output is a bunch of strings. Notice toward the top we have the string:
1 | Find address 0x0856BF to proceed |
Sweet. Let’s go back to the web with that.
Step Three: Directory Trolling
I went to /0x0856BF/ in my browser and sure enough, there’s more.
I’m now presented with two new folders:
- good_luck
- this_folder_contains_the_password
Wow, could it be this easy?
Each folder has a TXT file in it that looks like user credentials. Time to merge these into one.
1 | $ cat Pass.txt >> which_one_lol.txt |
Since it looks like I have some credentials, I’m feeling the need to check out SSH.
Step Four: Medusa Mayhem
I was thinking of just manually trying all the SSH combos I had, but I figured there had to be a better way. I learned about Medusa.
Initially, I made some mistakes, so I decided to go read a walkthrough for this VM to see how to properly use Medusa. Quickly, I was back on track. Here’s the code I ran:
1 | $ medusa -h 172.16.65.128 -U usernames.txt -p "Pass.txt" -t 10 -L -M ssh |
In the above code, Medusa will try to SSH by iterating through “usernames.txt” and each time use “Pass.txt” as the password. As a side note, lowercase is what to use when you want to pass a value directly, as is the case with “Pass.txt” and the uppercase is used for passing in a file name.
After a little bit, I received an awesome message from Medusa:
1 | RESULT: |
Yes!
I feel like I’m getting close now. Time to SSH into this bad boy.
Step Five: LOL Boot
After SSHing into the box, I copy out some random files and then get booted. WTH?
Wow, this is fun. There’s a cronjob running to boot users. Let’s fix that.
Step Six: Cron No
After getting back into the box, I ran the following commands:
1 | $ cd /var/log |
Ah hah. There you are. Let’s clean that up. :)
1 | $ nano /lib/log/cleaner.py |
I commented out the system command like so:
1 | try: |
Just in case you’re not familiar with Python and/or sys commands, this script is trying to rm all from /tmp/ and exiting if it can’t.
Ah, so nice. This script will no longer dump the contents of the /tmp/ directory, which means we can use it.
Step Seven: Turning Your Tool Against You
So what we have here is root running a Python script every so often. This is dangerous.
I knew that this was the key to me solving this CTF, but I wasn’t sure how exactly to accomplish my goal. Therefore, I looked at some walkthroughs and learned that I needed to compile a C program and have the Python script execute it.
Since this C wrapper is something that can be used often, I’ll post it here.
1 | #include <stdio.h> |
Here’s a quick sidebar on how to compile this C program on the Tr0ll box. Run these commands:
- $ nano /tmp/pwn.c
- Paste in that C code from above and save the file.
- $ gcc /tmp/pwn.c -o pwn
Compile that code in the /tmp directory then go back to the python script and add an OS execute with the file, like so:
1 | os.system('chown root:root /tmp/pwn; chmod 4755 /tmp/pwn') |
And now kick back and wait for the script to run again. When it runs, it’s going to boot me out then unwittingly make me a winner.
Side note: The cleaner.py script is Python and Python is a whitespace language, so tabs and spaces matter. If you find the code isn’t working for you, check to ensure that you don’t have spacing issues.
Step Eight: Tr0ll Harder
I logged back into the box and immediately went over to /tmp/. Yes! My file was sitting there all pretty. Now to execute it and get r00t.
1 | $./pwn |
BOOM! I am root!
1 | $ cd /root |
EXTRAS
To get the flag, I used privilege escalation with the C wrapper. However, there are multiple ways to defeat this CTF.
Think about it. You have root executing a python script and doing whatever in the heck it says. That’s pretty powerful.
Just go back to the cleaner.py script and replace the try with whatever you want to run.
One idea I saw was to copy your pub SSH key to /tmp then have root throw it into .ssh when it runs the cleaner script. Neat!
I had an absolute blast doing this CTF. I immediately went on to Tr0ll 2 and plan to do many, many more.
**If you find any errors or have comments about this walkthrough, hit me up on Twitter @jasonamartin.