Daniel Lowrie here. In this episode of CTF-Walkthrough, we take on a fairly straight-forward boot-2-root challenge. The narrative is a tale as old as time.
Boy meets girl (Bob and Alice).
They fall in love.
Girl gets job at a seemingly shady corporation.
Girl gets brainwashed by said shady-corp.
Boy hires a hacker to break into shady-corp to find out what is going on with his lady!
I’ve seen it a thousand times.
With that let’s see if we can’t help Bob rescue his loved-one from the clutches of this insidious scourge that has bewitched his precious Alice. Queue the music.
The CTF is available here if you’d like to take this journey with me.
We start by running an Nmap scan to see what services are running. I always run an aggressive scan first against all ports just to see what’s listening, then perform a more detailed scan against just the found open ports. Here we found ports 22 and 80, so I scan just those two.
Not a ton of output here, but we’ve just gotten started. Time to dig deeper and continue scanning and enumeration.
Since there is a web service running, let’s dust off trusty old Nikto to see what it can learn about the target.
OK, great! There are a couple of interesting entries. I slap a quick note into my working documentation so that we don’t forget about them and move on to directory fuzzing with GoBuster.
GoBuster doesn’t reveal anything we don’t already know, so I think it’s about time we visit the website of these heinous monsters!
Oh it’s like that, huh? OK, now it’s personal. Before we were just hackers-for-hire, but you just poked the wrong bear, buddy! Let’s see what’s behind the curtain and view the page source-code.
A HINT! And a good one too seeing as I’m not familiar with X-Forwarded-For other than it’s an HTTP Header. Maybe these folks aren’t so bad after all. Maybe we’ve been too harsh on them and they’re just misunderstood. Or maybe they’re the DEVIL!!! Anyway, moving on.
So I took the hint’s advice and started google-searching X-Forwarded-For. This site gave me a pretty good explanation of what this header does.
It looks like it’s used for connecting a client through a proxy. It grabs the client IP address and stuffs it in the header, then it combines that with a proxy server address. This allows the site to receive traffic through a proxy and still see what the original requesting client-IP is.
According to this Sjoerd Langkemper’s website “Some web applications make it possible to restrict access based on IP address of the visitor. This is particularly common for administrator interfaces. It is a good idea to restrict this interface to the IP addresses that are known to be used by actual administrators. To implement this, the web application will check the REMOTE_ADDR value that the webserver passes through to the application.”
It then goes on to say…
“The X-Forwarded-For header is usually set by a proxy, but it can also be added by an attacker. By adding his own X-Forwarded-For header, the attacker can spoof his IP address. If the IP block is implemented incorrectly, it can be bypassed by putting an allowed IP address in the header, even if the connection actually originated from a blocked IP address.”
This seems to be exactly the information we’re looking for! Remember the hint said that this site could only be accessed locally. Time to look at our request history.
I failed to mention at the beginning of our little adventure, I almost ALWAYS proxy my web traffic through Burp Suite. This makes it easy for me to see the actual requests and responses to sites I’m interacting with and then make quick adjustments to my requests to see what happens. It also keeps a history of your request/responses which allows you to look at the logical sequence of events as well as go back without having to necessarily revisit a page.
Back to the story.
Here is the request/response for the site without the X-Forwarded-For header.
And after adding the X-Forwarded-For header.
In the immortal words of John “Hannibal” Smith, “I love it when a plan comes together.”
What we accomplished was this. By adding localhost as the IP in the X-Forwarded-For header, it tricked the system into thinking that the originating IP was coming from the trusted/white-listed local machine.
It then was redirected (see that 302 response) to “?page=index“.
Cool! We’re making progress now. Time to see what this gets us.
- Turn on Burp Intercept
- Browse to target IP with your web browser of choice
- Add “X-Forwarded-For: localhost” to intercepted request and push “Forward”
- Add “X-Forwarded-For: localhost” to intercepted redirect to “?page=index“
And we are now accessing “Ceban Corp’s” hidden web portal.
A minor celebratory dance break is customary. I’ll wait.
While we have made some great progress, I find myself frustrated by the fact that we continually need to intercept EVERYTHING with Burp so that we can add the X-Forwarded-For header. There has got to be a better way. Oh, GOOGLE!!!
Come to find out, Burp Suite has this great feature called “Extender” and this will allow you to add extensions which increases its functionality. One of these marvelous extensions is called Bypass WAF. It’s free to install and allows us to automatically add specific headers, like X-Forwarded-For, to EVERY proxied request!
Configuring this thing took some help from here, but here’s the gist of it.
- Create Session Handling Rule
2. Add a Rule Description
3. Set the Scope to meet our needs
*YMMV. I set “Include all URLs” because this is in a sandbox environment.
4. Set the action to take when the Rule is applied
5. Click OK and you’re done!
Now that we can more easily explore the Ceban Corp web portal, let’s take a look around and see what we can see.
OK I haven’t gone crazy with a brute-force attack yet, but maybe we’ll come back to that. Let’s see what else we have. Oh! A registration page (<fingers_crossed>No email confirmation! No email confirmation! No email confirmation!</fingers_crossed>
Press log in
Excellent! We can now poke around as an authenticated user. Let’s check out that Profile page.
You’ll notice that I highlighted &user_id=14X up in the address bar. You don’t suppose? If I change &user_id=14 to &user_id=1, would that show me the Profile page for the user that corresponds with id1? It wouldn’t do that…would it?
Yes. Yes, it would.
I’m using Firefox, so I just right-click and choose “Inspect Element”, then look through the code for the password.
Sweet! So we can now cycle through all the ID numbers and gather all the passwords for each user! Working my way through this process I stumble upon.
We’ve found Alice’s profile! (id5) and now we have her password (4lic3)!
After thoroughly exploring the rest of the app, we find that this is basically the extent of it. We’ve got to assess what we’ve done, what we know, and what we’ve discovered.
A reexamination of our original recon, we’re reminded that SSH is open on port 22. We have some creds that we’ve gathered from the web app, but those passwords wouldn’t be reused by any of those users, would it? I think you see where this is going.
Look what I found lying around in Alice’s home dir.
This victory is bitter-sweet. It’s awesome to find the 1st flag, but poor Bob.
OK, that’s it! Let’s take Ceban Corp down! No one dogs my boy like that!
The first thing I do when gaining access to a system is two-fold.
- Check sudo access
- Upload a privilege escalation script like sh, LinEnum.sh, linuxprivchecker.py, and/or my own privy.sh
Checking sudo access.
You know, sudo is one of those things that can get a sysadmin in trouble if they don’t do it right. This is one of those times.
Checking GTFOBins to verify my suspicion.
Now, this is happening.
Now that we have root access, I think I’ll go do some work on the website.
This CTF was super fun and I’d like to thank @aldodimas73 for creating a great boot-2-root. It had an engaging story but didn’t get too esoteric with the challenges.
As a side note: if you root this box, take the time to deface its website. It’s a fun exercise to add as the cherry on top of the challenge. If you do deface the site, send me screen-shots of the defaced Ceban Corp site (firstname.lastname@example.org) and I’ll add them to this repository. Let’s keep it clean though.