<前の日記(2003年09月26日) 次の日記(2003年10月02日)> 最新 編集

高木浩光@自宅の日記

目次 はじめに 連絡先:blog@takagi-hiromitsu.jp
訪問者数 本日: 1954   昨日: 2734

2003年09月28日

絶対に見つけられないWebアプリ攻撃は存在する

7月に伊原さんからケーキオフの「WebAppへの攻撃は見つけられるのか?」の回への議論参加のお誘いを頂いていたのだが、ずいぶんはるか先の話だなあと思っているうちに忘れてしまい、それが今日だったことを知った。あれからもう2か月が過ぎ去ったのか。突っ込みコメントできることはありそうだったので行きたかったのだが、痛恨。

というわけで、資料とビデオを拝見した上で、以下コメント。

最後の「まとめ」として、「絶対に見つけられない攻撃は存在しないはず」と述べられているが、それは正しくない。

セッションIDを盗むまでもなくパスワードなしにログイン状態に入れてしまうタイプの欠陥を突いた攻撃については、一定時間以内前にパスワード送信のアクセスがあったかどうかをログから調べれば攻撃の有無を調べられるだろう。しかし、正規ユーザがログイン中のタイミングでのセッションハイジャック攻撃は、その方法では攻撃の有無を調べることができない。

国分氏の講演では、セッションハイジャックを見つける方法として、「Set-Cookie: で発行したセッションIDと異なる Cookie: が送られてきた場合を探す」ということが述べられているが、攻撃者は、そもそも Set-Cookie: を発生させるようなアクセス(通常、これはパスワード送信時に起きる)をすることなしに、最初から直接に、他人用のセッションIDを Cookie: としたリクエストを送信するのだから、この方法では検出できないだろう。

また、「同じユーザから何度もアクセスがある中で、セッションIDが途中から違っているものを見つけられるかもしれない」ということも述べられているが、問題は、「同じユーザ」というのをどうやって判別するのかだ。そもそも、同じユーザであることを識別するためにセッションIDを必要としているのであるから、「同じユーザからのセッションIDが変化した」ということを完全に検出することは本質的にできない。

では、「同じユーザ」を、同じIPアドレスからのアクセスかどうかで判別する方法はどうだろうか。

まず、同じIPアドレスから異なるセッションIDが飛んでくることは、ごく日常的な事態のはずだ。企業内ユーザのProxyサーバ経由のアクセスや、規模の大きなNATごしのアクセス(一部のケーブルテレビ接続の場合など)の場合には、当該ドメインから複数のユーザがログインしていれば、そうした事態は普通に起きる。それを攻撃とみなすわけにはいかないだろう。

次に、同じセッションIDが異なるIPアドレスから飛んできた場合を攻撃とみなすという考え方がある。しかし、ダイヤルアップ接続のユーザならば、一旦電話を切ってデータ入力をし、再び接続してボタンを押すという、ケチケチアクセスをするかもしれない。その場合、同じセッションIDが異なるIPアドレスからやってくることになるので、これを攻撃とみなすわけにはいかない。

これを「攻撃の可能性がある」とみなしてアクセスを拒否してしまうという対策はアリかもしれない。しかし、そうした対策をとっているサイトは極めて少ないようだ。

まず、企業内ユーザからのProxy経由のアクセスは、アクセスごとにIPアドレスが微妙に変化することが多い。Proxyが複数台のサーバで負荷分散されている場合に、アクセスごとに異なるIPアドレスのサーバを経由することがあるからだ。(この現象は、普通のWebサーバのアクセスログから、大手企業からのアクセスのログを探して、ざっと眺めてみるだけでも知ることができる。)したがって、単純に完全にIPアドレスが一致するかどうかで判別すると、Webアプリが正常に動かなくなってしまう。そこで、一定のアドレスブロックの範囲内であれば同一とみなすという対策が考えられる。こうした対策をとっているところは、少数派ではあるが、存在はする。しかし、同じダイヤルアップ接続プロバイダ内からの攻撃を判別することができない。より厳密に対策したければ、アクセス元が接続プロバイダなのかProxyなのかといった情報などから、細かく条件別に判別するようにするしかないだろう。

そして、この方法で対策をとったとしても、セッションハイジャック攻撃を完全に防げるわけではない。なぜなら、同一企業内、同一接続プロバイダ内、同一NAT内からの、第三者アクセスを判別することはできないからだ。同様に、事後に攻撃がなかったことを証明することも不可能だ。

では、セッションIDを盗み出す時点で攻撃を見つけるというのはどうだろうか。当該サーバのクロスサイトスクリプティング脆弱性を突いた攻撃は、POSTアクションも含めたログから検出することができるだろう。しかし、cookieを盗まれるのは、サーバ側のクロスサイトスクリプティング脆弱性だけではない。ブラウザのセキュリティホールによって盗まれることもあるし、ユーザ側のProxyのクロスサイトスクリプティング脆弱性によって盗まれることもあるし、secure属性の付いていないcookieをパケット盗聴で盗まれることもある。これらはサーバ側では検出できない。

