2018年05月

PlaidCTF 2018 writeup macsh

macsh

18 hours ago
Crypto (125 pts)

Forget ssh, this is a much more secure shell. 

Server running at macsh.chal.pwning.xxx:64791

提示されたファイルはPythonのソースファイルです。まず、macsh.pyを見てみます。
<|>が区切り記号になっています。区切り記号の後ろにtagコマンドを指定すると、その次に指定されたコマンドとパラメータを連結した文字列を暗号化した16進文字列を返してくれます。lsやcatなどが指定された場合は、Permission deniedとエラーメッセージが表示されて、暗号化された16進文字列は返却されません。そして、区切り文字の前に暗号化された16進文字列を指定し、それに対応する暗号化前のコマンド、パラメータを区切り文字の後ろに指定すると、一致している場合はそのコマンドが実行されます。
#!/usr/bin/env python3

import os
import sys

from fmac import fmac, keygen

cwd = os.getcwd()

k0, k1 = keygen()

commands = [
    "echo",
    "tag"
]

privileged = {
    "pwd",
    "cd",
    "ls",
    "cat"
}

commands.extend(privileged)

def echo(s):
    print(s)

def encode(cmdline):
    return cmdline.encode('utf-8')

def tag(cmd, *args):
    if cmd not in privileged:
        cmdline = encode(" ".join([cmd] + list(args)))
        print(bytes.hex(fmac(k0, k1, cmdline)))
    else:
        print("macsh: tag: Permission denied")

def pwd():
    print(cwd)

def cd(newdir):
    global cwd
    if not os.path.exists(newdir) or not os.path.isdir(newdir):
        print("macsh: cd: {}: No such file or directory".format(newdir))
    else:
        cwd = newdir
        os.chdir(newdir)

def ls(path):
    if not os.path.exists(path):
        print("ls: cannot access '{}': no such file or directory".format(path))
        return
    if os.path.isdir(path):
        for e in os.listdir(path):
            print(e)
    else:
        print(path)

def cat(path):
    if not os.path.exists(path):
        print("cat: {}: No such file or directory".format(path))
    else:
        sys.stdout.write(open(path).read())

while True:
    print("|$|> ", end='', flush=True)
    mac, cmdline = input().split('<|>')
    cmd, *args = cmdline.split()
    if cmd not in commands:
        print("macsh: {}: command not found".format(cmd))
        continue
    if cmd == "tag" or bytes.hex(fmac(k0, k1, encode(cmdline))) == mac:
        eval(cmd)(*args)
    else:
        print("macsh: bad tag")
指定されたサーバに接続して動作を確認してみます。そのとおりの動作になっています。
$ nc macsh.chal.pwning.xxx 64791
|$|> aaa<|>tag ls
macsh: tag: Permission denied
|$|> 6066a0282d9630f33afc0ba4f6986a51<|>echo aaa
macsh: bad tag
|$|> aaa<|>tag echo aaa
37fb5c10129f20faf8fe06d31695e194
|$|> 37fb5c10129f20faf8fe06d31695e194<|>echo aaa
aaa
|$|> 37fb5c10129f20faf8fe06d31695e194<|>echo bbb
macsh: bad tag
次に、fmac.pyを見てみます。こちらは暗号化を行うPythonプログラムです。暗号化にはECBモードが使用されています。リンク先を見ると分かりますが、もっとも単純な暗号モードでブロック単位に独立して暗号化されます。入力値であるブロックが同じであれば、暗号化された結果も同じになってしまうという特徴があります。
from Crypto import Random
from Crypto.Cipher import AES
from functools import reduce

N = AES.block_size

def to_int(b):
    return int(bytes.hex(b), 16)

def to_block(b):
    return bytes.fromhex('{:0{width}x}'.format(b, width=N*2))

def xor(x, y):
    return bytes([xe ^ ye for xe,ye in zip(x,y)])

