HITCON CTF 2016 Finals参加記

この記事はCTF Advent Calendarの4日目です.

まだ欠けているところがあるのでとりあえず速報版ということで…
12/07: 残りの写真などを貼りました.

12/2-12/3の2日間,台湾にてHITCON CTF 2016の決勝戦が開催され,TokyoWesternsとして参加してきました.
今回の遠征において起こったことを時系列順に書いていきます.

飛行機の遅延

我々は当初11:45に成田を出る飛行機に乗る予定だったのですが,前日の夜22時頃に突然メールが来て,

Flight Delay Notification

11:45発予定が19:00に変更?????
このままだと台湾につくのは22時過ぎ(現地時刻)になり,移動が極めて面倒なことになりそう,という結論に.
とりあえず問い合わせて,払い戻しが可能かどうかを聞くことにしました.(時間帯的に窓口が英語しか対応してなくて,非常にしんどかった)

どうやら払い戻しは可能っぽいので,実際に手続きをするのは翌朝に日本語の窓口が対応しているときにしよう,ということで急遽別の飛行機を予約するという話になりました (この時点で夜中の1時を過ぎており,寝落ちした→他の人より航空券が少し高くついた).

まあなんやかんやで無事に飛行機に乗れたので良しということで.

台湾着

台湾に着いて適当にSIMカードを購入したりして,ホテルまでのルートを調べました.
今回運営が用意してくれたホテルは結構良い所らしく,なんと空港からバス一本でたどり着くことができて感動しました.
ちなみにバスの券を販売しているところのPCにXPが写っていたり,発券された乗車券の時刻がクソ適当だったりといろいろ怪しい点は多かったものの,特にトラブルもなくホテルまで着き,先に来ていたhhc0nullと合流してすき家で食事を取りました.

f:id:icchyr:20161207230733j:plain:w200 f:id:icchyr:20161207230634j:plain:w300

あとLTEがクソ早くて感動した

f:id:icchyr:20161207230510p:plain

会場

今年のFinalsはHITCON Pacificと同時開催らしくて,Taipei New Horizonという所の最上階でした. f:id:icchyr:20161207230916j:plain

f:id:icchyr:20161207231020j:plain

f:id:icchyr:20161207231047j:plain

設営もめちゃくちゃ手が込んでいて,各チームのテーブルには看板が設置してありました.

f:id:icchyr:20161207231235j:plain:w300

…? 何か足りないですね…

ところでこれは某CTFの名札です

f:id:icchyr:20161207231815j:plain:w300

今年はチーム名を間違えられる呪いにでもかけられたんでしょうか.

Finals

去年に続き素晴らしい大会で,今年のA&DはPwnable3問,Web3問でした. 競技はday1 10:00 ~ 18:00, day2 8:30 ~ 15:30で,day2の12:30までは1ラウンド5min, それ以降は1ラウンド2minという設定でした. Pwnable問題は公開されてからは最後まで動いていて,Web問題は各問題が別々の時間に公開されて2つ以上の問題が同時に動くことはありませんでした.そのかわりWeb問題にはfirst bloodがあり,1500, 1000, 500, 300, 100という具合に解いた順にボーナスポイントが与えられました.

問題 時間 ジャンル 概要
digimon day1 10:00 ~ pwnable デジモンをモチーフにしたゲーム.ショップの番号に制限が無くて任意メモリの書き換えが可能(らしい)
rabbit day1 10:00 ~ 14:00 web zabbixが動いている./jsrpc.phpSQL injectionの脆弱性があり,Adminのセッションを奪うことができる.Adminはzabbixの機能でスクリプト実行が可能なのでflagを読む.
criticalheap_revenge day1 14:00(?) ~ pwnable よく読んでないけどFSBがあったらしい
webrop day1 14:00 ~ day2 12:30 web SugarCRMとphpMyAdminが置いてあるだけ.詳しくは後述します.
fx-1337 day2 9:30 ~ pwnable 電卓を模したアプリケーション.BackSpaceの回数に制限が無くて任意のアドレスにジャンプすることのできる脆弱性があった(らしい)
myide day2 12:30 ~ web flask製のテキスト共有システム.詳しくは後述.

僕がメインで取り組んでいたのはWebの3問で,前半2問(rabbit, webrop)はいずれも実際に使われているソフトウェアを用いており,オイオイ0dayゲーか〜???と思いましたが,3問目はお手製のflaskアプリでした. 実際にはrabbit, webropはCVEの付いている脆弱性を抱えており,それを用いて攻撃が可能,というものでした.

