【勉強会等参加記録】セキュリティキャンプ2019で提出した課題を晒す【セキュリティキャンプ】

 

ようやく大学の試験期間が終わったのでセキュリティキャンプの課題晒しをする。こんな回答でもセキュリティキャンプの選考通るけどもっと素晴らしいもの(熱意が伝わるようなもの)を書き上げてね💛

そもそもセキュリティキャンプとは?

www.security-camp.or.jp

まぁここに書いてある通りである。残念ながら年齢制限があるようなので行けるうちに行っておこう。2019年度から新しくセキュリティネクストキャンプなるものが新設されたようで、キャンプ修了生でも25歳以下なら参加できる。修了生じゃなくても修了生と同等の技術があれば参加できるようである。

セキュリティキャンプは主に選択コースと集中開発コースに分かれていて、私は選択コースの脆弱性マルウェア解析トラックに参加することになった。詳しいことはおいおい書いていくとして、とりあえず私の回答を後悔(?)していきたいと思う。

問1

 
## 問1
あなたが今まで作ってきたソフトウェアにはどのようなものがありますか?また、それらはどんな言語やライブラリを使って作ったのか、どこにこだわって作ったのか、たくさん自慢してください。 

 

回答

 

褒められるような出来のものを作成したことはないが、強いて言うなら、学部一年の時に作成した、ロボットの状態を3Dモデルで表示するプログラムとセンサから取得した二酸化炭素濃度をロボットの操縦者に表示するプログラムについて記述したい。ロボットの状態を3Dモデルで表示するプログラムはロボットのモーターの回転数をエンコーダーで読み取り、その値を受け、ubuntu上で動作するROS(Open Roboticsによって開発されたオープンソースソフトウェア。ロボットの開発に融通を利かせるために、開発時にあえてセキュリティの機能を外している)の可視化ソフトであるRviz上に出力するプログラムである。このソフトウェア動かすには、移動をシミュレートするC++のプログラム、ロボットの状態を記述するxmlのコード(URDF:Unified Robot Description Format)と実際にプログラムを起動するためのlaunchファイル(xml)を         作成しなくてはならなかった。当時はやっとC言語の学習を終えたばかりであり、セキュリティ系の知識はおろか、その他情報系の知識が皆無な状況だったので、毎日、その日の講義が終わったら、すぐに工房に向かいQiitaなどに公開されている、過去に同じようなことを行った人の記事を参考にしながら、先に挙げた三つのソフトウェアを作成していった。毎日帰宅が0時を過ぎるような状態だったため、自分の力不足を痛感させられた。また、公開されている技術情報を参考にしたとは言え、そもそも情報がそこまで多くなかったので、ひな型となるソースコードを作成したら、変数に思い当たる値やファイル名を代入して、実際に3Dモデルがrviz上に表示されるのか表示されないのか、表示されたらなぜ表示されたのかなど、完全に手探りの状態で開発を進めていった。また、launchファイルを実行してもrvizが立ち上がらないという問題も発生していたため、対処すべき課題は少ないとは言えなかった。結局、launch後にrvizが立ち上がらない問題はrvizの使い方がよく分かっていなかっために、rvizでの設定が間違っていた。3Dモデルが表示されない問題はURDFで指定したstlファイル(Standard Triangulated Languageの略で、三次元形状のデータを保存する。)が正しいディレクトリに格納されていなかったためだった。とりあえずrviz上に3Dモデルを表示させることは出来たので、次は、その3Dモデルがロボットの動きに連動して、ロボットの姿勢を反映してくれるかどうかを実験した。案の定うまく動いてくれなかった。うまく動かなかった現象としては、rviz上のサブクローラーが実機の運動に連動していない、連動していても実機の運動以上の動きをする、回転軸がずれている、描写時のフレームレートが高すぎて、rviz上に描写すると点滅が発生するなどの現象が発生した。(参考として、ロボットは六つのクローラーで移動し、車体の側面にメインクローラー二つ、メインクローラーの前後両端にサブクローラーが一つづつついている)これらの問題の多くは、シミュレートを行うc++プログラムに問題があると思われたため、プログラムの修正を行っていった。こちらも、rvizにモデルを表示させる時と同様に手探り的な開発になってしまい、c++プログラム内の値をちょうどよくなるように調整していった。結局、大体の挙動の問題は解決したが、サブクローラーの回転軸がずれている問題だけはどうしても解決できず、操縦者がうまく解釈して機体の状態を把握してもらうということになってしまった。二酸化炭素濃度を表示するプログラムは、当初センサーで収集した情報をサーバーを通して取得し、ロボットやその周辺の環境を統合的に表示する環境に表示する予定だったが、その環境の開発が思うように進まず、ターミナル上に表示することになった。Pythonを用いて作成したが、先ほど同様、Pythonについても全く触れたことがなかったので、既に作成済みであったサーバーとの簡単なやり取りをするプログラムを改造して使用することになった。こっちの方は実装はそんなにつまずくことはなかったが、実際にセンサーに息を吹きかけて二酸化炭素ノードが上昇するか実験してみたところ、著しい上昇は確認できなかった。そもそも、開発時点でどのくらい濃度の上昇があったら正しく動作しているか?センサーは本当に正常しているのか?(使用したセンサーが非常に安かったことと、アマゾンのレビューがあまり芳しくなかったため)などの認識が共有されていない中での開発であったので、開発がうまくいったとは言えなかった。何かしらの開発を行うときは、技術的な事柄以外にも、チームメンバーでよく協議することが大切であるということを体験した。これらのソフトウェアは2018年の5/3~5の間に岐阜県大垣市で開催されたロボカップジャパンオープンのレスキュー実機リーグに向けたものであったが、上記の理由で実装はされなかった。これらのことを通して、技術情報を常日頃から収集する必要性を感じた。また、このプロジェクトに参加するにあたって、こういった技術的な事柄を含むプロジェクトは、その内容が本当に好きじゃないと続かないということを実感し、以前から興味を持っていた情報セキュリティに関して、本格的にセキュリティに関する技術を勉強するきっかけになり、新潟大学の独自カリキュラムである、創造プロジェクトにおいて、新たに情報セキュリティに関する技術を習得するためのプロジェクトを設立する契機にもなった。

 はい。出だしから自慢の逆を行っている気がするので、自慢せよといわれたら自慢しよう!私は学部一年の時にはレスキューロボットを開発するプロジェクトに所属していた。他大学のことはよく分からないが、私の大学には講義の一環として、学生が自ら課題を設定し、それに対して取り組むことで技術力の向上を図っていくという講義がある。そのなかでいくつかプロジェクトがあって、その中のレスキューロボットを作るプロジェクトに所属していた。(過去形ということは現在は違うのであって、その話もそのうち出来たらいいと思っている)その時に開発したプログラムについて書いた。ここは個人がどんな経験をしてきたのかで書く内容が変わってくるのでどうしたらいいとかは言いにくいところではあると思うが、興味のある分野の勉強とかを進めてみれば、そのうち何か作ってみたいものが見えてくるのではないかと思う。

