2017年8月19日土曜日

セキュリティキャンプ全国大会2017に参加しました

2017年08月14日から08月18日まで、東京都府中市で開かれたセキュリティキャンプ全国大会に参加してきました。ここでは私の参加した集中Xコースのx86OS自作ゼミでの活動について書こうと思います。
今回作ったOSは
https://github.com/ptr-yudai/osdev
にあります。(キャンプ終了時点ではバグだらけです。) もしかしたらOSに名前を付けて別リポジトリでまた0から作り始めるかもしれません。

事前学習

まずは作りたいOSについて目標設定します。これは途中で変えてもいいのですが、最初は「ディスクから削除されたファイルを救出できる」という目標を建てました。(応募時は「ディスクを読み書きできるOS」を目標にしてました。)OSは0から作るのですが、私の場合6月くらいから作り始めています。目標はともかく、32ビットOSを作るために最初にやることは大きく分けて保護モードへの移行と割り込みの有効化なのですが、これらを7月始めくらいに完成させました。(サイボウズで07/03にIDEの話をしているのでこのくらい?)そこからIDEでハードディスクを読み込むのを実装するのですが、結構難しかったのを覚えています。ですが、この辺りまでは正直osdevのwikiやforumを参考にしてサクサク作っていた感じです。(1日平均1時間くらいしか時間を取れなかった。)ここからが地獄の始まりです。ディスクを直接読むのでファイルシステムを扱う必要があるのですが、最初にFAT, NTFS, EXTのどれにするか迷いました。世界的にシェアが高いのはFATかNTFSなのですが、FATは簡単すぎると思ってNTFSを目標にしてしまいます。MBRやブートセクタは簡単でしたし、MFTと呼ばれる各ファイル(ディレクトリやその他システム設定も)のレコードの構造も仕様通りに解析していました。ディレクト以下のファイル一覧は$INDEX_ROOT($INDEX_ALLOCATION)を見れば分かるので、これでルートディレクトリのlsもできました。しかし、ここで躓きます。$INDEX_ROOT($INDEX_ALLOCATION)にはINDEX_RECORDというのが並んでいて、それぞれがディレクトリ下のファイルの情報を持っているのですが、FILENAMEという属性しか持っていないのです。てっきり「ファイル情報」+「そのファイルのレコード本体へのポインタ(クラスタ番号)」みたいなのを持っていると思ったのですが、本体の場所が分からないのでFILENAME以外の情報は分かりません。ここで1週間以上悩んで、$MFTという「全てのファイルへ参照できるファイル」というものを使えばいいんじゃないかと思い、$MFTのDATA属性を辿ると目的のファイルが見つかりました。これで一件落着したと思ったのですが、$MFTのDATA属性をどこまで辿ればいいのか分からず、またファイル数が多いときは時間かかるんじゃないか、と思っています。これは未だに線形探索の実装しているので、誰か正しい方法知っていたらここかtwitterで教えてくださいm(_ _)m
 

キャンプ一日目

基調講演でサイバーディフェンス研究所の方がフォレンジックについてお話されたので聞いていて、ファイルを削除してもデータは残るよ、と言っていたのですが残念ながらその詳しい参照方法は説明されませんでした。キャンプ終了後に聞こうと思ったのですが、すぐに帰ってしまったらしく、分からずじまいになりました。
 

キャンプ二日目

なんだかんだでとりあえずディレクトリ一覧(fls)までは作ってきたので、icatとかistatとかを初日に実装します。他には細かいバグ潰しやコマンド入力画面を少しきれにしたりしていました。また、チューターの方が"File System Forensics Analysis"という本を貸してくださり、これが結構いろんな情報が書いてあり役に立ちました。そんなこともあって当初の目的であった削除済みファイルの復元には成功しました。このころ他の参加者はみんなページングとかタスク切り替えとかOSらしいことをしていたので、一人だけこんなOS作ってていいのかと思いながら二日目終了。
 

キャンプ三日目

 このころ、自作OSにLinuxにもWindowsにも無いオリジナリティを組込むという課題(?)を与えられます。ファイル復元なんて復元ソフトでもできますし、SystemRescueCdというもっと高機能なOSもあったので、この辺からフォレンジックに特化したOSを目ざし始めます。具体的にはTSKやAutopsyなどに付いているタイムライン機能やファイルカービングを付けようと思います。この日は画面をスクロールさせる機能を付けました。それから、"File System Forensics Analysis"に$LogFileというフォレンジックっぽいファイルがあったので、それを解析する機能を付けることにしました。しかし、このファイルはまだ仕様が解明されていないようで、結局$LogFile内の特定のファイル名を探索する機能だけを付けて終わりました。Microsoftは早くNTFSの仕様公開してください。また、タイムライン機能のために時間でソートする必要があるのですが、講師の方に赤黒木を使えば速いという話を聞きます。夜にプロに赤黒木について聞いたのですが、あと1日で作るには実装コストが高かったので線形リストを使ってO(n)O(n^2)で妥協することにしました。

キャンプ四日目

 最終日はタイムラインを実装しました。そこでまたオリジナリティについて問われるのですが、「OSにすることでディスクダンプの手間が省ける!」と言うと「LinuxのLive Bootでツール動かしちゃダメなの?」という正論をいただきます。そこで、それに加えて省メモリを売りにすることにしました。具体的に省メモリとは何かを定義するため、x86でファイルシステムを扱うOSについて調べると、Win 95の8MBでの動作が調べた限り最小でした。私のOSは2MBでも一応動くので、これなら省メモリと言えるだろうということにしました。(実は2MBだとタイムラインでファイルパスが取得できないので、タイムラインにはファイルパスを調査しないオプションを付けてごまかしました。)四日目の後半でコマンドを使うにつれてメモリ使用量が増えていることに気付いたのですが、何をfreeし忘れているのか分からず終了。今迄もfree忘れに気づくためにfreeチェッカーみたいな機能を付けていたのですが、そもそもその機構に問題があったらしく、全然freeできていませんでした。これは修正ポイントです。ですが、削除されたファイルが復旧できるというインパクトが強いので講師の方に成果報告の発表者として選んでいただきました。
 

その他

 キャンプでは専門講義以外にもグループワークや企業プレゼンなどがあったのですが、それについては他の参加者がたくさん書いてくれているので私からは書きません。ただ、BoFで海外のセキュリティ関連イベントについて聞いて、めちゃくちゃ海外イベントに参加したくなりました。何とかお金を使わず海外イベントに参加できる方法を模索しています。誰か連れてって〜。

まとめ

 「ファイルの読み書きができるOS」という最初の目標から「フォレンジックが得意なOS」に変貌しましたが、結果良かったと思います。OSの機構についても少し学べましたし、講師の方にOS開発で便利なライブラリをいくつか教えてもらえたので今後使ってみようと思います。私はずっとNTFSでしたが、周りの人との交流もあったのでマルチタスクがどんなものか、ページングをどう設定するか、64bit難しい、などなど自分が触れていない部分も知ることができました。参加前は「選択でも良かったかな〜」とか思っていましたが、今はX-Xを選んでおいて本当に良かったと思っています。
あと、ずっとNTFSに漬かっていたので特定のファイルを見つけるくらいならバイナリエディタで読める体質になってしまいました。

期待をはるかに上回った内容のセキュリティキャンプでした。運営、協賛企業等、講師、チュータの方々は本当にありがとうございました。参加者の方々はお疲れさまでした。これからもお世話になると思うのでよろしくお願いします!

2017年3月29日水曜日

[LINUX] Simple Voice Recorder for TOEFL Speaking Test


 Since I will take TOEFL iBT several months hence, I need to prepare for the speaking part, which I can't get good marks. It'll be the first time for me to take TOEFL iBT tests. I've ever taken TOEIC once before, though.
 Anyway, to practice speaking, I need to record my voice and listen to my (poor) English. As I have no voice recorders, I made a simple python code to record my voice. It's useless for most of those who take TOEFL because it's designed for linux users, but I decided to share this program.

This code can only be run on linux. Also, you need to install python and arecord in advance. Both of them are usually pre-installed in linux. To make this code work, you have to give one argument that indicates the output file name. As it's written on the top of the code, after running this program, you will have 15 seconds to prepare for your answer. In the 15 seconds, you need to come up with what to answer, consider its reasons and some examples. It's too short, isn't it? Well, next you will have 45 seconds to answer the question. You can optionally start sound player to listen to the recorded voice, by commenting out the last line of the code. (You need VLC media player in this case.)
Since this code was written in 10 minutes, it may contain some bugs.
Anyway, I hope it will help someone....

2016年12月22日木曜日

きつねさんでもわかるLLVM - kosen14s読書会

はじめに

この投稿はkosen14s読書会用の記事です。
Kosen14s読書会
kosen14s読書会では、何人かのメンバーが自由なジャンルの本を紹介します。前回はPractical Malware Analysisについて投稿しました。


きつねさんでもわかるLLVM


本記事で紹介する本は、柏木 餅子さんと風薬さんの著書「きつねさんでもわかるLLVM ~コンパイラを自作するためのガイドブック~」です。
きつねさんでもわかるLLVM ~コンパイラを自作するためのガイドブック~
表紙とタイトルを見て、「これならコンパイラが作れそう!」と思った時期もありました......
というのも、やはり内容は難しかったです。そして私はまだ完全に理解してません。そのため今回は、電卓を例にとってプログラミング言語がどのように表現されるかについて、かいつまんで説明します。ただ、あまり細かいところを理解していないのでところどころ説明に間違いがあるかもしれません。

電卓を作ってみる

こんな記事に辿り着く人はコンパイラを使ったことがある人がほとんどだと思います。コンパイラは入力されたソースコードを解析し、中間言語を生成したり実行ファイルを生成したり、とにかく人間が読めるコードを機械が解釈できるコードに変換するツールです。本書で使用するLLVMでは、ソースコードをレキシカルアナライザと呼ばれるプロセッサでトークンと呼ばれる意味を持った単語に分割されます。例えば次のような入力ソースコードがあったとします。
「4 / 3 * 3.14 * 10 ** 2」
レキシカルアナライザはこれを次のように分割します。
「4」「/」「*」「3.14」「*」「10」「**」「2」
そして、lex/yaccという言語(?)を使うと自分がどんな言語を作りたいかを規定するだけでこのトークン分割を自動でやってくれるのです。電卓程度ならこれを規定するのが非常に簡単です。例えば足し算「+」を定義したければ次のように書きます。
"+" {
    return OPERATOR_ADD;
}



OPERATOR_ADDなども別ファイルで自分で定義するので、四則演算だけでなく、複雑な演算やオリジナルの演算子を簡単に定義できてしまうのです。また、演算子以外にも「整数とは何か」や「小数とは何か」も定義する必要があります。例えば小数は次のように定義されます。
[0-9] *\.[0-9]* {
    double temp_box;
    sscanf(yytext, "%lf", &temp_box);
    yylval.double_value = temp_box;
    return DOUBLE_LITERAL;
}



先程の足し算より長くなりましたが、これは計算時に具体的な数字を参照するためにyytextなどを設定する必要があるからです。詳しくはぜひ本を読んでみてください。


このように「足し算とは」「整数とは」「文字列とは」「変数とは」「関数とは」などなど、トークンについて全て定義します。次にこれらトークンを解釈するのがパーサと呼ばれるプロセッサです。例えば「1+2*3」を計算するとき、人間は掛け算を優先します。また、「*は乗算である」だけでなく、「乗算とは何か」という具体的な処理を解釈するのがこのパーサyaccです。さらに、パーサはコンパイルエラーを出す必要があります。例えば「1+2*3*」という計算式はエラーとなります。ではエラーでない乗算とは何かというと、「A*B」のように「*」の両側に数字が付いていることです。数字というより、最終的に数字になる式がAやBにあたります。例えば「(1+2)*(3*4+1)」の場合、(1+2)と(3*4+1)をそれぞれA,Bとして認識させる必要があります。そういった表現の定義はBNFという記法で書かれます。先の例でAやBをtermとして定義します。(もちろんこれも自分で定義するのでtermじゃなくてhogeとかでもいいです。)
term
: primary_expression
| term OPERATOR_MUL primary_expression
{
    $$ = $1 * $3;
}
| term OPERATOR_DIV primary_expression
{
    $$ = $1 / $3;
}
;
一行目は「termとは何か」の定義開始です。二行目は「termとはprimary_expressionである」という意味です。ちなみにprimary_expressionは後で定義する「値」を表すものです。ここまでで「式termとは値primary_expressionである」と定義されました。三行目は「もしくはterm * primary_expressionである」という意味です。OPERATOR_MULは前にレキシカルアナライザのところで定義しました。ここで注目したいのが、termの定義にtermが入っているということです。これだとずっと自分自身を参照しそうですが、一行目の「termとはprimary_expressionである」があることにより、いつかはprimary_expressionに移るのです。「term * primary_expression」を宣言しましたが、これが返す具体的な値を各必要があります。これが四行目から六行目の括弧内にある「$$ = $1 * $3;」で、「返す値 = term * primary_expression」という意味です。$1とか$3は今解析しているトークンから何番目のトークンであるかを示します。同様にして除算も定義しました。加算や減算は優先順位が低いのでexpressionとして定義します。(最後に全体のコードを示します。)
さて、 「termとはprimary_expressionである」と定義したので、今度はprimary_expressionも定義します。これはただの値(今回は小数のみ)なので、次のようにかけます。
primary_expression
: DOUBLE_LITERAL
;
ここで始めてその項の評価が終わります。(ツリーの葉に到達する。)
詳しく知りたい方は是非本を読んでみることをおすすめしますが、今回の電卓の全体像を載せておきます。

