segunda-feira, 25 de agosto de 2014

Da Série: Melhor prevenir do que remediar - Heap Overflow

Dando continuação a série, mostrando algumas dicas de como se proteger de ataques de buffer overflow. Desta vez iremos falar de Heap Overflow.

Estouros de Heap são problemáticos pelo fato de que não são necessariamente protegidos pro CPU capazes de usar pilhas não-executáveis. Um Heap é uma área da memória alocada pela aplicação em tempo de execução para armazenar dados. O seguinte exemplo, em C, mostra um exploração de Heap overflow.

 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>

 #define BSIZE 16
 #define OVERSIZE 8 /* overflow buf2 by OVERSIZE bytes */

 void main(void) {
    u_long b_diff;
    char *buf0 = (char*)malloc(BSIZE);  // create two buffers
    char *buf1 = (char*)malloc(BSIZE);

    b_diff = (u_long)buf1 - (u_long)buf0; // difference between locations
    printf("Initial values:  ");
    printf("buf0=%p, buf1=%p, b_diff=0x%x bytes\n", buf0, buf1, b_diff);

    memset(buf1, 'A', BUFSIZE-1), buf1[BUFSIZE-1] = '\0';
    printf("Before overflow: buf1=%s\n", buf1);

    memset(buf0, 'B', (u_int)(diff + OVERSIZE));
    printf("After overflow:  buf1=%s\n", buf1);
}

[root /tmp]# ./heaptest

Initial values:  buf0=0x9322008, buf1=0x9322020, diff=0xff0 bytes
Before overflow: buf1=AAAAAAAAAAAAAAA
After overflow:  buf1=BBBBBBBBAAAAAAA

Este simples programa acima, mostra dois buffers sendo alocados no heap.
  • O primeiro buffer é "estourado" para sobrescrever o conteúdo do segundo buffer.
Como determinar se você é vulnerável e como se proteger:

É preciso utilizar das mesmas dicas de como se proteger de Stack Overflow, veja o post anterior.

Fonte:
https://www.owasp.org/index.php/Buffer_Overflows#Heap_Overflow

quinta-feira, 21 de agosto de 2014

Da série: Melhor prevenir do que remediar - Stack Overflow



No Geral...

...Ataques de buffer overflow baseiam-se em duas técnicas ( e normalmente a combinação delas):

  1. Escrevendo dados em um endereço específico na memória
  2.  Aproveitar-se do mau manuseio do sistema sobre o tipos de dados

Isso significa que linguagens de programação fortemente tipadas (e ambientes) que desabilitam acesso direto à memória, normalmente previnem buffer overflows de acontecerem.



Linguagem /Ambiente
Compilada ou Interpretada?
Fortemente Tipada?
Acesso direto à memória?
Seguro ou Inseguro?
Java, Java Virtual Machine (JVM)
Ambos
Sim
Não
Seguro
.NET
Ambos
Sim
Não
Seguro
Perl
Ambos
Sim
Não
Seguro
Python - interpretada
Interpretada
Sim
Não
Seguro
Ruby
Interpretada
Sim
Não
Seguro
C/C++
Compilada
Não
Sim
Inseguro
Assembly
Compilada
Não
Sim
Inseguro
COBOL
Compilada
Sim
Não
Seguro

Características de algumas linguagens
Stack Overflow

Stack Overflow (Estouro de pilha) é a forma de buffer overflow mais fácil de entender. Os básicos de stack overflow são simples.




  1. Existem dois buffers, um buffer de origem contendo uma entrada qualquer (presumindo, do atacante) e um buffer de destino que é muito pequeno para a entrada de ataque. O segundo buffer reside na pilha e ao lado do endereço de uma função de retorno na pilha.
  2.  O código 'desatento' não checa se o buffer de origem é grande a ponto de não caber no buffer de destino. Então copia a entrada no buffer de destino, e sobrescreve informações adicionais que estavam vizinhas na pilha (tais como o função de retorno ao lado)
  3. Quando a função retorna, a CPU retira o quadro (agora modificada) do endereço de retorno na pilha.
  4.  Controle não retorna a função como deveria. Ao invés, o código arbitrário (escolhido pelo atacante quando feito na entrada inicial) é executado.

"Não pise no gramado do vizinho, menino!"
O seguinte exemplo, escrito em C, demonstra um exploração de stack overflow:
#include <string.h>

void f(char* s) {
    char buffer[10]; // Tamanho 10
    strcpy(buffer, s);
}

void main(void) {
    f("01234567890123456789"); //Olha o tamanho da entrada!! isso não vai dar coisa boa!
}

[root /tmp]# ./stacktest

Segmentation fault



Como determinar se você é vulnerável


Se o seu programa:

· É escrito em uma linguagem ( ou sobre um programa que é escrito em uma linguagem) que permite que um buffer overflow seja criado (veja tabela acima) E

  • Copia dados de um buffer para outra na pilha sem checar primeiros os tamanhos E
  • Não usa técnicas tais como valores canário ou pilhas não-executáveis para prevenir buffer overflows 
ENTÃO é mais provável que a aplicação seja vulnerável a ataques desse tipo.