問2

 ## 問2
今までに解析したことのあるソフトウェアやハードウェアにはどのようなものがありますか?また、その解析目的や解析方法、工夫した点があればそれらも教えてください。

 

回答

 

スマートフォンを充電するついでにMTPを使ってスマートフォン内のファイルを見てみた。ほとんどのフォルダは空フォルダだったので何も得ることは出来なかったが、”.”から始まっているファイルなどからlinuxの名残を感じたり、base64でファイル名がエンコードされているようなファイルを見つけたりなど新しい発見もあり、forensicにも手を出してみたいと思った。ダウンロードフォルダには様々ファイルがあったので見て回っていた。その中にhtmlのファイル(A.htmlと呼称する)があった。見覚えのないファイルだったが、思い当たる節はあったので、あまり乗り気ではなかったがA.htmlを開いてみることにした。しかし、webページは表示されず、表示されたのは文字化けした文字とELFの3文字、そしてwww.php.netへのリンクだった。ダウンロードの途中で何らかの原因により終了したのかもしれないが、A.htmlのリンクを踏んでも明示的に何かダウンロードしている様子はなかった。(A.htmlで検索してみたら一件だけヒットした。)このことから、詳細な解析が必要なのではないかと思い、解析を行うことにした。本当にhtmlのファイルならテキストエディタで開いた時にhtmlの構文が現れるはずだが、vimで開いてもhtmlの構文は得られなかった。fileコマンドを使ってファイルの情報を得ようとしてみたが、エラーが生じたため、readelfコマンドを利用して、より詳細な情報を得ようとした。やはり実行可能ファイルであった。ABIがFreeBSDのものだったので、仮想環境を構築しようと思ったが、FreeBSDのisoファイルが見つからず、環境の構築はできなかった。結局、現在はA.htmlが何者だったのか分からず、今までバイナリ解析を主にやってきたが、forensicsについても興味を持つきっかけになった。

 

