[OSCP Practice Series 76] Proving Grounds — KeyVault

Ardian Danny
5 min readMar 31, 2024

--

Machine Type: Linux

The Attack

Regular Linux machine with two HTTP ports.

There’s a .git repository on port 8080. Let’s dump it.

We have obtained the source code.

The default credentials are admin:admin.

Chris is a potential user.

Seems like we miss credentials.php and secrets.php.

No wonder. But we got some info here. There’s a user called Ray. There’s nothing more we can enumerate. My Gobuster also found nothing on both ports 80 and 8080. Let’s take another look at the source code.

I see where this is going. We need to bypass some validations to trigger the index.php to output the credentials. Since we don’t have credentials.php, let’s just ignore that.

Foothold

We already know how to bypass auth.php by using admin:admin as the credentials. Now let’s analyze hmac.php.

We need to supply “h”, “host”, and “token” as GET parameters. We also need to specify the “token”. Then, there’s the function below:

hash_hmac('sha256', $_GET['host'], $secret);

It must be equal to the “h” parameter. Well… how could we know if we don’t know the secret?

The interesting thing here is that we control the $secret variable in this line of code.

if (isset($_GET['token'])) {
$secret = hash_hmac('sha256', $_GET['token'], $secret);
}

Oh, it turns out that in older versions of hash_hmac, if we can make this function produce an error, it will return false. Which means, we will know what the $secret value is (it will be false).

We can produce an error by passing an unexpected datatype to the $_GET[‘token’] parameter, like an array.

Then we will know what the output is.

Nice, let’s try.

192.168.214.207:8080/index.php?h=663e7fa98837d5b3e5aa3056efacfc215d2b0ac1e6bfe88df8c715eb26d2d7e8&host=asd&token[]=asd

Okay, we got Ray’s credentials.

ray:Iamsuperstrong3434

We are in.

local.txt: 91091401f598109a6af6c1deadede188

Getting Root

We can’t sudo. There’s nothing interesting in the system except for this apache-restart binary in /opt.

It asked for a password. It must be the root password since it executes as root. Let’s decompile it (I’ll use Ghidra).

Seems like this is a Python program. Let’s use a Python decompiler. This article really helped.

First, we use pyi-archive_viewer to extract the .pyc file from the ELF binary.

pyi-archive_viewer apache-restart

Then we use uncompyle6 to decompile the Python bytecode and obtain the Python code.

Hm… okay, we encountered issues. Luckily, HackTricks already has the answer.

Looking at the hex, we can already see the root password, but it’s not clear.

It doesn’t work, or I did something wrong. Let’s use pyinstxtractor.py instead.

python3 /opt/pyinstxtractor.py apache-restart
uncompyle6 apache-restart_extracted/apache-restart.pyc > decompiled_apache_restart.py

Let’s see. Hope this works.

We got the root password.

root:Mypetdognameisjack909

GG!

proof.txt: b913d6eace16465b02d68a542d6255f2

Learned

  • pyinstxtractor.py + Uncompyle6 is OP!

--

--

Ardian Danny

Penetration Tester, Ethical Hacker, CTF Player, and a Cat Lover. My first account got disabled by Medium, but it won’t stop me from sharing the things I love.