27 mai 2008

Ghost vuln... bhooooooooooo!!

(Pour toute réclamation concernant la précision du titre de l'article voire avec mes avocats)
Petit post au milieu d'une periode d'examens divers gourmande en temps! Petit panorama de ce qui attira mes yeux récemment.

Premierement (vous allez voire d'où me vient le titre incompréhensible de l'article :) ) la publication sur securityFocus d'un advisory sur une vulnerabilité du noyau linux. Le petit détail troublant c'est que personne ne semble savoir à quoi réfère cet advisory! La faille n'est pas classée, ils manquent d'informations, aucun exploit aperçu dans la nature... Bref, la faille fantôme! Sans doute un effet de l'accroissement brutal des responsible disclosures qui consistent à ne révéler une faille au grand public qu'après que les developpeurs l'aient patché.

Deuxièmement, un DoS via la fonction sleep de PHP qui l'eu cru? Vous en rêviez, Bugtrack vous l'offre! A voir ici et la aussi : http://www.milw0rm.com/exploits/5679 Le principe est simple, le temps d'execution de sleep() n'est pas comptabilisé dans la limite de temps d'execution des scripts PHP imposée courament par les serveurs web. L'exploit sature la memoire pour provoquer le DoS annoncé. Rien d'énorme cependant, l'attribution même du statut de "vulnérabilité" à cette annonce est d'ailleur contestée sur Bugtraq.

Enfin, la création il y a quelques temps de l'OCERT (Open Source Computer Emergency Response Team), un groupe d'experts en securité, assisté de la communauté, créé afin d'apporter un petit peu de réactivité à la securité des projets open source. Prometteur, annoncé à grands coups de buzz, à suivre...


Pendant ce temps là, Adrian Pastor continue de pentester son téléphone:

http://www.gnucitizen.org/blog/bt-home-flub-pwnin-the-bt-home-hub

http://www.gnucitizen.org/blog/bt-home-flub-pwnin-the-bt-home-hub-2
http://www.gnucitizen.org/blog/bt-home-flub-pwnin-the-bt-home-hub-3
http://www.gnucitizen.org/blog/bt-home-flub-pwnin-the-bt-home-hub-4
http://www.gnucitizen.org/blog/bt-home-flub-pwnin-the-bt-home-hub-5
http://www.gnucitizen.org/blog/default-key-algorithm-in-thomson-and-bt-home-hub-routers
http://www.gnucitizen.org/blog/dumping-the-admin-password-of-the-bt-home-hub
http://www.gnucitizen.org/blog/dumping-the-admin-password-of-the-bt-home-hub-pt-2

De l'acharnement? où ça?
;)

11 mai 2008

exploration réseau : Goolge rules again!