追記

課題7に取り組むにあたり、BZ(バイナリエディタ)を導入したため、BZを用いてビットマップを確認して解析のヒントを得ようとした。他の.htmlファイルや実行ファイルと比較した結果、やはり実行ファイルであるようだった。しかし、ビットマップをまじめに眺めたのがセキュリティキャンプの課題からであるために、ビットマップやフォレンジック調査に関するノウハウの欠如により、それ以上の情報は得られなかった。

 CTFでReversingの問題を解くことはあっても、実際に身の回りのものを解析したことはないなぁ(というか解析していいのか?ちなみに、お山に登るときに持っていくGPSの取扱説明書では明示的にリバースエンジニアリングが禁止されていた)と思いながら、PCで充電していたスマホに手を伸ばしてファイル転送を行ってみたのが事の発端である。実際に解析しなくとも、普段の生活の中で目に入ったものをどんな風に解析しようかと想像してみるのは割といいことかもしれないと思った。

問3

## 問3
ブログやGitHubなど技術情報を公開しているURLがあれば教えてください。またその内容についてアピールすべきポイントがあれば記載してください。

 

回答

ブログ→https://yamanobori-programing.hatenablog.com/

githubhttps://github.com/I-love-bin

twitterhttps://twitter.com/bot04220350

 

当初は2018年10月のセキュリティ・ミニキャンプ in 山梨で講師の坂井さんに「ブログとかやってるとアピールポイントが増えていい」と助言されてから始めたものだが、ブログを更新していくうちに毎回読んでくれる読者もでき、セキュリティキャンプの選考を通過するためのブログよりも、技術情報を共有するためのブログという側面も見えてきたので良かった。現在、ブログの内容は主に参加したCTFのwrite-upを掲載している。2019年になってから精力的にCTFに参加しているが、現在CTFには月一回程度のペースで参加しており、参加したCTFで、自分が解いた問題は必ず記事にするようにし、CTFを通じて得られた技術情報をなるべく発信するようにしている。また、CTFに出て、解けなかった問題もあるが、それについての考察も記載しており、write-upを読んでくれた人が新しい知見を得てくれればいいと考えている。また、技術情報を公開するブログとしてはいるものの、趣味で登山を行っているので、そのことについてもたまに記事にしたいと考えている。技術情報のみを記事にすると、そのブログを訪れる人は限られてくるが、技術情報以外の記事を追加することで、普段セキュリティにあまり興味のない人も訪問することになり、セキュリティの話題に触れる機会を提供する事が出来ると思う。今は主にCTFのwrite-upを載せているが、今後はCTF以外の技術的な話題(例えばJVN脆弱性レポートなどを題材とした話題など)も増やしていきたい。githubは主に作成したプログラムを公開するために使用している。バイナリファイルに加えてソースコードも原則公開しているため、自分では気に留めないようなことを指摘してもらえるかもしれないと考えている。また、オープンソース化することで、訪問した人に新たな知見を提供できるとも考えている。twitterは主に情報収集、情報発信用として活用している。ブログを開設しただけでは多くの人に記事を共有することは難しいが、ブログの更新を、twitterを利用して告知することで、技術情報の共有について効果を発揮していると考える。

 お山の記事も書いていきたいですねぇ。

坂井講師からのアドバイスで始めたこのブログも、もうすぐ200アクセスに届きそうである。某botのフォロワーも増えたので、CTF以外の技術的なトピックも扱っていきたいナリねぇ

問4

 ## 問4
あなたが今年のセキュリティ・キャンプで受講したいと思っている講義は何ですか?(複数可)またそれらを受講したい理由を教えてください。

 

回答

 