webrop

phpMyAdminとSugarCRMが置かれているが,phpMyAdminの指しているホストが126.0.0.1と128.0.0.1のみ選べるため,全く意味ない.ように見える.SugarCRMは普通の設定で,適当なユーザーでのログインはできる状態. この問題は1日目は全く動きが見られず,2日目に持ち越されたため結局first bloodは無効になりました. 我々のチームではytokuさんが一日目の夜に0dayの脆弱性を発見し,それを用いてexploitを作成していったところうまく刺さりました(もちろん数チームには途中から対策されました). 他にも0dayを見つけたチームがいて,CTFerの恐ろしさを見せつけられました. ちなみに競技終了後に運営に想定解を聞いたのですが,phpMyAdmin脆弱性によってセッションの上書きが可能であり,それを用いてSugarCRMで権限昇格を行う,というものだったそうです.PPPはこの方法で攻撃したそうです. 途中までは全部のチームからflagを取れていたのですが,PPPはログインをできなくしたせいで攻撃が刺さらなくなったにも関わらずSLAはALIVEになっていて,なるほど. 去年はSLAがクソ厳しかった上に,事前のルール説明に「脆弱性部分以外のパッチで防ぐのはやめろ」みたいなことが書いてあったため,どのチームも割とパッチに苦労してたと思うのですが… 結果的には結構な点を取れたと思います.

myide

flask製のアプリケーションで,一番最初に用いられた脆弱性はpath traversalでした.普通に任意ファイルを読むことができる感じ. テンプレートエンジンにjinja2を使っていたので案の定template injectionがあり,任意コードの実行が可能でした.ただしこの問題のみ,ソースコードに対するパッチが当てられなかった(当てても再起動する手段が無かった)ため,終わりの方はDOSの打ち合いという地獄絵図が広がっていました.

結果

最終結果はCykor, LC/BC, PPP, Shellphishに続いて5位でした!!!

決勝のA&Dでは今までの中で一番良い結果を残せたと思います.

余談

終了後の会場に良い話が転がっていました.

f:id:icchyr:20161207232458j:plain

終わりに

クソ適当な記事ですみませんでした.CTF Advent Calendarにはまだまだ空きがあるので是非書きましょう.
明日はyamaguchiさんのTSGCTFwriteupです.

El Capitanでtsocksを使う

コマンドを実行するとき,必ずSOCKSプロキシを通るようにするためのツールtsocksというものがあって,Linuxではもちろん,OSX Mavericksでも動くのでよく使っていました.

ところが,先日El Capitanにアップデートした途端動かなくなり,いろいろ調べてるうちに解決したのでそのメモ.

OSXでのインストール方法

標準のhomebrewには含まれておらず,homebrew用のスクリプトを用意してやる必要があります.

norisu0313.hatenablog.com

ここを参考に,

github.com

に含まれているスクリプト/usr/local/Library/Formula/に配置します.

~$ cat -> /usr/local/Library/Formula/tsocks.rb
require 'formula'

class Tsocks < Formula
  # The original is http://tsocks.sourceforge.net/
  # This GitHub repo is a maintained fork with OSX support
  homepage 'http://github.com/pc/tsocks'
  head 'https://github.com/pc/tsocks.git'

  depends_on 'autoconf' => :build if MacOS.xcode_version.to_f >= 4.3

  def install
    system "autoconf", "-v"
    system "./configure", "--prefix=#{prefix}", "--disable-debug", "--disable-dependency-tracking", "--with-conf=#{config_file}"

    inreplace("tsocks") { |bin| bin.change_make_var! "LIBDIR", lib }

    system "make"
    system "make install"

    etc.install "tsocks.conf.simple.example" => "tsocks.conf" unless config_file.exist?
  end

  def test
    puts 'Your current public ip is:'
    ohai `curl -sS ifconfig.me 2>&1`.chomp
    puts "If your correctly configured #{config_file}, this should show the ip you have trough the proxy"
    puts 'Your ip through the proxy is:'
    ohai `tsocks curl -sS ifconfig.me 2>&1`.chomp
  end

  def config_file
    etc / 'tsocks.conf'
  end
end
[EOF]
~$

tsocksのしくみ

tsocksのソースコードを読むとわかるのですが,ライブラリ関数のフックを用いてこの機能を実現しています.LinuxならLD_PRELOAD, OSXならDYLD_INSERT_LIBRARIESおよびDYLD_FORCE_FLAT_NAMESPACEといった具合です.tsocks本体のスクリプト環境変数に共有ライブラリを追加するためのラッパーで,実際には生成されたlibtsocksというライブラリが仕事をしています.