実行するとこんな感じで計算できます。



ついでに括弧付き計算や累乗にも対応したバージョンです。

実行するとこんな感じで計算できます。

さいごに

数年前にもこの本を手に取ったのですが、当時は何一つ分からずに放置していました。しばらくして読んでみると内容が全然違うとうに思えて面白いですね。まだまともな変数も実装できないですが、ちょっとずつ勉強して、いつかまともな言語を作れたらと思います。

2016年12月11日日曜日

SECCON 2016 Online予選に参加しました

結果

既に本選参加権は持っていたので、今回はいつものメンバーと分断して気楽にチームdogeとして参加しました。得点は700点で順位は125位でした。オンライン予選は初参加ですが、予想以上に難しかったです。今回は自分が解いた「VoIP」「Memory Analysis」「Anti-Debugging」「randomware」について軽くWriteupを書きます。

VoIP

タイトル通りVoIPを使用した電話のパケットを記録したデータを解析する問題です。Wiresharkにはこれを解析する機能が備わっているので、それで通話内容を再生できます。(LinuxのWiresharkでは再生機能がありませんでした。)あとは喋っているフラグを聞けばいいのですが、「V」を「B」と聞き間違えていたので結構時間がかかりました。気付くまでの間は次のMemory Analysisに取り組んでいました。
フラグ:FLAG{9001IVR}

Memory Analysis

これもタイトル通りで、Windowsのメモリダンプを解析する問題です。どれかというとForensicが得意分野なので何としても解かなければならない問題です。問題文は、「偽物のsvchost.exeが接続しようとしている宛先はどこですか」というものです。

$ volatility --file=forensic_100.raw imageinfo
[snip]
Suggested Profile(s) : WinXPSP2x86, WinXPSP3x86 (Instantiated with WinXPSP2x86)
[snip]
まぁ問題文から分かりますが、Windowsだそうです。とりあえずsvchost.exeについて調べる訳ですが、pstreeすると結構たくさんのsvchost.exeがありました。
$ volatility --file=forensic_100.raw --profile=WinXPSP2x86 pstree
上のコマンドの実行結果より、svchost.exeという名前のプロセスはPIDが1036,936,1088,848,1320,1776,1704の7個あります。次にこれらのプロセスのうち偽物を判別するために、dlllistを使用します。
 $ volatility --file=forensic_100.raw --profile=WinXPSP2x86 dlllist --pid=1036,936,1088,848,1320,1776,1704
すると、PIDが1776のsvchost.exeはパスが他と違って"C:\Windows\svchost.exe"である他、ロードされているDLLも他と大きく異なります。そこでこれをダンプして、stringsで接続先が見つからないかを試します。
$ volatility --file=forensic_100.raw --profile=WinXPSP2x86 procdump --pid=1776 -D ./
$ strings executable.1776.exe | grep http
C:\Program Files\Internet Explorer\iexplore.exe http://crattack.tistory.com/entry/Data-Science-import-pandas-as-pd
それらしいものが見つかりました。しかし、このサイトにはデータは存在しません。そこでhostsファイルを調べます。
$ volatility --file=forensic_100.raw --profile=WinXPSP2x86 filescan | grep hosts
0x000000000217b748      1      0 R--rw- \Device\HarddiskVolume1\WINDOWS\system32\drivers\etc\hosts
$ volatility --file=forensic_100.raw --profile=WinXPSP2x86 dumpfiles -Q 0x000000000217b748 --name -D ./
$ cat file.None.0x819a3008.hosts.dat
[snip]
153.127.200.178    crattack.tistory.com
実際の接続先が153.127.200.178であることが判明したので、こちらの方にアクセスします。ファイルをダウンロードすると中にフラグが書いてあります。
フラグ:SECCON{_h3110_w3_h4ve_fun_w4rg4m3_}

Anti-Debugging

アンチデバッグ系にはそこそこ慣れていたので簡単でした。ひたすらアンチデバッグ技術が登場するので、それらを掻い潜るとフラグを表示してくれます。普通に実行したらダメなの?と思いましたがVMware上にしかWindowsを持っておらず、VMware検知もあったのでデバッガで回避することに。OllyDbgやらIDAやらをいろんな方法で検知してきますが、ひたすらZFを変更し続けるとスキップできます。最後に0除算(?)で例外を発生させているので注意。(フラグは忘れました。)

randomware

これもフォレンジックなので個人的に解きたかった問題です。開始18時間くらいでうっかり寝ていて、起きたらスッキリして解けました。これはQEMUのディスクイメージが渡されるのですが、とりあえずrawに変換してFTKで中身を見ました。いろいろ見ていると「h1dd3n_s3cr3t_f14g.jpg」と「getflag」というファイルがあったのでここから着手することに。h1dd3n_s3cr3t_f14g.jpgの方はバイナリはJPEGのものとは大きく異なり、0から0xFFでXORしてみるも全てfileコマンドではdataとなりました。getflagはLinux用の32bitバイナリで、IDA Proで解析しました。問題を解くのに必要な大体の流れば次のようになります。

1) /dev/urandomから0x400バイトを取得 --> encrypt_keyに格納
2) 再帰的に特定の条件にマッチするファイルを選ぶ
3) 2)のファイル全体を0x400バイトのencrypt_keyでXOR

ということで、明らかにXORされたっぽいファイルを探します。「h1dd3n_s3cr3t_f14g.jpg」以外に、「blocklist.xml」「revocations.txt」「user-extension-html.xml」などのファイルがXORされていました。問題は、いずれも平文が無いということです。元の文が無いと数学的に考えて解読できないじゃないか!と思っていましたが、例えばXMLの最初が「<?xml version...」みたいな文字で始まることを考えると最初の部分のencrypt_keyは取得できます。
次のポイントは、blocklist.xmlおよびrevocations.txtはfirefox等が作成するファイルで、作者が用意したものではないという点です。実際これらのファイル名で調べると、内容はサイトによってバラバラであるものの、「だいたいこういうことが書いてある」ということは分かります。また、user-extension-html.xmlについては結構最初の部分が固定されているので、これで100バイトくらいはencrypt_keyを求められることになります。
これだけencrypt_keyを求められたら、反対にblocklist.xmlおよびrevocations.txtの最初の100バイトくらいも復元できます。解いてるときはこの辺で時間かかったのですが、ここでは最終的に確立したやり方だけを説明します。
revocations.txtは内容がBase64です。また、ファイル全体をBase64エンコードしている訳ではなく、意味のあるブロックごとにエンコードしています。したがって、例えばencrypt_keyにより最初の数バイト「MMGExCzAJ」くらいさえ分かれば、ネット上に転がっているrevocations.txtから同じブロックを探して、続きを予測することができます。続きが分かるということは、反対にencrypt_keyの分からなかった部分が徐々に分かっていくということです。この「blocklist.xml」<--encrypt_key-->「revocations.txt」のやりとりを繰り返すことでencrypt_keyを0x400バイト全て求めることができました。
正攻法かは分かりません。
フラグ:SECCON{This is Virtual FAT too} (お肉の写真とともに)

まとめ

挑戦した中でも「checker」なんかは解き方が分かってたのにコードでミスしてて諦めてしまいました。(「動かない」+「300pt」=「自分が間違ってる」)他にも「こんなの解けたじゃん」みたいな問題が500pt分くらいはあったので、もったいないなぁという感じでした。何はともあれ楽しかったです。運営のみなさん、参加者のみなさん、お疲れ様でした!


2016年8月29日月曜日

katagaitaiCTF#5 関西medに参加しました

本日(08月28日)に大阪で開催されたkatagaitai CTF勉強会(med)に参加してきました。

内容は午前はCryptography, 午後はPwnでした。Cryptographyはハッシュ関数に関する攻撃をやりました。問題はhack you 2014のhashmeと、ebCTF 2013のmd5collidingを中心に勉強しました。どうも講師の方がこのwriteupを読む可能性があるようなので、今回はしっかり書こうと思います。ちなみに一番前の中央に座っていました。[ ^o^]
katagaitaiCTFの5周年おめでとうございます。

午前 - Cryptography

Length extension attackやハッシュ衝突系の問題は昔勉強したことがあったので、今回のCryptographyはあまり資料を見なくても解けました。

hashme

ユーザー名を登録すると、「login=[username]&role=anonymous」で登録されます。ログインする際にroleにadministratorが入っていればフラグが表示されます。しかし、ログインするには登録時に生成される認証コードが必要です。認証コードは
s = "login=[username]&role=anonymous"
base64( xor( s + hashme(SALT + s), KEY ) )
で生成されます。
ただし、SALTとKEYはサーバー側にあり、不明です。(ローカルで実行する際はSALT="HOGE", KEY="\x01\x02\x03\x04"にしました)
ここでhashmeという独自実装のハッシュ関数がありますが、md5のように32バイトのhexdigestを出力するハッシュ関数で、ハッシュでごちゃごちゃにした各4バイトのA, B, C, DをB, A, D, Cの順にくっつけて出力しています。

(1)KEYを取得
とりあえずKEYは単純なxorで使われており、入出力はどちらも取得できるので、まずKEYを計算します。方法として、認証コード(cert)をbase64デコードし、それと"login=[username]&role=anonymous"をxorすれば、KEYの最初の方から復号化できます。さらに、[username]の長さを長くすると、それだけKEYを長く復号化できます。xorではKEYを繰り返してxorしているので、同じパターンの繰り返しが出た時点でそこまでが実際のKEY値です。

(2)length extension attackを実行
本日まではhashpumpしか使えなかったのですが、今回の講義を通して原理が分かったので実装することができました。ハッシュ関数は、ある時点で(A, B, C, D)が計算され、それをもとに次の(A, B, C, D)を計算する、という動作を繰り返しています。したがって、最終的に出力された(A, B, C, D)を使って、次の(A, B, C, D)を計算することで、hashme(A)の結果だけからhashme(A+B)が作れるということです。ただし、(A, B, C, D)の計算内には現在のバイトインデックスも含まれるので、Aの長さも必要です。今回の場合、 s = "login=[username]&role=anonymous"のときのhashme(SALT + s)が取得できるので、それをもとにhashme(SALT + s + "&role=administrator")を作ります。
しかし、SALTの長さは分からないので、ここは1から順番に仮定して、成功するまで繰り返します。

これらを実装したpython2のコードを載せます。ただし、pwntoolsというライブラリを使用しています。

今まで完全に闇の世界だったlength extension attackの原理が理解できたときは、かなり感動しました。

md5colliding