次に考えられる対策は、セッションIDとは別に、シーケンス番号をcookieなどでブラウザに渡す方法だ。ここで言うシーケンス番号とは、アクセス1ページごとに変化させるもので、同じセッションIDに対して同じシーケンス番号のアクセスが2度以上きたら異常事態とみなして、アクセスを拒否する方法だ。攻撃者がセッションハイジャックするとき、正規ユーザよりも先に「次ページ」をアクセスした場合には、残念ながらアクセス拒否とならないが、正規ユーザがその後に「次ページ」にアクセスした時点で異常は検出できる。

しかしこの対策がとられていたとしても、ユーザがログアウトボタンを押さずにウィンドウを閉じた場合には、攻撃者はその後を見計らってハイジャックアクセスするようにすれば、バレることなく攻撃を成功できてしまう。特に、パケット盗聴が可能な状況では、そうしたタイミングを見計らうこともできるだろうし、ブラウザのセキュリティホールを突いてcookieを盗む場合には、盗んだ後ブラウザを終了させてしまうこともできるだろう。

講演では、「ひとり分の情報だけ吸い出して満足することはないだろうから、次々と連続して複数のアカウントのデータを吸い出すだろうから、そうしたアクセスを見つける方法がある」と述べられていたが、それはその通りだろう。攻撃者が、一人分で満足する場合にはその限りでない。

総合的に言うと次のシナリオが最もバレない攻撃となる。攻撃者が被害者のパケットを盗聴できる状況にいる場合。この場合には、同じIPアドレスブロックから攻撃のアクセスができる場合が多いだろう。仮にシーケンス番号対策がとられていたとしても、ユーザのアクセス行動をウォッチできるのだから、シーケンス番号対策を回避できる。そして、攻撃対象Webアプリに、セッションID用cookieにsecure属性を付けてない欠陥があるならば、それを盗聴してセッションハイジャックされると、攻撃を検出できない。

一方、安全なWebアプリを作ることはできる。cookieでセッション追跡を実装すると、仮にWebアプリに欠陥がなくても、ユーザのブラウザのセキュリティホールを突いてセッションIDを盗まれる可能性があるが、セッションハイジャックされても、重要な情報を盗まれないような画面構成にすればよい。すなわち、重要な画面に入るには再度のパスワード入力が必要なようにし、そこのセッション追跡にcookieを使わないようにする。もちろん、その部分の仕組みに別の欠陥があってはならないのだが。

検索

<前の日記(2003年09月26日) 次の日記(2003年10月02日)> 最新 編集

最近のタイトル

2024年03月16日

2024年03月13日

2024年03月11日

2023年03月27日

2022年12月30日

2022年12月25日

2022年06月09日

2022年04月01日

2022年01月19日

2021年12月26日

2021年10月06日

2021年08月23日

2021年07月12日

2020年09月14日

2020年08月01日

2019年10月05日

2019年08月03日

2019年07月08日

2019年06月25日

2019年06月09日

2019年05月19日

2019年05月12日

2019年03月19日

2019年03月16日

2019年03月09日

2019年03月07日

2019年02月19日

2019年02月11日

2018年12月26日

2018年10月31日

2018年06月17日

2018年06月10日

2018年05月19日

2018年05月04日

2018年03月07日

2017年12月29日

2017年10月29日

2017年10月22日

2017年07月22日

2017年06月04日

2017年05月13日

2017年05月05日

2017年04月08日

2017年03月10日

2017年03月05日

2017年02月18日

2017年01月08日

2017年01月04日

2016年12月30日

2016年12月04日

2016年11月29日

2016年11月23日

2016年11月05日

2016年10月25日

2016年10月10日

2016年08月23日

2016年07月23日

2016年07月16日

2016年07月02日

2016年06月12日

2016年06月03日

2016年04月23日

2016年04月06日

2016年03月27日

2016年03月14日

2016年03月06日

2016年02月24日

2016年02月20日

2016年02月11日

2016年02月05日

2016年01月31日

2015年12月12日

2015年12月06日

2015年11月23日

2015年11月21日

2015年11月07日

2015年10月20日

2015年07月02日

2015年06月14日

2015年03月15日

2015年03月10日

2015年03月08日

2015年01月05日

2014年12月27日

2014年11月12日

2014年09月07日

2014年07月18日

2014年04月23日

2014年04月22日

2000|01|
2003|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|05|06|07|08|09|10|11|12|
2012|02|03|04|05|06|07|08|09|
2013|01|02|03|04|05|06|07|
2014|01|04|07|09|11|12|
2015|01|03|06|07|10|11|12|
2016|01|02|03|04|06|07|08|10|11|12|
2017|01|02|03|04|05|06|07|10|12|
2018|03|05|06|10|12|
2019|02|03|05|06|07|08|10|
2020|08|09|
2021|07|08|10|12|
2022|01|04|06|12|
2023|03|
2024|03|
<前の日記(2003年09月26日) 次の日記(2003年10月02日)> 最新 編集