様々興味のある講義は、脆弱性マルウェア解析トラック以外にもあるが、今回のセキュリティキャンプで特に受講してみたいと思っている講義は三日目に開催される「Reverse Engineering Malware – Know Your Enemies」、「難読化されたマルウェアの解析」の二つである。というのも、自分は普段CTFに参加しており、特にReversingについて主に担当しているため、現在の自分の力で、どこまで講義についていけるのか?また、自分が今までCTFを通して養ってきたReversingの力は、実際の現場でどのように役に立っているのか?といったことが気になるからである。加えて、元々低いレイヤーのセキュリティに関する技術に興味があり、難読化についても様々調べているのだが、その動作原理というのはよく分からない面もあった。そのため、今回の講義に参加して、少しでも難読化の動作原理や実装についてのヒントを得られれば良いと考えたため。また、三日目、四日目は他トラックの講義にも参加できるようなので、三日目は受講したい講義が選択トラックで設定されているため他のトラックの講義には参加できないが、四日目は他のトラックの講義に参加して知見を深めたいと考えている。具体的には、開発と運用トラックと特別トラックで開講される「つくって学ぶ、インターネットのアーキテクチャと運用」と「実践トラフィック解析」である。というのも、自分は普段ネットワーク系の技術やセキュリティの話題にかかわることが少ないと考えているため、これを契機として、ネットワーク系の話題や技術についても理解、習得ていきたいと考えたためである。また、「実践トラフィック解析」では、ダークネットのトラフィックを観測する。近年話題になっているダークネットはマルウェアの拡散のための利用などの不正な活動に利用されており、ネットワーク技術の習得のほかにも、マルウェアのより広い理解やいままでなんとなくしか知らなかったダークネットの具体テクな理解につなげられると考えたため、参加してみたいと考えた。

 ここは熱意の見せどころなのかな?講義の内容と絡めながら自分が興味を持っている技術について熱く語ってみてみるのも良いのだろうかと思った。

問5

 ## 問5
自分が最も技術的に興味を持った脆弱性をひとつ挙げ、技術的詳細(脆弱性の原因、攻略方法、対策方法など)について分かったことや思ったこと、調査の過程で工夫したこと等を報告してください。その際、書籍やウェブサイトを調べて分かったことはその情報源を明記し、自分が独自に気付いたことや思ったことはそれと分かる形で報告してください。また脆弱性の攻略方法を試す際は、他者に迷惑を掛けないように万全の措置をとってください。

 

 回答

 

ヒープオーバーフローの脆弱性について調べ、分からない単語等があれば、その単語が出てきた事項について概観しつつ、その単語についても調べることで、知識を広げつつ、なるべく多くのことについて理解できるように心がけた。この脆弱性について興味を持った背景について、脆弱性といわれてすぐに思いつくのはスタックベースのバッファオーバーフローだが、Security Intelligence Report vol.16によると、近年は攻撃に利用された脆弱性のうちの一割を切っており、代わりにuse-after-freeを用いた攻撃が増加傾向にある。そのために、use-after-freeに興味を持つと同時に、同じくヒープ領域に端を発する脆弱性であるヒープオーバーフローに興味を持った次第である。ヒープオーバーフローは、ヒープ領域に確保された変数に対して過剰な入力を与えることによって、同じくヒープ領域に確保された他の変数が上書ききされてしまうことに起因する脆弱性である。スタックオーバーフローでは過剰に入力を与えた結果、EIPを書き換えることで制御を奪う事が出来るが、ヒープオーバーフローではアドレスの書き換えのみ行うため、GOToverwriteなど他の攻撃テクニックと併用することで制御を奪う。CWE識別番号は122。この脆弱性を利用したwindowsOSにおける攻撃の一例として、Lookaside listを用いた攻撃がある。

 

[前提] windowsでのヒープの作成と管理等について