Como se proteger

  •  Estabeleça-se em sistemas capazes de usar pilhas não-executáveis, tais como:

    1.  AMD e Intel x86-64 chips com SO de 64 bits associados
    2. Windows XP SP2 (tanto 32 como de 64 bits, e agora SP3 também)
    3. Windows 2003 SP1 (tanto 32 como de 64 bits)
    4.  Linux após 2.6.8 em AMD e processadores x86-64 em modo 32 e 64 bits
    5.  OpenBSD (w^x em Intel, AMD, SPARC, Alpha e PowerPC)
    6.  Solaris 2.6 e mais recentes como a flag “noexec_user_stack” ativada.
  •  Use linguagens de programações de alto nível que são fortemente tipadas e que não permitem acesso direto à memória.
  • Valide entradas de usuário para prevenir que dados inesperados sejam processados, tais como serem muito longos, ou do tipo de dado errado, contendo caracteres "lixo", etc.
  • Caso se baseie em funções do sistema ou utilitários escritos em linguagem vulnerável, certifique-se de que:
    1.  Use do princípio de privilégio "At least"
    2.  Use compiladores que previnem stacks and heap overflows.
    3.  Estão atualizados, na questão de patches.


Fonte:
https://www.owasp.org/index.php/Buffer_Overflow
https://www.owasp.org/index.php/Buffer_Overflows

terça-feira, 19 de agosto de 2014

Android KeyStore Stack Buffer Overflow: To Keep Things Simple, Buffers Are Always Larger Than Needed

O texto abaixo é uma publicação do site Security Intelligence a respeito de uma vulnerablidade encontrada no Android KeyStore service, a equipe que a encontrou notificou a equipe de segurança do Android que reconheceu a brecha e disponibilizou um pack com a solução.

O texto abaixo encontra-se em inglês para manter a semântica original do texto, caso queira ler utilizando o serviço de tradução do Google clique aqui.

UPDATE  (Jun. 30, 2014):
The vulnerability affects Android 4.3 only. Thanks for the Android Security Team for correcting our advisory.+
Nine months ago, my team came across a classic stack-based buffer overflow in theAndroid KeyStore service.+
As always, we adhered to our responsible disclosure policy and privately reported this issue to the Android Security Team; the result is a patch that is now available in KitKat. Considering Android’s fragmented nature and the fact that this was a code-execution vulnerability, we decided to wait a bit with the public disclosure.+
SEE THE FULL ADVISORY WITH MORE DETAILS HERE. 
As an anecdote, the vulnerable source code file contains the following comment:+
Though things are simple, buffers are not always larger than the maximum space they needed.+

The Android KeyStore Service

Android provides a secure storage service implemented by /system/bin/keystore. In the past, this service was accessible to other applications using a UNIX socket daemon found under /dev/socket/keystore; nowadays, however, it is accessible by the Binderinterface. Each Android user receives his or her own secure storage area. A Blob is encrypted with AES using a master key, which is random, and is encrypted on-disk using a key that is derived from a password (the lock screen credentials) by thePKCS5_PBKDF2_HMAC_SHA1 function.+
In recent Android versions, credentials such as RSA private keys can be hardware-backed. This basically means that the keystore keys only serve as identifiers for the real keys backed by the hardware. Despite the hardware support, some credentials, such as VPN PPTP credentials, are still stored (encrypted) on-disk.+
The following diagram best illustrates the operation of the KeyStore service:+
KeyStore Modus Operandi
More internals of KeyStore are available on the excellent series of posts (12345) by Nikolay Elenkov.+

The Vulnerability

A stack buffer is created by the ‘KeyStore::getKeyForName’ method.+
This function has several callers, which are accessible by external applications using the Binder interface (e.g., ‘android::KeyStoreProxy::get’). Therefore, the ‘keyName’ variable can be controllable with an arbitrary size by a malicious application. As you can see, the ‘encode_key’ routine that is called by ‘encode_key_for_uid’ can overflow the ‘filename’ buffer, since bounds checking is absent:+
+

Exploitation

Exploiting this vulnerability can theoretically be done by a malicious application; however, a working exploit needs to overcome a combination of obstacles:+
  1. Data Execution Prevention (DEP). This can be bypassed by Return-Oriented Programming (ROP) payloads.
  2. Address Space Layout Randomization (ASLR)
  3. Stack Canaries
  4. Encoding. Characters below 0×30 (’0') or above 0x7e (‘~’) are encoded before being written on the buffer.
However, the Android KeyStore is respawned every time it terminates. This behavior enables a probabilistic approach; moreover, the attacker may even theoretically abuse ASLR to defeat the encoding.+

Impact

Successfully exploiting this vulnerability leads to a malicious code execution under the keystore process. Such code can:+
  1. Leak the device’s lock credentials. Since the master key is derived by the lock credentials, whenever the device is unlocked, ‘Android::KeyStoreProxy::password’ is called with the credentials.
  2. Leak decrypted master keys, data and hardware-backed key identifiers from the memory.
  3. Leak encrypted master keys, data and hardware-backed key identifiers from the disk for an offline attack.
  4. Interact with the hardware-backed storage and perform crypto operations (e.g., arbitrary data signing) on behalf of the user.

Vulnerable Versions

Android 4.3.+

Non-vulnerable Versions

Android 4.4.+

Disclosure Timeline

Jun. 23, 2014 Public disclosure.
Nov. 11, 2013 Fix confirmed by Android Security Team.
Oct. 22, 2013 Updates requested from Android Security Team.
Sept. 9, 2013 Vulnerability acknowledged by Android Security Team.
Sept. 9, 2013 Private disclosure to Android Security Team.+

Identifiers

CVE-2014-3100
ANDROID-10676015+

Acknowledgment

We would like to thank Android Security Team for the efficient way in which they handled this security vulnerability.

Fonte: http://securityintelligence.com/android-keystore-stack-buffer-overflow-to-keep-things-simple-buffers-are-always-larger-than-needed#.U_OOD8VdX_H