En traînant sur le site de "Johnny I hack stuff" (http://johnny.ihackstuff.com), monsieur Google hacking, je suis tombé sur un script perl de découverte réseau vraiment original! Ecrit par "Jimmy Neutron", il permet d'effectuer une découverte réseau active à l'aide de Google et du protocole DNS.
Ce script prend en argument deux mots clefs et un nom de domaine. Les deux mots clefs sont soumis à Google, qui va renvoyer d'autres mots proches.
Pour ceux qui ne connaissent pas Google sets : il s'agit d'un programme qui pour une suite de mots renvoie des mots proches (ainsi, avec en entrée Volta et Galilée, on obtient la liste suivante :

Predicted Items
galileo
volta
newton
torricelli
fermi
fulton
marconi
spallanzani
rubbia

Ensuite, des requêtes DNS sont effectuées sur les noms d'hôtes construits à partir des résultats de Google et du nom de domaine.

Une carte du réseau peut alors être établie en fonction de l'aboutissement ou non des requêtes DNS.
Le concept, s'il est simple, est également très ingénieux!
Le script est disponible ici : http://johnny.ihackstuff.com/downloads/task,doc_download/gid,26

Vous trouverez d'autres outils dans la section download du site, dont une version windows du programme décrit ici.

3 mai 2008

Coder un sniffer sous Linux

Cela faisait un moment que je voulais me coder un petit sniffer basique sous Gnu/Linux. C'est chose faite avec le petit code suivant.
Il reconnaît pour l'instant les trames TCP, UDP et ARP mais est simple à faire évoluer.
Le principe est simple, on ouvre une raw socket (SOCK_RAW) puis on la passe en mode promiscuous ("accepter toutes les données qui passent par l'interface réseau choisie"). Ensuite, plus qu'à lire paquet par paquet, puis parser les headers pour déterminer le protocole auquel nous avons à faire.

Voici le code. (Fichier .c)

/**
* @File sniffer.c
* @brief sniff network traffic
*
* @author Hth http://hatch-the-hitch.blogspot.com
* @date samedi 3 mai 2008, 00:31:21 (UTC+0200)
*
* version : <0.1 alpha
*
* gcc -o sniff sniffer.c -pedantic
*
*/

/* std */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/* usual networking */
#include <sys/socket.h>
#include <sys/types.h>
/* low level networking */
#include <sys/ioctl.h>
#include <net/if.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
/* headers paquets */
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <linux/tcp.h>



typedef struct {
char * ifaceName;
int sock;
unsigned long max_recv;
struct sockaddr_ll device;
} param_t;


/* --- PROTOTYPES --- */
char argumentManagement ( int argc, char **argv, param_t * parameters );
void initParams ( param_t * parameters );
char checkParams ( param_t * parameters );
void usage ( void );
char initSniff ( param_t * parameters );
void loop ( param_t * parameters );
int getPacketType ( unsigned char * packet );
void printOutTCP ( unsigned char * packet );
void printOutUDP ( unsigned char * packet );
/* ------------------ */


int main ( int argc, char **argv )
{
param_t parameters;

/* Parse and check command line */
if (argumentManagement(argc, argv, &parameters) < 0)
{
usage();
exit(EXIT_FAILURE);
}
else
{
/* Prepare system for sniffing */
if ( initSniff(&parameters) < 0 )
{
fprintf(stderr, "Can't prepare to sniff!\n");
exit(EXIT_FAILURE);
}
else
{
/* Sniffing loop : May never end */
loop(&parameters);
}
}

return 0;
}


char argumentManagement ( int argc, char **argv, param_t * parameters )
{
int opt;

while ( (opt = getopt(argc, argv, "hc:")) != -1 )
{
switch(opt)
{
/* exit after a specified number of packets received */
case 'c' : parameters->max_recv = atol(optarg);
break;

case 'h' :
case '?' :
default : return -1;
}
}
/* Non option arguments */
/* IFace name */
if (argv[optind] == NULL)
return -2;
else
parameters->ifaceName = argv[optind];

/* Checkif required parameters have been given etc... */
return checkParams(parameters);
}


void initParams ( param_t * parameters )
{
parameters->ifaceName = NULL;
parameters->sock = -1;
parameters->max_recv = 0;
memset(&parameters->device, 0x00, sizeof(struct sockaddr_ll));
}


char checkParams ( param_t * parameters )
{
/* Check if required arguments have been specified */
if ( (parameters->ifaceName == NULL) )
{
fprintf(stderr, "No interface selected!\n");
return -1;
}
else
return 0;
}


void usage ( void )
{
fprintf(stderr, "Usage : ./sniff [options] [interface]\n");
fprintf(stderr, "options\n");
fprintf(stderr, "\t-c [count]\t: stop after [count] packets received\n");
fprintf(stderr, "\t[interface]\t: network iface from which to sniff (required!)\n");
}


char initSniff ( param_t * parameters )
{
struct ifreq ifr;

/* Open raw socket, exit on failure */
parameters->sock = openRawSock();
/* Folowing instructions set selected iface into promisc mode */
strncpy(ifr.ifr_name, parameters->ifaceName, IFNAMSIZ-1);

if ( ioctl(parameters->sock, SIOCGIFFLAGS, &ifr) < 0 )
{
close(parameters->sock);
perror("Flags");
return -1;
}
ifr.ifr_flags |= IFF_PROMISC;

if ( ioctl(parameters->sock, SIOCSIFFLAGS, &ifr) < 0 )
{
perror("Can't turn into promiscuous mode");
close(parameters->sock);
return -2;
}
/* --- -- --- */
return 0;

}


void loop ( param_t * parameters )
{
unsigned long nb_recv;
unsigned char packet[4096];

/* This loop will never end if no max_recv specified */
for (nb_recv=1; ((nb_recv <= parameters->max_recv) || !(parameters->max_recv)); nb_recv++)
{
/* recv a packet */
read(parameters->sock, (char *)&packet, 4096);

fprintf(stdout, "\n--] Packet #%lu\n", nb_recv);
/* Add protocols and parsing functions here */
switch(getPacketType(packet))
{
case IPPROTO_TCP : printOutTCP(packet);
break;

case IPPROTO_UDP : printOutUDP(packet);
break;

case ETH_P_ARP : fprintf(stdout, "ARP request\n");
break;

default : fprintf(stdout, "Unrecognized packet\n");
break;
}
}

close(parameters->sock);
}


int getPacketType ( unsigned char * packet )
{
/* Read type of packet from ethernet header */
struct ethhdr * eth;

eth = (struct ethhdr *)packet;

/* If protocol is IP : we select between TCP and UDP */
if ( ntohs(eth->h_proto) == ETH_P_IP )
return getIPproto(packet);
else
return ntohs(eth->h_proto);
}


int getIPproto ( char * packet )
{
/* Look into IP header to know if this is UDP or TCP */
struct iphdr * ip=(struct iphdr *)(packet + sizeof(struct ethhdr));

return (ip->protocol);
}


/* This function prints out informations from a TCP packet */
void printOutTCP ( unsigned char * packet )
{
unsigned char *src, *dst;
struct iphdr * ip;
struct tcphdr * tcp;

/* put a pointer on IP header */
ip = (struct iphdr *)(packet + sizeof(struct ethhdr));
/* the same way for TCP */
tcp = (struct tcphdr *)(packet + sizeof(struct ethhdr) + sizeof(struct iphdr));

/* Used to print out IP addresses */
src = (unsigned char *)&(ip->saddr);
dst = (unsigned char *)&(ip->daddr);
/* --- */
fprintf(stdout, "TCP frame\n");
fprintf(stdout, "From\t: %u.%u.%u.%u (port : %u)\n", src[0], src[1], src[2], src[3], ntohs(tcp->source));
fprintf(stdout, "To\t: %u.%u.%u.%u (port : %u)\n", dst[0], dst[1], dst[2], dst[3], ntohs(tcp->dest));
fprintf(stdout, "TTL\t: %d\n", ip->ttl);
fprintf(stdout, "Flags\t: SYN=%d | ACK=%d | RST=%d | URG=%d | FIN=%d\n",tcp->syn, tcp->ack, tcp->rst, tcp->urg, tcp->fin);
}


/* This function prints out informations from a UDP packet */
void printOutUDP ( unsigned char * packet )
{
unsigned char *src, *dst;
struct iphdr * ip;
struct udphdr * udp;

/* put a pointer on IP header */
ip = (struct iphdr *)(packet + sizeof(struct ethhdr));
/* the same way for UDP */
udp = (struct udphdr *)(packet + sizeof(struct ethhdr) + sizeof(struct iphdr));

/* Used to print out IP addresses */
src = (unsigned char *)&(ip->saddr);
dst = (unsigned char *)&(ip->daddr);
/* --- */
fprintf(stdout, "UDP frame\n");
fprintf(stdout, "From\t: %u.%u.%u.%u (port : %u)\n", src[0], src[1], src[2], src[3], ntohs(udp->source));
fprintf(stdout, "To\t: %u.%u.%u.%u (port : %u)\n", dst[0], dst[1], dst[2], dst[3], ntohs(udp->dest));
fprintf(stdout, "TTL\t: %d\n", ip->ttl);
}


/* Open RAW socket, receive every packet that crosses our netdevice */
int openRawSock ( void )
{
int fd;

if ( (fd=socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL))) < 0 )
{
perror("Socket");
exit(EXIT_FAILURE);
}
else
return fd;
}


