応募用紙#2
-----------
■選択問題10
アンチデバッグというのは、ソフトウェアの解析をされてしまうのを防ぐ手法のことです。
ただ、解析を防止するといっても、これまでの解析防止手法はすでに破られているものがほとんどで、完全に解析を防止することは困難です。
そのため、完全に解析を防止しようとするのではなく、解析にかかる手間と時間を増大させ、解析するための労力と解析で得られる成果を見合わなくさせ解析を諦めさせるという考えが主流となっています。
学術、情報処理技術の分野では「耐タンパー技術」と呼ばれていて、難読化もこの技術のうちの一つとして知られています。
また、アンチデバッグはマルウェアなどにおいても、セキュリティソフト対策などに用いられる場合が多くあります。
解析防止の具体的な手法としては、WindowsAPIの一つであるFindWindow関数などを使用することにより、Process MonitorやOllydbg、wireshark、IDAなどの解析ソフトウェア自体を検知しソフトウェアの実行を停止する手法や、デバッグをする際breakpoint の挿入などによって命令間の処理時間が遅れるのを検知して実行を停止するなどがあります。
プログラム解析ツールの検出に使用されるAPI関数は先ほど挙げたFindWindow関数の他に、Windows上で実行されているプロセスを列挙するためのAPI関数であるProcess32FirstやEnumProcesses、EnumWindows関数と併用してウィンドウのタイトルを取得するGetWindowTextやGetClassName、自分のプロセスがデバッグされていることを検出するIsDebuggerPresent、特定のプロセスがデバッグされていることを検出する CheckRemoteDebuggerPresent、解析ツールが使用する特定のドライバなどを検出するCreateFileなど多数存在します。
通常のソフトウェアはアンチデバッグに以上の手法を取っていることが多いですが、マルウェアにおいては、過激な解析防止手法として「ロジックボム」と呼ばれるものを使っている場合が見られます。
ロジックボムとは、自身が解析されているのを検知すると、即座にハードディスク上のシステムファイルを削除するなどの危険な動作をするものです。
また、近年では解析されているのを検知すると、マルウェアとしての挙動を一切行わないようなものも増えていて、マルウェアを解析するときは注意が必要です。
また、もう一つアンチデバッグの手法として有名なのが、実行可能ファイルの各セクションを暗号化または圧縮する手法です。
実行可能ファイルのエントリーポイントを復号化または展開処理を行うプログラムコードの先頭アドレスにし、セクションごとに暗号化または圧縮をしておき、実行時には複合処理などを完了させてから本来のエントリーポイントへ実行処理を引き継がせます。
そうすることで、プログラム解析を防止することができます。
このような手法を行うソフトウェアを総称して「パッカー」と呼んでいます。
有名なパッカーとしては、UPX,PECompact,ASPackなどがあります。
ただアンチデバッグの効果としては、有名なパッカーはたいてい専用のアンパッカーが存在していたりするため、解析者の労力を増やす目的で用いられます。
次に、アンチデバッグの手法である難読化について説明します。
難読化とは、プログラムコードの実行処理の流れを意図的に複雑にして、逆アセンブラなどによる解析を困難にさせる解析防止手法のこと、またはソースコードを人間がなるべく理解しづらいものにする手法のことです。
難読化が必要な具体例を出すと、Microsoftの.NET用に作られたプログラムは、表出的なファイル構文を使用して実行可能コードMSILと呼ばれる中間ファイルを配信します。
このような中間ファイルはバイナリのマシン語コードよりも高度なもので、人間に理解可能な識別子やアルゴリズムを積み重ねたものです。
そして、.NETの逆コンパイラは誰でも無償で入手でき、これを利用すると簡単にリバースエンジニアリングすることができます。
そしてリバースエンジニアリングをされてしまうと、プログラムの隅々まで調べられ、セキュリティ上の欠陥を探して利用したり、ソフトウェアのアイディアを盗んだりされてしまいます。
それを防ぐために、ソースコードを難読化させることによって、デバッグや逆コンパイルを防止することが必要となってきます。
また、悪意あるWebサイトや正規サイトを改ざんしたものは、検出回避や挙動を隠すためにjavascriptが難読化してある状態で埋め込まれている場合が多いです。
通常のWebアプリケーションなどでも、可読性よりも効率を重視してminifyされたものが利用されています。
minifyとはHTTPリクエストの数、量、頻度を削減してページが表示されるまでの時間の短縮をするものです。
ソースコードの難読化についてはプログラマにとって頭の体操になると言われ、難読化の創作性などを競うコンテストなども行われています。
私が知っている難読化の技術の中で、一番はじめに知ったのはサイボウズ株式会社の竹迫さんが開発したperlの難読化である「ppencode」です。
ppencodeの動作例を以下に示します。
http://www.namazu.org/~takesako/ppencode/demo.htmlにて、「abc」を出力するppencodeのソースコードを出力させると以下のようになります。
(略)一見、なんのソースコードか全く分からず混乱すると思います。
このソースコードを読みやすいように整形すると、以下のようになります。
(略)
4行目以降が、文字を出力するコードとなっています。
まず、q e〜eでクオートされた文字列”ach l”をordに渡しています。
その後、ord関数は文字列の先頭のasciiコードを返すので、chrに0x61を渡します。
そして、chrで0x61を文字’a’に変換し、print関数で出力しています。
以上の操作の繰り返しで、順番に’a’,’b’,’c’を出力していることが確認できます。
このように、一見人間では読めないようなコードでも、ちゃんとperlとして実行することができます。
過去、私がプレイしていたオンラインゲームなどではアンチデバッグ手法を用いてきたものがたくさんありますが、破られて不正行為などを許してしまい、ゲームバランスが崩壊しているところが多かったです。
現在では、ほとんどの機能をサーバ側で管理するなどの手法をとることにより、デバッグされてもなるべく何もできないようにしているところが多いです。
それでも完全には不正行為を防ぎきれていませんが、私が知る限り不正行為は格段に減ったようです。
以上のことから、私はアンチデバッグや難読化はあくまで完全にセキュアなソフトウェアを作ることは現時点では困難で、他のセキュリティシステムと合わせて利用する必要があると思っています。
----------------
■選択問題11
まず、このバイナリはpcapファイルではないかと判断しました。
pcapファイルの特徴として、先頭の4バイトはマジックナンバーと呼ばれ、「D4 C3 B2 A1」と決まっています。
そして、問題のバイナリを見てみると、見事に先頭の4バイトがpcapのマジックナンバーと同じになっているため、pcapファイルだと判断できました。
そして、このバイナリをバイナリエディタに書き写して保存し、wiresharkで開いてみたところ、SSLパケットが1つ確認できました。
フレーム情報を見てみると、このパケットが受信ノードに到着した時刻は、日本時間で2014年10月17日19:12:24となっています。
pcapファイルの大きさは106バイトとなっていて、バイナリを見てみると122バイト記述されているため、バイナリファイルの先頭16バイトはファイル形式などを決めているとわかりました。
次に、このパケットをOSI参照モデルの低い順に分析します。
データリンク層での通信に注目し、MACアドレスを見てみると、送信元MACアドレスは11:11:11:11:11:11で、受信側のMACアドレスは22:22:22:22:22:22となっています。
送信元の先頭オクテットのGLビットを見てみると、0なのでグローバルMACアドレスで、受信側のGLビットを見てみると、1なのでローカルMACアドレスとなっていることがわかります。
そして、さらに同じオクテットのIGビットを見てみると、送信元の方は1となっているため、ブロードキャストまたはマルチキャストをしていることになっています。
また、受信元ではIGビットが0となっていて、ユニキャストをしていることになっています。
ですが、MACアドレスは見る限り偽装していると思われるため、MACアドレスの分析はあまり意味をなさないと感じました。
上位プロトコルを識別するタイプフィールドでは、0x8000となっていて、これはIPv4を表しています。
では、続けてネットワーク層を見ていきます。
ヘッダーの長さは20バイト、パケット長は68バイトとなっています。
送信元のIPアドレスは、192.168.146.1、受信側のIPアドレスは192.168.146.128となっています。
そして、フラグメント禁止のフラグが立っているため、このパケットはMTUが自身のパケット長よりも小さいノードには到達することができません。
また、TTLは128に設定されています。
では、トランスポート層を見ていきます。
まず、通信はTCPを用いていて、送信元のポートは4134、受信側のポートは443を使っています。
そして、TCPの443ポートで用いられているプロトコルは、SSL/TLSで、バージョンはTLSv1.2を使用しています。
SSLの仕組みは、まずサーバからクライアントにSSL証明書を送ります。
クライアントは送られてきた証明書をTrusted 3rd partyに送信して、有効かどうかを確認します。
そのあと、クライアントが鍵を認証書に書かれていたように暗号化しサーバに送ります。
そして、サーバとクライアントそれぞれでセッションキーと呼ばれる鍵を作り、セッションキーを使って暗号通信を開始します。
以上のような流れでSSLは動いています。
パケットの内容はHeartbeat Requestとなっています。
Heartbeat Requestとは、SSL HeartbeatというSSLの死活監視をするための機能として使われているものです。
SSL Heartbeatは、2011年にOpenSSLに導入された拡張機能で、RFC6520として登録されています。
SSLは通信をkeep-aliveする機能がもともとなかったため、SSLで通信状態を保つ為に導入されました。
Heartbeat Requestを相手に送り、Heartbeat Responseが返されたら既存の接続を維持するという仕組みとなっています。
また、Heartbeatにはとても有名で危険な脆弱性があります。
Heartbleedと呼ばれる脆弱性です。
Heartbeatは、Heartbeat Requestでパケットのデータサイズを明記してあり、Heartbeat Responseで同じデータの大きさ分をリクエストからコピーしてきて、パケットにつけて返します。
その時、パケット長の情報を大きな値に書き換えると、リクエストは大きな値の分だけリクエストからコピーしてこようとして、結果内部にあるクライアントに知らせるのを意図していないデータが一緒にコピーされてしまいます。
そして、そのままレスポンスしてしまうことで情報漏洩が起きてしまいます。
この脆弱性をHeartbleedと呼び、CVE-2014-0160に割り当てられています。
以下に通常のHeartbeatの動作例とHeartbleedの脆弱性を攻撃時の動作例を図で表しました。
(略)
では、このHeartbleedの脆弱性がありそうだということを頭に入れて、今回の問題であるパケットの詳細を確認していきます。
(略)
Payload Lengthは3835バイトとなっていて、それに反して実際のPayloadは4バイトとなっています。
このことから、このパケットはHeartbleedの脆弱性を攻撃しているものだと判断できました。
実際にこのパケットをHeartbleed対応しているSSL/TLSで送ると、応答で3831バイトの情報漏洩が生じることになります。
また、修正パッチでは、リクエストメッセージ長が改変不可であることを利用して、レスポンスメッセージ長が実際のリクエストメッセージ長よりも長かった場合は、破棄されるような条件分岐を追加しました。
最後に、一番下にPadding and HMACとあるのがわかります。
Paddingは埋め合わせの値を示していて、HMACはHash based Message Authentication Codeの略で、メッセージを送受信する際に相手が成りすましでないかどうかや、途中で改竄されていないかどうかを調べるための認証符号です。
以上がバイナリから判明した情報です。