insecureとしてTSG CTFに出ていました。868点で18位でした。難しくて実力不足を感じました。泣いた。
- [Forensics 92 + 178 pts (90 + 61)Solves] Obliterated File & Obliterated File Again
- [Crypto 497pts (10 Solves)] OPQRX
[Forensics 92 + 178 pts (90 + 61)Solves] Obliterated File & Obliterated File Again
※ This problem has unintended solution, fixed as "Obliterated File Again". Original problem statement is below.
Working on making a problem of TSG CTF, I noticed that I have staged and committed the flag file by mistake before I knew it. I googled and found the following commands, so I'm not sure but anyway typed them. It should be ok, right?
※ この問題は非想定な解法があり,"Obliterated File Again" で修正されました.元の問題文は以下の通りです.
TSG CTFに向けて問題を作っていたんですが,いつの間にか誤ってflagのファイルをコミットしていたことに気付いた!とにかく,Google先生にお伺いして次のようなコマンドを打ちこみました.よくわからないけどこれできっと大丈夫...?
$ git filter-branch --index-filter "git rm -f --ignore-unmatch problem/flag" --prune-empty -- --all $ git reflog expire --expire=now --all $ git gc --aggressive --prune=now
Difficulty Estimate: easy
I realized that the previous command had a mistake. It should be right this time...?
さっきのコマンドには間違いがあったことに気づきました.これで今度こそ本当に,本当に大丈夫なはず......?
$ git filter-branch --index-filter "git rm -f --ignore-unmatch *flag" --prune-empty -- --all $ git reflog expire --expire=now --all $ git gc --aggressive --prune=now
Difficulty Estimate: easy - medium
要するにgitで丁寧に削除したファイルを復元してみろという問題です。
1個目は
[https://stackoverflow.com/a/6018043:title]
を見てこれで探してみると、削除漏れらしきコミットが見えるので、その一つ前のコミットにcheckoutして中身を覗きました。zlib compressedなデータの読み方をPHP以外に知らないので、gzuncompressed
を使いました。
$ git log --diff-filter=D --summary commit 266f4148e4cf37bdbfb57da379ea49b2f106e6b2 (HEAD -> master) Author: tsgctf <info@tsg.ne.jp> Date: Fri May 3 04:33:22 2019 +0900 delete .travis.yml delete mode 100644 .travis.yml commit 28d2b74b0c40583a87cf275f9f0cdfd55042884d Author: tsgctf <info@tsg.ne.jp> Date: Thu May 2 05:45:41 2019 +0900 add problem statement delete mode 100644 flag
php -a Interactive mode enabled php > $a = file_get_contents("flag"); php > echo gzuncompress($a); TSGCTF{$_git_update-ref_-d_refs/original/refs/heads/master}
2問目はコマンドが少し変わって、1問目と同じ解き方ができなくなっています。最早 .git
以下のオブジェクトを全部見て回るしか無いと思ってそういう手段を探すと
git show - Git - how to list ALL objects in the database - Stack Overflow を見つけたのでやりました。
user@box:~/TSGCTF/obliterated_file_again/easy_web$ { > git rev-list --objects --all > git rev-list --objects -g --no-walk --all > git rev-list --objects --no-walk \ > $(git fsck --unreachable | > grep '^unreachable commit' | > cut -d' ' -f3) > } | sort | uniq | grep flag Checking object directories: 100% (256/256), done. Checking objects: 100% (101/101), done. c1e375244c834c08d537d564e2763a7b92d5f9a8 problem/flag user@box:~/TSGCTF/obliterated_file_again/easy_web$ git cat-file -p c1e375244c834c08d537d564e2763a7b92d5f9a8 > flag user@box:~/TSGCTF/obliterated_file_again/easy_web$ php -a Interactive mode enabled php > echo gzuncompress(file_get_contents("flag")); TSGCTF{$_git_update-ref_-d_refs/original/refs/heads/master_S0rry_f0r_m4king_4_m1st4k3_0n_th1s_pr0bl3m}
[Crypto 497pts (10 Solves)] OPQRX
Can you decrypt RSA? I'll give a hint value, XOR.
ここにRSAの暗号文がありますが、XORをあげるので、代わりに平文をください。
Difficulty Estimate: Easy
単純なRSAですが、 N, C, E に加えて X = P xor Q
としたXも与えられています。次のようなスクリプトで上位bitから候補を絞っていきました。少し待つとP, Qが得られます。p, qは順不同なのでそれをやると探索範囲が半分になりますね。今気が付きました。
exec(open("flag.enc").read()) K = 1 << 4095 kouhos = [[0, 0]] count = 4095 while K > 0: next_kouho = set() for kouho in kouhos: P, Q = kouho p = P | K q = Q | K if X & K: if p * Q <= N: next_kouho.add((p, Q)) if P * q <= N: next_kouho.add((P, q)) else: if p * q <= N: next_kouho.add((p, q)) else: next_kouho.add((P, Q)) assert len(next_kouho) > 0 kouhos = [] for n in next_kouho: P, Q = n p = P | (K - 1) q = Q | (K - 1) if p * q >= N and P * Q <= N: kouhos.append(n) print(count, len(kouhos)) count -= 1 K >>= 1 print(kouhos)
あとはやるだけです。
exec(open("primes").read()) exec(open("flag.enc").read()) from Crypto.Util.number import * print(len(primes)) for prime in primes: p, q = prime phi = (p - 1) * (q - 1) d = inverse(E, phi) m = pow(C, d, N) print(long_to_bytes(m))
フラグは TSGCTF{Absolutely, X should be 'S' in 'OPQRX'.}
でした。