Voilà!! En espérant qu'il pourra servir à quelqu'un. Je vous laisse le soin de refaire l'indentation détruite par l'éditeur wysiwyg! :)
Il aurait été possible d'utiliser la libPCAP (Packet CAPture) pour coder quelque chose de bien plus puissant, elle sert aussi à accéder aux basses couches du réseau, pas très utile sous Gnu/Linux où cela se fait bien "à la main", mais indispensable sous Windows!!

2 mai 2008

Relations publiques négatives : Pwnez l'Humain!

"Black PR" (black public relations) ou "negative PR" (cette seconde expression est celle retenue pour les traductions françaises) consiste à s'attaquer à l'image d'une personne ou d'une société (normalement vos rivaux).
Science (art?) proche de l'espionnage industriel, les relations publiques négatives sont étroitement liées à la sécurité informatique du fait que la connaissance des petits secrets de la "cible" constitue la première étape du processus offensif.

A partir de là, tous les coups sont permis (en pratique hein!!) : campagne de diffamation, débauchage des employés, entrave à l'embauche, paralysie des systèmes d'information de la cible, vol d'informations sur les ordinateurs de la cible...


Les articles rédigés par des professionnels de black PR font froid dans le dos : chantage, manipulation, harcèlement, humiliations etc... Le seul lien avec le hacking est ici une ambiance digne d'un roman CyberPunk!
En fait ce n'est pas vrai, il y a par exemple le fait que de telles attaques obligent la partie offensive à détenir un contrôle total sur l'environnement cible, un peu comme les connaissances requises pour attaquer un soft/hôte/réseau.

