投稿

1月29日(月)3、4コマ目

イメージ
今日、やったこと [やってみよう]バッファオーバーフロー 確認テスト 今日のホワイトボード [やってみよう]バッファオーバーフローその1 hasUpperCase()関数にはバッファオーバーフローの脆弱性がある。(13行目) main()関数にてhasUpperCase()を呼び出したときにスタック上に書き込まれるリターンアドレスを43行目のprintf()に書き換える。 プログラムの動き main()関数を逆アッセンブルすると以下のようになる。 図 main()を逆アッセンブルすると 通常はhasUpperCase()実行後、0x7f…400786番地に戻ってくるが、printf()実行の0x7f…4007aa番地に戻るようにスタックエリア上のリターンアドレスを書き換えればいい。 メモリの様子 hasUpperCase()実行時のスタックエリアの様子は以下のとおり。 図 hasUpperCase()実行時のメモリの様子 変数buffの先頭から40バイト離れた(41バイト目以降)ところにリターンアドレスが書き込まれている。ここをバッファオーバーフローで書き換える。 どうすればいい? どんな引数でもかならず”I DO NOT find UpperCase!”と出力するには、コマンドライン引数に40文字+リターンアドレスで実行すればいい。 [やってみよう]バッファオーバーフローその2 chkString()関数にはバッファオーバーフローの脆弱性がある。(23行目) main()関数にてchkString()を呼び出したときにスタック上に書き込まれるリターンアドレスを77行目のprintf()に書き換える。 プログラムの動き main()関数を逆アッセンブルすると以下のようになっている。 図 main()関数を逆アッセンブルすると 通常はchkString()実行後、0x7f…4007e2番地に戻ってくるが、printf()実行の0x7f…400817番地に戻るようにスタックエリア上のリターンアドレスを書き換えればいい。 メモリの様子 chkString()実行時のスタックエリアの様子は以下のとおり。 図 chkString()実行時のメモリの様子 その1と同じように変数buffの先頭から41バイト目にリターンアドレスが書き込まれる。ここを書き換えればいい。 どうすればい...

1月26日(金)1、2コマ目

イメージ
今日、やったこと バッファオーバーフロー 今日のホワイトボード メモリは プログラム実行時にコンピュータのメモリは以下の3つの領域に分けて使われる。 図 メモリの使われ方 [おまけ情報]C言語のif文 C言語にはtrue、falseのbool型がない。 if()もカッコ内が0なら条件不成立、0以外なら条件成立として扱われる。 図 C言語のif() サンプルプログラムでバッファオーバーフロー(パターン1) サンプルプログラムはcheck()関数のstrcpy()でバッファオバーフローを引き起こす可能性がある。 引数passwordの内容を変数password_bufferにコピーしているが、コピー先のpassword_bufferのサイズに関係なくコピーしているため、バッファオーバーフローが発生する。 デバッガでcheck()関数のローカル変数を確認すると、下図のようにメモリ上に配置されていることがわかる。 図 2つの変数のアドレス 図 2つの変数のメモリ上での状態 このメモリ配置からpassword_bufferの先頭から29バイト以上書き込めば、変数auth_flagのエリアに書き込むことになる。 バッファオーバーフローが発生するシナリオ バッファオーバーフローで誤ったパスワード("SamplePassword"ではない)でも認証成功になるには以下の原因から。 ①コマンドライン引数で29文字以上のパスワードを指定 ②check()関数にコマンドライン引数のパスワードが渡される ③strcpy()で変数password_bufferにパスワードをコピー  このとき、パスワードの29文字目以降が変数auth_flagのエリアにコピーされる。  これが主原因。 ④変数password_bufferが”SamplePassword”と等しいかチェック  等しければ変数auth_flagに1を代入  これも原因の1つ。本来なら等しくなれば0を代入すべき。 ⑤check()関数は変数auth_flagの値を返す  パスワードが”SamplePassword”なら1を返す  それ以外なら初期値の0が返ると思っている。 => 実際は③で上書きされている ⑥main()関数ではcheck()関数の戻り値で認証の成否を判断  戻り値が0以外なら認証成功。  ...