これ系も実は昔やったことがあり、そのときfastcollを使ったのも覚えていますが、2つまでしか同じハッシュを持つファイルが作れないなぁと思っていてそのままでした。今回の講義で少しステップアップした使い方ができるようになったかな。
さて、この問題は、指定された5つの文字列をそれぞれ出力するようなexeファイルを5つ作る、という問題です。ただし、5つのファイルは全てmd5が同じである必要があり、sha1が異なる必要があります。
fastcollというツールを使うと、
$ fastcoll A -o B C
でA+paddingという内容で、異なるpadding、同じmd5ハッシュ値を持つBとCが出力されます。ここから3つ以上同じハッシュを持つファイルの作り方が分からなかったのですが、
$ fastcoll B -o D E
としてCとD(もしくはE)との差分(追加分)をCに付けたせば良いようです。(なぜなら、hashmeで言ったように、サイズさえ一致すれば、それより前のバイナリは後のハッシュ値に影響しないからです。)
次にexeが異なる出力を持つ必要があるのですが、argv[0][0]などハッシュ値に影響しない部分を利用すれば良いようです。(もしファイル名が自動で割り当てられる場合はどんな方法がベストかな...?) とにかく今回はargv[0]で1から5までの出力を振り分けるのですが、Windows起動が面倒だったのでx86用のelfでやりました。
実行ファイル用のコードは次のようにしました。(linuxでは"./main"のように実行するのでargv[0][0]ではなくargv[0][2]を判定に使っています。) 実行ファイル用のCコードと、衝突生成用のpython2のコードを載せておきます。

同じmd5ハッシュ、異なるsha1ハッシュが出力され、出力内容も指定通りでした。コードは5個に限らず自由な個数だけ衝突ファイルを生成できるように工夫しています。

parlor

この問題はそもそも問題文を理解しておらず、時間内には解けませんでしたが、家でやったのでwriteupしておきます。
入力に対して条件を通過すれば賭け金だけ増え、失敗すれば賭け金が消えるゲームです。条件というのが
md5(hoge + input) % odds == 0
であることです。ちなみに問題文ではもうちょっと分りにくかったです。また、この「+」は文字列の結合で、hogeは16進数形式のダイジェストなのですが、バイナリとして結合されます。ここで数値加算してみたり文字列そのまま結合してみたりして時間取られました。さらに、inputには改行コードが最後に付いてくるっぽいのでそこにも注意。
この問題でユーザーが指定できるのはlog_2(odds)の整数とinputのバイナリです。hogeはランダムでサーバー側に保存されています。oddsの指数は100まで指定できるので、最大で2**100まで設定可能です。一回成功すればそれを繰り返せば良さそうなのですが、一度送ったinputは二度と送れません。

(1)md5(hoge + x)を知りたい
md5(hoge + x)が求まれば、md5(hoge + x + y)も求まります。しかし、md5(hoge + x)は最大でも下位100bitまでしか残りません。ということでbrute force attackで残りの28bitを探すことにしました。
...と書きながらコードを書いて実行したらあまりの重さにパソコンが止まったので今日はここまで。

午後 - Pwn

なんか凄いことやってるなぁって感じでした。
1つ1つのプロセスで何やってるのかは分かりましたし、資料にソースコードや構造体、サンドボックスの命令などが書かれていたので良かったものの、実際にソースコードも無い状態であれを解けと言われたら確実に捨てます。

tp

最後まで分からなかったこと(自分の書いた攻撃コードに関する疑問):
  • fastbinsに繋がったりbinsに繋がったり。その辺の設計もうろ覚えでした。 
  • 0x1337という数が分かりませんでした。idなら10とか20とかでもいいはず?
  • shellstormのshellcodeが動きませんでしたが、あれはseccompが原因だったのかな?
  • どうやってあんなに長いアセンブリを読む気になれるのか。

でも、やっぱりヒープ苦手だなと実感しました。もっと勉強してきます。

(2)習得したこと:
  • malloc, seccompなどの設計が少し分かりました。
  • main_arena以外にthread_arenaなるものがあるとは......
  • gdbでアタッチしたりダンプしたりするのが便利でした。
  • DynamicROP(?)の復習になりました。
最終的にflag1は取得できたので良かったですが、flag2については手も足も出ない状態です。特にヒープのところの動作がいまいち分かってないので解説みたいなのは書けませんが、書いた攻撃コードを載せておきます。(Ubuntuで書いたので日本語で書けませんでした。)

最初にひっかかったのはremote_readで、payloadを書き込んですぐにsendしなければならないのですが、remote_read内にrecvがあったので、次のステップに進めないままrecvで止まっていました。次にひっかかったのはpayloadのROP gadgetで、「pop esi; ret」を使ってるつもりが「pop esi; rep ...」みたいなのを使ってました。目grepが足りない。最後にひっかかったのがshellcodeで、shellstormからコピーしたものは動きませんでした。たぶんseccompのせいかな?
個人的にtpはflag1だけを集中的に説明しても良かったんじゃないかなとも思います。(そうするとプロが困るのかも。)

さいごに

今回はCryptography, Pwnいずれも前回のmedに比べるとかなり成長した状態で挑戦できたと思っています。(前のmedは1つも解けなかった。)
いつもkatagaitaiCTFではたくさんの知識を習得させてもらっています。講師のみなさん、NRIさんなど、運営してくださっている方々、本当にありがとうございます。
今後も参加したいと思っているので、よろしくお願いします!

2016年8月13日土曜日

katagaitaiCTF#6 関西easyに参加しました

本日(08月13日)に大阪で開催されたkatagaitai CTF勉強会(easy)に参加してきました。

内容は午前はWeb, 午後はReversingでした。WebはHack.lu CTF 2014のHotCows Datingという問題で、ReversingはCSAW CTF 2013のcrackmeという問題をそれぞれ解きました。正直Webの方はBurpの設定が上手くいかずにあまり付いていけませんでした。一応フラグは取得できたもののイマイチ「なんで?」というところが多いので、今回はcrackmeの方を中心にWriteUpを書こうと思います。

crackmeは32bitのLinux用バイナリで、とりあえずWindowsを起動してIDA Pro Freeで解析を開始しました。bindやaccpetなどから単体でサーバーとして動作するプログラムだと分かったので、とりあえずポート番号だけメモして動作しました。crackmeへ接続すると、パスフレーズを聞かれます。パスワードが合っていないと終了してしまいます。あまりIDAを使ったことの無い私は文字列検索で文字列を送信(表示)している部分を見つけ、その周辺から解析を始めました。その結果、明らかに分岐している部分があったので、その上の関数にverifyという名前を付けて関数を見ます。ちょっと前に変数名とコメントを付ける機能を知ってからはじゃんじゃん使ってるので解説が始まる前には解析が終わってたと思います。verify関数(仮)をC言語にすると次のようになりました。

int verify(char* input)
{
  char chr = input[0];
  int hash = 0x539;
  char *pass = input;
  int tmp;
 
  for(; *pass != 0; pass++) {
    tmp = chr + (hash << 5);
    chr = *(pass + 1);
    hash += tmp;
  }
 
  return hash;
}

あらためて見るといかにC言語が苦手かが分かります......
さて、とりあえず自分で解こうと思って6桁くらいまでのブルートフォースを書きましたが一向に終わらないので別の方針を立てることにしました。
そこで、入力を「A」「AA」「AAA」「AAAA」...のように試すと、徐々にハッシュ値が増加していることが分かりました。(4バイトを超えたらまた小さくなる感じでした。)
入力が長く、ASCII値が大きいほどハッシュ値も大きくなるので、二分探索(手動)で0xEF2E3558に徐々に近づけていきました。(でも5分程度で下2桁以外は揃いました。)
6桁でハッシュ値が答えに近づき、最後の方は揃わなそうだったので、最後の1文字だけブルートフォースアタックしました。その結果「aSA6>6」で通りそうだったので送ったらフラグが表示されました。

勉強会が終わった今では頭の悪い解き方です。はい。

ということで、勉強会ではkleeとz3pyを使う方法をやったので、その内勉強会中ずっとやってたz3による解法についてもWriteUpします。z3pyは条件式に当てはまるような入力を見つけてくれるモジュールです。文字列を探す方法は分からなかったのでIntVectorでやってましたが実行できず。スライドを読むとBitVecなら上手くいくそうなので時間がかかりましたが書いてみました。

実行すると入力条件に当てはまるような文字列を見つけて表示してくれます。講師の方の書かれたコードでは40秒程度かかりましたが、このコードでは1秒前後で実行できました。私は講師の方のコードをリストにして初期化に入力、hashともにBitVecを使っただけなのですが、なぜここまで違いが出たのかは全く分かりません......

easyとはいえ、今回の勉強会を通して知らなかったことをたくさん学ぶことができたので、大変有意義な1日でした。主催者やNRI Secureの皆様、ありがとうございます!次のmedも参加する予定なのでよろしくお願いします。

2016年7月17日日曜日

SECCON 2016 九州大会のWrite Upと感想

本日2016年07月17日(日)に、福岡県の博多にある富士通株式会社 九州支部で、IoT CTFが開催されました。このCTFは過去に参加してきたCTFと違い、電子回路やハードウェア関連の問題が出題されます。今回は部活のチーム4人で、チームinsecureとして参加しました。最終的なスコアテーブルの上位3位は以下の通りです。(他チームはぼかし処理済み)


ということで、何とか優勝してSECCON本戦出場権を獲得することができました。今回はチームでかなり協力し、労力を分散させて挑戦することができたのが良かったと思います。また、CTFとしては、過去にやったことの無いタイプでしたが、今までほとんど触れたことのない分野だけあって、非常に勉強になりました。

今回のCTFの概要

大会直前までどんな形式か全く分からず、「ブレッドボード回路が渡されるんじゃないか」とか「配線の写真からデコーダを書くんじゃないか」とか事前にいろいろ考えてきました。会場に入ると、各チームのテーブルにRaspberry Pi 2、ブレッドボード、配線、各種IC、テスタ、ニッパーなどが用意されていました。
問題は大問で4問、小問を含めて5問ありました。全て100[pt]です。insecureは3問(300[pt])を正解し、最初の1問がFirst Bloodだったので追加で10[pt]を獲得しました。今回は、どんな問題が出題されたのかと、解いた問題についてのWrite Upを書きます。



問題1

水道局員の人数が足りないから自動で制御しよう、という問題。用意された部品を使って、1秒毎にモータがON,OFFを繰り返す回路を作る。優しいことに、回路図が用意されていたので、回路の方はそのまま実装しました。なお、使用した機器は「Raspberry Pi 2」「モータ」「ダイオード」「抵抗」「MOSトランジスタ」です。
Raspberry Pi 2の3番ピンから1秒ごとに出力と入力を切り換えるようなコードを書いて実行します。正しく動作していることと、その入力をオシロスコープで示した上で、担当の方を呼んで動作確認してもらいます。実行結果が正しいと判断されたら、フラグが貰えました。
ここのオシロスコープの波形がかなりひどい状態でしたが、運営の方の優しさでフラグが貰えました。ありがとうございました。この問題がFirst Bloodでした。


問題2.a

スパイとして活動しているとき、任務内容を8PINのICで渡されるという問題です。8PINのICは24LC256で、これはEEPROMです。EEPROMについては調べてきて、Pickit2のも持って来たのですが、なぜかリードが正しくできずに挫折。その後、同じチームのtheoldmoon0602が、持って来たArduino互換機で挑戦し、見事データの抽出に成功。データのヘッダが1F 8Bで、一目見てtar.gzだと分かったので、解凍するとフラグのテキストが出てきました。


問題2.b

上と同じです。ここで、上の問題ではEEPROMの最初の方しか取り出しておらず、それに気付くのにかなり時間が取られました。結局最後までデータを取ると、回路図のjpgとRaspberry Pi用のコードがあり、回路図を構成してコードを実行するとフラグが取得できます。プログラムで回路をエミュレートしたものの、終了数分前だったのでダメでした。


問題3

1分ごとにエアコンのリモコンが使えなくなる原因を探ってほしい、という問題。会場の前後に回路が置いてあり、そこから赤外線が発生していました。(それはデバッグ用で、実際には運営に頼んで赤外線を定期的に発生させるボードを借りてくる。)この問題では、Raspberry Piのmode2コマンドを使って赤外線の波形データを取得しました。さらに、エアコンのリモコンの赤外線の仕様書を調べ、それに従って不要な部分をカットしました。しかし、このプロトコルは製造会社によって結構違い、どれを使えばいいか迷ってる間に時間切れでした。今思えば「SECCON{~~}」の「ECC」のところは取得できていたので、もう少し頑張れば解けたかもしれません。個人的には赤外線モジュールについて勉強できたので、非常に楽しい問題でした。


問題4

テロリストのUSB機器がどんな動作をするか確認する、という問題。この問題については私は全く触っておらず、チームメンバーが解いてくれたので詳細は知りません。チームメンバーの解き方としては、用意されたAVRマイコンに配布されたhexデータを書き込み、さらにUSBに変換する謎の機器とを接続し、それをパソコンに繋いだとのこと。すると、一定周期でキーボードが勝手に入力され、フラグが書かれたそうです。この問題は全チームが解いていました。すごい。
個人的に自分で作ってみたいので今後教えてもらおうかな。