Les analogies sont en réalité très nombreuses : Comparons une attaque black PR contre une entreprise et une attaque d'un réseau informatique.

Recon : Dans un cas comme dans l'autre, l'environnement doit être défini au mieux. Ici, on recherchera des personnalités/profils susceptible d'êtres utilisés pour récupérer des informations secrètes ou servir d'intermédiaire pour toucher un autre employé. Les "vulnérabilités" sont le besoin d'argent, la rancoeur/frustration, une trop haute estime de soi, le besoin insatiable de reconnaissance etc...

Exploit : La encore : aucune limite, tout dépend des objectifs fixés. Supposons qu'il ait été prévu que la campagne de discréditation de notre cible se fasse par la révélation au public de documents comptables, il nous faudra obtenir ces documents. Après avoir pris au piège certains employés minutieusement sélectionnés, ils seront amenés à dérober les documents.
Dans ce cas là comme dans d'autres, les rumeurs générées peuvent être diffusées par l'intermédiaire de journaux type "tabloids", ou sur le net.
Générez un buzz et le travail est fait!

Forensic : L'entreprise attaquée pourrait bien tenter de retrouver l'origine des rumeurs, néanmoins il est évident que tracer une rumeur sur le net demande vite plus d'efforts que la reconstruction d'une bonne image à grand renfort de publicité (et donc d'argent).

Protection
: Il existe des sociétés spécialisées dans la protection contre les attaques visant l'image. Ivana "Ink" Kalay, du site www.spinhunters.org en dirige une, basée en Angleterre. La encore le rapport avec la sécurité informatique est trivial : spinhunters est associé au GnuCitizen (on va encore dire que je ne parle que d'eux!)

Rapide présentation de ce qui se trame dans la cour des grands. Le scandale dans lequel fut impliqué Max Mosley constitue un exemple de ce à quoi peut ressembler une campagne de relations publiques négatives du point de vue extérieur.