1月19日(金)1、2コマ目

イメージ
今日、やったこと Webアプリケーションのセキュリティ 今日のホワイトボード セッションオブジェクト セッションオブジェクトはサーバー側でクライアント毎に用意する。 クライアントとセッションオブジェクトを紐づけるためにセッションIDが使われる。 図 セッションオブジェクトとセッションID Cookie CookieはWebブラウザがデータを保存する仕組み。Webアプリケーションでクライアント側にデータを保存する際に利用する。 〇Cookieをセットする Cookieはサーバーのset-cookieでデータ保存。 図 サーバーがCookieをセット 〇Cookieを送信する Webブラウザはサーバーにリクエストを送信する際にCookieも送信する。 図 クライアントがCookieを送信 〇セッションIDをクライアントに保存する セッションオブジェクトを識別するにはクライアント側でもセッションIDを保存する必要がある。ここでCookieが使われる。 クライアントがサーバーにリクエストするとレスポンスでset-cookieを使ってセッションIDをクライアントに保存させる。 図 サーバーからのレスポンスでset-cookie このやり取りのパケットのうち、HTTPヘッダ部はWebブラウザの開発者ツールでも確認できる。 〇クライアントがセッションIDをサーバーに送信する クライアントはサーバーにリクエストするたびにCookieをサーバーに送信する。 サーバーはCookie中のセッションIDからこのクライアントに紐づくセッションオブジェクトを探す。 図 クライアントのリクエストのcookieで送信 このやり取りのHTTPヘッダ部もWebブラウザの開発者ツールで確認できる。 セッションハイジャック 他人のセッションを横取りする攻撃の名前。 他人のセッションIDを取得(盗聴やブラウザのツールなど)し、自分のブラウザのCookieにセットすればセッションを横取りできる。 図 セッションハイジャック Cookieはサイトごとに用意される 同じブラウザで複数のサイトにアクセスすると、複数のCookieが保存される。 サイトAからセットされたCookieはサイトAにアクセスするときに送信する。別のサイト(サイトB、サイトC)にアクセスする際にはサイトAのCookieは送信しない。 図 送信...

1月15日(月)1、2コマ目

イメージ
今日、やったこと サニタイジング 練習問題 今日のホワイトボード サニタイジング 入力内容をそのまま出力するWebアプリケーションで  <h3>コメント</h3> と入力すると、見出しとして太文字で表示される。 出力時にHTMLのタグはそのまま出力せずに、 <は&lt;に>は&gt;に置き換え て出力する必要がある。これがサニタイジング(無害化)。 図 サニタイジング ソースコード 今日でやっと完成。全ソースコードをあげておきます。 [dtoパッケージ]Userクラス ユーザー情報受け渡し用クラス。 [daoパッケージ]UserDAOクラス ユーザーマスタテーブルアクセス用クラス。 [bllパッケージ]Serviceクラス 機能提供クラス。 [bllパッケージ]PasswordUtilクラス パスワードハッシュ化。 [presentationパッケージ]IndexSrvクラス 1ページ目(ログインページ)用サーブレット。 [presentationパッケージ]UserInfoSrvクラス 2ページ目(ユーザー情報)用サーブレット。 [presentationパッケージ]AuthFilterクラス 認証済みかチェックするフィルタ。2ページ用サーブレット(UserInfoSrv)実行前に実行。 [exceptionパッケージ]NotFilledExceptionクラス 未入力項目がある際にスローする検査例外クラス。 [exceptionパッケージ]InvalidPasswordExceptionクラス パスワード要件を満たさないときにスローする検査例外クラス。 [JSP]index.jsp 1ページ目(ログインページ)。 [JSP]userinfo.jsp 2ページ目(ユーザー情報)。 [JSP]error_500.jsp HTTPのステータスコード500(サーバー内部エラー)返信時に表示するエラーページ。 [JSP]erro...

1月12日(金)1、2コマ目

