GuidePoint Security CTF Feb 2021

The folks from GuidePoint Security set up another awesome CTF this February (I had enjoyed the Sep. 2020 one as well.). This event was all about exploring machines with little or no hints, like mini pentests! Just before the end of the event, my Kali VM crashed and I lost everything I had documented (silly me). So all I have left to share with you is how I found the 5 flags of the beni machine. Here we go!

All we are given is an ip address on the network we’re connected to via VPN.
The machine name is beni and its address is

Step 1: Recon

Alright, since we have absolutely no hints at all about the target, let’s start by scanning its open ports and the services that are running on them. I start by scanning with pretty basic parameters first to see if I can find something of interest before launching much more time consuming scans:

$ nmap -sV -sC > nmap.txt

This scans for ports using the default set of scripts (-sC) and does version scanning (-sV) as well. The most important findings I yield from this are the following:

22/tcp  open  ssh     OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.13 (Ubuntu Linux; protocol 2.0)
80/tcp  open  http    Apache httpd 2.4.7 ((Ubuntu))
| http-git: 
|     Git repository found!
111/tcp open  rpcbind 2-4 (RPC #100000)

We have ssh that is open on its default port 22, a web server running on port 80 that seems to be linked to a git repository, and RPC on its default port 111.

Clearly I don’t have enough information yet to try to get in with ssh. The only clue I have is that the machine name (beni) might be used as a username, and I could use hydra to try to bruteforce ssh. But first I’d like to go take a look at the web server that’s running on port 80.

Before I go check out the service in a web browser, I launch ffuf to try to find interesting folders on the web server:

$ ffuf -u -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt | tee ffuf.txt

I only find 2 directories, /js and /css. I check the files in those 2 directories to make sure they don’t contain hints or better, flags, but to no avail. If I don’t get more hints soon, I’ll also check for files using file extensions.

Step 2: Checking the web service

I load up in Firefox and am presented with the following form:

I check the page source, try to play around with XSS but no joy. I have other options so let’s check them out. My nmap scan (see above) revealed that there was a /.git/ directory in the web server. One thing I could do is download the files from the website to my machine. For this, I will use a python script called (merci Maxime !)

As a reminder, when you want to clone a repository, simply use the “git clone” command like so:

$ sudo git clone

Then install the requirements if there are any:

$ sudo pip install -r requirements.txt

Copy the python script to your /usr/local/bin so that you can run it from any folder:

$ sudo mv /usr/local/bin

Ok I’m all set to retrieve the files from the website now, let’s run the script:

$ beni_git

This downloads all the files from the web server that were linked to that git repository into a directory that I named beni_git. Among the downloaded files, I mostly find css and js files and a single file that really interests me: index.php:

Jackpot! There are a few interesting things in this file. First of all, these 2 lines give me a serious hint about the 1st flag:

I guess the purpose of this 1st flag is to remind me that my web recon was not thorough enough since I didn’t check the cookies. Let’s check the contents of the JSESSIONID_DEV cookie now:

That looks like some Hex, let’s try to xxd it to “unhex” it with the -r and -p parameters:

We’ve finally found our 1st flag out of 5!

Ok let’s check the rest of the index.php file. There seems to be a way to display information inside the form’s fields by specifying special query parameters:

Let’s try adding ?id=1&private=true to the url:

Bingo! We’ve just found a RSA private key belonging to user beni that we might be able to use to enter through ssh! Let’s save this into a file called id_rsa:

Oh wait! What have we got here! A flag! It was actually the last line of the text that was in the form above. Awesome, we have our 2nd flag out of 5: StormCTF{Net:Beni3:D44d2EBaD6A7674c622eDB1f01BC627E}

Ok now before we try to use the private key we just found, let’s try displaying the second piece of information that the form can reveal to us, by giving a random value to the private parameter:

Ok now we have beni‘s public key as well, but we might not need this as much as the private key we retrieved previously. Let’s change the permissions of the id_rsa file we just created to 600.

The .ssh directory permissions should be 700 (drwx——).
The public key (.pub file) should be 644 (-rw-r–r–).
The private key (id_rsa) on the client host, and the authorized_keys file on the server, should be 600 (-rw——-).

$ chmod 600 ./id_rsa

Now that this is done, I can try connecting to the machine with this private key using this syntax:


We’re in! Or at least kinda. This is a python command line. I should do some research on how to break out of it. But for now let’s see how I can still continue pwning this machine using the python command line.

It’s pretty easy to execute bash commands through the python command line. All I need to do is import the os module and then run commands like this:

import os
os.system('ls -la')

This displays all the files that are in the current directory. Of course my eye is immediately attracted to the file called flag.txt! Let’s check it out:

>>> os.system('cat flag.txt')

We’re doing well now with 3 flags found out of 5!

Step 3: Linux Privilege Escalation

Now that we’re connected to the machine with a regular user, typically we’re going to try to elevate our privileges to become root and go see what is in the /root directory, hoping that it will be a flag. This can be done multiple ways, by looking at which sudo permissions the user has, or finding SUIDs (Set owner User ID up on execution). Let’s start with the former and see if we have any luck there:

This is interesting, we learn that user beni can run 6 commands as root. We need one that will allow us to become root, if possible. A great resource to research these commands is GTFOBins:

“GTFOBins is a curated list of Unix binaries that can used to bypass local security restrictions in misconfigured systems.”

If you search for xz or tar on that site, you will see that both of these commands can help us out, but tar is the most complete because it could actually spawn a shell, so let’s try that one:

Let’s try it out!

That did the trick. We are now root on beni. Let’s go see what’s in the /root directory, hoping we will find one of the 2 flags we’re still missing. There is a file called flag.txt in that directory. Let’s check it out.

Ok we have our 4th flag, only 1 to go.

I look around the server and don’t find any extra hints. So I go back to my nmap file, and the files I downloaded from the webserver. I notice something special in index.php that mentions the second flag (the one that’s missing):

This doesn’t seem to help much at first sight, but… but… it’s actually a PHP comment, recognizable by the //. So maybe there could be a hint in a previous version of this file? Since we know that there is a git repository, we can check out the commits and see if there were any changes on that file that would give us a hint.

To examine the commits, we can use Extractor which is part of GitTools. First, we need to clone GitTools:

$ sudo git clone

Here is a quick description of what Extractor does:

A small bash script to extract commits and their content from a broken repository.
This script tries to recover incomplete git repositories:

  • Iterate through all commit-objects of a repository
  • Try to restore the contents of the commit
  • Commits are not sorted by date

To use Extractor, we need to supply 2 arguments, the name of the directory that we downloaded the repository’s files in, and the name of a destination directory where the commits will be saved:

$ /usr/local/bin/ ./git ./git_extractor/

After running Extractor, I notice that 2 commits have been saved in my destination directory. In each commit subdirectory, I will run diff to compare index.php to the one that I previously downloaded, to see if there is a difference in that part of the script where FLAG NUMBER TWO was mentioned. And this is what I find:

In the file I downloaded with

In the index.php file found in one of the 2 commits:

Now we know that there was previously some base64 encoded text in this file. Let’s decode it and finally get our last flag!

$ echo NTM3NDZmNzI2ZDQzNTQ0NjdiNGU2NTc0M2E0MjY1NmU2OTMyM2E0NjYyNjM2NDM1NjM0MjYzMzkzNTYyMzQzNjYzNjUzOTM1NDY0MzM4MzYzNzYzMzIzNzQ0NjMzNjM2MzczOTMxN2QwYQ== | base64 -d

Uh-oh, the result is still not a flag:


But it looks like hex, so let’s add some xxd in there:

And there we have it, our last flag:

This was a fun challenge! However I’m still learning and there were maybe more efficient ways of attacking this target. Please leave a comment below if you want to share tools or methods that could have been used to solve this challenge.

Thanks to the GuidePoint Security team that made this event possible, especially MaryLou Garcia and Alex Williams! Looking forward to the next event!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s