情報処理安全確保支援士や応用情報技術者試験、基本情報技術者試験で問われる「セキュリティ」分野についてまとめました。
サイバー攻撃手法には似たようなものが多くて覚えられない!という方は、ぜひ何度も見返してください。
SQLインジェクション
攻撃内容
SQLインジェクションとは、攻撃者が入力欄にSQLを入力して、サーバに送信(リクエスト)することで、サーバ側で攻撃者が入力したSQLを実行してしまう攻撃です。
通常、クライアントが入力した情報をもとにサーバ側でSQLを組み立てて、実行することで、対象のDBから値を取得したり、DBにレコードを追加・削除・更新したりします。
攻撃例
攻撃例は以下の通りです。
まず、ユーザ検索をするような検索フォームに、以下の値を攻撃者が入力します。
以下、入力値のことをリテラルと呼びます
' or '--' = '--
サーバ側で用意しているSQLは次のようになっているとします。
SELECT * FROM user WHERE id = 'リテラル';
攻撃者がリクエストした「文字列リテラル」をSQLに当てはめると、以下になります。
SELECT * FROM user WHERE id = '' or '--' = '--';
すると、本来は利用者が入力したid名でuserテーブルにある情報を取得してくるはずが、
「’–‘ = ‘–‘」がtrueになることで、userテーブルにあるユーザ情報全てを取得する命令に変わってしまっています。
対策
プレースホルダを使ってSQL組み立てを行う。
プレースホルダ「?」を使い、あらかじめSQLを固定化させておく手法です。
詳細は下記の記事をご参照下さい。
ウェブアプリケーションに渡すパラメータにSQL文をそのまま指定しない
SQLをhiddenパラメータで指定しているという事例がありました。
hiddenパラメータは一見ブラウザ上に表示されないように見えますが、ブラウザの開発者ツールを使えば簡単に改ざんできます。
hidddenパラメータに直接SQLを入れておくなんて、ぶっ飛んだ実装だね
エラーメッセージをそのままブラウザに表示しない
エラーメッセージの中には、実行されたSQLやデータベースの情報を表示する場合があります。
その場合、攻撃者に有益な情報を与えることにつながります。
OSコマンドインジェクション
攻撃手法
OSコマンドインジェクションとは、攻撃者が入力欄にOSコマンドを入力して、サーバに送信(リクエスト)することで、サーバ側で攻撃者が入力したOSコマンドを実行してしまう攻撃です。
OSとは
OSとは、Operating System(オペレーティングシステム)の略で、パソコンの操作やアプリなどを使うために必要なソフトウェアのことです。
OSのおかげで、ファイルの保存やコピー、キーボードでの文字入力など様々な操作が可能になります。
OSの代表例は、Linux、Windows、macOSなどがあります。
OSコマンドとは
OSコマンドとは、OSに命令する命令文のことです。
普段私たちは、OSコマンドを実行しなくても、PCの操作ができていますが、実はPCの裏側ではOSコマンドが実行されているのです。
ファイルをダブルクリックで開く操作も、OSに「ファイルを開け」と命令していることと同じなんだね。
OSコマンドは、シェルというソフトウェアによって実行されます。
さて、このOSコマンドが悪用されてしまうと、PC上であらゆる操作が可能になってしまいます。
例えば。サーバ内にあるファイルへのアクセス・改ざん、サーバの乗っ取りなどができます。
攻撃例
例えば、利用者がIPアドレスを入力すると、そのIPアドレスに対してpingコマンドを実行するWebサイトがあるとします。
攻撃者は、サーバへのリクエストパラメータに次のOSコマンドを送信します。
Webサーバは、クライアントからリクエストを受け付けると、当然リクエストの内容を解析して、処理した結果をレスポンスとしてクライアントに返します。
ステップ1 : ユーザーがWebブラウザにURLを入力する
ステップ2 : WebブラウザがリクエストをWebサーバーへ送る
ステップ3 : Webサーバーがリクエストを解析して処理する
ステップ4 : WebサーバーがレスポンスをWebブラウザへ返信する
ステップ5 : Webブラウザが受信データを解析して表示する
ステップ3のリクエスト確認では、HTTPヘッダやボディを見て処理します。
ボディには、クライアント側で入力した値が格納されています。
以下の例では、addrのIPアドレスにクライアントで入力された値が入っています。
クライアント側で入力されるボディには、OSコマンドを入れることが可能です。
whoamiが入力されているね
サーバー側で、下記のような処理があらかじめ用意されており、リクエストが来たら実行されるのでしょう。
/ping.cgi
body = json loads(request.body)
addr = body['addr']
os.exe('ping' + addr)
この処理では、pingとaddrを単純に結合させてOSコマンドとして実行します。
今回の場合、実行されるコマンドは以下になります。
ping 127.0.0.1;whoami;
whoamiコマンドは、ログイン中ユーザのログイン情報を表示するコマンド
対策
シェルを起動できる言語機能の利用を避ける
ウェブアプリケーションを作るプログラミング言語によって、シェルを起動できる言語があります。
攻撃者からの入力値によってシェルを起動できてしまうと、OSコマンドを勝手に実行されてしまいます。
入力値の特殊文字はエスケープ処理をする・入力値チェックをする
ユーザからの入力値がある場合は、入力値内に想定しない特殊文字(「;」や「<」など)が存在するかどうかをチェックします。これらの特殊文字が入力された場合は、特殊文字を無効化(エスケープ)したり、プログラムの処理を中断するようにします。
ディレクトリ・トラバーサル
攻撃方法
ディレクトリトラバーサル(パストラバーサル)は、ファイル名を指定する箇所で「../」などを指定することで公開を想定していないファイルを参照される攻撃です。
パスワードや設定ファイル、ソースコードを改ざんされたり、秘密の情報が公開されてしまう危険性があります。
攻撃例
サーバへのリクエストでファイル名を指定して呼び出す場合を想定しています。
例えば、正規の挙動では、上記の1.txtを呼び出しているとします。
しかし、リクエスト内のファイル名を「../txt/../test/himitsu/himitsu.txt」とすると、簡単にhimitsu.txtにアクセスできてしまいます。
対策
外部からのパラメータでウェブサーバ内のファイル名を直接指定する実装を避ける
リクエストでファイル名やファイルパスを指定する実装を避けることで、外部から非公開のファイルにアクセスされるのを防ぎます。
これは、hiddenパラメータを利用する場合でも同様です。
ファイルを開く際は、固定のディレクトリを指定し、かつファイル名にディレクトリ名が含まれないようにする
ディレクトリはあらかじめ固定することで、指定外のディレクトリに移動しない実装にします。
例えば、カレントディレクトリ上のファイル「filename」を開くつもりで、open(filename)のような形でコーディングしている場合、open(filename)のfilenameに絶対パス名が渡されることにより、任意ディレクトリのファイルが開いてしまう場合があります。
この絶対パス名による指定を回避する方法として、あらかじめ固定のディレクトリ「dirname」を指定し、open(dirname+filename)のような形でコーディングする方法があります
仮に、filenameに「C:\test\himitsu\himitsu.txt」と入力されたとしても、ディレクトリdirnameは固定値で「C:\test\txt\」が入っているため、正しくディレクトリ指定できません。
さらに、「../」などを利用したディレクトリ・トラバーサル攻撃を回避するために、basename()などの関数を利用して、filenameに与えられたパス名からファイル名のみを取り出すようにします。
このようにすることで、攻撃者が../himitsu.txtと入力してもhimitsu.txtのみが取り出され、filenameに格納されます。
dirnameはすでに固定されているため、dirname+filenameは「C:\test\txt\himitsu.txt」となります。
txtフォルダにはhimitsu.txtが存在しないため、アクセスできません。
「/」や「..\」、「../」、「..%2F」などの文字が含まれないかチェックする
ディレクトリトラバーサルを狙ったリクエスト内容でないかを確認しましょう。
URLエンコードした場合も考慮してチェックする必要があります。
URLエンコードとは、「RL/URIのファイル名やクエリ文字列などの一部としては使用できない記号や文字を、使用できる文字の特殊な組み合わせによって表記する変換規則」です。
「/」は「%2F」、「../」は「..%2F」などに変換されます。
サーバやファイルのアクセス権限を設定する
仮に、非公開のファイルに辿り着けても、アクセス権がなければ参照できません。
そのため、サーバやファイルに対して適切にアクセス権限をつける必要があります
セッション・ハイジャック
セッション・ハイジャックによる攻撃方法
セッション・ハイジャックとは、利用者の通信を識別するセッションIDを悪用し、正規の利用者になりすますことで、ショッピングサイトで勝手に決済したり、利用者の情報を改ざんする攻撃です。
サーバーは、このセッションIDを基に、利用者が過去にどのような操作をしたのかを把握します。
セッションハイジャックでは、攻撃者がこのセッションIDを盗むことで、その利用者として行動を起こすことができるのです。
そのため、セッションIDは攻撃者にバレないようにする必要があるのです。
セッションハイジャックにより、利用者のなりすましができる原因は、大きく3つあります。
セッションIDが推測される
セッションIDが簡単に推測できる値の場合は、攻撃者が推測できてしまいます。
セッションIDが奪取される
クライアントとサーバの通信が暗号化されていない場合は、盗聴によりセッションIDが盗まれます。
セッションIDを固定化される
攻撃者が取得した正規のセッションIDを利用者に使用させ、対象のWebサイトに利用者がログインしたのを確認して、攻撃者が背乗りする行為です。
セッションフィクセーション攻撃とも呼ばれる手段です。
攻撃者自身が正規のサイトにアクセスして、セッションIDを取得する必要があるよ
対策
セッションIDを推測が困難なものにする
推測されにくいIDにすることで、攻撃者のなりすましを防ぎます。
セッションIDをURLパラメータに格納しない。
URLパラメータにセッションIDが入っていると、ブラウザがReferer送信昨日によって、セッションIDの含まれたURLをリンク先の別サイトに送信してしまいます。
Cookieに格納するか、POSTメソッドのhiddenパラメータに入れましょう
HTTPS通信で利用するCookieにsecure属性を付与する
secure属性があるCookieは、HTTPS通信でのみ利用されます。
HTTPS通信は暗号化されているため、盗聴できません。
CookieにセッションIDを入れても安全に通信できます。
クロスサイト・スクリプティング(XSS)
クロスサイトスクリプティングの攻撃方法
XSSとは、スクリプトを標的のサイトに送り込み、スクリプトを含むHTMLを出力し、ブラウザ上で実行させる攻撃です。
スクリプトとは、<script>タグで囲まれたJavaScriptのことです。
外部から入力されたスクリプトをHTMLで動的に実行されるような実装にしていると、XSSのリスクがあります。
XSSには2種類のタイプがあります。
- 格納型:脆弱性のあるサイト自体にスクリプトを埋め込み、ユーザがアクセスするとスクリプトが実行される
- 反射型:罠サイト経由で脆弱性サイトにアクセスした時にスクリプトが実行される
例えば、以下のような罠サイトがあるよ
・スクリプトを仕込んだ脆弱性のある標的サイトのURLを掲示板で投稿する
・攻撃者が作ったブログに、スクリプトを仕込んだ脆弱性のある標的サイトのURLを貼っておく
Cookieを利用してログインのセッション管理を行っているサイトや、フィッシング詐欺の攻撃ターゲットになりやすいページ(ログイン画面、個人情報の入力画面等)を持つサイトは、特に注意が必要です。
XSSによる攻撃の影響としては、Cookieを取得されることでセッションIDを奪取されたり、偽の情報を表示したりなどが考えられます。
対策
ユーザが入力した文字列をHTMLタグとして解釈しないように処理する必要があります。
ウェブページに出力する全ての要素に対して、エスケープ処理を施す
HTMLにおいて特殊な意味を持つ記号文字をエスケープ処理することで、スクリプトとして読み込めないようにします。
< → <
> → >
“ → "
‘ → '
& → &
このように、エスケープ処理することでスクリプトを無害化することをサニタイジングと言います。
URLを出力するときは、「http://」や 「https://」で始まるURLのみを許可する
URLには、「http://」や「https://」から始まるものだけでなく、「javascript:」の形式で始まるものもあります。
引用:安全なウェブサイトの作り方 – 1.5 クロスサイト・スクリプティング|IPA
ウェブページに出力するリンク先や画像のURLが、外部からの入力に依存する形で動的に生成される場合、そのURLにスクリプトが含まれていると、クロスサイト・スクリプティング攻撃が可能となる場合があります。
たとえば、利用者から入力されたリンク先のURLを「<a href=”リンク先のURL”>」の形式でウェブページに出力するウェブアプリケーションは、リンク先のURLに「javascript:」等から始まる文字列を指定された場合に、スクリプトを埋め込まれてしまう可能性があります。
<script>…</script> 要素の内容を動的に生成しない
スタイルシートを任意のサイトから取り込めるようにしない
入力値の内容チェックを行う
HTTPレスポンスヘッダのContent-Typeフィールドに文字コード(charset)を指定する
HTTPのレスポンスヘッダのContent-Typeフィールドには、「Content-Type: text/html; charset=UTF-8」のように、文字コード(charset)を指定できます。
文字コードを指定しない場合、特定の文字コードをブラウザに選択させる文字列を埋め込み、指定した文字コードで解釈した場合にスクリプトタグとなるような文字列を埋め込みます。
Cookie情報の漏えい対策として、発行するCookieにHttpOnly属性を加え、TRACEメソッドを無効化する
「HttpOnly」は、Cookieに設定できる属性のひとつで、これが設定されたCookieは、HTMLテキスト内のスクリプトからのアクセスが禁止されます。
これにより、ウェブサイトにクロスサイト・スクリプティングの脆弱性が存在する場合であっても、その脆弱性によってCookieを盗まれるという事態を防止できます。
クロスサイト・リクエスト・フォージェリ
攻撃方法
クロスサイトリクエストフォージェリ(CSRF)は、悪意のあるスクリプトを埋め込んだWebページを訪問者に閲覧させて、利用者認証やセッション管理の脆弱性のある別のWebサイトで、その訪問者が意図しない操作(ショッピングでの決済・退会等)を行わせる攻撃です。
「会員サイトにログイン→罠サイトへアクセス→罠サイト経由で再度会員サイトにリクエスト」の流れだね。
影響
決済サービスや利用者情報の更新といったログインした会員しか利用できない処理を悪用される危険性があります。
対策
処理を実行するページをPOSTメソッドでアクセスするようにし、その「hiddenパラメータ」に秘密情報が挿入されるよう、前のページを自動生成して、実行ページではその値が正しい場合のみ処理を実行する
トークンを利用するイメージです。
あらかじめ、ログインした段階でトークンを発行しておきます。
罠サイトに用意されているURL等には、トークンの情報が含まれていません。
そのため、サーバでトークンチェックをした場合に引っかかってしまいます。
処理を実行する直前のページで再度パスワードの入力を求め、実行ページでは、再度入力されたパスワードが正しい場合のみ処理を実行する
Refererが正しいリンク元かを確認し、正しい場合のみ処理を実行する
Refererとは、サイト訪問したユーザーが1つ前に閲覧したWebサイト(Webページ)のことです。
Refererを確認することにより、本来の画面遷移を経ているかどうかを判断できます。
Refererが確認できない場合は、処理を実行しないようにします
重要な操作を行った際に、その旨を登録済みのメールアドレスに自動送信する
HTTPヘッダ・インジェクション
HTTPヘッダインジェクションとは、ユーザ⼊⼒値などのクライアントから送信される値を適切に処理することなく、HTTPレスポンスヘッダに含めてしまうことにより発⽣する脆弱性および攻撃⼿法です
脆弱性のあるサイトのリンクを罠サイトに仕込んで、利用者にリンクをクリックさせます。
罠サイトでは、HTTPリクエストヘッダを改ざんするように小細工しておきます。
すると、リンクを踏んだ利用者には、攻撃者によって改ざんされたレスポンスボディが届いたり、Cookieが盗まれたりします。
攻撃例
Set-Cookieヘッダを追加し、正規ユーザが利⽤するCookieに任意の値を設定する
CookieにセッションIDを入れて井奥ことで、セッションIDの固定化ができます。
- 攻撃者はHTTPヘッダインジェクションを⽤いて、
Set-Cookie
ヘッダに任意のセッションIDを指定するように細⼯したURLを何らかの⽅法で正規ユーザにクリックさせる - 正規ユーザは細⼯されたURLから脆弱なサイトにアクセスする
- 攻撃者は指定したセッションIDを⽤いて、正規ユーザとしてサイトにアクセスする
レスポンスボディを任意のコンテンツに改ざんする
HTTPリクエストの中に、htmlタグやscriptタグやを入れておくことで、任意のコンテンツを改ざんします
キャッシュサーバのキャッシュ汚染
攻撃者が用意したレスポンスボディをリバースプロキシなどにキャッシュさせることで、キャッシュ汚染が起こります。
リバースプロキシとは、Webサーバの間でFWの役目をしたり、キャッシュサーバの役目をするサーバのことです。
プロキシサーバは、社内から外のネットワークに対してリクエストを飛ばす時に使います。
対策
ヘッダの出力を直接行わず、ウェブアプリケーションの実行環境や言語に用意されているヘッダ出力用APIを使用する
改行コードを適切に処理するヘッダ出力用APIを利用できない場合は、改行を許可しないよう、開発者自身で適切な処理を実装する
外部からの入力の全てについて、改行コードを削除する
メールヘッダ・インジェクション
攻撃方法
メールヘッダに悪意のある内容を注入される攻撃。
勝手に送信先を指定されたり、迷惑メールの送信に悪用される
対応
メールヘッダを固定値にして、外部からの入力はすべてメール本文に出力する
外部からの入力をそのまま出力すると、外部から与えられた改行コードが余分な改行として差し込まれる。
メールヘッダを固定値にできない場合、ウェブアプリケーションの実行環境や言語に用意されているメール送信用APIを使用す
HTMLで宛先を指定しない
hiddenパラメータなどに宛先をそのまま指定するのはNG。
外部からの入力の全てについて、改行コードを削除する
メールヘッダは改行で区切られる。
クリックジャッキング
攻撃内容
罠サイトの上にiframeで重ね、見た目を透明にする。
対応方法
HTTPレスポンスヘッダに、X-Frame-Optionsヘッダフィールドを出力し、他ドメインのサイトからのframe要素やiframe要素による読み込みを制限
X-Frame-Optionsは、ウェブアプリケーションをクリックジャッキング攻撃から防御するためのヘッダです
HTTPのレスポンスヘッダに「X-Frame-Options: DENY」のように出力することで、X-Frame-Optionsに対応したブラウザにおいて、frame要素やiframe要素によるページ読み込みの制限ができます
バッファオーバーフロー
悪意のあるユーザーがサーバー・パソコンに処理能力を超える大量のデータや悪意のあるコードを送り、メモリ領域内のバッファの許容量を超えて溢れてしまう(オーバーフロー)脆弱性、またはその脆弱性を悪用した攻撃のことを指します。
対策
直接メモリにアクセスできない言語で記述する
直接メモリにアクセスできる言語で記述する部分を最小限にする
DoS攻撃
DoS/DDoS攻撃
ターゲットとなるサーバに集中アクセスし、サービスを停止させる。
ボットを使って複数端末から攻撃する場合はDDoS攻撃。
マルチベクトル型DDoS攻撃
複数のDDoS攻撃を組み合わせる
EDoS攻撃
経済的損失を与えることを狙ったDoS攻撃。
ICMP Flood(Ping Flood)攻撃
ICMP echo request(ping)を大量に送りつけ、攻撃対象そのものや攻撃対象が属するネットワークのリソースを枯渇させる攻撃のこと。
pingコマンドは、ICMP echo要求パケットを送信するコマンドで、ICMP Flood攻撃で使用される。
Smurf攻撃
発信元を偽装した大量のICMP echo requestによって、ターゲットのネットワーク帯域に大量の応答(ICMP echo reply)を流す攻撃
ICMP flood攻撃の攻撃対象が「宛先サーバ」であるのに対し、smurf攻撃は「偽装した送信元アドレスを利用するサーバ」である点です。
UDP flood攻撃
送信元IPアドレスを偽装し、UDPデータグラムを大量に送りつけることで、送信元IPアドレス利用サーバにICMP応答を大量に送りつける攻撃
一般的なサーバは、UDPデータgを受信すると、宛先に指定されたポート番号で待っているプログラムがないか調べ。なければ不在である旨をICMPで送信元に通知するよ。
SYN flood攻撃
発信元IP偽装した大量のTCP SYNパケットを送りつける攻撃。
SYNパケットを受け取ったサーバはSYN/ACKパケットを返すが、攻撃者はACKパケットを返さない。
この状態をハーフオープンという。
ハーフオープン状態をたくさん作ることで、宛先サーバのリソースを減らす。
DNSリフレクション攻撃
送信元のIPアドレスを偽装してDNSサーバにDNSリクエストを送信し、偽の送信元(攻撃対象)に大量のDNSパケットを送信して、攻撃対象をダウンさせる攻撃のこと。
DNSサーバは利用されているだけで、攻撃対象ではないよ。
このように、利用されることを「踏み台にする」といいます。
NTPリフレクション攻撃
DNSリフレクション攻撃のNTPバージョン。
NTPとは、Network Time Protocolのことで、システムに内蔵される時刻を返すプロトコル。
ARPポイズニング
偽のARP応答パケットを送信してARPキャッシュを書き換える攻撃。
ARPとは、IPアドレスのノードのMACアドレスを教えるプロトコル。
IPアドレスはPCの位置を識別するためのインターネットの情報で、最終目的地の宛先を示しているよ。
それに対して、MACアドレスは隣接のインターネット機器の間を通信するための重要な情報で、その次の宛先を示しているよ。
下図では、PC1から別のネットワークに属するPC2にパケットを送っているね。
送信元・宛先IPアドレスは、全てPC1,2であるのに対し、
送信元・宛先アドレスはネットワーク内であっても機器が違うことで変化します。
DNSサーバ関連攻撃
DNSキャッシュポイズニング
DNSキャッシュサーバが権威サーバに名前解決要求を送った時、正規の権威サーバからの応答が返ってくる前に偽の応答を返すことで、DNSキャッシュサーバのキャッシュを汚染する攻撃。
DNSの問い合わせ構造は下記の通り。
カミンスキー攻撃
ドメイン内に存在しないホスト名を攻撃対象のキャッシュDNSサーバに送信して、問い合わせを強制させてえキャッシュDNSを汚染する攻撃です。
DNS水責め攻撃(ランダムサブドメイン攻撃)
DNSサーバーに対してランダムなサブドメインを水責めのように集中させ、機能を停止させる攻撃。
キャッシュサーバには当然キャッシュされていないので、権威サーバに名前解決を要求するため、権威DNSサーバのリソースが逼迫します。
対策として、キャッシュDNSサーバをオープンリゾルバーにしないことが挙げられる。
オープンリゾルバーとは、外部の不特定のIPアドレスからの再帰的な問い合わせを許可しているDNSサーバのことです。
SSL/TLS関連攻撃
POODLE
暗号化された通信から、その脆弱性を突いて認証情報やクッキー情報を盗み出す攻撃。
具体的には、SSL3.0プロトコルの脆弱性を突く攻撃。
CBCモードのブロック暗号を利用している場合、一定の長さごとにデータを区切って暗号化するため、元のデータの長さによっては最後のブロックに空白ができる。
通常は、この空白をパディングデータというデータで埋める。
SSL3.0プロトコルの場合、このパディングデータの検証を十分に行わないため、通信内容を解読される危険性がある。
バージョンロールバック
暗号化通信(SSL/TLS)をする時に用いられるプロトコルについて、脆弱性のある古いバージョンのものを使うように誘導させる攻撃。
マルウェア
不正に動作するプログラム。
対策として下記がある。
- OSやソフトウェアのアップデート
- 不審なメールやファイルは開かない
感染後の対策は以下の通り
- ネットワークから感染したPCを切り離す
- 画面