C/C++ではmallocやnewを用いてヒープ領域の確保を行うが、windowsAPIではHeapCreateでヒープ領域の作成、HeapAllocでヒープ領域から特定サイズのメモリ領域の取得、HeapFreeで取得したメモリ領域の解放を行う。また、windowsのヒープ管理は主としてFrontendとBackendからなり、Frontendがアプリケーションと直接やり取りを行い、メモリ割り当ての最適化のために配置されている。WindowsはFrontendにおける機構として、windows XP以前ではLookaside listを、Windows Vista以降はLow Fragmentation Heapをサポートしている。また、Backendは実際にメモリ割り当てを行う。Windowsのヒープ構造について、ヒープの先頭には_HEAP構造体が配置されており、ヒープの管理情報が格納されている。その下には未使用領域や、chunk headerとデータ領域のセットが存在する。ある領域がHeapFreeで解放され、隣の領域が未使用領域であるときにはそれらの連結が行われ、既存の未使用領域は新規の未使用領域に連結される形になるために、未使用領域のリストから削除される。windows XP SP1まではこの時の双方向リストのunlink動作の特徴を利用して攻撃が行われていた。

 

windows XP SP1までの攻撃手法は、既存の未使用領域のFlinkとBlinkを任意の値に書き換え、その領域が新規の未使用領域に連結されるときのFlinkとBlinkの値の参照をを利用し、関数ポインタの値を書き換えることで任意コードの実行を行う。これに対しwindows XP SP2では対策が講じられ、Chunk HeaderのCookieの導入、Safe unlinking、PEB Randomizationが実装された。Chunk Headerのcookieの導入は、Chunk Headerに8bitの値(Chunkのアドレスから計算される)をあらかじめ書き込んでおき、その値が書き換えられたかどうか確認する。スタックにおけるカナリア領域のようなものであると思われる。文献は見当たらなかったが、スタックオーバーフローを利用した攻撃のように入力をうまく調整して、そこの8bit分だけ値を変えないようにすれば回避が可能なようである。Safe Unlinkingは双方向リストから要素を削除する前に前後の要素のポインタが自分を指しているかを確認し、矛盾がないことを確認する方法である。PEB(Process Environment Block:システム上で動作する各プロセスに一つずつ割り当てられるデータ構造で、当該プロセスが利用しているヒープ情報やファイルの情報、ロードしているモジュールの情報など、攻撃に利用されやすい情報を保持している) Randomizationは、元々PEBが実行中のプロセスのfs:30hのアドレスに常に配置されるようにwindows側で決定されていたものをランダムな配置に変更することで攻撃の成功確率を低下させるという対抗策である。これらの対策について、Lookaside listを用いた攻撃によって無効化できる。Lookaside listは解放済みのメモリ領域を指し示す単方向リストであり、HeapFreeによってメモリが解放される時は、最初にLookaside listによって管理される。HeapAllocでメモリ確保の要求があった際には、最初にLookaside listに未使用領域が存在するか調べ、存在するときはここから返される。Lookaside listについては、単方向リストであるために、Safe Unlinkingが適応されない。加えてChunk HeaderのCookieのチェックがないために、XP SP2以降に実装された対抗策が無効化されてしまっている。そのため、未使用領域のヘッダ領域がオーバーフローによって書き換えられたのちに、二回のHeapAllocが呼び出されると書き換えられたポインタを参照することで任意の領域のアドレスを返す事が出来る。あるいは、未使用領域のFlinkについて、関数ポインタを含むアドレスを指すように上書きし、二回目のHeapAllocでうまい入力を与える事が出来れば、関数ポインタを任意の値に上書きする事が出来る。これを受けて、windows Vistaでは、Low Fragmentation Heapの導入、Block Metadataのランダマイズ、Enhanced entry header cookie、Heap base randomization、Heap function pointer encodingが実装された。これまで利用されていたLookaside listに代わりメモリの断片化を提言するLFHが導入されたため先の攻撃は無効化された。Blpck MetadataのランダマイズによるCokkieを予想したChunk Headerの上書きの回避やEnhancedentry header cookieの導入によるChunk Headerの書き換え検知機能の強化によってwindows XPまでにメジャーであったヒープオーバーフローを利用した攻撃は鳴りを潜めたようである。しかし、当然、これらの対策にもLFHのオーバーフローを利用した_HEAP構造体の書き換えなどといった回避策が打ち出されており、鼬ごっこの様相を呈している。

 

調査中に気づいたこと

(1)複数のコマンドライン引数について、echoコマンドを用いて実行ファイルに渡す際は、xargsコマンドを用いて

$ echo hoge hoge hoge | xargs ./huga

として実行するとよい。