El Capitanでの問題

どうやらSystem Integrity Protection (SIP) が悪さ (セキュリティ的には良い挙動ですが) をしているらしく,DYLD_INSERT_LIBRARIESによるフックが無効化されていました.
SIPの無効化はリカバリーモードでcsrutil disableとか打つと良いのですが,影響を及ぼさないシステム保護まで解除してしまうため,必要なものだけを無効化します.

~$ csrutil disable
~$ csrutil enable --without debug

これによってApple InternalDebugging Restrictionsのみが無効化され,fsなどの保護は生きたままになります.

~$ csrutil status
System Integrity Protection status: enabled (Custom Configuration).

Configuration:
    Apple Internal: disabled
    Kext Signing: enabled
    Filesystem Protections: enabled
    Debugging Restrictions: disabled
    DTrace Restrictions: enabled
    NVRAM Protections: enabled

This is an unsupported configuration, likely to break in the future and leave your machine in an unknown state.

これでtsocksが使えるようになります.

~$ ssh -fND 1080 home
~$ tsocks curl 192.168.1.X

Linuxでunzipすると文字化けする

今年度が始まるちょっと前くらいに新しくバイトを始め,楽しくやっています.どこでバイトしているかは言えないので察していただきたいのですが,毎日楽しく業務をこなしています.
業務中に得られた小さな知見を公開できる範囲で共有したいと思います.

タイトル通り,Windowsで作成したzipファイルをそのままunzipすると悲惨なことになります.現在のディレクトリに展開された場合は削除するのも面倒です.
このような悲劇を生まないために,unzip -O cp932 hoge.zipしましょう.

rncc夏期講習に参加してきました

id:kkrntと相談しながら日取りを決め,FMSのNCCさんと東京農工大のMCCとで夏期講習を開催しました.
本当はMCCから4人くらい話す予定だったのですが,なんと僕のみの参加となってしまいました
ちなみにrnccというのは"r"と"n"が並ぶと"m"っぽく見えるのが由来です.

話したこと

皆にシェルの楽しさを知ってもらいたく,「シェル芸初心者によるシェル芸入門」というタイトルで発表をしました.
僕は趣味でシェル遊びをしているので,シェル芸人ではありません.

www.slideshare.net

他の人が話した内容

詳しいことはNCCの記事を見て下さい.

ncc.hateblo.jp

個人的にはES2015(ES6)に触れたのが面白かったです.npm便利.
あとchainerちょっと遊んでみたいと思いました.とりあえずpip install chainerしたので適当にやってみます

~/.ssh/config をカスタマイズする

半年前くらいから~/.ssh/configを使い始めました.
今のところ使っていて便利だなと思った機能を紹介します.

ホスト情報

example.comにuserで秘密鍵~/.ssh/id_rsa_exampleを使って接続するとき,毎回

ssh user@example.com -p 22 -i ~/.ssh/id_rsa_example

と書くのは面倒です. ここで~/.ssh/config

Host example
    HostName example.com
    User user
    Port 22
    IdentityFile ~/.ssh/id_rsa_example

と書くと

ssh example

で簡単に接続できるようになります.

多段ssh

ホスト情報が省略できるだけでも十分便利なのですが,例えば家の環境に接続したいときは外向けに解放しているゲートウェイサーバーを経由して接続しなければなりません.
しかしいちいちゲートウェイサーバーにsshしてからローカルマシンにsshするのは手間がかかります. そこで

Host home
    HostName 192.168.10.10
    User user
    Port 22
    IdentityFile ~/.ssh/id_rsa_home
    ProxyCommand ssh -W %h:%p gateway   # %h -> host, %p -> port

Host gateway
    HostName home.net
    User user
    Port 2222
    IdentityFile ~/.ssh/id_rsa_gateway

という風に書いてやると,ssh homegatewayホスト経由でローカルネットワークの192.168.10.10に接続してくれます.

2段以上のときも,

Host home_1
    HostName 192.168.10.11
    User user
    Port 22
    IdentityFile ~/.ssh/id_rsa_home_1
    ProxyCommand ssh -W %h:%p gateway

Host home_2
    HostName 192.168.10.12
    User user
    Port 22
    IdentityFile ~/.ssh/id_rsa_home_2
    ProxyCommand ssh -W %h:%p home_1

という具合に書けばremote -> gateway -> home_1 -> home_2のような接続が ssh home_2 を叩くだけで行えます.