感想

とにかく色んなことが勉強できて素晴らしかったです。企画してくださった運営の皆様、会場やパーツ等を提供してくださった協賛社の方々、本当にありがとうございます。それから今回出場されたチームの方々もお疲れ様でした。
細かい部品は持って帰っても構わないということで赤外線モジュールとEEPROM等をいただきました。家で勉強させていただきます。m(_ _)m
 





2016年6月27日月曜日

Practical Malware Analysis - kosen14s読書会

はじめに

この投稿は、kosen14s読書会用の記事です。

kosen14s読書会

kosen14s読書会では、何人かのメンバーが自由なジャンルの本を紹介します。私は他にブログらしきものを持っていないことと、ちょうど技術的な内容の本を紹介する予定だったので、ここに投稿しました。


Practical Malware Analysis


本記事で紹介するのは、Michael SikorskiさんとAndrew Honigさんの著書「Practical Malware Analysis: The Hands-On Guide to Dissecting Malicious Software」です。

Practical Malware Analysis

宇宙人が解剖されかけているという一見不思議な表紙ですが、これは「中身の分からないものを調査する」ということを暗示しているのだと思います。

さて、この本ではマルウェア(端的に言うとウイルス)を解析するために必要な知識を1から100まで記載した技術書で、内容がとにかく充実しています。私は自分の読みたいところだけを読む人なので、本当はこの本の内容を全て読んだ訳ではありません。しかし、さらっと読んだだけでも有用な情報が数多く書かれていたので、その中でも特に面白かったものについてのみここで取り上げようと思います。


この本との出会い

この本を初めて知ったのは高校1年生の冬、北海道で開かれたセキュリティミニキャンプという勉強会でした。その勉強会は私がコンピュータセキュリティを勉強するきっかけにもなったのですが、そのため当時は会場一の初心者でした。勉強会を通して活躍が見られた人にはこの本が貰えるとのことだったのですが、もちろん本はプロ達の手に渡っていきました。そこで、「プロが良本を手に入れるとよりプロになる」というプロサイクルを見出しました。これではいかんと思い、それから1年後にネット通販でこの本を買うことにしたのです。おしまい。


逆アセンブルとは

まず説明する前に、逆アセンブルということについて説明します。
逆アセンブルとは、実行ファイルなどの機械語を、アセンブリ言語という多少人間が読みやすい形式に変換する作業を指します。
機械語はintelやらARMやらといったプロセッサにより異なりますが、アセンブリ形式はどの種類でもある程度似ているので、普通の人がマルウェアを解析するとき、逆アセンブルされたものを読みます。この記事では、intel形式のアセンブリ言語(NASM)で書きたいと思います。

例えば

b8 77 00 00 00 50

という機械語列はさっぱり意味が分かりませんが、これを逆アセンブルして

mov eax, 0x77
push eax

にすると、あら不思議。分かりやすい。

さて、みなさんが普段使っているソフトウェアは、例えばWindowsならexeなどの実行ファイルになっていることが多いです。これが実行できるということは、このファイルの中に一連の動作を表す機械語が書かれています。マルウェアに限らず、実行ファイルを解析するときはこの機械語を逆アセンブルするのです。そして、逆アセンブルするためのツールはたくさん用意されています。個人的に代表的なのは次のツールです。

静的解析:IDA Pro, radare2
動的解析:OllyDbg, x64dbg

静的解析のツールは、先に説明したように、ただ機械語を逆アセンブルした結果を表示するツールです。ただ、こういったツールの良いところは、逆アセンブルした結果をフローチャートのようにするなど、できるだけ人間に分かりやすく整理して表示してくれるのです。動的解析のツールは、逆アセンブルをすると共に、そのプログラムを実行します。しかし、マルウェアは実行したら危ないので、今回はやりませんでした。


ANTI-DISASSEMBLY

解析を困難にする技術には大別して「ANTI-DISASSEMBLY」「ANTI-DEBUGGING」「ANTI-VIRTUAL MACHINE TECHNIQUES」「PACKERS」の4つがあります。特に3つ目の「ANTI-VIRTUAL MACHINE TECHNIQUES」 はマルウェア特有の技術ですし、「PACKERS」に関しては「ANTI-DISASSEMBLY」に含まれてもおかしくありません。ということで、個人 的には「ANTI-DISASSEMBLY」および「ANTI-DEBUGGING」に分かれるのですが、ANTI-DEBUGGINGの方は前から触ったことがあったので、そこまで驚きの技術ではありませんでした。
ということで、解析防止技術の中でも特に面白かったものが逆アセンブル自体を困難にする技術です。
そもそもなぜこんな面倒なことをするかと言うと、例えばC言語でゲームを作ったとしても、配布する時点では機械語の入った実行ファイルを公開します。そしてそれを逆アセンブルされると、理論的にはどんなプログラムでもソースコード(アセンブリ)が見られてしまいます。しかし、開発者としてはできればやめてほしいことも多いです。ゲームのストーリーからセーブデータの保存アルゴリズムまで見られてしまうのですから。ましてやパスワードやライセンスキーを要求するソフトウェアなどは解析されたらたまったものではありません。(実際に有名なソフトウェアでも解析されて構造がバレてしまうことが多々あります。)

そこで、頭の良い先人たちは、逆アセンブルを防ぐ技術(Anti-Disassembly)をいくつも考案してきました。とは言え、逆アセンブル自体は防げないので、逆アセンブルにより出力されたソースコード(アセンブリ)を、いかにツールに解析されにくく、そして人間にとって見にくくするかがポイントです。これを難読化といいます。


次のアセンブリを見てください。これは逆アセンブル結果ではなく、開発者が書くコードです。単純にSleep関数を実行するだけなのですが、これがバレたくない開発者は、コードに難読化を施します。

    jmp short obfuscation
    db 0xE8
obfuscation:
    push 0x2A
    call Sleep

このコードの説明は次のような感じです。

1行目:ラベル"obfuscation"にジャンプ(そこを実行)
2行目:機械語にしたときに、ちょうどここに0xE8という1バイトのデータを埋め込む
3行目:"obfuscation"というラベルを作る
4行目:メモリに0x2Aというデータを入れておく
5行目:Sleep関数を呼び出す。(引数は上の0x2Aとなる)

つまり実行すると、
「obfuscationにジャンプ」 -> 「Sleep(0x2A)を実行」
となるだけのコードです。

このコードを機械語にし、さらに逆アセンブルすると次のようになります。(あくまでも出力例)

    jmp short near ptr loc_2+1
loc_2:
    call near ptr 0x15ff2a71
    or [ecx], dl
    inc eax
    db 0


本来なら前に書いたコードがそのまま結果として出力されてほしいのですが、見たところ全く違うものが出てきました。もう一度オリジナルのコードを書きます。

    jmp short obfuscation
    db 0xE8
obfuscation:
    push 0x2A
    call Sleep

全然違いますね。ここで重要となるのは「db 0xE8」です。0xE8はintelのx86アーキテクチャの機械語において、call命令の最初のバイトです。したがって、逆アセンブルツール(逆アセンブラ)が機械語を解析する際、この0xE8をcall命令として読んでしまい、さらに次の機械語まで巻き込んでしまいます。

つまり本来なら次のように区切って解析してほしいのですが、

| 0xEB 0x01 (jmp) | 0xE8 (db) | 0x6A 0x2A (push) | 0xE8 ... (call) | ...

逐次的に解析するツールは次のように区切ってしまいます。

| 0xEB 0x01 (jmp) | 0xEB 0x6A 0x2A 0xE8 ... (call) | ... (or) | ... (inc) | ...

これだけの説明ではちょっと分かりにくいですが、このようにゴミデータを入れることによって、単純に上から解析するタイプのツールから、ある程度コードを守ることができます。(このように上から解析する逆アセンブリを"Linear Disassembly"と呼んでいます。)

今回紹介した本では、上述のような逆アセンブル防止技術だけでも、他にも様々な種類の技術が詳しく記載されています。


さいごに

この本の分かりやすいところは、たいてい実例を示して詳細に書かれていることです。
それでいて必要なポイントだけがまとめられているので、この本一冊からたくさんの情報を得ることができます。
それから、マルウェアについての解析を中心としているので、各種技術が身に付くとともに、マルウェアの仕組みについても分かります。

残念ならが、調べた限りでは日本語版はありませんが、マルウェア解析技術の本としては海外でも非常に評価の高い一冊です。さらに、kosen14s所属の古月くんもこの本の電子書籍版を持っており、いかにこの本が凄いかを証明しています。

表紙の上で解剖されんとする宇宙人を見た際には、是非一度手にとって読んでみてください。

2016年2月7日日曜日

katagaitai CTF 2016 関西 med に参加しました

2016年02月06日(土曜日)に大阪で開かれたkatagaitai CTFの中級者向け勉強会に参加しました。内容は暗号とエクスプロイトで、私は脱初心者を目指して参加しました。
暗号はCSAW CTF 2014 Crypto300のfeal.pyを、エクスプロイトはCodeGate 2015 Pwnable400のbeef_steakを中心にハンズオンで講義が行われました。
いずれも惜しくも時間内には解けませんでしたが、また時間に余裕がある時に解法コードを作って載せられたらと思います。(試験のすぐ前なので今は時間が無いです)

暗号 - feal.py

暗号問題は、サーバーで動作しているpythonコード(feal.py)が渡され、そこに接続します。
・第一段階
まず、指定された文字列(ランダムな16文字)から始まり、sha1の最終16ビットが全て1になるような文字列を送信しなくてはなりません。つまり、
h = sha1(str_rnd + something)
について、
h[:-1] == h[-2] == 0xFF
であれば通過できます。
これは単純にsomethingにブルートフォースしたら簡単に通りました。
ここまでは家で解いてきたのですが、その後はでっていう状態でした。

・第二段階
次に暗号化されたフラグが渡されます。これは保存しておきます。今回使用されている暗号は、タイトルの通りFEAL暗号ですが、よく見ると、

return ((x << 2) | (x >> 6)) & 0xff

であるはずのシフト関数が、

return ((x << 3) | (x >> 5)) & 0xff

になっていました。本来の仕様との違いはこれだけです。
今回使用する攻撃はDifferential Cryptanalysis(差分解読法)とかいう聞いたこともない方法で、要するに
「入力A, BについてFEAL(A), FEAL(B)が求まっていて、その出力差分FEAL(A) ^ FEAL(B)が一定ならX ^ Y == A ^ B(入力差分がA,Bと等しい)ような入力に対して、その出力の差分はFEAL(A) ^ FEAL(B)となる」
みたいな感じでした。(間違ってたらすいません)
なんとなーく分かったのですが、実際にコードを書くと何かしっくりこなかったです。それに、後から知ったのですが、pythonで書くと十数時間かかるようで、C言語で書く必要があったそうです。ずっとpythonで買いてパソコンのファンを鳴らしていました。

結局私のコードで答えは出ずに、解答だけ聞いて終了してしまいました。暇なときにコードを書きます。


エクスプロイト - beef_steak
エクスプロイトと聞いてうわぁって感じだったのですが、内容はとても面白かったです。とにかくスライドが詳しく書かれていました。(暗号のスライドも図が多くて分かりやすかったですが、こちらは300ページ程度ありました)
beef_steakでは、steakというLinux x86_64のバイナリが渡され、それを実行しているサーバーを攻略するという問題です。家で解析しておきましょうという指令が出ていたので、C言語のコードに直したのですが、その時はStack BOFがあるだけで、フラグが読めそうとは思いませんでした。というのも、Stack Canaryが付いており、オーバーフローしてもすぐに終了してしまうのです。

・第一段階
家で解析したときのCコードを以下に示します。

