This post is also available in: English
Introdução
Em minhas apresentações sobre segurança e vulnerabilidades de Oracle Database, eu sempre menciono os rootkits ou malwares que podem atacar um Banco de Dados por dentro (através de SQL Injection, alteração de códigos PL/SQL, leaks de Java, etc) ou por fora (através de alteração de arquivos do usuário oracle, tais como binários / libs / crontab / etc).
Para chegar a estas duas formas de ataques, um hacker costuma utilizar o que eu chamo de escada da alegria:
Normalmente um invasor começa o escalonamento de privilégios partir de um usuário com baixas permissões, muitas vezes apenas com o grant de CREATE SESSION, e tenta diversas técnicas para subir a escada, como SQL Injection, Java Vulnerabilities, Buffer Overflow, etc. Uma vez como SYSDBA ou DBA, é trivial o caminho para alcançar o usuário oracle de SO, responsável pelos binários do BD.
O objetivo deste artigo é apresentar como proteger os arquivos do usuário Oracle Home contra alterações indevidas e evitar assim a implantação de rootkits ou malwares.
OBS: Note que algumas etapas deste artigo não são documentadas ou suportadas pela Oracle. Portanto, faça por sua conta e risco.
Começando
No Oracle 18c foi introduzida uma nova funcionalidade chamada Read-Only Oracle Home (ou ROOH) e em cima deste novo recurso que iremos implementar esta proteção extra. Para BDs pre-18c, há uma sessão exclusiva neste tutorial.
Dentre os objetivos do ROOH estão:
• Remover do Oracle Home arquivos mutáveis.
• Consolidar estes arquivos em uma pasta separada.
• Facilitar a migração / clonagem de ambientes.
• Facilitar a utilização de Docker / compartilhamento de Oracle Homes via NFS / etc.
No entanto, o ROOH apenas garante que nenhum processo irá criar ou alterar arquivos no ORACLE_HOME, mas não torna impossível ao usuário oracle de implementar qualquer tipo de alteração em seus próprios arquivos. Uma vez como proprietário dos mesmos, ele obviamente ainda é capaz de alterá-los. Portanto, esses arquivos ainda não estão protegidos contra mudanças maliciosas.
O que faremos então, uma vez ativado o ROOH e tendo a certeza que o usuário oracle não precisará mais modificar qualquer arquivo dentro desta raiz (salvo em casos de aplicação de patches), será proteger os binários com as seguintes etapas:
- Salve os atuais proprietários e privilégios de todos os arquivos presentes ORACLE_HOME.
- Altere o atual proprietário de todos os arquivos do ORACLE_HOME para root.
O objetivo da Etapa 1 é ter uma forma de retornar ao proprietário e privilégios anteriores em caso de necessidade de aplicação de um patch ou qualquer outro tipo de alteração do ORACLE_HOME pelo usuário oracle.
O objetivo da Etapa 2 é proteger de fato o ORACLE_HOME de alterações indevidas, uma vez que o usuário oracle não será mais proprietário dos arquivos (parecido com o que ocorre hoje com o GRID_HOME, cujo proprietário é o root e não o grid).
Antes de começar
Certifique-se que:
- O ROOH está ativo para o seu ORACLE_HOME (veja esse doc para saber como).
- Nenhum processo está executando com o usuário proprietário do ORACLE_HOME (normalmente oracle).
1. Salvando as permissões e proprietários atuais
A primeira etapa é efetuar um backup dos privilégios e permissões.
Isso pode ser feito através do comando abaixo como oracle:
$ ORACLE_HOME=/u01/app/oracle/product/18.0.0/dbhome_1 $ cd $ORACLE_HOME $ find -depth -printf '%m:%u:%g:%p\0' | awk -v RS='\0' -F: ' BEGIN { print "#!/bin/sh"; print "set -e"; q = "\047"; } { gsub(q, q q "\\" q); f = $0; sub(/^[^:]*:[^:]*:[^:]*:/, "", f); print "chown --", q $2 ":" $3 q, q f q; print "chmod", $1, q f q; }' > original-permissions.sh
O comando find e awk acima irão gerar dentro do ORACLE_HOME o arquivo original-permissions.sh. Este shellscript possui comandos chown e chmod atuais para todos os arquivos existentes.
$ head original-permissions.sh #!/bin/sh set -e chown -- 'oracle:oinstall' './bin/lxegen' chmod 755 './bin/lxegen' chown -- 'oracle:oinstall' './bin/sqlldr' chmod 751 './bin/sqlldr' chown -- 'oracle:oinstall' './bin/lsnrctl' chmod 751 './bin/lsnrctl' chown -- 'oracle:oinstall' './bin/ore_srcexport.pl' chmod 644 './bin/ore_srcexport.pl'
2. Alterar o atual proprietário de todos os arquivos do ORACLE_HOME para root
Antes de mudar o atual proprietário dos arquivos para root, é preciso garantir algumas coisas, uma vez que os privilégios para o usuário oracle ler (r) e executá-los (x) se dará através do grupo do arquivo (normalmente oinstall):
- Se o proprietário do arquivo tinha poder de execução (x), o grupo precisará ter poder de execução.
- Se o proprietário do arquivo tinha poder de leitura (r), o grupo precisará ter poder de leitura.
- Grupo e others não poderão ter privilégios de alteração (w).
Isso pode ser feito através dos comandos abaixo, executados como root:
# ORACLE_HOME=/u01/app/oracle/product/18.0.0/dbhome_1 # cd $ORACLE_HOME # pwd /u01/app/oracle/product/18.0.0/dbhome_1 # find ./ -perm -u+x ! -perm -g+x -exec chmod g=u-w {} + # find ./ -perm -u+r ! -perm -g+r -exec chmod g=u-w {} + # find ./ -perm -g+w ! -type l -exec chmod g-w {} + # find ./ -perm -o+w ! -type l -exec chmod o-w {} + # chown -R root ./*
Pronto! Agora pode iniciar a sua instância com garantia que um ataque não conseguirá afetar os binários do BD.
OBS: Lembrando de que nada adianta esse tipo de proteção caso o usuário oracle consiga executar um su ou sudo para o usuário root.
Rollback
Sempre antes de aplicar um patch ou caso queira desfazer a alteração de proprietário e permissões, execute o arquivo original-permissions.sh (gerado na etapa 1) como root:
# ORACLE_HOME=/u01/app/oracle/product/18.0.0/dbhome_1 # cd $ORACLE_HOME # sh original-permissions.sh
OBS: Lembre-se de reexecutar a Etapa 1 após a execução de alterações no Oracle Home, a fim de garantir que permissões e proprietários de novos arquivos sejam inclusos no shellscript.
O meu Oracle Home está realmente protegido?
Como usuário oracle, eu posso agora verificar se a Oracle Home está realmente blindada. Como?
Tentarei remover todos os arquivos recursivamente como oracle.
JAMAIS TENTE ISSO EM SEU SERVIDOR.
$ cd $ORACLE_HOME $ pwd /u01/app/oracle/product/18.0.0/dbhome_1 $ find ./ | wc -l 42098 $ rm -rf ./* ./.* 2>&- $ find ./ | wc -l 42098
Como é possível ver do resultado acima, o usuário oracle não foi capaz de remover um sequer arquivo.
Banco de Dados Pré-18c
Em ambientes 12c ou anteriores, esse tipo de abordagem de proteção também funcionaria. No entanto, para evitar problemas é necessário mapear TODOS os arquivos que são mutáveis dentro do ORACLE_HOME (algo inexistente no 18c com ROOH) e mantê-los com as permissões originais do usuário oracle.
Como essa é uma tarefa muito difícil pois não é possível controlar os diretórios em que uma versão pré-18c gera arquivos, recomendo uma "abordagem inclusiva", com a proteção apenas de arquivos nas seguintes pastas para evitar impactos nos ambientes:
- ./bin/
- ./ctx/lib/
- ./hs/lib/
- ./javavm/admin/
- ./ldap/lib/
- ./lib/
- ./network/lib/
- ./odbc/lib/
- ./owb/wf/lib/
- ./plsql/lib/
- ./precomp/lib/
- ./racg/lib/
- ./rdbms/admin/
- ./rdbms/lib/
- ./sqlplus/lib/
- ./srvm/lib/
- ./sysman/lib/
- ./xdk/lib/
Isso pode ser feito através dos comandos abaixo como root (lembre-se de salvar as permissões atuais antes, conforme descrito no item 1):
# ORACLE_HOME=/u01/app/oracle/product/12.1.0/dbhome_1 # cd $ORACLE_HOME # pwd /u01/app/oracle/product/12.1.0/dbhome_1 # cat protected_folders.txt ./bin/ ./ctx/lib/ ./hs/lib/ ./javavm/admin/ ./ldap/lib/ ./lib/ ./network/lib/ ./odbc/lib/ ./owb/wf/lib/ ./plsql/lib/ ./precomp/lib/ ./racg/lib/ ./rdbms/admin/ ./rdbms/lib/ ./sqlplus/lib/ ./srvm/lib/ ./sysman/lib/ ./xdk/lib/ # find $(cat protected_folders.txt) -perm -u+x ! -perm -g+x -exec chmod g=u-w {} + # find $(cat protected_folders.txt) -perm -u+r ! -perm -g+r -exec chmod g=u-w {} + # find $(cat protected_folders.txt) -perm -g+w ! -type l -exec chmod g-w {} + # find $(cat protected_folders.txt) -perm -o+w ! -type l -exec chmod o-w {} + # chown -R root $(cat protected_folders.txt)
OBS: Você pode adicionar ou removes pastas da lista acima, a seu próprio risco, para aumentar ou diminuir a proteção.
Conclusão
Escalação de privilégios ( Usuário DBA no BD -> Usuário oracle no SO ), apesar de não apresentado por estar fora do escopo deste artigo, é algo realmente trivial e o principal objetivo final dos invasores. Portanto, dificultar a implantação de qualquer tipo de código malicioso nos binários é uma preocupação real que deve ser levantada em todos os tipos de ambientes, principalmente no de Produção.
Gostou? Não deixe de comentar ou deixar um 👍!