ワイルドカード

家にマシンが増えてくると,各々のマシンに対してリモートから接続するための設定と家のネットワークから直接接続する設定を書く必要が出てきます.

Host home_1
    HostName 192.168.10.11
    User user
    Port 22
    IdentityFile ~/.ssh/id_rsa_home_1
    ProxyCommand ssh -W %h:%p gateway

Host home_1_local
    HostName 192.168.10.11
    User user
    Port 22
    IdentityFile ~/.ssh/id_rsa_home_1

Host home_2
    HostName 192.168.10.12
    User user
    Port 22
    IdentityFile ~/.ssh/id_rsa_home_2
    ProxyCommand ssh -W %h:%p gateway

Host home_2_local
    HostName 192.168.10.12
    User user
    Port 22
    IdentityFile ~/.ssh/id_rsa_home_2

.
.
.

という具合にリモート用とローカル用で分けても良いのですが,同じ記述が複数回出てくるのはちょっと不格好です.

~/.ssh/configのHostにはワイルドカードを指定することができて,これにマッチしたHostに適用されます. 例えば,

Host *_via_home
    ProxyCommand ssh -W %h:%p gateway

と書くとssh ~~~~_via_homeは必ずgateway経由で接続されます.
これを利用して,

Host home_1*                 # 末尾に*を付けないとマッチしません
    HostName 192.168.10.11
    User user
    Port 22
    IdentityFile ~/.ssh/id_rsa_home_1

Host home_2*
    HostName 192.168.10.12
    User user
    Port 22
    IdentityFile ~/.ssh/id_rsa_home_2

Host *_via_home
    ProxyCommand ssh -W %h:%p gateway

と書いておくと
ローカル: ssh home_1
リモート: ssh home_1_via_home
とするだけで簡単に入れるようになります.(ただしsshコマンドのホスト補完が効かなくなります)

多段SSHの場合

どうやらうまく動かないようです.

Host *via_home_0*
    ProxyCommand ssh -W %h:%p gateway

Host *via_home_1*
    ProxyCommand ssh -W %h:%p home_1

と書いておいて

ssh home_2_via_home_1_via_home_0

remote -> gateway -> home_1 -> home_2な接続ができるかと思ったのですが,home_2_via_home_1までの時点でssh -W 192.168.10.12:22 home_1が実行されているためvia_home_0部分が完全に無視されています.
多段SSHの時はおとなしく書いたほうが良さそうです…(もしどなたか知見ありましたら教えて下さい)

ICPC 国内予選 2014

参加してきました.

一時期台風でどうなることかとヒヤヒヤさせられましたが,特に問題もありませんでした.僕のチームは

  • @osrehun
  • @xthexworldx
  • @icchyr

の3名でした.

~16:30

3限終了後に集合.特にすることもないので適当に時間をつぶしていると監督とコーチが到着する.
プリンターのセッティングをしてテンプレート等を印刷したがまだ時間が余っている.

僕,何を思ったかこれをやろうと言い出す.特に意味はない. そんなこんなで国内予選開始の時間となる.

本番開始

まずは僕(@icchyr)が初期設定をして,そのあとにA問を解いている間に二人がB問以降の方針を固めるという作戦.

16:30~17:00

A問を見る.

「何だ逆算するだけか」

コーディングが終わる.サンプルが通らない.

「ただの誤差っぽい」

修正する.通らない.まだ焦る時間じゃない.

17:00~17:30

さすがに危機感を感じたのか,@osrehunがペアプロに移る.
ただの全探索だった・・・

残りの問題に取り掛かる.B・Cは方針が立っていて,D問をとりあえず見る.
A問で「全探索」というワードが頭に染みついていたので一瞬で全探索であることを見破れた.デコード部分を書いておしまい.

17:30~18:00

@xthexworldxがB問でバグらせていた.ペアプロに移る.
少しずつコードを読み解いているうちにいつの間にかバグがいくつか直ってた.紙デバッグに移って@osrehunがD問のコードを書く.

通らない.ソートするのを忘れていたっぽい.
サンプルが通ったのでSubmitする.WA.

ここで一度体制を立て直す.

B問と交代しながらデバッグしていく.

18:00~18:30

D問のサンプルが通る.どうやらvectorにぶちこんでたら重複を許していたっぽい.
再度Submit.WA.さすがに焦る.

ここで僕が書いたデコーダが間違っていたことに気付く.
通す.実行時間が明らかにアウトだけど気にしない.出力さえ正しければよい.

18:30~19:00