RC4で暗号化されたデータを復号化するのが目的です。オーバーフローというとret2libcやROPのイメージが強かったので、今回は全く分からない状態からスタートしました。
ここで新たに学んだのは、"argv[0] leak"という手法です。(正式名称でない?)これは、Stack CanaryのStack Smashingメッセージが表示されることを利用し、内部のデータを取得するという方法です。
具体的には、オーバーフローを起こした際の
*** stack smashing detected ***: ./steak terminated
というおなじみのメッセージの
./steak
を取得したい変数に変更します。そのためASLRが有効な場合は固定アドレスに存在するデータが取得する対象となります。今回のCコードを読めば分かるように、key、state、output等のデータはアドレスが固定されています。
どうやって"./steak"の部分を変えるかですが、__stack_chk_fail関数では、普通にargvの内容からargv[0]のファイル名を表示しているそうです。(詳しくはkatagaitai CTFの資料を参考に。)つまり、十分にオーバーフローできる場合、argv[0]のポインタがある部分を取得したいデータのアドレスに書き換えてやります。
これを聞いてさっそく
"\xe0\x20\x60\x00\x00\x00\x00\x00" * 40
みたいなデータ(keyのアドレスを繰り返し)を送ろうと考えたのですが、よく考えたらkeyは使用した直後にmemsetで0にクリアされています。ということでstateを取得したら見事取得できました。と思ったら256バイトあるはずのデータを途中までしか取れていません。これはstateの途中に0x00が存在するのが原因で、
 接続→stateを取得(lengthバイト)→切断→接続→state+lengthを取得(lengthバイト)...
みたいに何度か接続するようにして全てのデータを取得しました。

・第二段階
もともと"What's your favorite food?"という質問に対して答えが正しければ通ります。取得したstateを元に、バイナリから取得した暗号化済みデータを復号化し、それを送りました。ここで新たなバグを使用します。steakは入力の文字数をstrlenで取得し、その分暗号化しているのですが、入力の最初に0x00を持ってくることで、暗号化処理をスキップできます。そうしてチェックを通過すると、自由にメッセージを"./message"に書き込むことができるようになります。
ここで使用するのがShared Library Injectionという手法で、これはLD_PRELOADで自前のライブラリを使用することで攻撃できます。したがって、今回のように自由にファイルをアップロードできる状態か、sshのような形式でないと利用できません。今回は、systemをexecve("/bin/sh", 0, NULL);に変更するようなライブラリを作りました。(messageへの書き込みにsystem関数が呼び出される。)messageに保存できたら、これを利用したいのですが、ライブラリmessageを読み込ませる手段が必要です。

・第三段階
messageを読み込ませるには、環境変数LD_PRELOADを./messageにする必要があります。つまり、オーバーフローを使用してenvp[0]のアドレスを"LD_PRELOAD=./message"を指すアドレスにすればよいのです。こんなコードを作って実行したのですが、ローカルでは「ライブラリをロードできません」みたいなメッセージが出て、リモートではそもそも何も起こりませんでした。ちょっとよく分からないので暇な時にやります。

この他にも様々なexploit tipsを教えていただきました。

まとめ
katagaitai CTFの勉強会に参加させていただくのは今回が初めてでしたが、内容は難しかったものの、その技術は(なんとなく)分かったので、非常に有意義な勉強会だったと言えます。どちらも全く知らなかった攻撃揃いだったので、自分でコードを作りながらも新鮮な感じがしました。難しかったとはいえ、このくらいのレベルはやってて楽しいので、次回も同じレベルの勉強会があれば是非参加したいです。

2016年1月31日日曜日

SECCON 2015 Final Intercollegeに参加しました

2016年01月30日(土)に東京電機大学でSECCON 2015 Final Intercollegeが開催されました。1チーム4人までで、中学生から大学院生までで構成された18チームが参加しました。私のチームはinsecureで、
初めてA&Dに参加したので、何をすればいいかが分からず、かなり戸惑いましたが、その上での感想と軽いwrite upをしようと思います。

各チームに一台のサーバーが割り当てられ、チームメンバーはあらかじめ渡されたパスワードで管理者(root)としてsshでログインできます。開始からしばらくはIPもユーザーも分からなかったので、全員何もできない状態でしたが、しばらくして運営から説明がありました。
サーバーでは3つのサービスを稼働させることができ、私はvulnerable_blogとsbox2015を担当しました。vulnerable_blogはブログの記事を投稿できるサービスです。サイトを見ると、XSSとSQL Injectionの脆弱性がありました。また、SQL Injectionの際のエラーがそのまま出力されます。とりあえず自分のチームのSQLiの脆弱性を修正し、Webアプリの設定をdevelopmentからproductionに変更してエラー出力を無くしました。チームでやったDefenseらしい行動はこれだけで、この防御力が後に悪く影響しました。
ORDER BY等で調べた結果からUNION SELECTを使用しました。

hoge') UNION SELECT 0,0,load_file("/var/www/html/vulnerable_blog/keycode"),0,0#

これにより管理者のパスワードを取得できます。また、自チームのkeycodeが初期状態で"test"だったので、"abc123password"みたいなのに変更しました。これで管理者になり、記事のログの削除キーにボットが登録したフラグが見つけられました。この時点でSQLiを修正していたり、keycodeを変更していたり、何かしら修正していたチームは半分以上あったと思います。
次にsbox2015の脆弱性を探し始めます。sbox2015でruby, php, pythonのコードを投稿すると、ランダムな数字が返され、その数字を同じアプリに渡すとコードが実行できるようになる。とりあえすlsを実行して一覧を取得し、何か無いかを探しました。vulnerable_blogのSQLiが修正されたサーバーについては、sbox2015のコード実行でkeycodeを取得しました。一部のチームはコード実行をできなくしたり、管理者ページにアクセスできなくしたりしていました。
チームメンバーがsbox2015により攻撃された際のコードを保存しておいてくれたので、それと同じ方法で他のチームに攻撃を開始しました。攻撃はmysqlコマンドをrootで実行することにより、他の問題のデータベースの内容を取得しました。自チームではrootでの実行を禁止することで対策しました。(チームメンバーがやってくれました)

他の問題などで脆弱性を突かれて防御点が大きく原点されていたようで、8000点以上の攻撃点を得たものの防御点は-7000点以上になっており、結果は18チーム中の15位でした。

今回のA&Dで分かったことは以下のことです。
・防御専門のメンバーを作る
・フラグの取得は自動化する
・サービスを中途半端に止めるなら、ずっと稼働させておく方が良い
・相手の攻撃から攻撃手法を知ることもできる
・相手の攻撃よりも先に自分のサーバーの修正をする
・上位チームを狙った方が点数はかなり稼ぎやすい

・チームで全部の問題を同時に担当する。(1つでも放置しておくと、それを通して他の問題のフラグも取られる)

とにかく難しかったですが、新しいことばかりで面白かったです。それから可視化システムは相変わらず格好良かったです。参加者のみなさん、運営のみなさん、その他関連している方々、お疲れ様でした。(internationalの方もお疲れさまです。)

2015年11月9日月曜日

SECCON福島大会 サイバー甲子園に参加しました

2015年11月07日(土)に福島の会津で開催されたサイバー甲子園(SECCON予選)に出場しました。10チームが抽選で選ばれ、私(ptr-yudai)のチーム名はinsecureで、theoldmoon0602殿と一緒に参加しました。

結果は2位で決勝の出場権を貰いました。以下が上位3位までの最終スコアです。
 CTF事情を知っている方によると、どうやら1位の方はプロだそうです。
以下は得点の推移です。(上位3チームまでチーム名を残しています)

とりあえず、自分が解いた問題の中で、覚えているもののwriteupを書こうと思います。