(2)脆弱性の指標として存在するCVE,CVSS,CWEについて、CVE(Common Vulnerabilities and Exposyres:共通脆弱性識別子)は個々の脆弱性に対して一元的に付与される識別子であり、例えば二つの脆弱性がそれぞれヒープオーバーフローに起因するものであっても、個別の事例ならば個々に特有の識別子が与えられる。CVSS(Common Vulnerability Scoring System:共通脆弱性評価システム)は脆弱性の深刻度に応じたスコアを付与するシステムであり、数字が10に近いほど深刻な脆弱性である。CWE(Common Weakness Enumeration:共通脆弱性タイプ一覧)は、個々の脆弱性がどういった領域の脆弱性なのかについて分類する。すべてのCVEについてCWE IDが付与されているわけではない。

 

 

参考にしたページは以下の通り

http://inaz2.hatenablog.com/entry/2014/05/14/011448

Heap-Overflowを用いたGOT-Overwrite攻撃

https://www.atmarkit.co.jp/ait/articles/1408/28/news010.html

Heap-Overflowの概説

https://www.atmarkit.co.jp/ait/articles/1111/18/news146_2.html

PEBに関する説明

https://www.keicode.com/windows/heap-internals1.php

Lookaside listについて

https://www.ffri.jp/assets/files/monthly_research/MR201312_History%20and%20Current%20State%20of%20Heap%20Exploit_JPN.pdf

lookaside listを用いた攻撃について

 ヒープオーバーフローについての脆弱性を調べて報告した。実際に環境を構築して実験できればよかったのだが...

脆弱性についても随時ブログで記事にしていきたいと思う。

問6

## 問6
以下にDebian 9.8(amd64)上で動作するプログラムflatteningのmain関数の逆アセンブル結果(*1)とmain関数で使われているデータ領域のダンプ結果(*2)があります。このプログラムは、コマンドライン引数としてある特定の文字列を指定されたときのみ実行結果が0となり、それ以外の場合は実行結果が1となります。この実行結果が0となる特定の文字列を探し、その文字列を得るまでに考えたことや試したこと、使ったツール、抱いた感想等について詳細に報告してください。

 

 

回答

 