D問は実行時間が長いのでこの間にB問を書いてもらう.バグもとれたっぽい.
D問の実行が終わる.Submit.AC.
続けてB問も通る.

ここまでで3AC.国内予選通過が危ぶまれる.
即座にC問のコーディングを@osrehunが開始.

19:00~19:30

バグが取れない.やばい.方針が良くないのかもしれない.

二分探索をすると太陽が通過した後の判定がうまくできていないことに@osrehunが気づく.
後は判定部分を適当に指摘する.サンプルが通る.
終了10分前.AC.

順位表を見る.東大が開始1時間ちょいで通しているところをみて戦慄する.

@osrehunがE問のコーディングを始めるも途中でタイムアップ.

終了後

順位表をみて気付いたが,コーディングに時間をかけすぎたこと,WAを結構な回数出したことから4完チームの中では最下位だった.
また,もう片方のチームは結構早い速度で4完していたため国内予選ほぼ確定.同時に僕のチームは敗退.
聞くところによると,ABCEをすべてC言語で通したらしい.おまけにコーダーは1人のみとのこと.是非アジア地区大会頑張ってきてほしい.

今回の反省点としては3人それぞれが泥沼にはまっていたこと,A問を通すのが非常に遅かったことが考えられる.
いくら簡単な問題とはいえ,解法から実装までを一人でやるのは良くない.万が一誤読したときのことを考えて2人以上で問題を読んでおくべきだと思う.チームで解くことを生かすならなるべく複数人で考えることが重要なのかもしれない.
E,F,Gに関しては方針すら全く浮かばなかったのでとにかく知識をつけてから問題を解いていきたいと思う.

蟻本読まねば・・・

Gitlab

といえば環境構築が非常に手間のかかる作業と思っていたのですが、どうやら最近はパッケージ一つで簡単に立てられるようです。

Gitlub omnibus

以下、CentOS6.4にて

https://www.gitlab.com/downloads/ から環境にあったパッケージをダウンロード

wget https://downloads-packages.s3.amazonaws.com/centos-6.5/gitlab-6.9.1_omnibus-1.el6.x86_64.rpm

openssh-serverとpostfixが必要になるので導入していない場合はインストールする

yum install openssh-server
yum install postfix

Gitlab omnibusインストール

rpm -i gitlab-6.9.1_omnibus-1.el6.x86_64.rpm

起動する

gitlab-ctl reconfigure
gitlab-ctl start

おしまい



しかしこのパッケージ、デフォルトで動かすといくつかの問題があります。

Apacheが死ぬ

Gitlab omnibusではnginxを80番で使用するため、既に80番で動いてるサービスがあると上書きされてしまいます。

リバースプロキシを設定することで回避できます。

/etc/gitlab/gitlab.rb

external_url "http://gitlab.icchy.net:8081"

virtual.conf

<VirtualHost *:80>
    ServerName gitlab.icchy.net

    DocumentRoot /opt/gitlab/embedded/service/gitlab-rails/public

    CustomLog /var/log/httpd/gitlab_access.log combined
    ErrorLog /var/log/httpd/gitlab_error.log

    ErrorDocument 502 /502.html

    <Directory "/opt/gitlab/embedded/service/gitlab-rails/public">
        Options FollowSymLinks
    </Directory>

    <Proxy *>
        AddDefaultCharset off
        Order deny,allow
        Allow from all
    </Proxy>

    ProxyVia On
    ProxyPreserveHost On

    ProxyRequests Off
    ProxyPass /assets/ !
    ProxyPass /Uploads/ !

    ProxyPass / http://gitlab.icchy.net:8081/ retry=1
    ProxyPassReverse / http://gitlab.icchy.net:8081/
</VirtualHost>

重い

貧弱なサーバだとつらいものがあるので、unicornのプロセスを減らしてpostgresのメモリ使用量も減らします。

/etc/gitlab/gitlab.rb

external_url "http://gitlab.icchy.net:8081"
unicorn["worker_processes"] = 1 
postgresql["shared_buffers"] = "128MB"
postgresql["effective_cache_size"] = "32MB"

dovecotが死ぬ

gitlab設定後、今まで使ってたメールが使えなくなりました。

f:id:icchyr:20140530111140p:plain:w200

原因を調べてみたところ、iptablesで塞がれていました。

/etc/sysconfig/iptables

-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited 

コメントアウトしてしまいましょう。

/etc/gitlab/gitlab.rbの中身を書き換えたあとはgitlab-ctl reconfigureまたはgitlab-ctl restartで設定を反映してください。