イメージ
今日、やったこと エラーページ フィルター 今日のホワイトボード エラーページ 例外スローの結果、エラーページをそのまま出力すると危険。 このエラーページには サーバーの種類(Tomcat)、バージョン プログラミング言語 DBの種類 等、色々な情報が含まれるため危険。 catchブロックを用意して、そのなかでエラーページを表示するようにすればいいが、Javaサーブレットにもデフォルトのエラーページを設定することができる。 図 エラーページの設定 ①設定ファイルweb.xmlを設定 エラーの種類(HTTPのステータスコード別、Javaの例外別)、エラーページが設定できる。 ②エラーページ作成 HTMLだけでなく、JSPも可。 なお、JSPでは暗黙オブジェクトexceptionが使える。exceptionはスローされた例外。 ただ、exceptionを使うにはエラーページであることを指定する必要あり。 エラーページへの遷移はフォワードで行われる。 よって、エラーページをWEB-INF/以下に置くことも可。 リダイレクトとフォワード いずれもページ遷移の仕組みだが、以下の違いがある。 フォワードはサーバー内で遷移先ページを読み込みクライアントへ返す=>1往復 リダイレクトはステータスコード302をクライアントに返して、クライアントが再リクエスト=>2往復 図 フォワードは1往復で遷移 図 リダイレクトは2往復で遷移 認証成功後のページ追加 認証に成功するとユーザー情報を表示する。流れは下図のようになる。 ...

1月11日(木)1、2コマ目

イメージ
今日、やったこと 入力チェック セッションオブジェクト、セッションID 今日のホワイトボード 入力チェックが必要なわけ 下図のように変な値が入力されるとプログラムが停まるから入力チェックをするわけではない。(当然このような場合の入力チェックも必要) 図 入力チェックが必要なケース 下図のように入力される内容によっては重大なインシデント発生につながることを防ぐために入力チェックを行う。 図 入力チェックが必要なケース(SQLインジェクションが発生する) 空白チェック用メソッド JavaのStringクラスにはisEmpty()やisBlank()があるが、いずれもインスタンスメソッド。 変数がnullの場合はNullPointerExceptionをスローする。よって、まずnullチェックが必要。 StringUtilsクラスのisEmpty()やisBlank()はクラスメソッド。チェック対象がnullならfalseを返すだけ。 図 空白チェック用メソッド 入力チェックで正規表現を使う StringUtilsクラスのisXXX()メソッドには以下のようなメソッドが用意されている。 メソッド 役割 isAlpha() アルファベット(大文字・小文字)以外を含むとfalse isNumeric() 数字以外を含むとfalse isAlphanumeric() アルファベット(大文字・小文字)、数字以外を含むとfalse これらのメソッドでチ...

1月9日(火)1、2コマ目

イメージ
今日、やったこと パスワードのハッシュ化 今日のホワイトボード ユーザー認証 ユーザー認証はパスワードが使われるケースが多いが、パスワード以外にもユーザー認証に使えるモノがある。 図 認証に使えるモノ ポイントは「本人しか」。 パスワードの取り扱い 今までは便宜上DBにパスワードを平文で保存していた。が、これは一般的にはありえない話。本来はDB上のデータが漏洩しても即セキュリティインシデントにつながらないようにしなければならない。 図 パスワードの取り扱い 一般的にはパスワードをハッシュ化してDBに保存する。 ハッシュ化 ハッシュ化と暗号化は同じように元の平文が推測しずらい点では一緒。暗号化は元の平文に複合できるが、ハッシュ化された文字列を元の平文に戻すことはできない。 厳密に言えば、できないわけではないが、総当たり攻撃や辞書攻撃になるため、かなり長い時間がかかる。  図 ハッシュ化 ハッシュ化ソースコード PasswordUtil.java 文字列+ソルトをアルゴリズムSHA256で10,000回ハッシュ化してハッシュ値を生成する。 Main.java PasswordUtilクラスを使ってパスワード+ソルトのハッシュ値を生成させる。 ソルトは実行時の現在時刻のナノ秒部を利用。 ハッシュ化されたパスワードで認証するには DBにハッシュ化されたパスワードを保存する場合、認証は入力されたパスワードのハッシュ値とDBのハッシュ値を比較することになる。 図 ハッシュ化されたパスワードで...