binary100
Linuxの32bit実行ファイルが渡されたので、gdbで起動しました。スタックに1を入れて、直後にその値が2より大きいかを調べて分岐しています。setでEIPを変更して続行すると「SECCON{Can Uread me?」と表示されましたが、送信してもポイントゲットならず。色々試して、「SECCON{Can U read me?}」を送ったら正解でした。

binary200:
Linuxの32bit実行ファイルが渡されたので、gdbで起動しました。重要な部分をCっぽく直すと、

gets(s);
for(i=0; i<32; i++) {
  tmp = esp_2C + s[i];
  foo = 0xFF ^ (char)tmp;
  bar = cipher[i];
  if ( bar == foo ) // OK
}


つまり、入力から1文字ずつNOTをとり、それを予め用意されたデータ(cipher)と比較しています。cipherをメモリから出力し、pythonでNOTをとるとフラグになりました。「SECCON{XOR_encryption_message}」

network100
パケットデータが渡されます。ファイル無いので覚えてないですが、認証みたいなのがあるので、見るとBase64文字列があります。デコードしたらフラグでした。(たぶん)

network100
パケットデータが渡されます。なんかエラーが連なっているところがあったので、そこらへんのIPの192.168.44.161でSYNフラグが立っている部分をwiresharkでフィルター(ip.src==192.168.44.161 && tcp.flags.syn==1)します。出て来たパケットを上から見ると、各パケットのオフセット0x12に連続してフラグが1バイトずつ書かれていました。「SECCON{Data_is_included_NOT_ONLY_in_payload_but_also_header_field.}」

net300
パケットデータが渡されます。wiresharkで見るとメールのプロトコルが使われており、中にいくつか送信されたデータがありました。まず目に止まったのが、何行にもわたるbase64文字列です。メールの添付ファイルだなと思ってデコードすると、zipファイルが出てきます。解凍しようとするとパスワードが求められます。メールの送信データの中にパスワードっぽいフレーズがいくつかあったので、試すと開きました。中にあったファイルはComposite Document Fileというもので、theoldmoon0602殿の助言でLibreで開くと、またパスワードを求められます。これもメール内の別のフレーズで試すと開き、フラグが表示されました。「SECCON{Sending_File_Password_with_Followed_Mail_is_bogus.}」


crypt100
「U0VDQ09Oe1VyOXdnbWZZWXh5N2VvOFFnTDJWfQ==」というbase64文字列が渡されるので、デコードすると「SECCON{Ur9wgmfYYxy7eo8QgL2V}」になります。


programming100
turtleとかいうライブラリを使用したpythonのコードが渡されます。windowsのpythonには標準で入っていたので、draw_flag関数を実行すると、亀が絵を書き始めます。ちょっと遅かったので早くし、最後に停止ルーチンを挟むと、国旗が表示されました。theoldmoon0602殿がすぐにミャンマーの国旗であると知らせてくれました。「SECCON{MYANMAR}」


web100
アクセスすると同じページがロードされるので、wiresharkで見るとフラグが受信されていました。

web100
ログインページでしたが、何を入力してもサーバー側でエラーになります(出題ミス?)。Fiddlerで見ると、レスポンスの最後にgzipデータがあったので、抽出して展開するとフラグのページが現れました。

misc100
Excelデータの各セルの背景色が色分けされており、SECCONの「突破」マークがドット絵みたいになっていました。Libreで開くと中央らへんに左三角がたくさん並んでいました。調べた結果から、excelのリスト機能と思って調査しました。とりあえず重たいので背景色を全て削除し、リスト内に「#」が書いているところと書いていないところを区別しようと閉じて、再度開くとなぜか三角が減っており、それらがフラグをAAのように表示していました。「SECCON{NIRVANA_KA1}」


misc100
「作者は誰か」という問題で、短いアルファベット羅列が渡される。ダブルクオーテーションで囲って調べると、たくさんのサイトがヒット。一番上のサイトを読むと、ベートーベンの楽曲のリズム(だったかな?)であることが判明。形式が指定されていなかったので、いろいろ入力しましたが、最終的にtheoldmoon0602殿が正しい形式で送ってくれました。


感想
CTF歴は1年ちょっとで、SECCON決勝を大きな目標として必死に勉強してきましたが、初の予選で決勝への出場権を貰えて嬉しいです。これからしばらくはAttack&Defenceの勉強をする予定です。
問題はちょうど良い難易度で、CTF4bでの講義が結構役に立ちました。
theoldmoon0602殿のプログラミング力は凄く、何やってるのか分かりませんでした。
まだまだ勉強しないと......

2015年10月26日月曜日

TUMCTFに参加しました

2015年10月24日の22:00(日本時間)から24時間開催されたTUMCTFにオンラインで参加しました。
3人でチームを組んで、睡眠も取って15時間以上は参加できたと思います。
世界から455チームが挑戦して(最低でも244チームは1問以上解いていました)、私達のチームは65ポイントで58位でした。

問題はCrypt, Web, Rev, Recon, Misc, Exploitから各5,6問程度ずつ出ました。今回は、私が解いた問題の内、覚えているwhitebox, bad_appleについてwriteupを書きます。

whitebox crypt - rev - 20[pt]
問題文:
Do not panic, it's only XTEA! I wonder what the key was...
ctf.link/assets/downloads/rev/xtea
問題ファイルをobjdumpで見ると、まずstrlenでargv[1]が16文字かをチェックしています。
そこで適当な16文字を渡していき、ブラックボックス的にテストすると、後半の8文字は出力に影響が無いことが分かりました。
さらに、問題文のXTEAで調べると、wikipediaに辿り着き、これを参考に解析を開始します。
wikiによると、暗号化の途中で sum + key[sum & 3] を行うのですが、keyがバレないように、この値は全て予め書き込まれています。
こんな感じ:
  4005a7:       89 ca                   mov    edx,ecx
  4005a9:       89 c8                   mov    eax,ecx
  4005ab:       c1 ea 05                shr    edx,0x5
  4005ae:       c1 e0 04                shl    eax,0x4
  4005b1:       31 d0                   xor    eax,edx
  4005b3:       01 c8                   add    eax,ecx
  4005b5:       35 68 78 70 7b          xor    eax,0x7b707868
  4005ba:       03 07                   add    eax,DWORD PTR [rdi]
  4005bc:       41 89 c2                mov    r10d,eax
  4005bf:       89 c2                   mov    edx,eax
  4005c1:       c1 e0 04                shl    eax,0x4
  4005c4:       41 c1 ea 05             shr    r10d,0x5
  4005c8:       41 31 c2                xor    r10d,eax
  4005cb:       41 01 d2                add    r10d,edx
  4005ce:       41 81 f2 2e ea 58 1b    xor    r10d,0x1b58ea2e
  4005d5:       45 8d 1c 0a             lea    r11d,[r10+rcx*1]



ということで、この sum + key[sum & 3] にあたる値を収集しました。

そのあと、なぜかこのencipherをC言語で書いたのですが、sumやkeyは入力に影響しないと気付いて、すぐにkeyの計算に取りかかりました。
wikiのdecipherを参考に、
・delta = 0x9E3779B9 で固定。
・sum = delta * num_round でnum_roundは今回の場合32個分あった。
・sum -= delta を繰り返す。
・keyは4要素ある32bit整数の配列
と分かりました。
すぐに解読コードを書きました:
#include <stdio.h>
#include <stdint.h>


int main()
{
  int num_rounds = 32, i;
  uint32_t delta = 0x9E3779B9, sum = delta * num_rounds;
  uint32_t l[64] = {0x7b707868, 0x1b58ea2e, 0xba9ae30, 0x9bd661db, 0x9bd661db, 0x4818a1a2, 0x57c7dda0, 0xf44e5f4c, 0xf44e5f4c, 0x9285d905, 0x84879514, 0x326e4acb, 0x14b448bf, 0xb2ebc278, 0xd0a5c484, 0x5f2e023f, 0x6d2c4630, 0xb63bfe9, 0xfd657bf8, 0xa99b39a2, 0x8d922fa3, 0x4983ab68, 0x4983ab68, 0xca012315, 0xe60a2d14, 0x764362dc, 0x764362dc, 0x147adc95, 0x6701687, 0xc0b09a3f, 0xc261924c, 0x60990c05, 0x5ee813f8, 0xe11683b2, 0xef2149c0, 0x8d58c379, 0x7f4dfd6b, 0x2b903d32, 0x3b3f7930, 0xd7c5fadc, 0xd7c5fadc, 0x77ae6ca, 0x67ff30a4, 0xf82be44f, 0xf82be44f, 0xa46e2416, 0xb41d6014, 0x42a59dcf, 0x50a3e1c0, 0xeedb5b79, 0xe0dd1788, 0x8ec3cd3f, 0x7109cb33, 0xf4144ec, 0x2cfb46f8, 0xad78bea5, 0xc981c8a4, 0x59bafe6c, 0x59bafe6c, 0x5f0bc16, 0xe9e7b217, 0xa5d92ddc, 0xa5d92ddc, 0x2656a589};
 
  uint32_t key[4] = {0,0,0,0};
 
  for(i = 0; i < num_rounds; i++) {
    key[(sum >> 11) & 3] = l[63 - i*2] - sum;
    sum -= delta;
    key[sum & 3] = l[62 - i*2] - sum;
  }

  printf("%08x %08x %08x %08x\n", key[3], key[2], key[1], key[0]);

  return 0;
}


出力結果をasciiにし、エンディアンを直したら、}!pu_gnimr4w{pxhとなりました。
これを逆にして、hxp{w4rming_up!}

bad_apple - Crypt -  15[pt]
問題文:
Baby's 1st

ctf.link/assets/downloads/cry/bad_apple.tar.xz

try:
    ncat 1.ctf.link 1027 < good.bin
expect:
    "hello"
xzにはgood.binとbad_apple.pyが含まれていました。
以下がbad_apple.pyです:
#!/usr/bin/env python3
import sys, binascii
from Crypto.Hash import SHA256

key = open('key.bin', 'rb').read()

message = sys.stdin.buffer.read(0x100)
if len(message) < SHA256.digest_size:
  print('len')
  exit(0)

tag, message = message[:SHA256.digest_size], message[SHA256.digest_size:]

if SHA256.new(key + message).digest() != tag:
  print('bad')
  exit(0)

if b'hello pls' in message:
  print('hello')
elif b'flag pls' in message:
  print(open('flag.txt', 'r').read())
送信されたファイルをハッシュ(tag)と文字(message)に分け、sha256(key + message)とtagの値が等しいことを確認します。
さらにmessageが"flag pls"ならフラグが取得できます。
不明な文字を足してハッシュを取る、というプログラムの時点で頭の中はhashpumpだけだったので、hashpumpを使う方向で解きました。
さて、good.binの中の前半のハッシュは「2628455f6617ecea024895a48578ebce00fa9204983d09b6d1757d05dc430567」で、文字は「hello pls」でした。
これを元に、flag plsを付け足したハッシュを作ります。
keyの長さが分からなかったのでpythonでループしました:
import commands
import binascii
i = 32
for i in range(1, 1024):
    ret = commands.getoutput("hashpump -s 2628455f6617ecea024895a48578ebce00fa9204983d09b6d1757d05dc430567 -d \"hello pls\" -a \"flag pls\" -k " + str(i))
    get = ret.split("\n")
    _hash_ = binascii.unhexlify(get[0])
    data = get[1].decode('string_escape')
    buf = _hash_ + data
    f = open("data", "wb")
    f.write(buf)
    f.close()
    ret = commands.getoutput("nc 1.ctf.link 1027 < data")
    print(str(i) + " : " + ret)
    if ret == "len" : continue
    if ret == "bad" : continue
    if ret == "hello" : continue
    break
32回目でフラグが返ってきましたとさ...。
hxp{M3rkL3_D4mg4rd_h4s_s0m3_Pr0bl3mZ}

全体を通して難しかったです。Web30とRev10とExploit10が解けなかったのが非常に悔しいです。あとは上級者向けが多く、1人〜3人程度しか解いていない問題ばかりで、難易度がすごい分かれていました。
もしかしたら暗号が向いているのかなぁ...

CTFで思ったのは、まず、Reconを予告しておきながら、最後の最後で0[pt]の答え無しのページにした運営に驚きました。あと、web20の問題の答えが後半でIRCに書き込まれたせいか、20[pt]にも関わらず145人もの人が後半でこのポイントを獲得しています。

ちょっと難しかったですが、解けたときは楽しかったです。

2015年10月4日日曜日

Arduino UNOを使ってみた

入門者向けキット付きのArduino UNOの互換ボードを安く買ったので、使用してみました。osoyooという所のを買ったのですが、URLのリンクが切れていました。環境はCent OS 7です。
とりあえず公式サイトからlinux 64bitsのIDEをダウンロードして解凍します。arduinoというELFファイルがあったので、実行したらそのまま動作しました。

Arduino自体が電子回路などの入門者向けで、簡単に回路を作ることが可能です。そのため僅か数時間で液晶ボードに文字を表示させるに至りました。いくつか詰まった点を適当に書いていきます。

まず、IDEはルート権限で起動しないと書き込めませんでした。それから、プロジェクトを「main」という名前にしていたらコンパイルできませんでした。その辺で一旦つまづいたところで、まずはLEDを点滅させる回路を作りました。LEDを13番とGNDに直で繋ぎ、プログラムを書き込みます。
書き込む前にメニューバーの「ツール」->「ボード」みたいなところを選択しておかないといけません。届いたキットにマニュアルは付いていないし、製造元サイトも閉鎖されてたので困りましたが、どうやら普通のarduinoと全く同じ方法でやればいいようです。

void setup() {
  pinMode(13, OUTPUT);
}
void loop() {
  digitalWrite(13, HIGH);
  delay(1000);
  digitalWrite(13, LOW);
  delay(1000);
}

言語仕様も非常に分かり易いです。コンパイルして書き込みすると、LEDが点滅しました。わーい。
それだけでは物足りなかったので、セットに付いていたI2D 1602 LCDに文字を表示させようと考えました。かなり前にPIC kitとマイコンでやろうとして、一瞬で挫折した記憶があるLCDに挑戦です。
まずはライブラリをいれます。こちらからライブラリをダウンロードして展開します。これを、~/Arduino/にフォルダごといれ、IDEを再起動するとライブラリが使用できます。
その後もいろんなサイトを参考にしながら、
VCC - 5V
GND - GND
SDA - Analog 4
SCL - Analog 5
に接続して、サンプルのHello, world!を書き込みましたが、液晶画面が光だけで何も起こりません。ここで暫く詰まったのですが、いろいろ見ていると、LCDのアドレスとやらを調べないといけないらしいです。こちらのコードを書き込んで、シリアルモニタでアドレスを確認します。サンプルは0x27だったのに対し、自分のは0x3Fでした。これに書き換えて最初のHello, world!を書き込みました。すると、初期化処理で画面が暗くなる反応を見せたものの、文字は表示されません。さらに調べると、裏にコントラスト調整用の部品がありました。これを回転させると文字が表示されました。

最後に作った電光掲示板もどき。初めての言語なので汚いコードかもしれません。使用する際はLCDのアドレスや画面サイズを適宜変更してください。
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

void display(String buf, int y);
LiquidCrystal_I2C lcd(0x3F,16,2);

int offset = 0;

void setup()
{
  lcd.init();
  lcd.backlight();
}

void loop()
{
  lcd.clear();
  display("Hello, world!", 0);
  delay(300);
}

void display(String buf, int y)
{
  lcd.setCursor(16 - offset, y);
  if ( offset > 16 ) {
    lcd.print(buf.substring(offset - 16));
  } else {
    lcd.print(buf);
  }
  offset = (offset + 1) % (16 * 2);
}

参考:
http://arduino.umemoto.org/home/i2c-lcd
http://forum.arduino.cc/index.php?topic=128635.0






2015年9月13日日曜日

ctf4b熊本に参加しました

2015年09月12日(土)に熊本の東海大学熊本キャンパスで開かれた「ctf for ビギナーズ 熊本」に参加しました。55人が参加しており、学生から大人までいろんな人が参加されていました。
WebとNetworkの講習があり、資料や問題としてはBinaryジャンルもありました。
講習では、CTFの問題を解くにあたっての説明や、各種ツールの使い方などを分かり易く説明していただきました。
CTFでは問題を解いたらランプが点灯しブザーが鳴るようになっていたので、ブザーが鳴るたびに焦りました。あとTDUよりは少なかったですが、変な動画も流れました。

さて、この記事ではCTFの方で問題が残っているものや、覚えているもののWriteupをします。
まず、最終のスコアボード:

わたしはptr-yudaiで2位でした。1〜3位までは同得点なので1位という扱いになりました。正直こんなにとれるとは思ってませんでした。

Other

1:練習問題 (100pt)

ctf4b{〜〜}みたいなのが書いてあるので、そのまま送信します。

6:Universal Web Page(笑) (500pt)

php://filterを使うのかと思ったのですが、上手くいかずに諦めました。500ptだからもっと難しいのでしょうが、誰も解けてませんでした。

Web

2:Can you login as admin? (100pt)

定番のSQLiで、「' OR '1'='1」をパスワードとして入力するとadminになりました。1番上をadminにしている作者さん優しいです。

3:Find the flag (200pt)

どんな問題か忘れました。ディレクトリトラバーサルだったかな?

4:1M4G3 V13W3R (300pt)

私の苦手なファイルアップロード問題です。php送ったりタイプをimage/jpegに偽装したりしましたが、できませんでした。ディレクトリトラバーサル等も確認できず、分かりませんでした。

5:SQL Injection Level 2 (400pt)

SQLiですが、ORが使えません。ORを削除していると予想して「' OORR '1'='1」を送ったら通りました。ちなみに正攻法はUNION SELECTする方法です。

Binary
7:matryoshka (100pt)
問題ファイルはこれです。fileコマンドで種類を調べるとisoだったので、mountでマウントすると、flagというファイルが出てきました。flagはzipだったので解凍すると、またflagが出てきました。これはmicrosoft cabinet的なファイルだったので、linuxのファイルマネージャで開くと、またファイルが出てきました。今度はPNGだったので、見ると、フラグが見つかります。

8:読めますか? (200pt) 【たぶんこんなタイトル】

問題ファイルはこれです。PNGファイルなのですが、Linuxでは開けませんでした。(解説のときはフラグがギリギリ見えない画像が映ってました)中身はぐちゃぐちゃだったので、しばらく悩みましたが、stringsでctfを探すとフラグが見つかりました。

9:Jump (300pt)

問題ファイルは後であげます。実行ファイルなのでIDA Proで見ると、argvを確認しているらしき部分がありました。順番に「ctf」「is」「so」「fun」(だったかな?)をチェックしているので、argvだなと思って、引数を指定して起動するとフラグが表示されました。

10:Readit (400pt)

アセンブリが渡されて、結果の数字を答える問題。疑似言語みたいなのに訳して、面倒そうだったので飛ばしたら最後までやりませんでした。
これです:
mov     [ebp+var_4], 0
mov     [ebp+var_8], 0
jmp     loc_40101F

loc_40101F:
cmp     [ebp+var_8], 0C8h
jge     short loc_40103C
mov     ecx, [ebp+var_4]
add     ecx, [ebp+var_8]
mov     [ebp+var_4], ecx
mov     edx, [ebp+var_4]
sub     edx, 0Ah
mov     [ebp+var_4], edx
jmp     short loc_401016
mov     eax, [ebp+var_8]
add     eax, 1
mov     [ebp+var_8], eax
jmp    loc_40101F:

loc_40103C:
mov     eax, [ebp+var_4]
push    eax
push    offset Format   ; "%d"
call    ds:printf

11:Checkit (500pt)

問題ファイルはこれです。フラグを入力したら正解かを確認するプログラムです。これに時間をとられてしまった上に解けませんでした。丁度このときにタイタニックの笛の動画が流れ始めて、投げ出しました。

Network

12:Insecure Protocol (100pt)

問題ファイルはこれです。telnetしてたので、telnetを見ると、フラグが書いてました。

13:Insecure Protocol 2 (200pt)

問題ファイル無いです。12番のtelnetと同じですが、フラグの部分が埋められていました。そこで、telnet先のサーバーにtelnetで接続して、パケットから抽出したユーザー名とパスワードを入力するとフラグが返ってきました。

14:File Transfer Protocol (300pt)

これも問題ファイル無いです。たしか、FTP-DATAを見たらフラグが見つかったような......。

15:This quiz is a NETWORK challenge (400pt)

問題ファイルはこれです。実行すると、しばらくして文字が表示されたので、ネットに接続していると予想し、wiresharkでパケットを取得しました。すると、basic認証でwebからファイルを取得していたので、ブラウザでアクセスしてbasicを認証して、フラグのファイルへアクセスしました。なんと逆解析して難読化されたコードを読んだ猛者もいました。

16:Oldies Communication (500pt)

パケットファイルなのですが開けませんでした。ヘッダが壊れていたので、別問題のヘッダを参考に修復して開きました。TCPで何かしているのですが、何をしているのか分からず、フラグもスペースで上書きされていて、IPも存在しなかったので解けませんでした。

以上、概要だけですが、writeupでした。
今回、会場に集まるようなCTFはTDUに続き2回目でしたが、好成績を修められてよかったです。とはいえ、SECCONではもっと難しい問題が出るので、まだまだ勉強するつもりです。

お疲れさまでした。

2015年5月2日土曜日

ホストCentOS 7上のゲストWindows 7の3D Accelerationを有効にする

最近メインのデスクトップPCをWindows 7からCentOS 7にし、VMware上にWindows 7を入れかえました。ところが、ホストのWindows 7上でUnityが動かないことからDirectなんたら(Direct X? Direct 3D)が使えないことに気づきました。CentOS関連の記事が少なくて、直すのが結構面倒だったのでメモ程度に書いておきます。

環境:
ホスト:CentOS 7 x64
ゲスト:Windows 7 SP1 x64
グラボ:GTX 640だったかな?あまり関係無いと思います。

症状:
VMwareからWindows 7を起動すると、「3D Accelerationが無効になりました」とか「デバイスが読み込めませんでした」とかのメッセージが表示され、3D Accelerationの機能が使えません。

対処法:
1.driconfを入れてS3TC Texture Compressionとやらを有効にする
まず、このリンク先からdriconfをダウンロードします。解凍してインストール。
tar xfvz driconf-0.9.1.tar.gz
cd driconf-0.9.1
python setup.py install
わーい、driconfが入った〜、と思うとエラーが起きます。
driconf
>〜〜〜
>UnboundLocalError: local variable 'j' referenced before assignment
>〜〜〜
どうやらpythonコードでエラーが発生している模様。
cd /usr/lib/driconf
vi driconf_simpleui.py
viエディタで、260行目あたりに以下の水色の文を追加します。
:
i = chars
j = i
while i >= chars/3:
:
保存すれば、エラーが発生しないと思います。driconfをもう一度実行します。
driconf
すると「Direct Rendering Preferences」というウィンドウが表示されます。
「Image Quality」タブの「Enable S3TC texture compression even if...」をクリックして「はい(Y)」にします。
下部の「Expert Mode」をクリックしてDefaultに保存します。
これで1つ目完了。

2.libtxc_dxtnをインストールする
以下のコマンドを実行してインストールします。
yum install libtxc_dxtn
以上。

3.ホストの設定を変える
ホストがシャットダウンしている状態で、vmxファイルを編集します。(Win7仮定)
cd /home/[username]/vmware/Windows7/
vi "Windows 7.vmx"
以下の文章がなければ追加してください。
mks.enable3d = "TRUE"
mks.gl.allowBlacklistedDrivers = "TRUE"
svga.vramSize = "67108864"

保存します。
最後に、ゲスト(CentOS)の再起動をしてください。

再起動が完了したらVMwareからホストを起動してください。エラーが発生せずに起動できたら成功です。フルスクリーンゲームとかやるひとはmouseの部分の設定も要るみたいですが、調べたらすぐに出てくるのでここには書きません。

-- 追記(2015/05/03) --
翌日起動したら
Vmware Player unrecoverable error: (svga)
Unexpected signal: 11
というエラーが発生しました。
書くのを忘れていましたが、ゲストを起動する前に、3D Accelerationのウィンドウを出しておく必要があります。
driconf &
これで「Direct Rendering Preferences」ウィンドウを一度起動させておかなければいけません。
1つのアプリケーションがグラフィックボードの機能を使った後に、他のソフトが使おうとするとVMwareが同じエラーで落ちることがあります。少なくともCentOSからの3D Accelerationはあまり良い機能を持っていませんね・・・

参考文献:
http://useranswaser.com/answer/how-to-fix-3d-acceleration-for-vmware-workstation-9/
http://ameblo.jp/yukisku/entry-11777593255.html
http://sourceforge.net/p/driconf/bugs/3/

2015年3月31日火曜日

TDU CTF 2014 Satellite in ConoHaへ行ってきました(writeup的な)

2015年03月29日に渋谷で開催された初心者向けCTFのTDU CTFに参加してきました。(CTF後に山梨で予定があったので書くのが遅くなりました。)初心者向けといいながらも上級者が来るんだろうなぁと思っていたら、やっぱり来ました(恐怖)。どこかに集まってやるCTFは今回が初めてだったので問題が解けるか不安でした。CTFには80人弱ほどの方が参加されていました。始めに運営の方々がXSSとかSQLiとかいろんな分野のプレゼンを少しされました。

では、解けた問題について書きます。スコアサーバーには自分の解けた問題や誰が解けたか、問題の点数などが書かれていないので、本当はもっと解いた問題、解けなかった問題があると思いますが、とりあえず思いついただけ。

web
・Easy SQLi Test
何かを検索するフォームがあります。適当に入力してもヒットしません。SQLi苦手なんですが、Easyと書いてあるのでテンプレで
" or 1=1;--
と入力すると全部出てきました。一番最後にフラグが書かれていました。この問題には複数のフラグがあり、flagTableに次のフラグが~みたいなのが書かれていましたが、ここで断念。

・Simple Uploader
ファイルをアップロードできるサイト。これもテンプレでphpをアップロードすると動きました。
<?php phpinfo(); ?>
を送るとphpinfoを見ることが出来、そこにフラグも書かれていました。この問題も複数のフラグがあるということで、
<?php system("cat /etc/passwd"); ?>
を送るとパスワードの中にフラグが。
<?php system("ls"); ?>
するといろいろあったので見てみるとこんな画像ファイルが。モザイクが掛かって見られないのですが、これはフラグなのかな?解けませんでした。もしかしたら誰かがアップロードした妨害用のファイルかもしれません。分かりません。
(追記:03/31/2015)他の方のwriteupを見るとこれと同じような画像ファイルがありました。そちらはモザイクが掛かっていなかったので、別の場所にこのファイルの元画像があったと思われます。

binary
・Trip Picture
ほしい方はダウンロード。
何かのストラップの写真があるので、バイナリエディタで見ると最後に
Flag is TDU{LoveLiverInKyoto!}
と書かれていました。私の知識不足でLoveLiverというものが何なのかが全く理解できていません。(アニメ?)

・読めない文字1
base64っぽいのでecho ~|base64 -dでデコード。またbase64っぽいのが出てきたのでもう一回デコード。終わり。

・ASCII Art
ほしい方はダウンロード。
zipが渡されるものの開けないのでバイナリエディタでみるとフラグがAAで書かれている。
TDU{HEXEDIT!}

・ string_compare
ほしい方はダウンロード。
exeが渡されるので、IDA送り。TDUで検索するとprintfの前に「TDU{%s_is_very_cutie}」とあったので、%sにあたるアドレス[ebp+var114]を探すと「MinamiKotori」と書いていたので
TDU{MinamiKotori_is_very_cutie}
がフラグでした。(´・ω・`)知らんがな

forensic
・ Evidence
ほしい方はダウンロード。
運営のnomukenさんが殺されたので、犯人グループの作戦名を掴んでくれ、みたいなフォレンジック問題。私はフォレンジック問題好きなので期待していたのですが、forensicカテゴリの問題は結局最後までこれ1つだけでした。(´・ω・`)
いつもはTSK使ってるのですが、TDU CTFで紹介されていたFTK Imagerというのを使ってみると、削除されたフォルダかな?にpdfが入っていたので開くとフラグがありました。
作戦名:TDU{OIL_SARDINE}


crypt
・我が同胞に告ぐ
単一漢字変換やシーザー暗号などを思わせる文字列があるのですが、すぐにvimだと判明。入力すると
vimisawesome
なのでTDU{vimisawesome}がフラグでした。
私は基本Emacsです。(たまにvimも使いますが)

network
・ 柚子胡椒 Vol.1
ほしい方はダウンロード。
pcapが渡されるので見るとフラグが送られていました。
TDU{bLu3T00tHDeTH}
TDU{PiNC0De2}
の2つがあったのですが、どっちがフラグだったか忘れました。


misc
・(タイトル忘れました)
TwitterアカウントのURLがあるので、TwitterIDをフラグにするだけ。

・Mini Quiz#1
何かの文章が問題として書かれています。意味分からなかったのですが、何かの引用かと思い調べてみると「ThinkPad X300が~」とあり、ちょうど穴埋めになっていた所がX300なので
TDU{X300}
でした。

・Mini Quiz#2
[単語]->[数字]の形式が並んでおり意味不明だったので、単語部と数字部を並べて調べるとOS Xのバージョンだと判明。Leopardとやらについて聞かれていたので、小数点を抜いて
TDU{105}
でした。




ここから先は解けなかった問題たち。
・unknown file
ほしい方はダウンロード。 
ファイル内が全部0x20で埋まっており意味不明。ファイル名に意味がありそうでしたが分かりませんでした。他の方のwriteup見るとTDUで検索したら出てきたとあるので、運営サイトのネットワークの問題?始めはおかしいと思い何回もダウンロードし直したんですけど、よく分かりません。

・Developper! Developper! Developper!
ほしい方はダウンロード。
zipファイルはパスワードかかっているのですが、ヒントに「無圧縮」とあったので調べるも解けませんでした。pkcrackというソフトで中のファイルと手持ちのファイルを平文攻撃することでパスワードが分かるとか。とても参考になりました。

・Omikuji
ほしい方はダウンロード。
おみくじができる実行ファイル。 TEMPに何か作ってるのは分かったのですが、どうやらネットワークで通信しているようです。

・(タイトル忘れました。string encoderだったかな)
ほしい方はダウンロード。
IDAで見るとメモリ上にフラグが見つかりそうな予感だったので起動しようと思ったのですが起動できませんでした。VC++2013再頒布入れたのに起動しませんでした。隣の方も起動できずに悩んでいる様子でした。次からはgccでstaticするか、VC++は知りませんが、必要なライブラリは全部埋め込んでほしいです。あと要望といえば、スコアサーバーでフラグ入力しても何も起こらないことが多々ありました。Javaだからかな。

・(タイトル忘れました。Phoneなんたらだったかな)
ほしい方はダウンロード。
まったく分からず。

・かっこいいフラグたち
なんと表示されているフラグを入力するだけでptがもらえるというかっこいいフラグがありました。入力する文字によって、-5000ptから-200ptくらいまで、かっこいい点数を獲得できます。かなり上級者向けの問題だったので解けませんでした。



他にもたくさん問題はありましたし、特にweb系では見つかっていないフラグがたくさんあると思います。
結果920ptを獲得して順位は20位でした(´・ω・`)初めて参加したにしては良い方かな・・・それに上級者多かったし・・・。まぁ次は10位くらいにはなれるように頑張りたいです。

とにかく、CTFってこんな感じなんだなぁ、というのが分かりました。問題を解くだけでなく、一体どこから拾ってきたんだというくらいの膨大な量の妨害用のBGM・動画が常に流れる会場も、貴重な経験になりました。

参加者・運営の皆さんお疲れ様、ありがとうございました。

2015年3月1日日曜日

セキュリティ体験講座 - ハッカーになってみよう、やってみよう -

02月28日に、兵庫県立大学大学院で開かれたセキュリティ体験講座の中の1つ、ザッカーリ・マシスさんの「ハッカーになってみよう、やってみよう」に参加しました。

前半はハッキングとは何か、過去から今までにどのようなハッカーがいたか、その目的はなにか、どのように攻撃するか、など幅広く説明して頂きました。短い時間の中で、さまざまな攻撃方法が説明されました。特に今回は一般向けなので、分かりやすかったです。
宿題(?)も出されました。
・ ・ ・
・ ・ ・
・ ・ ・
この9つの点を直線で一筆書きで結んだとき、4本や3本の線で結ぶ書き方はあるだろうか、というものです。答えは説明されませんでしたが、何が言いたいかと、その答えもたぶん分かりました。

後半は実際にコンピュータへ侵入する演習でした。ゲストのKali LinuxからゲストのDe-Iceサーバーへ侵入します。一般向けなのでCTFなどとは違い、一応簡単な説明を受けながら行いました。とはいえ、どのようなツールを使うべきか、などから自分で探していきます。(3人で2台のパソコン)
ということで、覚えている限りで、どのように侵入したかを書いておきます。
まずnetdiscoverで攻撃先のIPアドレスを特定します。
 netdiscover -i eth0
そしたら、定番のnmapで開いているポートを調べます。あとOSの種類も調べたいので-A指定もしておきました。(IPは192.168.1.100でした)
 nmap -Pn -A -p 0-65535 192.168.1.100 
そうすると、http, sshなど複数のポートが開いており、Linuxやカーネルのバージョンまで調べることができました。
ここで、metasploitのsearch及びsearchploitを使って、使用されているサービスの脆弱性情報を調べます。
(例)
 msfconsole 
 msf>searchploit openssh 
今回は脆弱性のあるサービスはなく、ただ侵入したいだけなのでDoSで落とすことなどは考えませんでした。
使われているサービスはたくさんありましたが、特に問題のあるバージョンのものや、脆弱性は見つかりませんでした。
そこで、hydra及びmedusaを使って総当り攻撃をすることにします。
まず、ユーザー名とパスワードのリストを作らなければなりません。攻撃先のホームページ(今回は192.168.1.100)を見ると、いわゆる社員情報的にメールアドレスがたくさん書かれていました。adamsa@~~~とか十人くらいの名前があったので、これがユーザー名ではないかと思いリスト化。パスワードリストは用意してくれてたのですが、展開すら面倒だったのでKali付属のnmap.lstを使いました。ここでhydraを使用しましたが、なかなか成功する気配がありませんでした。
そこでマシスさんから2つヒント(?)が与えられました。
adamsaやpatrickpなどに対し、ユーザー名はaadamsやppatrickなども考えられるよね、ということ。それと、こちらは時間の問題もあって答えにグッと近づけるものなのですが、ユーザー名とパスワードが同じだよということ。
ということで、ユーザーリストにaadamsなどいろいろ追加し、medusaでsshに仕掛けてみます。
 medusa -U users -e ns -h 192.168.1.100 -M ssh | grep SUCCESS 
すると見事にhoge(ユーザー名忘れたのでここからhogeにします。)が当たりました。
早速sshで接続
 ssh hoge@192.168.1.100 
 hoge' password : hoge 
 [hoge@192.168.1.100]$ 
はい入れました。
早速/etc/passwdや/etc/groupを取っていったのですが、ここで問題発生。/etc/shadowが取れない、つまりルート権限ではなかったのです。私はこれ以上進むことはできませんでしたが、非常に面白かったです。前でマシスさんがadams(root権限)で入ってて、いつの間にっ、という感じでした。
あと、ここまでには書きませんでしたが、ツールを使ったら、wiresharkでどんな通信が行われているかを確かめるなど、具体的な動作も確かめることができたので良かったです。

今回はサーバーへ侵入するという設定で行い、演習に来ていた他の方々も、甘いセキュリティに侵入することがいかに簡単かということを強く実感されたそうです。私は家で自分でセットした環境でしか侵入をしたことがないので、実際にホワイトハッカーの方の経験などを教えてもらい、侵入のコツをつかめたような気がします。大変有意義な講義、演習でした。
またこのような講義、演習があれば是非参加したいです。

2015年2月18日水曜日

セキュリティ・キャンプ・フォーラム2015

02月14日の土曜日に品川で開かれたセキュリティ・キャンプ・フォーラム2015に行ってきました。
本当は、13日に兵庫県立大学院でセキュリティ体験講座を受けてから行く予定だったのですが、夜行バスの時間を間違えてしまい、体験講座の方はVODで諦めるということにしました。

さて、フォーラムは、前半はキャンプ卒業生、協賛企業、政府からのメッセージなどでした。
キャンプ卒業生で起業をした人など、面白い 話を聞くことができて参考になりました。企業の方からは、企業内でのセキュリティ部門はどのような働きをするかなど、実際の現場について説明してもらいました。政府からは、セキュリティ人材の不足や、省庁のセキュリティの実情などが話されました。午前の話は個人的には将来に関わる内容が多かったです。
午後は、CTF、XSS、VM/カーネルを受けました。CTFはネットで開催しているものを除き初めてだったので、本当に短い時間とはいえ、わくわくしました。問題はリバースエンジニアリングのもので、出題者は簡単簡単と言うものの、結局時間内に解けたのは1人だけのようでした。リバースエンジニアリングは苦手分野でありながら、問題のファイルが環境変数を使っていることなど内部の動作がそこそこ分かったので、ほんのちょっと自信が付きました。ASCIIがたくさんあるところを探したのですが、結局"Flag:"の部分しか出てきませんでした。(そんな簡単なわけあるか。)
Shibuya XSSでは、最新のXSS事情や、XSSから少し離れたweb系の面白い話、また実際に攻撃から守る仕事をした人の話など、XSSだけでなく色々なことが聞けました。Web系の脆弱性には割と興味があって以前から勉強していたので、知らないことがたくさん知れてよかったです。
VM/カーネルは私には少し難しかったようにも思えます。始めにロボット関連のセキュリティの話があり、パソコン以外のデバイスのセキュリティも勉強してみようかなという気になりました。SECCONの決勝戦でサーバーを管理している方の話は、なんとなく分かったような感じです。やっぱりSECCONともなると、運営も高度な技術を求められるようです。VMの話では、VMを検出するマルウェアや、新しいマルウェア解析のアプローチなど低レイヤーの話をされました。私ができるようなことではありませんが、非常に興味深い内容でした。

今回のフォーラムでは、セキュリティやその他もろもろの分野で有名な方の話、また実際にセキュリティに関する実話など貴重な話を聞くことができて、とてもよかったです。

あとキャンプ卒業生は協賛企業からいろいろプレゼントを貰いました。ありがとうございます。

2014年12月19日金曜日

Windowsにrailsを入れる

Ruby on Railsを使うためWindowsマシンにrailsを入れようとしたのですが、はまった点がいくつかあるのでメモ程度に記録しておきます。
railsをインストールしようとgemを使うと次のようなエラーを吐かれました。

 SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: 
 certificate verify failed 

色々と調べてみると解決策になるようなサイトを発見。こちらです。
  1. ここから証明書ファイル(AddTrustExternalCARoot-2048.pem)をダウンロード。
  2. gem which rubygems でRubyGemsのディレクトリを確認。
  3. その中のssl_certsに証明書ファイルを配置。
これによりrailsをインストールすることに成功しました。
その後スケルトンを作成しようとしたのですが、以下のように警告されました。

 DL is deprecated, please use Fiddle

アプリケーションのフォルダ構成は正しそうだったので続けてrails serverを実行しようとしたら怒られました。

 Run `bundle install` to install missing gems. 

どうやらbundleというのをインストールできていなかったようです。指示された通りにbundleをインストールしました。その後もう一度rails serverを実行すると、相変わらず警告は出るものの動作しました。
さぁ、これでやっとRuby on Railsが使えるわけです。

2014年12月14日日曜日

情報オリンピックを受けてみました

今日(2014/12/14)の13時から3時間の間に問題を解く情報オリンピックの予選を受けてみました。
こういう問題形式の競技に出るのは今回が初めてでした。
予選はネット上で行われ、6問の問題にそれぞれ5つの入力ファイルが用意されています。入力に対する出力とプログラムのコードを提出して、それが採点されるようです。
どんなものかと気になったので試しに受けてみた程度です。他の人がどのくらい解けたのか分かりませんが、結果はあまりよろしくないみたいです。問1~3と問5の入力1だけ終わりました。
どんな問題が出て、何が難しかったかを簡単にまとめます。

まず問題の簡単な説明から。
  1. 水道料金を求める問題
  2. 番号(人)を当てるゲームの合計得点を算出する問題
  3. 各地点での天気を調べる問題
  4. 町間の移動にかかる最低限の労力を求める問題
  5. 砂場の城が波で崩れなくなる(安定する)までの波の数を求める問題
  6. 財宝の山分けで、ある条件を満たした上でBさんが最も満足するパターンを求める問題
対して解けなかったわけですが、それぞれ何が難しかったかを書いておきます。
1.問題文通りに実装すれば難しいものではありません。
2.二次配列を使いました。そこらへんとループを問う問題かと思われます。
3.文字の入力を問う問題。これも特に問題は無い。
4.総当りを使うのが手っ取り早いかと思われます。友達は総当りで解いていました。
5.問題文をじっくり読んで実装する問題。入力2から計算量が異常に多くなり計算が終わりませんでした。そこをどう最適化するかを問う問題かと思われます。
6.これも総当りで解けそうでしたが時間が足りませんでした。

今回が初挑戦ということもあるのか、少ししか解けなかったのですが、こういった競技
がどのようなものかを知ることができました。

言語は自由なのですが、C言語を使いました。実はC言語あまり使ったことがないので外部ライブラリではprintfとscanfしか使ってません。
アルゴリズムよりもC言語を先に勉強した方がいいかな。
とにかく、次挑戦するときはもう少し勉強して4問完全くらいは解きたいです。

---------------------- 追記(2014/12/19) -----------------------
 数日前に結果が公開されましたので一応書いておきます。
結果は320点でランクはBでした。こういうのは初めてなのでこれくらいでいいかな、という感じです。
一緒に受けた友人は420点でAランク、全国大会に行ってくるようです。ぐぬぬ。