最初に自分が取り組んだことは、実行遷移の解明である。このプログラムの特徴として、実行遷移先がアドレスで明示的に示されていないという点が挙げられる。raxレジスタに格納された値をアドレスとみなして遷移している。raxレジスタを適切な値にするためにはrdxレジスタが用いられる。rdxレジスタには、あらかじめ0x8b4が格納されていて、[rsp-0xc]に格納された任意の値をeaxレジスタに格納、その後rdx+rax*4番地(これは.rodataのアドレスとなる)の値を取得しraxに格納、rdxと足し合わせることで遷移先のアドレスが取得できる仕組みになっている。アドレスの取得方法が分かったので、次は渡された逆アセンブル結果を加工し、IDAやradare2のように、処理の流れを追いやすいように加工した。加工の結果、このプログラムは、主に5つの機能から成り立っていることが分かった。以降、一つずつ詳しく見ていく。最初の部分で、特筆すべき点として、ediが0x2以外の時は、eaxに1を代入して終了している。手元の環境(kali linux 2019.1)でコマンドライン引数を受け付ける環境を作成し、gdb-pedaでediレジスタの変化を観察してみる。渡すコマンドライン引数の長さや数を変えてみた結果、どうやらediレジスタには入力されたコマンドライン引数の個数が格納されているようだということが確認された。よって、この部分では、入力されたコマンドライン引数が(プログラム自身を除いて)一つだけかを確認していると推察される。次の部分ではループ構造になっていて、[rsi+0x8]に格納された値をr11レジスタに格納した後、1バイトずつ走査していき、r11レジスタに格納されている値が0x0の場合、またはループの回数が8回を超えた場合にループを抜け出すようになっている。処理を追ってみると、おそらくrsi+0x8は入力された文字列の先頭番地を表していると思われ、文字列を一文字ずつ格納していき、ヌル文字が現れた時点で格納を終了しているものと思われる。また、試行回数が8回を超えた時点でループを抜け出していることを鑑みると、9文字目以上の文字に特に意味はなく、求めるべき文字列の長さは8なのではないかということが推察される。このことは次の部分で明らかになっていて、次の部分ではループの回数が8以外の場合にはeaxレジスタに1を格納して終了している。次の部分では、特筆すべき点として、xor命令がある。文字列に対する処理として非常に重要な意味を持ちそうである。そして、xor命令の結果は0x593の命令より次のxor命令のために利用されている。この部分では文字列に対する数学的操作を行ってる。この数学的操作の結果を受け、その操作の結果がr10レジスタの内容と等しければeaxに0を格納(具体的にはxor演算を行っている)して終了する。以上のことから、個々の部分は、それぞれ「コマンドライン引数が正しく入力されたかを確かめる部分」、「入力された文字列がヌル文字かを確認する部分」、「入力された文字列が本来の長さかを確認する部分」、「入力された文字列に任意の操作を行う部分」、「操作を行った結果があらかじめ設定されている結果と等しくなっているかを確認する部分」である。以下、「入力された文字列に任意の操作を行う部分」について、さらに詳しく見ていく。具体的には0x6e1から0x5a0、0x588、0x568、0x559から始まる命令である。0x6e1の命令に入る前にr8dレジスタには-0xffffffccが格納されていて、r10レジスタに格納されている値は数学的操作後の値であると考えられ、その値は0xedd5a792ef95fa9eである。rcxレジスタには当初0が格納されている。この値は繰り返しごとにインクリメントされていく。最初、r11dレジスタにr8+rcx*1の値が格納される。その値の下位8bitをもって、入力された文字とのxorをとる。演算結果は[rsp+rax*1-0x8]のに格納され、raxの値はrcxの値に等しい。この時に格納された値はその後、r8dレジスタにゼロ拡張されてから格納される。この操作を繰り返すことで、最終的に0xedd5a792ef95fa9eが生成されればeaxレジスタに0が格納される。ここで、入力される文字列長は8であること、バイトオーダーとして、リトルエンディアンが採用されていることから、入力された文字列の数学的操作の結果は先頭文字から0x9e,0xfa,0x95,0xef,0x92,0xa7,0xd5,0xedに対応していることに気を付けなくてはいけない。以下、実際に入力された文字列を求めていく。当初、r11dには0xffffffccが格納されていて、その下位8bitは0xccである。そのために、入力された文字をXnで表現すると、X0 xor 0xcc = 0x9eであり、X0 = 0xcc xor 0x9e =0x52であり、これはasciiコードでRに該当する。この後、数学的処理の結果(=0x9e)は1を加算された後、次の文字とのxor演算に利用される。同様の計算を行うと以下のようになる。

X1 xor 0x9f = 0xfa

X2 xor 0xfc = 0x95

X3 xor 0x98 = 0xef

X4 xor 0xf3 = 0x92

X5 xor 0x97 = 0xa7

X6 xor 0xad = 0xd5

X7 xor 0xdc = 0xed

これらからXnを求めると、(X0,X1…X7)=(R,e,I,w,a,0,x,1)となり、特定の文字列はReiwa0x1となる。

 あきらめずに最後までアセンブリ言語と格闘しよう。ちなみに、文中に出てくる処理の流れを追いやすいように加工したものがこれである。

github.com

問7

## 問7
### 導入
本課題はSIFT Workstationでfuse-apfsを利用して実施することを想定しています。次のリンクからOVA形式の仮想マシンイメージをダウンロードして調査環境を構築してください。
- https://digital-forensics.sans.org/community/downloads

### 課題
ファイルsample.rawおよびchallenge.rawは暗号化されていないAPFSパーティションをDDでダンプしたイメージデータです。それぞれ1つのAPFSボリュームを含んでおり、3種類の異なるPDFファイルが双方のボリュームに一つずつ保存されています。ただし、challenge.raw は一部のデータが改ざんされており、このままではイメージに含まれるボリュームをマウントしたり、全てのファイルを正しく取り出したりすることができません。
資料apfs101.pdfを参考に、以下の問いに答えてください。なお、回答は全体で最大6,144文字とします。極力簡潔に記述してください。