def to_blocks(m):
    m += to_block(len(m))
    padb = N - len(m) % N
    m += bytes([padb]) * padb
    blocks = [m[N*i : N*(i+1)] for i in range(len(m) // N)]
    return blocks

def rot(n, c):
    return (n >> c) | ((n & ((1 << c) - 1)) << (8 * N - c))

def f(k0, i):
    return to_block(rot(to_int(k0), i % (8 * N)))

def fmac(k0, k1, m):
    C = AES.new(k1, AES.MODE_ECB)
    bs = [C.encrypt(xor(b, f(k0, i))) for i,b in enumerate(to_blocks(m))]
    return reduce(xor, bs, b"\x00" * N)

def keygen():
    R = Random.new()
    return R.read(N), R.read(N)
したがって、lsやcatなどの実行したいコマンドの暗号結果を計算することができれば、そのコマンドを実行させてフラグファイルを参照することができそうです。
さらに暗号処理を詳しく見てみます。fmac関数でbとf(k0, i)のXORを取った結果を暗号化しています。
def fmac(k0, k1, m):
    C = AES.new(k1, AES.MODE_ECB)
    bs = [C.encrypt(xor(b, f(k0, i))) for i,b in enumerate(to_blocks(m))]
    return reduce(xor, bs, b"\x00" * N)
f関数では、k0をrot関数でシフト演算していますが、第二引数の値に依存していますので、8 * Nのパターンしかありません。Nはblock_size=32なので、8×32=256通りとなります。つまり、0番目と256番目のf関数の結果が同じになります。bを0番目と256番目を同じ入力値にすれば暗号結果も同じになるということです。
def f(k0, i):
    return to_block(rot(to_int(k0), i % (8 * N)))
また、fmac関数で暗号化された結果を最後にxorをとっています。次のプログラムのようにxor関数の戻り値を表示するようにすると分かりますが、16文字ごとのブロックを256個コピーした文字列をfmacで暗号化すると、256個目までxorを取った結果がオール0になります。
def xor(x, y):
    print('xor====' + bytes.hex(bytes([xe ^ ye for xe,ye in zip(x,y)])))
    return bytes([xe ^ ye for xe,ye in zip(x,y)])

k0, k1 = keygen()
str = 'aaaaaaaaaaaaaaaa' * 256
p1 = fmac(k0, k1, str.encode('utf-8'))
print('fmac===' + bytes.hex(p1))
これらのことを利用して、次のPythonプログラムによって、cat flag.txtの暗号結果を計算し実行させることができます。
from pwn import *
import time
import argparse
import struct

parser = argparse.ArgumentParser()
parser.add_argument('--local', action='store_true')
args = parser.parse_args()

context.log_level = 'debug'
p = remote('macsh.chal.pwning.xxx', 64791)

p.recvuntil('|$|>')
p.sendline(
'aaa<|>tag '
+ 'aaaaaaaaaaaaaaaa' * 256
+ 'cat flag.txt'
)
ret1 = p.recvline()

p.recvuntil('|$|>')
p.sendline(
'aaa<|>tag '
+ 'aaaaaaaaaaaaaaaa' * 256
+ '123456789012'
)
ret2 = p.recvline()

p.recvuntil('|$|>')
p.sendline(
'aaa<|>tag '
+ '123456789012'
)
ret3 = p.recvline()

r = hex(int(ret1, 16) ^ int(ret2, 16) ^ int(ret3, 16))[2:]
p.recvuntil('|$|>')
p.sendline(
r + '<|>cat flag.txt'
)

p.recvall()
実行するとフラグを得ることができました。
$ python aaa.py
[+] Opening connection to macsh.chal.pwning.xxx on port 64791: Done
[DEBUG] Received 0x5 bytes:
    '|$|> '
[DEBUG] Sent 0x1017 bytes:
    'aaa<|>tag aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacat flag.txt\n'
[DEBUG] Received 0x26 bytes:
    '5a826d210792edec7a87da42e6b65bc7\n'
    '|$|> '
[DEBUG] Sent 0x1017 bytes:
    'aaa<|>tag aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa123456789012\n'
[DEBUG] Received 0x26 bytes:
    'b3201f3e569fe0afe6f9b03c00ee3225\n'
    '|$|> '
[DEBUG] Sent 0x17 bytes:
    'aaa<|>tag 123456789012\n'
[DEBUG] Received 0x26 bytes:
    '376e6623acc5dd72fbd0f4ef49e528d1\n'
    '|$|> '
[DEBUG] Sent 0x30 bytes:
    'decc143cfdc8d03167ae9e91afbd4133<|>cat flag.txt\n'
[-] Receiving all data: Failed
[DEBUG] Received 0x2b bytes:
    'PCTF{fmac_is_busted_use_PMAC_instead}\n'
    '|$|> '
フラグは、
PCTF{fmac_is_busted_use_PMAC_instead}
です。



STEM CTF: Cyber Challenge 2018 writeup Keyboard Shuffle

Keyboard Shuffle

Time Remaining: 0d 10h 48m 57s

Crypto - 100 points

Description

To the right, to the right, to the right, to the right To the left, to the left, to the left, to the left, to the left?

Ut awwna U;n cwrt vS r rtoubfm rgBJAB DIE VWUBF AI YBSWEARndubf BTQt~ nxPRTOUBF)UA)ooEWBRKT)Ges{

Keyboard Shift Cipherというものがあります。問題文の右・右・右・右・左・左・左・左・左より、左に1つずらすことが予想できます。
Ut awwna U;n cwrt vS r rtoubfm rgBJAB DIE VWUBF AI YBSWEARndubf BTQt~ nxPRTOUBF)UA)ooEWBRKT)Ges{
このサイトで上記暗号文を復号してみます。
Iy seems I'm vety bD t typing, thNKSN FOR BEING SO UNDERSTmfing NYWy mc{TYPING_IS_ppRENTLY_Hrd}
フラグの形式はMCA{}であるため、aが欠けています。また、HrdはHardであることが予想できます。ppRENTLYはGoogle翻訳によるとappaRENTLYであると教えてくれます。
フラグは、
MCA{TYPING_IS_appaRENTLY_Hard}
です。

STEM CTF: Cyber Challenge 2018 writeup It's all in the past now

It's all in the past now

Time Remaining: 0d 17h 2m 59s

Linux - 100 points

Description

There is a flag stored in /flag.txt but only root can read it. Figure out how to get root access to read the flag.

To connect: ssh ctf@138.247.115.163

sshコマンドでサーバに接続します。
$ ssh ctf@138.247.115.163
The authenticity of host '138.247.115.163 (138.247.115.163)' can't be established.
ECDSA key fingerprint is SHA256:AqYttsPq7Wf9h94q8PvDF3x00Tjpleg3C9yHm6ivwPA.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '138.247.115.163' (ECDSA) to the list of known hosts.
lsコマンドでファイルの一覧を確認します。
ctf@e73e8745b012:~$ ls -al
total 24
drwxr-xr-x 2 ctf  ctf  4096 Apr  4 21:00 .
drwxr-xr-x 6 root root 4096 Apr  4 21:00 ..
-rw-rw-r-- 1 ctf  ctf   702 Dec 22 00:38 .bash_history
-rw-r--r-- 1 ctf  ctf   220 Aug 31  2015 .bash_logout
-rw-r--r-- 1 ctf  ctf  3771 Aug 31  2015 .bashrc
-rw-r--r-- 1 ctf  ctf   655 May 16  2017 .profile
-rw-r--r-- 1 ctf  ctf     0 Apr  4 21:00 .sudo_as_admin_successful
lsコマンドでルートディレクトリのファイル一覧を確認します。
ctf@e73e8745b012:~$ ls -al / 
total 76
drwxr-xr-x  60 root root 4096 Apr 21 02:09 .
drwxr-xr-x  60 root root 4096 Apr 21 02:09 ..
-rwxr-xr-x   1 root root    0 Apr 21 02:09 .dockerenv
drwxr-xr-x   2 root root 4096 Feb 28 19:14 bin
drwxr-xr-x   2 root root 4096 Apr 12  2016 boot
drwxr-xr-x   5 root root  340 Apr 21 02:09 dev
drwxr-xr-x  72 root root 4096 Apr 21 02:09 etc
----------   1 root root   21 Apr  4 20:59 flag.txt
drwxr-xr-x   6 root root 4096 Apr  4 21:00 home
drwxr-xr-x  10 root root 4096 Apr  4 20:59 lib
drwxr-xr-x   2 root root 4096 Feb 28 19:14 lib64
drwxr-xr-x   2 root root 4096 Feb 28 19:13 media
drwxr-xr-x   2 root root 4096 Feb 28 19:13 mnt
drwxr-xr-x   2 root root 4096 Feb 28 19:13 opt
dr-xr-xr-x 520 root root    0 Apr 21 02:09 proc
drwx------   2 root root 4096 Feb 28 19:14 root
drwxr-xr-x   7 root root 4096 Apr 21 02:09 run
drwxr-xr-x   2 root root 4096 Mar  6 22:17 sbin
drwxr-xr-x   2 root root 4096 Feb 28 19:13 srv
dr-xr-xr-x  13 root root    0 Apr 20 19:05 sys
drwxrwxrwt   2 root root 4096 Apr  4 20:59 tmp
drwxr-xr-x  21 root root 4096 Apr  4 21:00 usr
drwxr-xr-x  21 root root 4096 Apr 21 02:09 var
flag.txtファイルがあります。アクセス権がないので中身を読むことはできません。
ctf@e73e8745b012:~$ cat /flag.txt
cat: /flag.txt: Permission denied
.bash_historyファイルを見てみます。sudoコマンドをタイプミスしてパスワードが記録されています。
ctf@e73e8745b012:~$ cat .bash_history 
vim myscript.sh
vi myscript.sh
sudo apt install vim-tiny
sudo apt install update
sudo apt update
sudo apt install vim-tiny
ls
vi myscript.sh
./myscript.sh
chmod +x myscript.sh
vi myscript.sh
./myscript.sh
vi myscript.sh
./myscript.sh
vi myscript.sh
./myscript.sh
vi myscript.sh
./myscript.sh
vi myscript.sh
./myscript.sh
ls
cat myscript.sh
sh ./myscript.sh
vi myscript.sh
./myscript.sh
vi myscript.sh
./myscript.sh
vi myscript.sh
./myscript.sh
vi myscript.sh
./myscript.sh
bash -x ./myscript.sh
rm myscript.sh
sudo ./myscript.sh
vi myscript.sh
sufo ./myscript.sh
tomatosoup
sudo ./myscript.sh
vi mycrypt.sh
sudo ./myscript.sh
vi mycrypt.sh
sudo ./myscript.sh
vi mycrypt.sh
./myscript.sh
rm myscript.sh
sudoでcatコマンドを実行します。パスワードにはtomatosoupと入力します。
ctf@e73e8745b012:~$ sudo cat /flag.txt
[sudo] password for ctf: 
MCA{shooJ5aeshaiw4y}
フラグは、
MCA{shooJ5aeshaiw4y}
です。

新しいLinuxの教科書
大角 祐介
SBクリエイティブ
2015-06-06


STEM CTF: Cyber Challenge 2018 writeup "Express" Checkout

"Express" Checkout

Time Remaining: 0d 16h 28m 52s

Web - 50 points

Description

It took a lot of courage but our great team accomplished the unthinkable. We are happy to announce a fantastic new express checkout experience. Our customers are going to love it! This new workflow has your items delivered to someone else in no time flat!

提示されたリンクをクリックすると次のページが表示されます。

1

Home Pageのリンクをクリックします。次のページが表示されます。

2

Products hereのリンクをクリックすると、次のようなページが表示されます。

3

customers hereのリンクをクリックすると、次のようなページが表示されます。ページをリロードするとリストの内容が変わります。

4

customersのリストのgrassyKnollを表示すると次のようなページが表示されます。

5

このメールアドレスをProductsのリストのDandelionsのページのEmail欄に入力しSubmitします。

6

次のようにフラグが表示されます。

7

フラグは、
MCA{aCzb163wL9}
です。



STEM CTF: Cyber Challenge 2018 writeup CTF Jams

CTF Jams

Time Remaining: 0d 3h 42m 17s

Grab Bag - 150 points

Description

The white cell loves to discover and share new music. Check out our new compilation album! We put a lot of work into the album art.

ダウンロードしたmp3ファイルをmp3tagで開きます。カバー画像を右クリックして[カバーをコピー]しファイルに保存します。カバー画像にフラグが記載されています。

1

フラグは、
MCA{songname?_the_ting_goes_vitas}
です。



STEM CTF: Cyber Challenge 2018 writeup Back to the Future

Back to the Future

Time Remaining: 0d 17h 51m 38s

Linux - 100 points

Description

Get in the pipe Marty! We gotta get all the way to Bendigo! We gotta get me keys back!

To connect: nc 138.247.115.174 1337

指定されたサーバに接続してみます。Hello!とだけ表示されて切断されます。
$ nc 138.247.115.174 1337
Hello!
今度はWiresharkでパケットキャプチャしながらサーバに接続します。次のように応答の中にフラグがありました。

1

フラグは、
MCA{dohCe9DouHeeHoa}
です。

パケットキャプチャの教科書 (Informatics&amp;IDEA)
みやた ひろし
SBクリエイティブ
2017-10-14


STEM CTF: Cyber Challenge 2018 writeup Adverse Reaction

Adverse Reaction

Time Remaining: 0d 4h 5m 0s

Web - 100 points

Description

We see you’re running an ad-blocker. To view this content consider opening yourself up to malware. You can also subscribe for $9.99/month and still receive ads!

提示されたリンクをクリックすると次のようなページが表示されます。

1

Cookieを確認するとフラグがあります。

2

フラグは、
MCA{Ads_Supp0rt_webSit3z_MON$Y}
です。

Google AdSense 成功の法則 57
染谷 昌利
ソーテック社
2014-07-19


ASIS CTF Quals 2018 writeup Welcome

提示されたリンクはTwitterへのリンクです。次のツイートにフラグが記載されています。
フラグは、
ASIS{Welcome_to_ASISCTF_Let's_increase_the_world's_entropy}
です。



ASIS CTF Quals 2018 writeup Warm up

提示されたファイルを解凍すると次のようなCソースファイルができます。
#define M 37
#define q (2+M/M)
#define v (q/q)
#define ef ((v+q)/2)
#define f (q-v-ef)
#define k (8-ef)
struct b{int64_t y[13];}S;int m=1811939329,N=1,t[1<<26]={2},a,*p,i,e=73421233,s,c,U=1;g(d,h){for(i=s;i<1<<25;i*=2)d=d*1LL*d%m;for(p=t;p<t+N;p+=s)for(i=s,c=1;i;i--)a=p[s]*(h?c:1LL)%m,p[s]=(m*1U+*p-a)*(h?1LL:c)%m,*p=(a*1U+*p)%m,p++,c=c*1LL*d%m;}l(){while(e/=2){N*=2;U=U*1LL*(m+1)/2%m;for(s=N;s/=2;)g(136,0);for(p=t;p<t+N;p++)*p=*p*1LL**p%m*U%m;for(s=1;s<N;s*=2)g(839354248,1);for(a=0,p=t;p<t+N;)a+=*p<<(e&1),*p++=a%10,a/=10;}}z(n){int y=3,j,c;for(j=2;j<=n;){l();for(c=2;c<=y-1;c++){l();if(y%c==0)break;}if(c==y){l();j++;}y++;}l();return y-1;}main(a, pq) char* pq;{int b=sizeof(S),y=b,j=M;l();int x[M]={b-M-sizeof((short int) a),(b>>v)+(k<<v)+ (v<<(q|ef)) + z(v+(ef<<v)),(z(k*ef)<<v)-pow(ef,f), z(( (j-ef*k)|(ef<<k>>v)/k-ef<<v)-ef),(((y+M)&b)<<(k/q+ef))-z(ef+v),((ef<<k)-v)&y,y*v+v,(ef<<(q*ef-v-(k>>ef)))*q-v,(f<<q)|(ef<<(q*f+k))-j+k,(z(z(z(z(z(v)))))*q)&(((j/q)-(ef<<v))<<q)|(j+(q|(ef<<v))),y|(q+v),(ef<<ef)-v+ef*(((j>>ef)|j)-v+ef-q+v),(z(j&(b<<ef))&(z(v<<v)<<k))-(q<<v)-q,(k<<q)+q,(z(y)>>(ef<<v))+(z(k+v))-q,(z(z(k&ef|j))&b|ef|v<<f<<q<<v&ef>>k|q<<ef<<v|k|q)+z(v<<v)+v,(ef>>v)*q*z(k-v)+z(ef<<ef&q|k)+ef,z(k<<k)&v&k|y+k-v,z(f>>ef|k>>ef|v|k)*(ef>>v)*q,(ef<<k-ef<<v>>q<<ef*ef)-j+(ef<<v),z(ef*k)*z(v<<v)+k-v,z((z(k)<<z(v)))&y|k|v,z(ef<<ef<<v<<v)/ef+z(v<<ef|k|(b>>q)&y-f)-(ef<<q)+(k-v)-ef,k<<(ef+q)/z(ef)*z(q)&z(k<<k)|v,((z(y|j>>k*ef))%ef<<z(v<<v<<v)>>q<<q|j)/ef+v,(j-ef<<ef<<v*z(v>>v<<v)>>ef)/ef%z(k<<j)+q,z(k-v)+k|z(ef<<k>>v<<f)-z(q<<q)*ef>>v,(z(ef|y&j|k)%q|j+ef<<z(k|ef)%k<<q|ef|k<<ef<<q/ef|y/ef+j>>q)&k<<j|ef+v,84,z(v*ef<<ef<<q)*q%ef<<k|k|q-v,((z(20)*v)|(f>>q)|(k<<k))/ef-(ef<<(v*q+ef))-(k<<q)+z(k)-q};while(j--){putchar(x[M-v-j]);}printf(" From ASIS With Love <3\n");return 0;}
ファイルの冒頭に以下のincludeを追加して、ファイル名をwarmup.cに変更します。
#include <stdint.h>
#include <stdio.h>
gccでコンパイルします。
$ gcc warmup.c
できた実行ファイルを実行します。少し時間がかかりますが次のように結果が出力されます。
$ ./a.out
ASIS{hi_all_w31c0m3_to_ASISCTF} From ASIS With Love <3
フラグは、
ASIS{hi_all_w31c0m3_to_ASISCTF}
です。

苦しんで覚えるC言語
MMGames
秀和システム
2011-06-24


ASIS CTF Quals 2018 writeup The Early School

提示されたファイルを解凍すると、暗号化されたファイルと次のようなPythonのソースファイルができます。
#!/usr/bin/python

from Crypto.Util.number import *
from flag import FLAG, round

def encrypt(msg):
    assert set(msg) == set(['0', '1'])
    enc = [msg[i:i+2] + str(int(msg[i]) ^ int(msg[min(i+1, len(msg)-1)])) for i in range(0, len(msg), 2)]
    return ''.join(enc)

ENC = bin(bytes_to_long(FLAG))[2:]

for _ in xrange(round):
    ENC = encrypt(ENC)

fp = open('FLAG.enc', 'w')
fp.write(long_to_bytes(int(ENC, 2)))
fp.close()
このPythonプログラムの処理の内容は次のようなものです。
  1. FLAG文字列を2進数の文字コードで表す。
  2. それをencrypt関数に渡して暗号化する操作をround回行う。
  3. encrypt関数では渡された2進文字列を先頭から2文字ずつ処理を行う。
  4. その2文字を1文字に分けてそのXORを取った結果を連結して3文字の文字列にする。
  5. 2文字ずつ処理を行う際、最後に1文字だけ残った場合はその1文字どおしのXORを取った結果(つまり0)を連結した2文字になる。
  6. それらを連結した結果をencrypt関数の戻り値とする。
具体的な例で確認すると、元のデータが'A'という文字列とすると、まず2進数文字列で表した1000001
をencrypt関数に渡します。2文字ずつ処理するので、10 00 00 1に分割して処理します。XORを取った結果を付加するので、101 000 000 10になります。

したがって、この暗号を復号するdecrypt関数は、次のような処理になります。
  1. 2進文字列を3文字ずつ区切って処理をする。
  2. 3文字目は不要なので切り捨てて2文字だけを残す。
  3. 最後が2文字になったときは、2文字目は不要で、1文字目だけ残す。
  4. 残したものを連結したものが復号結果となる。
roundの値は分からないので、decryptを繰り返し、先頭がフラグ形式のA=1000001になった時点でデータを表示するようにしてみます。
#!/usr/bin/python

from Crypto.Util.number import *

def decrypt(enc):
    msg = [enc[i:min(i+2, len(enc)-1)] for i in range(0, len(enc), 3)]
    return ''.join(msg)

fp = open('FLAG.enc', 'r')
FLAG = fp.read()
fp.close()

ENC = bin(bytes_to_long(FLAG))[2:]

i = 1
while True:
    ENC = decrypt(ENC)
    print(i)
    if ENC.startswith('1000001'):
        print(long_to_bytes(int(ENC, 2)))
        break
    i += 1
実行すると次のような結果となります。
$ python2 bbb.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ASIS{50_S1mPl3_CryptO__4__warmup____}
19回繰り返したところでフラグを得ることができました。
フラグは、
ASIS{50_S1mPl3_CryptO__4__warmup____}
です。



記事検索
ギャラリー
  • TetCTF 2023 NewYearBot
  • UUT CTF writeup Find The Password
  • UUT CTF writeup The Puzzle
  • Hack Zone Tunisia 2019 writeup Microscope
  • Hack Zone Tunisia 2019 writeup Welcome
  • SwampCTF 2019 writeup Brokerboard
  • SwampCTF 2019 writeup Leap of Faith
  • SwampCTF 2019 writeup Last Transmission
  • CBM CTF 2019 writeup Long road
カテゴリー