参考までに、APFSパーティションイメージをapfs-fuseでマウント/アンマウントする場合は、以下のオプションを利用します。
```
# apfs-fuse -s 0 <image file> <mount dir>
# fusermount -u <mount dir>

問7-1

#### 問7-1
challenge.rawをfuse-apfsでマウントできるようにするために修正し、以下の内容を答えてください。
1. 修正箇所のオフセットと修正内容。
2. そのように修正するとマウントできるようになる理由。

 

回答

書き換えたオフセット

オフセット0x0の4e7a1c850e1fe634をefd8aacfb4dfe089に

オフセット0x20の58を4eに

オフセット0x22の5858を5342に

オフセット0x25の00を10に

オフセット0x28の5a5fを981cに

オフセット0x48のdf3ec0be3c544eeebd31c70a0dc4cfcb0aを658aad5567e246d29b4b49e174dfdeda09に

オフセット0x60の3fを17に

オフセット0x6cのe8を7cに

オフセット0x84の0eを056に

オフセット0x90の0aを52に

オフセット0xa0の3201をec17に

オフセット0x3d8の2003を2701に

オフセット0x524の06を03に

オフセット0x1000のcb4ec5を5392c1に

オフセット0x1004の6c603aをec1b32に

オフセット0x1010の3dを15に

オフセット0x1048の0fを57に

オフセット0x12c8の10を58に

オフセット0x1098の11を59に

オフセット0x10c0の12を5aに

修正理由

pngファイルやelfファイルなどには、それ特有のマジックナンバーと呼ばれるものが存在する。バイナリエディタで開いたときに先頭の数バイトに記されている値は、そのファイル形式特有のものとなっている。今回渡されたrawファイルについても同様のことがいえるものと考え、rawファイルのマジックナンバーについて、情報が見当たらなかったために、apfs-fuseでマウントできるsample.rawとchallenge.rawのバイナリを比較し、差分を修正することでマウントできるようにした。

apfs-fuseを使えるようにするのに手間取った。日本語の解説がなかったのであきらめて英語の文章を読もう。というか英語大事。

問7-2

#### 問7-2
challenge.rawに含まれるボリュームには、sample.rawに含まれるものと同じPDFファ
イルが保存されています。しかし、問1の問題を解決してマウントしても、そのまま
では開くことができないファイルが1つあります。当該ファイルを開けるように
challenge.rawのデータを修正し、以下の内容を答えてください。
1. 修正箇所のオフセットと修正内容。
2. そのように修正するとファイルを開くことができるようになる理由。
3. 回答に至る調査の過程(簡潔に)。

 

書き換えたオフセット

不明

修正理由

不明

調査過程

まず、マウントしたrawファイルを開き、開けないpdfを特定することから始めた。調査の結果、iir_vol41.pdfのみ開く事が出来ず、エラーの内容はFile type unknown (application/octet-stream) is not supportedだった。このことから、pdfファイルのマジックナンバーが改ざんされているのではないかという仮説を立て、バイナリエディタで当該箇所を調査してみたが、マジックナンバーの改ざんは発見されなかった。次に、pdf本体を抽出して比較してみることにした。sample.rawとchallenge.rawからそれぞれiir_vol41.pdfを抽出し、比較してみた結果、challenge.rawから抽出したpdfファイルのバイナリは0x0で満たされていた。なお、sample.rawにおけるiir_vol41.pdfと同様のものと思われるファイルはchallenge.raw内にも存在するため、ファイルアクセス時に参照する情報が改ざんされているものと推定した。しかし、結局どの部分が改ざんされているのか特定することは出来なかった。

正直、この問題が解けなかったので選考とは通過できないと思っていたが、なぜか通過できた。他の人の課題晒しを見ながら復習せねば...

 

いやぁ、回答がしょぼい...

こんな回答をネットの海に放流して、1000年後の大学入試の試験問題の古典で出されたらどうしよう...

そんなことを思いつつも、どうも課題は技術力を見ているようではないので(技術があるに越したことはないけど)「技術的に難しいから応募は諦めよう...」とか思っちゃってるそこの君!!(誰?)この回答を見て少しでも「自分でも行けそう」と思ってくれればうれしいです。そして完答できなくとも、課題に取り組むことでセキュリティについて今までにないくらいに向き合う事が出来ると思うのでやはり取り組んでみてほしいと思います。そして回答に自信がなくてもとりあえず出してみることでもしかしたら選考通るかもしれないし、通らなかったとしても次のアクションのモチベーションにもなると思うので頑張ってください。